chocolatdemariage/www/modules/tntofficiel/libraries/helper/TNTOfficiel_ParcelsHelper.php

493 lines
17 KiB
PHP
Raw Normal View History

2017-09-12 10:48:51 +02:00
<?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');
}
}