* @copyright 2016-2017 GFI Informatique, 2016-2017 TNT * @license https://opensource.org/licenses/MIT MIT License */ require_once _PS_MODULE_DIR_.'tntofficiel/libraries/TNTOfficiel_Debug.php'; require_once _PS_MODULE_DIR_.'tntofficiel/libraries/TNTOfficiel_Cache.php'; require_once _PS_MODULE_DIR_.'tntofficiel/libraries/TNTOfficiel_Product.php'; require_once _PS_MODULE_DIR_.'tntofficiel/libraries/TNTOfficiel_Logger.php'; require_once _PS_MODULE_DIR_.'tntofficiel/libraries/TNTOfficiel_JsonRPCClient.php'; require_once _PS_MODULE_DIR_.'tntofficiel/libraries/TNTOfficiel_PasswordManager.php'; class TNTOfficiel_CarrierHelper { /** @var Singleton */ private static $_instance = null; /** @var TNTOfficiel_Logger */ private $logger; /** * Constructor. */ public function __construct() { TNTOfficiel_Debug::log(array('msg' => '>>', 'file' => __FILE__, 'line' => __LINE__)); $this->logger = new TNTOfficiel_Logger(); } /** * Creates a singleton. * * @param void * * @return TNTOfficiel_CarrierHelper */ public static function getInstance() { TNTOfficiel_Debug::log(array('msg' => '>>', 'file' => __FILE__, 'line' => __LINE__)); if (is_null(TNTOfficiel_CarrierHelper::$_instance)) { TNTOfficiel_CarrierHelper::$_instance = new TNTOfficiel_CarrierHelper(); } return TNTOfficiel_CarrierHelper::$_instance; } /** * Get the carriers from the middleware or from cache. * * @return array */ public function getMDWTNTCarrierList($objArgCustomer) { TNTOfficiel_Debug::log(array('msg' => '>>', 'file' => __FILE__, 'line' => __LINE__)); $objContext = Context::getContext(); $objCart = $objContext->cart; $arrTNTCarrierList = array(); // Validated account is required. if (!Configuration::get('TNT_CARRIER_ACTIVATED')) { return $arrTNTCarrierList; } // A shipping address is required. if ($objCart->id_address_delivery == 0) { return $arrTNTCarrierList; } // get params without timestamp $params = $this->_getCartData($objArgCustomer); $maxPackageWeightBtoB = (float)Configuration::get('TNT_CARRIER_MAX_PACKAGE_B2B'); $maxPackageWeightBtoC = (float)Configuration::get('TNT_CARRIER_MAX_PACKAGE_B2C'); $onlyBtoBServices = false; foreach ($params['quote']['items'] as $item) { if ($item['weight'] > $maxPackageWeightBtoB) { return; } if ($item['weight'] > $maxPackageWeightBtoC) { $onlyBtoBServices = true; } } $cache_key = 'middleware::getCarrierData_'.md5(serialize($params)); //check if already in cache if (!TNTOfficiel_Cache::isStored($cache_key)) { $client = new TNTOfficiel_JsonRPCClient(Configuration::get('TNT_CARRIER_MIDDLEWARE_URL')); $arrTNTCarrierList = null; try { $arrTNTCarrierList = $client->execute('getCarrierQuote', $params); $this->logger->logMessageTnt('getCarrierQuote', null, 'JSON', true, 'SUCCESS'); } catch (Exception $objException) { $strStatus = ($objException->getCode() == 500) ? 'FATAL' : 'ERROR'; $strMsg = $objException->getMessage(); $this->logger->logMessageTnt('getCarrierQuote', $strMsg, 'JSON', false, $strStatus); } if (!is_array($arrTNTCarrierList) || !array_key_exists('products', $arrTNTCarrierList)) { return; } $arrServiceEnable = array('ENTERPRISE', 'DEPOT'); foreach ($arrTNTCarrierList['products'] as $key => $product) { if ($onlyBtoBServices && !in_array($product['type'], $arrServiceEnable)) { unset($arrTNTCarrierList['products'][$key]); if (array_key_exists('relay_points', $arrTNTCarrierList)) { unset($arrTNTCarrierList['relay_points']); } continue; } $arrTNTCarrierList['products'][$key]['id'] = $product['code'].'_'.$product['type']; $arrTNTCarrierList['products'][$key]['due_date'] = null; if ($product['due_date']) { $arrTNTCarrierList['products'][$key]['due_date'] = date('d/m/Y', strtotime($product['due_date'])); } } // add in cache for 600 seconds TNTOfficiel_Cache::store($cache_key, Tools::jsonEncode($arrTNTCarrierList), 600); return $arrTNTCarrierList; } $arrTNTCarrierList = Tools::jsonDecode(TNTOfficiel_Cache::retrieve($cache_key), true); return $arrTNTCarrierList; } /** * Get all the data needed by the middleware from the cart. * * @return array */ private function _getCartData($objCustomer) { TNTOfficiel_Debug::log(array('msg' => '>>', 'file' => __FILE__, 'line' => __LINE__)); $objContext = Context::getContext(); $objCart = $objContext->cart; //get the checkout step if in checkout else set it to 0 $step = 0; if (property_exists($objContext->controller, 'step')) { $step = $objContext->controller->step; } //check if user is logged in $loggedIn = $objContext->controller->auth; //shipping address $shippingAddress = new Address((int)$objCart->id_address_delivery); //total discount $totalDiscount = 0; //items $items = array(); foreach ($objCart->getProducts() as $product) { //reduction amount $totalDiscount += $discount = Product::getPriceStatic($product['id_product'], false, $product['id_product_attribute'], 6, null, true); $attributes = TNTOfficiel_Product::getProductAttributes($product['id_product']); $items[] = array( 'qty' => $product['cart_quantity'], 'price' => $product['price'] + $discount, 'row_total' => $product['price_wt'] * $product['cart_quantity'], 'tax' => $product['cart_quantity'] * $product['price'] * $product['rate'] / 100, 'discount' => $discount, 'attributes' => $attributes, 'options' => (isset($product['attributes'])) ? $this->_attributesToArray($product['attributes']) : '', 'weight' => $product['weight'], ); } $data = array( 'store' => $objCart->id_shop, 'context' => ($step == 2) ? 'CHECKOUT' : 'QUOTE', 'merchant' => array( 'identity' => Configuration::get('TNT_CARRIER_USERNAME'), 'password' => TNTOfficiel_PasswordManager::getHash(), 'merchant_number' => Configuration::get('TNT_CARRIER_ACCOUNT'), ), 'customer' => array( 'name' => ($loggedIn == true) ? $objCustomer->firstname.' '.$objCustomer->lastname : null, 'email' => ($loggedIn == true) ? $objCustomer->email : '', 'group_id' => ($loggedIn == true) ? Customer::getDefaultGroupId((int)$objCustomer->id) : null, 'dob' => ($loggedIn == true) ? Customer::getDefaultGroupId((int)$objCustomer->birthday) : null, 'name' => $shippingAddress->company, ), 'shipping' => array( 'country_code' => Country::getIsoById($shippingAddress->id_country), 'region_code' => Tools::substr($shippingAddress->postcode, 0, 2), 'post_code' => $shippingAddress->postcode, 'city' => $shippingAddress->city, ), 'quote' => array( 'items' => $items, 'subtotal' => $objCart->getOrderTotal(false, Cart::ONLY_PRODUCTS_WITHOUT_SHIPPING), 'tax' => $objCart->getOrderTotal(true, Cart::BOTH_WITHOUT_SHIPPING) - $objCart->getOrderTotal(false, Cart::BOTH_WITHOUT_SHIPPING), 'discount' => -($objCart->getOrderTotal(false, Cart::BOTH_WITHOUT_SHIPPING) - $objCart->getOrderTotal(false, Cart::ONLY_PRODUCTS_WITHOUT_SHIPPING)), 'coupon_code' => $this->_getDiscountCodes($objCart), 'freeshipping' => '', ), ); return $data; } /** * Transform a string containing attributes data into an array. * * @param string $attributes * * @return array */ private function _attributesToArray($attributes) { TNTOfficiel_Debug::log(array('msg' => '>>', 'file' => __FILE__, 'line' => __LINE__)); $attributesArray = array(); $attributesTemp = explode(',', preg_replace('/\s+/', '', $attributes)); foreach ($attributesTemp as $attribute) { $temp = array(); $attributeArray = explode(':', $attribute); $temp['code'] = $attributeArray[0]; $temp['value'] = $attributeArray[1]; $attributesArray[] = $temp; } return $attributesArray; } /** * Gets all the cart discount codes separated by '|'. * Note: using Cart->getDiscounts() may cause infinite loop through Module->getOrderShippingCost(). * Note: Cart->getOrderedCartRulesIds() unavailable in Prestashop 1.6.0.5. * * @param CartCore $objArgCart * * @return string */ private function _getDiscountCodes($objArgCart) { TNTOfficiel_Debug::log(array('msg' => '>>', 'file' => __FILE__, 'line' => __LINE__)); $strKeyCache = 'TNTOfficiel_CarrierHelper::_getDiscountCodes'.$objArgCart->id.'-ids'; if (!Cache::isStored($strKeyCache)) { $arrCartRulesIdList = Db::getInstance()->executeS(' SELECT cr.`id_cart_rule` FROM `'._DB_PREFIX_.'cart_cart_rule` cd LEFT JOIN `'._DB_PREFIX_.'cart_rule` cr ON cd.`id_cart_rule` = cr.`id_cart_rule` LEFT JOIN `'._DB_PREFIX_.'cart_rule_lang` crl ON ( cd.`id_cart_rule` = crl.`id_cart_rule` AND crl.id_lang = '.(int)$objArgCart->id_lang.' ) WHERE `id_cart` = '.(int)$objArgCart->id.' ORDER BY cr.priority ASC '); Cache::store($strKeyCache, $arrCartRulesIdList); } else { $arrCartRulesIdList = Cache::retrieve($strKeyCache); } $arrDiscountCodes = array(); foreach ($arrCartRulesIdList as $arrCartRulesRow) { $objCartRule = new CartRule($arrCartRulesRow['id_cart_rule']); $arrDiscountCodes[] = $objCartRule->code; } return implode('|', $arrDiscountCodes); } }