2051 lines
70 KiB
PHP
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;
|
|
}
|
|
}
|