Files
bio-concept-pharma/web/modules/tntofficiel/classes/TNTOfficielCarrier.php
2019-11-17 19:14:07 +01:00

2051 lines
70 KiB
PHP

<?php
/**
* TNT OFFICIAL MODULE FOR PRESTASHOP
*
* @author GFI Informatique <www.gfi.world>
* @copyright 2016-2019 GFI Informatique, 2016-2019 TNT
* @license https://opensource.org/licenses/MIT MIT License
*/
require_once _PS_MODULE_DIR_.'tntofficiel/libraries/TNTOfficiel_ClassLoader.php';
/**
* Class TNTOfficielCarrier
*/
class TNTOfficielCarrier extends ObjectModel
{
// Hard to Reach Area.
const URL_HRA_JSON = 'http://www.citsupport.fr/fichiers/tnt-zda.json';
const URL_HRA_HELP = 'http://www.tnt.fr/zone-difficilement-accessible';
const PATH_HRA_JSON = '/libraries/data/hra/zipcode.json';
// id_tntofficiel_carrier
public $id;
/** @var int Carrier ID. */
public $id_carrier;
/** @var int Associated unique shop ID. */
public $id_shop;
/** @var int Account ID who create this carrier. */
public $id_account;
/** @var string Account Type. */
public $account_type;
/** @var string Carrier Type. */
public $carrier_type;
/** @var string Carrier Code 1. */
public $carrier_code1;
/** @var string Carrier Code 2 (optional). */
public $carrier_code2;
/** @var bool Is zones configuration enabled. */
public $zones_enabled;
/** @var bool Is zones cloning configuration enabled. */
public $zones_cloning_enabled;
/** @var string Serialized zones configuration. */
public $zones_config;
/** @var array Model definition. */
public static $definition = array(
'table' => 'tntofficiel_carrier',
'primary' => 'id_tntofficiel_carrier',
'fields' => array(
'id_carrier' => array(
'type' => ObjectModel::TYPE_INT,
'size' => 10,
'validate' => 'isUnsignedId',
'required' => true
),
'id_shop' => array(
'type' => ObjectModel::TYPE_INT,
'size' => 10,
'validate' => 'isUnsignedId',
),
'id_account' => array(
'type' => ObjectModel::TYPE_INT,
'size' => 10,
'validate' => 'isUnsignedId',
),
'account_type' => array(
'type' => ObjectModel::TYPE_STRING,
),
'carrier_type' => array(
'type' => ObjectModel::TYPE_STRING,
'size' => 16
),
'carrier_code1' => array(
'type' => ObjectModel::TYPE_STRING,
'size' => 1,
),
'carrier_code2' => array(
'type' => ObjectModel::TYPE_STRING,
'size' => 1,
),
'zones_enabled' => array(
'type' => ObjectModel::TYPE_BOOL,
'validate' => 'isBool'
),
'zones_cloning_enabled' => array(
'type' => ObjectModel::TYPE_BOOL,
'validate' => 'isBool'
),
'zones_config' => array(
'type' => ObjectModel::TYPE_STRING
),
),
);
/** @var array Carrier Type (AKA Receiver Type) list. */
public static $arrCarrierTypeList = array (
'ENTERPRISE',
'INDIVIDUAL',
'DROPOFFPOINT',
'DEPOT',
);
/** @var array White list using Account Type, Carrier Type (AKA Receiver Type) and Carrier Code. */
public static $arrWhiteList = array(
'*' => array(
'ENTERPRISE' => array(
'N' => true,
'A' => true,
'T' => true,
'M' => true,
'J' => true,
'P' => true
),
'DEPOT' => array(
'J' => true,
'P' => false
),
'DROPOFFPOINT' => array(
'JD' => true
),
'INDIVIDUAL' => array(
'AZ' => true,
'TZ' => true,
'MZ' => true,
'JZ' => true
)
),
'ALIMENT' => array(
'ENTERPRISE' => array(
'N' => false,
'A' => false,
'T' => false,
'M' => false,
'J' => false,
'P' => false
),
'DEPOT' => array(
'J' => false,
'P' => false
),
'DROPOFFPOINT' => array(
'JD' => false
),
'INDIVIDUAL' => array(
'AZ' => false,
'TZ' => false,
'MZ' => false,
'JZ' => false
)
),
'ASSU' => array(
'ENTERPRISE' => array(
'N' => false,
'A' => false,
'T' => false,
'M' => false,
'J' => false,
'P' => false
),
'DEPOT' => array(
'J' => false
),
'DROPOFFPOINT' => array(
'JD' => false
),
'INDIVIDUAL' => array(
'AZ' => false,
'TZ' => false,
'MZ' => false,
'JZ' => false
)
),
'RP' => array(
'ENTERPRISE' => array(
'AP' => true,
'TP' => true,
'MP' => true,
'JP' => true
),
'DEPOT' => array(
'JP' => true
)
),
'RP ALIMENT' => array(
'ENTERPRISE' => array(
'AP' => false,
'TP' => false,
'MP' => false,
'JP' => false
),
'DEPOT' => array(
'JP' => false
)
),
'RP ASSU' => array(
'ENTERPRISE' => array(
'AP' => false,
'TP' => false,
'MP' => false,
'JP' => false
),
'DEPOT' => array(
'JP' => false
)
),
'ESP' => array(
'ENTERPRISE' => array(
'AW' => true,
'TW' => true,
'MW' => true,
'JW' => true
),
'DEPOT' => array(
'JW' => true
)
),
'ESP ALIMENT' => array(
'ENTERPRISE' => array(
'AW' => false,
'TW' => false,
'MW' => false,
'JW' => false
),
'DEPOT' => array(
'JW' => false
)
),
'ESP ASSU' => array(
'ENTERPRISE' => array(
'AW' => false,
'TW' => false,
'MW' => false,
'JW' => false
),
'DEPOT' => array(
'JW' => false
)
),
'LPSE' => array(
'ENTERPRISE' => array(
'NE' => true,
'AE' => true,
'TE' => true,
'ME' => true,
'JE' => true,
'PE' => true
)
),
'FROID' => array(
'ENTERPRISE' => array(
'AF' => true,
'TF' => true,
'MF' => true,
'JF' => true
)
)
);
/** @var array Displayed informations on Front. */
private static $arrCarrierCodeInfos = array(
'*' => array(
'ENTERPRISE:N' => array(
'label' => '08:00 Express en entreprise',
'delay' => 'Livraison dès le lendemain de l\'expédition, avant 8 heures.',
'description' => 'Pour une livraison aux entreprises en France métropolitaine.<br />
Livraison en mains propres et contre signature dès le lendemain de l\'expédition de votre commande, avant 8 heures.',
),
'ENTERPRISE:A' => array(
'label' => '09:00 Express en entreprise',
'delay' => 'Livraison dès le lendemain de l\'expédition, avant 9 heures.',
'description' => 'Pour une livraison aux entreprises en France métropolitaine.<br />
Livraison en mains propres et contre signature dès le lendemain de l\'expédition de votre commande, avant 9 heures.',
),
'ENTERPRISE:T' => array(
'label' => '10:00 Express en entreprise',
'delay' => 'Livraison dès le lendemain de l\'expédition, avant 10 heures.',
'description' => 'Pour une livraison aux entreprises en France métropolitaine.<br />
Livraison en mains propres et contre signature dès le lendemain de l\'expédition de votre commande, avant 10 heures.',
),
'ENTERPRISE:M' => array(
'label' => '12:00 Express en entreprise',
'delay' => 'Livraison en entreprise dès le lendemain de l\'expédition, avant midi.',
'description' => 'Pour une livraison aux entreprises en France métropolitaine.<br />
Livraison en mains propres et contre signature dès le lendemain de l\'expédition de votre commande, avant midi.',
),
'ENTERPRISE:J' => array(
'label' => 'Express en entreprise',
'delay' => 'Livraison dès le lendemain de l\'expédition.',
'description' => 'Pour une livraison aux entreprises en France métropolitaine.<br />
Livraison en mains propres et contre signature dès le lendemain de l\'expédition de votre commande<small> <i><sup>(1)</sup></i></small>.',
'reference' => '<small><i><sup>(1)</sup> avant 13 heures ou en début d\'après-midi en zone rurale.</i></small>',
),
'ENTERPRISE:P' => array(
'label' => '18:00 Express en entreprise',
'delay' => 'Livraison dès le lendemain de l\'expédition, avant 18 heures.',
'description' => 'Pour une livraison aux entreprises en France métropolitaine.<br />
Livraison en mains propres et contre signature dès le lendemain de l\'expédition de votre commande, avant 18 heures.',
),
'INDIVIDUAL:A' => array(
'label' => '09:00 Express à domicile',
'delay' => 'Livraison dès le lendemain de l\'expédition, avant 9 heures.',
'description' => 'Pour une livraison à domicile en France métropolitaine.<br />
Livraison en mains propres et contre signature dès le lendemain de l\'expédition de votre commande, avant 9 heures.',
),
'INDIVIDUAL:T' => array(
'label' => '10:00 Express à domicile',
'delay' => 'Livraison dès le lendemain de l\'expédition, avant 10 heures.',
'description' => 'Pour une livraison à domicile en France métropolitaine.<br />
Livraison en mains propres et contre signature dès le lendemain de l\'expédition de votre commande, avant 10 heures.',
),
'INDIVIDUAL:M' => array(
'label' => '12:00 Express à domicile',
'delay' => 'Livraison dès le lendemain de l\'expédition, avant midi.',
'description' => 'Pour une livraison à domicile en France métropolitaine.<br />
Livraison en mains propres et contre signature dès le lendemain de l\'expédition de votre commande, avant midi.',
),
'INDIVIDUAL:J' => array(
'label' => 'Express à domicile',
'delay' => 'Livraison dès le lendemain de l\'expédition.',
'description' => 'Pour une livraison à domicile en France métropolitaine.<br />
Livraison en mains propres et contre signature dès le lendemain de l\'expédition de votre commande<small> <i><sup>(1)</sup></i></small>.',
'reference' => '<small><i><sup>(1)</sup> avant 13 heures ou en début d\'après-midi en zone rurale.</i></small>',
),
'DROPOFFPOINT:J' => array(
'label' => 'Express chez un commerçant partenaire',
'delay' => 'Livraison dès le lendemain de l\'expédition.',
'description' => 'Mise à disposition chez l\'un des 4500 commerçants partenaires en France métropolitaine.<br />
Remise contre signature et présentation d\'une pièce d\'identité dès le lendemain de l\'expédition de votre commande<small> <i><sup>(1)</sup></i></small>.',
'reference' => '<small><i><sup>(1)</sup> avant 13 heures ou en début d\'après-midi en zone rurale.</i></small>',
),
'DEPOT:J' => array(
'label' => 'Express en agence TNT',
'delay' => 'Livraison dès 8 heures le lendemain de l\'expédition. Mise à votre disposition pendant 10 Jours.',
'description' => 'Pour une livraison dans une de nos agences TNT en France métropolitaine.<br />
Mise à votre disposition sur présentation d\'une pièce d\'identité et contre signature dès 8 heures le lendemain de l\'expédition de votre commande et ce pendant 10 Jours.',
)
)
);
/** @var array Displayed informations on Front (optional). */
public static $arrCarrierTypeInfos = array(
// https://www.tnt.com/express/fr_fr/site/home/comment-expedier/services-livraison/services-complementaires/livraison-avec-paiement.html
'RP' => 'Colis remis contre un règlement par chèque.',
// https://www.tnt.com/express/fr_fr/site/home/comment-expedier/services-livraison/services-complementaires/livraison-sous-protection.html
'ESP' => 'Marchandises sensibles expédiées avec une sûreté renforcée du ramassage jusqu\'à la livraison.',
'FROID' => 'En cas d\'instance de votre colis, un traitement opérationnel spécifique prévoit sa mise en chambre froide.',
'LPSE' => 'En cas d\'absence, livraison possible sans émargement'
);
/** @var Cache and prevent race condition. */
private static $arrLoadedEntities = array();
/**
* Creates the tables needed by the model.
*
* @return bool
*/
public static function createTables()
{
TNTOfficiel_Logstack::log();
$strLogMessage = sprintf('%s::%s', __CLASS__, __FUNCTION__);
$strTablePrefix = _DB_PREFIX_;
$strTableEngine = _MYSQL_ENGINE_;
$strTableName = $strTablePrefix.TNTOfficielCarrier::$definition['table'];
// Create table.
$strSQLCreateCarrier = <<<SQL
CREATE TABLE IF NOT EXISTS `${strTableName}` (
`id_tntofficiel_carrier` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
`id_carrier` INT(10) UNSIGNED NOT NULL,
`id_shop` INT(10) UNSIGNED NOT NULL,
`id_account` INT(10) UNSIGNED NOT NULL,
`account_type` VARCHAR(50) NULL DEFAULT NULL,
`carrier_type` VARCHAR(16) NOT NULL,
`carrier_code1` VARCHAR(1) NOT NULL,
`carrier_code2` VARCHAR(1) NOT NULL,
`zones_enabled` TINYINT(1) UNSIGNED NOT NULL DEFAULT '1',
`zones_cloning_enabled` TINYINT(1) UNSIGNED NOT NULL DEFAULT '0',
`zones_config` TEXT NULL,
-- Key.
PRIMARY KEY (`id_tntofficiel_carrier`),
UNIQUE INDEX `id_carrier` (`id_carrier`)
) ENGINE = ${strTableEngine} DEFAULT CHARSET='utf8' COLLATE='utf8_general_ci';
SQL;
$objDB = Db::getInstance();
if (!$objDB->execute($strSQLCreateCarrier)) {
TNTOfficiel_Logger::logInstall($strLogMessage.' : '.$objDB->getMsgError(), false);
return false;
}
TNTOfficiel_Logger::logInstall($strLogMessage);
return true;
}
/**
* Constructor.
*/
public function __construct($intArgId = null, $intArgLangId = null)
{
TNTOfficiel_Logstack::log();
parent::__construct($intArgId, $intArgLangId);
}
/**
* Load existing object model or optionally create a new one for it's ID.
*
* @param $intArgCarrierID
* @param bool $boolArgCreate
* @param null $intArgLangID
*
* @return mixed|null|TNTOfficielCarrier
*/
public static function loadCarrierID($intArgCarrierID, $boolArgCreate = false, $intArgLangID = null)
{
TNTOfficiel_Logstack::log();
$intCarrierID = (int)$intArgCarrierID;
// An existing Carrier ID is required (to load or create).
if (!($intCarrierID > 0)) {
return null;
}
$strEntityID = '_'.$intCarrierID.'-'.(int)$intArgLangID.'-'.(int)null;
// If already loaded.
if (array_key_exists($strEntityID, TNTOfficielCarrier::$arrLoadedEntities)) {
$objTNTCarrierModel = TNTOfficielCarrier::$arrLoadedEntities[$strEntityID];
// Check.
if ((int)$objTNTCarrierModel->id_carrier === $intCarrierID
&& Validate::isLoadedObject($objTNTCarrierModel)
) {
return $objTNTCarrierModel;
}
}
// Search row for carrier ID.
$objDbQuery = new DbQuery();
$objDbQuery->select('*');
$objDbQuery->from(TNTOfficielCarrier::$definition['table']);
$objDbQuery->where('id_carrier = '.$intCarrierID);
$objDB = Db::getInstance();
$arrResult = $objDB->executeS($objDbQuery);
// If row found and match carrier ID.
if (count($arrResult) === 1 && $intCarrierID === (int)$arrResult[0]['id_carrier']) {
// Load existing TNT carrier entry.
$objTNTCarrierModel = new TNTOfficielCarrier((int)$arrResult[0]['id_tntofficiel_carrier'], $intArgLangID);
} elseif ($boolArgCreate === true) {
// Create a new TNT carrier entry.
$objTNTCarrierModelCreate = new TNTOfficielCarrier(null, $intArgLangID);
$objTNTCarrierModelCreate->id_carrier = $intCarrierID;
// init zonesEnabled by default is true
$objTNTCarrierModelCreate->setZonesEnabled(1);
$objTNTCarrierModelCreate->save();
// Reload to get default DB values after creation.
$objTNTCarrierModel = TNTOfficielCarrier::loadCarrierID($intCarrierID, false, $intArgLangID);
} else {
// Log only for TNT carrier.
if (TNTOfficielCarrier::isTNTOfficielCarrierID($intCarrierID)) {
$objException = new Exception('TNTOfficielCarrier not found for Carrier ID #'.$intCarrierID);
TNTOfficiel_Logger::logException($objException);
}
return null;
}
// Check.
if ((int)$objTNTCarrierModel->id_carrier !== $intCarrierID || !Validate::isLoadedObject($objTNTCarrierModel)) {
return null;
}
$objTNTCarrierModel->id = (int)$objTNTCarrierModel->id;
$objTNTCarrierModel->id_carrier = (int)$objTNTCarrierModel->id_carrier;
$objTNTCarrierModel->id_shop = (int)$objTNTCarrierModel->id_shop;
$objTNTCarrierModel->id_account = (int)$objTNTCarrierModel->id_account;
TNTOfficielCarrier::$arrLoadedEntities[$strEntityID] = $objTNTCarrierModel;
return $objTNTCarrierModel;
}
public static function isWhiteListed(
$strArgAccountType,
$strArgCarrierType,
$strArgCarrierCode1,
$strArgCarrierCode2
) {
TNTOfficiel_Logstack::log();
$strAccountType = (($strArgAccountType === '') ? '*' : $strArgAccountType);
return (array_key_exists($strAccountType, TNTOfficielCarrier::$arrWhiteList)
&& is_array(TNTOfficielCarrier::$arrWhiteList[$strAccountType])
&& array_key_exists($strArgCarrierType, TNTOfficielCarrier::$arrWhiteList[$strAccountType])
&& is_array(TNTOfficielCarrier::$arrWhiteList[$strAccountType][$strArgCarrierType])
&& array_key_exists(
$strArgCarrierCode1.$strArgCarrierCode2,
TNTOfficielCarrier::$arrWhiteList[$strAccountType][$strArgCarrierType]
)
&& TNTOfficielCarrier::$arrWhiteList[$strAccountType][$strArgCarrierType][
$strArgCarrierCode1.$strArgCarrierCode2
] === true
);
}
/**
* Load a Prestashop Carrier object from id.
*
* @param int $intArgCarrierID
*
* @return Carrier|null
*/
public static function getPSCarrier($intArgCarrierID)
{
TNTOfficiel_Logstack::log();
// Carrier ID must be an integer greater than 0.
if (empty($intArgCarrierID) || $intArgCarrierID != (int)$intArgCarrierID || !((int)$intArgCarrierID > 0)) {
return null;
}
$intCarrierID = (int)$intArgCarrierID;
// Load carrier.
$objPSCarrier = new Carrier($intCarrierID);
// If carrier object not available.
if (!(Validate::isLoadedObject($objPSCarrier) && (int)$objPSCarrier->id === $intCarrierID)) {
return null;
}
return $objPSCarrier;
}
/**
* Check if a Prestashop carrier ID is a TNTOfficel module one.
*
* @param int $intArgCarrierID
*
* @return boolean
*/
public static function isTNTOfficielCarrierID($intArgCarrierID)
{
TNTOfficiel_Logstack::log();
$objPSCarrier = TNTOfficielCarrier::getPSCarrier($intArgCarrierID);
// If carrier object not available.
if ($objPSCarrier === null) {
return false;
}
return $objPSCarrier->external_module_name === TNTOfficiel::MODULE_NAME;
}
/**
* Get the carrier Account model.
*
* @return TNTOfficielAccount|null
*/
public function getTNTAccountModel()
{
TNTOfficiel_Logstack::log();
return TNTOfficielAccount::loadAccountID($this->id_account);
}
/**
* Get the Shop associated with this carrier.
*
* @return int|null
*/
public function getPSShop()
{
TNTOfficiel_Logstack::log();
$intShopID = (int)$this->id_shop;
$objPSShop = new Shop($intShopID);
if (!Validate::isLoadedObject($objPSShop)
|| (int)$objPSShop->id !== $intShopID
) {
return null;
}
return $objPSShop;
}
/**
* Check if a non deleted carrier is already existing for a shop.
*
* @param int $intArgShopID
* @param string $strArgAccountType
* @param string $strArgCarrierType
* @param string $strArgCarrierCode1
* @param string $strArgCarrierCode2
*
* @return bool
*/
public static function isExist(
$intArgShopID,
$strArgAccountType,
$strArgCarrierType,
$strArgCarrierCode1,
$strArgCarrierCode2
) {
TNTOfficiel_Logstack::log();
$arrObjTNTCarrierModelList = array();
// Search row.
$objDbQuery = new DbQuery();
$objDbQuery->select('*');
$objDbQuery->from(TNTOfficielCarrier::$definition['table'], 't');
$objDbQuery->where('id_shop = '.$intArgShopID);
$objDbQuery->where('account_type = \''.pSQL($strArgAccountType).'\'');
$objDbQuery->where('carrier_type = \''.pSQL($strArgCarrierType).'\'');
$objDbQuery->where('carrier_code1 = \''.pSQL($strArgCarrierCode1).'\'');
$objDbQuery->where('carrier_code2 = \''.pSQL($strArgCarrierCode2).'\'');
/*
$objDbQuery->innerJoin(
'carrier', 'c'
, 't.id_carrier = c.id_carrier AND c.deleted = 0'
);
*/
$objDB = Db::getInstance();
$arrResult = $objDB->executeS($objDbQuery);
// If row found and match accound ID.
if (count($arrResult) > 0) {
foreach ($arrResult as $arrValue) {
$intCarrierID = (int)$arrValue['id_carrier'];
$objTNTCarrierModel = TNTOfficielCarrier::loadCarrierID($intCarrierID, false);
// If
if ($objTNTCarrierModel !== null) {
$objPSCarrier = TNTOfficielCarrier::getPSCarrier($intCarrierID);
// If carrier object available and not deleted.
if ($objPSCarrier !== null && !$objPSCarrier->deleted) {
$arrObjTNTCarrierModelList[(int)$objTNTCarrierModel->id_carrier] = $objTNTCarrierModel;
}
}
}
}
return count($arrObjTNTCarrierModelList) > 0;
}
/**
* Get the Prestashop Carrier name.
*
* @return string
*/
public function getName()
{
TNTOfficiel_Logstack::log();
$objPSCarrier = TNTOfficielCarrier::getPSCarrier($this->id_carrier);
// If carrier object not available.
if ($objPSCarrier === null) {
return 'N/A';
}
return $objPSCarrier->name;
}
/**
* Get carrier label.
*
* @return stdClass|null
*/
public static function getCarrierLabel($strArgAccountType, $strArgCarrierType, $strArgCarrierCode1)
{
TNTOfficiel_Logstack::log();
$strCarrierLabel = null;
$strCarrierKey = $strArgCarrierType.':'.$strArgCarrierCode1;
$arrCarrierCodeInfos = TNTOfficielCarrier::$arrCarrierCodeInfos['*'];
if (array_key_exists($strArgAccountType, TNTOfficielCarrier::$arrCarrierCodeInfos)) {
$arrCarrierCodeInfos = TNTOfficielCarrier::$arrCarrierCodeInfos[$strArgAccountType];
}
if (array_key_exists($strCarrierKey, $arrCarrierCodeInfos)) {
$strCarrierLabel = $arrCarrierCodeInfos[$strCarrierKey]['label'];
if ($strArgAccountType !== '*') {
$strCarrierLabel .= ' ('.$strArgAccountType.')';
}
}
return $strCarrierLabel;
}
/**
* Get carrier information.
*
* @return stdClass|null
*/
public function getCarrierInfos()
{
TNTOfficiel_Logstack::log();
$objCarrierInfos = null;
$strCarrierKey = $this->carrier_type.':'.$this->carrier_code1;
$arrCarrierCodeInfos = TNTOfficielCarrier::$arrCarrierCodeInfos['*'];
if (array_key_exists($this->account_type, TNTOfficielCarrier::$arrCarrierCodeInfos)) {
$arrCarrierCodeInfos = TNTOfficielCarrier::$arrCarrierCodeInfos[$this->account_type];
}
if (array_key_exists($strCarrierKey, $arrCarrierCodeInfos)) {
$objCarrierInfos = (object)$arrCarrierCodeInfos[$strCarrierKey];
$objCarrierInfos->label = TNTOfficielCarrier::getCarrierLabel(
$this->account_type,
$this->carrier_type,
$this->carrier_code1
);
if (array_key_exists($this->account_type, TNTOfficielCarrier::$arrCarrierTypeInfos)) {
$objCarrierInfos->description2 = TNTOfficielCarrier::$arrCarrierTypeInfos[$this->account_type];
}
}
return $objCarrierInfos;
}
/**
* Get the account type using carrier info from feasibility.
*
* @param string $strArgCarrierType
* @param string $strArgCarrierCode2
* @param string $strArgCarrierLabel
*
* @return string ['*', 'ALIMENT', 'ASSU', 'RP', 'RP ALIMENT', 'RP ASSU',
* 'ESP', 'ESP ALIMENT', 'ESP ASSU', 'LPSE', 'FROID']
*/
public static function getAccountType($strArgCarrierType, $strArgCarrierCode2, $strArgCarrierLabel)
{
TNTOfficiel_Logstack::log();
$strAccountType = '*';
$arrAccountType = array();
if ($strArgCarrierCode2 === 'P') {
$arrAccountType[] = 'RP';
} elseif ($strArgCarrierCode2 === 'W') {
$arrAccountType[] = 'ESP';
} elseif ($strArgCarrierCode2 === 'D') {
// Commerçants Partenaires.
//$arrAccountType[] = 'DROPOFFPOINT';
} elseif ($strArgCarrierCode2 === 'Z') {
//$arrAccountType[] = 'A Domicile';
} elseif ($strArgCarrierCode2 === 'E') {
$arrAccountType[] = 'LPSE';
}
// Aliment may not be detected.
if (preg_match('/\bALIMENT\b/ui', $strArgCarrierLabel) === 1) {
$arrAccountType[] = 'ALIMENT';
}
if (preg_match('/\bFROID\b/ui', $strArgCarrierLabel) === 1) {
$arrAccountType[] = 'FROID';
}
if (preg_match('/\bASSU\b/ui', $strArgCarrierLabel) === 1) {
$arrAccountType[] = 'ASSU';
}
if ($strArgCarrierType === 'DEPOT') {
// Agences TNT.
//$arrAccountType[] = 'DEPOT';
}
if (count($arrAccountType) > 0) {
$strAccountType = implode(' ', $arrAccountType);
}
return $strAccountType;
}
/**
* Modify a current TNT carrier ID to a new one.
*
* @param int $intArgCarrierOldID
* @param int $intArgCarrierNewID
*
* @return bool
*/
public static function updateCarrierID($intArgCarrierOldID, $intArgCarrierNewID)
{
TNTOfficiel_Logstack::log();
// Load the carrier ID.
$objTNTCarrierModelOld = TNTOfficielCarrier::loadCarrierID($intArgCarrierOldID, false);
// If fail or unexist.
if ($objTNTCarrierModelOld === null) {
return false;
}
// Create a new model for copy.
$objTNTCarrierModel = TNTOfficielCarrier::loadCarrierID($intArgCarrierNewID, true);
// If fail.
if ($objTNTCarrierModel === null) {
return false;
}
// Copy.
$objTNTCarrierModel->id_shop = $objTNTCarrierModelOld->id_shop;
$objTNTCarrierModel->id_account = $objTNTCarrierModelOld->id_account;
$objTNTCarrierModel->account_type = $objTNTCarrierModelOld->account_type;
$objTNTCarrierModel->carrier_type = $objTNTCarrierModelOld->carrier_type;
$objTNTCarrierModel->carrier_code1 = $objTNTCarrierModelOld->carrier_code1;
$objTNTCarrierModel->carrier_code2 = $objTNTCarrierModelOld->carrier_code2;
$objTNTCarrierModel->zones_enabled = $objTNTCarrierModelOld->zones_enabled;
$objTNTCarrierModel->zones_cloning_enabled = $objTNTCarrierModelOld->zones_cloning_enabled;
$objTNTCarrierModel->zones_config = $objTNTCarrierModelOld->zones_config;
return $objTNTCarrierModel->save();
}
/**
* Search for a list of non deleted existing carrier object model, associated to a shop context.
*
* @param float $fltArgHeaviestProduct filter result using the heaviest product weight.
* @param bool $boolArgIsReceiverB2B filter result as B2B (true) or B2C (false). null for no filter.
*
* @return array list of TNTOfficielCarrier model found.
*/
public static function getContextCarrierModelList(
$fltArgHeaviestProduct = 0.0,
$boolArgIsReceiverB2B = null
) {
TNTOfficiel_Logstack::log();
$fltHeaviestProduct = (float)$fltArgHeaviestProduct;
$arrObjTNTCarrierModelList = array();
$arrArgIntShopIDList = Shop::getContextListShopID();
$arrIntShopIDList = array_map('intval', $arrArgIntShopIDList);
try {
// Search row for account ID.
$objDbQuery = new DbQuery();
$objDbQuery->select('*');
$objDbQuery->from(TNTOfficielCarrier::$definition['table'], 't');
$objDbQuery->where('id_shop IN ('.implode(',', $arrIntShopIDList).')');
/*
$objDbQuery->innerJoin(
'carrier', 'c'
, 't.id_carrier = c.id_carrier AND c.deleted = 0'
);
*/
$objDB = Db::getInstance();
$arrResult = $objDB->executeS($objDbQuery);
// If row found and match accound ID.
if (count($arrResult) > 0) {
foreach ($arrResult as $arrValue) {
$intCarrierID = (int)$arrValue['id_carrier'];
$objTNTCarrierModel = TNTOfficielCarrier::loadCarrierID($intCarrierID, false);
// If
if ($objTNTCarrierModel !== null) {
$objPSCarrier = TNTOfficielCarrier::getPSCarrier($intCarrierID);
// If Carrier object available and not deleted.
if ($objPSCarrier !== null
&& !$objPSCarrier->deleted
// Filter using receiver type (B2B, B2C or unknown).
&& $objTNTCarrierModel->isAvailableForReceiverType($boolArgIsReceiverB2B)
// Filter using heaviest product weight (against package maximum weight).
&& $objTNTCarrierModel->isAvailableForProductWeight($fltHeaviestProduct)
) {
$arrObjTNTCarrierModelList[$objTNTCarrierModel->id_carrier] = $objTNTCarrierModel;
}
}
}
}
} catch (Exception $objException) {
TNTOfficiel_Logger::logException($objException);
}
return $arrObjTNTCarrierModelList;
}
/**
* Get the list of carrier object model, through feasibility webservice.
*
* @param float $fltArgHeaviestProduct
* @param int $intArgAddressIDDelivery
*
* @return array
*/
public static function getFeasibilitiesContextCarrierModelList(
$fltArgHeaviestProduct = 0.0,
$intArgAddressIDDelivery = null
) {
TNTOfficiel_Logstack::log();
$fltHeaviestProduct = (float)$fltArgHeaviestProduct;
$arrResult = array();
// A delivery address is optional.
$objPSAddressDelivery = TNTOfficielReceiver::getPSAddress($intArgAddressIDDelivery);
// If delivery address object is available.
if ($objPSAddressDelivery !== null) {
$boolIsReceiverB2B = !!$objPSAddressDelivery->company;
$strCountryISO = Country::getIsoById((int)$objPSAddressDelivery->id_country);
$strReceiverZipCode = $objPSAddressDelivery->postcode;
$strReceiverCity = $objPSAddressDelivery->city;
$arrObjTNTCarrierModelList = TNTOfficielCarrier::getContextCarrierModelList(
$fltHeaviestProduct,
$boolIsReceiverB2B
);
// Adding matching carriers with feasibilities.
foreach ($arrObjTNTCarrierModelList as $intCarrierID => $objTNTCarrierModel) {
$objTNTCarrierAccountModel = $objTNTCarrierModel->getTNTAccountModel();
if ($objTNTCarrierAccountModel === null) {
continue;
}
// Get cities from the webservice from the given postal code.
$arrResultCitiesGuide = $objTNTCarrierAccountModel->citiesGuide(
$strCountryISO,
$strReceiverZipCode,
$strReceiverCity
);
// If the country is not supported
// or the city does not match the postcode for the delivery address (without communication error).
if (!$arrResultCitiesGuide['boolIsCountrySupported']
|| (!$arrResultCitiesGuide['boolIsRequestComError']
&& !$arrResultCitiesGuide['boolIsCityNameValid']
)) {
continue;
}
$arrTNTServiceList = $objTNTCarrierAccountModel->feasibilities(
$strReceiverZipCode,
$strReceiverCity,
array($objTNTCarrierModel->carrier_type)
);
foreach ($arrTNTServiceList as $arrTNTService) {
if ($objTNTCarrierModel->account_type === $arrTNTService['accountType']
&& $objTNTCarrierModel->carrier_type === $arrTNTService['carrierType']
&& $objTNTCarrierModel->carrier_code1 === $arrTNTService['carrierCode1']
&& $objTNTCarrierModel->carrier_code2 === $arrTNTService['carrierCode2']
) {
$arrResult[$intCarrierID] = $objTNTCarrierModel;
}
}
}
} else {
// If there is no delivery address, use all carriers.
$arrResult = TNTOfficielCarrier::getContextCarrierModelList($fltHeaviestProduct);
}
return $arrResult;
}
/**
* Force all current carrier settings.
*
* @return bool
*/
public static function forceAllCarrierDefaultValues()
{
TNTOfficiel_Logstack::log();
$boolResult = true;
$arrObjTNTCarrierModelList = TNTOfficielCarrier::getContextCarrierModelList();
foreach ($arrObjTNTCarrierModelList as /*$intCarrierID =>*/ $objTNTCarrierModel) {
$boolResult = $objTNTCarrierModel->forceCarrierDefaultValues() && $boolResult;
}
TNTOfficielCarrier::autoClean();
return $boolResult;
}
/**
* Force a current carrier settings.
*
* @param string $strArgCarrierCode
*
* @return bool
*/
public function forceCarrierDefaultValues()
{
TNTOfficiel_Logstack::log();
$this->forceAssoUniqueShop();
//$this->forceAssoExcludeGroup();
return true;
}
/**
* Force the groups exclusion.
*
* @return boolean
*/
protected function forceAssoExcludeGroup()
{
TNTOfficiel_Logstack::log();
// Users groups to exclude.
$arrCarrierGroupExcludeConfigList = array(
//'PS_UNIDENTIFIED_GROUP',
//'PS_GUEST_GROUP'
);
$objPSCarrier = TNTOfficielCarrier::getPSCarrier($this->id_carrier);
// If Carrier object available.
if ($objPSCarrier !== null) {
// Get all users groups associated with the TNT carrier.
$arrCarrierGroups = $objPSCarrier->getGroups();
// If there is currently at least one users groups set.
if (is_array($arrCarrierGroups) && count($arrCarrierGroups) > 0) {
// Current users groups set.
$arrCarrierGroupSetIDList = array();
foreach ($arrCarrierGroups as $arrRowCarrierGroup) {
// DB request fail. stop here.
if (!array_key_exists('id_group', $arrRowCarrierGroup)) {
return false;
}
$arrCarrierGroupSetIDList[] = (int)$arrRowCarrierGroup['id_group'];
}
// Get users groups ID list to exclude.
$arrCarrierGroupExcludeIDList = array();
foreach ($arrCarrierGroupExcludeConfigList as $strGroupExcludeConfig) {
$arrCarrierGroupExcludeIDList[] = (int)Configuration::get($strGroupExcludeConfig);
}
// Get groups previously set, minus groups to exclude.
$arrCarrierGroupsApply = array_diff($arrCarrierGroupSetIDList, $arrCarrierGroupExcludeIDList);
// If groups change.
if (count(array_diff($arrCarrierGroupSetIDList, $arrCarrierGroupsApply)) > 0) {
// Force carrier users groups (delete all, then set).
$objPSCarrier->setGroups($arrCarrierGroupsApply, true);
}
}
}
return true;
}
/**
* Force the shop associations to an unique one.
*
* @return bool|void
*/
protected function forceAssoUniqueShop()
{
TNTOfficiel_Logstack::log();
$objContext = Context::getContext();
if (!property_exists($objContext, 'employee') || !$objContext->employee) {
return false;
}
if (!Shop::isFeatureActive()) {
return false;
}
if (!Shop::isTableAssociated('carrier')) {
return false;
}
$intTNTCarrierID = (int)$this->id_carrier;
$objDB = Db::getInstance();
/*
* Check current shop association.
*/
$arrCarrierAssoCurrentShopIDList = array();
$strSQLSelectCarrierAssoCurrentShopIDList
= 'SELECT id_shop FROM `'._DB_PREFIX_.'carrier_shop` WHERE `id_carrier` = '.$intTNTCarrierID;
$arrSQLResultCarrierAssoCurrentShopIDList = $objDB->executeS($strSQLSelectCarrierAssoCurrentShopIDList);
foreach ($arrSQLResultCarrierAssoCurrentShopIDList as $arrRowAssoCurrentShop) {
$arrCarrierAssoCurrentShopIDList[] = (int)$arrRowAssoCurrentShop['id_shop'];
}
// If no change needed.
if (count($arrCarrierAssoCurrentShopIDList) === 1
&& in_array($intTNTCarrierID, $arrCarrierAssoCurrentShopIDList, true)
) {
return false;
}
$arrCarrierAssoForcedShopIDList = array(
(int)$this->id_shop
);
// Get list of shop id we want to exclude from asso deletion
$arrExcludeShopIDList = $arrCarrierAssoForcedShopIDList;
// Exclude employee unauthorized shop ID for the carrier.
$strSQLSelectAllShopIDList = 'SELECT id_shop FROM '._DB_PREFIX_.'shop';
$arrSQLResultAllShopIDList = $objDB->executeS($strSQLSelectAllShopIDList);
foreach ($arrSQLResultAllShopIDList as $arrRowShop) {
if (!$objContext->employee->hasAuthOnShop($arrRowShop['id_shop'])) {
$arrExcludeShopIDList[] = (int)$arrRowShop['id_shop'];
}
}
// Delete shop ID list for the carrier.
$objDB->delete(
'carrier_shop',
'`id_carrier` = '.(int)$intTNTCarrierID
.($arrExcludeShopIDList ? ' AND id_shop NOT IN ('.implode(',', $arrExcludeShopIDList).')' : '')
);
$arrRowInsertCarrierAssoForcedShopIDList = array();
foreach ($arrCarrierAssoForcedShopIDList as $intForcedShopID) {
$arrRowInsertCarrierAssoForcedShopIDList[] = array(
'id_carrier' => (int)$intTNTCarrierID,
'id_shop' => (int)$intForcedShopID,
);
}
return $objDB->insert('carrier_shop', $arrRowInsertCarrierAssoForcedShopIDList, false, true, Db::INSERT_IGNORE);
}
/**
* Auto delete unused TNT carrier.
*/
public static function autoClean()
{
TNTOfficiel_Logstack::log();
$arrAllCarrier = Carrier::getCarriers(
//(int)$this->context->language->id,
(int)Configuration::get('PS_LANG_DEFAULT'),
false,
false,
false,
null,
Carrier::CARRIERS_MODULE
);
foreach ($arrAllCarrier as $arrCarrier) {
$intCarrierID = (int)$arrCarrier['id_carrier'];
// If Carrier is TNT Carrier.
if (TNTOfficielCarrier::isTNTOfficielCarrierID($intCarrierID)) {
$objPSCarrier = TNTOfficielCarrier::getPSCarrier($intCarrierID);
// If Carrier object available.
if ($objPSCarrier !== null) {
$objTNTCarrierModel = TNTOfficielCarrier::loadCarrierID($intCarrierID, false);
// If TNT carrier model does not exist.
if ($objTNTCarrierModel === null) {
// Delete carrier.
$objPSCarrier->active = false;
$objPSCarrier->deleted = true;
$objPSCarrier->save();
} else {
$objTNTCarrierAccountModel = $objTNTCarrierModel->getTNTAccountModel();
// If no TNT account or account is deleted.
if ($objTNTCarrierAccountModel === null
|| $objTNTCarrierAccountModel->deleted
) {
$objPSCarrier->active = false;
$objPSCarrier->deleted = true;
$objPSCarrier->save();
}
}
}
}
}
}
/**
* Is carrier available for a product weight.
*
* @param float $fltArgHeaviestProduct the heaviest product weight.
*
* @return bool
*/
public function isAvailableForProductWeight($fltArgHeaviestProduct = 0.0)
{
TNTOfficiel_Logstack::log();
$fltHeaviestProduct = (float)$fltArgHeaviestProduct;
// Filter Weight : If heaviest product is in B2C range (less or equal to 20 kg)
// or in B2B range (greater than 20 kg and less or equal to 30 kg) with B2B option.
return ($fltHeaviestProduct <= $this->getMaxPackageWeight());
}
/**
* Is carrier available for a receiver.
*
* @param bool $boolArgIsReceiverB2B true for B2B, false for B2C, null for unknown.
*
* @return bool
*/
public function isAvailableForReceiverType($boolArgIsReceiverB2B = null)
{
TNTOfficiel_Logstack::log();
// Filter B2B/B2C : If receiver business type is unknown,
// or receiver and carrier are B2B, or receiver and carrier are B2C.
return ($boolArgIsReceiverB2B === null
|| (in_array($this->carrier_type, array('DROPOFFPOINT', 'DEPOT')))
|| ($boolArgIsReceiverB2B === true && $this->carrier_type === 'ENTERPRISE')
|| ($boolArgIsReceiverB2B === false && $this->carrier_type === 'INDIVIDUAL')
);
}
/**
* Get the maximum package weight.
*
* @return float
*/
public function getMaxPackageWeight()
{
TNTOfficiel_Logstack::log();
if (in_array($this->carrier_type, array('ENTERPRISE', 'DEPOT'))) {
return 30.0;
}
// INDIVIDUAL, DROPOFFPOINT.
return 20.0;
}
/**
* Update the hard to reach areas zipcode list.
*
* @return boolean
*/
public static function updateHRAZipCodeList()
{
TNTOfficiel_Logstack::log();
$strFileLocation = _PS_MODULE_DIR_.TNTOfficiel::MODULE_NAME.TNTOfficielCarrier::PATH_HRA_JSON;
$arrResult = TNTOfficiel_Tools::cURLRequest(
TNTOfficielCarrier::URL_HRA_JSON,
array(
CURLOPT_HTTPHEADER => array(
'User-Agent: PHP/cURL',
'Accept: application/json',
'Connection: close',
),
)
);
$arrResponse = Tools::jsonDecode($arrResult['response'], true);
if (is_array($arrResponse) && array_key_exists('default', $arrResponse)) {
return file_put_contents($strFileLocation, $arrResult['response']) > 0;
}
return false;
}
/**
* Get the hard to reach areas zipcode list, if it was downloaded.
*
* @return array|null null if file unexist.
*/
public static function getHRAZipCodeList()
{
TNTOfficiel_Logstack::log();
$strFileLocation = _PS_MODULE_DIR_.TNTOfficiel::MODULE_NAME.TNTOfficielCarrier::PATH_HRA_JSON;
if (file_exists($strFileLocation)) {
$strFileContent = Tools::file_get_contents($strFileLocation);
if ($strFileContent !== false) {
$arrFileContent = Tools::jsonDecode($strFileContent, true);
if (array_key_exists('default', $arrFileContent)) {
return $arrFileContent['default'];
}
}
}
return null;
}
/**
* Check if a zipcode match the hard to reach areas.
*
* @param type $strArgZipCode
*
* @return type
*/
public static function isAnHRAZipCode($strArgZipCode)
{
TNTOfficiel_Logstack::log();
$arrHRAZipcodeList = TNTOfficielCarrier::getHRAZipCodeList();
return is_array($arrHRAZipcodeList) && in_array($strArgZipCode, $arrHRAZipcodeList, true);
}
/**
* Get list including estimated delivery date.
*
* @param string $strArgReceiverZipCode
* @param string $strArgReceiverCity
*
* @return string|null
*/
public function feasibilities($strArgReceiverZipCode, $strArgReceiverCity)
{
TNTOfficiel_Logstack::log();
$objTNTCarrierAccountModel = $this->getTNTAccountModel();
// If no account available for this carrier.
if ($objTNTCarrierAccountModel === null) {
return null;
}
$arrTNTServiceList = $objTNTCarrierAccountModel->feasibilities(
$strArgReceiverZipCode,
$strArgReceiverCity,
array($this->carrier_type)
);
$arrFeasibilitiesList = array();
foreach ($arrTNTServiceList as $arrTNTService) {
if ($this->account_type === $arrTNTService['accountType']
&& $this->carrier_type === $arrTNTService['carrierType']
&& $this->carrier_code1 === $arrTNTService['carrierCode1']
&& $this->carrier_code2 === $arrTNTService['carrierCode2']
) {
$arrFeasibilitiesList[] = array(
'shippingDate' => $arrTNTService['shippingDate'],
'dueDate' => $arrTNTService['dueDate'],
'saturdayDelivery' => (bool)$arrTNTService['saturdayDelivery'],
'afternoonDelivery' => (bool)$arrTNTService['afternoonDelivery'],
'insurance' => (bool)$arrTNTService['insurance'],
'priorityGuarantee' => (bool)$arrTNTService['priorityGuarantee']
);
}
}
return $arrFeasibilitiesList;
}
/**
* Get the estimated delivery date.
*
* @param string $strArgReceiverZipCode
* @param string $strArgReceiverCity
*
* @return array|null
*/
public function feasibility(
$strArgReceiverZipCode,
$strArgReceiverCity,
$strArgShippingDate = null
) {
TNTOfficiel_Logstack::log();
$objTNTCarrierAccountModel = $this->getTNTAccountModel();
// If no account available for this carrier.
if ($objTNTCarrierAccountModel === null) {
return null;
}
$arrTNTServiceList = $objTNTCarrierAccountModel->feasibility(
$strArgReceiverZipCode,
$strArgReceiverCity,
$strArgShippingDate,
array($this->carrier_type)
);
$arrFeasibilityList = array();
foreach ($arrTNTServiceList as $arrTNTService) {
if ($this->account_type === $arrTNTService['accountType']
&& $this->carrier_type === $arrTNTService['carrierType']
&& $this->carrier_code1 === $arrTNTService['carrierCode1']
&& $this->carrier_code2 === $arrTNTService['carrierCode2']
) {
$arrFeasibilityList[] = array(
'shippingDate' => $arrTNTService['shippingDate'],
'dueDate' => $arrTNTService['dueDate'],
'saturdayDelivery' => (bool)$arrTNTService['saturdayDelivery'],
'afternoonDelivery' => (bool)$arrTNTService['afternoonDelivery'],
'insurance' => (bool)$arrTNTService['insurance'],
'priorityGuarantee' => (bool)$arrTNTService['priorityGuarantee']
);
}
}
return $arrFeasibilityList;
}
/**
* Get delivery points list.
* Only available in for carrier type DROPOFFPOINT or DEPOT.
*
* @param $strArgReceiverZipCode
* @param $strArgReceiverCity
*
* @return array|null
*/
public function getDeliveryPoints($strArgReceiverZipCode, $strArgReceiverCity)
{
TNTOfficiel_Logstack::log();
$objTNTCarrierAccountModel = $this->getTNTAccountModel();
// If no account available for this carrier.
if ($objTNTCarrierAccountModel === null) {
return null;
}
$arrResultDeliveryPoints = null;
if ($this->carrier_type === 'DROPOFFPOINT') {
// Get an Estimated delivery date from the carrier selected in cart.
$strArgEDD = null;
$arrFeasibilitiesList = $this->feasibilities($strArgReceiverZipCode, $strArgReceiverCity);
foreach ($arrFeasibilitiesList as $arrFeasibility) {
$strArgEDD = $arrFeasibility['dueDate'];
break;
}
// Call WS to get list of delivery points.
$arrResultDeliveryPoints = $objTNTCarrierAccountModel->dropOffPoints(
$strArgReceiverZipCode,
$strArgReceiverCity,
$strArgEDD
);
} elseif ($this->carrier_type === 'DEPOT') {
// Call WS to get list of delivery points
$arrResultDeliveryPoints = $objTNTCarrierAccountModel->tntDepots(
$strArgReceiverZipCode,
$strArgReceiverCity
);
}
return $arrResultDeliveryPoints;
}
/**
* @return boolean
*/
public function isZonesEnabled()
{
TNTOfficiel_Logstack::log();
return (bool)$this->zones_enabled;
}
/**
* @param boolean $zones_enabled
*/
public function setZonesEnabled($zones_enabled)
{
TNTOfficiel_Logstack::log();
$this->zones_enabled = (bool)$zones_enabled;
return $this->save();
}
/**
* @return boolean
*/
public function isZonesCloningEnabled()
{
TNTOfficiel_Logstack::log();
return $this->zones_cloning_enabled;
}
/**
* @param $zones__cloning_enabled
*/
public function setZonesCloningEnabled($zones_cloning_enabled)
{
TNTOfficiel_Logstack::log();
$this->zones_cloning_enabled = $zones_cloning_enabled;
return $this->save();
}
/**
* Get all zones configuration or the specified one if exist.
*
* @param int $intArgZoneConfID
*
* @return array|null
*/
public function getZonesConf($intArgZoneConfID = null)
{
TNTOfficiel_Logstack::log();
$arrZonesConfList = Tools::unSerialize($this->zones_config);
if (!is_array($arrZonesConfList)) {
$arrZoneConfDefault = array (
'strRangeType' => 'weight',
'arrRangeWeightList' => array (),
'fltRangeWeightPricePerKg' => 0.0,
'fltRangeWeightLimitMax' => 0.0,
'arrRangePriceList' => array (),
'strOutOfRangeBehavior' => 'lastrange',
'fltHRAAdditionalCost' => 0.0,
'fltMarginPercent' => 0.0,
);
$arrZonesConfList = array(
$arrZoneConfDefault,
$arrZoneConfDefault,
$arrZoneConfDefault,
);
}
// If the zone ID is specified.
if ($intArgZoneConfID !== null) {
// If found.
if (array_key_exists($intArgZoneConfID, $arrZonesConfList)) {
// Get it.
return $arrZonesConfList[$intArgZoneConfID];
}
// Not found.
return array();
}
// All Zones
return $arrZonesConfList;
}
/**
* Save a zone configuration.
*
* @param int $intArgZoneConfID
* @param array $arrArgZoneConf
*
* @return bool
*/
private function saveZoneConf($intArgZoneConfID, $arrArgZoneConf)
{
TNTOfficiel_Logstack::log();
$arrZonesConfList = $this->getZonesConf();
$arrZonesConfList[$intArgZoneConfID] = $arrArgZoneConf;
// Filtering zones index.
$arrZonesConfListSave = array_intersect_key(
$arrZonesConfList,
array(array(), array(), array())
);
$this->zones_config = serialize($arrZonesConfListSave);
return $this->save();
}
/**
* Check if a zone is configured using a minimum of one limit in corresponding range type.
*
* @param int $intArgZoneConfID
*
* @return bool
*/
public function isZoneConfigured($intArgZoneConfID)
{
TNTOfficiel_Logstack::log();
$arrZoneConf = $this->getZonesConf($intArgZoneConfID);
if ($this->isZoneRangeByWeight($intArgZoneConfID)
&& is_array($arrZoneConf)
&& array_key_exists('arrRangeWeightList', $arrZoneConf)
&& is_array($arrZoneConf['arrRangeWeightList'])
&& count($arrZoneConf['arrRangeWeightList']) > 0
) {
return true;
}
if (!$this->isZoneRangeByWeight($intArgZoneConfID)
&& is_array($arrZoneConf)
&& array_key_exists('arrRangePriceList', $arrZoneConf)
&& is_array($arrZoneConf['arrRangePriceList'])
&& count($arrZoneConf['arrRangePriceList']) > 0
) {
return true;
}
return false;
}
/**
*
* @param int $intArgZoneConfID
* @param string $strArgRangeType
*
* @return bool
*/
public function setZoneRangeType($intArgZoneConfID, $strArgRangeType = 'weight')
{
TNTOfficiel_Logstack::log();
$arrZoneConf = $this->getZonesConf($intArgZoneConfID);
$strRangeType = 'price';
if ($strArgRangeType === 'weight') {
$strRangeType = 'weight';
}
$arrZoneConf['strRangeType'] = $strRangeType;
return $this->saveZoneConf($intArgZoneConfID, $arrZoneConf);
}
/**
*
* @param int $intArgZoneConfID
*
* @return bool
*/
public function isZoneRangeByWeight($intArgZoneConfID)
{
TNTOfficiel_Logstack::log();
$arrZoneConf = $this->getZonesConf($intArgZoneConfID);
if (is_array($arrZoneConf)
&& array_key_exists('strRangeType', $arrZoneConf)
&& $arrZoneConf['strRangeType'] === 'weight'
) {
return true;
}
return false;
}
/**
*
* @param int $intArgZoneConfID
* @param array $arrArgRangeWeightList
* @param float $fltArgRangeWeightPricePerKg
* @param float $fltArgRangeWeightLimitMax
*
* @return bool
*/
public function setZoneRangeWeightList(
$intArgZoneConfID,
array $arrArgRangeWeightList = array(),
$fltArgRangeWeightPricePerKg = 0.0,
$fltArgRangeWeightLimitMax = 0.0
) {
TNTOfficiel_Logstack::log();
$arrZoneConf = $this->getZonesConf($intArgZoneConfID);
$arrRangeWeightList = array();
foreach ($arrArgRangeWeightList as $key => &$value) {
$arrRangeWeightList[(string)$key] = (float)$value;
}
$arrZoneConf['arrRangeWeightList'] = $arrRangeWeightList;
$arrZoneConf['fltRangeWeightPricePerKg'] = (float)$fltArgRangeWeightPricePerKg;
$arrZoneConf['fltRangeWeightLimitMax'] = (float)$fltArgRangeWeightLimitMax;
return $this->saveZoneConf($intArgZoneConfID, $arrZoneConf);
}
/**
*
* @param int $intArgZoneConfID
* @param float $fltArgCartWeight
*
* @return float|false false if disabled.
*/
public function getZoneRangeWeightCost($intArgZoneConfID, $fltArgCartWeight)
{
TNTOfficiel_Logstack::log();
$arrZoneConf = $this->getZonesConf($intArgZoneConfID);
$arrRangeWeightList = $arrZoneConf['arrRangeWeightList'];
$fltRangeWeightPricePerKg = $arrZoneConf['fltRangeWeightPricePerKg'];
$fltRangeWeightLimitMax = $arrZoneConf['fltRangeWeightLimitMax'];
$fltWeightCost = 0.0;
$strFltRangeLimitMatch = (string)-1;
$strFltRangeLimitLast = (string)-1;
$strFltRangeLimitWeight = (string)-1;
$fltRangeLimitCost = 0;
foreach ($arrRangeWeightList as $strFltRangeLimitWeight => $fltRangeLimitCost) {
if ($strFltRangeLimitMatch == -1 && $fltArgCartWeight <= $strFltRangeLimitWeight) {
$strFltRangeLimitMatch = (string)$strFltRangeLimitWeight;
}
$strFltRangeLimitLast = (string)$strFltRangeLimitWeight;
}
// If no max limit defined, but there is a price per kg.
if (!($fltRangeWeightLimitMax > 0) && $fltRangeWeightPricePerKg > 0) {
// Max limit is set to the cart weight, to keep usage of the price per kg.
$fltRangeWeightLimitMax = $fltArgCartWeight;
}
// If max defined and is greater than last limit.
if ($fltRangeWeightLimitMax > $strFltRangeLimitLast) {
while (++$strFltRangeLimitWeight <= $fltRangeWeightLimitMax) {
$fltRangeLimitCost += $fltRangeWeightPricePerKg;
// Extending range.
$arrRangeWeightList[(string)$strFltRangeLimitWeight] = $fltRangeLimitCost;
if ($strFltRangeLimitMatch == -1 && $fltArgCartWeight <= $strFltRangeLimitWeight) {
$strFltRangeLimitMatch = (string)$strFltRangeLimitWeight;
}
}
$strFltRangeLimitLast = (string)$fltRangeWeightLimitMax;
// Termination.
if (!array_key_exists((string)$fltRangeWeightLimitMax, $arrRangeWeightList)) {
$fltRangeLimitCost += $fltRangeWeightPricePerKg;
$arrRangeWeightList[(string)$fltRangeWeightLimitMax] = $fltRangeLimitCost;
if ($strFltRangeLimitMatch == -1 && $fltArgCartWeight <= $fltRangeWeightLimitMax) {
$strFltRangeLimitMatch = (string)$fltRangeWeightLimitMax;
}
}
}
// Range match.
if (array_key_exists($strFltRangeLimitMatch, $arrRangeWeightList)) {
$fltWeightCost = $arrRangeWeightList[$strFltRangeLimitMatch];
}
TNTOfficiel_Logstack::dump(array(
'id_carrier' => $this->id_carrier,
'intArgZoneConfID' => $intArgZoneConfID,
'fltArgCartWeight' => $fltArgCartWeight,
'arrRangeWeightList' => $arrRangeWeightList,
'fltRangeLimitMatch' => $strFltRangeLimitMatch,
'fltRangeLimitLast' => $strFltRangeLimitLast,
'fltWeightCost' => $fltWeightCost,
'boolIsOutOfRange' => ($strFltRangeLimitLast == -1 || ($fltArgCartWeight > $strFltRangeLimitLast))
));
// Out of range.
if ($strFltRangeLimitLast == -1 || ($fltArgCartWeight > $strFltRangeLimitLast)) {
if ($this->isZoneOutOfRangeDisabled($intArgZoneConfID)) {
// Carrier is disabled.
return false;
} else {
// Use the last limit.
if (array_key_exists($strFltRangeLimitLast, $arrRangeWeightList)) {
$fltWeightCost = $arrRangeWeightList[$strFltRangeLimitLast];
}
}
}
return $fltWeightCost;
}
/**
*
* @param int $intArgZoneConfID
* @param array $arrArgRangePriceList
*
* @return bool
*/
public function setZoneRangePriceList(
$intArgZoneConfID,
array $arrArgRangePriceList = array()
) {
TNTOfficiel_Logstack::log();
$arrZoneConf = $this->getZonesConf($intArgZoneConfID);
$arrRangePriceList = array();
foreach ($arrArgRangePriceList as $key => &$value) {
$arrRangePriceList[(string)$key] = (float)$value;
}
$arrZoneConf['arrRangePriceList'] = $arrRangePriceList;
return $this->saveZoneConf($intArgZoneConfID, $arrZoneConf);
}
/**
*
* @param int $intArgZoneConfID
* @param float $fltArgCartPrice
*
* @return float|false false if disabled.
*/
public function getZoneRangePriceCost($intArgZoneConfID, $fltArgCartPrice)
{
TNTOfficiel_Logstack::log();
$arrZoneConf = $this->getZonesConf($intArgZoneConfID);
$arrRangePriceList = $arrZoneConf['arrRangePriceList'];
$fltPriceCost = 0.0;
$strFltRangeLimitMatch = (string)-1;
$strFltRangeLimitLast = (string)-1;
foreach ($arrRangePriceList as $strFltRangeLimitPrice => $fltRangeLimitCost) {
if ($strFltRangeLimitMatch == -1 && $fltArgCartPrice < $strFltRangeLimitPrice) {
$strFltRangeLimitMatch = (string)$strFltRangeLimitPrice;
}
$strFltRangeLimitLast = (string)$strFltRangeLimitPrice;
}
// Range match.
if (array_key_exists($strFltRangeLimitMatch, $arrRangePriceList)) {
$fltPriceCost = $arrRangePriceList[$strFltRangeLimitMatch];
}
TNTOfficiel_Logstack::dump(array(
'id_carrier' => $this->id_carrier,
'intArgZoneConfID' => $intArgZoneConfID,
'fltArgCartPrice' => $fltArgCartPrice,
'arrRangePriceList' => $arrRangePriceList,
'fltRangeLimitMatch' => $strFltRangeLimitMatch,
'fltRangeLimitLast' => $strFltRangeLimitLast,
'fltPriceCost' => $fltPriceCost,
'boolIsOutOfRange' => ($strFltRangeLimitLast == -1 || ($fltArgCartPrice > $strFltRangeLimitLast))
));
// Out of range.
if ($strFltRangeLimitLast == -1 || ($fltArgCartPrice >= $strFltRangeLimitLast)) {
if ($this->isZoneOutOfRangeDisabled($intArgZoneConfID)) {
// Carrier is disabled.
return false;
} else {
if (array_key_exists($strFltRangeLimitLast, $arrRangePriceList)) {
$fltPriceCost = $arrRangePriceList[$strFltRangeLimitLast];
}
}
}
return $fltPriceCost;
}
/**
* Set a zone configuration out of range behavior.
*
* @param int $intArgZoneConfID
* @param string $strArgOutOfRangeBehavior
*
* @return bool
*/
public function setZoneOutOfRangeBehavior($intArgZoneConfID, $strArgOutOfRangeBehavior = 'lastrange')
{
TNTOfficiel_Logstack::log();
$arrZoneConf = $this->getZonesConf($intArgZoneConfID);
$strOutOfRangeBehavior = 'disabled';
if ($strArgOutOfRangeBehavior === 'lastrange') {
$strOutOfRangeBehavior = 'lastrange';
}
$arrZoneConf['strOutOfRangeBehavior'] = $strOutOfRangeBehavior;
return $this->saveZoneConf($intArgZoneConfID, $arrZoneConf);
}
/**
*
* @param int $intZoneConfID
*
* @return bool
*/
public function isZoneOutOfRangeDisabled($intZoneConfID)
{
TNTOfficiel_Logstack::log();
$arrZoneConf = $this->getZonesConf($intZoneConfID);
if (is_array($arrZoneConf)
&& array_key_exists('strOutOfRangeBehavior', $arrZoneConf)
&& $arrZoneConf['strOutOfRangeBehavior'] === 'lastrange'
) {
return false;
}
return true;
}
/**
*
* @param int $intArgZoneConfID
* @param float $fltArgHRAAdditionalCost
*
* @return bool
*/
public function setZoneHRAAdditionalCost($intArgZoneConfID, $fltArgHRAAdditionalCost)
{
TNTOfficiel_Logstack::log();
$arrZoneConf = $this->getZonesConf($intArgZoneConfID);
$fltHRAAdditionalCost = 0.0;
if ($fltArgHRAAdditionalCost > 0.0) {
$fltHRAAdditionalCost = $fltArgHRAAdditionalCost;
}
$arrZoneConf['fltHRAAdditionalCost'] = $fltHRAAdditionalCost;
return $this->saveZoneConf($intArgZoneConfID, $arrZoneConf);
}
/**
*
* @param int $intArgZoneConfID
*
* @return float
*/
public function getZoneHRAAdditionalCost($intArgZoneConfID)
{
TNTOfficiel_Logstack::log();
$arrZoneConf = $this->getZonesConf($intArgZoneConfID);
if (is_array($arrZoneConf)
&& array_key_exists('fltHRAAdditionalCost', $arrZoneConf)
&& $arrZoneConf['fltHRAAdditionalCost'] > 0.0
) {
return $arrZoneConf['fltHRAAdditionalCost'];
}
return 0.0;
}
/**
*
* @param int $intArgZoneConfID
* @param float $fltArgMarginPercent
*
* @return bool
*/
public function setZoneMarginPercent($intArgZoneConfID, $fltArgMarginPercent)
{
TNTOfficiel_Logstack::log();
$arrZoneConf = $this->getZonesConf($intArgZoneConfID);
$fltMarginPercent = 0.0;
if ($fltArgMarginPercent > 0.0) {
$fltMarginPercent = $fltArgMarginPercent;
}
$arrZoneConf['fltMarginPercent'] = $fltMarginPercent;
return $this->saveZoneConf($intArgZoneConfID, $arrZoneConf);
}
/**
*
* @param int $intArgZoneConfID
*
* @return float
*/
public function getZoneMarginPercent($intArgZoneConfID)
{
TNTOfficiel_Logstack::log();
$arrZoneConf = $this->getZonesConf($intArgZoneConfID);
if (is_array($arrZoneConf)
&& array_key_exists('fltMarginPercent', $arrZoneConf)
&& $arrZoneConf['fltMarginPercent'] > 0.0
) {
return $arrZoneConf['fltMarginPercent'];
}
return 0.0;
}
/**
*
* @return real|false|null false if carrier is not available, null if must use native Prestashop configuration.
*/
public function getPrice($fltArgCartWeight, $fltArgCartPrice, $intArgAddressIDDelivery = null)
{
TNTOfficiel_Logstack::log();
if (!$this->zones_enabled) {
// Use Prestashop configuration.
return null;
}
$objTNTCarrierAccountModel = $this->getTNTAccountModel();
if ($objTNTCarrierAccountModel === null) {
// Use Prestashop configuration.
return null;
}
// Default Zone.
$intZoneConfID = 0;
$boolIsAnHRAZipCode = false;
$objPSAddressDelivery = TNTOfficielReceiver::getPSAddress($intArgAddressIDDelivery);
// If delivery address object is available.
if ($objPSAddressDelivery !== null) {
$strReceiverZipCode = $objPSAddressDelivery->postcode;
$intZoneConfID = $objTNTCarrierAccountModel->getZipCodeZone($strReceiverZipCode);
$boolIsAnHRAZipCode = $this->isAnHRAZipCode($strReceiverZipCode);
}
// If matching zone is not configured.
if (!$this->isZoneConfigured($intZoneConfID)) {
// Use default zone.
$intZoneConfID = 0;
}
if ($this->isZoneRangeByWeight($intZoneConfID)) {
$fltPrice = $this->getZoneRangeWeightCost($intZoneConfID, $fltArgCartWeight);
} else {
$fltPrice = $this->getZoneRangePriceCost($intZoneConfID, $fltArgCartPrice);
}
// Disabled.
if ($fltPrice === false) {
// Carrier is disabled.
return false;
}
// Add HRA Additional cost only for non free shipping.
if ($boolIsAnHRAZipCode && $fltPrice > 0.0) {
$fltPrice += $this->getZoneHRAAdditionalCost($intZoneConfID);
}
// Add Margin.
$fltPrice += ($this->getZoneMarginPercent($intZoneConfID) * $fltPrice / 100.0);
return $fltPrice;
}
}