441 lines
16 KiB
PHP
441 lines
16 KiB
PHP
<?php
|
|
/**
|
|
* TNT OFFICIAL MODULE FOR PRESTASHOP.
|
|
*
|
|
* @author GFI Informatique <www.gfi.fr>
|
|
* @copyright 2016-2017 GFI Informatique, 2016-2017 TNT
|
|
* @license https://opensource.org/licenses/MIT MIT License
|
|
*/
|
|
|
|
require_once _PS_MODULE_DIR_.'tntofficiel/libraries/TNTOfficiel_Debug.php';
|
|
require_once _PS_MODULE_DIR_.'tntofficiel/libraries/TNTOfficiel_Logger.php';
|
|
require_once _PS_MODULE_DIR_.'tntofficiel/libraries/TNTOfficiel_JsonRPCClient.php';
|
|
require_once _PS_MODULE_DIR_.'tntofficiel/libraries/TNTOfficiel_PasswordManager.php';
|
|
require_once _PS_MODULE_DIR_.'tntofficiel/libraries/helper/TNTOfficiel_OrderHelper.php';
|
|
require_once _PS_MODULE_DIR_.'tntofficiel/libraries/helper/TNTOfficiel_AddressHelper.php';
|
|
require_once _PS_MODULE_DIR_.'tntofficiel/libraries/helper/TNTOfficiel_ParcelsHelper.php';
|
|
require_once _PS_MODULE_DIR_.'tntofficiel/libraries/exceptions/TNTOfficiel_OrderAlreadyShippedException.php';
|
|
|
|
class TNTOfficiel_ShipmentHelper
|
|
{
|
|
/**
|
|
* The directory where the BT are stored.
|
|
*/
|
|
const BT_DIR = 'tnt_media/media/bt';
|
|
|
|
/** @var Singleton */
|
|
private static $_instance = null;
|
|
|
|
/** @var TNTOfficiel_Logger */
|
|
private $logger;
|
|
|
|
/**
|
|
* Constructor.
|
|
*/
|
|
public function __construct()
|
|
{
|
|
TNTOfficiel_Debug::log(array('msg' => '>>', 'file' => __FILE__, 'line' => __LINE__));
|
|
|
|
$this->logger = new TNTOfficiel_Logger();
|
|
}
|
|
|
|
/**
|
|
* Creates a singleton.
|
|
*
|
|
* @param void
|
|
*
|
|
* @return TNTOfficiel_ShipmentHelper
|
|
*/
|
|
public static function getInstance()
|
|
{
|
|
TNTOfficiel_Debug::log(array('msg' => '>>', 'file' => __FILE__, 'line' => __LINE__));
|
|
|
|
if (is_null(TNTOfficiel_ShipmentHelper::$_instance)) {
|
|
TNTOfficiel_ShipmentHelper::$_instance = new TNTOfficiel_ShipmentHelper();
|
|
}
|
|
|
|
return TNTOfficiel_ShipmentHelper::$_instance;
|
|
}
|
|
|
|
/**
|
|
* Send a shipment request to the middleware.
|
|
*
|
|
* @param $cart
|
|
* @param $orderId
|
|
*
|
|
* @return bool
|
|
*
|
|
* @throws Exception
|
|
*/
|
|
public function saveShipment($cart, $orderId)
|
|
{
|
|
TNTOfficiel_Debug::log(array('msg' => '>>', 'file' => __FILE__, 'line' => __LINE__));
|
|
|
|
$order = new Order($orderId);
|
|
try {
|
|
$arrTNTOrder = TNTOfficiel_OrderHelper::getInstance()->getOrderData($orderId);
|
|
if ($arrTNTOrder['is_shipped']) {
|
|
throw new TNTOfficiel_OrderAlreadyShippedException('The shipment has already been created for the order ' + $orderId);
|
|
}
|
|
$arrTNTAddress = TNTOfficiel_AddressHelper::getInstance()->getAddressData($order->id_address_delivery, $order->id_cart);
|
|
$parcels = TNTOfficiel_ParcelsHelper::getInstance()->getParcels($orderId);
|
|
} catch (Exception $objException) {
|
|
$objFileLogger = new FileLogger();
|
|
$objFileLogger->setFilename(_PS_ROOT_DIR_.'/log/'.date('Ymd').'_tnt_exception.log');
|
|
$objFileLogger->logError($objException->getMessage());
|
|
throw $objException;
|
|
}
|
|
|
|
//call the middleware
|
|
$arrParams = $this->_getParams(
|
|
$cart->id_shop,
|
|
$arrTNTOrder,
|
|
$arrTNTAddress,
|
|
$this->_getParcelsData($parcels, $order->reference),
|
|
$arrTNTOrder['shipping_date']
|
|
);
|
|
$response = $this->_callMiddleware($arrParams);
|
|
if (is_string($response)) {
|
|
throw new PrestaShopException($response);
|
|
}
|
|
|
|
//save the BT
|
|
if ($response) {
|
|
$this->_saveBT($response['bt'], $order);
|
|
$this->_saveTrackingUrls($response['parcels'], $orderId);
|
|
$this->_savePickupNumber($response['pickUpNumber'], $orderId);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Check if a shipment was successfully done for an order.
|
|
*
|
|
* @param $orderId
|
|
*
|
|
* @return bool
|
|
*/
|
|
public function isShipmentSaved($orderId)
|
|
{
|
|
TNTOfficiel_Debug::log(array('msg' => '>>', 'file' => __FILE__, 'line' => __LINE__));
|
|
|
|
$sql = 'SELECT * FROM '._DB_PREFIX_.'tntofficiel_order WHERE id_order = '.(int)$orderId;
|
|
$arrOrder = Db::getInstance()->getRow($sql, false);
|
|
|
|
return (bool)$arrOrder['is_shipped'];
|
|
}
|
|
|
|
/**
|
|
* Get the params.
|
|
*
|
|
* @param $intArgShopID
|
|
* @param $arrArgTNTOrder
|
|
* @param $arrArgTNTAddress
|
|
* @param $parcelsData
|
|
*
|
|
* @return array
|
|
*/
|
|
private function _getParams($intArgShopID, $arrArgTNTOrder, $arrArgTNTAddress, $parcelsData, $shippingDate = false)
|
|
{
|
|
TNTOfficiel_Debug::log(array('msg' => '>>', 'file' => __FILE__, 'line' => __LINE__));
|
|
|
|
$productCode = $arrArgTNTOrder['carrier_code'];
|
|
|
|
$typeId = (empty($arrArgTNTOrder['carrier_xett'])) ? $arrArgTNTOrder['carrier_pex'] : $arrArgTNTOrder['carrier_xett'];
|
|
$arrParams = array(
|
|
'store' => $intArgShopID,
|
|
'merchant' => array(
|
|
'identity' => Configuration::get('TNT_CARRIER_USERNAME'),
|
|
'password' => TNTOfficiel_PasswordManager::getHash(),
|
|
'merchant_number' => Configuration::get('TNT_CARRIER_ACCOUNT'),
|
|
),
|
|
'product' => $productCode,
|
|
'recipient' => array(
|
|
'xett' => $arrArgTNTOrder['carrier_xett'],
|
|
'pex' => $arrArgTNTOrder['carrier_pex'],
|
|
'firstname' => $arrArgTNTAddress['firstname'],
|
|
'lastname' => $arrArgTNTAddress['lastname'],
|
|
'address1' => Tools::substr($arrArgTNTAddress['address1'], 0, 32),
|
|
'address2' => Tools::substr($arrArgTNTAddress['address2'], 0, 32),
|
|
'post_code' => $arrArgTNTAddress['postcode'],
|
|
'city' => $arrArgTNTAddress['city'],
|
|
'email' => $arrArgTNTAddress['customer_email'],
|
|
'phone' => $arrArgTNTAddress['customer_mobile'],
|
|
'access_code' => $arrArgTNTAddress['address_accesscode'],
|
|
'floor' => $arrArgTNTAddress['address_floor'],
|
|
'building' => $arrArgTNTAddress['address_building'],
|
|
'name' => $arrArgTNTAddress['company'],
|
|
'typeId' => $typeId,
|
|
),
|
|
'parcels' => $parcelsData,
|
|
);
|
|
|
|
if ($shippingDate) {
|
|
$arrParams['shipping_date'] = $shippingDate;
|
|
}
|
|
|
|
return $arrParams;
|
|
}
|
|
|
|
/**
|
|
* Get parcels data.
|
|
*
|
|
* @param $parcels array
|
|
*
|
|
* @return array
|
|
*/
|
|
private function _getParcelsData($parcels, $orderReference)
|
|
{
|
|
TNTOfficiel_Debug::log(array('msg' => '>>', 'file' => __FILE__, 'line' => __LINE__));
|
|
|
|
$parcelsData = array();
|
|
foreach ($parcels as $parcel) {
|
|
$parcelsData[] = array(
|
|
'reference' => $orderReference,
|
|
'weight' => $parcel['weight'],
|
|
);
|
|
}
|
|
|
|
return $parcelsData;
|
|
}
|
|
|
|
/**
|
|
* Call the middleware to save the shipment.
|
|
*
|
|
* @param $params
|
|
*
|
|
* @return mixed
|
|
*
|
|
* @throws Exception
|
|
*/
|
|
private function _callMiddleware($params)
|
|
{
|
|
TNTOfficiel_Debug::log(array('msg' => '>>', 'file' => __FILE__, 'line' => __LINE__));
|
|
|
|
$client = new TNTOfficiel_JsonRPCClient(Configuration::get('TNT_CARRIER_MIDDLEWARE_URL'));
|
|
try {
|
|
$result = $client->execute('saveShipment', $params);
|
|
$this->logger->logMessageTnt('saveShipment', null, 'JSON', true, 'SUCCESS');
|
|
} catch (Exception $objException) {
|
|
$strStatus = ($objException->getCode() == 500) ? 'FATAL' : 'ERROR';
|
|
$strMsg = $objException->getMessage();
|
|
$this->logger->logMessageTnt('saveShipment', $strMsg, 'JSON', false, $strStatus);
|
|
throw $objException;
|
|
}
|
|
|
|
return $result;
|
|
}
|
|
|
|
/**
|
|
* Call the middleware to save the shipment.
|
|
*
|
|
* @param $params
|
|
*
|
|
* @return mixed
|
|
*
|
|
* @throws Exception
|
|
*/
|
|
private function _callMiddlewareWithService($params, $service)
|
|
{
|
|
TNTOfficiel_Debug::log(array('msg' => '>>', 'file' => __FILE__, 'line' => __LINE__));
|
|
|
|
$client = new TNTOfficiel_JsonRPCClient(Configuration::get('TNT_CARRIER_MIDDLEWARE_URL'));
|
|
try {
|
|
$result = $client->execute($service, $params);
|
|
$this->logger->logMessageTnt($service, null, 'JSON', true, 'SUCCESS');
|
|
} catch (Exception $objException) {
|
|
$strStatus = ($objException->getCode() == 500) ? 'FATAL' : 'ERROR';
|
|
$strMsg = $objException->getMessage();
|
|
$this->logger->logMessageTnt($service, $strMsg, 'JSON', false, $strStatus);
|
|
throw $objException;
|
|
}
|
|
|
|
return $result;
|
|
}
|
|
|
|
/**
|
|
* Saves the BT in the file system.
|
|
*
|
|
* @param $strBTContent
|
|
* @param $order
|
|
*
|
|
* @throws Exception
|
|
*/
|
|
private function _saveBT($strBTContent, $order)
|
|
{
|
|
TNTOfficiel_Debug::log(array('msg' => '>>', 'file' => __FILE__, 'line' => __LINE__));
|
|
|
|
//creates the directory if not exists
|
|
if (!is_dir(_PS_MODULE_DIR_.TNTOfficiel_ShipmentHelper::BT_DIR)) {
|
|
mkdir(_PS_MODULE_DIR_.TNTOfficiel_ShipmentHelper::BT_DIR, 0777, true);
|
|
}
|
|
$date = date('Y-m-d_H-i-s');
|
|
$strBTFilename = sprintf('BT_%s_%s.pdf', $order->reference, $date);
|
|
//create the file
|
|
try {
|
|
file_put_contents(_PS_MODULE_DIR_.TNTOfficiel_ShipmentHelper::BT_DIR.'/'.$strBTFilename, utf8_decode($strBTContent));
|
|
Db::getInstance()->update(
|
|
'tntofficiel_order',
|
|
array('bt_filename' => pSQL($strBTFilename), 'is_shipped' => true, 'previous_state' => (int)$order->current_state),
|
|
'id_order = '.(int)$order->id
|
|
);
|
|
} catch (Exception $objException) {
|
|
$objFileLogger = new FileLogger();
|
|
$objFileLogger->setFilename(_PS_ROOT_DIR_.'/log/'.date('Ymd').'_tnt_exception.log');
|
|
$objFileLogger->logError($objException->getMessage());
|
|
throw $objException;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Saves the tracking url for each parcel.
|
|
*
|
|
* @param $tntParcels
|
|
* @param $orderId
|
|
*
|
|
* @throws Exception
|
|
*/
|
|
private function _saveTrackingUrls($tntParcels, $orderId)
|
|
{
|
|
TNTOfficiel_Debug::log(array('msg' => '>>', 'file' => __FILE__, 'line' => __LINE__));
|
|
|
|
$sql = 'SELECT * FROM '._DB_PREFIX_.'tntofficiel_order_parcels where id_order = '.(int)$orderId;
|
|
$parcels = Db::getInstance()->executeS($sql);
|
|
$i = 0;
|
|
foreach ($tntParcels as $tntParcel) {
|
|
try {
|
|
Db::getInstance()->update(
|
|
'tntofficiel_order_parcels',
|
|
array(
|
|
'tracking_url' => pSQL($tntParcel['tracking_url']),
|
|
'parcel_number' => pSQL($tntParcel['number']),
|
|
),
|
|
'id_parcel = '.pSQL($parcels[$i]['id_parcel'])
|
|
);
|
|
} catch (Exception $objException) {
|
|
$objFileLogger = new FileLogger();
|
|
$objFileLogger->setFilename(_PS_ROOT_DIR_.'/log/'.date('Ymd').'_tnt_exception.log');
|
|
$objFileLogger->logError($objException->getMessage());
|
|
throw $objException;
|
|
}
|
|
++$i;
|
|
}
|
|
}
|
|
|
|
private function _savePickupNumber($pickupNumber, $orderId)
|
|
{
|
|
TNTOfficiel_Debug::log(array('msg' => '>>', 'file' => __FILE__, 'line' => __LINE__));
|
|
|
|
$sql = 'SELECT * FROM '._DB_PREFIX_.'tntofficiel_order where id_order = '.(int)$orderId;
|
|
$orders = Db::getInstance()->executeS($sql);
|
|
foreach ($orders as $order) {
|
|
Db::getInstance()->update(
|
|
'tntofficiel_order',
|
|
array('pickup_number' => pSQL($pickupNumber)),
|
|
'id_tntofficiel_order = '.(int)$order['id_tntofficiel_order']
|
|
);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Get the first available shipping date.
|
|
*
|
|
* @param $cart
|
|
* @param $intArgOrderID
|
|
*
|
|
* @return string|bool
|
|
*
|
|
* @throws Exception
|
|
*/
|
|
public function getShippingDate($intArgOrderID)
|
|
{
|
|
TNTOfficiel_Debug::log(array('msg' => '>>', 'file' => __FILE__, 'line' => __LINE__));
|
|
|
|
$objOrder = new Order($intArgOrderID);
|
|
try {
|
|
$arrTNTOrder = TNTOfficiel_OrderHelper::getInstance()->getOrderData($intArgOrderID);
|
|
if ($arrTNTOrder['is_shipped']) {
|
|
throw new TNTOfficiel_OrderAlreadyShippedException('The shipment has already been created for the order ' + $intArgOrderID);
|
|
}
|
|
$arrTNTAddress = TNTOfficiel_AddressHelper::getInstance()->getAddressData($objOrder->id_address_delivery, $objOrder->id_cart);
|
|
$parcels = TNTOfficiel_ParcelsHelper::getInstance()->getParcels($intArgOrderID);
|
|
} catch (Exception $objException) {
|
|
$objFileLogger = new FileLogger();
|
|
$objFileLogger->setFilename(_PS_ROOT_DIR_.'/log/'.date('Ymd').'_tnt_exception.log');
|
|
$objFileLogger->logError($objException->getMessage());
|
|
throw $objException;
|
|
}
|
|
|
|
//call the middleware
|
|
$arrParams = $this->_getParams(
|
|
$objOrder->id_shop,
|
|
$arrTNTOrder,
|
|
$arrTNTAddress,
|
|
$this->_getParcelsData($parcels, $objOrder->reference)
|
|
);
|
|
$arrMDWResponse = $this->_callMiddlewareWithService($arrParams, 'getShippingDate');
|
|
if (is_string($arrMDWResponse)) {
|
|
throw new PrestaShopException($arrMDWResponse);
|
|
}
|
|
|
|
return $arrMDWResponse;
|
|
}
|
|
|
|
/**
|
|
* Get the first available shipping date.
|
|
*
|
|
* @param $cart
|
|
* @param $orderId
|
|
*
|
|
* @return string|bool
|
|
*
|
|
* @throws Exception
|
|
*/
|
|
public function checkSaveShipmentDate($orderId, $shippingDate)
|
|
{
|
|
TNTOfficiel_Debug::log(array('msg' => '>>', 'file' => __FILE__, 'line' => __LINE__));
|
|
|
|
$order = new Order($orderId);
|
|
try {
|
|
$arrTNTOrder = TNTOfficiel_OrderHelper::getInstance()->getOrderData($orderId);
|
|
$arrTNTAddress = TNTOfficiel_AddressHelper::getInstance()->getAddressData($order->id_address_delivery, $order->id_cart);
|
|
$parcels = TNTOfficiel_ParcelsHelper::getInstance()->getParcels($orderId);
|
|
} catch (Exception $objException) {
|
|
$objFileLogger = new FileLogger();
|
|
$objFileLogger->setFilename(_PS_ROOT_DIR_.'/log/'.date('Ymd').'_tnt_exception.log');
|
|
$objFileLogger->logError($objException->getMessage());
|
|
throw $objException;
|
|
}
|
|
|
|
//call the middleware
|
|
$arrParams = $this->_getParams(
|
|
$order->id_shop,
|
|
$arrTNTOrder,
|
|
$arrTNTAddress,
|
|
$this->_getParcelsData($parcels, $order->reference),
|
|
$shippingDate
|
|
);
|
|
$arrMDWResponse = $this->_callMiddlewareWithService($arrParams, 'checkSaveShipment');
|
|
|
|
return $arrMDWResponse;
|
|
}
|
|
|
|
public function getNewShippingDate($intArgOrderID)
|
|
{
|
|
TNTOfficiel_Debug::log(array('msg' => '>>', 'file' => __FILE__, 'line' => __LINE__));
|
|
|
|
$arrMDWShippingDate = TNTOfficiel_ShipmentHelper::getInstance()->getShippingDate($intArgOrderID);
|
|
//$shippingDatePrepa = $response['shippingDatePrepa'];
|
|
$shippingDatePrepa = $arrMDWShippingDate['shippingDate'];
|
|
|
|
$arrMDWShippingDate = TNTOfficiel_ShipmentHelper::getInstance()->checkSaveShipmentDate($intArgOrderID, $shippingDatePrepa);
|
|
|
|
if (!array_key_exists('shippingDate', $arrMDWShippingDate)) {
|
|
return false;
|
|
}
|
|
|
|
return $arrMDWShippingDate;
|
|
}
|
|
}
|