1: <?php
2:
3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32:
33: if (!defined('_PS_VERSION_')) {
34: exit;
35: }
36:
37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48:
49: class eabi_dpd_parcelstore extends Module {
50:
51: const CONST_PREFIX = 'E_DPDEEP_';
52:
53: 54: 55: 56:
57: protected $_const_prefix;
58:
59: 60: 61:
62: const TRACKING_URL = 'https://tracking.dpd.de/cgi-bin/delistrack?typ=1&lang=en&pknr=@';
63:
64: 65: 66:
67: const = '-----EABI_DPDEE-----';
68:
69: 70: 71:
72: const NAME = 'eabi_dpd_parcelstore';
73:
74: 75: 76: 77: 78:
79: private $form_fields = array();
80:
81: 82: 83: 84:
85: protected static = false;
86:
87: 88: 89: 90:
91: protected $_carrierDisplayed = false;
92:
93: 94: 95: 96:
97: protected static $_helperModuleInstance;
98:
99: 100: 101: 102:
103: public $dataSendExecutor;
104:
105: 106: 107:
108: final public function __construct() {
109:
110: $this->_construct();
111:
112:
113: parent::__construct();
114: $this->init();
115:
116: }
117:
118: 119: 120:
121: protected function _construct() {
122: $this->_const_prefix = self::CONST_PREFIX;
123: $this->name = self::NAME;
124: $this->tab = 'shipping_logistics';
125: $this->version = '0.9';
126: $this->dependencies[] = 'eabi_postoffice';
127: $this->ps_versions_compliancy = array('min' => '1.5', 'max' => '1.7');
128: $this->displayName = $this->l('DPD Pakipoodi');
129: $this->description = $this->l('DPD offers high-quality shipping service from Estonia to whole Europe.');
130: $this->confirmUninstall = $this->l('Are you sure you want to delete your details?');
131: if (file_exists(_PS_MODULE_DIR_ . $this->name . '/datasend-executor.php')) {
132: require_once(_PS_MODULE_DIR_ . $this->name . '/datasend-executor.php');
133: $executorClass = $this->name . '_data_send_executor';
134: $this->dataSendExecutor = new $executorClass($this);
135: }
136: if (!$this->_getHelperModule() || !$this->getConfigData('TITLE') OR !$this->getConfigData('HANDLING_FEE')) {
137: $this->warning = $this->l('Details must be configured in order to use this module correctly');
138: }
139:
140:
141: }
142:
143: 144: 145:
146: private function init() {
147:
148: }
149:
150: 151: 152: 153:
154: final public function install() {
155: if (Shop::isFeatureActive()) {
156: Shop::setContext(Shop::CONTEXT_ALL);
157: }
158: if (!parent::install() or !$this->_install()) {
159: return false;
160: }
161: return true;
162: }
163:
164: 165: 166: 167:
168: final public function uninstall() {
169: if (Shop::isFeatureActive()) {
170: Shop::setContext(Shop::CONTEXT_ALL);
171: }
172: if (!$this->_uninstall() || !parent::uninstall()) {
173: return false;
174: }
175: return true;
176: }
177:
178: 179: 180: 181: 182: 183: 184: 185: 186: 187: 188: 189: 190:
191: protected function _install() {
192: if (!$this->registerHook('extraCarrier')
193: || !$this->_getHelperModule()->addCarrierModule($this->name, get_class($this), self::TRACKING_URL)
194: || !$this->registerHook('paymentConfirm')
195: || !$this->registerHook('actionAdminControllerSetMedia')
196: || !$this->registerHook('displayBackOfficeFooter')
197: || !$this->registerHook('displayHeader')
198: || !$this->registerHook('displayFooter')
199: || !$this->upgrade_module_0_6()
200: || !$this->upgrade_module_0_8()) {
201: return false;
202: }
203: return true;
204: }
205:
206: 207: 208: 209: 210: 211: 212: 213: 214: 215: 216: 217: 218: 219:
220: protected function _uninstall() {
221: if (!$this->unregisterHook('extraCarrier')
222: || !$this->unregisterHook('paymentConfirm')
223: || !$this->unregisterHook('displayBackOfficeFooter')
224: || !$this->unregisterHook('displayHeader')
225: || !$this->unregisterHook('displayFooter')) {
226: return false;
227: }
228:
229:
230: $this->unregisterHook('displayBackOfficeHeader');
231: $this->unregisterHook('actionAdminControllerSetMedia');
232: if (!$this->_getHelperModule()->removeCarrierModule($this->name)) {
233: return false;
234: }
235:
236: if ($this->dataSendExecutor != null) {
237: $this->dataSendExecutor->uninstall();
238: }
239: return true;
240: }
241:
242: 243: 244: 245: 246: 247: 248: 249:
250: public function getRequestForAutoSendData($order, $address, $selectedOfficeId, $forceCod = false) {
251: $telephone = $address->phone_mobile;
252: if (!$telephone) {
253: $telephone = $address->phone;
254: }
255:
256:
257:
258: $requestData = array(
259: 'Sh_name' => $address->firstname.' '.$address->lastname,
260: 'Sh_company' => '',
261: 'Sh_street' => $this->_getStreetFromDescription($selectedOfficeId),
262: 'Sh_postal' => $selectedOfficeId['zip_code'],
263: 'Sh_country' => strtolower($selectedOfficeId['country']),
264: 'Sh_city' => $selectedOfficeId['city'],
265: 'Sh_contact' => $selectedOfficeId['name'],
266: 'Sh_phone' => $this->_getPhoneFromDescription($selectedOfficeId),
267: 'Po_remark' => $this->_getRemark($order),
268: 'Sh_remark' => '',
269: 'Sh_pudo' => 'true',
270: 'Sh_pudo_id' => $selectedOfficeId['remote_place_id'],
271: 'Sh_parcel_qty' => $this->_getNumberOfPackagesForOrder($order),
272: 'Sh_cust_reference' => $order->id,
273: );
274: if ($address->id_state) {
275: $requestData['Sh_city'] = $address->city . ', ' . State::getNameById($address->id_state);
276: }
277:
278:
279: $phoneNumbers = $this->_getDialCodeHelper()->separatePhoneNumberFromCountryCode($telephone, Country::getIsoById($address->id_country));
280: $requestData['Sh_notify_phone_code'] = $phoneNumbers['dial_code'];
281: $requestData['Sh_notify_contact_phone'] = $phoneNumbers['phone_number'];
282:
283:
284: if (!$order->hasBeenPaid() && $forceCod) {
285:
286:
287: $requestData['Sh_cod_amount'] = number_format(round($order->total_paid_tax_incl, 2), 2, '.', '');
288: $requestData['Sh_cod_currency'] = $this->_getCurrencyIso($order->id_currency);
289: }
290:
291:
292: return $requestData;
293: }
294:
295:
296: protected function _getCurrencyIso($id_currency) {
297: $currency = Currency::getCurrency($id_currency);
298: return $currency['iso_code'];
299: }
300:
301:
302: private function _getStreetFromDescription($selectedOffice) {
303: $zip = $selectedOffice['zip_code'];
304: $encoding = 'UTF-8';
305: return trim(mb_substr($selectedOffice['description'], 0, mb_strpos($selectedOffice['description'], $zip, 0, $encoding), $encoding));
306: }
307: private function _getPhoneFromDescription($selectedOffice) {
308: $zip = $selectedOffice['zip_code'];
309: $country = $selectedOffice['country'];
310: $matches = array();
311: $isMatched = preg_match('/(?s:[\+][0-9]+)/', $selectedOffice['description'], $matches);
312: if ($isMatched) {
313: return $matches[0];
314: }
315: return '';
316: }
317:
318: 319: 320: 321: 322:
323: public function hookPaymentConfirm(&$params) {
324: if ($this->dataSendExecutor != null) {
325: $this->dataSendExecutor->hookpaymentConfirm($params);
326: }
327: return '';
328: }
329:
330: 331: 332:
333: public function hookActionAdminControllerSetMedia() {
334: $this->context->controller->addCSS($this->_path . 'css/' . self::NAME . '.css', 'all');
335: $this->context->controller->addJqueryPlugin('loadTemplate', $this->_path . 'js/plugins/');
336: $this->context->controller->addJS($this->_path . 'js/' . self::NAME . '.js');
337: }
338:
339: 340: 341:
342: public function () {
343: $className = 'AdminOrdersController';
344:
345:
346:
347:
348: if (!self::$_footerCalled && $this->context->controller instanceof $className && $this->getConfigData('SENDDATA_ENABLE') == 'yes') {
349: self::$_footerCalled = true;
350:
351: $targetName = eabi_dpd_parcelstore::NAME;
352: if (!ModuleCore::isEnabled(eabi_dpd_parcelstore::NAME)) {
353: $targetName = 'eabi_dpd_courier';
354: }
355: $buttonCssClass = 'process-icon-new';
356: if (substr(_PS_VERSION_, 0, 3) == "1.6") {
357: $buttonCssClass = 'process-icon-dpd';
358: }
359:
360: if (!(Tools::getValue('vieworder', false) === '')) {
361:
362: if ($this->getConfigData('COURIER_ENABLE') == 'yes') {
363: $jsonParams = array(
364: 'url' => $this->context->link->getModuleLink($targetName, 'courier', array('fc' => 'module')),
365: 'button' => '<li id="eabi-dpdee-courier"><a href="#" ><span class="'.$buttonCssClass.'"></span><div></div></a></li>',
366: 'a_class' => 'toolbar_btn eabi_dpdee_call_courier_button',
367: 'title' => $this->l('Order in DPD Courier'),
368: );
369: }
370: } else {
371:
372: $order = new Order(Tools::getValue('id_order'));
373: if ($pdf = $this->dataSendExecutor->getBarcode($order)) {
374: $jsonParams = array(
375: 'url' => '',
376: 'button' => '<li id="eabi-dpdee-parcel-pdf"><a href="#" ><span class="'.$buttonCssClass.'"></span><div></div></a></li>',
377: 'a_class' => 'toolbar_btn eabi_dpdee_print_slip_button',
378: 'title' => $this->l('Print packing slip'),
379: 'redirect_click' => urldecode($pdf),
380: );
381: } else {
382: return '';
383: }
384: }
385:
386: return $this->_getFooterJs($jsonParams);
387: }
388: }
389:
390: protected function ($jsonParams) {
391: $js = '';
392: $jQuerySelector = 'div.toolbarHead ul.cc_button';
393: if (substr(_PS_VERSION_, 0, 3) == "1.6") {
394: $jQuerySelector = 'ul#toolbar-nav';
395: }
396:
397: $js .= <<<JS
398: <script type="text/javascript">
399: // <![CDATA[
400: jQuery(document).ready(function() {
401: jQuery({$this->_toJson($jQuerySelector)}).eabi_dpdee_courierbutton(
402: {$this->_toJson($jsonParams)});
403: });
404: // ]]>
405: </script>
406: JS;
407: return $js;
408: }
409:
410: protected function _toJson($input) {
411: return json_encode($input);
412: }
413:
414: 415: 416:
417: public function () {
418:
419: $this->context->controller->addCSS($this->_path . 'css/' . self::NAME . '-public.css', 'all');
420:
421: if (substr(_PS_VERSION_, 0, 3) == "1.5") {
422: $this->context->controller->addCSS($this->_path . 'css/' . self::NAME . '-public_1.5.css', 'all');
423: }
424: $this->context->controller->addJS($this->_path . 'js/' . self::NAME . '-public.js');
425:
426: }
427:
428: 429: 430: 431: 432:
433: public function () {
434: $className = 'OrderOpcController';
435: $php_self = 'order-opc';
436: if ($this->context->controller instanceof $className && $this->context->controller->php_self == $php_self) {
437: if (!$this->_carrierDisplayed) {
438: return $this->hookExtraCarrier(array('cart' => $this->context->cart));
439: }
440: }
441: }
442:
443: 444: 445: 446:
447: protected function _postValidation() {
448: $errors = array();
449: if (strtoupper($_SERVER['REQUEST_METHOD']) != 'POST') {
450:
451: return $errors;
452: }
453: foreach ($this->_initFormFields() as $formFieldName => $formFieldData) {
454: $validationRules = isset($formFieldData['validate']) ? $formFieldData['validate'] : array();
455: $validationIfRules = isset($formFieldData['validate-if']) ? $formFieldData['validate-if'] : array();
456:
457: $selectValidationResult = $this->_getValidator()->validate('validate_select', strtoupper($formFieldName), $_POST, $validationIfRules, $formFieldData);
458: if (is_string($selectValidationResult)) {
459:
460: $errors[] = sprintf($selectValidationResult, $formFieldData['title']);
461: break;
462: }
463:
464: foreach ($validationRules as $validationRule) {
465: $validationResult = $this->_getValidator()->validate($validationRule, strtoupper($formFieldName), $_POST, $validationIfRules, $formFieldData);
466: if (is_string($validationResult)) {
467:
468: $errors[] = sprintf($this->l($validationResult), $formFieldData['title']);
469: break;
470: }
471: }
472: }
473:
474:
475: return $errors;
476: }
477:
478: 479: 480: 481:
482: private function _postProcess() {
483: $html = '';
484: $data = $_POST;
485: if (isset($data['btnSubmit'])) {
486: foreach ($this->_initFormFields() as $formFieldName => $formFieldDataSet) {
487:
488: if ($formFieldDataSet['type'] == 'multiselect') {
489: if (!isset($data[strtoupper($formFieldName)])) {
490: $data[strtoupper($formFieldName)] = '';
491: }
492: if (is_array($data[strtoupper($formFieldName)])) {
493: $data[strtoupper($formFieldName)] = implode(',', $data[strtoupper($formFieldName)]);
494: }
495: }
496:
497:
498: if (is_array($data[strtoupper($formFieldName)])) {
499: $data[strtoupper($formFieldName)] = serialize($data[strtoupper($formFieldName)]);
500: }
501: Configuration::updateValue(self::CONST_PREFIX . strtoupper($formFieldName), $data[strtoupper($formFieldName)]);
502:
503: }
504: $this->_getHelperModule()->setTaxGroup($this->name, $this->getConfigData('TAX'));
505: $title = $this->getConfigData('TITLE');
506: $finalTitle = $title;
507: if ($this->_isSerialized($title)) {
508: $title = @unserialize($title);
509: if (is_array($title)) {
510: $finalTitle = isset($title[$this->context->language->id]) ? $title[$this->context->language->id] : $title[0];
511: }
512: }
513: $this->_getHelperModule()->setDisplayName($this->name, $finalTitle);
514: $this->_getHelperModule()->refresh($this->name, true);
515:
516:
517: $html .= '<div class="conf confirm"><img src="../img/admin/ok.gif" alt="' . $this->l('ok') . '" /> ' . $this->l('Settings updated') . '</div>';
518: }
519: return $html;
520: }
521:
522: 523: 524: 525:
526: private function () {
527: $html = '<img src="../modules/' . $this->name . '/' . $this->name . '.png" style="float:left; margin-right:15px;"><b>' . $this->l('DPD offers high-quality shipping service from Estonia to whole Europe.') . '</b><br /><br />
528: ' . $this->l('DPD ParcelShop service can be used in Estonia, Latvia, and Lithuania by selecting preferred DPD ParcelShop from select menu.') . '<br />';
529: return $html;
530: }
531:
532: 533: 534: 535: 536: 537: 538: 539: 540: 541: 542: 543: 544: 545: 546: 547: 548: 549: 550: 551: 552:
553: public function ($params) {
554:
555: $shouldHide = false;
556: $this->_carrierDisplayed = true;
557:
558:
559: $cart = $params['cart'];
560: $summaryDetails = $cart->getSummaryDetails();
561:
562:
563: if ($this->getConfigData('SALLOWSPECIFIC') == '1') {
564: $allowedCountries = explode(',', $this->getConfigData('SPECIFICCOUNTRY'));
565: if (!in_array(Country::getIsoById($summaryDetails['delivery']->id_country), $allowedCountries)) {
566: $shouldHide = true;
567: }
568: }
569:
570:
571: if (!$summaryDetails['delivery']->country) {
572: $shouldHide = true;
573: if (!isset($params['address']) || !$params['address']) {
574: $params['address'] = (object) array(
575: 'id' => '0',
576: );
577: }
578: }
579:
580:
581: if ($this->getConfigData('CHECKITEMS') == 'yes' && !$shouldHide) {
582: $prods = $cart->getProducts();
583: foreach ($prods as $prod) {
584: if (stripos($prod['description_short'], '<!-- no dpd_ee_module -->') !== false) {
585: $shouldHide = true;
586: break;
587: }
588: }
589: }
590:
591:
592: $loadedProductWeights = array();
593: if (($this->getConfigData('MAX_PACKAGE_WEIGHT') > 0 || $this->getConfigData('MIN_PACKAGE_WEIGHT') > 0) && !$shouldHide) {
594: $products = $cart->getProducts();
595: foreach ($products as $product) {
596: if ($product['is_virtual']) {
597: continue;
598: }
599: for ($i = 0; $i < $product['cart_quantity']; $i++) {
600: $loadedProductWeights[] = $product['weight'];
601: }
602: if ($this->getConfigData('MAX_PACKAGE_WEIGHT') > 0 && !$shouldHide) {
603: if (max($loadedProductWeights) > (float) $this->getConfigData('MAX_PACKAGE_WEIGHT')) {
604: $shouldHide = true;
605: }
606: }
607: if ($this->getConfigData('MIN_PACKAGE_WEIGHT') > 0 && !$shouldHide) {
608: if (min($loadedProductWeights) > (float) $this->getConfigData('MIN_PACKAGE_WEIGHT')) {
609: $shouldHide = true;
610: }
611: }
612: }
613: }
614: $title = $this->getConfigData('TITLE');
615: $finalTitle = $title;
616: if ($this->_isSerialized($title)) {
617: $title = @unserialize($title);
618: if (is_array($title)) {
619: $finalTitle = isset($title[$this->context->language->id]) ? $title[$this->context->language->id] : $title[0];
620: }
621: }
622:
623: $extraParams = array(
624: 'id_address_delivery' => $cart->id_address_delivery,
625: 'price' => $this->getOrderShippingCost($cart),
626: 'title' => $finalTitle,
627: 'logo' => __PS_BASE_URI__ . 'modules/' . $this->name . '/logo.gif',
628: 'id_address_invoice' => $cart->id_address_invoice,
629: 'error_message' => '',
630: 'is_default' => false,
631: );
632:
633: return $this->_getHelperModule()->displayExtraCarrier($this->name, $extraParams, $shouldHide);
634: }
635:
636: protected function _isSerialized($input) {
637: return preg_match('/^([adObis]):/', $input);
638: }
639:
640:
641: 642: 643: 644:
645: public function getContent() {
646: $html = '<h2>' . $this->displayName . '</h2>';
647:
648: if (!empty($_POST)) {
649: $postErrors = $this->_postValidation();
650: if (!sizeof($postErrors)) {
651: $html .= $this->_postProcess();
652: } else {
653: foreach ($postErrors as $err) {
654: $html .= '<div class="alert error">' . $err . '</div>';
655: }
656: }
657: } else {
658: $html .= '<br />';
659: }
660: $html .= $this->_displayFormHeader();
661: $html .= $this->_displayForm();
662:
663:
664: return $html;
665: }
666:
667: 668: 669: 670:
671: protected function _displayForm() {
672: $html = '';
673: $html .= $this->_getFormHtml($_SERVER['REQUEST_URI'], 'post', $this->_initFormFields());
674: return $html;
675: }
676:
677: 678: 679: 680: 681:
682: public function getConfigData($param) {
683: $value = Configuration::get(self::CONST_PREFIX . $param);
684: if ($value === null || $value === false) {
685: $formFields = $this->_initFormFields();
686: if (isset($formFields[strtolower($param)]) && $formFields[strtolower($param)]['default']) {
687: return $formFields[strtolower($param)]['default'];
688: }
689: }
690: return $value;
691: }
692:
693: 694: 695: 696: 697:
698: public function getConfigDataForThis($param) {
699: $value = Configuration::get($this->_const_prefix . $param);
700: if ($value === null || $value === false) {
701: $formFields = $this->_initFormFields();
702: if (isset($formFields[strtolower($param)]) && $formFields[strtolower($param)]['default']) {
703: return $formFields[strtolower($param)]['default'];
704: }
705: }
706: return $value;
707: }
708:
709: 710: 711: 712: 713: 714: 715:
716: protected function _getFormHtml($action, $method, $formFields) {
717: $action = Tools::htmlentitiesUTF8($action);
718: $html = '';
719:
720: $formElementsHtml = '';
721: $formElementHelper = $this->_getHtmlHelper();
722: foreach ($formFields as $fieldName => $fieldData) {
723: $methodName = 'get' . ucfirst($fieldData['type']) . 'Html';
724: $fieldPropertyName = '_' . $fieldName;
725: $value = Tools::getValue(strtoupper($fieldName), $this->getConfigData(strtoupper($fieldName)));
726: if (method_exists($formElementHelper, $methodName)) {
727: $formElementsHtml .= $formElementHelper->$methodName(strtoupper($fieldName), $fieldData, $value);
728: } else {
729: $formElementsHtml .= $formElementHelper->getTextHtml(strtoupper($fieldName), $fieldData, $value);
730: }
731: }
732:
733: $formClass = eabi_dpd_parcelstore::NAME;
734:
735: $html .= <<<HTML
736: <form action="{$action}" method="{$method}">
737: <fieldset>
738: <legend><img src="../img/admin/contact.gif" alt="" />{$this->l('Configuration details')}</legend>
739: <table id="form" class="{$formClass}">
740: <colgroup class="label"></colgroup>
741: <colgroup class="value"></colgroup>
742: <tbody>
743: {$formElementsHtml}
744: <tr>
745: <td colspan="2"><input class="button" name="btnSubmit" value="{$this->l('Update settings')}" type="submit" /></td>
746: </tr>
747: </tbody>
748: </table>
749: </fieldset>
750: </form>
751: HTML;
752: return $html;
753: }
754:
755: 756: 757: 758: 759:
760: public function getOrderShippingCostExternal($cartObject) {
761: return $this->getOrderShippingCost($cartObject, 0);
762: }
763:
764: 765: 766: 767: 768: 769: 770: 771:
772: public function getOrderShippingCost($cartObject, $shippingPrice = 0) {
773: $codFee = 0;
774: if ($cartObject->id_customer > 0) {
775:
776: $freeGroups = explode(',', $this->getConfigData('FREE_GROUPS'));
777: if (count($freeGroups) > 0 && $this->getConfigData('FREE_GROUPS') != '') {
778: $customerGroups = CustomerCore::getGroupsStatic($cartObject->id_customer);
779: foreach ($customerGroups as $customerGroup) {
780: if (in_array($customerGroup, $freeGroups)) {
781:
782: return 0;
783: }
784: }
785: }
786: }
787: if (isset($cartObject->codFee) && $cartObject->codFee) {
788: $codFee = $cartObject->codFee;
789:
790:
791: $idTaxRulesGroup = $this->getConfigDataForThis('TAX');
792: if ($idTaxRulesGroup) {
793: $codFee = $codFee / (1 + ($this->_getTaxRateForCart($cartObject) / 100));
794: }
795: }
796:
797:
798:
799: $totalSum = $cartObject->getOrderTotal(true, Cart::BOTH_WITHOUT_SHIPPING);
800:
801:
802: if ($this->getConfigData('ENABLE_FREE_SHIPPING') == 'yes' && $totalSum >= Tools::convertPrice($this->getConfigData('FREE_SHIPPING_FROM'), Currency::getCurrencyInstance((int) ($cartObject->id_currency)))) {
803: return 0 + $codFee;
804: }
805:
806: $shippingMatrix = $this->_decodeShippingMatrix($this->getConfigDataForThis('HANDLING_FEE_COUNTRY'));
807: $destinationAddress = new Address($cartObject->id_address_delivery);
808:
809: if ($destinationAddress->id_country && ($destCountry = Country::getIsoById($destinationAddress->id_country)) && isset($shippingMatrix[$destCountry])) {
810:
811: if ($shippingMatrix[$destCountry]['free_shipping_from'] !== '') {
812: if ($totalSum >= Tools::convertPrice($shippingMatrix[$destCountry]['free_shipping_from'], Currency::getCurrencyInstance((int) ($cartObject->id_currency)))) {
813: return 0 + $codFee;
814: }
815: }
816:
817:
818: $loadedProductWeights = array();
819: if (($this->getConfigData('MAX_PACKAGE_WEIGHT') > 0 || $this->getConfigData('MIN_PACKAGE_WEIGHT') > 0)) {
820: $products = $cartObject->getProducts();
821: foreach ($products as $product) {
822: if ($product['is_virtual']) {
823: continue;
824: }
825: for ($i = 0; $i < $product['cart_quantity']; $i++) {
826: $loadedProductWeights[] = $product['weight'];
827: }
828: }
829: }
830:
831:
832:
833:
834: $packageWeight = $cartObject->getTotalWeight() - 0.000001;
835: $weightSet = 10;
836:
837:
838:
839:
840: $extraWeightCost = max(floor($packageWeight / $weightSet) * $shippingMatrix[$destCountry]['kg_price'], 0);
841:
842: $handlingFee = $shippingMatrix[$destCountry]['base_price'];
843: if ($this->getConfigData('HANDLING_ACTION') == 'P') {
844: $handlingFee = ($this->_getDpdHelper()->getNumberOfPackagesFromItemWeights($loadedProductWeights, $this->getConfigData('MAX_PACKAGE_WEIGHT'))) * $handlingFee;
845: }
846: $handlingFee += $extraWeightCost;
847:
848:
849: $idTaxRulesGroup = $this->getConfigDataForThis('TAX');
850: if ($idTaxRulesGroup) {
851: $handlingFee = $handlingFee / (1 + ($this->_getTaxRateForCart($cartObject)/100));
852: }
853:
854:
855: return Tools::convertPrice($handlingFee + $codFee, Currency::getCurrencyInstance((int) ($cartObject->
856: id_currency)));
857: }
858:
859: $handlingFee = (float) str_replace(',', '.', $this->getConfigData('HANDLING_FEE'));
860: if ($this->getConfigData('HANDLING_ACTION') == 'P') {
861: $price = ($this->_getDpdHelper()->getNumberOfPackagesFromItemWeights($loadedProductWeights, $this->getConfigData('MAX_PACKAGE_WEIGHT'))) * $handlingFee;
862: } else {
863: $price = $handlingFee;
864: }
865:
866: $idTaxRulesGroup = $this->getConfigDataForThis('TAX');
867: if ($idTaxRulesGroup) {
868: $price = $price / (1 + ($this->_getTaxRateForCart($cartObject)/100));
869: }
870:
871:
872: return Tools::convertPrice($price + $codFee, Currency::getCurrencyInstance((int) ($cartObject->
873: id_currency)));
874: }
875:
876:
877:
878: 879: 880: 881: 882: 883: 884:
885: public function getCodFee($address) {
886: if ($address->id_country) {
887: $shippingMatrix = $this->_decodeShippingMatrix($this->getConfigDataForThis('HANDLING_FEE_COUNTRY'));
888: if ($address->id_country && ($destCountry = Country::getIsoById($address->id_country)) && isset($shippingMatrix[$destCountry])) {
889:
890: if (isset($shippingMatrix[$destCountry]['cod_fee']) && $shippingMatrix[$destCountry]['cod_fee'] !== '') {
891: $codFee = (float) str_replace(',', '.', $shippingMatrix[$destCountry]['cod_fee']);
892: if ($codFee >= 0) {
893:
894:
895: return $codFee;
896: }
897: }
898: }
899: }
900:
901: return false;
902: }
903:
904: 905: 906: 907: 908: 909:
910: public function isCodEnabled($address) {
911: if ($address->id_country) {
912: $shippingMatrix = $this->_decodeShippingMatrix($this->getConfigDataForThis('HANDLING_FEE_COUNTRY'));
913: if ($address->id_country && ($destCountry = Country::getIsoById($address->id_country)) && isset($shippingMatrix[$destCountry])) {
914:
915: if (isset($shippingMatrix[$destCountry]['cod_fee']) && $shippingMatrix[$destCountry]['cod_fee'] !== '') {
916: $codFee = (float) str_replace(',', '.', $shippingMatrix[$destCountry]['cod_fee']);
917: if ($codFee >= 0) {
918: return true;
919: }
920: }
921: }
922: }
923:
924: return true;
925: }
926:
927:
928: 929: 930: 931:
932: protected function _getTaxRateForCart($cart) {
933:
934: $complete_product_list = $cart->getProducts();
935: $products = $complete_product_list;
936:
937: if (Configuration::get('PS_TAX_ADDRESS_TYPE') == 'id_address_invoice') {
938: $address_id = (int) $cart->id_address_invoice;
939: } elseif (count($products)) {
940: $prod = current($products);
941: $address_id = (int) $prod['id_address_delivery'];
942: } else {
943: $address_id = null;
944: }
945: if (!Address::addressExists($address_id)) {
946: $address_id = null;
947: }
948:
949: $carrier = $this->_getHelperModule()->getCarrierFromCode($this->name);
950:
951: $address = Address::initialize((int) $address_id);
952:
953: return $carrier->getTaxesRate($address);
954: }
955:
956: 957: 958: 959: 960: 961: 962: 963: 964: 965: 966:
967: protected function _decodeShippingMatrix($input) {
968: $shippingMatrix = @unserialize($input);
969: $result = array();
970: if (!is_array($shippingMatrix)) {
971: return $result;
972: }
973: foreach ($shippingMatrix as $countryDefinition) {
974: $result[$countryDefinition['country_id']] = $countryDefinition;
975: }
976: return $result;
977: }
978:
979: 980: 981: 982: 983:
984: protected function _initFormFields() {
985: if (count($this->form_fields)) {
986: return $this->form_fields;
987: }
988: $yesno = array(
989: 'yes' => $this->l('Yes'),
990: 'no' => $this->l('No'),
991: );
992: $boxUnits = array(
993: 'order' => $this->l('Per Order'),
994: 'item' => $this->l('Per Package'),
995: );
996: $countryUnits = array(
997: '0' => $this->l('All Allowed Countries'),
998: '1' => $this->l('Specific Countries'),
999: );
1000:
1001: $this->form_fields = array(
1002: 'title' => array(
1003: 'title' => $this->l('Title'),
1004: 'type' => 'multilang',
1005: 'description' => $this->l('This controls the title which the user sees during checkout.'),
1006: 'default' => $this->l('DPD Pakipoodi'),
1007: 'css' => 'width: 300px;',
1008: ),
1009: 'handling_fee' => array(
1010: 'title' => $this->l('Price'),
1011: 'type' => 'text',
1012: 'description' => '',
1013: 'default' => '4.90',
1014: 'css' => 'width: 300px;',
1015: 'validate' => array('required_entry', 'validate_number'),
1016: ),
1017: 'tax' => array(
1018: 'title' => $this->l('Tax Id'),
1019: 'type' => 'select',
1020: 'description' => $this->l('Prices here are tax inclusive'),
1021: 'default' => '',
1022: 'css' => 'width: 300px;',
1023: 'validate' => array(),
1024: 'options' => $this->_getHelperModule()->getTaxes(),
1025: ),
1026: 'handling_fee_country' => array(
1027: 'title' => $this->l('Price per country'),
1028: 'type' => 'countryprice',
1029: 'description' => $this->l('If country is not listed here, but this method is available, then general handling fee is applied'),
1030: 'default' => 'a:3:{s:18:"_1388439524852_852";a:5:{s:10:"country_id";s:2:"EE";s:10:"base_price";s:4:"4.90";s:8:"kg_price";s:1:"0";s:18:"free_shipping_from";s:0:"";s:7:"cod_fee";s:4:"2.50";}s:17:"_1388442604053_53";a:5:{s:10:"country_id";s:2:"LV";s:10:"base_price";s:5:"12.90";s:8:"kg_price";s:1:"0";s:18:"free_shipping_from";s:0:"";s:7:"cod_fee";s:4:"2.50";}s:18:"_1388709088932_932";a:5:{s:10:"country_id";s:2:"LT";s:10:"base_price";s:5:"13.90";s:8:"kg_price";s:1:"0";s:18:"free_shipping_from";s:0:"";s:7:"cod_fee";s:4:"2.50";}}',
1031: 'css' => 'width: 300px;',
1032: 'validate' => array('validate_handling_fee_country'),
1033: ),
1034: 'shortname' => array(
1035: 'title' => $this->l('Show short office names'),
1036: 'type' => 'select',
1037: 'description' => $this->l('Yes: Shows only office name') . '<br/>' . $this->l('No: Shows office name and address'),
1038: 'default' => 'yes',
1039: 'css' => 'width: 300px;',
1040: 'options' => $yesno,
1041: ),
1042: 'sort_offices' => array(
1043: 'title' => $this->l('Sort offices by priority'),
1044: 'type' => 'select',
1045: 'description' => $this->l('Yes: Offices from bigger cities will be in front')
1046: . '<br/>' . $this->l('No: Offices are sorted alphabetically')
1047: ,
1048: 'default' => 'yes',
1049: 'css' => 'width: 300px;',
1050: 'options' => $yesno,
1051: ),
1052: 'checkitems' => array(
1053: 'title' => sprintf($this->l('Disable this carrier if product\'s short description contains HTML comment %s'), '<!-- no dpd_ee_module -->'),
1054: 'type' => 'select',
1055: 'description' => '',
1056: 'default' => 'no',
1057: 'css' => 'width: 300px;',
1058: 'options' => $yesno,
1059: ),
1060: 'max_package_weight' => array(
1061: 'title' => $this->l('Maximum allowed package weight for this carrier'),
1062: 'type' => 'text',
1063: 'description' => '',
1064: 'default' => '20',
1065: 'css' => 'width: 300px;',
1066: ),
1067: 'handling_action' => array(
1068: 'title' => $this->l('Handling action'),
1069: 'type' => 'select',
1070: 'description' => $this->l('Per Order: Shipping cost equals Shipping price')
1071: . '<br/>' . $this->l('Per Package: Shipping cost equals Number of Items in cart multiplied by shipping price')
1072: ,
1073: 'default' => 'yes',
1074: 'css' => 'width: 300px;',
1075: 'options' => $boxUnits,
1076: ),
1077: 'free_groups' => array(
1078: 'title' => $this->l('Client groups who can get free shipping'),
1079: 'type' => 'multiselect',
1080: 'description' => $this->l('hold down CTRL / CMD button to select/deselect multiple'),
1081: 'default' => '',
1082: 'css' => 'width: 300px;',
1083: 'options' => $this->_getHelperModule()->getClientGroups(),
1084: ),
1085: 'enable_free_shipping' => array(
1086: 'title' => $this->l('Enable free shipping'),
1087: 'type' => 'select',
1088: 'description' => '',
1089: 'default' => 'no',
1090: 'css' => 'width: 300px;',
1091: 'options' => $yesno,
1092: ),
1093: 'free_shipping_from' => array(
1094: 'title' => $this->l('Free shipping subtotal'),
1095: 'type' => 'text',
1096: 'description' => '',
1097: 'default' => '',
1098: 'css' => 'width: 300px;',
1099: 'validate' => array('validate_number'),
1100: ),
1101: 'sallowspecific' => array(
1102: 'title' => $this->l('Ship to applicable countries'),
1103: 'type' => 'select',
1104: 'description' => '',
1105: 'default' => '1',
1106: 'css' => 'width: 300px;',
1107: 'options' => $countryUnits,
1108: ),
1109: 'specificcountry' => array(
1110: 'title' => $this->l('Ship to Specific countries'),
1111: 'type' => 'multiselect',
1112: 'description' => '',
1113: 'default' => 'EE,LV,LT',
1114: 'css' => 'width: 300px;',
1115: 'options' => $this->_getHelperModule()->getCountriesAsOptions(),
1116: ),
1117: 'dis_first' => array(
1118: 'title' => $this->l('Show customer one dropdown instead of two'),
1119: 'type' => 'select',
1120: 'description' => $this->l('If this setting is enabled, then customer will be displayed only with a list of stores you entered.')
1121: . '<br/>' . $this->l('If this setting is disabled, then customer has to pick country/city first and then customer will be displayed second select menu, which contains stores in the selected county/city.'),
1122: 'default' => 'yes',
1123: 'css' => 'width: 300px;',
1124: 'options' => $yesno,
1125: ),
1126: 'gr_width' => array(
1127: 'title' => $this->l('Width in pixels for city select menu'),
1128: 'type' => 'text',
1129: 'description' => $this->l('Use only when you feel that select menu is too wide.'),
1130: 'default' => '',
1131: 'css' => 'width: 300px;',
1132: ),
1133: 'of_width' => array(
1134: 'title' => $this->l('Width in pixels for office select menu'),
1135: 'type' => 'text',
1136: 'description' => $this->l('Use only when you feel that select menu is too wide.'),
1137: 'default' => '250',
1138: 'css' => 'width: 300px;',
1139: ),
1140: );
1141:
1142:
1143: if ($this->dataSendExecutor) {
1144: $this->form_fields = $this->addArrayAfterKey($this->form_fields, $this->dataSendExecutor->initFormFields(), 'free_shipping_from');
1145: }
1146:
1147: return $this->form_fields;
1148: }
1149:
1150: 1151: 1152: 1153: 1154: 1155:
1156: public function displayInfoByCart($cart_id) {
1157: $offices = $this->_getHelperModule()->getOfficesFromCart($cart_id);
1158: $terminals = array();
1159: foreach ($offices as $address_id => $office) {
1160: $terminals[] = $this->getAdminTerminalTitle($office);
1161: }
1162: if ($this->dataSendExecutor != null) {
1163: $extraInfo = $this->dataSendExecutor->displayInfoByCart($cart_id);
1164: }
1165: return '<div class="eabi_dpd_parcelstore_chosen">'.$this->l('Chosen parcel terminal:') . ' <b>' . implode(', ', $terminals) . '</b>' . $extraInfo.'</div>';
1166: }
1167:
1168: 1169: 1170: 1171: 1172: 1173: 1174:
1175: public function addArrayAfterKey($inputArray, $appendArray, $afterKey = false) {
1176: $resultingArray = array();
1177: $appended = false;
1178: if (!is_string($afterKey)) {
1179: $afterKey = false;
1180: }
1181:
1182: foreach ($inputArray as $key => $value) {
1183: $resultingArray[$key] = $value;
1184: if ($key === $afterKey) {
1185: foreach ($appendArray as $iKey => $iValue) {
1186: $resultingArray[$iKey] = $iValue;
1187: }
1188: $appended = true;
1189: }
1190: }
1191:
1192: if (!$appended) {
1193: foreach ($appendArray as $iKey => $iValue) {
1194: $resultingArray[$iKey] = $iValue;
1195: }
1196: $appended = true;
1197: }
1198: return $resultingArray;
1199: }
1200:
1201: 1202: 1203: 1204:
1205: public function _getHelperModule() {
1206: if (is_null(self::$_helperModuleInstance)) {
1207: self::$_helperModuleInstance = Module::getInstanceByName('eabi_postoffice');
1208: }
1209: return self::$_helperModuleInstance;
1210: }
1211:
1212: 1213: 1214: 1215:
1216: public function getUpdateInterval() {
1217: $interval = $this->getConfigData('UPD_INTERVAL');
1218: if (!$interval) {
1219: return 1440;
1220: }
1221: return $interval;
1222: }
1223:
1224: 1225: 1226: 1227: 1228:
1229: public function setLastUpdated($lastUpdated) {
1230: Configuration::updateValue(self::CONST_PREFIX . 'LST_UPD', $lastUpdated);
1231: return;
1232: }
1233:
1234: 1235: 1236: 1237:
1238: public function getLastUpdated() {
1239: return $this->getConfigData('LST_UPD');
1240: }
1241:
1242: 1243: 1244: 1245: 1246:
1247: public function getGroupTitle($group) {
1248: return htmlspecialchars($group['group_name']);
1249: }
1250:
1251: 1252: 1253: 1254: 1255: 1256:
1257: public function getTerminalTitle($terminal) {
1258: if ($this->getConfigData('SHORTNAME') == 'yes') {
1259: return htmlspecialchars($terminal['name']);
1260: }
1261: return htmlspecialchars($terminal['name'] . ' (' . $terminal['description'] . ')');
1262: }
1263:
1264: 1265: 1266: 1267: 1268: 1269:
1270: public function getAdminTerminalTitle($terminal) {
1271: if ($this->getConfigData('SHORTNAME') == 'yes') {
1272: return htmlspecialchars($terminal['group_name'] . ' - ' . $terminal['name']);
1273: }
1274: return htmlspecialchars($terminal['group_name'] . ' - ' . $terminal['name'] . ' ' . $terminal['description']);
1275: }
1276:
1277: 1278: 1279: 1280: 1281:
1282: public function ls($string) {
1283: return $this->l($string);
1284: }
1285:
1286: 1287: 1288: 1289:
1290: public function getOfficeList() {
1291:
1292: $url = $this->getConfigData('API_URL');
1293:
1294: $auth = '';
1295: if (strpos($url, 'dpd.surflink.ee') > 0) {
1296: $auth = "Authorization: Basic " . base64_encode("demo:demo") . "\r\n";
1297: }
1298:
1299: $options = array(
1300: 'http' => array(
1301: 'method' => 'POST',
1302: 'header' => $auth ."Content-type: application/x-www-form-urlencoded\r\n",
1303:
1304: 'content' => http_build_query(array('op' => 'pudo')),
1305: ));
1306: $context = stream_context_create($options);
1307: $postRequestResult = file_get_contents($url, false, $context);
1308: $body = @json_decode($postRequestResult, true);
1309: if (!is_array($body) || !isset($body['Error_code']) || $body['Error_code'] !== 0) {
1310: throw new Exception(sprintf($this->l('DPD request failed with response: %s'), print_r($body, true)));
1311: }
1312:
1313:
1314:
1315:
1316: if (!$body || !is_array($body) || !isset($body['data'])) {
1317: return false;
1318: }
1319: $result = array();
1320: foreach ($body['data'] as $remoteParcelTerminal) {
1321: $result[] = array(
1322: 'place_id' => $remoteParcelTerminal['Sh_pudo_id'],
1323: 'name' => $remoteParcelTerminal['Pudo_name'],
1324: 'city' => trim($remoteParcelTerminal['Sh_city']),
1325: 'county' => '',
1326: 'description' => $this->_getDescription($remoteParcelTerminal),
1327: 'country' => $remoteParcelTerminal['Sh_country'],
1328: 'zip' => $remoteParcelTerminal['Sh_postal'],
1329: 'group_sort' => $this->getGroupSort($remoteParcelTerminal['Sh_city']),
1330: );
1331: }
1332: if (count($result) == 0) {
1333: return false;
1334: }
1335: return $result;
1336: }
1337:
1338: 1339: 1340: 1341: 1342:
1343: protected function _getDescription($parcelT) {
1344: if (!isset($parcelT['Pudo_worktime']) || !$parcelT['Pudo_worktime']) {
1345: return trim($parcelT['Sh_street'] . ' ' . $parcelT['Sh_city'] . ' ' . $parcelT['Sh_postal'] . ', ' . $parcelT['Sh_country'] . ' ' . $parcelT['Sh_phone']);
1346: } else {
1347: return trim($parcelT['Sh_street'] . ' ' . $parcelT['Sh_city'] . ' ' . $parcelT['Sh_postal'] . ', ' . $parcelT['Sh_country'] . ' ' . $parcelT['Sh_phone']
1348: . ' ' . $this->_getDpdHelper()->getOpeningsDescriptionFromTerminal($parcelT['Pudo_worktime'], $this->_getDpdHelper()->getLocaleToTerritory(strtoupper($parcelT['Sh_country']))));
1349: }
1350: }
1351:
1352: 1353: 1354: 1355: 1356: 1357: 1358: 1359: 1360: 1361: 1362:
1363: public function getGroupSort($group_name) {
1364: $group_name = trim(strtolower($group_name));
1365: $sorts = array(
1366:
1367: 'tallinn' => 20,
1368: 'tartu' => 19,
1369: 'pärnu' => 18,
1370:
1371: 'riga' => 20,
1372: 'daugavpils' => 19,
1373: 'liepaja' => 18,
1374: 'jelgava' => 17,
1375: 'jurmala' => 16,
1376:
1377: 'vilnius' => 20,
1378: 'kaunas' => 19,
1379: 'klaipeda' => 18,
1380: 'siauliai' => 17,
1381: 'alytus' => 16,
1382: );
1383: if (isset($sorts[$group_name]) && $this->getConfigData('SORT_OFFICES')) {
1384: return $sorts[$group_name];
1385: }
1386: if (strpos($group_name, '/') > 0 && $this->getConfigData('SORT_OFFICES')) {
1387: return 0;
1388: }
1389: return 0;
1390: }
1391:
1392: 1393: 1394: 1395:
1396: protected function _getValidator() {
1397: return $this->_getHelperModule()->helper('validator_helper', eabi_dpd_parcelstore::NAME);
1398: }
1399:
1400: 1401: 1402: 1403:
1404: protected function _getHtmlHelper() {
1405:
1406: $helper = $this->_getHelperModule()->helper('html_helper', eabi_dpd_parcelstore::NAME);
1407: $helper->setContext($this->context)->setModuleInstance($this);
1408: return $helper;
1409: }
1410:
1411: 1412: 1413: 1414:
1415: protected function _getDpdHelper() {
1416: return $this->_getHelperModule()->helper('dpd_helper', eabi_dpd_parcelstore::NAME);
1417: }
1418:
1419: 1420: 1421: 1422:
1423: protected function _getDialCodeHelper() {
1424: return $this->_getHelperModule()->helper('dialcode_helper', 'eabi_postoffice');
1425: }
1426:
1427: 1428: 1429: 1430: 1431:
1432: protected function ($order) {
1433: return '';
1434: }
1435:
1436: 1437: 1438: 1439: 1440: 1441:
1442: protected function _getNumberOfPackagesForOrder($order) {
1443: $productWeights = array();
1444: $orderItems = $order->getProducts();
1445: foreach ($orderItems as $orderItem) {
1446:
1447: for ($i = 0; $i < ($orderItem['product_quantity'] - $orderItem['product_quantity_refunded']); $i++) {
1448: $productWeights[] = $orderItem['product_weight'];
1449: }
1450: }
1451: return $this->_getDpdHelper()->getNumberOfPackagesFromItemWeights($productWeights, $this->getConfigData('MAX_PACKAGE_WEIGHT'));
1452: }
1453:
1454:
1455:
1456: 1457: 1458: 1459:
1460: public function upgrade_module_0_6() {
1461: 1462: 1463: 1464: 1465: 1466: 1467: 1468:
1469: $configPaths = array(
1470: 'E_DPDEEP_HANDLING_FEE_COUNTRY',
1471: );
1472: $countriesToApply = array(
1473: 'EE', 'LV', 'LT',
1474: );
1475: $db = Db::getInstance();
1476:
1477:
1478:
1479: $inConfigPaths = implode("','", $configPaths);
1480: $sql = "SELECT * FROM `"._DB_PREFIX_."configuration` where `name` IN ('{$inConfigPaths}')";
1481: $configDatas = $db->executeS($sql, true);
1482:
1483: foreach ($configDatas as $configData) {
1484: $oldShippingPriceSet = @unserialize($configData['value']);
1485:
1486: if (is_array($oldShippingPriceSet)) {
1487: foreach ($oldShippingPriceSet as $randomKey => $countryPrices) {
1488: if (in_array($countryPrices['country_id'], $countriesToApply)) {
1489: if (!isset($countryPrices['cod_fee']) || !$countryPrices['cod_fee']) {
1490: $oldShippingPriceSet[$randomKey]['cod_fee'] = '2.50';
1491: }
1492: }
1493: }
1494:
1495: $configData['value'] = serialize($oldShippingPriceSet);
1496: $idConfiguration = $configData['id_configuration'];
1497:
1498:
1499: unset($configData['id_configuration']);
1500:
1501:
1502:
1503: unset($configData['id_shop']);
1504: unset($configData['id_shop_group']);
1505: unset($configData['name']);
1506:
1507: $res = $db->update('configuration', $configData, "id_configuration = '{$db->escape($idConfiguration)}'");
1508: if ($res === false) {
1509: return false;
1510: }
1511: }
1512: }
1513: return true;
1514: }
1515:
1516:
1517: public function upgrade_module_0_8() {
1518: $configPaths = array(
1519: 'E_DPDEEP_API_URL',
1520: );
1521: $db = Db::getInstance();
1522: $inConfigPaths = implode("','", $configPaths);
1523: $sql = "SELECT * FROM `" . _DB_PREFIX_ . "configuration` where `name` IN ('{$inConfigPaths}')";
1524: $configDatas = $db->executeS($sql, true);
1525:
1526:
1527: foreach ($configDatas as $configData) {
1528: $oldValue = $configData['value'];
1529: if ($oldValue == 'http://dpd.surflink.ee/rpc/gateway/' || $oldValue == 'http://dpd.surflink.ee/rpc/gateway') {
1530: $configData['value'] = 'http://demo.surflink.ee:51680/rpc/gateway/';
1531: $idConfiguration = $configData['id_configuration'];
1532:
1533:
1534: unset($configData['id_configuration']);
1535:
1536:
1537:
1538: unset($configData['id_shop']);
1539: unset($configData['id_shop_group']);
1540: unset($configData['name']);
1541:
1542: $res = $db->update('configuration', $configData, "id_configuration = '{$db->escape($idConfiguration)}'");
1543: if ($res === false) {
1544: return false;
1545: }
1546: }
1547: }
1548: return true;
1549: }
1550:
1551: }
1552: