chocolatdemariage/www/modules/tntofficiel/libraries/helper/TNTOfficiel_ParcelsHelper.php
Preprod mutu dc0edebeb0 tnt
2017-09-12 10:48:51 +02:00

493 lines
17 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?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/tntofficiel.php';
require_once _PS_MODULE_DIR_.'tntofficiel/classes/TNTOfficielCart.php';
require_once _PS_MODULE_DIR_.'tntofficiel/libraries/TNTOfficiel_Debug.php';
require_once _PS_MODULE_DIR_.'tntofficiel/libraries/TNTOfficiel_Parcel.php';
require_once _PS_MODULE_DIR_.'tntofficiel/libraries/TNTOfficiel_SoapClient.php';
require_once _PS_MODULE_DIR_.'tntofficiel/libraries/helper/TNTOfficiel_OrderHelper.php';
require_once _PS_MODULE_DIR_.'tntofficiel/libraries/exceptions/TNTOfficiel_MaxPackageWeightException.php';
class TNTOfficiel_ParcelsHelper
{
/** @var TNTOfficiel_ParcelsHelper */
private static $_instance = null;
/**
* Constructor.
*/
public function __construct()
{
TNTOfficiel_Debug::log(array('msg' => '>>', 'file' => __FILE__, 'line' => __LINE__));
}
/**
* Creates a singleton.
*
* @param void
*
* @return TNTOfficiel_ParcelsHelper
*/
public static function getInstance()
{
TNTOfficiel_Debug::log(array('msg' => '>>', 'file' => __FILE__, 'line' => __LINE__));
if (is_null(TNTOfficiel_ParcelsHelper::$_instance)) {
TNTOfficiel_ParcelsHelper::$_instance = new TNTOfficiel_ParcelsHelper();
}
return TNTOfficiel_ParcelsHelper::$_instance;
}
/**
* Creates the parcels for an order.
*
* @param $objCart
* @param $intArgOrderID
*
* @return bool
*/
public function createParcels($objCart, $intArgOrderID)
{
TNTOfficiel_Debug::log(array('msg' => '>>', 'file' => __FILE__, 'line' => __LINE__));
$orderedProducts = $this->_getProductsOrderedByWeight($objCart->getProducts());
$fltMaxParcelWeight = $this->_getMaxPackageWeight($intArgOrderID);
$parcels = array();
$parcel = new TNTOfficiel_Parcel();
foreach ($orderedProducts as $product) {
$productQuantity = $product['quantity'];
for ($i = 0; $i < $productQuantity; ++$i) {
//check if parcel's weight exceeds the maximum parcel weight
//and remove the last added product in the parcel if it's not the only product in it
if (($parcel->getWeight() + $product['weight']) <= $fltMaxParcelWeight) {
$parcel->addProduct($product);
} else {
$parcels[] = $parcel;
$parcel = new TNTOfficiel_Parcel();
$parcel->addProduct($product);
}
}
}
//if the parcels contains at least one product we add it to the list
if (count($parcel->getProductList())) {
$parcels[] = $parcel;
}
//save the parcels
$this->_saveParcels($parcels, $intArgOrderID);
return true;
}
/**
* Order a list of products by weight.
*
* @param $products
*
* @return array
*/
private function _getProductsOrderedByWeight($products)
{
TNTOfficiel_Debug::log(array('msg' => '>>', 'file' => __FILE__, 'line' => __LINE__));
usort($products, array(__CLASS__, 'compareProductByWeight'));
return $products;
}
/**
* Compare two products by their weight.
*
* @param $productA
* @param $productB
*
* @return int
*/
public static function compareProductByWeight($productA, $productB)
{
TNTOfficiel_Debug::log(array('msg' => '>>', 'file' => __FILE__, 'line' => __LINE__));
if ($productA['weight'] == $productB['weight']) {
return 0;
}
return ($productA['weight'] < $productB['weight']) ? -1 : 1;
}
/**
* Save the parcels in the database.
*
* @param $parcels array
* @param $orderId int
*/
private function _saveParcels($parcels, $orderId)
{
TNTOfficiel_Debug::log(array('msg' => '>>', 'file' => __FILE__, 'line' => __LINE__));
foreach ($parcels as $parcel) {
//insert into the parcel table
$this->addParcel($orderId, $parcel->getWeight(), true);
}
}
/**
* Get the parcels of an order.
*
* @param $orderId int
*
* @return array
*/
public function getParcels($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);
return $parcels;
}
/**
* Remove a parcel.
*
* @param $parcelId int
*
* @return bool
*/
public function removeParcel($parcelId)
{
TNTOfficiel_Debug::log(array('msg' => '>>', 'file' => __FILE__, 'line' => __LINE__));
return Db::getInstance()->delete('tntofficiel_order_parcels', 'id_parcel = '.(int)$parcelId);
}
/**
* Add a parcel.
*
* @param $intArgOrderID int
* @param $fltArgWeight float
* @param $isOrderCreation
*
* @return array
*
* @throws TNTOfficiel_MaxPackageWeightException
*/
public function addParcel($intArgOrderID, $fltArgWeight, $isOrderCreation = true)
{
TNTOfficiel_Debug::log(array('msg' => '>>', 'file' => __FILE__, 'line' => __LINE__));
$fltMaxPackageWeight = $this->_getMaxPackageWeight($intArgOrderID);
//Does not throw an exception when this is an order creation
//the parcel can contains one product which weight exceeds the maximum weight
if ((float)$fltArgWeight > $fltMaxPackageWeight && !$isOrderCreation) {
throw new TNTOfficiel_MaxPackageWeightException('Le poids d\'un colis ne peut dépasser '.$fltMaxPackageWeight.'Kg');
}
Db::getInstance()->insert('tntofficiel_order_parcels', array(
'id_order' => (int)$intArgOrderID,
'weight' => max(round((float)$fltArgWeight, 1, PHP_ROUND_HALF_UP), 0.1),
));
$sql = 'SELECT * FROM '._DB_PREFIX_.'tntofficiel_order_parcels WHERE id_parcel ='.Db::getInstance()->Insert_ID();
return Db::getInstance()->executeS($sql);
}
/**
* Update a parcel.
*
* @param $parcelId int
* @param $weight float
* @param $intArgOrderID int
*
* @return bool
*
* @throws TNTOfficiel_MaxPackageWeightException
*/
public function updateParcel($parcelId, $weight, $intArgOrderID)
{
TNTOfficiel_Debug::log(array('msg' => '>>', 'file' => __FILE__, 'line' => __LINE__));
$fltMaxPackageWeight = $this->_getMaxPackageWeight($intArgOrderID);
if ((float)$weight > $fltMaxPackageWeight) {
throw new TNTOfficiel_MaxPackageWeightException('Le poids d\'un colis ne peut dépasser '.$fltMaxPackageWeight.'Kg');
}
$weight = max(round($weight, 1, PHP_ROUND_HALF_UP), 0.1);
$result = array();
$result['result'] = Db::getInstance()->update(
'tntofficiel_order_parcels',
array('weight' => (float)$weight),
'id_parcel = '.(int)$parcelId
);
$result['weight'] = $weight;
return $result;
}
/**
* @param $parcel array
*
* @return array
*/
public function getTrackingData($parcel)
{
TNTOfficiel_Debug::log(array('msg' => '>>', 'file' => __FILE__, 'line' => __LINE__));
$response = $this->_callTntWs($parcel['parcel_number']);
$response = (array)$response;
$returnData = '';
if (count($response) && isset($response['Parcel'])) {
$returnData = $response['Parcel'];
}
if ($returnData) {
$this->_savePdl($returnData, $parcel['id_parcel']);
$returnData = array(
'history' => $this->_getHistory($returnData),
'status' => $this->_getStatus($returnData),
'allStatus' => $this->_getAllStatus($this->_getStatus($returnData)),
);
}
return $returnData;
}
/**
* Get the maximum package weight for the order.
*
* @param $intArgOrderID
*
* @return float
*
* @throws Exception
*/
private function _getMaxPackageWeight($intArgOrderID)
{
TNTOfficiel_Debug::log(array('msg' => '>>', 'file' => __FILE__, 'line' => __LINE__));
try {
$arrTNTOrder = TNTOfficiel_OrderHelper::getInstance()->getOrderData($intArgOrderID);
$strCarrierCode = $arrTNTOrder['carrier_code'];
} catch (Exception $objException) {
// TODO : Should not happen ! Why using carrier code from cart ??
$objContext = Context::getContext();
$objCart = $objContext->cart;
$intCartID = (int)$objCart->id;
// Load TNT cart info or create a new one for it's ID.
$objTNTCartModel = TNTOfficielCart::loadCartID($intCartID);
if(Validate::isLoadedObject($objTNTCartModel)) {
$strCarrierCode = $objTNTCartModel->carrier_code;
}
// throw $objException;
}
// If carrier code is B2B.
if (strpos($strCarrierCode, 'ENTERPRISE')) {
$fltMaxPackageWeight = (float)Configuration::get('TNT_CARRIER_MAX_PACKAGE_B2B');
} else {
$fltMaxPackageWeight = (float)Configuration::get('TNT_CARRIER_MAX_PACKAGE_B2C');
}
return $fltMaxPackageWeight;
}
/**
* Call the tnt.
*
* @param $parcelNumber
*
* @return stdClass
*/
private function _callTntWs($parcelNumber)
{
TNTOfficiel_Debug::log(array('msg' => '>>', 'file' => __FILE__, 'line' => __LINE__));
$client = new TNTOfficiel_SoapClient();
$result = $client->trackingByConsignment($parcelNumber);
return $result;
}
/**
* Return All Status de display : depends on status -> maximum 5 status.
*
* @param $status
*
* @return array
*/
protected function _getAllStatus($status)
{
TNTOfficiel_Debug::log(array('msg' => '>>', 'file' => __FILE__, 'line' => __LINE__));
$statusArray = array(
1 => TNTOfficiel_ParcelsHelper::translate('Colis chez lexpéditeur'),
2 => TNTOfficiel_ParcelsHelper::translate('Ramassage du Colis'),
3 => TNTOfficiel_ParcelsHelper::translate('Acheminement'),
4 => TNTOfficiel_ParcelsHelper::translate('Livraison en cours'),
5 => TNTOfficiel_ParcelsHelper::translate('Livré'),
);
switch ($status) {
case 6:
$statusArray[5] = TNTOfficiel_ParcelsHelper::translate('Incident');
break;
case 7:
$statusArray[5] = TNTOfficiel_ParcelsHelper::translate("Retourné à l'expéditeur");
break;
}
return $statusArray;
}
/**
* @param $parcel
*
* @return bool|int
*/
protected function _getStatus($parcel)
{
TNTOfficiel_Debug::log(array('msg' => '>>', 'file' => __FILE__, 'line' => __LINE__));
$parcel = (array)$parcel;
$statusLabel = isset($parcel['shortStatus']) ? $parcel['shortStatus'] : false;
if (!$statusLabel) {
return false;
}
$mapping = array(
TNTOfficiel_ParcelsHelper::translate('En attente') => 1,
'--' => 2,
TNTOfficiel_ParcelsHelper::translate('En cours d\'acheminement') => 3,
TNTOfficiel_ParcelsHelper::translate('En cours de livraison') => 4,
TNTOfficiel_ParcelsHelper::translate('En agence TNT') => 4,
TNTOfficiel_ParcelsHelper::translate('Récupéré à l\'agence TNT') => 5,
TNTOfficiel_ParcelsHelper::translate('Livré') => 5,
TNTOfficiel_ParcelsHelper::translate('En attente de vos instructions') => 6,
TNTOfficiel_ParcelsHelper::translate('En attente d\'instructions') => 6,
TNTOfficiel_ParcelsHelper::translate('En attente d\'instructions') => 6,
TNTOfficiel_ParcelsHelper::translate('Incident de livraison') => 6,
TNTOfficiel_ParcelsHelper::translate('Incident intervention') => 6,
TNTOfficiel_ParcelsHelper::translate('Colis refusé par le destinataire') => 6,
TNTOfficiel_ParcelsHelper::translate('Livraison reprogrammée') => 6,
TNTOfficiel_ParcelsHelper::translate('Prise de rendez-vous en cours') => 6,
TNTOfficiel_ParcelsHelper::translate('Prise de rendez-vous en cours') => 6,
TNTOfficiel_ParcelsHelper::translate('Problème douane') => 6,
TNTOfficiel_ParcelsHelper::translate('Enlevé au dépôt') => 3,
TNTOfficiel_ParcelsHelper::translate('En dépôt restant') => 3,
TNTOfficiel_ParcelsHelper::translate('Retourné à l\'expéditeur') => 7,
);
return isset($mapping[$statusLabel]) ? $mapping[$statusLabel] : 1;
}
/**
* @param $parcel
*
* @return bool
*/
protected function _getHistory($parcel)
{
TNTOfficiel_Debug::log(array('msg' => '>>', 'file' => __FILE__, 'line' => __LINE__));
if (!$parcel->events) {
return false;
}
$history = array();
$states = array(1 => 'request', 2 => 'process', 3 => 'arrival', 4 => 'deliveryDeparture', 5 => 'delivery');
$events = (array)$parcel->events;
foreach ($states as $idx => $state) {
if ((isset($events[$state.'Center']) || isset($events[$state.'Date']))
&& Tools::strlen($events[$state.'Date'])
) {
$history[$idx] = array(
'label' => $this->_getLabel($state),
'date' => isset($events[$state.'Date']) ? $events[$state.'Date'] : '',
'center' => isset($events[$state.'Center']) ? $events[$state.'Center'] : '',
);
}
}
return $history;
}
protected function _getLabel($state)
{
TNTOfficiel_Debug::log(array('msg' => '>>', 'file' => __FILE__, 'line' => __LINE__));
$labels = array(
'request' => TNTOfficiel_ParcelsHelper::translate('Colis chez lexpéditeur'),
'process' => TNTOfficiel_ParcelsHelper::translate('Ramassage du colis'),
'arrival' => TNTOfficiel_ParcelsHelper::translate('Acheminement du colis'),
'deliveryDeparture' => TNTOfficiel_ParcelsHelper::translate('Livraison du colis en cours'),
'delivery' => TNTOfficiel_ParcelsHelper::translate('Livraison du colis'),
);
return isset($labels[$state]) ? $labels[$state] : '';
}
/**
* Save the PDL.
*
* @param $data
* @param $parcelId
*
* @return bool
*/
protected function _savePdl($data, $parcelId)
{
TNTOfficiel_Debug::log(array('msg' => '>>', 'file' => __FILE__, 'line' => __LINE__));
$result = false;
$pdl = $this->_getPdl($data);
if ($pdl) {
$result = Db::getInstance()->update('tntofficiel_order_parcels', array('pdl' => pSQL($pdl)), 'id_parcel = '.(int)$parcelId);
}
return $result;
}
/**
* Get POD Url from parcel data.
*
* @param $data
*
* @return bool|string
*/
protected function _getPdl($data)
{
TNTOfficiel_Debug::log(array('msg' => '>>', 'file' => __FILE__, 'line' => __LINE__));
$data = (array)$data;
return isset($data['primaryPODUrl']) && $data['primaryPODUrl'] ? $data['primaryPODUrl'] :
(isset($data['secondaryPODUrl']) && $data['secondaryPODUrl'] ? $data['secondaryPODUrl'] : false);
}
/**
* get translation.
*
* @param $string
*
* @return string
*/
public static function translate($string)
{
TNTOfficiel_Debug::log(array('msg' => '>>', 'file' => __FILE__, 'line' => __LINE__));
// TODO
return Translate::getModuleTranslation(TNTOfficiel::MODULE_NAME, $string, 'parcelshelper');
}
}