DPDFrance_Shipping - Version 5.1.2

Version Notes

DPDFrance_Shipping for Magento CE 1.4 - 1.9

Download this release

Release Info

Developer DPD France S.A.S.
Extension DPDFrance_Shipping
Version 5.1.2
Comparing to
See all releases


Code changes from version 5.1.1 to 5.1.2

Files changed (43) hide show
  1. app/code/community/DPDFrance/Classic/Helper/Data.php +3 -3
  2. app/code/community/DPDFrance/Classic/Model/Carrier/DPDFranceClassicShipping.php +305 -305
  3. app/code/community/DPDFrance/Classic/Model/Owebia.php +947 -1150
  4. app/code/community/DPDFrance/Classic/etc/config.xml +60 -107
  5. app/code/community/DPDFrance/Classic/etc/system.xml +3 -3
  6. app/code/community/DPDFrance/Export/Block/Export/Orders.php +3 -3
  7. app/code/community/DPDFrance/Export/Block/Export/Orders/Grid.php +3 -3
  8. app/code/community/DPDFrance/Export/Block/Tracking/Orders.php +3 -3
  9. app/code/community/DPDFrance/Export/Block/Tracking/Orders/Grid.php +3 -3
  10. app/code/community/DPDFrance/Export/Helper/Data.php +3 -3
  11. app/code/community/DPDFrance/Export/controllers/ExportController.php +3 -3
  12. app/code/community/DPDFrance/Export/controllers/TrackingController.php +3 -3
  13. app/code/community/DPDFrance/Export/etc/config.xml +4 -4
  14. app/code/community/DPDFrance/Predict/Helper/Data.php +3 -3
  15. app/code/community/DPDFrance/Predict/Model/Carrier/DPDFrancePredictShipping.php +305 -305
  16. app/code/community/DPDFrance/Predict/Model/Observer.php +3 -3
  17. app/code/community/DPDFrance/Predict/Model/Owebia.php +948 -1150
  18. app/code/community/DPDFrance/Predict/etc/config.xml +28 -47
  19. app/code/community/DPDFrance/Predict/etc/system.xml +3 -3
  20. app/code/community/DPDFrance/Relais/Helper/Data.php +3 -3
  21. app/code/community/DPDFrance/Relais/Model/Carrier/DPDFranceRelaisShipping.php +305 -305
  22. app/code/community/DPDFrance/Relais/Model/Observer.php +3 -3
  23. app/code/community/DPDFrance/Relais/Model/Outputs.php +3 -3
  24. app/code/community/DPDFrance/Relais/Model/Owebia.php +949 -1152
  25. app/code/community/DPDFrance/Relais/controllers/PickupController.php +3 -3
  26. app/code/community/DPDFrance/Relais/etc/config.xml +28 -47
  27. app/code/community/DPDFrance/Relais/etc/system.xml +3 -3
  28. app/design/frontend/base/default/layout/dpdfrpredict.xml +3 -3
  29. app/design/frontend/base/default/layout/dpdfrrelais.xml +3 -3
  30. app/design/frontend/base/default/template/dpdfrpredict/checkout/onepage/progress/shipping.phtml +3 -3
  31. app/design/frontend/base/default/template/dpdfrpredict/checkout/onepage/progress/shipping_method.phtml +3 -3
  32. app/design/frontend/base/default/template/dpdfrpredict/checkout/onepage/shipping_method.phtml +3 -3
  33. app/design/frontend/base/default/template/dpdfrpredict/checkout/onepage/shipping_method/available.phtml +3 -3
  34. app/design/frontend/base/default/template/dpdfrrelais/checkout/onepage/progress/shipping.phtml +3 -3
  35. app/design/frontend/base/default/template/dpdfrrelais/checkout/onepage/progress/shipping_method.phtml +3 -3
  36. app/design/frontend/base/default/template/dpdfrrelais/checkout/onepage/shipping_method.phtml +3 -3
  37. app/design/frontend/base/default/template/dpdfrrelais/checkout/onepage/shipping_method/available.phtml +3 -3
  38. media/dpdfrance/readme_dpdfrance_magento.pdf +0 -0
  39. package.xml +4 -4
  40. skin/frontend/base/default/css/dpdfrance/dpdfrpredict.css +3 -3
  41. skin/frontend/base/default/css/dpdfrance/dpdfrrelais.css +3 -3
  42. skin/frontend/base/default/js/dpdfrance/dpdfrpredict.js +3 -3
  43. skin/frontend/base/default/js/dpdfrance/dpdfrrelais.js +3 -3
app/code/community/DPDFrance/Classic/Helper/Data.php CHANGED
@@ -1,11 +1,11 @@
1
  <?php
2
  /**
3
- * DPD France v5.1.0 shipping module for Magento
4
  *
5
  * @category DPDFrance
6
  * @package DPDFrance_Shipping
7
- * @author DPD S.A.S. <ensavoirplus.ecommerce@dpd.fr>
8
- * @copyright 2015 DPD S.A.S., société par actions simplifiée, au capital de 18.500.000 euros, dont le siège social est situé 27 Rue du Colonel Pierre Avia - 75015 PARIS, immatriculée au registre du commerce et des sociétés de Paris sous le numéro 444 420 830
9
  * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
10
  */
11
 
1
  <?php
2
  /**
3
+ * DPD France v5.1.2 shipping module for Magento
4
  *
5
  * @category DPDFrance
6
  * @package DPDFrance_Shipping
7
+ * @author DPD France S.A.S. <ensavoirplus.ecommerce@dpd.fr>
8
+ * @copyright 2015 DPD France S.A.S., société par actions simplifiée, au capital de 18.500.000 euros, dont le siège social est situé 27 Rue du Colonel Pierre Avia - 75015 PARIS, immatriculée au registre du commerce et des sociétés de Paris sous le numéro 444 420 830
9
  * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
10
  */
11
 
app/code/community/DPDFrance/Classic/Model/Carrier/DPDFranceClassicShipping.php CHANGED
@@ -1,31 +1,31 @@
1
  <?php
2
  /**
3
- * DPD France v5.1.0 shipping module for Magento
4
  *
5
  * @category DPDFrance
6
  * @package DPDFrance_Shipping
7
- * @author DPD S.A.S. <ensavoirplus.ecommerce@dpd.fr>
8
- * @copyright 2015 DPD S.A.S., société par actions simplifiée, au capital de 18.500.000 euros, dont le siège social est situé 27 Rue du Colonel Pierre Avia - 75015 PARIS, immatriculée au registre du commerce et des sociétés de Paris sous le numéro 444 420 830
9
  * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
10
  */
11
 
12
  class DPDFrance_Classic_Model_Carrier_DPDFranceClassicShipping extends Mage_Shipping_Model_Carrier_Abstract {
13
 
14
- protected $_code = "dpdfrclassic";
15
- protected $_expenseConfig;
16
- /**
17
- * Owebia
18
- *
19
- * @var DPDFrance_Classic_Model_Owebia
20
- */
21
- protected $_owebiaCore;
22
- protected $_messages;
23
-
24
- protected function _addMessages($messages) {
25
- if (!is_array($messages)) $messages = array($messages);
26
- if (!is_array($this->_messages)) $this->_messages = $messages;
27
- else $this->_messages = array_merge($this->_messages, $messages);
28
- }
29
 
30
  public function getAllowedMethods() {
31
  $process = array();
@@ -39,26 +39,26 @@ class DPDFrance_Classic_Model_Carrier_DPDFranceClassicShipping extends Mage_Ship
39
  return $allowed_methods;
40
  }
41
 
42
- protected function _appendMethod($process, $row, $fees) {
43
- $method = Mage::getModel('shipping/rate_result_method')
44
- ->setCarrier($this->_code)
45
- ->setCarrierTitle($this->getConfigData('title'))
46
- ->setMethod($row['*code'])
47
- // ->setMethod('dpdfrclassic')
48
- ->setMethodTitle($this->getConfigData('methodname') . ' ' . $this->_getMethodText($process,$row,'label'))
49
- //->setMethodDescription($this->_getMethodText($process,$row,'description')) // can be enabled if necessary
50
- ->setPrice($fees)
51
- ->setCost($fees)
52
- ;
53
-
54
- $process['result']->append($method);
55
- }
56
-
57
- protected function _formatPrice($price) {
58
- return Mage::helper('core')->currency($price);
59
- }
60
-
61
- protected function _getCartTaxAmount($process) {
62
  $quote = Mage::getSingleton('checkout/session')->getQuote();
63
  $items_in_cart = $quote->getAllVisibleItems();
64
  // var_dump($quote, $items_in_cart);exit;
@@ -86,194 +86,194 @@ class DPDFrance_Classic_Model_Carrier_DPDFranceClassicShipping extends Mage_Ship
86
 
87
  }
88
 
89
- /**
90
- * Get Checkout Session Model
91
- *
92
- * @return Mage_Checkout_Model_Session
93
- */
94
- protected function _getCheckoutSession()
95
- {
96
- return Mage::getSingleton('checkout/session');
97
- }
98
-
99
- protected function _getConfig() {
100
- if (!isset($this->_expenseConfig)) {
101
- $this->_owebiaCore = Mage::getModel('dpdfrclassic/owebia', $this->getConfigData('expense'));
102
- $this->_expenseConfig = $this->_owebiaCore->getConfig();
103
- $this->_addMessages($this->_owebiaCore->getMessages());
104
- }
105
- return $this->_expenseConfig;
106
- }
107
-
108
- protected function _getCountryName($country_code) {
109
- return Mage::getModel('directory/country')->load($country_code)->getName();
110
- }
111
-
112
- protected function _getMethodText($process, $row, $property) {
113
- if (!isset($row[$property])) return '';
114
-
115
- return $this->_owebiaCore->evalInput($process,$row,$property,str_replace(
116
- array('{cart.weight}','{cart.price_including_tax}','{cart.price_excluding_tax}'),
117
- array(
118
- $process['data']['cart.weight'].$process['data']['cart.weight.unit'],
119
- $this->_formatPrice($process['data']['cart.price_including_tax']),
120
- $this->_formatPrice($process['data']['cart.price_excluding_tax'])
121
- ),
122
- $this->_owebiaCore->getRowProperty($row,$property)
123
- ));
124
- }
125
-
126
- protected function _process(&$process) {
127
- $store = Mage::app()->getStore($process['data']['store.id']);
128
- $timestamp = time();
129
- $customer_group_id = Mage::getSingleton('customer/session')->getCustomerGroupId();
130
- // Pour les commandes depuis Adminhtml
131
- if ($customer_group_id==0) {
132
- $customer_group_id2 = Mage::getSingleton('adminhtml/session_quote')->getQuote()->getCustomerGroupId();
133
- if (isset($customer_group_id2)) $customer_group_id = $customer_group_id2;
134
- }
135
-
136
- $customer_group_code = Mage::getSingleton('customer/group')->load($customer_group_id)->getData('customer_group_code');
137
- $process['data'] = array_merge($process['data'],array(
138
- 'customer.group.id' => $customer_group_id,
139
- 'customer.group.code' => $customer_group_code,
140
- 'destination.country.name' => $this->_getCountryName($process['data']['destination.country.code']),
141
- 'destination.postal.code' => Mage::getSingleton('checkout/session')->getQuote()->getShippingAddress()->getPostcode(),
142
- 'origin.country.name' => $this->_getCountryName($process['data']['origin.country.code']),
143
- 'cart.weight.unit' => 'kg',
144
- 'store.code' => $store->getCode(),
145
- 'store.name' => $store->getConfig('general/store_information/name'),
146
- 'store.address' => $store->getConfig('general/store_information/address'),
147
- 'store.phone' => $store->getConfig('general/store_information/phone'),
148
- 'date.timestamp' => $timestamp,
149
- 'date.year' => (int)date('Y',$timestamp),
150
- 'date.month' => (int)date('m',$timestamp),
151
- 'date.day' => (int)date('d',$timestamp),
152
- 'date.hour' => (int)date('H',$timestamp),
153
- 'date.minute' => (int)date('i',$timestamp),
154
- 'date.second' => (int)date('s',$timestamp),
155
- ));
156
-
157
- // We don't need process certain products. If necessary, enable this block.
158
- foreach ($process['cart.items'] as $id => $item) {
159
- if ($item->getProduct()->getTypeId()!='configurable') {
160
- $parent_item_id = $item->getParentItemId();
161
- $process['products'][] = new DPDFrance_Classic_Magento_Product($item, isset($process['cart.items'][$parent_item_id]) ? $process['cart.items'][$parent_item_id] : null);
162
- }
163
- }
164
-
165
-
166
- if (!$process['data']['free_shipping']) {
167
- foreach ($process['cart.items'] as $item) {
168
- if ($item->getProduct() instanceof Mage_Catalog_Model_Product) {
169
- if ($item->getFreeShipping()) $process['data']['free_shipping'] = true;
170
- else {
171
- $process['data']['free_shipping'] = false;
172
- break;
173
- }
174
- }
175
- }
176
- }
177
-
178
- $process['data']['cart.price_including_tax'] = $this->_getCartTaxAmount($process)+$process['data']['cart.price_excluding_tax'];
179
  // var_dump($process['data']['cart.price_excluding_tax'], $process['data']['cart.price_including_tax']);exit;
180
 
181
- $value_found = false;
182
- foreach ($this->_getConfig() as $row) {
183
- $result = $this->_owebiaCore->processRow($process, $row);
184
- $this->_addMessages($this->_owebiaCore->getMessages());
185
- if ($result->success) {
186
  if ($process['stop_to_first_match'] && $value_found) {
187
- // Mage::log('DPD Classic shipping Method : WARNING, destination is duplicated in BO configuration. Using first one, skipping others', Zend_Log::WARN);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
188
  break;
189
  }
190
- $value_found = true;
191
- $this->_appendMethod($process, $row, $result->result);
192
- }
193
- }
194
-
195
- if (!$value_found && $this->getConfigData('showerror')) $this->_setError($process, $this->getConfigData('specificerrmsg'));
196
- }
197
-
198
- protected function _setError(&$process, $message) {
199
- if (is_array($this->_messages))
200
- foreach ($this->_messages as $errMessage)
201
- if ($errMessage->type == 'over_weight') {
202
- $message = 'Your shopping cart is too heavy for being shipped by DPD Classic';
203
- break;
204
- }
205
- $error = Mage::getModel('shipping/rate_result_error')
206
- ->setCarrier($this->_code)
207
- ->setCarrierTitle($this->getConfigData('title'))
208
- ->setErrorMessage(Mage::helper('shipping')->__($message))
209
- ;
210
- $process['result'] = $error;
211
- }
212
-
213
- public function collectRates(Mage_Shipping_Model_Rate_Request $request){
214
- try {
215
- $process = array(
216
- 'result' => Mage::getModel('shipping/rate_result'),
217
- 'cart.items' => array(),
218
- 'products' => array(),
219
- 'data' => array(
220
- 'cart.price_excluding_tax' => $request->_data['package_value_with_discount'],
221
- 'cart.price_including_tax' => $request->_data['package_value_with_discount'],
222
- 'cart.weight' => $request->_data['package_weight'],
223
- 'cart.weight.unit' => null,
224
- 'cart.quantity' => $request->_data['package_qty'],
225
  'cart.coupon' => Mage::getSingleton('checkout/cart')->getQuote()->getCouponCode(),
226
- 'destination.country.code' => $request->_data['dest_country_id'],
227
- 'destination.country.name' => null,
228
- 'destination.region.code' => $request->_data['dest_region_code'],
229
- 'destination.postal.code' => $request->_data['dest_postcode'],
230
- 'origin.country.code' => $request->_data['country_id'],
231
- 'origin.country.name' => null,
232
- 'origin.region.code' => $request->_data['region_id'],
233
- 'origin.postal.code' => $request->_data['postcode'],
234
- 'customer.group.id' => null,
235
- 'customer.group.code' => null,
236
- 'free_shipping' => $request->getFreeShipping(),
237
- 'store.id' => $request->_data['store_id'],
238
- 'store.code' => null,
239
- 'store.name' => null,
240
- 'store.address' => null,
241
- 'store.phone' => null,
242
- 'date.timestamp' => null,
243
- 'date.year' => null,
244
- 'date.month' => null,
245
- 'date.day' => null,
246
- 'date.hour' => null,
247
- 'date.minute' => null,
248
- 'date.second' => null,
249
- ),
250
- 'stop_to_first_match' => TRUE,
251
- 'config' => null,
252
- );
253
-
254
- // We don't need process certain products. If necessary, enable this block.
255
- $items = $request->getAllItems();
256
- for ($i=0, $n=count($items); $i<$n; $i++) {
257
- $item = $items[$i];
258
- if ($item->getProduct() instanceof Mage_Catalog_Model_Product) $process['cart.items'][$item->getId()] = $item;
259
- }
260
-
261
-
262
- $this->_process($process);
263
- return $process['result'];
264
- }
265
- catch (Exception $e){
266
- Mage::logException($e);
267
- }
268
-
269
- }
270
-
271
- public function isTrackingAvailable() {
272
- return true;
273
- }
274
-
275
- public function getTrackingInfo($trackingNumber)
276
- {
277
  $trackingUrlByRef = 'http://www.dpd.fr/tracer_'.$trackingNumber;
278
  $trackingUrlByNb = 'http://www.dpd.fr/traces_'.$trackingNumber;
279
  $cargo = Mage::getStoreConfig('carriers/dpdfrclassic/cargo');
@@ -281,7 +281,7 @@ class DPDFrance_Classic_Model_Carrier_DPDFranceClassicShipping extends Mage_Ship
281
  $cargoutilise = substr($trackingNumber, -(int) $longueurcargo);
282
 
283
  if($cargoutilise == $cargo){
284
- $trackingStatus = Mage::getModel('shipping/tracking_result_status')
285
  ->setCarrier('dpdfrclassic')
286
  ->setCarrierTitle('DPD Classic')
287
  ->setTracking($trackingNumber)
@@ -309,93 +309,93 @@ class DPDFrance_Classic_Model_Carrier_DPDFranceClassicShipping extends Mage_Ship
309
  }
310
 
311
  class DPDFrance_Classic_Magento_Product implements DPDFrance_Classic_Os_Product {
312
- private $parent_cart_item;
313
- private $cart_item;
314
- private $cart_product;
315
- private $loaded_product;
316
- private $quantity;
317
-
318
- public function __construct($cart_item, $parent_cart_item) {
319
- $this->cart_item = $cart_item;
320
- $this->cart_product = $cart_item->getProduct();
321
- $this->parent_cart_item = $parent_cart_item;
322
- $this->quantity = isset($parent_cart_item) ? $parent_cart_item->getQty() : $cart_item->getQty();
323
- }
324
-
325
- public function getOption($option_name, $get_by_id=false) {
326
- $value = null;
327
- $product = $this->cart_product;
328
- foreach ($product->getOptions() as $option) {
329
- if ($option->getTitle()==$option_name) {
330
- $custom_option = $product->getCustomOption('option_'.$option->getId());
331
- if ($custom_option) {
332
- $value = $custom_option->getValue();
333
- if ($option->getType()=='drop_down' && !$get_by_id) {
334
- $option_value = $option->getValueById($value);
335
- if ($option_value) $value = $option_value->getTitle();
336
- }
337
- }
338
- break;
339
- }
340
- }
341
- return $value;
342
- }
343
-
344
- public function getAttribute($attribute_name, $get_by_id=false) {
345
- $value = null;
346
- $product = $this->_getLoadedProduct();
347
- $attribute = $product->getResource()->getAttribute($attribute_name);
348
- if ($attribute) {
349
- $input_type = $attribute->getFrontend()->getInputType();
350
- switch ($input_type) {
351
- case 'select' :
352
- $value = $get_by_id ? $product->getData($attribute_name) : $product->getAttributeText($attribute_name);
353
- break;
354
- default :
355
- $value = $product->getData($attribute_name);
356
- break;
357
- }
358
- }
359
- return $value;
360
- }
361
-
362
- private function _getLoadedProduct() {
363
- if (!isset($this->loaded_product)) $this->loaded_product = Mage::getModel('catalog/product')->load($this->cart_product->getId());
364
- return $this->loaded_product;
365
- }
366
-
367
- public function getQuantity() {
368
- return $this->quantity;
369
- }
370
-
371
- public function getName() {
372
- return $this->cart_product->getName();
373
- }
374
-
375
- public function getSku() {
376
- return $this->cart_product->getSku();
377
- }
378
-
379
- public function getStockData($key) {
380
- $stock = $this->cart_product->getStockItem();
381
- switch ($key) {
382
- case 'is_in_stock':
383
- return (bool)$stock->getIsInStock();
384
- case 'quantity':
385
- $quantity = $stock->getQty();
386
- return $stock->getIsQtyDecimal() ? (float)$quantity : (int)$quantity;
387
- }
388
- return null;
389
- }
390
  }
391
 
392
  interface DPDFrance_Classic_Os_Product {
393
- public function getOption($option);
394
- public function getAttribute($attribute);
395
- public function getName();
396
- public function getSku();
397
- public function getQuantity();
398
- public function getStockData($key);
399
  }
400
 
401
  ?>
1
  <?php
2
  /**
3
+ * DPD France v5.1.2 shipping module for Magento
4
  *
5
  * @category DPDFrance
6
  * @package DPDFrance_Shipping
7
+ * @author DPD France S.A.S. <ensavoirplus.ecommerce@dpd.fr>
8
+ * @copyright 2015 DPD France S.A.S., société par actions simplifiée, au capital de 18.500.000 euros, dont le siège social est situé 27 Rue du Colonel Pierre Avia - 75015 PARIS, immatriculée au registre du commerce et des sociétés de Paris sous le numéro 444 420 830
9
  * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
10
  */
11
 
12
  class DPDFrance_Classic_Model_Carrier_DPDFranceClassicShipping extends Mage_Shipping_Model_Carrier_Abstract {
13
 
14
+ protected $_code = "dpdfrclassic";
15
+ protected $_expenseConfig;
16
+ /**
17
+ * Owebia
18
+ *
19
+ * @var DPDFrance_Classic_Model_Owebia
20
+ */
21
+ protected $_owebiaCore;
22
+ protected $_messages;
23
+
24
+ protected function _addMessages($messages) {
25
+ if (!is_array($messages)) $messages = array($messages);
26
+ if (!is_array($this->_messages)) $this->_messages = $messages;
27
+ else $this->_messages = array_merge($this->_messages, $messages);
28
+ }
29
 
30
  public function getAllowedMethods() {
31
  $process = array();
39
  return $allowed_methods;
40
  }
41
 
42
+ protected function _appendMethod($process, $row, $fees) {
43
+ $method = Mage::getModel('shipping/rate_result_method')
44
+ ->setCarrier($this->_code)
45
+ ->setCarrierTitle($this->getConfigData('title'))
46
+ ->setMethod($row['*code'])
47
+ // ->setMethod('dpdfrclassic')
48
+ ->setMethodTitle($this->getConfigData('methodname') . ' ' . $this->_getMethodText($process,$row,'label'))
49
+ //->setMethodDescription($this->_getMethodText($process,$row,'description')) // can be enabled if necessary
50
+ ->setPrice($fees)
51
+ ->setCost($fees)
52
+ ;
53
+
54
+ $process['result']->append($method);
55
+ }
56
+
57
+ protected function _formatPrice($price) {
58
+ return Mage::helper('core')->currency($price);
59
+ }
60
+
61
+ protected function _getCartTaxAmount($process) {
62
  $quote = Mage::getSingleton('checkout/session')->getQuote();
63
  $items_in_cart = $quote->getAllVisibleItems();
64
  // var_dump($quote, $items_in_cart);exit;
86
 
87
  }
88
 
89
+ /**
90
+ * Get Checkout Session Model
91
+ *
92
+ * @return Mage_Checkout_Model_Session
93
+ */
94
+ protected function _getCheckoutSession()
95
+ {
96
+ return Mage::getSingleton('checkout/session');
97
+ }
98
+
99
+ protected function _getConfig() {
100
+ if (!isset($this->_expenseConfig)) {
101
+ $this->_owebiaCore = Mage::getModel('dpdfrclassic/owebia', $this->getConfigData('expense'));
102
+ $this->_expenseConfig = $this->_owebiaCore->getConfig();
103
+ $this->_addMessages($this->_owebiaCore->getMessages());
104
+ }
105
+ return $this->_expenseConfig;
106
+ }
107
+
108
+ protected function _getCountryName($country_code) {
109
+ return Mage::getModel('directory/country')->load($country_code)->getName();
110
+ }
111
+
112
+ protected function _getMethodText($process, $row, $property) {
113
+ if (!isset($row[$property])) return '';
114
+
115
+ return $this->_owebiaCore->evalInput($process,$row,$property,str_replace(
116
+ array('{cart.weight}','{cart.price_including_tax}','{cart.price_excluding_tax}'),
117
+ array(
118
+ $process['data']['cart.weight'].$process['data']['cart.weight.unit'],
119
+ $this->_formatPrice($process['data']['cart.price_including_tax']),
120
+ $this->_formatPrice($process['data']['cart.price_excluding_tax'])
121
+ ),
122
+ $this->_owebiaCore->getRowProperty($row,$property)
123
+ ));
124
+ }
125
+
126
+ protected function _process(&$process) {
127
+ $store = Mage::app()->getStore($process['data']['store.id']);
128
+ $timestamp = time();
129
+ $customer_group_id = Mage::getSingleton('customer/session')->getCustomerGroupId();
130
+ // Pour les commandes depuis Adminhtml
131
+ if ($customer_group_id==0) {
132
+ $customer_group_id2 = Mage::getSingleton('adminhtml/session_quote')->getQuote()->getCustomerGroupId();
133
+ if (isset($customer_group_id2)) $customer_group_id = $customer_group_id2;
134
+ }
135
+
136
+ $customer_group_code = Mage::getSingleton('customer/group')->load($customer_group_id)->getData('customer_group_code');
137
+ $process['data'] = array_merge($process['data'],array(
138
+ 'customer.group.id' => $customer_group_id,
139
+ 'customer.group.code' => $customer_group_code,
140
+ 'shipto.country.name' => $this->_getCountryName($process['data']['shipto.country.code']),
141
+ 'shipto.postal.code' => Mage::getSingleton('checkout/session')->getQuote()->getShippingAddress()->getPostcode(),
142
+ 'origin.country.name' => $this->_getCountryName($process['data']['origin.country.code']),
143
+ 'cart.weight.unit' => 'kg',
144
+ 'store.code' => $store->getCode(),
145
+ 'store.name' => $store->getConfig('general/store_information/name'),
146
+ 'store.address' => $store->getConfig('general/store_information/address'),
147
+ 'store.phone' => $store->getConfig('general/store_information/phone'),
148
+ 'date.timestamp' => $timestamp,
149
+ 'date.year' => (int)date('Y',$timestamp),
150
+ 'date.month' => (int)date('m',$timestamp),
151
+ 'date.day' => (int)date('d',$timestamp),
152
+ 'date.hour' => (int)date('H',$timestamp),
153
+ 'date.minute' => (int)date('i',$timestamp),
154
+ 'date.second' => (int)date('s',$timestamp),
155
+ ));
156
+
157
+ // We don't need process certain products. If necessary, enable this block.
158
+ foreach ($process['cart.items'] as $id => $item) {
159
+ if ($item->getProduct()->getTypeId()!='configurable') {
160
+ $parent_item_id = $item->getParentItemId();
161
+ $process['products'][] = new DPDFrance_Classic_Magento_Product($item, isset($process['cart.items'][$parent_item_id]) ? $process['cart.items'][$parent_item_id] : null);
162
+ }
163
+ }
164
+
165
+
166
+ if (!$process['data']['free_shipping']) {
167
+ foreach ($process['cart.items'] as $item) {
168
+ if ($item->getProduct() instanceof Mage_Catalog_Model_Product) {
169
+ if ($item->getFreeShipping()) $process['data']['free_shipping'] = true;
170
+ else {
171
+ $process['data']['free_shipping'] = false;
172
+ break;
173
+ }
174
+ }
175
+ }
176
+ }
177
+
178
+ $process['data']['cart.price_including_tax'] = $this->_getCartTaxAmount($process)+$process['data']['cart.price_excluding_tax'];
179
  // var_dump($process['data']['cart.price_excluding_tax'], $process['data']['cart.price_including_tax']);exit;
180
 
181
+ $value_found = false;
182
+ foreach ($this->_getConfig() as $row) {
183
+ $result = $this->_owebiaCore->processRow($process, $row);
184
+ $this->_addMessages($this->_owebiaCore->getMessages());
185
+ if ($result->success) {
186
  if ($process['stop_to_first_match'] && $value_found) {
187
+ // Mage::log('DPD Classic shipping Method : WARNING, shipto is duplicated in BO configuration. Using first one, skipping others', Zend_Log::WARN);
188
+ break;
189
+ }
190
+ $value_found = true;
191
+ $this->_appendMethod($process, $row, $result->result);
192
+ }
193
+ }
194
+
195
+ if (!$value_found && $this->getConfigData('showerror')) $this->_setError($process, $this->getConfigData('specificerrmsg'));
196
+ }
197
+
198
+ protected function _setError(&$process, $message) {
199
+ if (is_array($this->_messages))
200
+ foreach ($this->_messages as $errMessage)
201
+ if ($errMessage->type == 'over_weight') {
202
+ $message = 'Your shopping cart is too heavy for being shipped by DPD Classic';
203
  break;
204
  }
205
+ $error = Mage::getModel('shipping/rate_result_error')
206
+ ->setCarrier($this->_code)
207
+ ->setCarrierTitle($this->getConfigData('title'))
208
+ ->setErrorMessage(Mage::helper('shipping')->__($message))
209
+ ;
210
+ $process['result'] = $error;
211
+ }
212
+
213
+ public function collectRates(Mage_Shipping_Model_Rate_Request $request){
214
+ try {
215
+ $process = array(
216
+ 'result' => Mage::getModel('shipping/rate_result'),
217
+ 'cart.items' => array(),
218
+ 'products' => array(),
219
+ 'data' => array(
220
+ 'cart.price_excluding_tax' => $request->_data['package_value_with_discount'],
221
+ 'cart.price_including_tax' => $request->_data['package_value_with_discount'],
222
+ 'cart.weight' => $request->_data['package_weight'],
223
+ 'cart.weight.unit' => null,
224
+ 'cart.quantity' => $request->_data['package_qty'],
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
225
  'cart.coupon' => Mage::getSingleton('checkout/cart')->getQuote()->getCouponCode(),
226
+ 'shipto.country.code' => $request->_data['dest_country_id'],
227
+ 'shipto.country.name' => null,
228
+ 'shipto.region.code' => $request->_data['dest_region_code'],
229
+ 'shipto.postal.code' => $request->_data['dest_postcode'],
230
+ 'origin.country.code' => $request->_data['country_id'],
231
+ 'origin.country.name' => null,
232
+ 'origin.region.code' => $request->_data['region_id'],
233
+ 'origin.postal.code' => $request->_data['postcode'],
234
+ 'customer.group.id' => null,
235
+ 'customer.group.code' => null,
236
+ 'free_shipping' => $request->getFreeShipping(),
237
+ 'store.id' => $request->_data['store_id'],
238
+ 'store.code' => null,
239
+ 'store.name' => null,
240
+ 'store.address' => null,
241
+ 'store.phone' => null,
242
+ 'date.timestamp' => null,
243
+ 'date.year' => null,
244
+ 'date.month' => null,
245
+ 'date.day' => null,
246
+ 'date.hour' => null,
247
+ 'date.minute' => null,
248
+ 'date.second' => null,
249
+ ),
250
+ 'stop_to_first_match' => TRUE,
251
+ 'config' => null,
252
+ );
253
+
254
+ // We don't need process certain products. If necessary, enable this block.
255
+ $items = $request->getAllItems();
256
+ for ($i=0, $n=count($items); $i<$n; $i++) {
257
+ $item = $items[$i];
258
+ if ($item->getProduct() instanceof Mage_Catalog_Model_Product) $process['cart.items'][$item->getId()] = $item;
259
+ }
260
+
261
+
262
+ $this->_process($process);
263
+ return $process['result'];
264
+ }
265
+ catch (Exception $e){
266
+ Mage::logException($e);
267
+ }
268
+
269
+ }
270
+
271
+ public function isTrackingAvailable() {
272
+ return true;
273
+ }
274
+
275
+ public function getTrackingInfo($trackingNumber)
276
+ {
277
  $trackingUrlByRef = 'http://www.dpd.fr/tracer_'.$trackingNumber;
278
  $trackingUrlByNb = 'http://www.dpd.fr/traces_'.$trackingNumber;
279
  $cargo = Mage::getStoreConfig('carriers/dpdfrclassic/cargo');
281
  $cargoutilise = substr($trackingNumber, -(int) $longueurcargo);
282
 
283
  if($cargoutilise == $cargo){
284
+ $trackingStatus = Mage::getModel('shipping/tracking_result_status')
285
  ->setCarrier('dpdfrclassic')
286
  ->setCarrierTitle('DPD Classic')
287
  ->setTracking($trackingNumber)
309
  }
310
 
311
  class DPDFrance_Classic_Magento_Product implements DPDFrance_Classic_Os_Product {
312
+ private $parent_cart_item;
313
+ private $cart_item;
314
+ private $cart_product;
315
+ private $loaded_product;
316
+ private $quantity;
317
+
318
+ public function __construct($cart_item, $parent_cart_item) {
319
+ $this->cart_item = $cart_item;
320
+ $this->cart_product = $cart_item->getProduct();
321
+ $this->parent_cart_item = $parent_cart_item;
322
+ $this->quantity = isset($parent_cart_item) ? $parent_cart_item->getQty() : $cart_item->getQty();
323
+ }
324
+
325
+ public function getOption($option_name, $get_by_id=false) {
326
+ $value = null;
327
+ $product = $this->cart_product;
328
+ foreach ($product->getOptions() as $option) {
329
+ if ($option->getTitle()==$option_name) {
330
+ $custom_option = $product->getCustomOption('option_'.$option->getId());
331
+ if ($custom_option) {
332
+ $value = $custom_option->getValue();
333
+ if ($option->getType()=='drop_down' && !$get_by_id) {
334
+ $option_value = $option->getValueById($value);
335
+ if ($option_value) $value = $option_value->getTitle();
336
+ }
337
+ }
338
+ break;
339
+ }
340
+ }
341
+ return $value;
342
+ }
343
+
344
+ public function getAttribute($attribute_name, $get_by_id=false) {
345
+ $value = null;
346
+ $product = $this->_getLoadedProduct();
347
+ $attribute = $product->getResource()->getAttribute($attribute_name);
348
+ if ($attribute) {
349
+ $input_type = $attribute->getFrontend()->getInputType();
350
+ switch ($input_type) {
351
+ case 'select' :
352
+ $value = $get_by_id ? $product->getData($attribute_name) : $product->getAttributeText($attribute_name);
353
+ break;
354
+ default :
355
+ $value = $product->getData($attribute_name);
356
+ break;
357
+ }
358
+ }
359
+ return $value;
360
+ }
361
+
362
+ private function _getLoadedProduct() {
363
+ if (!isset($this->loaded_product)) $this->loaded_product = Mage::getModel('catalog/product')->load($this->cart_product->getId());
364
+ return $this->loaded_product;
365
+ }
366
+
367
+ public function getQuantity() {
368
+ return $this->quantity;
369
+ }
370
+
371
+ public function getName() {
372
+ return $this->cart_product->getName();
373
+ }
374
+
375
+ public function getSku() {
376
+ return $this->cart_product->getSku();
377
+ }
378
+
379
+ public function getStockData($key) {
380
+ $stock = $this->cart_product->getStockItem();
381
+ switch ($key) {
382
+ case 'is_in_stock':
383
+ return (bool)$stock->getIsInStock();
384
+ case 'quantity':
385
+ $quantity = $stock->getQty();
386
+ return $stock->getIsQtyDecimal() ? (float)$quantity : (int)$quantity;
387
+ }
388
+ return null;
389
+ }
390
  }
391
 
392
  interface DPDFrance_Classic_Os_Product {
393
+ public function getOption($option);
394
+ public function getAttribute($attribute);
395
+ public function getName();
396
+ public function getSku();
397
+ public function getQuantity();
398
+ public function getStockData($key);
399
  }
400
 
401
  ?>
app/code/community/DPDFrance/Classic/Model/Owebia.php CHANGED
@@ -1,1173 +1,970 @@
1
  <?php
2
  /**
3
- * DPD France v5.1.0 shipping module for Magento
4
  *
5
  * @category DPDFrance
6
  * @package DPDFrance_Shipping
7
- * @author DPD S.A.S. <ensavoirplus.ecommerce@dpd.fr>
8
- * @copyright 2015 DPD S.A.S., société par actions simplifiée, au capital de 18.500.000 euros, dont le siège social est situé 27 Rue du Colonel Pierre Avia - 75015 PARIS, immatriculée au registre du commerce et des sociétés de Paris sous le numéro 444 420 830
9
  * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
10
  */
11
 
12
  class DPDFrance_Classic_Model_Owebia
13
  {
14
- public static $FLOAT_REGEX = '[-]?\d+(?:[.]\d+)?';
15
- public static $POSITIVE_FLOAT_REGEX = '\d+(?:[.]\d+)?';
16
- //public static $COUPLE_REGEX = '(?:[0-9.]+|\*)(?:\[|\])?\:[0-9.]+(?:\:[0-9.]+%?)*';
17
- public static $COUPLE_REGEX = '(?:[0-9.]+|\*) *(?:\[|\])? *\: *[0-9.]+';
18
- public static $UNCOMPRESSED_STRINGS = array(
19
- ' product.attribute.',
20
- ' product.option.',
21
- ' product.stock.',
22
- '{product.attribute.',
23
- '{product.option.',
24
- '{product.stock.',
25
- '{product.weight}',
26
- '{product.quantity}',
27
- '{cart.weight}',
28
- '{cart.quantity}',
29
  '{cart.coupon}',
30
- '{cart.price_including_tax}',
31
- '{cart.price_excluding_tax}',
32
- '{cart.',
33
- '{customvar.',
34
- '{selection.weight}',
35
- '{selection.quantity}',
36
- '{selection.',
37
- '{destination.country.',
38
- '{foreach ',
39
- '{/foreach}',
40
- );
41
- public static $COMPRESSED_STRINGS = array(
42
- ' p.a.',
43
- ' p.o.',
44
- ' p.s.',
45
- '{p.a.',
46
- '{p.o.',
47
- '{p.s.',
48
- '{p.w}',
49
- '{p.qty}',
50
- '{c.w}',
51
- '{c.qty}',
52
  '{c.cpn}',
53
- '{c.pit}',
54
- '{c.pet}',
55
- '{c.',
56
- '{v.',
57
- '{s.w}',
58
- '{s.qty}',
59
- '{s.',
60
- '{dest.ctry.',
61
- '{each ',
62
- '{/each}',
63
- );
64
-
65
- protected $_input;
66
- protected $_config;
67
- protected $_messages;
68
- protected $_formula_cache;
69
- protected $_expression_cache;
70
- protected $_overWeightMessage = 'Over weight';
71
- public $debug = 0;
72
- public $debug_output = '';
73
- public $debug_header = null;
74
-
75
- public function __construct($input) {
76
- $this->_formula_cache = array();
77
- $this->_messages = array();
78
- $this->_input = $input;
79
- $this->_config = array();
80
- $this->_parseInput();
81
- }
82
-
83
- private function debug($text, $level=10) {
84
- if ($this->debug>=$level) $this->debug_output .= "<p>".$text."</p>";
85
- }
86
-
87
- public function printDebug() {
88
- if ($this->debug>0) echo "<style rel=\"stylesheet\" type=\"text/css\">"
89
- .".osh-formula{color:#f90;} .osh-key{color:#0099f7;}"
90
- .".osh-error{color:#f00;} .osh-warning{color:#ff0;} .osh-info{color:#7bf700;}"
91
- .".osh-debug{background:#000;color:#bbb;position:absolute;top:0;left:0;width:100%;z-index:100;-moz-opacity:0.9;opacity:0.9;text-align:left;white-space:pre-wrap;}"
92
- .".osh-debug-content{padding:10px;}"
93
- .".osh-replacement{color:#ff3000;}"
94
- ."</style>"
95
- ."<div id=\"osh-debug\" class=\"osh-debug\"><pre class=\"osh-debug-content\"><span style=\"float:right;cursor:pointer;\" onclick=\"document.getElementById('osh-debug').style.display = 'none';\">[<span style=\"padding:0 5px;color:#f00;\">X</span>]</span>"
96
- ."<p>".$this->debug_header."</p>".$this->debug_output."</pre></div>";
97
- }
98
-
99
- public function setDebugHeader($process) {
100
- $header = 'DEBUG ' . __FILE__;//'DEBUG app/code/community/Owebia/Shipping/2/Model/Carrier/OwebiaShippingHelper.php<br/>';
101
- foreach ($process['data'] as $key => $data) {
102
- $header .= ' <span class="osh-key">'.$key.'</span> = <span class="osh-formula">'.$this->_toString($data).'</span><br/>';
103
- }
104
- $this->debug_header = $header;
105
- }
106
-
107
- public function getConfig() {
108
- return $this->_config;
109
- }
110
-
111
- public function getMessages() {
112
- $messages = $this->_messages;
113
- $this->_messages = array();
114
- return $messages;
115
- }
116
-
117
- public function formatConfig($compress) {
118
- $output = '';
119
- foreach ($this->_config as $code => $row) {
120
- if (!isset($row['lines'])) {
121
- if (isset($row['*comment']['value'])) {
122
- $output .= trim($row['*comment']['value'])."\n";
123
- }
124
- $output .= '{'.($compress ? '' : "\n");
125
- foreach ($row as $key => $property) {
126
- if (substr($key,0,1)!='*') {
127
- $value = $property['value'];
128
- if (isset($property['comment'])) $output .= ($compress ? '' : "\t").'/* '.$property['comment'].' */'.($compress ? '' : "\n");
129
- $output .= ($compress ? '' : "\t").$key.':'.($compress ? '' : ' ');
130
- if (is_bool($value)) $output .= $value ? 'true' : 'false';
131
- else if (is_int($value)) $output .= $value;
132
- else if ((string)((float)$value)==$value) $output .= $value;
133
- else $output .= '"'.str_replace('"','\\"',$value).'"';
134
- $output .= ','.($compress ? '' : "\n");
135
- }
136
- }
137
- if ($compress) $output = preg_replace('/,$/','',$output);
138
- $output .= "}\n".($compress ? '' : "\n");
139
- } else {
140
- $output .= $row['lines']."\n";
141
- }
142
- }
143
- return $compress ? $this->compress($output) : $this->uncompress($output);
144
- }
145
-
146
- public function checkConfig() {
147
- $process = array(
148
- 'result' => null,
149
- 'data' => array(
150
- 'cart.price_excluding_tax' => 0,
151
- 'cart.price_including_tax' => 0,
152
- 'destination.country.code' => '',
153
- 'destination.country.name' => '',
154
- 'destination.region.code' => '',
155
- 'destination.postal.code' => '',
156
- 'origin.country.code' => '',
157
- 'origin.country.name' => '',
158
- 'origin.region.code' => '',
159
- 'origin.postal.code' => '',
160
- 'free_shipping' => false,
161
- 'customer.group.id' => '',
162
- 'customer.group.code' => '',
163
- 'cart.weight' => 0,
164
- 'cart.weight.unit' => 'kg',
165
- 'cart.quantity' => 0,
166
- ),
167
- 'cart.items' => array(),
168
- 'products' => array(),
169
- 'config' => $this->_config,
170
- );
171
- foreach ($this->_config as $code => &$row) {
172
- $this->processRow($process,$row,$check_all_conditions=true);
173
- foreach ($row as $property_key => $property_value) {
174
- if (substr($property_key,0,1)!='*') $this->getRowProperty($row,$property_key);
175
- }
176
- }
177
- }
178
-
179
- public function processRow($process, &$row, $is_checking=false) {
180
- if (!isset($row['*code'])) return;
181
-
182
- self::debug('process row <span class="osh-key">'.$row['*code'].'</span>',1);
183
- if (!isset($row['label']['value'])) $row['label']['value'] = '';
184
-
185
- $enabled = $this->getRowProperty($row,'enabled');
186
- if (isset($enabled)) {
187
- if (!$is_checking && !$enabled) {
188
- $this->addMessage('info',$row,'enabled','Configuration disabled');
189
- return new DPDFranceClassic_Os_Result(false);
190
- }
191
- }
192
-
193
- $conditions = $this->getRowProperty($row,'conditions');
194
- if (isset($conditions)) {
195
- $result = $this->_processFormula($process,$row,'conditions',$conditions,$is_checking);
196
- if (!$is_checking) {
197
- if (!$result->success) return $result;
198
- if (!$result->result) {
199
- $this->addMessage('info',$row,'conditions',"The cart doesn't match conditions");
200
- return new DPDFranceClassic_Os_Result(false);
201
- }
202
- }
203
- }
204
-
205
- $destination = $this->getRowProperty($row,'destination');
206
- if (isset($destination)) {
207
- $destination_match = $this->_addressMatch($destination,array(
208
- 'country_code' => $process['data']['destination.country.code'],
209
- 'region_code' => $process['data']['destination.region.code'],
210
- 'postcode' => $process['data']['destination.postal.code']
211
- ));
212
- if (!$is_checking && !$destination_match) {
213
- $this->addMessage('info',$row,'destination',"The shipping method doesn't cover the zone");
214
- return new DPDFranceClassic_Os_Result(false);
215
- }
216
- }
217
-
218
- $origin = $this->getRowProperty($row,'origin');
219
- if (isset($origin)) {
220
- $origin_match = $this->_addressMatch($origin,array(
221
- 'country_code' => $process['data']['origin.country.code'],
222
- 'region_code' => $process['data']['origin.region.code'],
223
- 'postcode' => $process['data']['origin.postal.code']
224
- ));
225
- if (!$is_checking && !$origin_match) {
226
- $this->addMessage('info',$row,'origin',"The shipping method doesn't match to shipping origin");
227
- return new DPDFranceClassic_Os_Result(false);
228
- }
229
- }
230
-
231
- $customer_groups = $this->getRowProperty($row,'customer_groups');
232
- if (isset($customer_groups)) {
233
- $groups = explode(',',$customer_groups);
234
- $group_match = false;
235
- //self::debug('code:'.$process['data']['customer.group.code'].', id:'.$process['data']['customer.group.id']);
236
- foreach ($groups as $group) {
237
- $group = trim($group);
238
- if ($group==$process['data']['customer.group.code'] || is_int($group) && $group==$process['data']['customer.group.id'] || $group=='*') {
239
- $group_match = true;
240
- break;
241
- }
242
- }
243
- if (!$is_checking && !$group_match) {
244
- $this->addMessage('info',$row,'customer_groups',"The shipping method doesn't match to customer group (%s)",$process['data']['customer.group.code']);
245
- return new DPDFranceClassic_Os_Result(false);
246
- }
247
- }
248
-
249
- $fees = $this->getRowProperty($row,'fees');
250
- if (isset($fees)) {
251
- $result = $this->_processFormula($process,$row,'fees',$fees,$is_checking);
252
- if (!$result->success) return $result;
253
- self::debug(' => <span class="osh-info">result = <span class="osh-formula">'.$this->_toString($result->result).'</span>',1);
254
- return new DPDFranceClassic_Os_Result(true,(float)$result->result);
255
- }
256
- return new DPDFranceClassic_Os_Result(false);
257
- }
258
-
259
- public function getRowProperty($row, $key, $original_row=null, $original_key=null) {
260
- $property = null;
261
- $output = null;
262
- if (isset($original_row) && isset($original_key) && $original_row['*code']==$row['*code'] && $original_key==$key) {
263
- $this->addMessage('error',$row,$key,'Infinite loop %s',"<span class=\"code\">{".$row['*code'].'.'.$key."}</span>");
264
- return array('error' => 'Infinite loop');
265
- }
266
- if (isset($row[$key]['value'])) {
267
- $property = $row[$key]['value'];
268
- $output = $property;
269
- $code = array_key_exists('*code', $row) ? $row['*code'] : NULL; self::debug(' get <span class="osh-key">'.$code.'</span>.<span class="osh-key">'.$key.'</span> = <span class="osh-formula">'.$this->_toString($property).'</span>',5);
270
- preg_match_all('/{([a-z0-9_]+)\.([a-z0-9_]+)}/i',$output,$result_set,PREG_SET_ORDER);
271
- foreach ($result_set as $result) {
272
- list($original,$ref_code,$ref_key) = $result;
273
- if (!in_array($ref_code,array('module','date','store','cart','product','selection','customvar'))) {
274
- if ($ref_code==$row['code']['value'] && $ref_key==$key) {
275
- $this->addMessage('error',$row,$key,'Infinite loop %s',"<span class=\"code\">".$original."</span>");
276
- return null;
277
- }
278
- if (isset($this->_config[$ref_code][$ref_key]['value'])) {
279
- $replacement = $this->getRowProperty($this->_config[$ref_code],$ref_key,
280
- isset($original_row) ? $original_row : $row,isset($original_key) ? $original_key : $key);
281
- if (is_array($replacement) && isset($replacement['error'])) {
282
- return isset($original_row) ? $replacement : 'false';
283
- }
284
- } else {
285
- $this->addMessage('error',$row,$key,'Non-existent property %s',"<span class=\"code\">".$original."</span>");
286
- $replacement = 'null';
287
- }
288
- $output = $this->replace($original,$replacement,$output);
289
- }
290
- }
291
- } else {
292
- $code = array_key_exists('*code', $row) ? $row['*code'] : NULL; self::debug(' get <span class="osh-key">'.$code.'</span>.<span class="osh-key">'.$key.'</span> = <span class="osh-formula">null</span>',5);
293
- }
294
- return $output;
295
- }
296
-
297
- protected function _toString($value) {
298
- if (!isset($value)) return 'null';
299
- else if (is_bool($value)) return $value ? 'true' : 'false';
300
- else return $value;
301
- }
302
-
303
- protected function replace($from, $to, $input) {
304
- if ($from===$to) return $input;
305
- if (strpos($input,$from)===false) return $input;
306
- $to = $this->_toString($to);
307
- self::debug(' replace <span class="osh-replacement">'.$this->_toString($from).'</span> by <span class="osh-replacement">'.$to.'</span> =&gt; <span class="osh-formula">'.str_replace($from,'<span class="osh-replacement">'.$to.'</span>',$input).'</span>',5);
308
- return str_replace($from,$to,$input);
309
- }
310
-
311
- protected function _min() {
312
- $args = func_get_args();
313
- $min = null;
314
- foreach ($args as $arg) {
315
- if (isset($arg) && (!isset($min) || $min>$arg)) $min = $arg;
316
- }
317
- return $min;
318
- }
319
-
320
- protected function _max() {
321
- $args = func_get_args();
322
- $max = null;
323
- foreach ($args as $arg) {
324
- if (isset($arg) && (!isset($max) || $max<$arg)) $max = $arg;
325
- }
326
- return $max;
327
- }
328
-
329
- protected function _processFormula($process, &$row, $property_key, $formula_string, $is_checking, $use_cache=true)
330
- {
331
- $result = $this->_prepareFormula($process,$row,$property_key,$formula_string,$is_checking,$use_cache);
332
- if (!$result->success) return $result;
333
-
334
- $eval_result = $this->_evalFormula($result->result);
335
- if ($result->result == 'null') {
336
- $this->addMessage('over_weight',$row,$property_key, $this->_overWeightMessage);
337
- $result = new DPDFranceClassic_Os_Result(false);
338
- if ($use_cache) $this->setCache($formula_string,$result);
339
- return $result;
340
- }
341
- if (!isset($eval_result)) {
342
- $this->addMessage('error',$row,$property_key,'Invalid formula');
343
- $result = new DPDFranceClassic_Os_Result(false);
344
- if ($use_cache) $this->setCache($formula_string,$result);
345
- return $result;
346
- }
347
- self::debug(' formula evaluation = <span class="osh-formula">'.$this->_toString($eval_result).'</span>',10);
348
- $result = new DPDFranceClassic_Os_Result(true,$eval_result);
349
- if ($use_cache) $this->setCache($formula_string,$result);
350
- return $result;
351
- }
352
-
353
- public function evalInput($process, $row, $property_key, $input) {
354
- $result = $this->_prepareFormula($process,$row,$property_key,$input,$is_checking=false,$use_cache=true);
355
- return $result->success ? $result->result : $input;
356
- }
357
-
358
- protected function setCache($expression, $value) {
359
- if ($value instanceof DPDFranceClassic_Os_Result) {
360
- $this->_formula_cache[$expression] = $value;
361
- self::debug(' cache <span class="osh-replacement">'.$expression.'</span> = <span class="osh-formula">'.$this->_toString($this->_formula_cache[$expression]).'</span>',10);
362
- } else {
363
- $value = $this->_toString($value);
364
- $this->_expression_cache[$expression] = $value;
365
- self::debug(' cache <span class="osh-replacement">'.$expression.'</span> = <span class="osh-formula">'.$value.'</span>',10);
366
- }
367
- }
368
-
369
- protected function _prepareFormula($process, $row, $property_key, $formula_string, $is_checking, $use_cache=true)
370
- {
371
- if ($use_cache && isset($this->_formula_cache[$formula_string])) {
372
- $result = $this->_formula_cache[$formula_string];
373
- self::debug(' get cached formula <span class="osh-replacement">'.$formula_string.'</span> = <span class="osh-formula">'.$this->_toString($result->result).'</span>',10);
374
- return $result;
375
- }
376
-
377
- $formula = $formula_string;
378
- //self::debug(' formula = <span class="osh-formula">'.$formula.'</span>',10);
379
-
380
- while (preg_match("#{foreach product\.((?:attribute|option)\.(?:[a-z0-9_]+))}(.*){/foreach}#i",$formula,$result)) {
381
- $original = $result[0];
382
- if ($use_cache && isset($this->_expression_cache[$original])) {
383
- $replacement = $this->_expression_cache[$original];
384
- self::debug(' get cached expression <span class="osh-replacement">'.$original.'</span> = <span class="osh-formula">'.$replacement.'</span>',10);
385
- }
386
- else {
387
- $replacement = 0;
388
- list($filter_property_type,$filter_property_name) = explode('.',$result[1]);
389
- $selections = array();
390
- self::debug(' :: foreach <span class="osh-key">'.$filter_property_type.'</span>.<span class="osh-key">'.$filter_property_name.'</span>',10);
391
- foreach ($process['products'] as $product) {
392
- $tmp_value = $this->_getProductProperty($product,$filter_property_type,$filter_property_name,$get_by_id=false);
393
- self::debug(' products[<span class="osh-formula">'.$product->getName().'</span>].<span class="osh-key">'.$filter_property_type.'</span>.<span class="osh-key">'.$filter_property_name.'</span> = <span class="osh-formula">'.$this->_toString($tmp_value).'</span>',10);
394
- $key = 'val_'.$tmp_value;
395
- $sel = isset($selections[$key]) ? $selections[$key] : null;
396
- $selections[$key]['products'][] = $product;
397
- $selections[$key]['weight'] = (isset($sel['weight']) ? $sel['weight'] : 0)+$product->getAttribute('weight')*$product->getQuantity();
398
- $selections[$key]['quantity'] = (isset($sel['quantity']) ? $sel['quantity'] : 0)+$product->getQuantity();
399
- }
400
- self::debug(' :: start foreach',10);
401
- foreach ($selections as $selection) {
402
- $process2 = $process;
403
- $process2['products'] = $selection['products'];
404
- $process2['data']['selection.quantity'] = $selection['quantity'];
405
- $process2['data']['selection.weight'] = $selection['weight'];
406
- $process_result = $this->_processFormula($process2,$row,$property_key,$result[2],$is_checking,$tmp_use_cache=false);
407
- $replacement += $process_result->result;
408
- }
409
- self::debug(' :: end foreach <span class="osh-key">'.$filter_property_type.'</span>.<span class="osh-key">'.$filter_property_name.'</span>',10);
410
- if ($use_cache) $this->setCache($original,$replacement);
411
- }
412
- $formula = $this->replace($original,$replacement,$formula);
413
- }
414
-
415
- $formula = str_replace(array("\n","\t"),array('',''),$formula);
416
-
417
- while (preg_match("#{customvar\.([a-z0-9_]+)}#i",$formula,$result)) {
418
- $original = $result[0];
419
- $replacement = Mage::getModel('core/variable')->loadByCode($result[1])->getValue('plain');
420
- $formula = $this->replace($original,$replacement,$formula);
421
- }
422
-
423
- $first_product = isset($process['products'][0]) ? $process['products'][0] : null;
424
- if (!isset($process['data']['selection.weight'])) $process['data']['selection.weight'] = $process['data']['cart.weight'];
425
- if (!isset($process['data']['selection.quantity'])) $process['data']['selection.quantity'] = $process['data']['cart.quantity'];
426
- $process['data']['product.weight'] = isset($first_product) ? $first_product->getAttribute('weight') : 0;
427
- $process['data']['product.quantity'] = isset($first_product) ? $first_product->getQuantity() : 0;
428
-
429
- foreach ($process['data'] as $original => $replacement) {
430
- $formula = $this->replace('{'.$original.'}',$replacement,$formula);
431
- }
432
-
433
- if (isset($first_product)) {
434
- while (preg_match("#{product\.(attribute|option|stock)\.([a-z0-9_]+)}#i",$formula,$result)) {
435
- $original = $result[0];
436
- switch ($result[1]) {
437
- case 'attribute': $replacement = $first_product->getAttribute($result[2]); break;
438
- case 'option': $replacement = $first_product->getOption($result[2]); break;
439
- case 'stock': $replacement = $first_product->getStockData($result[2]); break;
440
- }
441
- $formula = $this->replace($original,$replacement,$formula);
442
- }
443
- }
444
-
445
- //while (preg_match("/{(count|all|any) (attribute|option) '([^'\)]+)' ?(==|<=|>=|<|>|!=) ?(".self::$FLOAT_REGEX."|true|false|'[^'\)]*')}/",$formula,$result)
446
- // || preg_match("/{(sum|count distinct) (attribute|option) '([^'\)]+)'}/",$formula,$result))
447
- while (preg_match("/{(count) products(?: where ([^}]+))?}/i",$formula,$result)
448
- || preg_match("/{(sum|count distinct) product\.(attribute|option)\.([a-z0-9_]+)(?: where ([^}]+))?}/i",$formula,$result)) {
449
- $original = $result[0];
450
- if ($use_cache && isset($this->_expression_cache[$original])) {
451
- $replacement = $this->_expression_cache[$original];
452
- self::debug(' get cached expression <span class="osh-replacement">'.$original.'</span> = <span class="osh-formula">'.$replacement.'</span>',10);
453
- }
454
- else {
455
- $replacement = $this->_processProductProperty($process['products'],$result);
456
- if ($use_cache) $this->setCache($result[0],$replacement);
457
- }
458
- $formula = $this->replace($original,$replacement,$formula);
459
- }
460
-
461
- //while (preg_match("/{table '([^']+)' ([^}]+)}/",$formula,$result))
462
- while (preg_match("/{table ([^}]+) in ([0-9\.:,\*\[\] ]+)}/i",$formula,$result)) {
463
- $original = $result[0];
464
- if ($use_cache && isset($this->_expression_cache[$original])) {
465
- $replacement = $this->_expression_cache[$original];
466
- self::debug(' get cached expression <span class="osh-replacement">'.$original.'</span> = <span class="osh-formula">'.$replacement.'</span>',10);
467
- } else {
468
- $reference_value = $this->_evalFormula($result[1]);
469
- if (isset($reference_value)) {
470
- $fees_table_string = $result[2];
471
-
472
- if (!preg_match('#^'.self::$COUPLE_REGEX.'(?:, *'.self::$COUPLE_REGEX.')*$#',$fees_table_string)) {
473
- $this->addMessage('error',$row,$property_key,'Error in table %s','<span class="osh-formula">'.htmlentities($result[0]).'</span>');
474
- $result = new DPDFranceClassic_Os_Result(false);
475
- if ($use_cache) $this->setCache($formula_string,$result);
476
- return $result;
477
- }
478
- $fees_table = explode(',',$fees_table_string);
479
-
480
- $replacement = null;
481
- foreach ($fees_table as $item) {
482
- $fee_data = explode(':',$item);
483
-
484
- $fee = trim($fee_data[1]);
485
- $max_value = trim($fee_data[0]);
486
-
487
- $last_char = $max_value{strlen($max_value)-1};
488
- if ($last_char=='[') $including_max_value = false;
489
- else if ($last_char==']') $including_max_value = true;
490
- else $including_max_value = true;
491
-
492
- $max_value = str_replace(array('[',']'),'',$max_value);
493
-
494
- if ($max_value=='*' || $including_max_value && $reference_value<=$max_value || !$including_max_value && $reference_value<$max_value) {
495
- $replacement = $fee;//$this->_calculateFee($process,$fee,$var);
496
- break;
497
- }
498
- }
499
- }
500
- $replacement = $this->_toString($replacement);
501
- if ($use_cache) $this->setCache($original,$replacement);
502
- }
503
- $formula = $this->replace($original,$replacement,$formula);
504
- }
505
- $result = new DPDFranceClassic_Os_Result(true,$formula);
506
- return $result;
507
- }
508
-
509
- protected function _evalFormula($formula) {
510
- if (is_bool($formula)) return $formula;
511
- if (!preg_match('/^(?:floor|ceil|round|max|min|rand|pow|pi|sqrt|log|exp|abs|int|float|true|false|null|and|or|in|substr|strtolower'
512
- .'|in_array\(\'(?:[^\']*)\', *array\( *(?:\'(?:[^\']+)\') *(?: *, *\'(?:[^\']+)\')* *\) *\)'
513
- .'|\'[^\']*\'|[0-9,\'\.\-\(\)\*\/\?\:\+\<\>\=\&\|%! ])*$/',$formula)) {
514
- self::debug(' doesn\'t match',10);
515
- return null;
516
- }
517
- $formula = str_replace(
518
- array('min','max'),
519
- array('$this->_min','$this->_max'),
520
- $formula
521
- );
522
- $eval_result = null;
523
- @eval('$eval_result = ('.$formula.');');
524
- return $eval_result;
525
- }
526
-
527
- protected function _getOptionsAndData($string) {
528
- if (preg_match('/^(\\s*\(\\s*([^\] ]*)\\s*\)\\s*)/',$string,$result)) {
529
- $options = $result[2];
530
- $data = str_replace($result[1],'',$string);
531
- } else {
532
- $options = '';
533
- $data = $string;
534
- }
535
- return array(
536
- 'options' => $options,
537
- 'data' => $data,
538
- );
539
- }
540
-
541
- public function compress($input) {
542
- if (preg_match_all("/{table (.*) in (".self::$COUPLE_REGEX."(?:, *".self::$COUPLE_REGEX.")*)}/imsU",$input,$result,PREG_SET_ORDER)) {
543
- foreach ($result as $result_i) {
544
- $fees_table = explode(',',$result_i[2]);
545
- $value = null;
546
- foreach ($fees_table as $index => $item) {
547
- list($max_value,$fee) = explode(':',$item);
548
- $last_char = $max_value{strlen($max_value)-1};
549
- if (in_array($last_char,array('[',']'))) {
550
- $including_char = $last_char;
551
- $max_value = str_replace(array('[',']'),'',$max_value);
552
- } else $including_char = '';
553
- $fees_table[$index] = ((float)$max_value).$including_char.':'.((float)$fee);
554
- }
555
- $input = str_replace($result_i[2],implode(',',$fees_table),$input);
556
- $input = str_replace($result_i[1],trim($result_i[1]),$input);
557
- }
558
- }
559
- if (preg_match_all("#{foreach ([^}]*)}(.*){/foreach}#imsU",$input,$result,PREG_SET_ORDER)) {
560
- foreach ($result as $result_i) {
561
- $input = str_replace($result_i[1],trim($result_i[1]),$input);
562
- $input = str_replace($result_i[2],trim($result_i[2]),$input);
563
- }
564
- }
565
- return '$$'.str_replace(
566
- self::$UNCOMPRESSED_STRINGS,
567
- self::$COMPRESSED_STRINGS,
568
- $input
569
- );
570
- }
571
-
572
- public function uncompress($input) {
573
- if (preg_match_all("/{table (.*) in (".self::$COUPLE_REGEX."(?:, *".self::$COUPLE_REGEX.")*)}/iU",$input,$result,PREG_SET_ORDER)) {
574
- foreach ($result as $result_i) {
575
- $fees_table = explode(',',$result_i[2]);
576
- $value = null;
577
- foreach ($fees_table as $index => $item) {
578
- list($max_value,$fee) = explode(':',$item);
579
- $last_char = $max_value{strlen($max_value)-1};
580
- if (in_array($last_char,array('[',']'))) {
581
- $including_char = $last_char;
582
- $max_value = str_replace(array('[',']'),'',$max_value);
583
- } else $including_char = '';
584
- $max_value = (float)$max_value;
585
- $fee = (float)$fee;
586
- $new_max_value = number_format($max_value,2,'.','');
587
- $new_fee = number_format($fee,2,'.','');
588
- $fees_table[$index] = (((float)$new_max_value)==$max_value ? $new_max_value : $max_value).$including_char.':'
589
- .(((float)$new_fee)==$fee ? $new_fee : $fee);
590
- }
591
- $input = str_replace($result_i[2],implode(', ',$fees_table),$input);
592
- $input = str_replace($result_i[1],trim($result_i[1]),$input);
593
- }
594
- }
595
- if (preg_match_all("#{foreach ([^}]*)}(.*){/foreach}#iU",$input,$result,PREG_SET_ORDER)) {
596
- foreach ($result as $result_i) {
597
- $input = str_replace($result_i[1],trim($result_i[1]),$input);
598
- $input = str_replace($result_i[2],trim($result_i[2]),$input);
599
- }
600
- }
601
- return str_replace(
602
- self::$COMPRESSED_STRINGS,
603
- self::$UNCOMPRESSED_STRINGS,
604
- $input
605
- );
606
- }
607
-
608
- public function parseProperty($input) {
609
- $value = $input==='false' || $input==='true' ? $input=='true' : str_replace('\"','"',preg_replace('/^(?:"|\')(.*)(?:"|\')$/s','$1',$input));
610
- return $value==='' ? null : $value;
611
- }
612
-
613
- public function cleanProperty(&$row, $key) {
614
- $input = $row[$key]['value'];
615
- if (is_string($input)) {
616
- $input = str_replace(array("\n"),array(''),$input);
617
- while (preg_match('/({TABLE |{SUM |{COUNT | DISTINCT | IN )/',$input,$resi)) {
618
- $input = str_replace($resi[0],strtolower($resi[0]),$input);
619
- }
620
-
621
- while (preg_match('/{{customVar code=([a-zA-Z0-9_-]+)}}/',$input,$resi)) {
622
- $input = str_replace($resi[0],'{customvar.'.$resi[1].'}',$input);
623
- }
624
-
625
- $regex = "{(weight|products_quantity|price_including_tax|price_excluding_tax|country)}";
626
- if (preg_match('/'.$regex.'/',$input,$resi)) {
627
- $this->addMessage('warning',$row,$key,'Usage of deprecated syntax %s','<span class="osh-formula">'.$resi[0].'</span>');
628
- while (preg_match('/'.$regex.'/',$input,$resi)) {
629
- switch ($resi[1]) {
630
- case 'price_including_tax':
631
- case 'price_excluding_tax':
632
- case 'weight':
633
- $input = str_replace($resi[0],"{cart.".$resi[1]."}",$input);
634
- break;
635
- case 'products_quantity': $input = str_replace($resi[0],"{cart.quantity}",$input); break;
636
- case 'country': $input = str_replace($resi[0],"{destination.country.name}",$input); break;
637
- }
638
- }
639
- }
640
-
641
- $regex1 = "{copy '([a-zA-Z0-9_]+)'\.'([a-zA-Z0-9_]+)'}";
642
- if (preg_match('/'.$regex1.'/',$input,$resi)) {
643
- $this->addMessage('warning',$row,$key,'Usage of deprecated syntax %s','<span class="osh-formula">'.$resi[0].'</span>');
644
- while (preg_match('/'.$regex1.'/',$input,$resi)) $input = str_replace($resi[0],'{'.$resi[1].'.'.$resi[2].'}',$input);
645
- }
646
-
647
- $regex1 = "{(count|all|any) (attribute|option) '([^'\)]+)' ?((?:==|<=|>=|<|>|!=) ?(?:".self::$FLOAT_REGEX."|true|false|'[^'\)]*'))}";
648
- $regex2 = "{(sum) (attribute|option) '([^'\)]+)'}";
649
- if (preg_match('/'.$regex1.'/',$input,$resi) || preg_match('/'.$regex2.'/',$input,$resi)) {
650
- $this->addMessage('warning',$row,$key,'Usage of deprecated syntax %s','<span class="osh-formula">'.$resi[0].'</span>');
651
- while (preg_match('/'.$regex1.'/',$input,$resi) || preg_match('/'.$regex2.'/',$input,$resi)) {
652
- switch ($resi[1]) {
653
- case 'count': $input = str_replace($resi[0],"{count products where product.".$resi[2]."s.".$resi[3].$resi[4]."}",$input); break;
654
- case 'all': $input = str_replace($resi[0],"{count products where product.".$resi[2]."s.".$resi[3].$resi[4]."}=={products_quantity}",$input); break;
655
- case 'any': $input = str_replace($resi[0],"{count products where product.".$resi[2]."s.".$resi[3].$resi[4]."}>0",$input); break;
656
- case 'sum': $input = str_replace($resi[0],"{sum product.".$resi[2].".".$resi[3]."}",$input); break;
657
- }
658
- }
659
- }
660
-
661
- $regex = "((?:{| )product.(?:attribute|option))s.";
662
- if (preg_match('/'.$regex.'/',$input,$resi)) {
663
- $this->addMessage('warning',$row,$key,'Usage of deprecated syntax %s','<span class="osh-formula">'.$resi[0].'</span>');
664
- while (preg_match('/'.$regex.'/',$input,$resi)) {
665
- $input = str_replace($resi[0],$resi[1].'.',$input);
666
- }
667
- }
668
-
669
- $regex = "{table '([^']+)' (".self::$COUPLE_REGEX."(?:, *".self::$COUPLE_REGEX.")*)}";
670
- if (preg_match('/'.$regex.'/',$input,$resi)) {
671
- $this->addMessage('warning',$row,$key,'Usage of deprecated syntax %s','<span class="osh-formula">'.$resi[0].'</span>');
672
- while (preg_match('/'.$regex.'/',$input,$resi)) {
673
- switch ($resi[1]) {
674
- case 'products_quantity':
675
- $input = str_replace($resi[0],"{table {cart.weight} in ".$resi[2]."}*{cart.quantity}",$input);
676
- break;
677
- default:
678
- $input = str_replace($resi[0],"{table {cart.".$resi[1]."} in ".$resi[2]."}",$input);
679
- break;
680
- }
681
- }
682
- }
683
- }
684
- $row[$key]['value'] = $input;
685
- }
686
-
687
- protected function _parseInput() {
688
- $config_string = str_replace(
689
- array('&gt;','&lt;','“','”',utf8_encode(chr(147)),utf8_encode(chr(148)),'&laquo;','&raquo;',"\r\n"),
690
- array('>','<','"','"','"','"','"','"',"\n"),
691
- $this->_input
692
- );
693
-
694
- if (substr($config_string,0,2)=='$$') $config_string = $this->uncompress(substr($config_string,2,strlen($config_string)));
695
-
696
- $row_regex = '[ \\t]*([a-z0-9_]+)\\s*:\\s*("(?:(?:[^"]|\\\\")*[^\\\\])?"|'.self::$FLOAT_REGEX.'|false|true)\\s*(,)?[ \\t]*(?:\\n)?';
697
- preg_match_all('/((?:#+[^{\\n]*\\s+)*)\\s*(#)?{\\s*('.$row_regex.')+\\s*}/i',$config_string,$result,PREG_SET_ORDER);
698
-
699
- $this->_config = array();
700
- $available_keys = array(
701
- 'code','label','enabled','description','fees','conditions','destination','origin','customer_groups','tracking_url',
702
- 'fees_table','fees_formula','fixed_fees','reference_value',
703
- 'prices_range','weights_range','product_properties',
704
- 'free_shipping__fees_table','free_shipping__fees_formula','free_shipping__fixed_fees','free_shipping__label',
705
- );
706
-
707
- foreach ($result as $block) {
708
- $deprecated_properties = array();
709
- $unknown_properties = array();
710
- $missing_semicolon = array();
711
- $obsolete_disabling_method = array();
712
-
713
- //$before = strstr($config_string,$block[0],true); // Seulement compatible avec PHP 5.3.0
714
- list($before) = explode($block[0],$config_string,2);
715
- if ($before!==false && trim($before)!='') {
716
- $config_string = substr($config_string,strlen($before));
717
- $this->_addIgnoredLines(trim($before));
718
- $this->addMessage('info',$row=null,null,'Ignored lines %s','<div class="code">'.trim($before).'</div>');
719
- }
720
-
721
- $config_string = str_replace($block[0], '', $config_string);
722
- preg_match_all('/'.$row_regex.'/i',$block[0],$result2,PREG_SET_ORDER);
723
- $block_string = $block[0];
724
-
725
- $row = array();
726
- $i = 1;
727
- foreach ($result2 as $data) {
728
- $key = $data[1];
729
- if (in_array($key,$available_keys) || substr($key,0,1)=='_') {
730
- $property = $this->parseProperty($data[2]);
731
- if (isset($property)) {
732
- $row[$key] = array('value' => $property, 'original_value' => $property);
733
- $this->cleanProperty($row,$key);
734
- }
735
- if ($i>2) {
736
- $block_string = str_replace($data[0],$i==3 ? "...\n" : '',$block_string);
737
- }
738
- if ($i!=count($result2) && !isset($data[3]) || isset($data[3]) && $data[3]!=',') {
739
- if (preg_match('/^("|\')(.{40})(.*)("|\')$/s',$data[2],$resultx))
740
- $missing_semicolon[] = trim(str_replace($data[2],$resultx[1].$resultx[2].' ...'.$resultx[4],$data[0]));
741
- else $missing_semicolon[] = trim($data[0]);
742
- }
743
- } else {
744
- if (!in_array($key,$unknown_properties)) $unknown_properties[] = $key;
745
- }
746
- $i++;
747
- }
748
- if ($block[1]!='') $row['*comment']['value'] = $block[1];
749
- if ($block[2]=='#' && !isset($row['enabled'])) {
750
- $row['enabled'] = array('value' => false);
751
- $obsolete_disabling_method[] = $block_string;
752
- }
753
-
754
- $formula_fields_to_check = array();
755
- if (isset($row['conditions'])) $formula_fields_to_check[] = 'conditions';
756
- if (isset($row['fees'])) $formula_fields_to_check[] = 'fees';
757
-
758
- if (count($formula_fields_to_check)>0) {
759
- foreach ($formula_fields_to_check as $property) {
760
- $property_value = $row[$property]['value'];
761
- if (preg_match('/{ +/',$property_value)) {
762
- $this->addMessage('warning',$row,$property,'There are unwanted spaces after char `%s`','{');
763
- $property_value = preg_replace('/{ +/','{',$property_value);
764
- }
765
- if (preg_match('/ +}/',$property_value)) {
766
- $this->addMessage('warning',$row,$property,'There are unwanted spaces before char `%s`','}');
767
- $property_value = preg_replace('/ +}/','}',$property_value);
768
- }
769
- if (preg_match('/ +/',$property_value)) {
770
- $this->addMessage('warning',$row,$property,'There are unwanted multiples spaces `%s`',preg_replace('/( +)/','<span class="osh-formula">*$1*</span>',$property_value));
771
- $property_value = preg_replace('/ +/',' ',$property_value);
772
- }
773
- $row[$property]['value'] = trim($property_value);
774
- }
775
- }
776
-
777
- $float_value_regex = '\\s*('.self::$POSITIVE_FLOAT_REGEX.'|\*)\\s*';
778
- $conditions = array();
779
- if (isset($row['prices_range'])) {
780
- if (!in_array('prices_range',$deprecated_properties)) $deprecated_properties[] = 'prices_range';
781
-
782
- $result = $this->_getOptionsAndData($row['prices_range']['value']);
783
- $options = $result['options'];
784
- $prices_range = $result['data'];
785
-
786
- if (($options=='' || in_array($options,array('incl.tax','ttc')))
787
- && preg_match('/^\\s*(\[|\])?'.$float_value_regex.'=>'.$float_value_regex.'(\[|\])?\\s*$/',$prices_range,$result)) {
788
- $min_price_included = $result[1]=='[';
789
- $min_price = $result[2]=='*' ? -1 : (float)$result[2];
790
- $max_price = $result[3]=='*' ? -1 : (float)$result[3];
791
- $max_price_included = !isset($result[4]) || $result[4]==']' || $result[4]=='';
792
-
793
- $tax_included = $options!='' && in_array($options,array('incl.tax','ttc')) || isset($row['reference_value']) && $row['reference_value']['value']=='price_including_tax';
794
- $price = $tax_included ? '{cart.price_including_tax}' : '{cart.price_excluding_tax}';
795
-
796
- if ($min_price!=-1) $conditions[] = $price.'>'.($min_price_included ? '=' : '').$min_price;
797
- if ($max_price!=-1) $conditions[] = $price.'<'.($max_price_included ? '=' : '').$max_price;
798
- }
799
- else $this->addMessage('error',$row,null,'Unrecognized value of deprecated property %s %s','<span class="osh-key">prices_range</span>','<span class="osh-formula">'.$row['prices_range']['value'].'</span>');
800
- unset($row['prices_range']);
801
- }
802
- if (isset($row['weights_range'])) {
803
- if (!in_array('weights_range',$deprecated_properties)) $deprecated_properties[] = 'weights_range';
804
- if (preg_match('/^\\s*(\[|\])?'.$float_value_regex.'=>'.$float_value_regex.'(\[|\])?\\s*$/',$row['weights_range']['value'],$result)) {
805
- $min_weight_included = $result[1]=='[';
806
- $min_weight = $result[2]=='*' ? -1 : (float)$result[2];
807
- $max_weight = $result[3]=='*' ? -1 : (float)$result[3];
808
- $max_weight_included = !isset($result[4]) || $result[4]==']' || $result[4]=='';
809
-
810
- if ($min_weight!=-1) $conditions[] = '{cart.weight}>'.($min_weight_included ? '=' : '').$min_weight;
811
- if ($max_weight!=-1) $conditions[] = '{cart.weight}<'.($max_weight_included ? '=' : '').$max_weight;
812
- }
813
- else $this->addMessage('error',$row,null,'Unrecognized value of deprecated property %s %s','<span class="osh-key">weights_range</span>','<span class="osh-formula">'.$row['weights_range']['value'].'</span>');
814
- unset($row['weights_range']);
815
- }
816
- if (isset($row['product_properties'])) {
817
- if (!in_array('product_properties',$deprecated_properties)) $deprecated_properties[] = 'product_properties';
818
- $product_property_regex = "\\s*(and|or)? *\((?:(all|any|sum) )?(attribute|option) '([^'\)]+)' ?(==|=|<=|>=|<|>|!=) ?(".self::$FLOAT_REGEX."|true|false|'[^'\)]*')\)\\s*";
819
- if (preg_match('/^('.$product_property_regex.')+$/',$row['product_properties']['value'],$result)) {
820
- preg_match_all('/'.$product_property_regex.'/',$row['product_properties']['value'],$results,PREG_SET_ORDER);
821
- $product_properties_condition = '';
822
- foreach ($results as $result) {
823
- $and_or = $result[1];
824
- if ($and_or=='') $and_or = 'and';
825
- $any_all_sum = $result[2];
826
- if ($any_all_sum=='') $any_all_sum = 'any';
827
- $property_type = $result[3];
828
- $property_name = $result[4];
829
- $cmp_symbol = $result[5];
830
- if ($cmp_symbol=='=') $cmp_symbol = '==';
831
- $cmp_value = $result[6];
832
-
833
- $product_properties_condition .= $product_properties_condition=='' ? '' : ' '.$and_or.' ';
834
- switch ($any_all_sum) {
835
- case 'sum':
836
- $product_properties_condition .= "{sum product.".$property_type.".".$property_name."}".$cmp_symbol.$cmp_value;
837
- break;
838
- case 'all':
839
- $product_properties_condition .= "{count products where product.".$property_type.".".$property_name.$cmp_symbol.$cmp_value."}=={products_quantity}";
840
- break;
841
- case 'any':
842
- $product_properties_condition .= "{count products where product.".$property_type.".".$property_name.$cmp_symbol.$cmp_value."}>0";
843
- break;
844
- }
845
- }
846
- if ($product_properties_condition!='') $conditions[] = $product_properties_condition;
847
- }
848
- else $this->addMessage('error',$row,null,'Unrecognized value of deprecated property %s %s','<span class="osh-key">product_properties</span>','<span class="osh-formula">'.$row['product_properties']['value'].'</span>');
849
- unset($row['product_properties']);
850
- }
851
- if (count($conditions)>0) $row['conditions'] = array('value' => count($conditions)==1 ? $conditions[0] : '('.implode(') && (',$conditions).')');
852
-
853
- $fees = array();
854
- if (isset($row['fees_table'])) {
855
- if (!in_array('fees_table',$deprecated_properties)) $deprecated_properties[] = 'fees_table';
856
- $options_and_data = $this->_getOptionsAndData($row['fees_table']['value']);
857
- $options = $options_and_data['options'];
858
- $fees_table_string = $options_and_data['data'];
859
-
860
- $var = null;
861
- if ($options=='') $var = (isset($row['reference_value']) ? $row['reference_value']['value'] : 'weight');
862
- else if (in_array($options,array('incl.tax','ttc'))) $var = 'price_including_tax';
863
- else if (in_array($options,array('excl.tax','ht'))) $var = 'price_excluding_tax';
864
-
865
- if (isset($var)) {
866
- if ($var=='price') $var = 'price_excluding_tax';
867
- if ($var=='products_quantity') $var = 'quantity';
868
- if (preg_match('/^[[:space:]]*\*[[:space:]]*:[[:space:]]*('.$float_value_regex.')[[:space:]]*$/s',$fees_table_string,$result)) $fees[] = $result[1];
869
- else $fees[] = "{table {cart.".$var."} in ".str_replace(' ','',$fees_table_string)."}".($var=='quantity' ? '*{cart.quantity}' : '');
870
- }
871
- else $this->addMessage('error',$row,null,'Unrecognized value of deprecated property %s %s','<span class="osh-key">fees_table</span>','<span class="osh-formula">'.$row['fees_table']['value'].'</span>');
872
- unset($row['fees_table']);
873
- }
874
- if (isset($row['fees_formula'])) {
875
- if (!in_array('fees_formula',$deprecated_properties)) $deprecated_properties[] = 'fees_formula';
876
- $fees[] = str_replace(' ','',$row['fees_formula']['value']);
877
- unset($row['fees_formula']);
878
- }
879
- if (isset($row['fixed_fees'])) {
880
- if (!in_array('fixed_fees',$deprecated_properties)) $deprecated_properties[] = 'fixed_fees';
881
- if ($row['fixed_fees']['value']!=0 || count($fees)==0) $fees[] = str_replace(' ','',$row['fixed_fees']['value']);
882
- unset($row['fixed_fees']);
883
- }
884
- if (!isset($row['fees']) && count($fees)>0) $row['fees'] = array('value' => implode('+',$fees));
885
-
886
- $fs_fees = array();
887
- if (isset($row['free_shipping__fees_table'])) {
888
- if (!in_array('free_shipping__fees_table',$deprecated_properties)) $deprecated_properties[] = 'free_shipping__fees_table';
889
- $options_and_data = $this->_getOptionsAndData($row['free_shipping__fees_table']['value']);
890
- $options = $options_and_data['options'];
891
- $fees_table_string = $options_and_data['data'];
892
-
893
- $var = null;
894
- if ($options=='') $var = isset($row['reference_value']) ? $row['reference_value']['value'] : 'weight';
895
- else if (in_array($options,array('incl.tax','ttc'))) $var = 'price_including_tax';
896
- else if (in_array($options,array('excl.tax','ht'))) $var = 'price_excluding_tax';
897
- if ($var=='price') $var = 'price_excluding_tax';
898
-
899
- if (isset($var)) {
900
- if ($var=='price') $var = 'price_excluding_tax';
901
- if ($var=='products_quantity') $var = 'quantity';
902
- if (preg_match('/^[[:space:]]*\*[[:space:]]*:[[:space:]]*('.$float_value_regex.')[[:space:]]*$/s',$fees_table_string,$result)) $fs_fees[] = $result[1];
903
- else $fs_fees[] = "{table {cart.".$var."} in ".str_replace(' ','',$fees_table_string)."}".($var=='quantity' ? '*{cart.quantity}' : '');
904
- }
905
- else $this->addMessage('error',$row,null,'Unrecognized value of deprecated property %s %s','<span class="osh-key">free_shipping__fees_table</span>','<span class="osh-formula">'.$row['free_shipping__fees_table']['value'].'</span>');
906
- unset($row['free_shipping__fees_table']);
907
- }
908
- if (isset($row['free_shipping__fees_formula'])) {
909
- if (!in_array('free_shipping__fees_formula',$deprecated_properties)) $deprecated_properties[] = 'free_shipping__fees_formula';
910
- $fs_fees[] = str_replace(' ','',$row['free_shipping__fees_formula']['value']);
911
- unset($row['free_shipping__fees_formula']);
912
- }
913
- if (isset($row['free_shipping__fixed_fees'])) {
914
- if (!in_array('free_shipping__fixed_fees',$deprecated_properties)) $deprecated_properties[] = 'free_shipping__fixed_fees';
915
- if ($row['free_shipping__fixed_fees']['value']!=0 || count($fees)==0) $fs_fees[] = str_replace(' ','',$row['free_shipping__fixed_fees']['value']);
916
- unset($row['free_shipping__fixed_fees']);
917
- }
918
-
919
- if (isset($row['reference_value'])) {
920
- if (!in_array('reference_value',$deprecated_properties)) $deprecated_properties[] = 'reference_value';
921
- unset($row['reference_value']);
922
- }
923
-
924
- if (count($fs_fees)>0) {
925
- $row2 = $row;
926
- if (isset($row['code'])) $row2['code']['value'] = $row['code']['value'].'__free_shipping';
927
- $row2['fees']['value'] = implode('+',$fs_fees);
928
- $row2['conditions']['value'] = isset($row2['conditions']) ? '('.$row2['conditions']+') and {free_shipping}' : '{free_shipping}';
929
- $row['conditions']['value'] = isset($row['conditions']) ? '('.$row['conditions']+') and !{free_shipping}' : '!{free_shipping}';
930
- if (isset($row['free_shipping__label'])) {
931
- if (!in_array('free_shipping__label',$deprecated_properties)) $deprecated_properties[] = 'free_shipping__label';
932
- $row2['label']['value'] = $row['free_shipping__label']['value'];
933
- unset($row['free_shipping__label']);
934
- unset($row2['free_shipping__label']);
935
- }
936
- $this->_addRow($row2);
937
- }
938
- if (count($unknown_properties)>0) $this->addMessage('error',$row,null,'Usage of unknown properties %s',': <span class="osh-key">'.implode('</span>, <span class="osh-key">',$unknown_properties).'</span>');
939
- if (count($deprecated_properties)>0) $this->addMessage('warning',$row,null,'Usage of deprecated properties %s',': <span class="osh-key">'.implode('</span>, <span class="osh-key">',$deprecated_properties).'</span>');
940
- if (count($obsolete_disabling_method)>0) $this->addMessage('warning',$row,null,'Usage of obsolete method to disabling a shipping method (`#` before `{`)%s','<div class="code">'.implode('<br />',$obsolete_disabling_method).'</div>');
941
- if (count($missing_semicolon)>0) $this->addMessage('warning',$row,null,'A semicolon is missing at the end of following lines %s','<div class="code">'.implode('<br />',$missing_semicolon).'</div>');
942
- $this->_addRow($row);
943
- }
944
- if (trim($config_string)!='') {
945
- $this->_addIgnoredLines(trim($config_string));
946
- $row=null;$this->addMessage('info',$row,null,'Ignored lines %s','<div class="code">'.trim($config_string).'</div>');
947
- }
948
- }
949
-
950
- public function addMessage($type, &$row, $property) {
951
- $args = func_get_args();
952
- array_shift($args);
953
- array_shift($args);
954
- array_shift($args);
955
- $message = new DPDFranceClassic_Os_Message($type,$args);
956
- if (isset($row)) {
957
- if (isset($property)) {
958
- $row[$property]['messages'][] = $message;
959
- } else {
960
- $row['*messages'][] = $message;
961
- }
962
- }
963
- $this->_messages[] = $message;
964
- self::debug(' => <span class="osh-'.$message->type.'">'.$message->toString().'</span>',1);
965
- }
966
-
967
- protected function _addRow(&$row) {
968
- if (isset($row['code'])) {
969
- $key = $row['code']['value'];
970
- if (isset($this->_config[$key])) $this->addMessage('error',$row,'code','The property `code` must be unique, `%s` has been found twice',$key);
971
- while (isset($this->_config[$key])) $key .= rand(0,9);
972
- //$row['code'] = $key;
973
- } else {
974
- $i = 1;
975
- do {
976
- $key = 'code_auto'.sprintf('%03d',$i);
977
- $i++;
978
- } while (isset($this->_config[$key]));
979
- }
980
- $row['*code'] = $key;
981
- $this->_config[$key] = $row;
982
- }
983
-
984
- protected function _addIgnoredLines($lines) {
985
- $this->_config[] = array('lines' => $lines);
986
- }
987
-
988
- protected function _addressMatch($address_filter, $address) {
989
- $excluding = false;
990
- if (preg_match('# *\* *- *\((.*)\) *#s',$address_filter,$result)) {
991
- $address_filter = $result[1];
992
- $excluding = true;
993
- }
994
-
995
- $tmp_address_filter_array = explode(',',trim($address_filter));
996
-
997
- $concat = false;
998
- $concatened = '';
999
- $address_filter_array = array();
1000
- $i = 0;
1001
-
1002
- foreach ($tmp_address_filter_array as $address_filter) {
1003
- if ($concat) $concatened .= ','.$address_filter;
1004
- else {
1005
- if ($i<count($tmp_address_filter_array)-1 && preg_match('#\(#',$address_filter)) {
1006
- $concat = true;
1007
- $concatened .= $address_filter;
1008
- } else $address_filter_array[] = $address_filter;
1009
- }
1010
- if (preg_match('#\)#',$address_filter)) {
1011
- $address_filter_array[] = $concatened;
1012
- $concatened = '';
1013
- $concat = false;
1014
- }
1015
- $i++;
1016
- }
1017
-
1018
- foreach ($address_filter_array as $address_filter) {
1019
- if (preg_match('# *([A-Z]{2}) *(-)? *(?:\( *(-)? *(.*)\))? *#s',$address_filter,$result)) {
1020
- $country_code = $result[1];
1021
- if ($address['country_code']==$country_code) {
1022
- self::debug(' country code <span class="osh-replacement">'.$address['country_code'].'</span> matches',5);
1023
- if (!isset($result[4]) || $result[4]=='') return !$excluding;
1024
- else {
1025
- $region_codes = explode(',',$result[4]);
1026
- $in_array = false;
1027
- for ($i=count($region_codes); --$i>=0;) {
1028
- $code = trim($region_codes[$i]);
1029
- $region_codes[$i] = $code;
1030
- if ($address['region_code']===$code) {
1031
- self::debug(' region code <span class="osh-replacement">'.$address['region_code'].'</span> matches',5);
1032
- $in_array = true;
1033
- } else if ($address['postcode']===$code) {
1034
- self::debug(' postcode <span class="osh-replacement">'.$address['postcode'].'</span> matches',5);
1035
- $in_array = true;
1036
- } else if (strpos($code,'*')!==false && preg_match('/^'.str_replace('*','(?:.*)',$code).'$/',$address['postcode'])) {
1037
- self::debug(' postcode <span class="osh-replacement">'.$address['postcode'].'</span> matches <span class="osh-formula">'.$code.'</span>',5);
1038
- $in_array = true;
1039
- }
1040
- if ($in_array) break;
1041
- }
1042
- if (!$in_array) {
1043
- self::debug(' region code <span class="osh-replacement">'.$address['region_code'].'</span> and postcode <span class="osh-replacement">'.$address['postcode'].'</span> don\'t match',5);
1044
- }
1045
- // Vérification stricte
1046
- // $in_array = in_array($address['region_code'],$region_codes,true) || in_array($address['postcode'],$region_codes,true);
1047
- $excluding_region = $result[2]=='-' || $result[3]=='-';
1048
- if ($excluding_region && !$in_array || !$excluding_region && $in_array) return !$excluding;
1049
- }
1050
- }
1051
- }
1052
- }
1053
- return $excluding;
1054
- }
1055
-
1056
- protected function _getProductProperty($product, $property_type, $property_name, $get_by_id=false) {
1057
- switch ($property_type) {
1058
- case 'attribute':
1059
- case 'attributes': return $product->getAttribute($property_name,$get_by_id);
1060
- case 'option':
1061
- case 'options': return $product->getOption($property_name,$get_by_id);
1062
- case 'stock': return $product->getStockData($property_name);
1063
- }
1064
- return null;
1065
- }
1066
-
1067
- protected function _processProductProperty($products, $regex_result) {
1068
- // COUNT, SUM or COUNT DISTINCT
1069
- $operation = strtolower($regex_result[1]);
1070
- switch ($operation) {
1071
- case 'sum':
1072
- case 'count distinct':
1073
- $property_type = $regex_result[2];
1074
- $property_name = $regex_result[3];
1075
- $conditions = isset($regex_result[4]) ? $regex_result[4] : null;
1076
- break;
1077
- case 'count':
1078
- $conditions = isset($regex_result[2]) ? $regex_result[2] : null;
1079
- break;
1080
- }
1081
-
1082
- self::debug(' :: start <span class="osh-replacement">'.$regex_result[0].'</span>',10);
1083
-
1084
- $return_value = 0;
1085
-
1086
- preg_match_all('/product\.(attribute(?:s)?|option(?:s)?|stock)\.([a-z0-9_]+)(?:\.(id))?/i',$conditions,$properties_regex_result,PREG_SET_ORDER);
1087
- $properties = array();
1088
- foreach ($properties_regex_result as $property_regex_result) {
1089
- $key = $property_regex_result[0];
1090
- if (!isset($properties[$key])) $properties[$key] = $property_regex_result;
1091
- }
1092
-
1093
- foreach ($products as $product) {
1094
- if (isset($conditions) && $conditions!='') {
1095
- $formula = $conditions;
1096
- foreach ($properties as $property) {
1097
- $value = $this->_getProductProperty(
1098
- $product,
1099
- $tmp_property_type = $property[1],
1100
- $tmp_property_name = $property[2],
1101
- $get_by_id = isset($property[3]) && $property[3]=='id'
1102
- );
1103
- //$formula = $this->replace($property[0],$value,$formula);
1104
- $from = $property[0];
1105
- $to = is_string($value) || empty($value) ? "'".$value."'" : $value;
1106
- $formula = str_replace($from,$to,$formula);
1107
- self::debug(' replace <span class="osh-replacement">'.$from.'</span> by <span class="osh-replacement">'.$to.'</span> =&gt; <span class="osh-formula">'.str_replace($from,'<span class="osh-replacement">'.$to.'</span>',$formula).'</span>',5);
1108
- }
1109
- $eval_result = $this->_evalFormula($formula);
1110
- if (!isset($eval_result)) return 'null';
1111
- }
1112
- else $eval_result = true;
1113
-
1114
- if ($eval_result==true) {
1115
- switch ($operation) {
1116
- case 'sum':
1117
- $value = $this->_getProductProperty($product,$property_type,$property_name);
1118
- //self::debug($product->getSku().'.'.$property_type.'.'.$property_name.' = "'.$value.'" x '.$product->getQuantity(),10);
1119
- $return_value += $value*$product->getQuantity();
1120
- break;
1121
- case 'count distinct':
1122
- if (!isset($distinct_values)) $distinct_values = array();
1123
- $value = $this->_getProductProperty($product,$property_type,$property_name);
1124
- if (!in_array($value,$distinct_values)) {
1125
- $distinct_values[] = $value;
1126
- $return_value++;
1127
- }
1128
- break;
1129
- case 'count':
1130
- $return_value += $product->getQuantity();
1131
- break;
1132
- }
1133
- }
1134
- }
1135
-
1136
- self::debug(' :: end <span class="osh-replacement">'.$regex_result[0].'</span>',10);
1137
-
1138
- return $return_value;
1139
- }
1140
-
1141
  }
1142
 
1143
  class DPDFranceClassic_Os_Message {
1144
- public $type;
1145
- public $message;
1146
- public $args;
1147
-
1148
- public function __construct($type, $args) {
1149
- $this->type = $type;
1150
- $this->message = array_shift($args);
1151
- $this->args = $args;
1152
- }
1153
-
1154
- public function toString() {
1155
- return vsprintf($this->message,$this->args);
1156
- }
1157
  }
1158
 
1159
  class DPDFranceClassic_Os_Result {
1160
- public $success;
1161
- public $result;
1162
 
1163
- public function __construct($success, $result=null) {
1164
- $this->success = $success;
1165
- $this->result = $result;
1166
- }
1167
 
1168
- public function __toString() {
1169
- return is_bool($this->result) ? ($this->result ? 'true' : 'false') : (string)$this->result;
1170
- }
1171
  }
1172
 
1173
 
1
  <?php
2
  /**
3
+ * DPD France v5.1.2 shipping module for Magento
4
  *
5
  * @category DPDFrance
6
  * @package DPDFrance_Shipping
7
+ * @author DPD France S.A.S. <ensavoirplus.ecommerce@dpd.fr>
8
+ * @copyright 2015 DPD France S.A.S., société par actions simplifiée, au capital de 18.500.000 euros, dont le siège social est situé 27 Rue du Colonel Pierre Avia - 75015 PARIS, immatriculée au registre du commerce et des sociétés de Paris sous le numéro 444 420 830
9
  * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
10
  */
11
 
12
  class DPDFrance_Classic_Model_Owebia
13
  {
14
+ public static $FLOAT_REGEX = '[-]?\d+(?:[.]\d+)?';
15
+ public static $POSITIVE_FLOAT_REGEX = '\d+(?:[.]\d+)?';
16
+ //public static $COUPLE_REGEX = '(?:[0-9.]+|\*)(?:\[|\])?\:[0-9.]+(?:\:[0-9.]+%?)*';
17
+ public static $COUPLE_REGEX = '(?:[0-9.]+|\*) *(?:\[|\])? *\: *[0-9.]+';
18
+ public static $UNCOMPRESSED_STRINGS = array(
19
+ ' product.attribute.',
20
+ ' product.option.',
21
+ ' product.stock.',
22
+ '{product.attribute.',
23
+ '{product.option.',
24
+ '{product.stock.',
25
+ '{product.weight}',
26
+ '{product.quantity}',
27
+ '{cart.weight}',
28
+ '{cart.quantity}',
29
  '{cart.coupon}',
30
+ '{cart.price_including_tax}',
31
+ '{cart.price_excluding_tax}',
32
+ '{cart.',
33
+ '{customvar.',
34
+ '{selection.weight}',
35
+ '{selection.quantity}',
36
+ '{selection.',
37
+ '{shipto.country.',
38
+ '{foreach ',
39
+ '{/foreach}',
40
+ );
41
+ public static $COMPRESSED_STRINGS = array(
42
+ ' p.a.',
43
+ ' p.o.',
44
+ ' p.s.',
45
+ '{p.a.',
46
+ '{p.o.',
47
+ '{p.s.',
48
+ '{p.w}',
49
+ '{p.qty}',
50
+ '{c.w}',
51
+ '{c.qty}',
52
  '{c.cpn}',
53
+ '{c.pit}',
54
+ '{c.pet}',
55
+ '{c.',
56
+ '{v.',
57
+ '{s.w}',
58
+ '{s.qty}',
59
+ '{s.',
60
+ '{dest.ctry.',
61
+ '{each ',
62
+ '{/each}',
63
+ );
64
+
65
+ protected $_input;
66
+ protected $_config;
67
+ protected $_messages;
68
+ protected $_formula_cache;
69
+ protected $_expression_cache;
70
+ protected $_overWeightMessage = 'Over weight';
71
+ public $debug = 0;
72
+ public $debug_output = '';
73
+ public $debug_header = null;
74
+
75
+ public function __construct($input) {
76
+ $this->_formula_cache = array();
77
+ $this->_messages = array();
78
+ $this->_input = $input;
79
+ $this->_config = array();
80
+ $this->_parseInput();
81
+ }
82
+
83
+ private function debug($text, $level=10) {
84
+ if ($this->debug>=$level) $this->debug_output .= "<p>".$text."</p>";
85
+ }
86
+
87
+ public function printDebug() {
88
+ if ($this->debug>0) echo "<style rel=\"stylesheet\" type=\"text/css\">"
89
+ .".osh-formula{color:#f90;} .osh-key{color:#0099f7;}"
90
+ .".osh-error{color:#f00;} .osh-warning{color:#ff0;} .osh-info{color:#7bf700;}"
91
+ .".osh-debug{background:#000;color:#bbb;position:absolute;top:0;left:0;width:100%;z-index:100;-moz-opacity:0.9;opacity:0.9;text-align:left;white-space:pre-wrap;}"
92
+ .".osh-debug-content{padding:10px;}"
93
+ .".osh-replacement{color:#ff3000;}"
94
+ ."</style>"
95
+ ."<div id=\"osh-debug\" class=\"osh-debug\"><pre class=\"osh-debug-content\"><span style=\"float:right;cursor:pointer;\" onclick=\"document.getElementById('osh-debug').style.display = 'none';\">[<span style=\"padding:0 5px;color:#f00;\">X</span>]</span>"
96
+ ."<p>".$this->debug_header."</p>".$this->debug_output."</pre></div>";
97
+ }
98
+
99
+ public function setDebugHeader($process) {
100
+ $header = 'DEBUG ' . __FILE__;//'DEBUG app/code/community/Owebia/Shipping/2/Model/Carrier/OwebiaShippingHelper.php<br/>';
101
+ foreach ($process['data'] as $key => $data) {
102
+ $header .= ' <span class="osh-key">'.$key.'</span> = <span class="osh-formula">'.$this->_toString($data).'</span><br/>';
103
+ }
104
+ $this->debug_header = $header;
105
+ }
106
+
107
+ public function getConfig() {
108
+ return $this->_config;
109
+ }
110
+
111
+ public function getMessages() {
112
+ $messages = $this->_messages;
113
+ $this->_messages = array();
114
+ return $messages;
115
+ }
116
+
117
+ public function formatConfig($compress) {
118
+ $output = '';
119
+ foreach ($this->_config as $code => $row) {
120
+ if (!isset($row['lines'])) {
121
+ if (isset($row['*comment']['value'])) {
122
+ $output .= trim($row['*comment']['value'])."\n";
123
+ }
124
+ $output .= '{'.($compress ? '' : "\n");
125
+ foreach ($row as $key => $property) {
126
+ if (substr($key,0,1)!='*') {
127
+ $value = $property['value'];
128
+ if (isset($property['comment'])) $output .= ($compress ? '' : "\t").'/* '.$property['comment'].' */'.($compress ? '' : "\n");
129
+ $output .= ($compress ? '' : "\t").$key.':'.($compress ? '' : ' ');
130
+ if (is_bool($value)) $output .= $value ? 'true' : 'false';
131
+ else if (is_int($value)) $output .= $value;
132
+ else if ((string)((float)$value)==$value) $output .= $value;
133
+ else $output .= '"'.str_replace('"','\\"',$value).'"';
134
+ $output .= ','.($compress ? '' : "\n");
135
+ }
136
+ }
137
+ if ($compress) $output = preg_replace('/,$/','',$output);
138
+ $output .= "}\n".($compress ? '' : "\n");
139
+ } else {
140
+ $output .= $row['lines']."\n";
141
+ }
142
+ }
143
+ return $compress ? $this->compress($output) : $this->uncompress($output);
144
+ }
145
+
146
+ public function checkConfig() {
147
+ $process = array(
148
+ 'result' => null,
149
+ 'data' => array(
150
+ 'cart.price_excluding_tax' => 0,
151
+ 'cart.price_including_tax' => 0,
152
+ 'shipto.country.code' => '',
153
+ 'shipto.country.name' => '',
154
+ 'shipto.region.code' => '',
155
+ 'shipto.postal.code' => '',
156
+ 'origin.country.code' => '',
157
+ 'origin.country.name' => '',
158
+ 'origin.region.code' => '',
159
+ 'origin.postal.code' => '',
160
+ 'free_shipping' => false,
161
+ 'customer.group.id' => '',
162
+ 'customer.group.code' => '',
163
+ 'cart.weight' => 0,
164
+ 'cart.weight.unit' => 'kg',
165
+ 'cart.quantity' => 0,
166
+ ),
167
+ 'cart.items' => array(),
168
+ 'products' => array(),
169
+ 'config' => $this->_config,
170
+ );
171
+ foreach ($this->_config as $code => &$row) {
172
+ $this->processRow($process,$row,$check_all_conditions=true);
173
+ foreach ($row as $property_key => $property_value) {
174
+ if (substr($property_key,0,1)!='*') $this->getRowProperty($row,$property_key);
175
+ }
176
+ }
177
+ }
178
+
179
+ public function processRow($process, &$row, $is_checking=false) {
180
+ if (!isset($row['*code'])) return;
181
+
182
+ self::debug('process row <span class="osh-key">'.$row['*code'].'</span>',1);
183
+ if (!isset($row['label']['value'])) $row['label']['value'] = '';
184
+
185
+ $enabled = $this->getRowProperty($row,'enabled');
186
+ if (isset($enabled)) {
187
+ if (!$is_checking && !$enabled) {
188
+ $this->addMessage('info',$row,'enabled','Configuration disabled');
189
+ return new DPDFranceClassic_Os_Result(false);
190
+ }
191
+ }
192
+
193
+ $conditions = $this->getRowProperty($row,'conditions');
194
+ if (isset($conditions)) {
195
+ $result = $this->_processFormula($process,$row,'conditions',$conditions,$is_checking);
196
+ if (!$is_checking) {
197
+ if (!$result->success) return $result;
198
+ if (!$result->result) {
199
+ $this->addMessage('info',$row,'conditions',"The cart doesn't match conditions");
200
+ return new DPDFranceClassic_Os_Result(false);
201
+ }
202
+ }
203
+ }
204
+
205
+ $shipto = $this->getRowProperty($row,'shipto');
206
+ if (isset($shipto)) {
207
+ $shipto_match = $this->_addressMatch($shipto,array(
208
+ 'country_code' => $process['data']['shipto.country.code'],
209
+ 'region_code' => $process['data']['shipto.region.code'],
210
+ 'postcode' => $process['data']['shipto.postal.code']
211
+ ));
212
+ if (!$is_checking && !$shipto_match) {
213
+ $this->addMessage('info',$row,'shipto',"The shipping method doesn't cover the zone");
214
+ return new DPDFranceClassic_Os_Result(false);
215
+ }
216
+ }
217
+
218
+ $origin = $this->getRowProperty($row,'origin');
219
+ if (isset($origin)) {
220
+ $origin_match = $this->_addressMatch($origin,array(
221
+ 'country_code' => $process['data']['origin.country.code'],
222
+ 'region_code' => $process['data']['origin.region.code'],
223
+ 'postcode' => $process['data']['origin.postal.code']
224
+ ));
225
+ if (!$is_checking && !$origin_match) {
226
+ $this->addMessage('info',$row,'origin',"The shipping method doesn't match to shipping origin");
227
+ return new DPDFranceClassic_Os_Result(false);
228
+ }
229
+ }
230
+
231
+ $customer_groups = $this->getRowProperty($row,'customer_groups');
232
+ if (isset($customer_groups)) {
233
+ $groups = explode(',',$customer_groups);
234
+ $group_match = false;
235
+ //self::debug('code:'.$process['data']['customer.group.code'].', id:'.$process['data']['customer.group.id']);
236
+ foreach ($groups as $group) {
237
+ $group = trim($group);
238
+ if ($group==$process['data']['customer.group.code'] || is_int($group) && $group==$process['data']['customer.group.id'] || $group=='*') {
239
+ $group_match = true;
240
+ break;
241
+ }
242
+ }
243
+ if (!$is_checking && !$group_match) {
244
+ $this->addMessage('info',$row,'customer_groups',"The shipping method doesn't match to customer group (%s)",$process['data']['customer.group.code']);
245
+ return new DPDFranceClassic_Os_Result(false);
246
+ }
247
+ }
248
+
249
+ $fees = $this->getRowProperty($row,'fees');
250
+ if (isset($fees)) {
251
+ $result = $this->_processFormula($process,$row,'fees',$fees,$is_checking);
252
+ if (!$result->success) return $result;
253
+ self::debug(' => <span class="osh-info">result = <span class="osh-formula">'.$this->_toString($result->result).'</span>',1);
254
+ return new DPDFranceClassic_Os_Result(true,(float)$result->result);
255
+ }
256
+ return new DPDFranceClassic_Os_Result(false);
257
+ }
258
+
259
+ public function getRowProperty($row, $key, $original_row=null, $original_key=null) {
260
+ $property = null;
261
+ $output = null;
262
+ if (isset($original_row) && isset($original_key) && $original_row['*code']==$row['*code'] && $original_key==$key) {
263
+ $this->addMessage('error',$row,$key,'Infinite loop %s',"<span class=\"code\">{".$row['*code'].'.'.$key."}</span>");
264
+ return array('error' => 'Infinite loop');
265
+ }
266
+ if (isset($row[$key]['value'])) {
267
+ $property = $row[$key]['value'];
268
+ $output = $property;
269
+ $code = array_key_exists('*code', $row) ? $row['*code'] : NULL; self::debug(' get <span class="osh-key">'.$code.'</span>.<span class="osh-key">'.$key.'</span> = <span class="osh-formula">'.$this->_toString($property).'</span>',5);
270
+ preg_match_all('/{([a-z0-9_]+)\.([a-z0-9_]+)}/i',$output,$result_set,PREG_SET_ORDER);
271
+ foreach ($result_set as $result) {
272
+ list($original,$ref_code,$ref_key) = $result;
273
+ if (!in_array($ref_code,array('module','date','store','cart','product','selection','customvar'))) {
274
+ if ($ref_code==$row['code']['value'] && $ref_key==$key) {
275
+ $this->addMessage('error',$row,$key,'Infinite loop %s',"<span class=\"code\">".$original."</span>");
276
+ return null;
277
+ }
278
+ if (isset($this->_config[$ref_code][$ref_key]['value'])) {
279
+ $replacement = $this->getRowProperty($this->_config[$ref_code],$ref_key,
280
+ isset($original_row) ? $original_row : $row,isset($original_key) ? $original_key : $key);
281
+ if (is_array($replacement) && isset($replacement['error'])) {
282
+ return isset($original_row) ? $replacement : 'false';
283
+ }
284
+ } else {
285
+ $this->addMessage('error',$row,$key,'Non-existent property %s',"<span class=\"code\">".$original."</span>");
286
+ $replacement = 'null';
287
+ }
288
+ $output = $this->replace($original,$replacement,$output);
289
+ }
290
+ }
291
+ } else {
292
+ $code = array_key_exists('*code', $row) ? $row['*code'] : NULL; self::debug(' get <span class="osh-key">'.$code.'</span>.<span class="osh-key">'.$key.'</span> = <span class="osh-formula">null</span>',5);
293
+ }
294
+ return $output;
295
+ }
296
+
297
+ protected function _toString($value) {
298
+ if (!isset($value)) return 'null';
299
+ else if (is_bool($value)) return $value ? 'true' : 'false';
300
+ else return $value;
301
+ }
302
+
303
+ protected function replace($from, $to, $input) {
304
+ if ($from===$to) return $input;
305
+ if (strpos($input,$from)===false) return $input;
306
+ $to = $this->_toString($to);
307
+ self::debug(' replace <span class="osh-replacement">'.$this->_toString($from).'</span> by <span class="osh-replacement">'.$to.'</span> =&gt; <span class="osh-formula">'.str_replace($from,'<span class="osh-replacement">'.$to.'</span>',$input).'</span>',5);
308
+ return str_replace($from,$to,$input);
309
+ }
310
+
311
+ protected function _min() {
312
+ $args = func_get_args();
313
+ $min = null;
314
+ foreach ($args as $arg) {
315
+ if (isset($arg) && (!isset($min) || $min>$arg)) $min = $arg;
316
+ }
317
+ return $min;
318
+ }
319
+
320
+ protected function _max() {
321
+ $args = func_get_args();
322
+ $max = null;
323
+ foreach ($args as $arg) {
324
+ if (isset($arg) && (!isset($max) || $max<$arg)) $max = $arg;
325
+ }
326
+ return $max;
327
+ }
328
+
329
+ protected function _processFormula($process, &$row, $property_key, $formula_string, $is_checking, $use_cache=true)
330
+ {
331
+ $result = $this->_prepareFormula($process,$row,$property_key,$formula_string,$is_checking,$use_cache);
332
+ if (!$result->success) return $result;
333
+
334
+ $eval_result = $this->_evalFormula($result->result);
335
+ if ($result->result == 'null') {
336
+ $this->addMessage('over_weight',$row,$property_key, $this->_overWeightMessage);
337
+ $result = new DPDFranceClassic_Os_Result(false);
338
+ if ($use_cache) $this->setCache($formula_string,$result);
339
+ return $result;
340
+ }
341
+ if (!isset($eval_result)) {
342
+ $this->addMessage('error',$row,$property_key,'Invalid formula');
343
+ $result = new DPDFranceClassic_Os_Result(false);
344
+ if ($use_cache) $this->setCache($formula_string,$result);
345
+ return $result;
346
+ }
347
+ self::debug(' formula evaluation = <span class="osh-formula">'.$this->_toString($eval_result).'</span>',10);
348
+ $result = new DPDFranceClassic_Os_Result(true,$eval_result);
349
+ if ($use_cache) $this->setCache($formula_string,$result);
350
+ return $result;
351
+ }
352
+
353
+ public function evalInput($process, $row, $property_key, $input) {
354
+ $result = $this->_prepareFormula($process,$row,$property_key,$input,$is_checking=false,$use_cache=true);
355
+ return $result->success ? $result->result : $input;
356
+ }
357
+
358
+ protected function setCache($expression, $value) {
359
+ if ($value instanceof DPDFranceClassic_Os_Result) {
360
+ $this->_formula_cache[$expression] = $value;
361
+ self::debug(' cache <span class="osh-replacement">'.$expression.'</span> = <span class="osh-formula">'.$this->_toString($this->_formula_cache[$expression]).'</span>',10);
362
+ } else {
363
+ $value = $this->_toString($value);
364
+ $this->_expression_cache[$expression] = $value;
365
+ self::debug(' cache <span class="osh-replacement">'.$expression.'</span> = <span class="osh-formula">'.$value.'</span>',10);
366
+ }
367
+ }
368
+
369
+ protected function _prepareFormula($process, $row, $property_key, $formula_string, $is_checking, $use_cache=true)
370
+ {
371
+ if ($use_cache && isset($this->_formula_cache[$formula_string])) {
372
+ $result = $this->_formula_cache[$formula_string];
373
+ self::debug(' get cached formula <span class="osh-replacement">'.$formula_string.'</span> = <span class="osh-formula">'.$this->_toString($result->result).'</span>',10);
374
+ return $result;
375
+ }
376
+
377
+ $formula = $formula_string;
378
+ //self::debug(' formula = <span class="osh-formula">'.$formula.'</span>',10);
379
+
380
+ while (preg_match("#{foreach product\.((?:attribute|option)\.(?:[a-z0-9_]+))}(.*){/foreach}#i",$formula,$result)) {
381
+ $original = $result[0];
382
+ if ($use_cache && isset($this->_expression_cache[$original])) {
383
+ $replacement = $this->_expression_cache[$original];
384
+ self::debug(' get cached expression <span class="osh-replacement">'.$original.'</span> = <span class="osh-formula">'.$replacement.'</span>',10);
385
+ }
386
+ else {
387
+ $replacement = 0;
388
+ list($filter_property_type,$filter_property_name) = explode('.',$result[1]);
389
+ $selections = array();
390
+ self::debug(' :: foreach <span class="osh-key">'.$filter_property_type.'</span>.<span class="osh-key">'.$filter_property_name.'</span>',10);
391
+ foreach ($process['products'] as $product) {
392
+ $tmp_value = $this->_getProductProperty($product,$filter_property_type,$filter_property_name,$get_by_id=false);
393
+ self::debug(' products[<span class="osh-formula">'.$product->getName().'</span>].<span class="osh-key">'.$filter_property_type.'</span>.<span class="osh-key">'.$filter_property_name.'</span> = <span class="osh-formula">'.$this->_toString($tmp_value).'</span>',10);
394
+ $key = 'val_'.$tmp_value;
395
+ $sel = isset($selections[$key]) ? $selections[$key] : null;
396
+ $selections[$key]['products'][] = $product;
397
+ $selections[$key]['weight'] = (isset($sel['weight']) ? $sel['weight'] : 0)+$product->getAttribute('weight')*$product->getQuantity();
398
+ $selections[$key]['quantity'] = (isset($sel['quantity']) ? $sel['quantity'] : 0)+$product->getQuantity();
399
+ }
400
+ self::debug(' :: start foreach',10);
401
+ foreach ($selections as $selection) {
402
+ $process2 = $process;
403
+ $process2['products'] = $selection['products'];
404
+ $process2['data']['selection.quantity'] = $selection['quantity'];
405
+ $process2['data']['selection.weight'] = $selection['weight'];
406
+ $process_result = $this->_processFormula($process2,$row,$property_key,$result[2],$is_checking,$tmp_use_cache=false);
407
+ $replacement += $process_result->result;
408
+ }
409
+ self::debug(' :: end foreach <span class="osh-key">'.$filter_property_type.'</span>.<span class="osh-key">'.$filter_property_name.'</span>',10);
410
+ if ($use_cache) $this->setCache($original,$replacement);
411
+ }
412
+ $formula = $this->replace($original,$replacement,$formula);
413
+ }
414
+
415
+ $formula = str_replace(array("\n","\t"),array('',''),$formula);
416
+
417
+ while (preg_match("#{customvar\.([a-z0-9_]+)}#i",$formula,$result)) {
418
+ $original = $result[0];
419
+ $replacement = Mage::getModel('core/variable')->loadByCode($result[1])->getValue('plain');
420
+ $formula = $this->replace($original,$replacement,$formula);
421
+ }
422
+
423
+ $first_product = isset($process['products'][0]) ? $process['products'][0] : null;
424
+ if (!isset($process['data']['selection.weight'])) $process['data']['selection.weight'] = $process['data']['cart.weight'];
425
+ if (!isset($process['data']['selection.quantity'])) $process['data']['selection.quantity'] = $process['data']['cart.quantity'];
426
+ $process['data']['product.weight'] = isset($first_product) ? $first_product->getAttribute('weight') : 0;
427
+ $process['data']['product.quantity'] = isset($first_product) ? $first_product->getQuantity() : 0;
428
+
429
+ foreach ($process['data'] as $original => $replacement) {
430
+ $formula = $this->replace('{'.$original.'}',$replacement,$formula);
431
+ }
432
+
433
+ if (isset($first_product)) {
434
+ while (preg_match("#{product\.(attribute|option|stock)\.([a-z0-9_]+)}#i",$formula,$result)) {
435
+ $original = $result[0];
436
+ switch ($result[1]) {
437
+ case 'attribute': $replacement = $first_product->getAttribute($result[2]); break;
438
+ case 'option': $replacement = $first_product->getOption($result[2]); break;
439
+ case 'stock': $replacement = $first_product->getStockData($result[2]); break;
440
+ }
441
+ $formula = $this->replace($original,$replacement,$formula);
442
+ }
443
+ }
444
+
445
+ //while (preg_match("/{(count|all|any) (attribute|option) '([^'\)]+)' ?(==|<=|>=|<|>|!=) ?(".self::$FLOAT_REGEX."|true|false|'[^'\)]*')}/",$formula,$result)
446
+ // || preg_match("/{(sum|count distinct) (attribute|option) '([^'\)]+)'}/",$formula,$result))
447
+ while (preg_match("/{(count) products(?: where ([^}]+))?}/i",$formula,$result)
448
+ || preg_match("/{(sum|count distinct) product\.(attribute|option)\.([a-z0-9_]+)(?: where ([^}]+))?}/i",$formula,$result)) {
449
+ $original = $result[0];
450
+ if ($use_cache && isset($this->_expression_cache[$original])) {
451
+ $replacement = $this->_expression_cache[$original];
452
+ self::debug(' get cached expression <span class="osh-replacement">'.$original.'</span> = <span class="osh-formula">'.$replacement.'</span>',10);
453
+ }
454
+ else {
455
+ $replacement = $this->_processProductProperty($process['products'],$result);
456
+ if ($use_cache) $this->setCache($result[0],$replacement);
457
+ }
458
+ $formula = $this->replace($original,$replacement,$formula);
459
+ }
460
+
461
+ //while (preg_match("/{table '([^']+)' ([^}]+)}/",$formula,$result))
462
+ while (preg_match("/{table ([^}]+) in ([0-9\.:,\*\[\] ]+)}/i",$formula,$result)) {
463
+ $original = $result[0];
464
+ if ($use_cache && isset($this->_expression_cache[$original])) {
465
+ $replacement = $this->_expression_cache[$original];
466
+ self::debug(' get cached expression <span class="osh-replacement">'.$original.'</span> = <span class="osh-formula">'.$replacement.'</span>',10);
467
+ } else {
468
+ $reference_value = $this->_evalFormula($result[1]);
469
+ if (isset($reference_value)) {
470
+ $fees_table_string = $result[2];
471
+
472
+ if (!preg_match('#^'.self::$COUPLE_REGEX.'(?:, *'.self::$COUPLE_REGEX.')*$#',$fees_table_string)) {
473
+ $this->addMessage('error',$row,$property_key,'Error in table %s','<span class="osh-formula">'.htmlentities($result[0]).'</span>');
474
+ $result = new DPDFranceClassic_Os_Result(false);
475
+ if ($use_cache) $this->setCache($formula_string,$result);
476
+ return $result;
477
+ }
478
+ $fees_table = explode(',',$fees_table_string);
479
+
480
+ $replacement = null;
481
+ foreach ($fees_table as $item) {
482
+ $fee_data = explode(':',$item);
483
+
484
+ $fee = trim($fee_data[1]);
485
+ $max_value = trim($fee_data[0]);
486
+
487
+ $last_char = $max_value{strlen($max_value)-1};
488
+ if ($last_char=='[') $including_max_value = false;
489
+ else if ($last_char==']') $including_max_value = true;
490
+ else $including_max_value = true;
491
+
492
+ $max_value = str_replace(array('[',']'),'',$max_value);
493
+
494
+ if ($max_value=='*' || $including_max_value && $reference_value<=$max_value || !$including_max_value && $reference_value<$max_value) {
495
+ $replacement = $fee;//$this->_calculateFee($process,$fee,$var);
496
+ break;
497
+ }
498
+ }
499
+ }
500
+ $replacement = $this->_toString($replacement);
501
+ if ($use_cache) $this->setCache($original,$replacement);
502
+ }
503
+ $formula = $this->replace($original,$replacement,$formula);
504
+ }
505
+ $result = new DPDFranceClassic_Os_Result(true,$formula);
506
+ return $result;
507
+ }
508
+
509
+ protected function _evalFormula($formula) {
510
+ if (is_bool($formula)) return $formula;
511
+ if (!preg_match('/^(?:floor|ceil|round|max|min|rand|pow|pi|sqrt|log|exp|abs|int|float|true|false|null|and|or|in|substr|strtolower'
512
+ .'|in_array\(\'(?:[^\']*)\', *array\( *(?:\'(?:[^\']+)\') *(?: *, *\'(?:[^\']+)\')* *\) *\)'
513
+ .'|\'[^\']*\'|[0-9,\'\.\-\(\)\*\/\?\:\+\<\>\=\&\|%! ])*$/',$formula)) {
514
+ self::debug(' doesn\'t match',10);
515
+ return null;
516
+ }
517
+ $formula = str_replace(
518
+ array('min','max'),
519
+ array('$this->_min','$this->_max'),
520
+ $formula
521
+ );
522
+ $eval_result = null;
523
+ @eval('$eval_result = ('.$formula.');');
524
+ return $eval_result;
525
+ }
526
+
527
+ protected function _getOptionsAndData($string) {
528
+ if (preg_match('/^(\\s*\(\\s*([^\] ]*)\\s*\)\\s*)/',$string,$result)) {
529
+ $options = $result[2];
530
+ $data = str_replace($result[1],'',$string);
531
+ } else {
532
+ $options = '';
533
+ $data = $string;
534
+ }
535
+ return array(
536
+ 'options' => $options,
537
+ 'data' => $data,
538
+ );
539
+ }
540
+
541
+ public function compress($input) {
542
+ if (preg_match_all("/{table (.*) in (".self::$COUPLE_REGEX."(?:, *".self::$COUPLE_REGEX.")*)}/imsU",$input,$result,PREG_SET_ORDER)) {
543
+ foreach ($result as $result_i) {
544
+ $fees_table = explode(',',$result_i[2]);
545
+ $value = null;
546
+ foreach ($fees_table as $index => $item) {
547
+ list($max_value,$fee) = explode(':',$item);
548
+ $last_char = $max_value{strlen($max_value)-1};
549
+ if (in_array($last_char,array('[',']'))) {
550
+ $including_char = $last_char;
551
+ $max_value = str_replace(array('[',']'),'',$max_value);
552
+ } else $including_char = '';
553
+ $fees_table[$index] = ((float)$max_value).$including_char.':'.((float)$fee);
554
+ }
555
+ $input = str_replace($result_i[2],implode(',',$fees_table),$input);
556
+ $input = str_replace($result_i[1],trim($result_i[1]),$input);
557
+ }
558
+ }
559
+ if (preg_match_all("#{foreach ([^}]*)}(.*){/foreach}#imsU",$input,$result,PREG_SET_ORDER)) {
560
+ foreach ($result as $result_i) {
561
+ $input = str_replace($result_i[1],trim($result_i[1]),$input);
562
+ $input = str_replace($result_i[2],trim($result_i[2]),$input);
563
+ }
564
+ }
565
+ return '$$'.str_replace(
566
+ self::$UNCOMPRESSED_STRINGS,
567
+ self::$COMPRESSED_STRINGS,
568
+ $input
569
+ );
570
+ }
571
+
572
+ public function uncompress($input) {
573
+ if (preg_match_all("/{table (.*) in (".self::$COUPLE_REGEX."(?:, *".self::$COUPLE_REGEX.")*)}/iU",$input,$result,PREG_SET_ORDER)) {
574
+ foreach ($result as $result_i) {
575
+ $fees_table = explode(',',$result_i[2]);
576
+ $value = null;
577
+ foreach ($fees_table as $index => $item) {
578
+ list($max_value,$fee) = explode(':',$item);
579
+ $last_char = $max_value{strlen($max_value)-1};
580
+ if (in_array($last_char,array('[',']'))) {
581
+ $including_char = $last_char;
582
+ $max_value = str_replace(array('[',']'),'',$max_value);
583
+ } else $including_char = '';
584
+ $max_value = (float)$max_value;
585
+ $fee = (float)$fee;
586
+ $new_max_value = number_format($max_value,2,'.','');
587
+ $new_fee = number_format($fee,2,'.','');
588
+ $fees_table[$index] = (((float)$new_max_value)==$max_value ? $new_max_value : $max_value).$including_char.':'
589
+ .(((float)$new_fee)==$fee ? $new_fee : $fee);
590
+ }
591
+ $input = str_replace($result_i[2],implode(', ',$fees_table),$input);
592
+ $input = str_replace($result_i[1],trim($result_i[1]),$input);
593
+ }
594
+ }
595
+ if (preg_match_all("#{foreach ([^}]*)}(.*){/foreach}#iU",$input,$result,PREG_SET_ORDER)) {
596
+ foreach ($result as $result_i) {
597
+ $input = str_replace($result_i[1],trim($result_i[1]),$input);
598
+ $input = str_replace($result_i[2],trim($result_i[2]),$input);
599
+ }
600
+ }
601
+ return str_replace(
602
+ self::$COMPRESSED_STRINGS,
603
+ self::$UNCOMPRESSED_STRINGS,
604
+ $input
605
+ );
606
+ }
607
+
608
+ public function parseProperty($input) {
609
+ $value = $input==='false' || $input==='true' ? $input=='true' : str_replace('\"','"',preg_replace('/^(?:"|\')(.*)(?:"|\')$/s','$1',$input));
610
+ return $value==='' ? null : $value;
611
+ }
612
+
613
+ public function cleanProperty(&$row, $key) {
614
+ $input = $row[$key]['value'];
615
+ if (is_string($input)) {
616
+ $input = str_replace(array("\n"),array(''),$input);
617
+ while (preg_match('/({TABLE |{SUM |{COUNT | DISTINCT | IN )/',$input,$resi)) {
618
+ $input = str_replace($resi[0],strtolower($resi[0]),$input);
619
+ }
620
+
621
+ while (preg_match('/{{customVar code=([a-zA-Z0-9_-]+)}}/',$input,$resi)) {
622
+ $input = str_replace($resi[0],'{customvar.'.$resi[1].'}',$input);
623
+ }
624
+
625
+ $regex = "{(weight|products_quantity|price_including_tax|price_excluding_tax|country)}";
626
+ if (preg_match('/'.$regex.'/',$input,$resi)) {
627
+ $this->addMessage('warning',$row,$key,'Usage of deprecated syntax %s','<span class="osh-formula">'.$resi[0].'</span>');
628
+ while (preg_match('/'.$regex.'/',$input,$resi)) {
629
+ switch ($resi[1]) {
630
+ case 'price_including_tax':
631
+ case 'price_excluding_tax':
632
+ case 'weight':
633
+ $input = str_replace($resi[0],"{cart.".$resi[1]."}",$input);
634
+ break;
635
+ case 'products_quantity': $input = str_replace($resi[0],"{cart.quantity}",$input); break;
636
+ case 'country': $input = str_replace($resi[0],"{shipto.country.name}",$input); break;
637
+ }
638
+ }
639
+ }
640
+
641
+ $regex1 = "{copy '([a-zA-Z0-9_]+)'\.'([a-zA-Z0-9_]+)'}";
642
+ if (preg_match('/'.$regex1.'/',$input,$resi)) {
643
+ $this->addMessage('warning',$row,$key,'Usage of deprecated syntax %s','<span class="osh-formula">'.$resi[0].'</span>');
644
+ while (preg_match('/'.$regex1.'/',$input,$resi)) $input = str_replace($resi[0],'{'.$resi[1].'.'.$resi[2].'}',$input);
645
+ }
646
+
647
+ $regex1 = "{(count|all|any) (attribute|option) '([^'\)]+)' ?((?:==|<=|>=|<|>|!=) ?(?:".self::$FLOAT_REGEX."|true|false|'[^'\)]*'))}";
648
+ $regex2 = "{(sum) (attribute|option) '([^'\)]+)'}";
649
+ if (preg_match('/'.$regex1.'/',$input,$resi) || preg_match('/'.$regex2.'/',$input,$resi)) {
650
+ $this->addMessage('warning',$row,$key,'Usage of deprecated syntax %s','<span class="osh-formula">'.$resi[0].'</span>');
651
+ while (preg_match('/'.$regex1.'/',$input,$resi) || preg_match('/'.$regex2.'/',$input,$resi)) {
652
+ switch ($resi[1]) {
653
+ case 'count': $input = str_replace($resi[0],"{count products where product.".$resi[2]."s.".$resi[3].$resi[4]."}",$input); break;
654
+ case 'all': $input = str_replace($resi[0],"{count products where product.".$resi[2]."s.".$resi[3].$resi[4]."}=={products_quantity}",$input); break;
655
+ case 'any': $input = str_replace($resi[0],"{count products where product.".$resi[2]."s.".$resi[3].$resi[4]."}>0",$input); break;
656
+ case 'sum': $input = str_replace($resi[0],"{sum product.".$resi[2].".".$resi[3]."}",$input); break;
657
+ }
658
+ }
659
+ }
660
+
661
+ $regex = "((?:{| )product.(?:attribute|option))s.";
662
+ if (preg_match('/'.$regex.'/',$input,$resi)) {
663
+ $this->addMessage('warning',$row,$key,'Usage of deprecated syntax %s','<span class="osh-formula">'.$resi[0].'</span>');
664
+ while (preg_match('/'.$regex.'/',$input,$resi)) {
665
+ $input = str_replace($resi[0],$resi[1].'.',$input);
666
+ }
667
+ }
668
+
669
+ $regex = "{table '([^']+)' (".self::$COUPLE_REGEX."(?:, *".self::$COUPLE_REGEX.")*)}";
670
+ if (preg_match('/'.$regex.'/',$input,$resi)) {
671
+ $this->addMessage('warning',$row,$key,'Usage of deprecated syntax %s','<span class="osh-formula">'.$resi[0].'</span>');
672
+ while (preg_match('/'.$regex.'/',$input,$resi)) {
673
+ switch ($resi[1]) {
674
+ case 'products_quantity':
675
+ $input = str_replace($resi[0],"{table {cart.weight} in ".$resi[2]."}*{cart.quantity}",$input);
676
+ break;
677
+ default:
678
+ $input = str_replace($resi[0],"{table {cart.".$resi[1]."} in ".$resi[2]."}",$input);
679
+ break;
680
+ }
681
+ }
682
+ }
683
+ }
684
+ $row[$key]['value'] = $input;
685
+ }
686
+
687
+ protected static function json_decode($input)
688
+ {
689
+ if (function_exists('json_decode')) { // PHP >= 5.2.0
690
+ $output = json_decode($input);
691
+ if (function_exists('json_last_error')) { // PHP >= 5.3.0
692
+ $error = json_last_error();
693
+ if ($error!=JSON_ERROR_NONE) throw new Exception($error);
694
+ }
695
+ return $output;
696
+ } else {
697
+ return Zend_Json::decode($input);
698
+ }
699
+ }
700
+
701
+ protected function _parseInput() {
702
+ $config_string = str_replace(
703
+ array('&gt;','&lt;','','”',utf8_encode(chr(147)),utf8_encode(chr(148)),'&laquo;','&raquo;',"\r\n"),
704
+ array('>','<','"','"','"','"','"','"',"\n"),
705
+ $this->_input
706
+ );
707
+
708
+ if (substr($config_string,0,2)=='$$') $config_string = $this->uncompress(substr($config_string,2,strlen($config_string)));
709
+
710
+ $config = self::json_decode($config_string);
711
+ $config = (array)$config;
712
+
713
+ $this->_config = array();
714
+ $available_keys = array('type', 'label', 'enabled', 'fees', 'conditions', 'shipto', 'origin', 'customer_groups');
715
+ $reserved_keys = array('*code');
716
+
717
+ $deprecated_properties = array();
718
+ $unknown_properties = array();
719
+
720
+ foreach ($config as $code => $object) {
721
+ $object = (array)$object;
722
+ $row = array();
723
+ $i = 1;
724
+ foreach ($object as $property_name => $property_value)
725
+ {
726
+ if (in_array($property_name, $reserved_keys))
727
+ continue;
728
+ if (in_array($property_name, $available_keys)
729
+ || substr($property_name, 0, 1)=='_'
730
+ || in_array($object['type'], array('data', 'meta')))
731
+ {
732
+ if (isset($property_value))
733
+ $row[$property_name] = array('value' => $property_value, 'original_value' => $property_value);
734
+ }
735
+ else
736
+ if (!in_array($property_name, $unknown_properties)) $unknown_properties[] = $property_name;
737
+ $i++;
738
+ }
739
+ $this->_addRow($row);
740
+ }
741
+ $row = null;
742
+ if (count($unknown_properties)>0)
743
+ $this->addMessage('error', $row, null, 'Usage of unknown properties %s', ': <span class=osh-key>'.implode('</span>, <span class=osh-key>', $unknown_properties).'</span>');
744
+ if (count($deprecated_properties)>0)
745
+ $this->addMessage('warning', $row, null, 'Usage of deprecated properties %s', ': <span class=osh-key>'.implode('</span>, <span class=osh-key>', $deprecated_properties).'</span>');
746
+ }
747
+
748
+ public function addMessage($type, &$row, $property) {
749
+ $args = func_get_args();
750
+ array_shift($args);
751
+ array_shift($args);
752
+ array_shift($args);
753
+ $message = new DPDFranceClassic_Os_Message($type,$args);
754
+ if (isset($row)) {
755
+ if (isset($property)) {
756
+ $row[$property]['messages'][] = $message;
757
+ } else {
758
+ $row['*messages'][] = $message;
759
+ }
760
+ }
761
+ $this->_messages[] = $message;
762
+ self::debug(' => <span class="osh-'.$message->type.'">'.$message->toString().'</span>',1);
763
+ }
764
+
765
+ protected function _addRow(&$row) {
766
+ if (isset($row['code'])) {
767
+ $key = $row['code']['value'];
768
+ if (isset($this->_config[$key])) $this->addMessage('error',$row,'code','The property `code` must be unique, `%s` has been found twice',$key);
769
+ while (isset($this->_config[$key])) $key .= rand(0,9);
770
+ //$row['code'] = $key;
771
+ } else {
772
+ $i = 1;
773
+ do {
774
+ $key = 'code_auto'.sprintf('%03d',$i);
775
+ $i++;
776
+ } while (isset($this->_config[$key]));
777
+ }
778
+ $row['*code'] = $key;
779
+ $this->_config[$key] = $row;
780
+ }
781
+
782
+ protected function _addIgnoredLines($lines) {
783
+ $this->_config[] = array('lines' => $lines);
784
+ }
785
+
786
+ protected function _addressMatch($address_filter, $address) {
787
+ $excluding = false;
788
+ if (preg_match('# *\* *- *\((.*)\) *#s',$address_filter,$result)) {
789
+ $address_filter = $result[1];
790
+ $excluding = true;
791
+ }
792
+
793
+ $tmp_address_filter_array = explode(',',trim($address_filter));
794
+
795
+ $concat = false;
796
+ $concatened = '';
797
+ $address_filter_array = array();
798
+ $i = 0;
799
+
800
+ foreach ($tmp_address_filter_array as $address_filter) {
801
+ if ($concat) $concatened .= ','.$address_filter;
802
+ else {
803
+ if ($i<count($tmp_address_filter_array)-1 && preg_match('#\(#',$address_filter)) {
804
+ $concat = true;
805
+ $concatened .= $address_filter;
806
+ } else $address_filter_array[] = $address_filter;
807
+ }
808
+ if (preg_match('#\)#',$address_filter)) {
809
+ $address_filter_array[] = $concatened;
810
+ $concatened = '';
811
+ $concat = false;
812
+ }
813
+ $i++;
814
+ }
815
+
816
+ foreach ($address_filter_array as $address_filter) {
817
+ if (preg_match('# *([A-Z]{2}) *(-)? *(?:\( *(-)? *(.*)\))? *#s',$address_filter,$result)) {
818
+ $country_code = $result[1];
819
+ if ($address['country_code']==$country_code) {
820
+ self::debug(' country code <span class="osh-replacement">'.$address['country_code'].'</span> matches',5);
821
+ if (!isset($result[4]) || $result[4]=='') return !$excluding;
822
+ else {
823
+ $region_codes = explode(',',$result[4]);
824
+ $in_array = false;
825
+ for ($i=count($region_codes); --$i>=0;) {
826
+ $code = trim($region_codes[$i]);
827
+ $region_codes[$i] = $code;
828
+ if ($address['region_code']===$code) {
829
+ self::debug(' region code <span class="osh-replacement">'.$address['region_code'].'</span> matches',5);
830
+ $in_array = true;
831
+ } else if ($address['postcode']===$code) {
832
+ self::debug(' postcode <span class="osh-replacement">'.$address['postcode'].'</span> matches',5);
833
+ $in_array = true;
834
+ } else if (strpos($code,'*')!==false && preg_match('/^'.str_replace('*','(?:.*)',$code).'$/',$address['postcode'])) {
835
+ self::debug(' postcode <span class="osh-replacement">'.$address['postcode'].'</span> matches <span class="osh-formula">'.$code.'</span>',5);
836
+ $in_array = true;
837
+ }
838
+ if ($in_array) break;
839
+ }
840
+ if (!$in_array) {
841
+ self::debug(' region code <span class="osh-replacement">'.$address['region_code'].'</span> and postcode <span class="osh-replacement">'.$address['postcode'].'</span> don\'t match',5);
842
+ }
843
+ // Vérification stricte
844
+ // $in_array = in_array($address['region_code'],$region_codes,true) || in_array($address['postcode'],$region_codes,true);
845
+ $excluding_region = $result[2]=='-' || $result[3]=='-';
846
+ if ($excluding_region && !$in_array || !$excluding_region && $in_array) return !$excluding;
847
+ }
848
+ }
849
+ }
850
+ }
851
+ return $excluding;
852
+ }
853
+
854
+ protected function _getProductProperty($product, $property_type, $property_name, $get_by_id=false) {
855
+ switch ($property_type) {
856
+ case 'attribute':
857
+ case 'attributes': return $product->getAttribute($property_name,$get_by_id);
858
+ case 'option':
859
+ case 'options': return $product->getOption($property_name,$get_by_id);
860
+ case 'stock': return $product->getStockData($property_name);
861
+ }
862
+ return null;
863
+ }
864
+
865
+ protected function _processProductProperty($products, $regex_result) {
866
+ // COUNT, SUM or COUNT DISTINCT
867
+ $operation = strtolower($regex_result[1]);
868
+ switch ($operation) {
869
+ case 'sum':
870
+ case 'count distinct':
871
+ $property_type = $regex_result[2];
872
+ $property_name = $regex_result[3];
873
+ $conditions = isset($regex_result[4]) ? $regex_result[4] : null;
874
+ break;
875
+ case 'count':
876
+ $conditions = isset($regex_result[2]) ? $regex_result[2] : null;
877
+ break;
878
+ }
879
+
880
+ self::debug(' :: start <span class="osh-replacement">'.$regex_result[0].'</span>',10);
881
+
882
+ $return_value = 0;
883
+
884
+ preg_match_all('/product\.(attribute(?:s)?|option(?:s)?|stock)\.([a-z0-9_]+)(?:\.(id))?/i',$conditions,$properties_regex_result,PREG_SET_ORDER);
885
+ $properties = array();
886
+ foreach ($properties_regex_result as $property_regex_result) {
887
+ $key = $property_regex_result[0];
888
+ if (!isset($properties[$key])) $properties[$key] = $property_regex_result;
889
+ }
890
+
891
+ foreach ($products as $product) {
892
+ if (isset($conditions) && $conditions!='') {
893
+ $formula = $conditions;
894
+ foreach ($properties as $property) {
895
+ $value = $this->_getProductProperty(
896
+ $product,
897
+ $tmp_property_type = $property[1],
898
+ $tmp_property_name = $property[2],
899
+ $get_by_id = isset($property[3]) && $property[3]=='id'
900
+ );
901
+ //$formula = $this->replace($property[0],$value,$formula);
902
+ $from = $property[0];
903
+ $to = is_string($value) || empty($value) ? "'".$value."'" : $value;
904
+ $formula = str_replace($from,$to,$formula);
905
+ self::debug(' replace <span class="osh-replacement">'.$from.'</span> by <span class="osh-replacement">'.$to.'</span> =&gt; <span class="osh-formula">'.str_replace($from,'<span class="osh-replacement">'.$to.'</span>',$formula).'</span>',5);
906
+ }
907
+ $eval_result = $this->_evalFormula($formula);
908
+ if (!isset($eval_result)) return 'null';
909
+ }
910
+ else $eval_result = true;
911
+
912
+ if ($eval_result==true) {
913
+ switch ($operation) {
914
+ case 'sum':
915
+ $value = $this->_getProductProperty($product,$property_type,$property_name);
916
+ //self::debug($product->getSku().'.'.$property_type.'.'.$property_name.' = "'.$value.'" x '.$product->getQuantity(),10);
917
+ $return_value += $value*$product->getQuantity();
918
+ break;
919
+ case 'count distinct':
920
+ if (!isset($distinct_values)) $distinct_values = array();
921
+ $value = $this->_getProductProperty($product,$property_type,$property_name);
922
+ if (!in_array($value,$distinct_values)) {
923
+ $distinct_values[] = $value;
924
+ $return_value++;
925
+ }
926
+ break;
927
+ case 'count':
928
+ $return_value += $product->getQuantity();
929
+ break;
930
+ }
931
+ }
932
+ }
933
+
934
+ self::debug(' :: end <span class="osh-replacement">'.$regex_result[0].'</span>',10);
935
+
936
+ return $return_value;
937
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
938
  }
939
 
940
  class DPDFranceClassic_Os_Message {
941
+ public $type;
942
+ public $message;
943
+ public $args;
944
+
945
+ public function __construct($type, $args) {
946
+ $this->type = $type;
947
+ $this->message = array_shift($args);
948
+ $this->args = $args;
949
+ }
950
+
951
+ public function toString() {
952
+ return vsprintf($this->message,$this->args);
953
+ }
954
  }
955
 
956
  class DPDFranceClassic_Os_Result {
957
+ public $success;
958
+ public $result;
959
 
960
+ public function __construct($success, $result=null) {
961
+ $this->success = $success;
962
+ $this->result = $result;
963
+ }
964
 
965
+ public function __toString() {
966
+ return is_bool($this->result) ? ($this->result ? 'true' : 'false') : (string)$this->result;
967
+ }
968
  }
969
 
970
 
app/code/community/DPDFrance/Classic/etc/config.xml CHANGED
@@ -1,12 +1,12 @@
1
  <?xml version="1.0" encoding="UTF-8"?>
2
  <!--
3
  /**
4
- * DPD France v5.1.0 shipping module for Magento
5
  *
6
  * @category DPDFrance
7
  * @package DPDFrance_Shipping
8
- * @author DPD S.A.S. <ensavoirplus.ecommerce@dpd.fr>
9
- * @copyright 2015 DPD S.A.S., société par actions simplifiée, au capital de 18.500.000 euros, dont le siège social est situé 27 Rue du Colonel Pierre Avia - 75015 PARIS, immatriculée au registre du commerce et des sociétés de Paris sous le numéro 444 420 830
10
  * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
11
  */
12
  -->
@@ -21,110 +21,63 @@
21
  <title>Livraison par DPD</title>
22
  <methodname></methodname>
23
  <expense>
24
- # Franco de port à 89€ sauf Corse
25
  {
26
- label: "Livraison en 24-48h du lundi au vendredi pour tous ceux qui font le choix de recevoir leur colis sur leur lieu de travail",
27
- destination: "FR-(2A,2B),MC",
28
- conditions: "{cart.price_including_tax}>=89",
29
- fees: 0.00
30
- }
31
- # Zones de montagne
32
- {
33
- label: "Livraison en 24-48h du lundi au vendredi pour tous ceux qui font le choix de recevoir leur colis sur leur lieu de travail",
34
- destination: "FR(04120,04130,04140,04160,04170,04200,04240,04260,04300,04310,04330,04360,04370,04400,04510,04530,04600,04700,04850,05100,05110,05120,05130,05150,05160,05170,05200,05220,05240,05250,05260,05290,05300,05310,05320,05330,05340,05350,05400,05460,05470,05500,05560,05600,05700,05800,06140,06380,06390,06410,06420,06430,06450,06470,06530,06540,06620,06710,06750,06910,09110,09140,09300,09460,25120,25140,25240,25370,25450,25500,25650,30570,31110,38112,38114,38142,38190,38250,38350,38380,38410,38580,38660,38700,38750,38860,38880,39220,39310,39400,63113,63210,63240,63610,63660,63690,63840,63850,64440,64490,64560,64570,65110,65120,65170,65200,65240,65400,65510,65710,66210,66760,66800,68140,68610,68650,73110,73120,73130,73140,73150,73160,73170,73190,73210,73220,73230,73250,73260,73270,73300,73320,73340,73350,73390,73400,73440,73450,73460,73470,73500,73530,73550,73590,73600,73620,73630,73640,73710,73720,73870,74110,74120,74170,74220,74230,74260,74310,74340,74350,74360,74390,74400,74420,74430,74440,74450,74470,74480,74660,74740,74920,83111,83440,83530,83560,83630,83690,83830,83840,84390,88310,88340,88370,88400,90200)",
35
- fees: "5+{table {cart.weight} in
36
- 0.5:5.30,
37
- 1.0:6.50,
38
- 2.0:7.40,
39
- 3.0:8.30,
40
- 5.0:10.10,
41
- 10.0:12.50,
42
- 20.0:15.00,
43
- 30.0:18.00}",
44
- }
45
- # Zones Iles et Corse
46
- {
47
- label: "Livraison en 24-48h du lundi au vendredi pour tous ceux qui font le choix de recevoir leur colis sur leur lieu de travail",
48
- destination: "FR(20*,17111,17123,17190,17310,17370,17410,17480,17550,17580,17590,17630,17650,17670,17740,17840,17880,17940,22870,29242,29253,29259,29980,29990,56360,56590,56780,56840,85350)",
49
- fees: "16+{table {cart.weight} in
50
- 0.5:5.30,
51
- 1.0:6.50,
52
- 2.0:7.40,
53
- 3.0:8.30,
54
- 5.0:10.10,
55
- 10.0:12.50,
56
- 20.0:15.00,
57
- 30.0:18.00}",
58
- }
59
- # Zone France et Monaco
60
- {
61
- label: "Livraison en 24-48h du lundi au vendredi pour tous ceux qui font le choix de recevoir leur colis sur leur lieu de travail",
62
- destination: "FR,MC",
63
- fees: "{table {cart.weight} in
64
- 0.5:5.30,
65
- 1.0:6.50,
66
- 2.0:7.40,
67
- 3.0:8.30,
68
- 5.0:10.10,
69
- 10.0:12.50,
70
- 20.0:15.00,
71
- 30.0:18.00}",
72
- }
73
- # Zone DPD Europe 1
74
- {
75
- label: "Livraison en 48-96h dans toute l’Europe, et dans le monde entier avec la fiabilité du réseau DPD",
76
- destination: "DE,BE,LU,NL",
77
- fees: "8+{table {cart.weight} in
78
- 0.5:5.30,
79
- 1.0:6.50,
80
- 2.0:7.40,
81
- 3.0:8.30,
82
- 5.0:10.10,
83
- 10.0:12.50,
84
- 20.0:15.00,
85
- 30.0:18.00}",
86
- }
87
- # Zone DPD Europe 2
88
- {
89
- label: "Livraison en 48-96h dans toute l’Europe, et dans le monde entier avec la fiabilité du réseau DPD",
90
- destination: "AT,ES,GB,IT",
91
- fees: "11+{table {cart.weight} in
92
- 0.5:5.30,
93
- 1.0:6.50,
94
- 2.0:7.40,
95
- 3.0:8.30,
96
- 5.0:10.10,
97
- 10.0:12.50,
98
- 20.0:15.00,
99
- 30.0:18.00}",
100
- }
101
- # Zone DPD Europe 3
102
- {
103
- label: "Livraison en 48-96h dans toute l’Europe, et dans le monde entier avec la fiabilité du réseau DPD",
104
- destination: "HR,DK,EE,HU,IE,LT,PL,PT,CZ,SI,SK,SE",
105
- fees: "18+{table {cart.weight} in
106
- 0.5:5.30,
107
- 1.0:6.50,
108
- 2.0:7.40,
109
- 3.0:8.30,
110
- 5.0:10.10,
111
- 10.0:12.50,
112
- 20.0:15.00,
113
- 30.0:18.00}",
114
- }
115
- # Zone DPD Europe 4
116
- {
117
- label: "Livraison en 48-96h dans toute l’Europe, et dans le monde entier avec la fiabilité du réseau DPD",
118
- destination: "GR,FI,BG,RO",
119
- fees: "32+{table {cart.weight} in
120
- 0.5:5.30,
121
- 1.0:6.50,
122
- 2.0:7.40,
123
- 3.0:8.30,
124
- 5.0:10.10,
125
- 10.0:12.50,
126
- 20.0:15.00,
127
- 30.0:18.00}",
128
  }
129
  </expense>
130
  </dpdfrclassic>
@@ -132,7 +85,7 @@
132
  </default>
133
  <modules>
134
  <DPDFrance_Classic>
135
- <version>5.1.1</version>
136
  <depends>
137
  <Mage_Shipping/>
138
  </depends>
1
  <?xml version="1.0" encoding="UTF-8"?>
2
  <!--
3
  /**
4
+ * DPD France v5.1.2 shipping module for Magento
5
  *
6
  * @category DPDFrance
7
  * @package DPDFrance_Shipping
8
+ * @author DPD France S.A.S. <ensavoirplus.ecommerce@dpd.fr>
9
+ * @copyright 2015 DPD France S.A.S., société par actions simplifiée, au capital de 18.500.000 euros, dont le siège social est situé 27 Rue du Colonel Pierre Avia - 75015 PARIS, immatriculée au registre du commerce et des sociétés de Paris sous le numéro 444 420 830
10
  * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
11
  */
12
  -->
21
  <title>Livraison par DPD</title>
22
  <methodname></methodname>
23
  <expense>
 
24
  {
25
+ "Franco de port à 89€ sauf Corse":
26
+ {
27
+ "label": "Livraison en 24-48h du lundi au vendredi pour tous ceux qui font le choix de recevoir leur colis sur leur lieu de travail",
28
+ "shipto": "FR-(2A,2B),MC",
29
+ "conditions": "{cart.price_including_tax}>=89",
30
+ "fees": 0.00
31
+ },
32
+
33
+ "Zones de montagne":
34
+ {
35
+ "label": "Livraison en 24-48h du lundi au vendredi pour tous ceux qui font le choix de recevoir leur colis sur leur lieu de travail",
36
+ "shipto": "FR(04120,04130,04140,04160,04170,04200,04240,04260,04300,04310,04330,04360,04370,04400,04510,04530,04600,04700,04850,05100,05110,05120,05130,05150,05160,05170,05200,05220,05240,05250,05260,05290,05300,05310,05320,05330,05340,05350,05400,05460,05470,05500,05560,05600,05700,05800,06140,06380,06390,06410,06420,06430,06450,06470,06530,06540,06620,06710,06750,06910,09110,09140,09300,09460,25120,25140,25240,25370,25450,25500,25650,30570,31110,38112,38114,38142,38190,38250,38350,38380,38410,38580,38660,38700,38750,38860,38880,39220,39310,39400,63113,63210,63240,63610,63660,63690,63840,63850,64440,64490,64560,64570,65110,65120,65170,65200,65240,65400,65510,65710,66210,66760,66800,68140,68610,68650,73110,73120,73130,73140,73150,73160,73170,73190,73210,73220,73230,73250,73260,73270,73300,73320,73340,73350,73390,73400,73440,73450,73460,73470,73500,73530,73550,73590,73600,73620,73630,73640,73710,73720,73870,74110,74120,74170,74220,74230,74260,74310,74340,74350,74360,74390,74400,74420,74430,74440,74450,74470,74480,74660,74740,74920,83111,83440,83530,83560,83630,83690,83830,83840,84390,88310,88340,88370,88400,90200)",
37
+ "fees": "5+{table {cart.weight} in 0.5:5.30, 1.0:6.50, 2.0:7.40, 3.0:8.30, 5.0:10.10, 10.0:12.50, 20.0:15.00, 30.0:18.00}"
38
+ },
39
+
40
+ "Zones Iles et Corse":
41
+ {
42
+ "label": "Livraison en 24-48h du lundi au vendredi pour tous ceux qui font le choix de recevoir leur colis sur leur lieu de travail",
43
+ "shipto": "FR(20*,17111,17123,17190,17310,17370,17410,17480,17550,17580,17590,17630,17650,17670,17740,17840,17880,17940,22870,29242,29253,29259,29980,29990,56360,56590,56780,56840,85350)",
44
+ "fees": "16+{table {cart.weight} in 0.5:5.30, 1.0:6.50, 2.0:7.40, 3.0:8.30, 5.0:10.10, 10.0:12.50, 20.0:15.00, 30.0:18.00}"
45
+ },
46
+
47
+ "Zone France et Monaco":
48
+ {
49
+ "label": "Livraison en 24-48h du lundi au vendredi pour tous ceux qui font le choix de recevoir leur colis sur leur lieu de travail",
50
+ "shipto": "FR,MC",
51
+ "fees": "{table {cart.weight} in 0.5:5.30, 1.0:6.50, 2.0:7.40, 3.0:8.30, 5.0:10.10, 10.0:12.50, 20.0:15.00, 30.0:18.00}"
52
+ },
53
+
54
+ "Zone DPD Europe 1":
55
+ {
56
+ "label": "Livraison en 48-96h dans toute l’Europe, et dans le monde entier avec la fiabilité du réseau DPD",
57
+ "shipto": "DE,BE,LU,NL",
58
+ "fees": "8+{table {cart.weight} in 0.5:5.30, 1.0:6.50, 2.0:7.40, 3.0:8.30, 5.0:10.10, 10.0:12.50, 20.0:15.00, 30.0:18.00}"
59
+ },
60
+
61
+ "Zone DPD Europe 2":
62
+ {
63
+ "label": "Livraison en 48-96h dans toute l’Europe, et dans le monde entier avec la fiabilité du réseau DPD",
64
+ "shipto": "AT,ES,GB,IT",
65
+ "fees": "11+{table {cart.weight} in 0.5:5.30, 1.0:6.50, 2.0:7.40, 3.0:8.30, 5.0:10.10, 10.0:12.50, 20.0:15.00, 30.0:18.00}"
66
+ },
67
+
68
+ "Zone DPD Europe 3":
69
+ {
70
+ "label": "Livraison en 48-96h dans toute l’Europe, et dans le monde entier avec la fiabilité du réseau DPD",
71
+ "shipto": "HR,DK,EE,HU,IE,LT,PL,PT,CZ,SI,SK,SE",
72
+ "fees": "18+{table {cart.weight} in 0.5:5.30, 1.0:6.50, 2.0:7.40, 3.0:8.30, 5.0:10.10, 10.0:12.50, 20.0:15.00, 30.0:18.00}"
73
+ },
74
+
75
+ "Zone DPD Europe 4":
76
+ {
77
+ "label": "Livraison en 48-96h dans toute l’Europe, et dans le monde entier avec la fiabilité du réseau DPD",
78
+ "shipto": "GR,FI,BG,RO",
79
+ "fees": "32+{table {cart.weight} in 0.5:5.30, 1.0:6.50, 2.0:7.40, 3.0:8.30, 5.0:10.10, 10.0:12.50, 20.0:15.00, 30.0:18.00}"
80
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
81
  }
82
  </expense>
83
  </dpdfrclassic>
85
  </default>
86
  <modules>
87
  <DPDFrance_Classic>
88
+ <version>5.1.2</version>
89
  <depends>
90
  <Mage_Shipping/>
91
  </depends>
app/code/community/DPDFrance/Classic/etc/system.xml CHANGED
@@ -1,12 +1,12 @@
1
  <?xml version="1.0" encoding="UTF-8"?>
2
  <!--
3
  /**
4
- * DPD France v5.1.0 shipping module for Magento
5
  *
6
  * @category DPDFrance
7
  * @package DPDFrance_Shipping
8
- * @author DPD S.A.S. <ensavoirplus.ecommerce@dpd.fr>
9
- * @copyright 2015 DPD S.A.S., société par actions simplifiée, au capital de 18.500.000 euros, dont le siège social est situé 27 Rue du Colonel Pierre Avia - 75015 PARIS, immatriculée au registre du commerce et des sociétés de Paris sous le numéro 444 420 830
10
  * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
11
  */
12
  -->
1
  <?xml version="1.0" encoding="UTF-8"?>
2
  <!--
3
  /**
4
+ * DPD France v5.1.2 shipping module for Magento
5
  *
6
  * @category DPDFrance
7
  * @package DPDFrance_Shipping
8
+ * @author DPD France S.A.S. <ensavoirplus.ecommerce@dpd.fr>
9
+ * @copyright 2015 DPD France S.A.S., société par actions simplifiée, au capital de 18.500.000 euros, dont le siège social est situé 27 Rue du Colonel Pierre Avia - 75015 PARIS, immatriculée au registre du commerce et des sociétés de Paris sous le numéro 444 420 830
10
  * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
11
  */
12
  -->
app/code/community/DPDFrance/Export/Block/Export/Orders.php CHANGED
@@ -1,11 +1,11 @@
1
  <?php
2
  /**
3
- * DPD France v5.1.0 shipping module for Magento
4
  *
5
  * @category DPDFrance
6
  * @package DPDFrance_Shipping
7
- * @author DPD S.A.S. <ensavoirplus.ecommerce@dpd.fr>
8
- * @copyright 2015 DPD S.A.S., société par actions simplifiée, au capital de 18.500.000 euros, dont le siège social est situé 27 Rue du Colonel Pierre Avia - 75015 PARIS, immatriculée au registre du commerce et des sociétés de Paris sous le numéro 444 420 830
9
  * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
10
  */
11
 
1
  <?php
2
  /**
3
+ * DPD France v5.1.2 shipping module for Magento
4
  *
5
  * @category DPDFrance
6
  * @package DPDFrance_Shipping
7
+ * @author DPD France S.A.S. <ensavoirplus.ecommerce@dpd.fr>
8
+ * @copyright 2015 DPD France S.A.S., société par actions simplifiée, au capital de 18.500.000 euros, dont le siège social est situé 27 Rue du Colonel Pierre Avia - 75015 PARIS, immatriculée au registre du commerce et des sociétés de Paris sous le numéro 444 420 830
9
  * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
10
  */
11
 
app/code/community/DPDFrance/Export/Block/Export/Orders/Grid.php CHANGED
@@ -1,11 +1,11 @@
1
  <?php
2
  /**
3
- * DPD France v5.1.0 shipping module for Magento
4
  *
5
  * @category DPDFrance
6
  * @package DPDFrance_Shipping
7
- * @author DPD S.A.S. <ensavoirplus.ecommerce@dpd.fr>
8
- * @copyright 2015 DPD S.A.S., société par actions simplifiée, au capital de 18.500.000 euros, dont le siège social est situé 27 Rue du Colonel Pierre Avia - 75015 PARIS, immatriculée au registre du commerce et des sociétés de Paris sous le numéro 444 420 830
9
  * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
10
  */
11
 
1
  <?php
2
  /**
3
+ * DPD France v5.1.2 shipping module for Magento
4
  *
5
  * @category DPDFrance
6
  * @package DPDFrance_Shipping
7
+ * @author DPD France S.A.S. <ensavoirplus.ecommerce@dpd.fr>
8
+ * @copyright 2015 DPD France S.A.S., société par actions simplifiée, au capital de 18.500.000 euros, dont le siège social est situé 27 Rue du Colonel Pierre Avia - 75015 PARIS, immatriculée au registre du commerce et des sociétés de Paris sous le numéro 444 420 830
9
  * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
10
  */
11
 
app/code/community/DPDFrance/Export/Block/Tracking/Orders.php CHANGED
@@ -1,11 +1,11 @@
1
  <?php
2
  /**
3
- * DPD France v5.1.0 shipping module for Magento
4
  *
5
  * @category DPDFrance
6
  * @package DPDFrance_Shipping
7
- * @author DPD S.A.S. <ensavoirplus.ecommerce@dpd.fr>
8
- * @copyright 2015 DPD S.A.S., société par actions simplifiée, au capital de 18.500.000 euros, dont le siège social est situé 27 Rue du Colonel Pierre Avia - 75015 PARIS, immatriculée au registre du commerce et des sociétés de Paris sous le numéro 444 420 830
9
  * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
10
  */
11
 
1
  <?php
2
  /**
3
+ * DPD France v5.1.2 shipping module for Magento
4
  *
5
  * @category DPDFrance
6
  * @package DPDFrance_Shipping
7
+ * @author DPD France S.A.S. <ensavoirplus.ecommerce@dpd.fr>
8
+ * @copyright 2015 DPD France S.A.S., société par actions simplifiée, au capital de 18.500.000 euros, dont le siège social est situé 27 Rue du Colonel Pierre Avia - 75015 PARIS, immatriculée au registre du commerce et des sociétés de Paris sous le numéro 444 420 830
9
  * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
10
  */
11
 
app/code/community/DPDFrance/Export/Block/Tracking/Orders/Grid.php CHANGED
@@ -1,11 +1,11 @@
1
  <?php
2
  /**
3
- * DPD France v5.1.0 shipping module for Magento
4
  *
5
  * @category DPDFrance
6
  * @package DPDFrance_Shipping
7
- * @author DPD S.A.S. <ensavoirplus.ecommerce@dpd.fr>
8
- * @copyright 2015 DPD S.A.S., société par actions simplifiée, au capital de 18.500.000 euros, dont le siège social est situé 27 Rue du Colonel Pierre Avia - 75015 PARIS, immatriculée au registre du commerce et des sociétés de Paris sous le numéro 444 420 830
9
  * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
10
  */
11
 
1
  <?php
2
  /**
3
+ * DPD France v5.1.2 shipping module for Magento
4
  *
5
  * @category DPDFrance
6
  * @package DPDFrance_Shipping
7
+ * @author DPD France S.A.S. <ensavoirplus.ecommerce@dpd.fr>
8
+ * @copyright 2015 DPD France S.A.S., société par actions simplifiée, au capital de 18.500.000 euros, dont le siège social est situé 27 Rue du Colonel Pierre Avia - 75015 PARIS, immatriculée au registre du commerce et des sociétés de Paris sous le numéro 444 420 830
9
  * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
10
  */
11
 
app/code/community/DPDFrance/Export/Helper/Data.php CHANGED
@@ -1,11 +1,11 @@
1
  <?php
2
  /**
3
- * DPD France v5.1.0 shipping module for Magento
4
  *
5
  * @category DPDFrance
6
  * @package DPDFrance_Shipping
7
- * @author DPD S.A.S. <ensavoirplus.ecommerce@dpd.fr>
8
- * @copyright 2015 DPD S.A.S., société par actions simplifiée, au capital de 18.500.000 euros, dont le siège social est situé 27 Rue du Colonel Pierre Avia - 75015 PARIS, immatriculée au registre du commerce et des sociétés de Paris sous le numéro 444 420 830
9
  * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
10
  */
11
 
1
  <?php
2
  /**
3
+ * DPD France v5.1.2 shipping module for Magento
4
  *
5
  * @category DPDFrance
6
  * @package DPDFrance_Shipping
7
+ * @author DPD France S.A.S. <ensavoirplus.ecommerce@dpd.fr>
8
+ * @copyright 2015 DPD France S.A.S., société par actions simplifiée, au capital de 18.500.000 euros, dont le siège social est situé 27 Rue du Colonel Pierre Avia - 75015 PARIS, immatriculée au registre du commerce et des sociétés de Paris sous le numéro 444 420 830
9
  * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
10
  */
11
 
app/code/community/DPDFrance/Export/controllers/ExportController.php CHANGED
@@ -1,11 +1,11 @@
1
  <?php
2
  /**
3
- * DPD France v5.1.0 shipping module for Magento
4
  *
5
  * @category DPDFrance
6
  * @package DPDFrance_Shipping
7
- * @author DPD S.A.S. <ensavoirplus.ecommerce@dpd.fr>
8
- * @copyright 2015 DPD S.A.S., société par actions simplifiée, au capital de 18.500.000 euros, dont le siège social est situé 27 Rue du Colonel Pierre Avia - 75015 PARIS, immatriculée au registre du commerce et des sociétés de Paris sous le numéro 444 420 830
9
  * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
10
  */
11
 
1
  <?php
2
  /**
3
+ * DPD France v5.1.2 shipping module for Magento
4
  *
5
  * @category DPDFrance
6
  * @package DPDFrance_Shipping
7
+ * @author DPD France S.A.S. <ensavoirplus.ecommerce@dpd.fr>
8
+ * @copyright 2015 DPD France S.A.S., société par actions simplifiée, au capital de 18.500.000 euros, dont le siège social est situé 27 Rue du Colonel Pierre Avia - 75015 PARIS, immatriculée au registre du commerce et des sociétés de Paris sous le numéro 444 420 830
9
  * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
10
  */
11
 
app/code/community/DPDFrance/Export/controllers/TrackingController.php CHANGED
@@ -1,11 +1,11 @@
1
  <?php
2
  /**
3
- * DPD France v5.1.0 shipping module for Magento
4
  *
5
  * @category DPDFrance
6
  * @package DPDFrance_Shipping
7
- * @author DPD S.A.S. <ensavoirplus.ecommerce@dpd.fr>
8
- * @copyright 2015 DPD S.A.S., société par actions simplifiée, au capital de 18.500.000 euros, dont le siège social est situé 27 Rue du Colonel Pierre Avia - 75015 PARIS, immatriculée au registre du commerce et des sociétés de Paris sous le numéro 444 420 830
9
  * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
10
  */
11
 
1
  <?php
2
  /**
3
+ * DPD France v5.1.2 shipping module for Magento
4
  *
5
  * @category DPDFrance
6
  * @package DPDFrance_Shipping
7
+ * @author DPD France S.A.S. <ensavoirplus.ecommerce@dpd.fr>
8
+ * @copyright 2015 DPD France S.A.S., société par actions simplifiée, au capital de 18.500.000 euros, dont le siège social est situé 27 Rue du Colonel Pierre Avia - 75015 PARIS, immatriculée au registre du commerce et des sociétés de Paris sous le numéro 444 420 830
9
  * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
10
  */
11
 
app/code/community/DPDFrance/Export/etc/config.xml CHANGED
@@ -1,19 +1,19 @@
1
  <?xml version="1.0" encoding="UTF-8"?>
2
  <!--
3
  /**
4
- * DPD France v5.1.0 shipping module for Magento
5
  *
6
  * @category DPDFrance
7
  * @package DPDFrance_Shipping
8
- * @author DPD S.A.S. <ensavoirplus.ecommerce@dpd.fr>
9
- * @copyright 2015 DPD S.A.S., société par actions simplifiée, au capital de 18.500.000 euros, dont le siège social est situé 27 Rue du Colonel Pierre Avia - 75015 PARIS, immatriculée au registre du commerce et des sociétés de Paris sous le numéro 444 420 830
10
  * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
11
  */
12
  -->
13
  <config>
14
  <modules>
15
  <DPDFrance_Export>
16
- <version>5.1.1</version>
17
  <depends>
18
  <Mage_Shipping/>
19
  </depends>
1
  <?xml version="1.0" encoding="UTF-8"?>
2
  <!--
3
  /**
4
+ * DPD France v5.1.2 shipping module for Magento
5
  *
6
  * @category DPDFrance
7
  * @package DPDFrance_Shipping
8
+ * @author DPD France S.A.S. <ensavoirplus.ecommerce@dpd.fr>
9
+ * @copyright 2015 DPD France S.A.S., société par actions simplifiée, au capital de 18.500.000 euros, dont le siège social est situé 27 Rue du Colonel Pierre Avia - 75015 PARIS, immatriculée au registre du commerce et des sociétés de Paris sous le numéro 444 420 830
10
  * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
11
  */
12
  -->
13
  <config>
14
  <modules>
15
  <DPDFrance_Export>
16
+ <version>5.1.2</version>
17
  <depends>
18
  <Mage_Shipping/>
19
  </depends>
app/code/community/DPDFrance/Predict/Helper/Data.php CHANGED
@@ -1,11 +1,11 @@
1
  <?php
2
  /**
3
- * DPD France v5.1.0 shipping module for Magento
4
  *
5
  * @category DPDFrance
6
  * @package DPDFrance_Shipping
7
- * @author DPD S.A.S. <ensavoirplus.ecommerce@dpd.fr>
8
- * @copyright 2015 DPD S.A.S., société par actions simplifiée, au capital de 18.500.000 euros, dont le siège social est situé 27 Rue du Colonel Pierre Avia - 75015 PARIS, immatriculée au registre du commerce et des sociétés de Paris sous le numéro 444 420 830
9
  * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
10
  */
11
 
1
  <?php
2
  /**
3
+ * DPD France v5.1.2 shipping module for Magento
4
  *
5
  * @category DPDFrance
6
  * @package DPDFrance_Shipping
7
+ * @author DPD France S.A.S. <ensavoirplus.ecommerce@dpd.fr>
8
+ * @copyright 2015 DPD France S.A.S., société par actions simplifiée, au capital de 18.500.000 euros, dont le siège social est situé 27 Rue du Colonel Pierre Avia - 75015 PARIS, immatriculée au registre du commerce et des sociétés de Paris sous le numéro 444 420 830
9
  * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
10
  */
11
 
app/code/community/DPDFrance/Predict/Model/Carrier/DPDFrancePredictShipping.php CHANGED
@@ -1,31 +1,31 @@
1
  <?php
2
  /**
3
- * DPD France v5.1.0 shipping module for Magento
4
  *
5
  * @category DPDFrance
6
  * @package DPDFrance_Shipping
7
- * @author DPD S.A.S. <ensavoirplus.ecommerce@dpd.fr>
8
- * @copyright 2015 DPD S.A.S., société par actions simplifiée, au capital de 18.500.000 euros, dont le siège social est situé 27 Rue du Colonel Pierre Avia - 75015 PARIS, immatriculée au registre du commerce et des sociétés de Paris sous le numéro 444 420 830
9
  * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
10
  */
11
 
12
  class DPDFrance_Predict_Model_Carrier_DPDFrancePredictShipping extends Mage_Shipping_Model_Carrier_Abstract {
13
 
14
- protected $_code = "dpdfrpredict";
15
- protected $_expenseConfig;
16
- /**
17
- * Owebia
18
- *
19
- * @var DPDFrance_Predict_Model_Owebia
20
- */
21
- protected $_owebiaCore;
22
- protected $_messages;
23
-
24
- protected function _addMessages($messages) {
25
- if (!is_array($messages)) $messages = array($messages);
26
- if (!is_array($this->_messages)) $this->_messages = $messages;
27
- else $this->_messages = array_merge($this->_messages, $messages);
28
- }
29
 
30
  public function getAllowedMethods() {
31
  $process = array();
@@ -39,26 +39,26 @@ class DPDFrance_Predict_Model_Carrier_DPDFrancePredictShipping extends Mage_Ship
39
  return $allowed_methods;
40
  }
41
 
42
- protected function _appendMethod($process, $row, $fees) {
43
- $method = Mage::getModel('shipping/rate_result_method')
44
- ->setCarrier($this->_code)
45
- ->setCarrierTitle($this->getConfigData('title'))
46
- ->setMethod($row['*code'])
47
- // ->setMethod('dpdfrpredict')
48
- ->setMethodTitle($this->getConfigData('methodname') . ' ' . $this->_getMethodText($process,$row,'label'))
49
- //->setMethodDescription($this->_getMethodText($process,$row,'description')) // can be enabled if necessary
50
- ->setPrice($fees)
51
- ->setCost($fees)
52
- ;
53
-
54
- $process['result']->append($method);
55
- }
56
-
57
- protected function _formatPrice($price) {
58
- return Mage::helper('core')->currency($price);
59
- }
60
-
61
- protected function _getCartTaxAmount($process) {
62
  $quote = Mage::getSingleton('checkout/session')->getQuote();
63
  $items_in_cart = $quote->getAllVisibleItems();
64
  // var_dump($quote, $items_in_cart);exit;
@@ -86,194 +86,194 @@ class DPDFrance_Predict_Model_Carrier_DPDFrancePredictShipping extends Mage_Ship
86
 
87
  }
88
 
89
- /**
90
- * Get Checkout Session Model
91
- *
92
- * @return Mage_Checkout_Model_Session
93
- */
94
- protected function _getCheckoutSession()
95
- {
96
- return Mage::getSingleton('checkout/session');
97
- }
98
-
99
- protected function _getConfig() {
100
- if (!isset($this->_expenseConfig)) {
101
- $this->_owebiaCore = Mage::getModel('dpdfrpredict/owebia', $this->getConfigData('expense'));
102
- $this->_expenseConfig = $this->_owebiaCore->getConfig();
103
- $this->_addMessages($this->_owebiaCore->getMessages());
104
- }
105
- return $this->_expenseConfig;
106
- }
107
-
108
- protected function _getCountryName($country_code) {
109
- return Mage::getModel('directory/country')->load($country_code)->getName();
110
- }
111
-
112
- protected function _getMethodText($process, $row, $property) {
113
- if (!isset($row[$property])) return '';
114
-
115
- return $this->_owebiaCore->evalInput($process,$row,$property,str_replace(
116
- array('{cart.weight}','{cart.price_including_tax}','{cart.price_excluding_tax}'),
117
- array(
118
- $process['data']['cart.weight'].$process['data']['cart.weight.unit'],
119
- $this->_formatPrice($process['data']['cart.price_including_tax']),
120
- $this->_formatPrice($process['data']['cart.price_excluding_tax'])
121
- ),
122
- $this->_owebiaCore->getRowProperty($row,$property)
123
- ));
124
- }
125
-
126
- protected function _process(&$process) {
127
- $store = Mage::app()->getStore($process['data']['store.id']);
128
- $timestamp = time();
129
- $customer_group_id = Mage::getSingleton('customer/session')->getCustomerGroupId();
130
- // Pour les commandes depuis Adminhtml
131
- if ($customer_group_id==0) {
132
- $customer_group_id2 = Mage::getSingleton('adminhtml/session_quote')->getQuote()->getCustomerGroupId();
133
- if (isset($customer_group_id2)) $customer_group_id = $customer_group_id2;
134
- }
135
-
136
- $customer_group_code = Mage::getSingleton('customer/group')->load($customer_group_id)->getData('customer_group_code');
137
- $process['data'] = array_merge($process['data'],array(
138
- 'customer.group.id' => $customer_group_id,
139
- 'customer.group.code' => $customer_group_code,
140
- 'destination.country.name' => $this->_getCountryName($process['data']['destination.country.code']),
141
- 'destination.postal.code' => Mage::getSingleton('checkout/session')->getQuote()->getShippingAddress()->getPostcode(),
142
- 'origin.country.name' => $this->_getCountryName($process['data']['origin.country.code']),
143
- 'cart.weight.unit' => 'kg',
144
- 'store.code' => $store->getCode(),
145
- 'store.name' => $store->getConfig('general/store_information/name'),
146
- 'store.address' => $store->getConfig('general/store_information/address'),
147
- 'store.phone' => $store->getConfig('general/store_information/phone'),
148
- 'date.timestamp' => $timestamp,
149
- 'date.year' => (int)date('Y',$timestamp),
150
- 'date.month' => (int)date('m',$timestamp),
151
- 'date.day' => (int)date('d',$timestamp),
152
- 'date.hour' => (int)date('H',$timestamp),
153
- 'date.minute' => (int)date('i',$timestamp),
154
- 'date.second' => (int)date('s',$timestamp),
155
- ));
156
-
157
- // We don't need process certain products. If necessary, enable this block.
158
- foreach ($process['cart.items'] as $id => $item) {
159
- if ($item->getProduct()->getTypeId()!='configurable') {
160
- $parent_item_id = $item->getParentItemId();
161
- $process['products'][] = new DPDFrance_Predict_Magento_Product($item, isset($process['cart.items'][$parent_item_id]) ? $process['cart.items'][$parent_item_id] : null);
162
- }
163
- }
164
-
165
-
166
- if (!$process['data']['free_shipping']) {
167
- foreach ($process['cart.items'] as $item) {
168
- if ($item->getProduct() instanceof Mage_Catalog_Model_Product) {
169
- if ($item->getFreeShipping()) $process['data']['free_shipping'] = true;
170
- else {
171
- $process['data']['free_shipping'] = false;
172
- break;
173
- }
174
- }
175
- }
176
- }
177
-
178
- $process['data']['cart.price_including_tax'] = $this->_getCartTaxAmount($process)+$process['data']['cart.price_excluding_tax'];
179
  // var_dump($process['data']['cart.price_excluding_tax'], $process['data']['cart.price_including_tax']);exit;
180
 
181
- $value_found = false;
182
- foreach ($this->_getConfig() as $row) {
183
- $result = $this->_owebiaCore->processRow($process, $row);
184
- $this->_addMessages($this->_owebiaCore->getMessages());
185
- if ($result->success) {
186
  if ($process['stop_to_first_match'] && $value_found) {
187
- // Mage::log('DPD Predict shipping Method : WARNING, destination is duplicated in BO configuration. Using first one, skipping others', Zend_Log::WARN);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
188
  break;
189
  }
190
- $value_found = true;
191
- $this->_appendMethod($process, $row, $result->result);
192
- }
193
- }
194
-
195
- if (!$value_found && $this->getConfigData('showerror')) $this->_setError($process, $this->getConfigData('specificerrmsg'));
196
- }
197
-
198
- protected function _setError(&$process, $message) {
199
- if (is_array($this->_messages))
200
- foreach ($this->_messages as $errMessage)
201
- if ($errMessage->type == 'over_weight') {
202
- $message = 'Your shopping cart is too heavy for being shipped by DPD Predict';
203
- break;
204
- }
205
- $error = Mage::getModel('shipping/rate_result_error')
206
- ->setCarrier($this->_code)
207
- ->setCarrierTitle($this->getConfigData('title'))
208
- ->setErrorMessage(Mage::helper('shipping')->__($message))
209
- ;
210
- $process['result'] = $error;
211
- }
212
-
213
- public function collectRates(Mage_Shipping_Model_Rate_Request $request){
214
- try {
215
- $process = array(
216
- 'result' => Mage::getModel('shipping/rate_result'),
217
- 'cart.items' => array(),
218
- 'products' => array(),
219
- 'data' => array(
220
- 'cart.price_excluding_tax' => $request->_data['package_value_with_discount'],
221
- 'cart.price_including_tax' => $request->_data['package_value_with_discount'],
222
- 'cart.weight' => $request->_data['package_weight'],
223
- 'cart.weight.unit' => null,
224
- 'cart.quantity' => $request->_data['package_qty'],
225
  'cart.coupon' => Mage::getSingleton('checkout/cart')->getQuote()->getCouponCode(),
226
- 'destination.country.code' => $request->_data['dest_country_id'],
227
- 'destination.country.name' => null,
228
- 'destination.region.code' => $request->_data['dest_region_code'],
229
- 'destination.postal.code' => $request->_data['dest_postcode'],
230
- 'origin.country.code' => $request->_data['country_id'],
231
- 'origin.country.name' => null,
232
- 'origin.region.code' => $request->_data['region_id'],
233
- 'origin.postal.code' => $request->_data['postcode'],
234
- 'customer.group.id' => null,
235
- 'customer.group.code' => null,
236
- 'free_shipping' => $request->getFreeShipping(),
237
- 'store.id' => $request->_data['store_id'],
238
- 'store.code' => null,
239
- 'store.name' => null,
240
- 'store.address' => null,
241
- 'store.phone' => null,
242
- 'date.timestamp' => null,
243
- 'date.year' => null,
244
- 'date.month' => null,
245
- 'date.day' => null,
246
- 'date.hour' => null,
247
- 'date.minute' => null,
248
- 'date.second' => null,
249
- ),
250
- 'stop_to_first_match' => TRUE,
251
- 'config' => null,
252
- );
253
-
254
- // We don't need process certain products. If necessary, enable this block.
255
- $items = $request->getAllItems();
256
- for ($i=0, $n=count($items); $i<$n; $i++) {
257
- $item = $items[$i];
258
- if ($item->getProduct() instanceof Mage_Catalog_Model_Product) $process['cart.items'][$item->getId()] = $item;
259
- }
260
-
261
-
262
- $this->_process($process);
263
- return $process['result'];
264
- }
265
- catch (Exception $e){
266
- Mage::logException($e);
267
- }
268
-
269
- }
270
-
271
- public function isTrackingAvailable() {
272
- return true;
273
- }
274
-
275
- public function getTrackingInfo($trackingNumber)
276
- {
277
  $trackingUrlByRef = 'http://www.dpd.fr/tracer_'.$trackingNumber;
278
  $trackingUrlByNb = 'http://www.dpd.fr/traces_'.$trackingNumber;
279
  $cargo = Mage::getStoreConfig('carriers/dpdfrpredict/cargo');
@@ -281,7 +281,7 @@ class DPDFrance_Predict_Model_Carrier_DPDFrancePredictShipping extends Mage_Ship
281
  $cargoutilise = substr($trackingNumber, -(int) $longueurcargo);
282
 
283
  if($cargoutilise == $cargo){
284
- $trackingStatus = Mage::getModel('shipping/tracking_result_status')
285
  ->setCarrier('dpdfrpredict')
286
  ->setCarrierTitle('DPD Predict')
287
  ->setTracking($trackingNumber)
@@ -309,93 +309,93 @@ class DPDFrance_Predict_Model_Carrier_DPDFrancePredictShipping extends Mage_Ship
309
  }
310
 
311
  class DPDFrance_Predict_Magento_Product implements DPDFrance_Predict_Os_Product {
312
- private $parent_cart_item;
313
- private $cart_item;
314
- private $cart_product;
315
- private $loaded_product;
316
- private $quantity;
317
-
318
- public function __construct($cart_item, $parent_cart_item) {
319
- $this->cart_item = $cart_item;
320
- $this->cart_product = $cart_item->getProduct();
321
- $this->parent_cart_item = $parent_cart_item;
322
- $this->quantity = isset($parent_cart_item) ? $parent_cart_item->getQty() : $cart_item->getQty();
323
- }
324
-
325
- public function getOption($option_name, $get_by_id=false) {
326
- $value = null;
327
- $product = $this->cart_product;
328
- foreach ($product->getOptions() as $option) {
329
- if ($option->getTitle()==$option_name) {
330
- $custom_option = $product->getCustomOption('option_'.$option->getId());
331
- if ($custom_option) {
332
- $value = $custom_option->getValue();
333
- if ($option->getType()=='drop_down' && !$get_by_id) {
334
- $option_value = $option->getValueById($value);
335
- if ($option_value) $value = $option_value->getTitle();
336
- }
337
- }
338
- break;
339
- }
340
- }
341
- return $value;
342
- }
343
-
344
- public function getAttribute($attribute_name, $get_by_id=false) {
345
- $value = null;
346
- $product = $this->_getLoadedProduct();
347
- $attribute = $product->getResource()->getAttribute($attribute_name);
348
- if ($attribute) {
349
- $input_type = $attribute->getFrontend()->getInputType();
350
- switch ($input_type) {
351
- case 'select' :
352
- $value = $get_by_id ? $product->getData($attribute_name) : $product->getAttributeText($attribute_name);
353
- break;
354
- default :
355
- $value = $product->getData($attribute_name);
356
- break;
357
- }
358
- }
359
- return $value;
360
- }
361
-
362
- private function _getLoadedProduct() {
363
- if (!isset($this->loaded_product)) $this->loaded_product = Mage::getModel('catalog/product')->load($this->cart_product->getId());
364
- return $this->loaded_product;
365
- }
366
-
367
- public function getQuantity() {
368
- return $this->quantity;
369
- }
370
-
371
- public function getName() {
372
- return $this->cart_product->getName();
373
- }
374
-
375
- public function getSku() {
376
- return $this->cart_product->getSku();
377
- }
378
-
379
- public function getStockData($key) {
380
- $stock = $this->cart_product->getStockItem();
381
- switch ($key) {
382
- case 'is_in_stock':
383
- return (bool)$stock->getIsInStock();
384
- case 'quantity':
385
- $quantity = $stock->getQty();
386
- return $stock->getIsQtyDecimal() ? (float)$quantity : (int)$quantity;
387
- }
388
- return null;
389
- }
390
  }
391
 
392
  interface DPDFrance_Predict_Os_Product {
393
- public function getOption($option);
394
- public function getAttribute($attribute);
395
- public function getName();
396
- public function getSku();
397
- public function getQuantity();
398
- public function getStockData($key);
399
  }
400
 
401
  ?>
1
  <?php
2
  /**
3
+ * DPD France v5.1.2 shipping module for Magento
4
  *
5
  * @category DPDFrance
6
  * @package DPDFrance_Shipping
7
+ * @author DPD France S.A.S. <ensavoirplus.ecommerce@dpd.fr>
8
+ * @copyright 2015 DPD France S.A.S., société par actions simplifiée, au capital de 18.500.000 euros, dont le siège social est situé 27 Rue du Colonel Pierre Avia - 75015 PARIS, immatriculée au registre du commerce et des sociétés de Paris sous le numéro 444 420 830
9
  * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
10
  */
11
 
12
  class DPDFrance_Predict_Model_Carrier_DPDFrancePredictShipping extends Mage_Shipping_Model_Carrier_Abstract {
13
 
14
+ protected $_code = "dpdfrpredict";
15
+ protected $_expenseConfig;
16
+ /**
17
+ * Owebia
18
+ *
19
+ * @var DPDFrance_Predict_Model_Owebia
20
+ */
21
+ protected $_owebiaCore;
22
+ protected $_messages;
23
+
24
+ protected function _addMessages($messages) {
25
+ if (!is_array($messages)) $messages = array($messages);
26
+ if (!is_array($this->_messages)) $this->_messages = $messages;
27
+ else $this->_messages = array_merge($this->_messages, $messages);
28
+ }
29
 
30
  public function getAllowedMethods() {
31
  $process = array();
39
  return $allowed_methods;
40
  }
41
 
42
+ protected function _appendMethod($process, $row, $fees) {
43
+ $method = Mage::getModel('shipping/rate_result_method')
44
+ ->setCarrier($this->_code)
45
+ ->setCarrierTitle($this->getConfigData('title'))
46
+ ->setMethod($row['*code'])
47
+ // ->setMethod('dpdfrpredict')
48
+ ->setMethodTitle($this->getConfigData('methodname') . ' ' . $this->_getMethodText($process,$row,'label'))
49
+ //->setMethodDescription($this->_getMethodText($process,$row,'description')) // can be enabled if necessary
50
+ ->setPrice($fees)
51
+ ->setCost($fees)
52
+ ;
53
+
54
+ $process['result']->append($method);
55
+ }
56
+
57
+ protected function _formatPrice($price) {
58
+ return Mage::helper('core')->currency($price);
59
+ }
60
+
61
+ protected function _getCartTaxAmount($process) {
62
  $quote = Mage::getSingleton('checkout/session')->getQuote();
63
  $items_in_cart = $quote->getAllVisibleItems();
64
  // var_dump($quote, $items_in_cart);exit;
86
 
87
  }
88
 
89
+ /**
90
+ * Get Checkout Session Model
91
+ *
92
+ * @return Mage_Checkout_Model_Session
93
+ */
94
+ protected function _getCheckoutSession()
95
+ {
96
+ return Mage::getSingleton('checkout/session');
97
+ }
98
+
99
+ protected function _getConfig() {
100
+ if (!isset($this->_expenseConfig)) {
101
+ $this->_owebiaCore = Mage::getModel('dpdfrpredict/owebia', $this->getConfigData('expense'));
102
+ $this->_expenseConfig = $this->_owebiaCore->getConfig();
103
+ $this->_addMessages($this->_owebiaCore->getMessages());
104
+ }
105
+ return $this->_expenseConfig;
106
+ }
107
+
108
+ protected function _getCountryName($country_code) {
109
+ return Mage::getModel('directory/country')->load($country_code)->getName();
110
+ }
111
+
112
+ protected function _getMethodText($process, $row, $property) {
113
+ if (!isset($row[$property])) return '';
114
+
115
+ return $this->_owebiaCore->evalInput($process,$row,$property,str_replace(
116
+ array('{cart.weight}','{cart.price_including_tax}','{cart.price_excluding_tax}'),
117
+ array(
118
+ $process['data']['cart.weight'].$process['data']['cart.weight.unit'],
119
+ $this->_formatPrice($process['data']['cart.price_including_tax']),
120
+ $this->_formatPrice($process['data']['cart.price_excluding_tax'])
121
+ ),
122
+ $this->_owebiaCore->getRowProperty($row,$property)
123
+ ));
124
+ }
125
+
126
+ protected function _process(&$process) {
127
+ $store = Mage::app()->getStore($process['data']['store.id']);
128
+ $timestamp = time();
129
+ $customer_group_id = Mage::getSingleton('customer/session')->getCustomerGroupId();
130
+ // Pour les commandes depuis Adminhtml
131
+ if ($customer_group_id==0) {
132
+ $customer_group_id2 = Mage::getSingleton('adminhtml/session_quote')->getQuote()->getCustomerGroupId();
133
+ if (isset($customer_group_id2)) $customer_group_id = $customer_group_id2;
134
+ }
135
+
136
+ $customer_group_code = Mage::getSingleton('customer/group')->load($customer_group_id)->getData('customer_group_code');
137
+ $process['data'] = array_merge($process['data'],array(
138
+ 'customer.group.id' => $customer_group_id,
139
+ 'customer.group.code' => $customer_group_code,
140
+ 'shipto.country.name' => $this->_getCountryName($process['data']['shipto.country.code']),
141
+ 'shipto.postal.code' => Mage::getSingleton('checkout/session')->getQuote()->getShippingAddress()->getPostcode(),
142
+ 'origin.country.name' => $this->_getCountryName($process['data']['origin.country.code']),
143
+ 'cart.weight.unit' => 'kg',
144
+ 'store.code' => $store->getCode(),
145
+ 'store.name' => $store->getConfig('general/store_information/name'),
146
+ 'store.address' => $store->getConfig('general/store_information/address'),
147
+ 'store.phone' => $store->getConfig('general/store_information/phone'),
148
+ 'date.timestamp' => $timestamp,
149
+ 'date.year' => (int)date('Y',$timestamp),
150
+ 'date.month' => (int)date('m',$timestamp),
151
+ 'date.day' => (int)date('d',$timestamp),
152
+ 'date.hour' => (int)date('H',$timestamp),
153
+ 'date.minute' => (int)date('i',$timestamp),
154
+ 'date.second' => (int)date('s',$timestamp),
155
+ ));
156
+
157
+ // We don't need process certain products. If necessary, enable this block.
158
+ foreach ($process['cart.items'] as $id => $item) {
159
+ if ($item->getProduct()->getTypeId()!='configurable') {
160
+ $parent_item_id = $item->getParentItemId();
161
+ $process['products'][] = new DPDFrance_Predict_Magento_Product($item, isset($process['cart.items'][$parent_item_id]) ? $process['cart.items'][$parent_item_id] : null);
162
+ }
163
+ }
164
+
165
+
166
+ if (!$process['data']['free_shipping']) {
167
+ foreach ($process['cart.items'] as $item) {
168
+ if ($item->getProduct() instanceof Mage_Catalog_Model_Product) {
169
+ if ($item->getFreeShipping()) $process['data']['free_shipping'] = true;
170
+ else {
171
+ $process['data']['free_shipping'] = false;
172
+ break;
173
+ }
174
+ }
175
+ }
176
+ }
177
+
178
+ $process['data']['cart.price_including_tax'] = $this->_getCartTaxAmount($process)+$process['data']['cart.price_excluding_tax'];
179
  // var_dump($process['data']['cart.price_excluding_tax'], $process['data']['cart.price_including_tax']);exit;
180
 
181
+ $value_found = false;
182
+ foreach ($this->_getConfig() as $row) {
183
+ $result = $this->_owebiaCore->processRow($process, $row);
184
+ $this->_addMessages($this->_owebiaCore->getMessages());
185
+ if ($result->success) {
186
  if ($process['stop_to_first_match'] && $value_found) {
187
+ // Mage::log('DPD Predict shipping Method : WARNING, shipto is duplicated in BO configuration. Using first one, skipping others', Zend_Log::WARN);
188
+ break;
189
+ }
190
+ $value_found = true;
191
+ $this->_appendMethod($process, $row, $result->result);
192
+ }
193
+ }
194
+
195
+ if (!$value_found && $this->getConfigData('showerror')) $this->_setError($process, $this->getConfigData('specificerrmsg'));
196
+ }
197
+
198
+ protected function _setError(&$process, $message) {
199
+ if (is_array($this->_messages))
200
+ foreach ($this->_messages as $errMessage)
201
+ if ($errMessage->type == 'over_weight') {
202
+ $message = 'Your shopping cart is too heavy for being shipped by DPD Predict';
203
  break;
204
  }
205
+ $error = Mage::getModel('shipping/rate_result_error')
206
+ ->setCarrier($this->_code)
207
+ ->setCarrierTitle($this->getConfigData('title'))
208
+ ->setErrorMessage(Mage::helper('shipping')->__($message))
209
+ ;
210
+ $process['result'] = $error;
211
+ }
212
+
213
+ public function collectRates(Mage_Shipping_Model_Rate_Request $request){
214
+ try {
215
+ $process = array(
216
+ 'result' => Mage::getModel('shipping/rate_result'),
217
+ 'cart.items' => array(),
218
+ 'products' => array(),
219
+ 'data' => array(
220
+ 'cart.price_excluding_tax' => $request->_data['package_value_with_discount'],
221
+ 'cart.price_including_tax' => $request->_data['package_value_with_discount'],
222
+ 'cart.weight' => $request->_data['package_weight'],
223
+ 'cart.weight.unit' => null,
224
+ 'cart.quantity' => $request->_data['package_qty'],
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
225
  'cart.coupon' => Mage::getSingleton('checkout/cart')->getQuote()->getCouponCode(),
226
+ 'shipto.country.code' => $request->_data['dest_country_id'],
227
+ 'shipto.country.name' => null,
228
+ 'shipto.region.code' => $request->_data['dest_region_code'],
229
+ 'shipto.postal.code' => $request->_data['dest_postcode'],
230
+ 'origin.country.code' => $request->_data['country_id'],
231
+ 'origin.country.name' => null,
232
+ 'origin.region.code' => $request->_data['region_id'],
233
+ 'origin.postal.code' => $request->_data['postcode'],
234
+ 'customer.group.id' => null,
235
+ 'customer.group.code' => null,
236
+ 'free_shipping' => $request->getFreeShipping(),
237
+ 'store.id' => $request->_data['store_id'],
238
+ 'store.code' => null,
239
+ 'store.name' => null,
240
+ 'store.address' => null,
241
+ 'store.phone' => null,
242
+ 'date.timestamp' => null,
243
+ 'date.year' => null,
244
+ 'date.month' => null,
245
+ 'date.day' => null,
246
+ 'date.hour' => null,
247
+ 'date.minute' => null,
248
+ 'date.second' => null,
249
+ ),
250
+ 'stop_to_first_match' => TRUE,
251
+ 'config' => null,
252
+ );
253
+
254
+ // We don't need process certain products. If necessary, enable this block.
255
+ $items = $request->getAllItems();
256
+ for ($i=0, $n=count($items); $i<$n; $i++) {
257
+ $item = $items[$i];
258
+ if ($item->getProduct() instanceof Mage_Catalog_Model_Product) $process['cart.items'][$item->getId()] = $item;
259
+ }
260
+
261
+
262
+ $this->_process($process);
263
+ return $process['result'];
264
+ }
265
+ catch (Exception $e){
266
+ Mage::logException($e);
267
+ }
268
+
269
+ }
270
+
271
+ public function isTrackingAvailable() {
272
+ return true;
273
+ }
274
+
275
+ public function getTrackingInfo($trackingNumber)
276
+ {
277
  $trackingUrlByRef = 'http://www.dpd.fr/tracer_'.$trackingNumber;
278
  $trackingUrlByNb = 'http://www.dpd.fr/traces_'.$trackingNumber;
279
  $cargo = Mage::getStoreConfig('carriers/dpdfrpredict/cargo');
281
  $cargoutilise = substr($trackingNumber, -(int) $longueurcargo);
282
 
283
  if($cargoutilise == $cargo){
284
+ $trackingStatus = Mage::getModel('shipping/tracking_result_status')
285
  ->setCarrier('dpdfrpredict')
286
  ->setCarrierTitle('DPD Predict')
287
  ->setTracking($trackingNumber)
309
  }
310
 
311
  class DPDFrance_Predict_Magento_Product implements DPDFrance_Predict_Os_Product {
312
+ private $parent_cart_item;
313
+ private $cart_item;
314
+ private $cart_product;
315
+ private $loaded_product;
316
+ private $quantity;
317
+
318
+ public function __construct($cart_item, $parent_cart_item) {
319
+ $this->cart_item = $cart_item;
320
+ $this->cart_product = $cart_item->getProduct();
321
+ $this->parent_cart_item = $parent_cart_item;
322
+ $this->quantity = isset($parent_cart_item) ? $parent_cart_item->getQty() : $cart_item->getQty();
323
+ }
324
+
325
+ public function getOption($option_name, $get_by_id=false) {
326
+ $value = null;
327
+ $product = $this->cart_product;
328
+ foreach ($product->getOptions() as $option) {
329
+ if ($option->getTitle()==$option_name) {
330
+ $custom_option = $product->getCustomOption('option_'.$option->getId());
331
+ if ($custom_option) {
332
+ $value = $custom_option->getValue();
333
+ if ($option->getType()=='drop_down' && !$get_by_id) {
334
+ $option_value = $option->getValueById($value);
335
+ if ($option_value) $value = $option_value->getTitle();
336
+ }
337
+ }
338
+ break;
339
+ }
340
+ }
341
+ return $value;
342
+ }
343
+
344
+ public function getAttribute($attribute_name, $get_by_id=false) {
345
+ $value = null;
346
+ $product = $this->_getLoadedProduct();
347
+ $attribute = $product->getResource()->getAttribute($attribute_name);
348
+ if ($attribute) {
349
+ $input_type = $attribute->getFrontend()->getInputType();
350
+ switch ($input_type) {
351
+ case 'select' :
352
+ $value = $get_by_id ? $product->getData($attribute_name) : $product->getAttributeText($attribute_name);
353
+ break;
354
+ default :
355
+ $value = $product->getData($attribute_name);
356
+ break;
357
+ }
358
+ }
359
+ return $value;
360
+ }
361
+
362
+ private function _getLoadedProduct() {
363
+ if (!isset($this->loaded_product)) $this->loaded_product = Mage::getModel('catalog/product')->load($this->cart_product->getId());
364
+ return $this->loaded_product;
365
+ }
366
+
367
+ public function getQuantity() {
368
+ return $this->quantity;
369
+ }
370
+
371
+ public function getName() {
372
+ return $this->cart_product->getName();
373
+ }
374
+
375
+ public function getSku() {
376
+ return $this->cart_product->getSku();
377
+ }
378
+
379
+ public function getStockData($key) {
380
+ $stock = $this->cart_product->getStockItem();
381
+ switch ($key) {
382
+ case 'is_in_stock':
383
+ return (bool)$stock->getIsInStock();
384
+ case 'quantity':
385
+ $quantity = $stock->getQty();
386
+ return $stock->getIsQtyDecimal() ? (float)$quantity : (int)$quantity;
387
+ }
388
+ return null;
389
+ }
390
  }
391
 
392
  interface DPDFrance_Predict_Os_Product {
393
+ public function getOption($option);
394
+ public function getAttribute($attribute);
395
+ public function getName();
396
+ public function getSku();
397
+ public function getQuantity();
398
+ public function getStockData($key);
399
  }
400
 
401
  ?>
app/code/community/DPDFrance/Predict/Model/Observer.php CHANGED
@@ -1,11 +1,11 @@
1
  <?php
2
  /**
3
- * DPD France v5.1.0 shipping module for Magento
4
  *
5
  * @category DPDFrance
6
  * @package DPDFrance_Shipping
7
- * @author DPD S.A.S. <ensavoirplus.ecommerce@dpd.fr>
8
- * @copyright 2015 DPD S.A.S., société par actions simplifiée, au capital de 18.500.000 euros, dont le siège social est situé 27 Rue du Colonel Pierre Avia - 75015 PARIS, immatriculée au registre du commerce et des sociétés de Paris sous le numéro 444 420 830
9
  * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
10
  */
11
 
1
  <?php
2
  /**
3
+ * DPD France v5.1.2 shipping module for Magento
4
  *
5
  * @category DPDFrance
6
  * @package DPDFrance_Shipping
7
+ * @author DPD France S.A.S. <ensavoirplus.ecommerce@dpd.fr>
8
+ * @copyright 2015 DPD France S.A.S., société par actions simplifiée, au capital de 18.500.000 euros, dont le siège social est situé 27 Rue du Colonel Pierre Avia - 75015 PARIS, immatriculée au registre du commerce et des sociétés de Paris sous le numéro 444 420 830
9
  * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
10
  */
11
 
app/code/community/DPDFrance/Predict/Model/Owebia.php CHANGED
@@ -1,1173 +1,971 @@
1
  <?php
2
  /**
3
- * DPD France v5.1.0 shipping module for Magento
4
  *
5
  * @category DPDFrance
6
  * @package DPDFrance_Shipping
7
- * @author DPD S.A.S. <ensavoirplus.ecommerce@dpd.fr>
8
- * @copyright 2015 DPD S.A.S., société par actions simplifiée, au capital de 18.500.000 euros, dont le siège social est situé 27 Rue du Colonel Pierre Avia - 75015 PARIS, immatriculée au registre du commerce et des sociétés de Paris sous le numéro 444 420 830
9
  * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
10
  */
11
 
12
  class DPDFrance_Predict_Model_Owebia
13
  {
14
- public static $FLOAT_REGEX = '[-]?\d+(?:[.]\d+)?';
15
- public static $POSITIVE_FLOAT_REGEX = '\d+(?:[.]\d+)?';
16
- //public static $COUPLE_REGEX = '(?:[0-9.]+|\*)(?:\[|\])?\:[0-9.]+(?:\:[0-9.]+%?)*';
17
- public static $COUPLE_REGEX = '(?:[0-9.]+|\*) *(?:\[|\])? *\: *[0-9.]+';
18
- public static $UNCOMPRESSED_STRINGS = array(
19
- ' product.attribute.',
20
- ' product.option.',
21
- ' product.stock.',
22
- '{product.attribute.',
23
- '{product.option.',
24
- '{product.stock.',
25
- '{product.weight}',
26
- '{product.quantity}',
27
- '{cart.weight}',
28
- '{cart.quantity}',
29
  '{cart.coupon}',
30
- '{cart.price_including_tax}',
31
- '{cart.price_excluding_tax}',
32
- '{cart.',
33
- '{customvar.',
34
- '{selection.weight}',
35
- '{selection.quantity}',
36
- '{selection.',
37
- '{destination.country.',
38
- '{foreach ',
39
- '{/foreach}',
40
- );
41
- public static $COMPRESSED_STRINGS = array(
42
- ' p.a.',
43
- ' p.o.',
44
- ' p.s.',
45
- '{p.a.',
46
- '{p.o.',
47
- '{p.s.',
48
- '{p.w}',
49
- '{p.qty}',
50
- '{c.w}',
51
- '{c.qty}',
52
  '{c.cpn}',
53
- '{c.pit}',
54
- '{c.pet}',
55
- '{c.',
56
- '{v.',
57
- '{s.w}',
58
- '{s.qty}',
59
- '{s.',
60
- '{dest.ctry.',
61
- '{each ',
62
- '{/each}',
63
- );
64
-
65
- protected $_input;
66
- protected $_config;
67
- protected $_messages;
68
- protected $_formula_cache;
69
- protected $_expression_cache;
70
- protected $_overWeightMessage = 'Over weight';
71
- public $debug = 0;
72
- public $debug_output = '';
73
- public $debug_header = null;
74
-
75
- public function __construct($input) {
76
- $this->_formula_cache = array();
77
- $this->_messages = array();
78
- $this->_input = $input;
79
- $this->_config = array();
80
- $this->_parseInput();
81
- }
82
-
83
- private function debug($text, $level=10) {
84
- if ($this->debug>=$level) $this->debug_output .= "<p>".$text."</p>";
85
- }
86
-
87
- public function printDebug() {
88
- if ($this->debug>0) echo "<style rel=\"stylesheet\" type=\"text/css\">"
89
- .".osh-formula{color:#f90;} .osh-key{color:#0099f7;}"
90
- .".osh-error{color:#f00;} .osh-warning{color:#ff0;} .osh-info{color:#7bf700;}"
91
- .".osh-debug{background:#000;color:#bbb;position:absolute;top:0;left:0;width:100%;z-index:100;-moz-opacity:0.9;opacity:0.9;text-align:left;white-space:pre-wrap;}"
92
- .".osh-debug-content{padding:10px;}"
93
- .".osh-replacement{color:#ff3000;}"
94
- ."</style>"
95
- ."<div id=\"osh-debug\" class=\"osh-debug\"><pre class=\"osh-debug-content\"><span style=\"float:right;cursor:pointer;\" onclick=\"document.getElementById('osh-debug').style.display = 'none';\">[<span style=\"padding:0 5px;color:#f00;\">X</span>]</span>"
96
- ."<p>".$this->debug_header."</p>".$this->debug_output."</pre></div>";
97
- }
98
-
99
- public function setDebugHeader($process) {
100
- $header = 'DEBUG ' . __FILE__;//'DEBUG app/code/community/Owebia/Shipping/2/Model/Carrier/OwebiaShippingHelper.php<br/>';
101
- foreach ($process['data'] as $key => $data) {
102
- $header .= ' <span class="osh-key">'.$key.'</span> = <span class="osh-formula">'.$this->_toString($data).'</span><br/>';
103
- }
104
- $this->debug_header = $header;
105
- }
106
-
107
- public function getConfig() {
108
- return $this->_config;
109
- }
110
-
111
- public function getMessages() {
112
- $messages = $this->_messages;
113
- $this->_messages = array();
114
- return $messages;
115
- }
116
-
117
- public function formatConfig($compress) {
118
- $output = '';
119
- foreach ($this->_config as $code => $row) {
120
- if (!isset($row['lines'])) {
121
- if (isset($row['*comment']['value'])) {
122
- $output .= trim($row['*comment']['value'])."\n";
123
- }
124
- $output .= '{'.($compress ? '' : "\n");
125
- foreach ($row as $key => $property) {
126
- if (substr($key,0,1)!='*') {
127
- $value = $property['value'];
128
- if (isset($property['comment'])) $output .= ($compress ? '' : "\t").'/* '.$property['comment'].' */'.($compress ? '' : "\n");
129
- $output .= ($compress ? '' : "\t").$key.':'.($compress ? '' : ' ');
130
- if (is_bool($value)) $output .= $value ? 'true' : 'false';
131
- else if (is_int($value)) $output .= $value;
132
- else if ((string)((float)$value)==$value) $output .= $value;
133
- else $output .= '"'.str_replace('"','\\"',$value).'"';
134
- $output .= ','.($compress ? '' : "\n");
135
- }
136
- }
137
- if ($compress) $output = preg_replace('/,$/','',$output);
138
- $output .= "}\n".($compress ? '' : "\n");
139
- } else {
140
- $output .= $row['lines']."\n";
141
- }
142
- }
143
- return $compress ? $this->compress($output) : $this->uncompress($output);
144
- }
145
-
146
- public function checkConfig() {
147
- $process = array(
148
- 'result' => null,
149
- 'data' => array(
150
- 'cart.price_excluding_tax' => 0,
151
- 'cart.price_including_tax' => 0,
152
- 'destination.country.code' => '',
153
- 'destination.country.name' => '',
154
- 'destination.region.code' => '',
155
- 'destination.postal.code' => '',
156
- 'origin.country.code' => '',
157
- 'origin.country.name' => '',
158
- 'origin.region.code' => '',
159
- 'origin.postal.code' => '',
160
- 'free_shipping' => false,
161
- 'customer.group.id' => '',
162
- 'customer.group.code' => '',
163
- 'cart.weight' => 0,
164
- 'cart.weight.unit' => 'kg',
165
- 'cart.quantity' => 0,
166
- ),
167
- 'cart.items' => array(),
168
- 'products' => array(),
169
- 'config' => $this->_config,
170
- );
171
- foreach ($this->_config as $code => &$row) {
172
- $this->processRow($process,$row,$check_all_conditions=true);
173
- foreach ($row as $property_key => $property_value) {
174
- if (substr($property_key,0,1)!='*') $this->getRowProperty($row,$property_key);
175
- }
176
- }
177
- }
178
-
179
- public function processRow($process, &$row, $is_checking=false) {
180
- if (!isset($row['*code'])) return;
181
-
182
- self::debug('process row <span class="osh-key">'.$row['*code'].'</span>',1);
183
- if (!isset($row['label']['value'])) $row['label']['value'] = '';
184
-
185
- $enabled = $this->getRowProperty($row,'enabled');
186
- if (isset($enabled)) {
187
- if (!$is_checking && !$enabled) {
188
- $this->addMessage('info',$row,'enabled','Configuration disabled');
189
- return new DPDFrancePredict_Os_Result(false);
190
- }
191
- }
192
-
193
- $conditions = $this->getRowProperty($row,'conditions');
194
- if (isset($conditions)) {
195
- $result = $this->_processFormula($process,$row,'conditions',$conditions,$is_checking);
196
- if (!$is_checking) {
197
- if (!$result->success) return $result;
198
- if (!$result->result) {
199
- $this->addMessage('info',$row,'conditions',"The cart doesn't match conditions");
200
- return new DPDFrancePredict_Os_Result(false);
201
- }
202
- }
203
- }
204
-
205
- $destination = $this->getRowProperty($row,'destination');
206
- if (isset($destination)) {
207
- $destination_match = $this->_addressMatch($destination,array(
208
- 'country_code' => $process['data']['destination.country.code'],
209
- 'region_code' => $process['data']['destination.region.code'],
210
- 'postcode' => $process['data']['destination.postal.code']
211
- ));
212
- if (!$is_checking && !$destination_match) {
213
- $this->addMessage('info',$row,'destination',"The shipping method doesn't cover the zone");
214
- return new DPDFrancePredict_Os_Result(false);
215
- }
216
- }
217
-
218
- $origin = $this->getRowProperty($row,'origin');
219
- if (isset($origin)) {
220
- $origin_match = $this->_addressMatch($origin,array(
221
- 'country_code' => $process['data']['origin.country.code'],
222
- 'region_code' => $process['data']['origin.region.code'],
223
- 'postcode' => $process['data']['origin.postal.code']
224
- ));
225
- if (!$is_checking && !$origin_match) {
226
- $this->addMessage('info',$row,'origin',"The shipping method doesn't match to shipping origin");
227
- return new DPDFrancePredict_Os_Result(false);
228
- }
229
- }
230
-
231
- $customer_groups = $this->getRowProperty($row,'customer_groups');
232
- if (isset($customer_groups)) {
233
- $groups = explode(',',$customer_groups);
234
- $group_match = false;
235
- //self::debug('code:'.$process['data']['customer.group.code'].', id:'.$process['data']['customer.group.id']);
236
- foreach ($groups as $group) {
237
- $group = trim($group);
238
- if ($group==$process['data']['customer.group.code'] || is_int($group) && $group==$process['data']['customer.group.id'] || $group=='*') {
239
- $group_match = true;
240
- break;
241
- }
242
- }
243
- if (!$is_checking && !$group_match) {
244
- $this->addMessage('info',$row,'customer_groups',"The shipping method doesn't match to customer group (%s)",$process['data']['customer.group.code']);
245
- return new DPDFrancePredict_Os_Result(false);
246
- }
247
- }
248
-
249
- $fees = $this->getRowProperty($row,'fees');
250
- if (isset($fees)) {
251
- $result = $this->_processFormula($process,$row,'fees',$fees,$is_checking);
252
- if (!$result->success) return $result;
253
- self::debug(' => <span class="osh-info">result = <span class="osh-formula">'.$this->_toString($result->result).'</span>',1);
254
- return new DPDFrancePredict_Os_Result(true,(float)$result->result);
255
- }
256
- return new DPDFrancePredict_Os_Result(false);
257
- }
258
-
259
- public function getRowProperty($row, $key, $original_row=null, $original_key=null) {
260
- $property = null;
261
- $output = null;
262
- if (isset($original_row) && isset($original_key) && $original_row['*code']==$row['*code'] && $original_key==$key) {
263
- $this->addMessage('error',$row,$key,'Infinite loop %s',"<span class=\"code\">{".$row['*code'].'.'.$key."}</span>");
264
- return array('error' => 'Infinite loop');
265
- }
266
- if (isset($row[$key]['value'])) {
267
- $property = $row[$key]['value'];
268
- $output = $property;
269
- $code = array_key_exists('*code', $row) ? $row['*code'] : NULL; self::debug(' get <span class="osh-key">'.$code.'</span>.<span class="osh-key">'.$key.'</span> = <span class="osh-formula">'.$this->_toString($property).'</span>',5);
270
- preg_match_all('/{([a-z0-9_]+)\.([a-z0-9_]+)}/i',$output,$result_set,PREG_SET_ORDER);
271
- foreach ($result_set as $result) {
272
- list($original,$ref_code,$ref_key) = $result;
273
- if (!in_array($ref_code,array('module','date','store','cart','product','selection','customvar'))) {
274
- if ($ref_code==$row['code']['value'] && $ref_key==$key) {
275
- $this->addMessage('error',$row,$key,'Infinite loop %s',"<span class=\"code\">".$original."</span>");
276
- return null;
277
- }
278
- if (isset($this->_config[$ref_code][$ref_key]['value'])) {
279
- $replacement = $this->getRowProperty($this->_config[$ref_code],$ref_key,
280
- isset($original_row) ? $original_row : $row,isset($original_key) ? $original_key : $key);
281
- if (is_array($replacement) && isset($replacement['error'])) {
282
- return isset($original_row) ? $replacement : 'false';
283
- }
284
- } else {
285
- $this->addMessage('error',$row,$key,'Non-existent property %s',"<span class=\"code\">".$original."</span>");
286
- $replacement = 'null';
287
- }
288
- $output = $this->replace($original,$replacement,$output);
289
- }
290
- }
291
- } else {
292
- $code = array_key_exists('*code', $row) ? $row['*code'] : NULL; self::debug(' get <span class="osh-key">'.$code.'</span>.<span class="osh-key">'.$key.'</span> = <span class="osh-formula">null</span>',5);
293
- }
294
- return $output;
295
- }
296
-
297
- protected function _toString($value) {
298
- if (!isset($value)) return 'null';
299
- else if (is_bool($value)) return $value ? 'true' : 'false';
300
- else return $value;
301
- }
302
-
303
- protected function replace($from, $to, $input) {
304
- if ($from===$to) return $input;
305
- if (strpos($input,$from)===false) return $input;
306
- $to = $this->_toString($to);
307
- self::debug(' replace <span class="osh-replacement">'.$this->_toString($from).'</span> by <span class="osh-replacement">'.$to.'</span> =&gt; <span class="osh-formula">'.str_replace($from,'<span class="osh-replacement">'.$to.'</span>',$input).'</span>',5);
308
- return str_replace($from,$to,$input);
309
- }
310
-
311
- protected function _min() {
312
- $args = func_get_args();
313
- $min = null;
314
- foreach ($args as $arg) {
315
- if (isset($arg) && (!isset($min) || $min>$arg)) $min = $arg;
316
- }
317
- return $min;
318
- }
319
-
320
- protected function _max() {
321
- $args = func_get_args();
322
- $max = null;
323
- foreach ($args as $arg) {
324
- if (isset($arg) && (!isset($max) || $max<$arg)) $max = $arg;
325
- }
326
- return $max;
327
- }
328
-
329
- protected function _processFormula($process, &$row, $property_key, $formula_string, $is_checking, $use_cache=true)
330
- {
331
- $result = $this->_prepareFormula($process,$row,$property_key,$formula_string,$is_checking,$use_cache);
332
- if (!$result->success) return $result;
333
-
334
- $eval_result = $this->_evalFormula($result->result);
335
- if ($result->result == 'null') {
336
- $this->addMessage('over_weight',$row,$property_key, $this->_overWeightMessage);
337
- $result = new DPDFrancePredict_Os_Result(false);
338
- if ($use_cache) $this->setCache($formula_string,$result);
339
- return $result;
340
- }
341
- if (!isset($eval_result)) {
342
- $this->addMessage('error',$row,$property_key,'Invalid formula');
343
- $result = new DPDFrancePredict_Os_Result(false);
344
- if ($use_cache) $this->setCache($formula_string,$result);
345
- return $result;
346
- }
347
- self::debug(' formula evaluation = <span class="osh-formula">'.$this->_toString($eval_result).'</span>',10);
348
- $result = new DPDFrancePredict_Os_Result(true,$eval_result);
349
- if ($use_cache) $this->setCache($formula_string,$result);
350
- return $result;
351
- }
352
-
353
- public function evalInput($process, $row, $property_key, $input) {
354
- $result = $this->_prepareFormula($process,$row,$property_key,$input,$is_checking=false,$use_cache=true);
355
- return $result->success ? $result->result : $input;
356
- }
357
-
358
- protected function setCache($expression, $value) {
359
- if ($value instanceof DPDFrancePredict_Os_Result) {
360
- $this->_formula_cache[$expression] = $value;
361
- self::debug(' cache <span class="osh-replacement">'.$expression.'</span> = <span class="osh-formula">'.$this->_toString($this->_formula_cache[$expression]).'</span>',10);
362
- } else {
363
- $value = $this->_toString($value);
364
- $this->_expression_cache[$expression] = $value;
365
- self::debug(' cache <span class="osh-replacement">'.$expression.'</span> = <span class="osh-formula">'.$value.'</span>',10);
366
- }
367
- }
368
-
369
- protected function _prepareFormula($process, $row, $property_key, $formula_string, $is_checking, $use_cache=true)
370
- {
371
- if ($use_cache && isset($this->_formula_cache[$formula_string])) {
372
- $result = $this->_formula_cache[$formula_string];
373
- self::debug(' get cached formula <span class="osh-replacement">'.$formula_string.'</span> = <span class="osh-formula">'.$this->_toString($result->result).'</span>',10);
374
- return $result;
375
- }
376
-
377
- $formula = $formula_string;
378
- //self::debug(' formula = <span class="osh-formula">'.$formula.'</span>',10);
379
-
380
- while (preg_match("#{foreach product\.((?:attribute|option)\.(?:[a-z0-9_]+))}(.*){/foreach}#i",$formula,$result)) {
381
- $original = $result[0];
382
- if ($use_cache && isset($this->_expression_cache[$original])) {
383
- $replacement = $this->_expression_cache[$original];
384
- self::debug(' get cached expression <span class="osh-replacement">'.$original.'</span> = <span class="osh-formula">'.$replacement.'</span>',10);
385
- }
386
- else {
387
- $replacement = 0;
388
- list($filter_property_type,$filter_property_name) = explode('.',$result[1]);
389
- $selections = array();
390
- self::debug(' :: foreach <span class="osh-key">'.$filter_property_type.'</span>.<span class="osh-key">'.$filter_property_name.'</span>',10);
391
- foreach ($process['products'] as $product) {
392
- $tmp_value = $this->_getProductProperty($product,$filter_property_type,$filter_property_name,$get_by_id=false);
393
- self::debug(' products[<span class="osh-formula">'.$product->getName().'</span>].<span class="osh-key">'.$filter_property_type.'</span>.<span class="osh-key">'.$filter_property_name.'</span> = <span class="osh-formula">'.$this->_toString($tmp_value).'</span>',10);
394
- $key = 'val_'.$tmp_value;
395
- $sel = isset($selections[$key]) ? $selections[$key] : null;
396
- $selections[$key]['products'][] = $product;
397
- $selections[$key]['weight'] = (isset($sel['weight']) ? $sel['weight'] : 0)+$product->getAttribute('weight')*$product->getQuantity();
398
- $selections[$key]['quantity'] = (isset($sel['quantity']) ? $sel['quantity'] : 0)+$product->getQuantity();
399
- }
400
- self::debug(' :: start foreach',10);
401
- foreach ($selections as $selection) {
402
- $process2 = $process;
403
- $process2['products'] = $selection['products'];
404
- $process2['data']['selection.quantity'] = $selection['quantity'];
405
- $process2['data']['selection.weight'] = $selection['weight'];
406
- $process_result = $this->_processFormula($process2,$row,$property_key,$result[2],$is_checking,$tmp_use_cache=false);
407
- $replacement += $process_result->result;
408
- }
409
- self::debug(' :: end foreach <span class="osh-key">'.$filter_property_type.'</span>.<span class="osh-key">'.$filter_property_name.'</span>',10);
410
- if ($use_cache) $this->setCache($original,$replacement);
411
- }
412
- $formula = $this->replace($original,$replacement,$formula);
413
- }
414
-
415
- $formula = str_replace(array("\n","\t"),array('',''),$formula);
416
-
417
- while (preg_match("#{customvar\.([a-z0-9_]+)}#i",$formula,$result)) {
418
- $original = $result[0];
419
- $replacement = Mage::getModel('core/variable')->loadByCode($result[1])->getValue('plain');
420
- $formula = $this->replace($original,$replacement,$formula);
421
- }
422
-
423
- $first_product = isset($process['products'][0]) ? $process['products'][0] : null;
424
- if (!isset($process['data']['selection.weight'])) $process['data']['selection.weight'] = $process['data']['cart.weight'];
425
- if (!isset($process['data']['selection.quantity'])) $process['data']['selection.quantity'] = $process['data']['cart.quantity'];
426
- $process['data']['product.weight'] = isset($first_product) ? $first_product->getAttribute('weight') : 0;
427
- $process['data']['product.quantity'] = isset($first_product) ? $first_product->getQuantity() : 0;
428
-
429
- foreach ($process['data'] as $original => $replacement) {
430
- $formula = $this->replace('{'.$original.'}',$replacement,$formula);
431
- }
432
-
433
- if (isset($first_product)) {
434
- while (preg_match("#{product\.(attribute|option|stock)\.([a-z0-9_]+)}#i",$formula,$result)) {
435
- $original = $result[0];
436
- switch ($result[1]) {
437
- case 'attribute': $replacement = $first_product->getAttribute($result[2]); break;
438
- case 'option': $replacement = $first_product->getOption($result[2]); break;
439
- case 'stock': $replacement = $first_product->getStockData($result[2]); break;
440
- }
441
- $formula = $this->replace($original,$replacement,$formula);
442
- }
443
- }
444
-
445
- //while (preg_match("/{(count|all|any) (attribute|option) '([^'\)]+)' ?(==|<=|>=|<|>|!=) ?(".self::$FLOAT_REGEX."|true|false|'[^'\)]*')}/",$formula,$result)
446
- // || preg_match("/{(sum|count distinct) (attribute|option) '([^'\)]+)'}/",$formula,$result))
447
- while (preg_match("/{(count) products(?: where ([^}]+))?}/i",$formula,$result)
448
- || preg_match("/{(sum|count distinct) product\.(attribute|option)\.([a-z0-9_]+)(?: where ([^}]+))?}/i",$formula,$result)) {
449
- $original = $result[0];
450
- if ($use_cache && isset($this->_expression_cache[$original])) {
451
- $replacement = $this->_expression_cache[$original];
452
- self::debug(' get cached expression <span class="osh-replacement">'.$original.'</span> = <span class="osh-formula">'.$replacement.'</span>',10);
453
- }
454
- else {
455
- $replacement = $this->_processProductProperty($process['products'],$result);
456
- if ($use_cache) $this->setCache($result[0],$replacement);
457
- }
458
- $formula = $this->replace($original,$replacement,$formula);
459
- }
460
-
461
- //while (preg_match("/{table '([^']+)' ([^}]+)}/",$formula,$result))
462
- while (preg_match("/{table ([^}]+) in ([0-9\.:,\*\[\] ]+)}/i",$formula,$result)) {
463
- $original = $result[0];
464
- if ($use_cache && isset($this->_expression_cache[$original])) {
465
- $replacement = $this->_expression_cache[$original];
466
- self::debug(' get cached expression <span class="osh-replacement">'.$original.'</span> = <span class="osh-formula">'.$replacement.'</span>',10);
467
- } else {
468
- $reference_value = $this->_evalFormula($result[1]);
469
- if (isset($reference_value)) {
470
- $fees_table_string = $result[2];
471
-
472
- if (!preg_match('#^'.self::$COUPLE_REGEX.'(?:, *'.self::$COUPLE_REGEX.')*$#',$fees_table_string)) {
473
- $this->addMessage('error',$row,$property_key,'Error in table %s','<span class="osh-formula">'.htmlentities($result[0]).'</span>');
474
- $result = new DPDFrancePredict_Os_Result(false);
475
- if ($use_cache) $this->setCache($formula_string,$result);
476
- return $result;
477
- }
478
- $fees_table = explode(',',$fees_table_string);
479
-
480
- $replacement = null;
481
- foreach ($fees_table as $item) {
482
- $fee_data = explode(':',$item);
483
-
484
- $fee = trim($fee_data[1]);
485
- $max_value = trim($fee_data[0]);
486
-
487
- $last_char = $max_value{strlen($max_value)-1};
488
- if ($last_char=='[') $including_max_value = false;
489
- else if ($last_char==']') $including_max_value = true;
490
- else $including_max_value = true;
491
-
492
- $max_value = str_replace(array('[',']'),'',$max_value);
493
-
494
- if ($max_value=='*' || $including_max_value && $reference_value<=$max_value || !$including_max_value && $reference_value<$max_value) {
495
- $replacement = $fee;//$this->_calculateFee($process,$fee,$var);
496
- break;
497
- }
498
- }
499
- }
500
- $replacement = $this->_toString($replacement);
501
- if ($use_cache) $this->setCache($original,$replacement);
502
- }
503
- $formula = $this->replace($original,$replacement,$formula);
504
- }
505
- $result = new DPDFrancePredict_Os_Result(true,$formula);
506
- return $result;
507
- }
508
-
509
- protected function _evalFormula($formula) {
510
- if (is_bool($formula)) return $formula;
511
- if (!preg_match('/^(?:floor|ceil|round|max|min|rand|pow|pi|sqrt|log|exp|abs|int|float|true|false|null|and|or|in|substr|strtolower'
512
- .'|in_array\(\'(?:[^\']*)\', *array\( *(?:\'(?:[^\']+)\') *(?: *, *\'(?:[^\']+)\')* *\) *\)'
513
- .'|\'[^\']*\'|[0-9,\'\.\-\(\)\*\/\?\:\+\<\>\=\&\|%! ])*$/',$formula)) {
514
- self::debug(' doesn\'t match',10);
515
- return null;
516
- }
517
- $formula = str_replace(
518
- array('min','max'),
519
- array('$this->_min','$this->_max'),
520
- $formula
521
- );
522
- $eval_result = null;
523
- @eval('$eval_result = ('.$formula.');');
524
- return $eval_result;
525
- }
526
-
527
- protected function _getOptionsAndData($string) {
528
- if (preg_match('/^(\\s*\(\\s*([^\] ]*)\\s*\)\\s*)/',$string,$result)) {
529
- $options = $result[2];
530
- $data = str_replace($result[1],'',$string);
531
- } else {
532
- $options = '';
533
- $data = $string;
534
- }
535
- return array(
536
- 'options' => $options,
537
- 'data' => $data,
538
- );
539
- }
540
-
541
- public function compress($input) {
542
- if (preg_match_all("/{table (.*) in (".self::$COUPLE_REGEX."(?:, *".self::$COUPLE_REGEX.")*)}/imsU",$input,$result,PREG_SET_ORDER)) {
543
- foreach ($result as $result_i) {
544
- $fees_table = explode(',',$result_i[2]);
545
- $value = null;
546
- foreach ($fees_table as $index => $item) {
547
- list($max_value,$fee) = explode(':',$item);
548
- $last_char = $max_value{strlen($max_value)-1};
549
- if (in_array($last_char,array('[',']'))) {
550
- $including_char = $last_char;
551
- $max_value = str_replace(array('[',']'),'',$max_value);
552
- } else $including_char = '';
553
- $fees_table[$index] = ((float)$max_value).$including_char.':'.((float)$fee);
554
- }
555
- $input = str_replace($result_i[2],implode(',',$fees_table),$input);
556
- $input = str_replace($result_i[1],trim($result_i[1]),$input);
557
- }
558
- }
559
- if (preg_match_all("#{foreach ([^}]*)}(.*){/foreach}#imsU",$input,$result,PREG_SET_ORDER)) {
560
- foreach ($result as $result_i) {
561
- $input = str_replace($result_i[1],trim($result_i[1]),$input);
562
- $input = str_replace($result_i[2],trim($result_i[2]),$input);
563
- }
564
- }
565
- return '$$'.str_replace(
566
- self::$UNCOMPRESSED_STRINGS,
567
- self::$COMPRESSED_STRINGS,
568
- $input
569
- );
570
- }
571
-
572
- public function uncompress($input) {
573
- if (preg_match_all("/{table (.*) in (".self::$COUPLE_REGEX."(?:, *".self::$COUPLE_REGEX.")*)}/iU",$input,$result,PREG_SET_ORDER)) {
574
- foreach ($result as $result_i) {
575
- $fees_table = explode(',',$result_i[2]);
576
- $value = null;
577
- foreach ($fees_table as $index => $item) {
578
- list($max_value,$fee) = explode(':',$item);
579
- $last_char = $max_value{strlen($max_value)-1};
580
- if (in_array($last_char,array('[',']'))) {
581
- $including_char = $last_char;
582
- $max_value = str_replace(array('[',']'),'',$max_value);
583
- } else $including_char = '';
584
- $max_value = (float)$max_value;
585
- $fee = (float)$fee;
586
- $new_max_value = number_format($max_value,2,'.','');
587
- $new_fee = number_format($fee,2,'.','');
588
- $fees_table[$index] = (((float)$new_max_value)==$max_value ? $new_max_value : $max_value).$including_char.':'
589
- .(((float)$new_fee)==$fee ? $new_fee : $fee);
590
- }
591
- $input = str_replace($result_i[2],implode(', ',$fees_table),$input);
592
- $input = str_replace($result_i[1],trim($result_i[1]),$input);
593
- }
594
- }
595
- if (preg_match_all("#{foreach ([^}]*)}(.*){/foreach}#iU",$input,$result,PREG_SET_ORDER)) {
596
- foreach ($result as $result_i) {
597
- $input = str_replace($result_i[1],trim($result_i[1]),$input);
598
- $input = str_replace($result_i[2],trim($result_i[2]),$input);
599
- }
600
- }
601
- return str_replace(
602
- self::$COMPRESSED_STRINGS,
603
- self::$UNCOMPRESSED_STRINGS,
604
- $input
605
- );
606
- }
607
-
608
- public function parseProperty($input) {
609
- $value = $input==='false' || $input==='true' ? $input=='true' : str_replace('\"','"',preg_replace('/^(?:"|\')(.*)(?:"|\')$/s','$1',$input));
610
- return $value==='' ? null : $value;
611
- }
612
-
613
- public function cleanProperty(&$row, $key) {
614
- $input = $row[$key]['value'];
615
- if (is_string($input)) {
616
- $input = str_replace(array("\n"),array(''),$input);
617
- while (preg_match('/({TABLE |{SUM |{COUNT | DISTINCT | IN )/',$input,$resi)) {
618
- $input = str_replace($resi[0],strtolower($resi[0]),$input);
619
- }
620
-
621
- while (preg_match('/{{customVar code=([a-zA-Z0-9_-]+)}}/',$input,$resi)) {
622
- $input = str_replace($resi[0],'{customvar.'.$resi[1].'}',$input);
623
- }
624
-
625
- $regex = "{(weight|products_quantity|price_including_tax|price_excluding_tax|country)}";
626
- if (preg_match('/'.$regex.'/',$input,$resi)) {
627
- $this->addMessage('warning',$row,$key,'Usage of deprecated syntax %s','<span class="osh-formula">'.$resi[0].'</span>');
628
- while (preg_match('/'.$regex.'/',$input,$resi)) {
629
- switch ($resi[1]) {
630
- case 'price_including_tax':
631
- case 'price_excluding_tax':
632
- case 'weight':
633
- $input = str_replace($resi[0],"{cart.".$resi[1]."}",$input);
634
- break;
635
- case 'products_quantity': $input = str_replace($resi[0],"{cart.quantity}",$input); break;
636
- case 'country': $input = str_replace($resi[0],"{destination.country.name}",$input); break;
637
- }
638
- }
639
- }
640
-
641
- $regex1 = "{copy '([a-zA-Z0-9_]+)'\.'([a-zA-Z0-9_]+)'}";
642
- if (preg_match('/'.$regex1.'/',$input,$resi)) {
643
- $this->addMessage('warning',$row,$key,'Usage of deprecated syntax %s','<span class="osh-formula">'.$resi[0].'</span>');
644
- while (preg_match('/'.$regex1.'/',$input,$resi)) $input = str_replace($resi[0],'{'.$resi[1].'.'.$resi[2].'}',$input);
645
- }
646
-
647
- $regex1 = "{(count|all|any) (attribute|option) '([^'\)]+)' ?((?:==|<=|>=|<|>|!=) ?(?:".self::$FLOAT_REGEX."|true|false|'[^'\)]*'))}";
648
- $regex2 = "{(sum) (attribute|option) '([^'\)]+)'}";
649
- if (preg_match('/'.$regex1.'/',$input,$resi) || preg_match('/'.$regex2.'/',$input,$resi)) {
650
- $this->addMessage('warning',$row,$key,'Usage of deprecated syntax %s','<span class="osh-formula">'.$resi[0].'</span>');
651
- while (preg_match('/'.$regex1.'/',$input,$resi) || preg_match('/'.$regex2.'/',$input,$resi)) {
652
- switch ($resi[1]) {
653
- case 'count': $input = str_replace($resi[0],"{count products where product.".$resi[2]."s.".$resi[3].$resi[4]."}",$input); break;
654
- case 'all': $input = str_replace($resi[0],"{count products where product.".$resi[2]."s.".$resi[3].$resi[4]."}=={products_quantity}",$input); break;
655
- case 'any': $input = str_replace($resi[0],"{count products where product.".$resi[2]."s.".$resi[3].$resi[4]."}>0",$input); break;
656
- case 'sum': $input = str_replace($resi[0],"{sum product.".$resi[2].".".$resi[3]."}",$input); break;
657
- }
658
- }
659
- }
660
-
661
- $regex = "((?:{| )product.(?:attribute|option))s.";
662
- if (preg_match('/'.$regex.'/',$input,$resi)) {
663
- $this->addMessage('warning',$row,$key,'Usage of deprecated syntax %s','<span class="osh-formula">'.$resi[0].'</span>');
664
- while (preg_match('/'.$regex.'/',$input,$resi)) {
665
- $input = str_replace($resi[0],$resi[1].'.',$input);
666
- }
667
- }
668
-
669
- $regex = "{table '([^']+)' (".self::$COUPLE_REGEX."(?:, *".self::$COUPLE_REGEX.")*)}";
670
- if (preg_match('/'.$regex.'/',$input,$resi)) {
671
- $this->addMessage('warning',$row,$key,'Usage of deprecated syntax %s','<span class="osh-formula">'.$resi[0].'</span>');
672
- while (preg_match('/'.$regex.'/',$input,$resi)) {
673
- switch ($resi[1]) {
674
- case 'products_quantity':
675
- $input = str_replace($resi[0],"{table {cart.weight} in ".$resi[2]."}*{cart.quantity}",$input);
676
- break;
677
- default:
678
- $input = str_replace($resi[0],"{table {cart.".$resi[1]."} in ".$resi[2]."}",$input);
679
- break;
680
- }
681
- }
682
- }
683
- }
684
- $row[$key]['value'] = $input;
685
- }
686
-
687
- protected function _parseInput() {
688
- $config_string = str_replace(
689
- array('&gt;','&lt;','“','”',utf8_encode(chr(147)),utf8_encode(chr(148)),'&laquo;','&raquo;',"\r\n"),
690
- array('>','<','"','"','"','"','"','"',"\n"),
691
- $this->_input
692
- );
693
-
694
- if (substr($config_string,0,2)=='$$') $config_string = $this->uncompress(substr($config_string,2,strlen($config_string)));
695
-
696
- $row_regex = '[ \\t]*([a-z0-9_]+)\\s*:\\s*("(?:(?:[^"]|\\\\")*[^\\\\])?"|'.self::$FLOAT_REGEX.'|false|true)\\s*(,)?[ \\t]*(?:\\n)?';
697
- preg_match_all('/((?:#+[^{\\n]*\\s+)*)\\s*(#)?{\\s*('.$row_regex.')+\\s*}/i',$config_string,$result,PREG_SET_ORDER);
698
-
699
- $this->_config = array();
700
- $available_keys = array(
701
- 'code','label','enabled','description','fees','conditions','destination','origin','customer_groups','tracking_url',
702
- 'fees_table','fees_formula','fixed_fees','reference_value',
703
- 'prices_range','weights_range','product_properties',
704
- 'free_shipping__fees_table','free_shipping__fees_formula','free_shipping__fixed_fees','free_shipping__label',
705
- );
706
-
707
- foreach ($result as $block) {
708
- $deprecated_properties = array();
709
- $unknown_properties = array();
710
- $missing_semicolon = array();
711
- $obsolete_disabling_method = array();
712
-
713
- //$before = strstr($config_string,$block[0],true); // Seulement compatible avec PHP 5.3.0
714
- list($before) = explode($block[0],$config_string,2);
715
- if ($before!==false && trim($before)!='') {
716
- $config_string = substr($config_string,strlen($before));
717
- $this->_addIgnoredLines(trim($before));
718
- $this->addMessage('info',$row=null,null,'Ignored lines %s','<div class="code">'.trim($before).'</div>');
719
- }
720
-
721
- $config_string = str_replace($block[0], '', $config_string);
722
- preg_match_all('/'.$row_regex.'/i',$block[0],$result2,PREG_SET_ORDER);
723
- $block_string = $block[0];
724
-
725
- $row = array();
726
- $i = 1;
727
- foreach ($result2 as $data) {
728
- $key = $data[1];
729
- if (in_array($key,$available_keys) || substr($key,0,1)=='_') {
730
- $property = $this->parseProperty($data[2]);
731
- if (isset($property)) {
732
- $row[$key] = array('value' => $property, 'original_value' => $property);
733
- $this->cleanProperty($row,$key);
734
- }
735
- if ($i>2) {
736
- $block_string = str_replace($data[0],$i==3 ? "...\n" : '',$block_string);
737
- }
738
- if ($i!=count($result2) && !isset($data[3]) || isset($data[3]) && $data[3]!=',') {
739
- if (preg_match('/^("|\')(.{40})(.*)("|\')$/s',$data[2],$resultx))
740
- $missing_semicolon[] = trim(str_replace($data[2],$resultx[1].$resultx[2].' ...'.$resultx[4],$data[0]));
741
- else $missing_semicolon[] = trim($data[0]);
742
- }
743
- } else {
744
- if (!in_array($key,$unknown_properties)) $unknown_properties[] = $key;
745
- }
746
- $i++;
747
- }
748
- if ($block[1]!='') $row['*comment']['value'] = $block[1];
749
- if ($block[2]=='#' && !isset($row['enabled'])) {
750
- $row['enabled'] = array('value' => false);
751
- $obsolete_disabling_method[] = $block_string;
752
- }
753
-
754
- $formula_fields_to_check = array();
755
- if (isset($row['conditions'])) $formula_fields_to_check[] = 'conditions';
756
- if (isset($row['fees'])) $formula_fields_to_check[] = 'fees';
757
-
758
- if (count($formula_fields_to_check)>0) {
759
- foreach ($formula_fields_to_check as $property) {
760
- $property_value = $row[$property]['value'];
761
- if (preg_match('/{ +/',$property_value)) {
762
- $this->addMessage('warning',$row,$property,'There are unwanted spaces after char `%s`','{');
763
- $property_value = preg_replace('/{ +/','{',$property_value);
764
- }
765
- if (preg_match('/ +}/',$property_value)) {
766
- $this->addMessage('warning',$row,$property,'There are unwanted spaces before char `%s`','}');
767
- $property_value = preg_replace('/ +}/','}',$property_value);
768
- }
769
- if (preg_match('/ +/',$property_value)) {
770
- $this->addMessage('warning',$row,$property,'There are unwanted multiples spaces `%s`',preg_replace('/( +)/','<span class="osh-formula">*$1*</span>',$property_value));
771
- $property_value = preg_replace('/ +/',' ',$property_value);
772
- }
773
- $row[$property]['value'] = trim($property_value);
774
- }
775
- }
776
-
777
- $float_value_regex = '\\s*('.self::$POSITIVE_FLOAT_REGEX.'|\*)\\s*';
778
- $conditions = array();
779
- if (isset($row['prices_range'])) {
780
- if (!in_array('prices_range',$deprecated_properties)) $deprecated_properties[] = 'prices_range';
781
-
782
- $result = $this->_getOptionsAndData($row['prices_range']['value']);
783
- $options = $result['options'];
784
- $prices_range = $result['data'];
785
-
786
- if (($options=='' || in_array($options,array('incl.tax','ttc')))
787
- && preg_match('/^\\s*(\[|\])?'.$float_value_regex.'=>'.$float_value_regex.'(\[|\])?\\s*$/',$prices_range,$result)) {
788
- $min_price_included = $result[1]=='[';
789
- $min_price = $result[2]=='*' ? -1 : (float)$result[2];
790
- $max_price = $result[3]=='*' ? -1 : (float)$result[3];
791
- $max_price_included = !isset($result[4]) || $result[4]==']' || $result[4]=='';
792
-
793
- $tax_included = $options!='' && in_array($options,array('incl.tax','ttc')) || isset($row['reference_value']) && $row['reference_value']['value']=='price_including_tax';
794
- $price = $tax_included ? '{cart.price_including_tax}' : '{cart.price_excluding_tax}';
795
-
796
- if ($min_price!=-1) $conditions[] = $price.'>'.($min_price_included ? '=' : '').$min_price;
797
- if ($max_price!=-1) $conditions[] = $price.'<'.($max_price_included ? '=' : '').$max_price;
798
- }
799
- else $this->addMessage('error',$row,null,'Unrecognized value of deprecated property %s %s','<span class="osh-key">prices_range</span>','<span class="osh-formula">'.$row['prices_range']['value'].'</span>');
800
- unset($row['prices_range']);
801
- }
802
- if (isset($row['weights_range'])) {
803
- if (!in_array('weights_range',$deprecated_properties)) $deprecated_properties[] = 'weights_range';
804
- if (preg_match('/^\\s*(\[|\])?'.$float_value_regex.'=>'.$float_value_regex.'(\[|\])?\\s*$/',$row['weights_range']['value'],$result)) {
805
- $min_weight_included = $result[1]=='[';
806
- $min_weight = $result[2]=='*' ? -1 : (float)$result[2];
807
- $max_weight = $result[3]=='*' ? -1 : (float)$result[3];
808
- $max_weight_included = !isset($result[4]) || $result[4]==']' || $result[4]=='';
809
-
810
- if ($min_weight!=-1) $conditions[] = '{cart.weight}>'.($min_weight_included ? '=' : '').$min_weight;
811
- if ($max_weight!=-1) $conditions[] = '{cart.weight}<'.($max_weight_included ? '=' : '').$max_weight;
812
- }
813
- else $this->addMessage('error',$row,null,'Unrecognized value of deprecated property %s %s','<span class="osh-key">weights_range</span>','<span class="osh-formula">'.$row['weights_range']['value'].'</span>');
814
- unset($row['weights_range']);
815
- }
816
- if (isset($row['product_properties'])) {
817
- if (!in_array('product_properties',$deprecated_properties)) $deprecated_properties[] = 'product_properties';
818
- $product_property_regex = "\\s*(and|or)? *\((?:(all|any|sum) )?(attribute|option) '([^'\)]+)' ?(==|=|<=|>=|<|>|!=) ?(".self::$FLOAT_REGEX."|true|false|'[^'\)]*')\)\\s*";
819
- if (preg_match('/^('.$product_property_regex.')+$/',$row['product_properties']['value'],$result)) {
820
- preg_match_all('/'.$product_property_regex.'/',$row['product_properties']['value'],$results,PREG_SET_ORDER);
821
- $product_properties_condition = '';
822
- foreach ($results as $result) {
823
- $and_or = $result[1];
824
- if ($and_or=='') $and_or = 'and';
825
- $any_all_sum = $result[2];
826
- if ($any_all_sum=='') $any_all_sum = 'any';
827
- $property_type = $result[3];
828
- $property_name = $result[4];
829
- $cmp_symbol = $result[5];
830
- if ($cmp_symbol=='=') $cmp_symbol = '==';
831
- $cmp_value = $result[6];
832
-
833
- $product_properties_condition .= $product_properties_condition=='' ? '' : ' '.$and_or.' ';
834
- switch ($any_all_sum) {
835
- case 'sum':
836
- $product_properties_condition .= "{sum product.".$property_type.".".$property_name."}".$cmp_symbol.$cmp_value;
837
- break;
838
- case 'all':
839
- $product_properties_condition .= "{count products where product.".$property_type.".".$property_name.$cmp_symbol.$cmp_value."}=={products_quantity}";
840
- break;
841
- case 'any':
842
- $product_properties_condition .= "{count products where product.".$property_type.".".$property_name.$cmp_symbol.$cmp_value."}>0";
843
- break;
844
- }
845
- }
846
- if ($product_properties_condition!='') $conditions[] = $product_properties_condition;
847
- }
848
- else $this->addMessage('error',$row,null,'Unrecognized value of deprecated property %s %s','<span class="osh-key">product_properties</span>','<span class="osh-formula">'.$row['product_properties']['value'].'</span>');
849
- unset($row['product_properties']);
850
- }
851
- if (count($conditions)>0) $row['conditions'] = array('value' => count($conditions)==1 ? $conditions[0] : '('.implode(') && (',$conditions).')');
852
-
853
- $fees = array();
854
- if (isset($row['fees_table'])) {
855
- if (!in_array('fees_table',$deprecated_properties)) $deprecated_properties[] = 'fees_table';
856
- $options_and_data = $this->_getOptionsAndData($row['fees_table']['value']);
857
- $options = $options_and_data['options'];
858
- $fees_table_string = $options_and_data['data'];
859
-
860
- $var = null;
861
- if ($options=='') $var = (isset($row['reference_value']) ? $row['reference_value']['value'] : 'weight');
862
- else if (in_array($options,array('incl.tax','ttc'))) $var = 'price_including_tax';
863
- else if (in_array($options,array('excl.tax','ht'))) $var = 'price_excluding_tax';
864
-
865
- if (isset($var)) {
866
- if ($var=='price') $var = 'price_excluding_tax';
867
- if ($var=='products_quantity') $var = 'quantity';
868
- if (preg_match('/^[[:space:]]*\*[[:space:]]*:[[:space:]]*('.$float_value_regex.')[[:space:]]*$/s',$fees_table_string,$result)) $fees[] = $result[1];
869
- else $fees[] = "{table {cart.".$var."} in ".str_replace(' ','',$fees_table_string)."}".($var=='quantity' ? '*{cart.quantity}' : '');
870
- }
871
- else $this->addMessage('error',$row,null,'Unrecognized value of deprecated property %s %s','<span class="osh-key">fees_table</span>','<span class="osh-formula">'.$row['fees_table']['value'].'</span>');
872
- unset($row['fees_table']);
873
- }
874
- if (isset($row['fees_formula'])) {
875
- if (!in_array('fees_formula',$deprecated_properties)) $deprecated_properties[] = 'fees_formula';
876
- $fees[] = str_replace(' ','',$row['fees_formula']['value']);
877
- unset($row['fees_formula']);
878
- }
879
- if (isset($row['fixed_fees'])) {
880
- if (!in_array('fixed_fees',$deprecated_properties)) $deprecated_properties[] = 'fixed_fees';
881
- if ($row['fixed_fees']['value']!=0 || count($fees)==0) $fees[] = str_replace(' ','',$row['fixed_fees']['value']);
882
- unset($row['fixed_fees']);
883
- }
884
- if (!isset($row['fees']) && count($fees)>0) $row['fees'] = array('value' => implode('+',$fees));
885
-
886
- $fs_fees = array();
887
- if (isset($row['free_shipping__fees_table'])) {
888
- if (!in_array('free_shipping__fees_table',$deprecated_properties)) $deprecated_properties[] = 'free_shipping__fees_table';
889
- $options_and_data = $this->_getOptionsAndData($row['free_shipping__fees_table']['value']);
890
- $options = $options_and_data['options'];
891
- $fees_table_string = $options_and_data['data'];
892
-
893
- $var = null;
894
- if ($options=='') $var = isset($row['reference_value']) ? $row['reference_value']['value'] : 'weight';
895
- else if (in_array($options,array('incl.tax','ttc'))) $var = 'price_including_tax';
896
- else if (in_array($options,array('excl.tax','ht'))) $var = 'price_excluding_tax';
897
- if ($var=='price') $var = 'price_excluding_tax';
898
-
899
- if (isset($var)) {
900
- if ($var=='price') $var = 'price_excluding_tax';
901
- if ($var=='products_quantity') $var = 'quantity';
902
- if (preg_match('/^[[:space:]]*\*[[:space:]]*:[[:space:]]*('.$float_value_regex.')[[:space:]]*$/s',$fees_table_string,$result)) $fs_fees[] = $result[1];
903
- else $fs_fees[] = "{table {cart.".$var."} in ".str_replace(' ','',$fees_table_string)."}".($var=='quantity' ? '*{cart.quantity}' : '');
904
- }
905
- else $this->addMessage('error',$row,null,'Unrecognized value of deprecated property %s %s','<span class="osh-key">free_shipping__fees_table</span>','<span class="osh-formula">'.$row['free_shipping__fees_table']['value'].'</span>');
906
- unset($row['free_shipping__fees_table']);
907
- }
908
- if (isset($row['free_shipping__fees_formula'])) {
909
- if (!in_array('free_shipping__fees_formula',$deprecated_properties)) $deprecated_properties[] = 'free_shipping__fees_formula';
910
- $fs_fees[] = str_replace(' ','',$row['free_shipping__fees_formula']['value']);
911
- unset($row['free_shipping__fees_formula']);
912
- }
913
- if (isset($row['free_shipping__fixed_fees'])) {
914
- if (!in_array('free_shipping__fixed_fees',$deprecated_properties)) $deprecated_properties[] = 'free_shipping__fixed_fees';
915
- if ($row['free_shipping__fixed_fees']['value']!=0 || count($fees)==0) $fs_fees[] = str_replace(' ','',$row['free_shipping__fixed_fees']['value']);
916
- unset($row['free_shipping__fixed_fees']);
917
- }
918
-
919
- if (isset($row['reference_value'])) {
920
- if (!in_array('reference_value',$deprecated_properties)) $deprecated_properties[] = 'reference_value';
921
- unset($row['reference_value']);
922
- }
923
-
924
- if (count($fs_fees)>0) {
925
- $row2 = $row;
926
- if (isset($row['code'])) $row2['code']['value'] = $row['code']['value'].'__free_shipping';
927
- $row2['fees']['value'] = implode('+',$fs_fees);
928
- $row2['conditions']['value'] = isset($row2['conditions']) ? '('.$row2['conditions']+') and {free_shipping}' : '{free_shipping}';
929
- $row['conditions']['value'] = isset($row['conditions']) ? '('.$row['conditions']+') and !{free_shipping}' : '!{free_shipping}';
930
- if (isset($row['free_shipping__label'])) {
931
- if (!in_array('free_shipping__label',$deprecated_properties)) $deprecated_properties[] = 'free_shipping__label';
932
- $row2['label']['value'] = $row['free_shipping__label']['value'];
933
- unset($row['free_shipping__label']);
934
- unset($row2['free_shipping__label']);
935
- }
936
- $this->_addRow($row2);
937
- }
938
- if (count($unknown_properties)>0) $this->addMessage('error',$row,null,'Usage of unknown properties %s',': <span class="osh-key">'.implode('</span>, <span class="osh-key">',$unknown_properties).'</span>');
939
- if (count($deprecated_properties)>0) $this->addMessage('warning',$row,null,'Usage of deprecated properties %s',': <span class="osh-key">'.implode('</span>, <span class="osh-key">',$deprecated_properties).'</span>');
940
- if (count($obsolete_disabling_method)>0) $this->addMessage('warning',$row,null,'Usage of obsolete method to disabling a shipping method (`#` before `{`)%s','<div class="code">'.implode('<br />',$obsolete_disabling_method).'</div>');
941
- if (count($missing_semicolon)>0) $this->addMessage('warning',$row,null,'A semicolon is missing at the end of following lines %s','<div class="code">'.implode('<br />',$missing_semicolon).'</div>');
942
- $this->_addRow($row);
943
- }
944
- if (trim($config_string)!='') {
945
- $this->_addIgnoredLines(trim($config_string));
946
- $row=null;$this->addMessage('info',$row,null,'Ignored lines %s','<div class="code">'.trim($config_string).'</div>');
947
- }
948
- }
949
-
950
- public function addMessage($type, &$row, $property) {
951
- $args = func_get_args();
952
- array_shift($args);
953
- array_shift($args);
954
- array_shift($args);
955
- $message = new DPDFrancePredict_Os_Message($type,$args);
956
- if (isset($row)) {
957
- if (isset($property)) {
958
- $row[$property]['messages'][] = $message;
959
- } else {
960
- $row['*messages'][] = $message;
961
- }
962
- }
963
- $this->_messages[] = $message;
964
- self::debug(' => <span class="osh-'.$message->type.'">'.$message->toString().'</span>',1);
965
- }
966
-
967
- protected function _addRow(&$row) {
968
- if (isset($row['code'])) {
969
- $key = $row['code']['value'];
970
- if (isset($this->_config[$key])) $this->addMessage('error',$row,'code','The property `code` must be unique, `%s` has been found twice',$key);
971
- while (isset($this->_config[$key])) $key .= rand(0,9);
972
- //$row['code'] = $key;
973
- } else {
974
- $i = 1;
975
- do {
976
- $key = 'code_auto'.sprintf('%03d',$i);
977
- $i++;
978
- } while (isset($this->_config[$key]));
979
- }
980
- $row['*code'] = $key;
981
- $this->_config[$key] = $row;
982
- }
983
-
984
- protected function _addIgnoredLines($lines) {
985
- $this->_config[] = array('lines' => $lines);
986
- }
987
-
988
- protected function _addressMatch($address_filter, $address) {
989
- $excluding = false;
990
- if (preg_match('# *\* *- *\((.*)\) *#s',$address_filter,$result)) {
991
- $address_filter = $result[1];
992
- $excluding = true;
993
- }
994
-
995
- $tmp_address_filter_array = explode(',',trim($address_filter));
996
-
997
- $concat = false;
998
- $concatened = '';
999
- $address_filter_array = array();
1000
- $i = 0;
1001
-
1002
- foreach ($tmp_address_filter_array as $address_filter) {
1003
- if ($concat) $concatened .= ','.$address_filter;
1004
- else {
1005
- if ($i<count($tmp_address_filter_array)-1 && preg_match('#\(#',$address_filter)) {
1006
- $concat = true;
1007
- $concatened .= $address_filter;
1008
- } else $address_filter_array[] = $address_filter;
1009
- }
1010
- if (preg_match('#\)#',$address_filter)) {
1011
- $address_filter_array[] = $concatened;
1012
- $concatened = '';
1013
- $concat = false;
1014
- }
1015
- $i++;
1016
- }
1017
-
1018
- foreach ($address_filter_array as $address_filter) {
1019
- if (preg_match('# *([A-Z]{2}) *(-)? *(?:\( *(-)? *(.*)\))? *#s',$address_filter,$result)) {
1020
- $country_code = $result[1];
1021
- if ($address['country_code']==$country_code) {
1022
- self::debug(' country code <span class="osh-replacement">'.$address['country_code'].'</span> matches',5);
1023
- if (!isset($result[4]) || $result[4]=='') return !$excluding;
1024
- else {
1025
- $region_codes = explode(',',$result[4]);
1026
- $in_array = false;
1027
- for ($i=count($region_codes); --$i>=0;) {
1028
- $code = trim($region_codes[$i]);
1029
- $region_codes[$i] = $code;
1030
- if ($address['region_code']===$code) {
1031
- self::debug(' region code <span class="osh-replacement">'.$address['region_code'].'</span> matches',5);
1032
- $in_array = true;
1033
- } else if ($address['postcode']===$code) {
1034
- self::debug(' postcode <span class="osh-replacement">'.$address['postcode'].'</span> matches',5);
1035
- $in_array = true;
1036
- } else if (strpos($code,'*')!==false && preg_match('/^'.str_replace('*','(?:.*)',$code).'$/',$address['postcode'])) {
1037
- self::debug(' postcode <span class="osh-replacement">'.$address['postcode'].'</span> matches <span class="osh-formula">'.$code.'</span>',5);
1038
- $in_array = true;
1039
- }
1040
- if ($in_array) break;
1041
- }
1042
- if (!$in_array) {
1043
- self::debug(' region code <span class="osh-replacement">'.$address['region_code'].'</span> and postcode <span class="osh-replacement">'.$address['postcode'].'</span> don\'t match',5);
1044
- }
1045
- // Vérification stricte
1046
- // $in_array = in_array($address['region_code'],$region_codes,true) || in_array($address['postcode'],$region_codes,true);
1047
- $excluding_region = $result[2]=='-' || $result[3]=='-';
1048
- if ($excluding_region && !$in_array || !$excluding_region && $in_array) return !$excluding;
1049
- }
1050
- }
1051
- }
1052
- }
1053
- return $excluding;
1054
- }
1055
-
1056
- protected function _getProductProperty($product, $property_type, $property_name, $get_by_id=false) {
1057
- switch ($property_type) {
1058
- case 'attribute':
1059
- case 'attributes': return $product->getAttribute($property_name,$get_by_id);
1060
- case 'option':
1061
- case 'options': return $product->getOption($property_name,$get_by_id);
1062
- case 'stock': return $product->getStockData($property_name);
1063
- }
1064
- return null;
1065
- }
1066
-
1067
- protected function _processProductProperty($products, $regex_result) {
1068
- // COUNT, SUM or COUNT DISTINCT
1069
- $operation = strtolower($regex_result[1]);
1070
- switch ($operation) {
1071
- case 'sum':
1072
- case 'count distinct':
1073
- $property_type = $regex_result[2];
1074
- $property_name = $regex_result[3];
1075
- $conditions = isset($regex_result[4]) ? $regex_result[4] : null;
1076
- break;
1077
- case 'count':
1078
- $conditions = isset($regex_result[2]) ? $regex_result[2] : null;
1079
- break;
1080
- }
1081
-
1082
- self::debug(' :: start <span class="osh-replacement">'.$regex_result[0].'</span>',10);
1083
-
1084
- $return_value = 0;
1085
-
1086
- preg_match_all('/product\.(attribute(?:s)?|option(?:s)?|stock)\.([a-z0-9_]+)(?:\.(id))?/i',$conditions,$properties_regex_result,PREG_SET_ORDER);
1087
- $properties = array();
1088
- foreach ($properties_regex_result as $property_regex_result) {
1089
- $key = $property_regex_result[0];
1090
- if (!isset($properties[$key])) $properties[$key] = $property_regex_result;
1091
- }
1092
-
1093
- foreach ($products as $product) {
1094
- if (isset($conditions) && $conditions!='') {
1095
- $formula = $conditions;
1096
- foreach ($properties as $property) {
1097
- $value = $this->_getProductProperty(
1098
- $product,
1099
- $tmp_property_type = $property[1],
1100
- $tmp_property_name = $property[2],
1101
- $get_by_id = isset($property[3]) && $property[3]=='id'
1102
- );
1103
- //$formula = $this->replace($property[0],$value,$formula);
1104
- $from = $property[0];
1105
- $to = is_string($value) || empty($value) ? "'".$value."'" : $value;
1106
- $formula = str_replace($from,$to,$formula);
1107
- self::debug(' replace <span class="osh-replacement">'.$from.'</span> by <span class="osh-replacement">'.$to.'</span> =&gt; <span class="osh-formula">'.str_replace($from,'<span class="osh-replacement">'.$to.'</span>',$formula).'</span>',5);
1108
- }
1109
- $eval_result = $this->_evalFormula($formula);
1110
- if (!isset($eval_result)) return 'null';
1111
- }
1112
- else $eval_result = true;
1113
-
1114
- if ($eval_result==true) {
1115
- switch ($operation) {
1116
- case 'sum':
1117
- $value = $this->_getProductProperty($product,$property_type,$property_name);
1118
- //self::debug($product->getSku().'.'.$property_type.'.'.$property_name.' = "'.$value.'" x '.$product->getQuantity(),10);
1119
- $return_value += $value*$product->getQuantity();
1120
- break;
1121
- case 'count distinct':
1122
- if (!isset($distinct_values)) $distinct_values = array();
1123
- $value = $this->_getProductProperty($product,$property_type,$property_name);
1124
- if (!in_array($value,$distinct_values)) {
1125
- $distinct_values[] = $value;
1126
- $return_value++;
1127
- }
1128
- break;
1129
- case 'count':
1130
- $return_value += $product->getQuantity();
1131
- break;
1132
- }
1133
- }
1134
- }
1135
-
1136
- self::debug(' :: end <span class="osh-replacement">'.$regex_result[0].'</span>',10);
1137
-
1138
- return $return_value;
1139
- }
1140
-
1141
  }
1142
 
1143
  class DPDFrancePredict_Os_Message {
1144
- public $type;
1145
- public $message;
1146
- public $args;
1147
-
1148
- public function __construct($type, $args) {
1149
- $this->type = $type;
1150
- $this->message = array_shift($args);
1151
- $this->args = $args;
1152
- }
1153
-
1154
- public function toString() {
1155
- return vsprintf($this->message,$this->args);
1156
- }
1157
  }
1158
 
1159
  class DPDFrancePredict_Os_Result {
1160
- public $success;
1161
- public $result;
1162
 
1163
- public function __construct($success, $result=null) {
1164
- $this->success = $success;
1165
- $this->result = $result;
1166
- }
1167
 
1168
- public function __toString() {
1169
- return is_bool($this->result) ? ($this->result ? 'true' : 'false') : (string)$this->result;
1170
- }
1171
  }
1172
 
1173
 
1
  <?php
2
  /**
3
+ * DPD France v5.1.2 shipping module for Magento
4
  *
5
  * @category DPDFrance
6
  * @package DPDFrance_Shipping
7
+ * @author DPD France S.A.S. <ensavoirplus.ecommerce@dpd.fr>
8
+ * @copyright 2015 DPD France S.A.S., société par actions simplifiée, au capital de 18.500.000 euros, dont le siège social est situé 27 Rue du Colonel Pierre Avia - 75015 PARIS, immatriculée au registre du commerce et des sociétés de Paris sous le numéro 444 420 830
9
  * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
10
  */
11
 
12
  class DPDFrance_Predict_Model_Owebia
13
  {
14
+ public static $FLOAT_REGEX = '[-]?\d+(?:[.]\d+)?';
15
+ public static $POSITIVE_FLOAT_REGEX = '\d+(?:[.]\d+)?';
16
+ //public static $COUPLE_REGEX = '(?:[0-9.]+|\*)(?:\[|\])?\:[0-9.]+(?:\:[0-9.]+%?)*';
17
+ public static $COUPLE_REGEX = '(?:[0-9.]+|\*) *(?:\[|\])? *\: *[0-9.]+';
18
+ public static $UNCOMPRESSED_STRINGS = array(
19
+ ' product.attribute.',
20
+ ' product.option.',
21
+ ' product.stock.',
22
+ '{product.attribute.',
23
+ '{product.option.',
24
+ '{product.stock.',
25
+ '{product.weight}',
26
+ '{product.quantity}',
27
+ '{cart.weight}',
28
+ '{cart.quantity}',
29
  '{cart.coupon}',
30
+ '{cart.price_including_tax}',
31
+ '{cart.price_excluding_tax}',
32
+ '{cart.',
33
+ '{customvar.',
34
+ '{selection.weight}',
35
+ '{selection.quantity}',
36
+ '{selection.',
37
+ '{shipto.country.',
38
+ '{foreach ',
39
+ '{/foreach}',
40
+ );
41
+ public static $COMPRESSED_STRINGS = array(
42
+ ' p.a.',
43
+ ' p.o.',
44
+ ' p.s.',
45
+ '{p.a.',
46
+ '{p.o.',
47
+ '{p.s.',
48
+ '{p.w}',
49
+ '{p.qty}',
50
+ '{c.w}',
51
+ '{c.qty}',
52
  '{c.cpn}',
53
+ '{c.pit}',
54
+ '{c.pet}',
55
+ '{c.',
56
+ '{v.',
57
+ '{s.w}',
58
+ '{s.qty}',
59
+ '{s.',
60
+ '{dest.ctry.',
61
+ '{each ',
62
+ '{/each}',
63
+ );
64
+
65
+ protected $_input;
66
+ protected $_config;
67
+ protected $_messages;
68
+ protected $_formula_cache;
69
+ protected $_expression_cache;
70
+ protected $_overWeightMessage = 'Over weight';
71
+ public $debug = 0;
72
+ public $debug_output = '';
73
+ public $debug_header = null;
74
+
75
+ public function __construct($input) {
76
+ $this->_formula_cache = array();
77
+ $this->_messages = array();
78
+ $this->_input = $input;
79
+ $this->_config = array();
80
+ $this->_parseInput();
81
+ }
82
+
83
+ private function debug($text, $level=10) {
84
+ if ($this->debug>=$level) $this->debug_output .= "<p>".$text."</p>";
85
+ }
86
+
87
+ public function printDebug() {
88
+ if ($this->debug>0) echo "<style rel=\"stylesheet\" type=\"text/css\">"
89
+ .".osh-formula{color:#f90;} .osh-key{color:#0099f7;}"
90
+ .".osh-error{color:#f00;} .osh-warning{color:#ff0;} .osh-info{color:#7bf700;}"
91
+ .".osh-debug{background:#000;color:#bbb;position:absolute;top:0;left:0;width:100%;z-index:100;-moz-opacity:0.9;opacity:0.9;text-align:left;white-space:pre-wrap;}"
92
+ .".osh-debug-content{padding:10px;}"
93
+ .".osh-replacement{color:#ff3000;}"
94
+ ."</style>"
95
+ ."<div id=\"osh-debug\" class=\"osh-debug\"><pre class=\"osh-debug-content\"><span style=\"float:right;cursor:pointer;\" onclick=\"document.getElementById('osh-debug').style.display = 'none';\">[<span style=\"padding:0 5px;color:#f00;\">X</span>]</span>"
96
+ ."<p>".$this->debug_header."</p>".$this->debug_output."</pre></div>";
97
+ }
98
+
99
+ public function setDebugHeader($process) {
100
+ $header = 'DEBUG ' . __FILE__;//'DEBUG app/code/community/Owebia/Shipping/2/Model/Carrier/OwebiaShippingHelper.php<br/>';
101
+ foreach ($process['data'] as $key => $data) {
102
+ $header .= ' <span class="osh-key">'.$key.'</span> = <span class="osh-formula">'.$this->_toString($data).'</span><br/>';
103
+ }
104
+ $this->debug_header = $header;
105
+ }
106
+
107
+ public function getConfig() {
108
+ return $this->_config;
109
+ }
110
+
111
+ public function getMessages() {
112
+ $messages = $this->_messages;
113
+ $this->_messages = array();
114
+ return $messages;
115
+ }
116
+
117
+ public function formatConfig($compress) {
118
+ $output = '';
119
+ foreach ($this->_config as $code => $row) {
120
+ if (!isset($row['lines'])) {
121
+ if (isset($row['*comment']['value'])) {
122
+ $output .= trim($row['*comment']['value'])."\n";
123
+ }
124
+ $output .= '{'.($compress ? '' : "\n");
125
+ foreach ($row as $key => $property) {
126
+ if (substr($key,0,1)!='*') {
127
+ $value = $property['value'];
128
+ if (isset($property['comment'])) $output .= ($compress ? '' : "\t").'/* '.$property['comment'].' */'.($compress ? '' : "\n");
129
+ $output .= ($compress ? '' : "\t").$key.':'.($compress ? '' : ' ');
130
+ if (is_bool($value)) $output .= $value ? 'true' : 'false';
131
+ else if (is_int($value)) $output .= $value;
132
+ else if ((string)((float)$value)==$value) $output .= $value;
133
+ else $output .= '"'.str_replace('"','\\"',$value).'"';
134
+ $output .= ','.($compress ? '' : "\n");
135
+ }
136
+ }
137
+ if ($compress) $output = preg_replace('/,$/','',$output);
138
+ $output .= "}\n".($compress ? '' : "\n");
139
+ } else {
140
+ $output .= $row['lines']."\n";
141
+ }
142
+ }
143
+ return $compress ? $this->compress($output) : $this->uncompress($output);
144
+ }
145
+
146
+ public function checkConfig() {
147
+ $process = array(
148
+ 'result' => null,
149
+ 'data' => array(
150
+ 'cart.price_excluding_tax' => 0,
151
+ 'cart.price_including_tax' => 0,
152
+ 'cart.coupon' => '',
153
+ 'shipto.country.code' => '',
154
+ 'shipto.country.name' => '',
155
+ 'shipto.region.code' => '',
156
+ 'shipto.postal.code' => '',
157
+ 'origin.country.code' => '',
158
+ 'origin.country.name' => '',
159
+ 'origin.region.code' => '',
160
+ 'origin.postal.code' => '',
161
+ 'free_shipping' => false,
162
+ 'customer.group.id' => '',
163
+ 'customer.group.code' => '',
164
+ 'cart.weight' => 0,
165
+ 'cart.weight.unit' => 'kg',
166
+ 'cart.quantity' => 0,
167
+ ),
168
+ 'cart.items' => array(),
169
+ 'products' => array(),
170
+ 'config' => $this->_config,
171
+ );
172
+ foreach ($this->_config as $code => &$row) {
173
+ $this->processRow($process,$row,$check_all_conditions=true);
174
+ foreach ($row as $property_key => $property_value) {
175
+ if (substr($property_key,0,1)!='*') $this->getRowProperty($row,$property_key);
176
+ }
177
+ }
178
+ }
179
+
180
+ public function processRow($process, &$row, $is_checking=false) {
181
+ if (!isset($row['*code'])) return;
182
+
183
+ self::debug('process row <span class="osh-key">'.$row['*code'].'</span>',1);
184
+ if (!isset($row['label']['value'])) $row['label']['value'] = '';
185
+
186
+ $enabled = $this->getRowProperty($row,'enabled');
187
+ if (isset($enabled)) {
188
+ if (!$is_checking && !$enabled) {
189
+ $this->addMessage('info',$row,'enabled','Configuration disabled');
190
+ return new DPDFrancePredict_Os_Result(false);
191
+ }
192
+ }
193
+
194
+ $conditions = $this->getRowProperty($row,'conditions');
195
+ if (isset($conditions)) {
196
+ $result = $this->_processFormula($process,$row,'conditions',$conditions,$is_checking);
197
+ if (!$is_checking) {
198
+ if (!$result->success) return $result;
199
+ if (!$result->result) {
200
+ $this->addMessage('info',$row,'conditions',"The cart doesn't match conditions");
201
+ return new DPDFrancePredict_Os_Result(false);
202
+ }
203
+ }
204
+ }
205
+
206
+ $shipto = $this->getRowProperty($row,'shipto');
207
+ if (isset($shipto)) {
208
+ $shipto_match = $this->_addressMatch($shipto,array(
209
+ 'country_code' => $process['data']['shipto.country.code'],
210
+ 'region_code' => $process['data']['shipto.region.code'],
211
+ 'postcode' => $process['data']['shipto.postal.code']
212
+ ));
213
+ if (!$is_checking && !$shipto_match) {
214
+ $this->addMessage('info',$row,'shipto',"The shipping method doesn't cover the zone");
215
+ return new DPDFrancePredict_Os_Result(false);
216
+ }
217
+ }
218
+
219
+ $origin = $this->getRowProperty($row,'origin');
220
+ if (isset($origin)) {
221
+ $origin_match = $this->_addressMatch($origin,array(
222
+ 'country_code' => $process['data']['origin.country.code'],
223
+ 'region_code' => $process['data']['origin.region.code'],
224
+ 'postcode' => $process['data']['origin.postal.code']
225
+ ));
226
+ if (!$is_checking && !$origin_match) {
227
+ $this->addMessage('info',$row,'origin',"The shipping method doesn't match to shipping origin");
228
+ return new DPDFrancePredict_Os_Result(false);
229
+ }
230
+ }
231
+
232
+ $customer_groups = $this->getRowProperty($row,'customer_groups');
233
+ if (isset($customer_groups)) {
234
+ $groups = explode(',',$customer_groups);
235
+ $group_match = false;
236
+ //self::debug('code:'.$process['data']['customer.group.code'].', id:'.$process['data']['customer.group.id']);
237
+ foreach ($groups as $group) {
238
+ $group = trim($group);
239
+ if ($group==$process['data']['customer.group.code'] || is_int($group) && $group==$process['data']['customer.group.id'] || $group=='*') {
240
+ $group_match = true;
241
+ break;
242
+ }
243
+ }
244
+ if (!$is_checking && !$group_match) {
245
+ $this->addMessage('info',$row,'customer_groups',"The shipping method doesn't match to customer group (%s)",$process['data']['customer.group.code']);
246
+ return new DPDFrancePredict_Os_Result(false);
247
+ }
248
+ }
249
+
250
+ $fees = $this->getRowProperty($row,'fees');
251
+ if (isset($fees)) {
252
+ $result = $this->_processFormula($process,$row,'fees',$fees,$is_checking);
253
+ if (!$result->success) return $result;
254
+ self::debug(' => <span class="osh-info">result = <span class="osh-formula">'.$this->_toString($result->result).'</span>',1);
255
+ return new DPDFrancePredict_Os_Result(true,(float)$result->result);
256
+ }
257
+ return new DPDFrancePredict_Os_Result(false);
258
+ }
259
+
260
+ public function getRowProperty($row, $key, $original_row=null, $original_key=null) {
261
+ $property = null;
262
+ $output = null;
263
+ if (isset($original_row) && isset($original_key) && $original_row['*code']==$row['*code'] && $original_key==$key) {
264
+ $this->addMessage('error',$row,$key,'Infinite loop %s',"<span class=\"code\">{".$row['*code'].'.'.$key."}</span>");
265
+ return array('error' => 'Infinite loop');
266
+ }
267
+ if (isset($row[$key]['value'])) {
268
+ $property = $row[$key]['value'];
269
+ $output = $property;
270
+ $code = array_key_exists('*code', $row) ? $row['*code'] : NULL; self::debug(' get <span class="osh-key">'.$code.'</span>.<span class="osh-key">'.$key.'</span> = <span class="osh-formula">'.$this->_toString($property).'</span>',5);
271
+ preg_match_all('/{([a-z0-9_]+)\.([a-z0-9_]+)}/i',$output,$result_set,PREG_SET_ORDER);
272
+ foreach ($result_set as $result) {
273
+ list($original,$ref_code,$ref_key) = $result;
274
+ if (!in_array($ref_code,array('module','date','store','cart','product','selection','customvar'))) {
275
+ if ($ref_code==$row['code']['value'] && $ref_key==$key) {
276
+ $this->addMessage('error',$row,$key,'Infinite loop %s',"<span class=\"code\">".$original."</span>");
277
+ return null;
278
+ }
279
+ if (isset($this->_config[$ref_code][$ref_key]['value'])) {
280
+ $replacement = $this->getRowProperty($this->_config[$ref_code],$ref_key,
281
+ isset($original_row) ? $original_row : $row,isset($original_key) ? $original_key : $key);
282
+ if (is_array($replacement) && isset($replacement['error'])) {
283
+ return isset($original_row) ? $replacement : 'false';
284
+ }
285
+ } else {
286
+ $this->addMessage('error',$row,$key,'Non-existent property %s',"<span class=\"code\">".$original."</span>");
287
+ $replacement = 'null';
288
+ }
289
+ $output = $this->replace($original,$replacement,$output);
290
+ }
291
+ }
292
+ } else {
293
+ $code = array_key_exists('*code', $row) ? $row['*code'] : NULL; self::debug(' get <span class="osh-key">'.$code.'</span>.<span class="osh-key">'.$key.'</span> = <span class="osh-formula">null</span>',5);
294
+ }
295
+ return $output;
296
+ }
297
+
298
+ protected function _toString($value) {
299
+ if (!isset($value)) return 'null';
300
+ else if (is_bool($value)) return $value ? 'true' : 'false';
301
+ else return $value;
302
+ }
303
+
304
+ protected function replace($from, $to, $input) {
305
+ if ($from===$to) return $input;
306
+ if (strpos($input,$from)===false) return $input;
307
+ $to = $this->_toString($to);
308
+ self::debug(' replace <span class="osh-replacement">'.$this->_toString($from).'</span> by <span class="osh-replacement">'.$to.'</span> =&gt; <span class="osh-formula">'.str_replace($from,'<span class="osh-replacement">'.$to.'</span>',$input).'</span>',5);
309
+ return str_replace($from,$to,$input);
310
+ }
311
+
312
+ protected function _min() {
313
+ $args = func_get_args();
314
+ $min = null;
315
+ foreach ($args as $arg) {
316
+ if (isset($arg) && (!isset($min) || $min>$arg)) $min = $arg;
317
+ }
318
+ return $min;
319
+ }
320
+
321
+ protected function _max() {
322
+ $args = func_get_args();
323
+ $max = null;
324
+ foreach ($args as $arg) {
325
+ if (isset($arg) && (!isset($max) || $max<$arg)) $max = $arg;
326
+ }
327
+ return $max;
328
+ }
329
+
330
+ protected function _processFormula($process, &$row, $property_key, $formula_string, $is_checking, $use_cache=true)
331
+ {
332
+ $result = $this->_prepareFormula($process,$row,$property_key,$formula_string,$is_checking,$use_cache);
333
+ if (!$result->success) return $result;
334
+
335
+ $eval_result = $this->_evalFormula($result->result);
336
+ if ($result->result == 'null') {
337
+ $this->addMessage('over_weight',$row,$property_key, $this->_overWeightMessage);
338
+ $result = new DPDFrancePredict_Os_Result(false);
339
+ if ($use_cache) $this->setCache($formula_string,$result);
340
+ return $result;
341
+ }
342
+ if (!isset($eval_result)) {
343
+ $this->addMessage('error',$row,$property_key,'Invalid formula');
344
+ $result = new DPDFrancePredict_Os_Result(false);
345
+ if ($use_cache) $this->setCache($formula_string,$result);
346
+ return $result;
347
+ }
348
+ self::debug(' formula evaluation = <span class="osh-formula">'.$this->_toString($eval_result).'</span>',10);
349
+ $result = new DPDFrancePredict_Os_Result(true,$eval_result);
350
+ if ($use_cache) $this->setCache($formula_string,$result);
351
+ return $result;
352
+ }
353
+
354
+ public function evalInput($process, $row, $property_key, $input) {
355
+ $result = $this->_prepareFormula($process,$row,$property_key,$input,$is_checking=false,$use_cache=true);
356
+ return $result->success ? $result->result : $input;
357
+ }
358
+
359
+ protected function setCache($expression, $value) {
360
+ if ($value instanceof DPDFrancePredict_Os_Result) {
361
+ $this->_formula_cache[$expression] = $value;
362
+ self::debug(' cache <span class="osh-replacement">'.$expression.'</span> = <span class="osh-formula">'.$this->_toString($this->_formula_cache[$expression]).'</span>',10);
363
+ } else {
364
+ $value = $this->_toString($value);
365
+ $this->_expression_cache[$expression] = $value;
366
+ self::debug(' cache <span class="osh-replacement">'.$expression.'</span> = <span class="osh-formula">'.$value.'</span>',10);
367
+ }
368
+ }
369
+
370
+ protected function _prepareFormula($process, $row, $property_key, $formula_string, $is_checking, $use_cache=true)
371
+ {
372
+ if ($use_cache && isset($this->_formula_cache[$formula_string])) {
373
+ $result = $this->_formula_cache[$formula_string];
374
+ self::debug(' get cached formula <span class="osh-replacement">'.$formula_string.'</span> = <span class="osh-formula">'.$this->_toString($result->result).'</span>',10);
375
+ return $result;
376
+ }
377
+
378
+ $formula = $formula_string;
379
+ //self::debug(' formula = <span class="osh-formula">'.$formula.'</span>',10);
380
+
381
+ while (preg_match("#{foreach product\.((?:attribute|option)\.(?:[a-z0-9_]+))}(.*){/foreach}#i",$formula,$result)) {
382
+ $original = $result[0];
383
+ if ($use_cache && isset($this->_expression_cache[$original])) {
384
+ $replacement = $this->_expression_cache[$original];
385
+ self::debug(' get cached expression <span class="osh-replacement">'.$original.'</span> = <span class="osh-formula">'.$replacement.'</span>',10);
386
+ }
387
+ else {
388
+ $replacement = 0;
389
+ list($filter_property_type,$filter_property_name) = explode('.',$result[1]);
390
+ $selections = array();
391
+ self::debug(' :: foreach <span class="osh-key">'.$filter_property_type.'</span>.<span class="osh-key">'.$filter_property_name.'</span>',10);
392
+ foreach ($process['products'] as $product) {
393
+ $tmp_value = $this->_getProductProperty($product,$filter_property_type,$filter_property_name,$get_by_id=false);
394
+ self::debug(' products[<span class="osh-formula">'.$product->getName().'</span>].<span class="osh-key">'.$filter_property_type.'</span>.<span class="osh-key">'.$filter_property_name.'</span> = <span class="osh-formula">'.$this->_toString($tmp_value).'</span>',10);
395
+ $key = 'val_'.$tmp_value;
396
+ $sel = isset($selections[$key]) ? $selections[$key] : null;
397
+ $selections[$key]['products'][] = $product;
398
+ $selections[$key]['weight'] = (isset($sel['weight']) ? $sel['weight'] : 0)+$product->getAttribute('weight')*$product->getQuantity();
399
+ $selections[$key]['quantity'] = (isset($sel['quantity']) ? $sel['quantity'] : 0)+$product->getQuantity();
400
+ }
401
+ self::debug(' :: start foreach',10);
402
+ foreach ($selections as $selection) {
403
+ $process2 = $process;
404
+ $process2['products'] = $selection['products'];
405
+ $process2['data']['selection.quantity'] = $selection['quantity'];
406
+ $process2['data']['selection.weight'] = $selection['weight'];
407
+ $process_result = $this->_processFormula($process2,$row,$property_key,$result[2],$is_checking,$tmp_use_cache=false);
408
+ $replacement += $process_result->result;
409
+ }
410
+ self::debug(' :: end foreach <span class="osh-key">'.$filter_property_type.'</span>.<span class="osh-key">'.$filter_property_name.'</span>',10);
411
+ if ($use_cache) $this->setCache($original,$replacement);
412
+ }
413
+ $formula = $this->replace($original,$replacement,$formula);
414
+ }
415
+
416
+ $formula = str_replace(array("\n","\t"),array('',''),$formula);
417
+
418
+ while (preg_match("#{customvar\.([a-z0-9_]+)}#i",$formula,$result)) {
419
+ $original = $result[0];
420
+ $replacement = Mage::getModel('core/variable')->loadByCode($result[1])->getValue('plain');
421
+ $formula = $this->replace($original,$replacement,$formula);
422
+ }
423
+
424
+ $first_product = isset($process['products'][0]) ? $process['products'][0] : null;
425
+ if (!isset($process['data']['selection.weight'])) $process['data']['selection.weight'] = $process['data']['cart.weight'];
426
+ if (!isset($process['data']['selection.quantity'])) $process['data']['selection.quantity'] = $process['data']['cart.quantity'];
427
+ $process['data']['product.weight'] = isset($first_product) ? $first_product->getAttribute('weight') : 0;
428
+ $process['data']['product.quantity'] = isset($first_product) ? $first_product->getQuantity() : 0;
429
+
430
+ foreach ($process['data'] as $original => $replacement) {
431
+ $formula = $this->replace('{'.$original.'}',$replacement,$formula);
432
+ }
433
+
434
+ if (isset($first_product)) {
435
+ while (preg_match("#{product\.(attribute|option|stock)\.([a-z0-9_]+)}#i",$formula,$result)) {
436
+ $original = $result[0];
437
+ switch ($result[1]) {
438
+ case 'attribute': $replacement = $first_product->getAttribute($result[2]); break;
439
+ case 'option': $replacement = $first_product->getOption($result[2]); break;
440
+ case 'stock': $replacement = $first_product->getStockData($result[2]); break;
441
+ }
442
+ $formula = $this->replace($original,$replacement,$formula);
443
+ }
444
+ }
445
+
446
+ //while (preg_match("/{(count|all|any) (attribute|option) '([^'\)]+)' ?(==|<=|>=|<|>|!=) ?(".self::$FLOAT_REGEX."|true|false|'[^'\)]*')}/",$formula,$result)
447
+ // || preg_match("/{(sum|count distinct) (attribute|option) '([^'\)]+)'}/",$formula,$result))
448
+ while (preg_match("/{(count) products(?: where ([^}]+))?}/i",$formula,$result)
449
+ || preg_match("/{(sum|count distinct) product\.(attribute|option)\.([a-z0-9_]+)(?: where ([^}]+))?}/i",$formula,$result)) {
450
+ $original = $result[0];
451
+ if ($use_cache && isset($this->_expression_cache[$original])) {
452
+ $replacement = $this->_expression_cache[$original];
453
+ self::debug(' get cached expression <span class="osh-replacement">'.$original.'</span> = <span class="osh-formula">'.$replacement.'</span>',10);
454
+ }
455
+ else {
456
+ $replacement = $this->_processProductProperty($process['products'],$result);
457
+ if ($use_cache) $this->setCache($result[0],$replacement);
458
+ }
459
+ $formula = $this->replace($original,$replacement,$formula);
460
+ }
461
+
462
+ //while (preg_match("/{table '([^']+)' ([^}]+)}/",$formula,$result))
463
+ while (preg_match("/{table ([^}]+) in ([0-9\.:,\*\[\] ]+)}/i",$formula,$result)) {
464
+ $original = $result[0];
465
+ if ($use_cache && isset($this->_expression_cache[$original])) {
466
+ $replacement = $this->_expression_cache[$original];
467
+ self::debug(' get cached expression <span class="osh-replacement">'.$original.'</span> = <span class="osh-formula">'.$replacement.'</span>',10);
468
+ } else {
469
+ $reference_value = $this->_evalFormula($result[1]);
470
+ if (isset($reference_value)) {
471
+ $fees_table_string = $result[2];
472
+
473
+ if (!preg_match('#^'.self::$COUPLE_REGEX.'(?:, *'.self::$COUPLE_REGEX.')*$#',$fees_table_string)) {
474
+ $this->addMessage('error',$row,$property_key,'Error in table %s','<span class="osh-formula">'.htmlentities($result[0]).'</span>');
475
+ $result = new DPDFrancePredict_Os_Result(false);
476
+ if ($use_cache) $this->setCache($formula_string,$result);
477
+ return $result;
478
+ }
479
+ $fees_table = explode(',',$fees_table_string);
480
+
481
+ $replacement = null;
482
+ foreach ($fees_table as $item) {
483
+ $fee_data = explode(':',$item);
484
+
485
+ $fee = trim($fee_data[1]);
486
+ $max_value = trim($fee_data[0]);
487
+
488
+ $last_char = $max_value{strlen($max_value)-1};
489
+ if ($last_char=='[') $including_max_value = false;
490
+ else if ($last_char==']') $including_max_value = true;
491
+ else $including_max_value = true;
492
+
493
+ $max_value = str_replace(array('[',']'),'',$max_value);
494
+
495
+ if ($max_value=='*' || $including_max_value && $reference_value<=$max_value || !$including_max_value && $reference_value<$max_value) {
496
+ $replacement = $fee;//$this->_calculateFee($process,$fee,$var);
497
+ break;
498
+ }
499
+ }
500
+ }
501
+ $replacement = $this->_toString($replacement);
502
+ if ($use_cache) $this->setCache($original,$replacement);
503
+ }
504
+ $formula = $this->replace($original,$replacement,$formula);
505
+ }
506
+ $result = new DPDFrancePredict_Os_Result(true,$formula);
507
+ return $result;
508
+ }
509
+
510
+ protected function _evalFormula($formula) {
511
+ if (is_bool($formula)) return $formula;
512
+ if (!preg_match('/^(?:floor|ceil|round|max|min|rand|pow|pi|sqrt|log|exp|abs|int|float|true|false|null|and|or|in|substr|strtolower'
513
+ .'|in_array\(\'(?:[^\']*)\', *array\( *(?:\'(?:[^\']+)\') *(?: *, *\'(?:[^\']+)\')* *\) *\)'
514
+ .'|\'[^\']*\'|[0-9,\'\.\-\(\)\*\/\?\:\+\<\>\=\&\|%! ])*$/',$formula)) {
515
+ self::debug(' doesn\'t match',10);
516
+ return null;
517
+ }
518
+ $formula = str_replace(
519
+ array('min','max'),
520
+ array('$this->_min','$this->_max'),
521
+ $formula
522
+ );
523
+ $eval_result = null;
524
+ @eval('$eval_result = ('.$formula.');');
525
+ return $eval_result;
526
+ }
527
+
528
+ protected function _getOptionsAndData($string) {
529
+ if (preg_match('/^(\\s*\(\\s*([^\] ]*)\\s*\)\\s*)/',$string,$result)) {
530
+ $options = $result[2];
531
+ $data = str_replace($result[1],'',$string);
532
+ } else {
533
+ $options = '';
534
+ $data = $string;
535
+ }
536
+ return array(
537
+ 'options' => $options,
538
+ 'data' => $data,
539
+ );
540
+ }
541
+
542
+ public function compress($input) {
543
+ if (preg_match_all("/{table (.*) in (".self::$COUPLE_REGEX."(?:, *".self::$COUPLE_REGEX.")*)}/imsU",$input,$result,PREG_SET_ORDER)) {
544
+ foreach ($result as $result_i) {
545
+ $fees_table = explode(',',$result_i[2]);
546
+ $value = null;
547
+ foreach ($fees_table as $index => $item) {
548
+ list($max_value,$fee) = explode(':',$item);
549
+ $last_char = $max_value{strlen($max_value)-1};
550
+ if (in_array($last_char,array('[',']'))) {
551
+ $including_char = $last_char;
552
+ $max_value = str_replace(array('[',']'),'',$max_value);
553
+ } else $including_char = '';
554
+ $fees_table[$index] = ((float)$max_value).$including_char.':'.((float)$fee);
555
+ }
556
+ $input = str_replace($result_i[2],implode(',',$fees_table),$input);
557
+ $input = str_replace($result_i[1],trim($result_i[1]),$input);
558
+ }
559
+ }
560
+ if (preg_match_all("#{foreach ([^}]*)}(.*){/foreach}#imsU",$input,$result,PREG_SET_ORDER)) {
561
+ foreach ($result as $result_i) {
562
+ $input = str_replace($result_i[1],trim($result_i[1]),$input);
563
+ $input = str_replace($result_i[2],trim($result_i[2]),$input);
564
+ }
565
+ }
566
+ return '$$'.str_replace(
567
+ self::$UNCOMPRESSED_STRINGS,
568
+ self::$COMPRESSED_STRINGS,
569
+ $input
570
+ );
571
+ }
572
+
573
+ public function uncompress($input) {
574
+ if (preg_match_all("/{table (.*) in (".self::$COUPLE_REGEX."(?:, *".self::$COUPLE_REGEX.")*)}/iU",$input,$result,PREG_SET_ORDER)) {
575
+ foreach ($result as $result_i) {
576
+ $fees_table = explode(',',$result_i[2]);
577
+ $value = null;
578
+ foreach ($fees_table as $index => $item) {
579
+ list($max_value,$fee) = explode(':',$item);
580
+ $last_char = $max_value{strlen($max_value)-1};
581
+ if (in_array($last_char,array('[',']'))) {
582
+ $including_char = $last_char;
583
+ $max_value = str_replace(array('[',']'),'',$max_value);
584
+ } else $including_char = '';
585
+ $max_value = (float)$max_value;
586
+ $fee = (float)$fee;
587
+ $new_max_value = number_format($max_value,2,'.','');
588
+ $new_fee = number_format($fee,2,'.','');
589
+ $fees_table[$index] = (((float)$new_max_value)==$max_value ? $new_max_value : $max_value).$including_char.':'
590
+ .(((float)$new_fee)==$fee ? $new_fee : $fee);
591
+ }
592
+ $input = str_replace($result_i[2],implode(', ',$fees_table),$input);
593
+ $input = str_replace($result_i[1],trim($result_i[1]),$input);
594
+ }
595
+ }
596
+ if (preg_match_all("#{foreach ([^}]*)}(.*){/foreach}#iU",$input,$result,PREG_SET_ORDER)) {
597
+ foreach ($result as $result_i) {
598
+ $input = str_replace($result_i[1],trim($result_i[1]),$input);
599
+ $input = str_replace($result_i[2],trim($result_i[2]),$input);
600
+ }
601
+ }
602
+ return str_replace(
603
+ self::$COMPRESSED_STRINGS,
604
+ self::$UNCOMPRESSED_STRINGS,
605
+ $input
606
+ );
607
+ }
608
+
609
+ public function parseProperty($input) {
610
+ $value = $input==='false' || $input==='true' ? $input=='true' : str_replace('\"','"',preg_replace('/^(?:"|\')(.*)(?:"|\')$/s','$1',$input));
611
+ return $value==='' ? null : $value;
612
+ }
613
+
614
+ public function cleanProperty(&$row, $key) {
615
+ $input = $row[$key]['value'];
616
+ if (is_string($input)) {
617
+ $input = str_replace(array("\n"),array(''),$input);
618
+ while (preg_match('/({TABLE |{SUM |{COUNT | DISTINCT | IN )/',$input,$resi)) {
619
+ $input = str_replace($resi[0],strtolower($resi[0]),$input);
620
+ }
621
+
622
+ while (preg_match('/{{customVar code=([a-zA-Z0-9_-]+)}}/',$input,$resi)) {
623
+ $input = str_replace($resi[0],'{customvar.'.$resi[1].'}',$input);
624
+ }
625
+
626
+ $regex = "{(weight|products_quantity|price_including_tax|price_excluding_tax|country)}";
627
+ if (preg_match('/'.$regex.'/',$input,$resi)) {
628
+ $this->addMessage('warning',$row,$key,'Usage of deprecated syntax %s','<span class="osh-formula">'.$resi[0].'</span>');
629
+ while (preg_match('/'.$regex.'/',$input,$resi)) {
630
+ switch ($resi[1]) {
631
+ case 'price_including_tax':
632
+ case 'price_excluding_tax':
633
+ case 'weight':
634
+ $input = str_replace($resi[0],"{cart.".$resi[1]."}",$input);
635
+ break;
636
+ case 'products_quantity': $input = str_replace($resi[0],"{cart.quantity}",$input); break;
637
+ case 'country': $input = str_replace($resi[0],"{shipto.country.name}",$input); break;
638
+ }
639
+ }
640
+ }
641
+
642
+ $regex1 = "{copy '([a-zA-Z0-9_]+)'\.'([a-zA-Z0-9_]+)'}";
643
+ if (preg_match('/'.$regex1.'/',$input,$resi)) {
644
+ $this->addMessage('warning',$row,$key,'Usage of deprecated syntax %s','<span class="osh-formula">'.$resi[0].'</span>');
645
+ while (preg_match('/'.$regex1.'/',$input,$resi)) $input = str_replace($resi[0],'{'.$resi[1].'.'.$resi[2].'}',$input);
646
+ }
647
+
648
+ $regex1 = "{(count|all|any) (attribute|option) '([^'\)]+)' ?((?:==|<=|>=|<|>|!=) ?(?:".self::$FLOAT_REGEX."|true|false|'[^'\)]*'))}";
649
+ $regex2 = "{(sum) (attribute|option) '([^'\)]+)'}";
650
+ if (preg_match('/'.$regex1.'/',$input,$resi) || preg_match('/'.$regex2.'/',$input,$resi)) {
651
+ $this->addMessage('warning',$row,$key,'Usage of deprecated syntax %s','<span class="osh-formula">'.$resi[0].'</span>');
652
+ while (preg_match('/'.$regex1.'/',$input,$resi) || preg_match('/'.$regex2.'/',$input,$resi)) {
653
+ switch ($resi[1]) {
654
+ case 'count': $input = str_replace($resi[0],"{count products where product.".$resi[2]."s.".$resi[3].$resi[4]."}",$input); break;
655
+ case 'all': $input = str_replace($resi[0],"{count products where product.".$resi[2]."s.".$resi[3].$resi[4]."}=={products_quantity}",$input); break;
656
+ case 'any': $input = str_replace($resi[0],"{count products where product.".$resi[2]."s.".$resi[3].$resi[4]."}>0",$input); break;
657
+ case 'sum': $input = str_replace($resi[0],"{sum product.".$resi[2].".".$resi[3]."}",$input); break;
658
+ }
659
+ }
660
+ }
661
+
662
+ $regex = "((?:{| )product.(?:attribute|option))s.";
663
+ if (preg_match('/'.$regex.'/',$input,$resi)) {
664
+ $this->addMessage('warning',$row,$key,'Usage of deprecated syntax %s','<span class="osh-formula">'.$resi[0].'</span>');
665
+ while (preg_match('/'.$regex.'/',$input,$resi)) {
666
+ $input = str_replace($resi[0],$resi[1].'.',$input);
667
+ }
668
+ }
669
+
670
+ $regex = "{table '([^']+)' (".self::$COUPLE_REGEX."(?:, *".self::$COUPLE_REGEX.")*)}";
671
+ if (preg_match('/'.$regex.'/',$input,$resi)) {
672
+ $this->addMessage('warning',$row,$key,'Usage of deprecated syntax %s','<span class="osh-formula">'.$resi[0].'</span>');
673
+ while (preg_match('/'.$regex.'/',$input,$resi)) {
674
+ switch ($resi[1]) {
675
+ case 'products_quantity':
676
+ $input = str_replace($resi[0],"{table {cart.weight} in ".$resi[2]."}*{cart.quantity}",$input);
677
+ break;
678
+ default:
679
+ $input = str_replace($resi[0],"{table {cart.".$resi[1]."} in ".$resi[2]."}",$input);
680
+ break;
681
+ }
682
+ }
683
+ }
684
+ }
685
+ $row[$key]['value'] = $input;
686
+ }
687
+
688
+ protected static function json_decode($input)
689
+ {
690
+ if (function_exists('json_decode')) { // PHP >= 5.2.0
691
+ $output = json_decode($input);
692
+ if (function_exists('json_last_error')) { // PHP >= 5.3.0
693
+ $error = json_last_error();
694
+ if ($error!=JSON_ERROR_NONE) throw new Exception($error);
695
+ }
696
+ return $output;
697
+ } else {
698
+ return Zend_Json::decode($input);
699
+ }
700
+ }
701
+
702
+ protected function _parseInput() {
703
+ $config_string = str_replace(
704
+ array('&gt;','&lt;','','',utf8_encode(chr(147)),utf8_encode(chr(148)),'&laquo;','&raquo;',"\r\n"),
705
+ array('>','<','"','"','"','"','"','"',"\n"),
706
+ $this->_input
707
+ );
708
+
709
+ if (substr($config_string,0,2)=='$$') $config_string = $this->uncompress(substr($config_string,2,strlen($config_string)));
710
+
711
+ $config = self::json_decode($config_string);
712
+ $config = (array)$config;
713
+
714
+ $this->_config = array();
715
+ $available_keys = array('type', 'label', 'enabled', 'fees', 'conditions', 'shipto', 'origin', 'customer_groups');
716
+ $reserved_keys = array('*code');
717
+
718
+ $deprecated_properties = array();
719
+ $unknown_properties = array();
720
+
721
+ foreach ($config as $code => $object) {
722
+ $object = (array)$object;
723
+ $row = array();
724
+ $i = 1;
725
+ foreach ($object as $property_name => $property_value)
726
+ {
727
+ if (in_array($property_name, $reserved_keys))
728
+ continue;
729
+ if (in_array($property_name, $available_keys)
730
+ || substr($property_name, 0, 1)=='_'
731
+ || in_array($object['type'], array('data', 'meta')))
732
+ {
733
+ if (isset($property_value))
734
+ $row[$property_name] = array('value' => $property_value, 'original_value' => $property_value);
735
+ }
736
+ else
737
+ if (!in_array($property_name, $unknown_properties)) $unknown_properties[] = $property_name;
738
+ $i++;
739
+ }
740
+ $this->_addRow($row);
741
+ }
742
+ $row = null;
743
+ if (count($unknown_properties)>0)
744
+ $this->addMessage('error', $row, null, 'Usage of unknown properties %s', ': <span class=osh-key>'.implode('</span>, <span class=osh-key>', $unknown_properties).'</span>');
745
+ if (count($deprecated_properties)>0)
746
+ $this->addMessage('warning', $row, null, 'Usage of deprecated properties %s', ': <span class=osh-key>'.implode('</span>, <span class=osh-key>', $deprecated_properties).'</span>');
747
+ }
748
+
749
+ public function addMessage($type, &$row, $property) {
750
+ $args = func_get_args();
751
+ array_shift($args);
752
+ array_shift($args);
753
+ array_shift($args);
754
+ $message = new DPDFrancePredict_Os_Message($type,$args);
755
+ if (isset($row)) {
756
+ if (isset($property)) {
757
+ $row[$property]['messages'][] = $message;
758
+ } else {
759
+ $row['*messages'][] = $message;
760
+ }
761
+ }
762
+ $this->_messages[] = $message;
763
+ self::debug(' => <span class="osh-'.$message->type.'">'.$message->toString().'</span>',1);
764
+ }
765
+
766
+ protected function _addRow(&$row) {
767
+ if (isset($row['code'])) {
768
+ $key = $row['code']['value'];
769
+ if (isset($this->_config[$key])) $this->addMessage('error',$row,'code','The property `code` must be unique, `%s` has been found twice',$key);
770
+ while (isset($this->_config[$key])) $key .= rand(0,9);
771
+ //$row['code'] = $key;
772
+ } else {
773
+ $i = 1;
774
+ do {
775
+ $key = 'code_auto'.sprintf('%03d',$i);
776
+ $i++;
777
+ } while (isset($this->_config[$key]));
778
+ }
779
+ $row['*code'] = $key;
780
+ $this->_config[$key] = $row;
781
+ }
782
+
783
+ protected function _addIgnoredLines($lines) {
784
+ $this->_config[] = array('lines' => $lines);
785
+ }
786
+
787
+ protected function _addressMatch($address_filter, $address) {
788
+ $excluding = false;
789
+ if (preg_match('# *\* *- *\((.*)\) *#s',$address_filter,$result)) {
790
+ $address_filter = $result[1];
791
+ $excluding = true;
792
+ }
793
+
794
+ $tmp_address_filter_array = explode(',',trim($address_filter));
795
+
796
+ $concat = false;
797
+ $concatened = '';
798
+ $address_filter_array = array();
799
+ $i = 0;
800
+
801
+ foreach ($tmp_address_filter_array as $address_filter) {
802
+ if ($concat) $concatened .= ','.$address_filter;
803
+ else {
804
+ if ($i<count($tmp_address_filter_array)-1 && preg_match('#\(#',$address_filter)) {
805
+ $concat = true;
806
+ $concatened .= $address_filter;
807
+ } else $address_filter_array[] = $address_filter;
808
+ }
809
+ if (preg_match('#\)#',$address_filter)) {
810
+ $address_filter_array[] = $concatened;
811
+ $concatened = '';
812
+ $concat = false;
813
+ }
814
+ $i++;
815
+ }
816
+
817
+ foreach ($address_filter_array as $address_filter) {
818
+ if (preg_match('# *([A-Z]{2}) *(-)? *(?:\( *(-)? *(.*)\))? *#s',$address_filter,$result)) {
819
+ $country_code = $result[1];
820
+ if ($address['country_code']==$country_code) {
821
+ self::debug(' country code <span class="osh-replacement">'.$address['country_code'].'</span> matches',5);
822
+ if (!isset($result[4]) || $result[4]=='') return !$excluding;
823
+ else {
824
+ $region_codes = explode(',',$result[4]);
825
+ $in_array = false;
826
+ for ($i=count($region_codes); --$i>=0;) {
827
+ $code = trim($region_codes[$i]);
828
+ $region_codes[$i] = $code;
829
+ if ($address['region_code']===$code) {
830
+ self::debug(' region code <span class="osh-replacement">'.$address['region_code'].'</span> matches',5);
831
+ $in_array = true;
832
+ } else if ($address['postcode']===$code) {
833
+ self::debug(' postcode <span class="osh-replacement">'.$address['postcode'].'</span> matches',5);
834
+ $in_array = true;
835
+ } else if (strpos($code,'*')!==false && preg_match('/^'.str_replace('*','(?:.*)',$code).'$/',$address['postcode'])) {
836
+ self::debug(' postcode <span class="osh-replacement">'.$address['postcode'].'</span> matches <span class="osh-formula">'.$code.'</span>',5);
837
+ $in_array = true;
838
+ }
839
+ if ($in_array) break;
840
+ }
841
+ if (!$in_array) {
842
+ self::debug(' region code <span class="osh-replacement">'.$address['region_code'].'</span> and postcode <span class="osh-replacement">'.$address['postcode'].'</span> don\'t match',5);
843
+ }
844
+ // Vérification stricte
845
+ // $in_array = in_array($address['region_code'],$region_codes,true) || in_array($address['postcode'],$region_codes,true);
846
+ $excluding_region = $result[2]=='-' || $result[3]=='-';
847
+ if ($excluding_region && !$in_array || !$excluding_region && $in_array) return !$excluding;
848
+ }
849
+ }
850
+ }
851
+ }
852
+ return $excluding;
853
+ }
854
+
855
+ protected function _getProductProperty($product, $property_type, $property_name, $get_by_id=false) {
856
+ switch ($property_type) {
857
+ case 'attribute':
858
+ case 'attributes': return $product->getAttribute($property_name,$get_by_id);
859
+ case 'option':
860
+ case 'options': return $product->getOption($property_name,$get_by_id);
861
+ case 'stock': return $product->getStockData($property_name);
862
+ }
863
+ return null;
864
+ }
865
+
866
+ protected function _processProductProperty($products, $regex_result) {
867
+ // COUNT, SUM or COUNT DISTINCT
868
+ $operation = strtolower($regex_result[1]);
869
+ switch ($operation) {
870
+ case 'sum':
871
+ case 'count distinct':
872
+ $property_type = $regex_result[2];
873
+ $property_name = $regex_result[3];
874
+ $conditions = isset($regex_result[4]) ? $regex_result[4] : null;
875
+ break;
876
+ case 'count':
877
+ $conditions = isset($regex_result[2]) ? $regex_result[2] : null;
878
+ break;
879
+ }
880
+
881
+ self::debug(' :: start <span class="osh-replacement">'.$regex_result[0].'</span>',10);
882
+
883
+ $return_value = 0;
884
+
885
+ preg_match_all('/product\.(attribute(?:s)?|option(?:s)?|stock)\.([a-z0-9_]+)(?:\.(id))?/i',$conditions,$properties_regex_result,PREG_SET_ORDER);
886
+ $properties = array();
887
+ foreach ($properties_regex_result as $property_regex_result) {
888
+ $key = $property_regex_result[0];
889
+ if (!isset($properties[$key])) $properties[$key] = $property_regex_result;
890
+ }
891
+
892
+ foreach ($products as $product) {
893
+ if (isset($conditions) && $conditions!='') {
894
+ $formula = $conditions;
895
+ foreach ($properties as $property) {
896
+ $value = $this->_getProductProperty(
897
+ $product,
898
+ $tmp_property_type = $property[1],
899
+ $tmp_property_name = $property[2],
900
+ $get_by_id = isset($property[3]) && $property[3]=='id'
901
+ );
902
+ //$formula = $this->replace($property[0],$value,$formula);
903
+ $from = $property[0];
904
+ $to = is_string($value) || empty($value) ? "'".$value."'" : $value;
905
+ $formula = str_replace($from,$to,$formula);
906
+ self::debug(' replace <span class="osh-replacement">'.$from.'</span> by <span class="osh-replacement">'.$to.'</span> =&gt; <span class="osh-formula">'.str_replace($from,'<span class="osh-replacement">'.$to.'</span>',$formula).'</span>',5);
907
+ }
908
+ $eval_result = $this->_evalFormula($formula);
909
+ if (!isset($eval_result)) return 'null';
910
+ }
911
+ else $eval_result = true;
912
+
913
+ if ($eval_result==true) {
914
+ switch ($operation) {
915
+ case 'sum':
916
+ $value = $this->_getProductProperty($product,$property_type,$property_name);
917
+ //self::debug($product->getSku().'.'.$property_type.'.'.$property_name.' = "'.$value.'" x '.$product->getQuantity(),10);
918
+ $return_value += $value*$product->getQuantity();
919
+ break;
920
+ case 'count distinct':
921
+ if (!isset($distinct_values)) $distinct_values = array();
922
+ $value = $this->_getProductProperty($product,$property_type,$property_name);
923
+ if (!in_array($value,$distinct_values)) {
924
+ $distinct_values[] = $value;
925
+ $return_value++;
926
+ }
927
+ break;
928
+ case 'count':
929
+ $return_value += $product->getQuantity();
930
+ break;
931
+ }
932
+ }
933
+ }
934
+
935
+ self::debug(' :: end <span class="osh-replacement">'.$regex_result[0].'</span>',10);
936
+
937
+ return $return_value;
938
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
939
  }
940
 
941
  class DPDFrancePredict_Os_Message {
942
+ public $type;
943
+ public $message;
944
+ public $args;
945
+
946
+ public function __construct($type, $args) {
947
+ $this->type = $type;
948
+ $this->message = array_shift($args);
949
+ $this->args = $args;
950
+ }
951
+
952
+ public function toString() {
953
+ return vsprintf($this->message,$this->args);
954
+ }
955
  }
956
 
957
  class DPDFrancePredict_Os_Result {
958
+ public $success;
959
+ public $result;
960
 
961
+ public function __construct($success, $result=null) {
962
+ $this->success = $success;
963
+ $this->result = $result;
964
+ }
965
 
966
+ public function __toString() {
967
+ return is_bool($this->result) ? ($this->result ? 'true' : 'false') : (string)$this->result;
968
+ }
969
  }
970
 
971
 
app/code/community/DPDFrance/Predict/etc/config.xml CHANGED
@@ -1,12 +1,12 @@
1
  <?xml version="1.0" encoding="UTF-8"?>
2
  <!--
3
  /**
4
- * DPD France v5.1.0 shipping module for Magento
5
  *
6
  * @category DPDFrance
7
  * @package DPDFrance_Shipping
8
- * @author DPD S.A.S. <ensavoirplus.ecommerce@dpd.fr>
9
- * @copyright 2015 DPD S.A.S., société par actions simplifiée, au capital de 18.500.000 euros, dont le siège social est situé 27 Rue du Colonel Pierre Avia - 75015 PARIS, immatriculée au registre du commerce et des sociétés de Paris sous le numéro 444 420 830
10
  * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
11
  */
12
  -->
@@ -21,50 +21,31 @@
21
  <title>Livraison à domicile Predict sur rendez-vous </title>
22
  <methodname>Livraison 24-48h à domicile dans le créneau horaire qui vous convient le mieux (parmi des choix proposés par DPD)</methodname>
23
  <expense>
24
- # Franco de port à 89€ sauf Corse
25
  {
26
- destination: "FR-(2A,2B),MC",
27
- conditions: "{cart.price_including_tax}>=89",
28
- fees: 0.00
29
- }
30
- # Zones de montagne
31
- {
32
- destination: "FR(04120,04130,04140,04160,04170,04200,04240,04260,04300,04310,04330,04360,04370,04400,04510,04530,04600,04700,04850,05100,05110,05120,05130,05150,05160,05170,05200,05220,05240,05250,05260,05290,05300,05310,05320,05330,05340,05350,05400,05460,05470,05500,05560,05600,05700,05800,06140,06380,06390,06410,06420,06430,06450,06470,06530,06540,06620,06710,06750,06910,09110,09140,09300,09460,25120,25140,25240,25370,25450,25500,25650,30570,31110,38112,38114,38142,38190,38250,38350,38380,38410,38580,38660,38700,38750,38860,38880,39220,39310,39400,63113,63210,63240,63610,63660,63690,63840,63850,64440,64490,64560,64570,65110,65120,65170,65200,65240,65400,65510,65710,66210,66760,66800,68140,68610,68650,73110,73120,73130,73140,73150,73160,73170,73190,73210,73220,73230,73250,73260,73270,73300,73320,73340,73350,73390,73400,73440,73450,73460,73470,73500,73530,73550,73590,73600,73620,73630,73640,73710,73720,73870,74110,74120,74170,74220,74230,74260,74310,74340,74350,74360,74390,74400,74420,74430,74440,74450,74470,74480,74660,74740,74920,83111,83440,83530,83560,83630,83690,83830,83840,84390,88310,88340,88370,88400,90200)",
33
- fees: "5+{table {cart.weight} in
34
- 0.5:5.30,
35
- 1.0:6.50,
36
- 2.0:7.40,
37
- 3.0:8.30,
38
- 5.0:10.10,
39
- 10.0:12.50,
40
- 20.0:15.00,
41
- 30.0:18.00}",
42
- }
43
- # Zones Iles et Corse
44
- {
45
- destination: "FR(20*,17111,17123,17190,17310,17370,17410,17480,17550,17580,17590,17630,17650,17670,17740,17840,17880,17940,22870,29242,29253,29259,29980,29990,56360,56590,56780,56840,85350)",
46
- fees: "16+{table {cart.weight} in
47
- 0.5:5.30,
48
- 1.0:6.50,
49
- 2.0:7.40,
50
- 3.0:8.30,
51
- 5.0:10.10,
52
- 10.0:12.50,
53
- 20.0:15.00,
54
- 30.0:18.00}",
55
- }
56
- # Zone France et Monaco
57
- {
58
- destination: "FR,MC",
59
- fees: "{table {cart.weight} in
60
- 0.5:5.30,
61
- 1.0:6.50,
62
- 2.0:7.40,
63
- 3.0:8.30,
64
- 5.0:10.10,
65
- 10.0:12.50,
66
- 20.0:15.00,
67
- 30.0:18.00}",
68
  }
69
  </expense>
70
  </dpdfrpredict>
@@ -72,7 +53,7 @@
72
  </default>
73
  <modules>
74
  <DPDFrance_Predict>
75
- <version>5.1.1</version>
76
  <depends>
77
  <Mage_Shipping/>
78
  </depends>
1
  <?xml version="1.0" encoding="UTF-8"?>
2
  <!--
3
  /**
4
+ * DPD France v5.1.2 shipping module for Magento
5
  *
6
  * @category DPDFrance
7
  * @package DPDFrance_Shipping
8
+ * @author DPD France S.A.S. <ensavoirplus.ecommerce@dpd.fr>
9
+ * @copyright 2015 DPD France S.A.S., société par actions simplifiée, au capital de 18.500.000 euros, dont le siège social est situé 27 Rue du Colonel Pierre Avia - 75015 PARIS, immatriculée au registre du commerce et des sociétés de Paris sous le numéro 444 420 830
10
  * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
11
  */
12
  -->
21
  <title>Livraison à domicile Predict sur rendez-vous </title>
22
  <methodname>Livraison 24-48h à domicile dans le créneau horaire qui vous convient le mieux (parmi des choix proposés par DPD)</methodname>
23
  <expense>
 
24
  {
25
+ "Franco de port à 89€ sauf Corse":
26
+ {
27
+ "shipto": "FR-(2A,2B),MC",
28
+ "conditions": "{cart.price_including_tax}>=89",
29
+ "fees": 0.00
30
+ },
31
+
32
+ "Zones de montagne":
33
+ {
34
+ "shipto": "FR(04120,04130,04140,04160,04170,04200,04240,04260,04300,04310,04330,04360,04370,04400,04510,04530,04600,04700,04850,05100,05110,05120,05130,05150,05160,05170,05200,05220,05240,05250,05260,05290,05300,05310,05320,05330,05340,05350,05400,05460,05470,05500,05560,05600,05700,05800,06140,06380,06390,06410,06420,06430,06450,06470,06530,06540,06620,06710,06750,06910,09110,09140,09300,09460,25120,25140,25240,25370,25450,25500,25650,30570,31110,38112,38114,38142,38190,38250,38350,38380,38410,38580,38660,38700,38750,38860,38880,39220,39310,39400,63113,63210,63240,63610,63660,63690,63840,63850,64440,64490,64560,64570,65110,65120,65170,65200,65240,65400,65510,65710,66210,66760,66800,68140,68610,68650,73110,73120,73130,73140,73150,73160,73170,73190,73210,73220,73230,73250,73260,73270,73300,73320,73340,73350,73390,73400,73440,73450,73460,73470,73500,73530,73550,73590,73600,73620,73630,73640,73710,73720,73870,74110,74120,74170,74220,74230,74260,74310,74340,74350,74360,74390,74400,74420,74430,74440,74450,74470,74480,74660,74740,74920,83111,83440,83530,83560,83630,83690,83830,83840,84390,88310,88340,88370,88400,90200)",
35
+ "fees": "5+{table {cart.weight} in 0.5:5.30, 1.0:6.50, 2.0:7.40, 3.0:8.30, 5.0:10.10, 10.0:12.50, 20.0:15.00, 30.0:18.00}"
36
+ },
37
+
38
+ "Zones Iles et Corse":
39
+ {
40
+ "shipto": "FR(20*,17111,17123,17190,17310,17370,17410,17480,17550,17580,17590,17630,17650,17670,17740,17840,17880,17940,22870,29242,29253,29259,29980,29990,56360,56590,56780,56840,85350)",
41
+ "fees": "16+{table {cart.weight} in 0.5:5.30, 1.0:6.50, 2.0:7.40, 3.0:8.30, 5.0:10.10, 10.0:12.50, 20.0:15.00, 30.0:18.00}"
42
+ },
43
+
44
+ "Zone France et Monaco":
45
+ {
46
+ "shipto": "FR,MC",
47
+ "fees": "{table {cart.weight} in 0.5:5.30, 1.0:6.50, 2.0:7.40, 3.0:8.30, 5.0:10.10, 10.0:12.50, 20.0:15.00, 30.0:18.00}"
48
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
49
  }
50
  </expense>
51
  </dpdfrpredict>
53
  </default>
54
  <modules>
55
  <DPDFrance_Predict>
56
+ <version>5.1.2</version>
57
  <depends>
58
  <Mage_Shipping/>
59
  </depends>
app/code/community/DPDFrance/Predict/etc/system.xml CHANGED
@@ -1,12 +1,12 @@
1
  <?xml version="1.0" encoding="UTF-8"?>
2
  <!--
3
  /**
4
- * DPD France v5.1.0 shipping module for Magento
5
  *
6
  * @category DPDFrance
7
  * @package DPDFrance_Shipping
8
- * @author DPD S.A.S. <ensavoirplus.ecommerce@dpd.fr>
9
- * @copyright 2015 DPD S.A.S., société par actions simplifiée, au capital de 18.500.000 euros, dont le siège social est situé 27 Rue du Colonel Pierre Avia - 75015 PARIS, immatriculée au registre du commerce et des sociétés de Paris sous le numéro 444 420 830
10
  * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
11
  */
12
  -->
1
  <?xml version="1.0" encoding="UTF-8"?>
2
  <!--
3
  /**
4
+ * DPD France v5.1.2 shipping module for Magento
5
  *
6
  * @category DPDFrance
7
  * @package DPDFrance_Shipping
8
+ * @author DPD France S.A.S. <ensavoirplus.ecommerce@dpd.fr>
9
+ * @copyright 2015 DPD France S.A.S., société par actions simplifiée, au capital de 18.500.000 euros, dont le siège social est situé 27 Rue du Colonel Pierre Avia - 75015 PARIS, immatriculée au registre du commerce et des sociétés de Paris sous le numéro 444 420 830
10
  * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
11
  */
12
  -->
app/code/community/DPDFrance/Relais/Helper/Data.php CHANGED
@@ -1,11 +1,11 @@
1
  <?php
2
  /**
3
- * DPD France v5.1.0 shipping module for Magento
4
  *
5
  * @category DPDFrance
6
  * @package DPDFrance_Shipping
7
- * @author DPD S.A.S. <ensavoirplus.ecommerce@dpd.fr>
8
- * @copyright 2015 DPD S.A.S., société par actions simplifiée, au capital de 18.500.000 euros, dont le siège social est situé 27 Rue du Colonel Pierre Avia - 75015 PARIS, immatriculée au registre du commerce et des sociétés de Paris sous le numéro 444 420 830
9
  * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
10
  */
11
 
1
  <?php
2
  /**
3
+ * DPD France v5.1.2 shipping module for Magento
4
  *
5
  * @category DPDFrance
6
  * @package DPDFrance_Shipping
7
+ * @author DPD France S.A.S. <ensavoirplus.ecommerce@dpd.fr>
8
+ * @copyright 2015 DPD France S.A.S., société par actions simplifiée, au capital de 18.500.000 euros, dont le siège social est situé 27 Rue du Colonel Pierre Avia - 75015 PARIS, immatriculée au registre du commerce et des sociétés de Paris sous le numéro 444 420 830
9
  * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
10
  */
11
 
app/code/community/DPDFrance/Relais/Model/Carrier/DPDFranceRelaisShipping.php CHANGED
@@ -1,31 +1,31 @@
1
  <?php
2
  /**
3
- * DPD France v5.1.0 shipping module for Magento
4
  *
5
  * @category DPDFrance
6
  * @package DPDFrance_Shipping
7
- * @author DPD S.A.S. <ensavoirplus.ecommerce@dpd.fr>
8
- * @copyright 2015 DPD S.A.S., société par actions simplifiée, au capital de 18.500.000 euros, dont le siège social est situé 27 Rue du Colonel Pierre Avia - 75015 PARIS, immatriculée au registre du commerce et des sociétés de Paris sous le numéro 444 420 830
9
  * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
10
  */
11
 
12
  class DPDFrance_Relais_Model_Carrier_DPDFranceRelaisShipping extends Mage_Shipping_Model_Carrier_Abstract {
13
 
14
- protected $_code = "dpdfrrelais";
15
- protected $_expenseConfig;
16
- /**
17
- * Owebia
18
- *
19
- * @var DPDFrance_Relais_Model_Owebia
20
- */
21
- protected $_owebiaCore;
22
- protected $_messages;
23
-
24
- protected function _addMessages($messages) {
25
- if (!is_array($messages)) $messages = array($messages);
26
- if (!is_array($this->_messages)) $this->_messages = $messages;
27
- else $this->_messages = array_merge($this->_messages, $messages);
28
- }
29
 
30
  public function getAllowedMethods() {
31
  $process = array();
@@ -40,26 +40,26 @@ class DPDFrance_Relais_Model_Carrier_DPDFranceRelaisShipping extends Mage_Shippi
40
  }
41
 
42
 
43
- protected function _appendMethod($process, $row, $fees) {
44
- $method = Mage::getModel('shipping/rate_result_method')
45
- ->setCarrier($this->_code)
46
- ->setCarrierTitle($this->getConfigData('title'))
47
- ->setMethod($row['*code'])
48
- // ->setMethod('dpdfrrelais')
49
- ->setMethodTitle($this->getConfigData('methodname') . ' ' . $this->_getMethodText($process,$row,'label'))
50
- //->setMethodDescription($this->_getMethodText($process,$row,'description')) // can be enabled if necessary
51
- ->setPrice($fees)
52
- ->setCost($fees)
53
- ;
54
-
55
- $process['result']->append($method);
56
- }
57
-
58
- protected function _formatPrice($price) {
59
- return Mage::helper('core')->currency($price);
60
- }
61
-
62
- protected function _getCartTaxAmount($process) {
63
  $quote = Mage::getSingleton('checkout/session')->getQuote();
64
  $items_in_cart = $quote->getAllVisibleItems();
65
  // var_dump($quote, $items_in_cart);exit;
@@ -87,194 +87,194 @@ class DPDFrance_Relais_Model_Carrier_DPDFranceRelaisShipping extends Mage_Shippi
87
 
88
  }
89
 
90
- /**
91
- * Get Checkout Session Model
92
- *
93
- * @return Mage_Checkout_Model_Session
94
- */
95
- protected function _getCheckoutSession()
96
- {
97
- return Mage::getSingleton('checkout/session');
98
- }
99
-
100
- protected function _getConfig() {
101
- if (!isset($this->_expenseConfig)) {
102
- $this->_owebiaCore = Mage::getModel('dpdfrrelais/owebia', $this->getConfigData('expense'));
103
- $this->_expenseConfig = $this->_owebiaCore->getConfig();
104
- $this->_addMessages($this->_owebiaCore->getMessages());
105
- }
106
- return $this->_expenseConfig;
107
- }
108
-
109
- protected function _getCountryName($country_code) {
110
- return Mage::getModel('directory/country')->load($country_code)->getName();
111
- }
112
-
113
- protected function _getMethodText($process, $row, $property) {
114
- if (!isset($row[$property])) return '';
115
-
116
- return $this->_owebiaCore->evalInput($process,$row,$property,str_replace(
117
- array('{cart.weight}','{cart.price_including_tax}','{cart.price_excluding_tax}'),
118
- array(
119
- $process['data']['cart.weight'].$process['data']['cart.weight.unit'],
120
- $this->_formatPrice($process['data']['cart.price_including_tax']),
121
- $this->_formatPrice($process['data']['cart.price_excluding_tax'])
122
- ),
123
- $this->_owebiaCore->getRowProperty($row,$property)
124
- ));
125
- }
126
-
127
- protected function _process(&$process) {
128
- $store = Mage::app()->getStore($process['data']['store.id']);
129
- $timestamp = time();
130
- $customer_group_id = Mage::getSingleton('customer/session')->getCustomerGroupId();
131
- // Pour les commandes depuis Adminhtml
132
- if ($customer_group_id==0) {
133
- $customer_group_id2 = Mage::getSingleton('adminhtml/session_quote')->getQuote()->getCustomerGroupId();
134
- if (isset($customer_group_id2)) $customer_group_id = $customer_group_id2;
135
- }
136
-
137
- $customer_group_code = Mage::getSingleton('customer/group')->load($customer_group_id)->getData('customer_group_code');
138
- $process['data'] = array_merge($process['data'],array(
139
- 'customer.group.id' => $customer_group_id,
140
- 'customer.group.code' => $customer_group_code,
141
- 'destination.country.name' => $this->_getCountryName($process['data']['destination.country.code']),
142
- 'destination.postal.code' => Mage::getSingleton('checkout/session')->getQuote()->getShippingAddress()->getPostcode(),
143
- 'origin.country.name' => $this->_getCountryName($process['data']['origin.country.code']),
144
- 'cart.weight.unit' => 'kg',
145
- 'store.code' => $store->getCode(),
146
- 'store.name' => $store->getConfig('general/store_information/name'),
147
- 'store.address' => $store->getConfig('general/store_information/address'),
148
- 'store.phone' => $store->getConfig('general/store_information/phone'),
149
- 'date.timestamp' => $timestamp,
150
- 'date.year' => (int)date('Y',$timestamp),
151
- 'date.month' => (int)date('m',$timestamp),
152
- 'date.day' => (int)date('d',$timestamp),
153
- 'date.hour' => (int)date('H',$timestamp),
154
- 'date.minute' => (int)date('i',$timestamp),
155
- 'date.second' => (int)date('s',$timestamp),
156
- ));
157
-
158
- // We don't need process certain products. If necessary, enable this block.
159
- foreach ($process['cart.items'] as $id => $item) {
160
- if ($item->getProduct()->getTypeId()!='configurable') {
161
- $parent_item_id = $item->getParentItemId();
162
- $process['products'][] = new DPDFrance_Relais_Magento_Product($item, isset($process['cart.items'][$parent_item_id]) ? $process['cart.items'][$parent_item_id] : null);
163
- }
164
- }
165
-
166
-
167
- if (!$process['data']['free_shipping']) {
168
- foreach ($process['cart.items'] as $item) {
169
- if ($item->getProduct() instanceof Mage_Catalog_Model_Product) {
170
- if ($item->getFreeShipping()) $process['data']['free_shipping'] = true;
171
- else {
172
- $process['data']['free_shipping'] = false;
173
- break;
174
- }
175
- }
176
- }
177
- }
178
-
179
- $process['data']['cart.price_including_tax'] = $this->_getCartTaxAmount($process)+$process['data']['cart.price_excluding_tax'];
180
  // var_dump($process['data']['cart.price_excluding_tax'], $process['data']['cart.price_including_tax']);exit;
181
 
182
- $value_found = false;
183
- foreach ($this->_getConfig() as $row) {
184
- $result = $this->_owebiaCore->processRow($process, $row);
185
- $this->_addMessages($this->_owebiaCore->getMessages());
186
- if ($result->success) {
187
  if ($process['stop_to_first_match'] && $value_found) {
188
- // Mage::log('DPD Relais shipping Method : WARNING, destination is duplicated in BO configuration. Using first one, skipping others', Zend_Log::WARN);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
189
  break;
190
  }
191
- $value_found = true;
192
- $this->_appendMethod($process, $row, $result->result);
193
- }
194
- }
195
-
196
- if (!$value_found && $this->getConfigData('showerror')) $this->_setError($process, $this->getConfigData('specificerrmsg'));
197
- }
198
-
199
- protected function _setError(&$process, $message) {
200
- if (is_array($this->_messages))
201
- foreach ($this->_messages as $errMessage)
202
- if ($errMessage->type == 'over_weight') {
203
- $message = 'Your shopping cart is too heavy for being shipped by DPD Relais';
204
- break;
205
- }
206
- $error = Mage::getModel('shipping/rate_result_error')
207
- ->setCarrier($this->_code)
208
- ->setCarrierTitle($this->getConfigData('title'))
209
- ->setErrorMessage(Mage::helper('shipping')->__($message))
210
- ;
211
- $process['result'] = $error;
212
- }
213
-
214
- public function collectRates(Mage_Shipping_Model_Rate_Request $request){
215
- try {
216
- $process = array(
217
- 'result' => Mage::getModel('shipping/rate_result'),
218
- 'cart.items' => array(),
219
- 'products' => array(),
220
- 'data' => array(
221
- 'cart.price_excluding_tax' => $request->_data['package_value_with_discount'],
222
- 'cart.price_including_tax' => $request->_data['package_value_with_discount'],
223
- 'cart.weight' => $request->_data['package_weight'],
224
- 'cart.weight.unit' => null,
225
- 'cart.quantity' => $request->_data['package_qty'],
226
  'cart.coupon' => Mage::getSingleton('checkout/cart')->getQuote()->getCouponCode(),
227
- 'destination.country.code' => $request->_data['dest_country_id'],
228
- 'destination.country.name' => null,
229
- 'destination.region.code' => $request->_data['dest_region_code'],
230
- 'destination.postal.code' => $request->_data['dest_postcode'],
231
- 'origin.country.code' => $request->_data['country_id'],
232
- 'origin.country.name' => null,
233
- 'origin.region.code' => $request->_data['region_id'],
234
- 'origin.postal.code' => $request->_data['postcode'],
235
- 'customer.group.id' => null,
236
- 'customer.group.code' => null,
237
- 'free_shipping' => $request->getFreeShipping(),
238
- 'store.id' => $request->_data['store_id'],
239
- 'store.code' => null,
240
- 'store.name' => null,
241
- 'store.address' => null,
242
- 'store.phone' => null,
243
- 'date.timestamp' => null,
244
- 'date.year' => null,
245
- 'date.month' => null,
246
- 'date.day' => null,
247
- 'date.hour' => null,
248
- 'date.minute' => null,
249
- 'date.second' => null,
250
- ),
251
- 'stop_to_first_match' => TRUE,
252
- 'config' => null,
253
- );
254
-
255
- // We don't need process certain products. If necessary, enable this block.
256
- $items = $request->getAllItems();
257
- for ($i=0, $n=count($items); $i<$n; $i++) {
258
- $item = $items[$i];
259
- if ($item->getProduct() instanceof Mage_Catalog_Model_Product) $process['cart.items'][$item->getId()] = $item;
260
- }
261
-
262
-
263
- $this->_process($process);
264
- return $process['result'];
265
- }
266
- catch (Exception $e){
267
- Mage::logException($e);
268
- }
269
-
270
- }
271
-
272
- public function isTrackingAvailable() {
273
- return true;
274
- }
275
-
276
- public function getTrackingInfo($trackingNumber)
277
- {
278
  $trackingUrlByRef = 'http://www.dpd.fr/tracer_'.$trackingNumber;
279
  $trackingUrlByNb = 'http://www.dpd.fr/traces_'.$trackingNumber;
280
  $cargo = Mage::getStoreConfig('carriers/dpdfrrelais/cargo');
@@ -282,7 +282,7 @@ class DPDFrance_Relais_Model_Carrier_DPDFranceRelaisShipping extends Mage_Shippi
282
  $cargoutilise = substr($trackingNumber, -(int) $longueurcargo);
283
 
284
  if($cargoutilise == $cargo){
285
- $trackingStatus = Mage::getModel('shipping/tracking_result_status')
286
  ->setCarrier('dpdfrrelais')
287
  ->setCarrierTitle('DPD Relais')
288
  ->setTracking($trackingNumber)
@@ -310,93 +310,93 @@ class DPDFrance_Relais_Model_Carrier_DPDFranceRelaisShipping extends Mage_Shippi
310
  }
311
 
312
  class DPDFrance_Relais_Magento_Product implements DPDFrance_Relais_Os_Product {
313
- private $parent_cart_item;
314
- private $cart_item;
315
- private $cart_product;
316
- private $loaded_product;
317
- private $quantity;
318
-
319
- public function __construct($cart_item, $parent_cart_item) {
320
- $this->cart_item = $cart_item;
321
- $this->cart_product = $cart_item->getProduct();
322
- $this->parent_cart_item = $parent_cart_item;
323
- $this->quantity = isset($parent_cart_item) ? $parent_cart_item->getQty() : $cart_item->getQty();
324
- }
325
-
326
- public function getOption($option_name, $get_by_id=false) {
327
- $value = null;
328
- $product = $this->cart_product;
329
- foreach ($product->getOptions() as $option) {
330
- if ($option->getTitle()==$option_name) {
331
- $custom_option = $product->getCustomOption('option_'.$option->getId());
332
- if ($custom_option) {
333
- $value = $custom_option->getValue();
334
- if ($option->getType()=='drop_down' && !$get_by_id) {
335
- $option_value = $option->getValueById($value);
336
- if ($option_value) $value = $option_value->getTitle();
337
- }
338
- }
339
- break;
340
- }
341
- }
342
- return $value;
343
- }
344
-
345
- public function getAttribute($attribute_name, $get_by_id=false) {
346
- $value = null;
347
- $product = $this->_getLoadedProduct();
348
- $attribute = $product->getResource()->getAttribute($attribute_name);
349
- if ($attribute) {
350
- $input_type = $attribute->getFrontend()->getInputType();
351
- switch ($input_type) {
352
- case 'select' :
353
- $value = $get_by_id ? $product->getData($attribute_name) : $product->getAttributeText($attribute_name);
354
- break;
355
- default :
356
- $value = $product->getData($attribute_name);
357
- break;
358
- }
359
- }
360
- return $value;
361
- }
362
-
363
- private function _getLoadedProduct() {
364
- if (!isset($this->loaded_product)) $this->loaded_product = Mage::getModel('catalog/product')->load($this->cart_product->getId());
365
- return $this->loaded_product;
366
- }
367
-
368
- public function getQuantity() {
369
- return $this->quantity;
370
- }
371
-
372
- public function getName() {
373
- return $this->cart_product->getName();
374
- }
375
-
376
- public function getSku() {
377
- return $this->cart_product->getSku();
378
- }
379
-
380
- public function getStockData($key) {
381
- $stock = $this->cart_product->getStockItem();
382
- switch ($key) {
383
- case 'is_in_stock':
384
- return (bool)$stock->getIsInStock();
385
- case 'quantity':
386
- $quantity = $stock->getQty();
387
- return $stock->getIsQtyDecimal() ? (float)$quantity : (int)$quantity;
388
- }
389
- return null;
390
- }
391
  }
392
 
393
  interface DPDFrance_Relais_Os_Product {
394
- public function getOption($option);
395
- public function getAttribute($attribute);
396
- public function getName();
397
- public function getSku();
398
- public function getQuantity();
399
- public function getStockData($key);
400
  }
401
 
402
  ?>
1
  <?php
2
  /**
3
+ * DPD France v5.1.2 shipping module for Magento
4
  *
5
  * @category DPDFrance
6
  * @package DPDFrance_Shipping
7
+ * @author DPD France S.A.S. <ensavoirplus.ecommerce@dpd.fr>
8
+ * @copyright 2015 DPD France S.A.S., société par actions simplifiée, au capital de 18.500.000 euros, dont le siège social est situé 27 Rue du Colonel Pierre Avia - 75015 PARIS, immatriculée au registre du commerce et des sociétés de Paris sous le numéro 444 420 830
9
  * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
10
  */
11
 
12
  class DPDFrance_Relais_Model_Carrier_DPDFranceRelaisShipping extends Mage_Shipping_Model_Carrier_Abstract {
13
 
14
+ protected $_code = "dpdfrrelais";
15
+ protected $_expenseConfig;
16
+ /**
17
+ * Owebia
18
+ *
19
+ * @var DPDFrance_Relais_Model_Owebia
20
+ */
21
+ protected $_owebiaCore;
22
+ protected $_messages;
23
+
24
+ protected function _addMessages($messages) {
25
+ if (!is_array($messages)) $messages = array($messages);
26
+ if (!is_array($this->_messages)) $this->_messages = $messages;
27
+ else $this->_messages = array_merge($this->_messages, $messages);
28
+ }
29
 
30
  public function getAllowedMethods() {
31
  $process = array();
40
  }
41
 
42
 
43
+ protected function _appendMethod($process, $row, $fees) {
44
+ $method = Mage::getModel('shipping/rate_result_method')
45
+ ->setCarrier($this->_code)
46
+ ->setCarrierTitle($this->getConfigData('title'))
47
+ ->setMethod($row['*code'])
48
+ // ->setMethod('dpdfrrelais')
49
+ ->setMethodTitle($this->getConfigData('methodname') . ' ' . $this->_getMethodText($process,$row,'label'))
50
+ //->setMethodDescription($this->_getMethodText($process,$row,'description')) // can be enabled if necessary
51
+ ->setPrice($fees)
52
+ ->setCost($fees)
53
+ ;
54
+
55
+ $process['result']->append($method);
56
+ }
57
+
58
+ protected function _formatPrice($price) {
59
+ return Mage::helper('core')->currency($price);
60
+ }
61
+
62
+ protected function _getCartTaxAmount($process) {
63
  $quote = Mage::getSingleton('checkout/session')->getQuote();
64
  $items_in_cart = $quote->getAllVisibleItems();
65
  // var_dump($quote, $items_in_cart);exit;
87
 
88
  }
89
 
90
+ /**
91
+ * Get Checkout Session Model
92
+ *
93
+ * @return Mage_Checkout_Model_Session
94
+ */
95
+ protected function _getCheckoutSession()
96
+ {
97
+ return Mage::getSingleton('checkout/session');
98
+ }
99
+
100
+ protected function _getConfig() {
101
+ if (!isset($this->_expenseConfig)) {
102
+ $this->_owebiaCore = Mage::getModel('dpdfrrelais/owebia', $this->getConfigData('expense'));
103
+ $this->_expenseConfig = $this->_owebiaCore->getConfig();
104
+ $this->_addMessages($this->_owebiaCore->getMessages());
105
+ }
106
+ return $this->_expenseConfig;
107
+ }
108
+
109
+ protected function _getCountryName($country_code) {
110
+ return Mage::getModel('directory/country')->load($country_code)->getName();
111
+ }
112
+
113
+ protected function _getMethodText($process, $row, $property) {
114
+ if (!isset($row[$property])) return '';
115
+
116
+ return $this->_owebiaCore->evalInput($process,$row,$property,str_replace(
117
+ array('{cart.weight}','{cart.price_including_tax}','{cart.price_excluding_tax}'),
118
+ array(
119
+ $process['data']['cart.weight'].$process['data']['cart.weight.unit'],
120
+ $this->_formatPrice($process['data']['cart.price_including_tax']),
121
+ $this->_formatPrice($process['data']['cart.price_excluding_tax'])
122
+ ),
123
+ $this->_owebiaCore->getRowProperty($row,$property)
124
+ ));
125
+ }
126
+
127
+ protected function _process(&$process) {
128
+ $store = Mage::app()->getStore($process['data']['store.id']);
129
+ $timestamp = time();
130
+ $customer_group_id = Mage::getSingleton('customer/session')->getCustomerGroupId();
131
+ // Pour les commandes depuis Adminhtml
132
+ if ($customer_group_id==0) {
133
+ $customer_group_id2 = Mage::getSingleton('adminhtml/session_quote')->getQuote()->getCustomerGroupId();
134
+ if (isset($customer_group_id2)) $customer_group_id = $customer_group_id2;
135
+ }
136
+
137
+ $customer_group_code = Mage::getSingleton('customer/group')->load($customer_group_id)->getData('customer_group_code');
138
+ $process['data'] = array_merge($process['data'],array(
139
+ 'customer.group.id' => $customer_group_id,
140
+ 'customer.group.code' => $customer_group_code,
141
+ 'shipto.country.name' => $this->_getCountryName($process['data']['shipto.country.code']),
142
+ 'shipto.postal.code' => Mage::getSingleton('checkout/session')->getQuote()->getShippingAddress()->getPostcode(),
143
+ 'origin.country.name' => $this->_getCountryName($process['data']['origin.country.code']),
144
+ 'cart.weight.unit' => 'kg',
145
+ 'store.code' => $store->getCode(),
146
+ 'store.name' => $store->getConfig('general/store_information/name'),
147
+ 'store.address' => $store->getConfig('general/store_information/address'),
148
+ 'store.phone' => $store->getConfig('general/store_information/phone'),
149
+ 'date.timestamp' => $timestamp,
150
+ 'date.year' => (int)date('Y',$timestamp),
151
+ 'date.month' => (int)date('m',$timestamp),
152
+ 'date.day' => (int)date('d',$timestamp),
153
+ 'date.hour' => (int)date('H',$timestamp),
154
+ 'date.minute' => (int)date('i',$timestamp),
155
+ 'date.second' => (int)date('s',$timestamp),
156
+ ));
157
+
158
+ // We don't need process certain products. If necessary, enable this block.
159
+ foreach ($process['cart.items'] as $id => $item) {
160
+ if ($item->getProduct()->getTypeId()!='configurable') {
161
+ $parent_item_id = $item->getParentItemId();
162
+ $process['products'][] = new DPDFrance_Relais_Magento_Product($item, isset($process['cart.items'][$parent_item_id]) ? $process['cart.items'][$parent_item_id] : null);
163
+ }
164
+ }
165
+
166
+
167
+ if (!$process['data']['free_shipping']) {
168
+ foreach ($process['cart.items'] as $item) {
169
+ if ($item->getProduct() instanceof Mage_Catalog_Model_Product) {
170
+ if ($item->getFreeShipping()) $process['data']['free_shipping'] = true;
171
+ else {
172
+ $process['data']['free_shipping'] = false;
173
+ break;
174
+ }
175
+ }
176
+ }
177
+ }
178
+
179
+ $process['data']['cart.price_including_tax'] = $this->_getCartTaxAmount($process)+$process['data']['cart.price_excluding_tax'];
180
  // var_dump($process['data']['cart.price_excluding_tax'], $process['data']['cart.price_including_tax']);exit;
181
 
182
+ $value_found = false;
183
+ foreach ($this->_getConfig() as $row) {
184
+ $result = $this->_owebiaCore->processRow($process, $row);
185
+ $this->_addMessages($this->_owebiaCore->getMessages());
186
+ if ($result->success) {
187
  if ($process['stop_to_first_match'] && $value_found) {
188
+ // Mage::log('DPD Relais shipping Method : WARNING, shipto is duplicated in BO configuration. Using first one, skipping others', Zend_Log::WARN);
189
+ break;
190
+ }
191
+ $value_found = true;
192
+ $this->_appendMethod($process, $row, $result->result);
193
+ }
194
+ }
195
+
196
+ if (!$value_found && $this->getConfigData('showerror')) $this->_setError($process, $this->getConfigData('specificerrmsg'));
197
+ }
198
+
199
+ protected function _setError(&$process, $message) {
200
+ if (is_array($this->_messages))
201
+ foreach ($this->_messages as $errMessage)
202
+ if ($errMessage->type == 'over_weight') {
203
+ $message = 'Your shopping cart is too heavy for being shipped by DPD Relais';
204
  break;
205
  }
206
+ $error = Mage::getModel('shipping/rate_result_error')
207
+ ->setCarrier($this->_code)
208
+ ->setCarrierTitle($this->getConfigData('title'))
209
+ ->setErrorMessage(Mage::helper('shipping')->__($message))
210
+ ;
211
+ $process['result'] = $error;
212
+ }
213
+
214
+ public function collectRates(Mage_Shipping_Model_Rate_Request $request){
215
+ try {
216
+ $process = array(
217
+ 'result' => Mage::getModel('shipping/rate_result'),
218
+ 'cart.items' => array(),
219
+ 'products' => array(),
220
+ 'data' => array(
221
+ 'cart.price_excluding_tax' => $request->_data['package_value_with_discount'],
222
+ 'cart.price_including_tax' => $request->_data['package_value_with_discount'],
223
+ 'cart.weight' => $request->_data['package_weight'],
224
+ 'cart.weight.unit' => null,
225
+ 'cart.quantity' => $request->_data['package_qty'],
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
226
  'cart.coupon' => Mage::getSingleton('checkout/cart')->getQuote()->getCouponCode(),
227
+ 'shipto.country.code' => $request->_data['dest_country_id'],
228
+ 'shipto.country.name' => null,
229
+ 'shipto.region.code' => $request->_data['dest_region_code'],
230
+ 'shipto.postal.code' => $request->_data['dest_postcode'],
231
+ 'origin.country.code' => $request->_data['country_id'],
232
+ 'origin.country.name' => null,
233
+ 'origin.region.code' => $request->_data['region_id'],
234
+ 'origin.postal.code' => $request->_data['postcode'],
235
+ 'customer.group.id' => null,
236
+ 'customer.group.code' => null,
237
+ 'free_shipping' => $request->getFreeShipping(),
238
+ 'store.id' => $request->_data['store_id'],
239
+ 'store.code' => null,
240
+ 'store.name' => null,
241
+ 'store.address' => null,
242
+ 'store.phone' => null,
243
+ 'date.timestamp' => null,
244
+ 'date.year' => null,
245
+ 'date.month' => null,
246
+ 'date.day' => null,
247
+ 'date.hour' => null,
248
+ 'date.minute' => null,
249
+ 'date.second' => null,
250
+ ),
251
+ 'stop_to_first_match' => TRUE,
252
+ 'config' => null,
253
+ );
254
+
255
+ // We don't need process certain products. If necessary, enable this block.
256
+ $items = $request->getAllItems();
257
+ for ($i=0, $n=count($items); $i<$n; $i++) {
258
+ $item = $items[$i];
259
+ if ($item->getProduct() instanceof Mage_Catalog_Model_Product) $process['cart.items'][$item->getId()] = $item;
260
+ }
261
+
262
+
263
+ $this->_process($process);
264
+ return $process['result'];
265
+ }
266
+ catch (Exception $e){
267
+ Mage::logException($e);
268
+ }
269
+
270
+ }
271
+
272
+ public function isTrackingAvailable() {
273
+ return true;
274
+ }
275
+
276
+ public function getTrackingInfo($trackingNumber)
277
+ {
278
  $trackingUrlByRef = 'http://www.dpd.fr/tracer_'.$trackingNumber;
279
  $trackingUrlByNb = 'http://www.dpd.fr/traces_'.$trackingNumber;
280
  $cargo = Mage::getStoreConfig('carriers/dpdfrrelais/cargo');
282
  $cargoutilise = substr($trackingNumber, -(int) $longueurcargo);
283
 
284
  if($cargoutilise == $cargo){
285
+ $trackingStatus = Mage::getModel('shipping/tracking_result_status')
286
  ->setCarrier('dpdfrrelais')
287
  ->setCarrierTitle('DPD Relais')
288
  ->setTracking($trackingNumber)
310
  }
311
 
312
  class DPDFrance_Relais_Magento_Product implements DPDFrance_Relais_Os_Product {
313
+ private $parent_cart_item;
314
+ private $cart_item;
315
+ private $cart_product;
316
+ private $loaded_product;
317
+ private $quantity;
318
+
319
+ public function __construct($cart_item, $parent_cart_item) {
320
+ $this->cart_item = $cart_item;
321
+ $this->cart_product = $cart_item->getProduct();
322
+ $this->parent_cart_item = $parent_cart_item;
323
+ $this->quantity = isset($parent_cart_item) ? $parent_cart_item->getQty() : $cart_item->getQty();
324
+ }
325
+
326
+ public function getOption($option_name, $get_by_id=false) {
327
+ $value = null;
328
+ $product = $this->cart_product;
329
+ foreach ($product->getOptions() as $option) {
330
+ if ($option->getTitle()==$option_name) {
331
+ $custom_option = $product->getCustomOption('option_'.$option->getId());
332
+ if ($custom_option) {
333
+ $value = $custom_option->getValue();
334
+ if ($option->getType()=='drop_down' && !$get_by_id) {
335
+ $option_value = $option->getValueById($value);
336
+ if ($option_value) $value = $option_value->getTitle();
337
+ }
338
+ }
339
+ break;
340
+ }
341
+ }
342
+ return $value;
343
+ }
344
+
345
+ public function getAttribute($attribute_name, $get_by_id=false) {
346
+ $value = null;
347
+ $product = $this->_getLoadedProduct();
348
+ $attribute = $product->getResource()->getAttribute($attribute_name);
349
+ if ($attribute) {
350
+ $input_type = $attribute->getFrontend()->getInputType();
351
+ switch ($input_type) {
352
+ case 'select' :
353
+ $value = $get_by_id ? $product->getData($attribute_name) : $product->getAttributeText($attribute_name);
354
+ break;
355
+ default :
356
+ $value = $product->getData($attribute_name);
357
+ break;
358
+ }
359
+ }
360
+ return $value;
361
+ }
362
+
363
+ private function _getLoadedProduct() {
364
+ if (!isset($this->loaded_product)) $this->loaded_product = Mage::getModel('catalog/product')->load($this->cart_product->getId());
365
+ return $this->loaded_product;
366
+ }
367
+
368
+ public function getQuantity() {
369
+ return $this->quantity;
370
+ }
371
+
372
+ public function getName() {
373
+ return $this->cart_product->getName();
374
+ }
375
+
376
+ public function getSku() {
377
+ return $this->cart_product->getSku();
378
+ }
379
+
380
+ public function getStockData($key) {
381
+ $stock = $this->cart_product->getStockItem();
382
+ switch ($key) {
383
+ case 'is_in_stock':
384
+ return (bool)$stock->getIsInStock();
385
+ case 'quantity':
386
+ $quantity = $stock->getQty();
387
+ return $stock->getIsQtyDecimal() ? (float)$quantity : (int)$quantity;
388
+ }
389
+ return null;
390
+ }
391
  }
392
 
393
  interface DPDFrance_Relais_Os_Product {
394
+ public function getOption($option);
395
+ public function getAttribute($attribute);
396
+ public function getName();
397
+ public function getSku();
398
+ public function getQuantity();
399
+ public function getStockData($key);
400
  }
401
 
402
  ?>
app/code/community/DPDFrance/Relais/Model/Observer.php CHANGED
@@ -1,11 +1,11 @@
1
  <?php
2
  /**
3
- * DPD France v5.1.0 shipping module for Magento
4
  *
5
  * @category DPDFrance
6
  * @package DPDFrance_Shipping
7
- * @author DPD S.A.S. <ensavoirplus.ecommerce@dpd.fr>
8
- * @copyright 2015 DPD S.A.S., société par actions simplifiée, au capital de 18.500.000 euros, dont le siège social est situé 27 Rue du Colonel Pierre Avia - 75015 PARIS, immatriculée au registre du commerce et des sociétés de Paris sous le numéro 444 420 830
9
  * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
10
  */
11
 
1
  <?php
2
  /**
3
+ * DPD France v5.1.2 shipping module for Magento
4
  *
5
  * @category DPDFrance
6
  * @package DPDFrance_Shipping
7
+ * @author DPD France S.A.S. <ensavoirplus.ecommerce@dpd.fr>
8
+ * @copyright 2015 DPD France S.A.S., société par actions simplifiée, au capital de 18.500.000 euros, dont le siège social est situé 27 Rue du Colonel Pierre Avia - 75015 PARIS, immatriculée au registre du commerce et des sociétés de Paris sous le numéro 444 420 830
9
  * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
10
  */
11
 
app/code/community/DPDFrance/Relais/Model/Outputs.php CHANGED
@@ -1,11 +1,11 @@
1
  <?php
2
  /**
3
- * DPD France v5.1.0 shipping module for Magento
4
  *
5
  * @category DPDFrance
6
  * @package DPDFrance_Shipping
7
- * @author DPD S.A.S. <ensavoirplus.ecommerce@dpd.fr>
8
- * @copyright 2015 DPD S.A.S., société par actions simplifiée, au capital de 18.500.000 euros, dont le siège social est situé 27 Rue du Colonel Pierre Avia - 75015 PARIS, immatriculée au registre du commerce et des sociétés de Paris sous le numéro 444 420 830
9
  * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
10
  */
11
 
1
  <?php
2
  /**
3
+ * DPD France v5.1.2 shipping module for Magento
4
  *
5
  * @category DPDFrance
6
  * @package DPDFrance_Shipping
7
+ * @author DPD France S.A.S. <ensavoirplus.ecommerce@dpd.fr>
8
+ * @copyright 2015 DPD France S.A.S., société par actions simplifiée, au capital de 18.500.000 euros, dont le siège social est situé 27 Rue du Colonel Pierre Avia - 75015 PARIS, immatriculée au registre du commerce et des sociétés de Paris sous le numéro 444 420 830
9
  * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
10
  */
11
 
app/code/community/DPDFrance/Relais/Model/Owebia.php CHANGED
@@ -1,1174 +1,971 @@
1
  <?php
2
  /**
3
- * DPD France v5.1.0 shipping module for Magento
4
  *
5
  * @category DPDFrance
6
  * @package DPDFrance_Shipping
7
- * @author DPD S.A.S. <ensavoirplus.ecommerce@dpd.fr>
8
- * @copyright 2015 DPD S.A.S., société par actions simplifiée, au capital de 18.500.000 euros, dont le siège social est situé 27 Rue du Colonel Pierre Avia - 75015 PARIS, immatriculée au registre du commerce et des sociétés de Paris sous le numéro 444 420 830
9
  * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
10
  */
11
 
12
  class DPDFrance_Relais_Model_Owebia
13
  {
14
- public static $FLOAT_REGEX = '[-]?\d+(?:[.]\d+)?';
15
- public static $POSITIVE_FLOAT_REGEX = '\d+(?:[.]\d+)?';
16
- //public static $COUPLE_REGEX = '(?:[0-9.]+|\*)(?:\[|\])?\:[0-9.]+(?:\:[0-9.]+%?)*';
17
- public static $COUPLE_REGEX = '(?:[0-9.]+|\*) *(?:\[|\])? *\: *[0-9.]+';
18
- public static $UNCOMPRESSED_STRINGS = array(
19
- ' product.attribute.',
20
- ' product.option.',
21
- ' product.stock.',
22
- '{product.attribute.',
23
- '{product.option.',
24
- '{product.stock.',
25
- '{product.weight}',
26
- '{product.quantity}',
27
- '{cart.weight}',
28
- '{cart.quantity}',
29
- '{cart.coupon}',
30
- '{cart.price_including_tax}',
31
- '{cart.price_excluding_tax}',
32
- '{cart.',
33
- '{customvar.',
34
- '{selection.weight}',
35
- '{selection.quantity}',
36
- '{selection.',
37
- '{destination.country.',
38
- '{foreach ',
39
- '{/foreach}',
40
- );
41
- public static $COMPRESSED_STRINGS = array(
42
- ' p.a.',
43
- ' p.o.',
44
- ' p.s.',
45
- '{p.a.',
46
- '{p.o.',
47
- '{p.s.',
48
- '{p.w}',
49
- '{p.qty}',
50
- '{c.w}',
51
- '{c.qty}',
52
- '{c.cpn}',
53
- '{c.pit}',
54
- '{c.pet}',
55
- '{c.',
56
- '{v.',
57
- '{s.w}',
58
- '{s.qty}',
59
- '{s.',
60
- '{dest.ctry.',
61
- '{each ',
62
- '{/each}',
63
- );
64
-
65
- protected $_input;
66
- protected $_config;
67
- protected $_messages;
68
- protected $_formula_cache;
69
- protected $_expression_cache;
70
- protected $_overWeightMessage = 'Over weight';
71
- public $debug = 0;
72
- public $debug_output = '';
73
- public $debug_header = null;
74
-
75
- public function __construct($input) {
76
- $this->_formula_cache = array();
77
- $this->_messages = array();
78
- $this->_input = $input;
79
- $this->_config = array();
80
- $this->_parseInput();
81
- }
82
-
83
- private function debug($text, $level=10) {
84
- if ($this->debug>=$level) $this->debug_output .= "<p>".$text."</p>";
85
- }
86
-
87
- public function printDebug() {
88
- if ($this->debug>0) echo "<style rel=\"stylesheet\" type=\"text/css\">"
89
- .".osh-formula{color:#f90;} .osh-key{color:#0099f7;}"
90
- .".osh-error{color:#f00;} .osh-warning{color:#ff0;} .osh-info{color:#7bf700;}"
91
- .".osh-debug{background:#000;color:#bbb;position:absolute;top:0;left:0;width:100%;z-index:100;-moz-opacity:0.9;opacity:0.9;text-align:left;white-space:pre-wrap;}"
92
- .".osh-debug-content{padding:10px;}"
93
- .".osh-replacement{color:#ff3000;}"
94
- ."</style>"
95
- ."<div id=\"osh-debug\" class=\"osh-debug\"><pre class=\"osh-debug-content\"><span style=\"float:right;cursor:pointer;\" onclick=\"document.getElementById('osh-debug').style.display = 'none';\">[<span style=\"padding:0 5px;color:#f00;\">X</span>]</span>"
96
- ."<p>".$this->debug_header."</p>".$this->debug_output."</pre></div>";
97
- }
98
-
99
- public function setDebugHeader($process) {
100
- $header = 'DEBUG ' . __FILE__;//'DEBUG app/code/community/Owebia/Shipping/2/Model/Carrier/OwebiaShippingHelper.php<br/>';
101
- foreach ($process['data'] as $key => $data) {
102
- $header .= ' <span class="osh-key">'.$key.'</span> = <span class="osh-formula">'.$this->_toString($data).'</span><br/>';
103
- }
104
- $this->debug_header = $header;
105
- }
106
-
107
- public function getConfig() {
108
- return $this->_config;
109
- }
110
-
111
- public function getMessages() {
112
- $messages = $this->_messages;
113
- $this->_messages = array();
114
- return $messages;
115
- }
116
-
117
- public function formatConfig($compress) {
118
- $output = '';
119
- foreach ($this->_config as $code => $row) {
120
- if (!isset($row['lines'])) {
121
- if (isset($row['*comment']['value'])) {
122
- $output .= trim($row['*comment']['value'])."\n";
123
- }
124
- $output .= '{'.($compress ? '' : "\n");
125
- foreach ($row as $key => $property) {
126
- if (substr($key,0,1)!='*') {
127
- $value = $property['value'];
128
- if (isset($property['comment'])) $output .= ($compress ? '' : "\t").'/* '.$property['comment'].' */'.($compress ? '' : "\n");
129
- $output .= ($compress ? '' : "\t").$key.':'.($compress ? '' : ' ');
130
- if (is_bool($value)) $output .= $value ? 'true' : 'false';
131
- else if (is_int($value)) $output .= $value;
132
- else if ((string)((float)$value)==$value) $output .= $value;
133
- else $output .= '"'.str_replace('"','\\"',$value).'"';
134
- $output .= ','.($compress ? '' : "\n");
135
- }
136
- }
137
- if ($compress) $output = preg_replace('/,$/','',$output);
138
- $output .= "}\n".($compress ? '' : "\n");
139
- } else {
140
- $output .= $row['lines']."\n";
141
- }
142
- }
143
- return $compress ? $this->compress($output) : $this->uncompress($output);
144
- }
145
-
146
- public function checkConfig() {
147
- $process = array(
148
- 'result' => null,
149
- 'data' => array(
150
- 'cart.price_excluding_tax' => 0,
151
- 'cart.price_including_tax' => 0,
152
  'cart.coupon' => '',
153
- 'destination.country.code' => '',
154
- 'destination.country.name' => '',
155
- 'destination.region.code' => '',
156
- 'destination.postal.code' => '',
157
- 'origin.country.code' => '',
158
- 'origin.country.name' => '',
159
- 'origin.region.code' => '',
160
- 'origin.postal.code' => '',
161
- 'free_shipping' => false,
162
- 'customer.group.id' => '',
163
- 'customer.group.code' => '',
164
- 'cart.weight' => 0,
165
- 'cart.weight.unit' => 'kg',
166
- 'cart.quantity' => 0,
167
- ),
168
- 'cart.items' => array(),
169
- 'products' => array(),
170
- 'config' => $this->_config,
171
- );
172
- foreach ($this->_config as $code => &$row) {
173
- $this->processRow($process,$row,$check_all_conditions=true);
174
- foreach ($row as $property_key => $property_value) {
175
- if (substr($property_key,0,1)!='*') $this->getRowProperty($row,$property_key);
176
- }
177
- }
178
- }
179
-
180
- public function processRow($process, &$row, $is_checking=false) {
181
- if (!isset($row['*code'])) return;
182
-
183
- self::debug('process row <span class="osh-key">'.$row['*code'].'</span>',1);
184
- if (!isset($row['label']['value'])) $row['label']['value'] = '';
185
-
186
- $enabled = $this->getRowProperty($row,'enabled');
187
- if (isset($enabled)) {
188
- if (!$is_checking && !$enabled) {
189
- $this->addMessage('info',$row,'enabled','Configuration disabled');
190
- return new DPDFranceRelais_Os_Result(false);
191
- }
192
- }
193
-
194
- $conditions = $this->getRowProperty($row,'conditions');
195
- if (isset($conditions)) {
196
- $result = $this->_processFormula($process,$row,'conditions',$conditions,$is_checking);
197
- if (!$is_checking) {
198
- if (!$result->success) return $result;
199
- if (!$result->result) {
200
- $this->addMessage('info',$row,'conditions',"The cart doesn't match conditions");
201
- return new DPDFranceRelais_Os_Result(false);
202
- }
203
- }
204
- }
205
-
206
- $destination = $this->getRowProperty($row,'destination');
207
- if (isset($destination)) {
208
- $destination_match = $this->_addressMatch($destination,array(
209
- 'country_code' => $process['data']['destination.country.code'],
210
- 'region_code' => $process['data']['destination.region.code'],
211
- 'postcode' => $process['data']['destination.postal.code']
212
- ));
213
- if (!$is_checking && !$destination_match) {
214
- $this->addMessage('info',$row,'destination',"The shipping method doesn't cover the zone");
215
- return new DPDFranceRelais_Os_Result(false);
216
- }
217
- }
218
-
219
- $origin = $this->getRowProperty($row,'origin');
220
- if (isset($origin)) {
221
- $origin_match = $this->_addressMatch($origin,array(
222
- 'country_code' => $process['data']['origin.country.code'],
223
- 'region_code' => $process['data']['origin.region.code'],
224
- 'postcode' => $process['data']['origin.postal.code']
225
- ));
226
- if (!$is_checking && !$origin_match) {
227
- $this->addMessage('info',$row,'origin',"The shipping method doesn't match to shipping origin");
228
- return new DPDFranceRelais_Os_Result(false);
229
- }
230
- }
231
-
232
- $customer_groups = $this->getRowProperty($row,'customer_groups');
233
- if (isset($customer_groups)) {
234
- $groups = explode(',',$customer_groups);
235
- $group_match = false;
236
- //self::debug('code:'.$process['data']['customer.group.code'].', id:'.$process['data']['customer.group.id']);
237
- foreach ($groups as $group) {
238
- $group = trim($group);
239
- if ($group==$process['data']['customer.group.code'] || is_int($group) && $group==$process['data']['customer.group.id'] || $group=='*') {
240
- $group_match = true;
241
- break;
242
- }
243
- }
244
- if (!$is_checking && !$group_match) {
245
- $this->addMessage('info',$row,'customer_groups',"The shipping method doesn't match to customer group (%s)",$process['data']['customer.group.code']);
246
- return new DPDFranceRelais_Os_Result(false);
247
- }
248
- }
249
-
250
- $fees = $this->getRowProperty($row,'fees');
251
- if (isset($fees)) {
252
- $result = $this->_processFormula($process,$row,'fees',$fees,$is_checking);
253
- if (!$result->success) return $result;
254
- self::debug(' => <span class="osh-info">result = <span class="osh-formula">'.$this->_toString($result->result).'</span>',1);
255
- return new DPDFranceRelais_Os_Result(true,(float)$result->result);
256
- }
257
- return new DPDFranceRelais_Os_Result(false);
258
- }
259
-
260
- public function getRowProperty($row, $key, $original_row=null, $original_key=null) {
261
- $property = null;
262
- $output = null;
263
- if (isset($original_row) && isset($original_key) && $original_row['*code']==$row['*code'] && $original_key==$key) {
264
- $this->addMessage('error',$row,$key,'Infinite loop %s',"<span class=\"code\">{".$row['*code'].'.'.$key."}</span>");
265
- return array('error' => 'Infinite loop');
266
- }
267
- if (isset($row[$key]['value'])) {
268
- $property = $row[$key]['value'];
269
- $output = $property;
270
- $code = array_key_exists('*code', $row) ? $row['*code'] : NULL; self::debug(' get <span class="osh-key">'.$code.'</span>.<span class="osh-key">'.$key.'</span> = <span class="osh-formula">'.$this->_toString($property).'</span>',5);
271
- preg_match_all('/{([a-z0-9_]+)\.([a-z0-9_]+)}/i',$output,$result_set,PREG_SET_ORDER);
272
- foreach ($result_set as $result) {
273
- list($original,$ref_code,$ref_key) = $result;
274
- if (!in_array($ref_code,array('module','date','store','cart','product','selection','customvar'))) {
275
- if ($ref_code==$row['code']['value'] && $ref_key==$key) {
276
- $this->addMessage('error',$row,$key,'Infinite loop %s',"<span class=\"code\">".$original."</span>");
277
- return null;
278
- }
279
- if (isset($this->_config[$ref_code][$ref_key]['value'])) {
280
- $replacement = $this->getRowProperty($this->_config[$ref_code],$ref_key,
281
- isset($original_row) ? $original_row : $row,isset($original_key) ? $original_key : $key);
282
- if (is_array($replacement) && isset($replacement['error'])) {
283
- return isset($original_row) ? $replacement : 'false';
284
- }
285
- } else {
286
- $this->addMessage('error',$row,$key,'Non-existent property %s',"<span class=\"code\">".$original."</span>");
287
- $replacement = 'null';
288
- }
289
- $output = $this->replace($original,$replacement,$output);
290
- }
291
- }
292
- } else {
293
- $code = array_key_exists('*code', $row) ? $row['*code'] : NULL; self::debug(' get <span class="osh-key">'.$code.'</span>.<span class="osh-key">'.$key.'</span> = <span class="osh-formula">null</span>',5);
294
- }
295
- return $output;
296
- }
297
-
298
- protected function _toString($value) {
299
- if (!isset($value)) return 'null';
300
- else if (is_bool($value)) return $value ? 'true' : 'false';
301
- else return $value;
302
- }
303
-
304
- protected function replace($from, $to, $input) {
305
- if ($from===$to) return $input;
306
- if (strpos($input,$from)===false) return $input;
307
- $to = $this->_toString($to);
308
- self::debug(' replace <span class="osh-replacement">'.$this->_toString($from).'</span> by <span class="osh-replacement">'.$to.'</span> =&gt; <span class="osh-formula">'.str_replace($from,'<span class="osh-replacement">'.$to.'</span>',$input).'</span>',5);
309
- return str_replace($from,$to,$input);
310
- }
311
-
312
- protected function _min() {
313
- $args = func_get_args();
314
- $min = null;
315
- foreach ($args as $arg) {
316
- if (isset($arg) && (!isset($min) || $min>$arg)) $min = $arg;
317
- }
318
- return $min;
319
- }
320
-
321
- protected function _max() {
322
- $args = func_get_args();
323
- $max = null;
324
- foreach ($args as $arg) {
325
- if (isset($arg) && (!isset($max) || $max<$arg)) $max = $arg;
326
- }
327
- return $max;
328
- }
329
-
330
- protected function _processFormula($process, &$row, $property_key, $formula_string, $is_checking, $use_cache=true)
331
- {
332
- $result = $this->_prepareFormula($process,$row,$property_key,$formula_string,$is_checking,$use_cache);
333
- if (!$result->success) return $result;
334
-
335
- $eval_result = $this->_evalFormula($result->result);
336
- if ($result->result == 'null') {
337
- $this->addMessage('over_weight',$row,$property_key, $this->_overWeightMessage);
338
- $result = new DPDFranceRelais_Os_Result(false);
339
- if ($use_cache) $this->setCache($formula_string,$result);
340
- return $result;
341
- }
342
- if (!isset($eval_result)) {
343
- $this->addMessage('error',$row,$property_key,'Invalid formula');
344
- $result = new DPDFranceRelais_Os_Result(false);
345
- if ($use_cache) $this->setCache($formula_string,$result);
346
- return $result;
347
- }
348
- self::debug(' formula evaluation = <span class="osh-formula">'.$this->_toString($eval_result).'</span>',10);
349
- $result = new DPDFranceRelais_Os_Result(true,$eval_result);
350
- if ($use_cache) $this->setCache($formula_string,$result);
351
- return $result;
352
- }
353
-
354
- public function evalInput($process, $row, $property_key, $input) {
355
- $result = $this->_prepareFormula($process,$row,$property_key,$input,$is_checking=false,$use_cache=true);
356
- return $result->success ? $result->result : $input;
357
- }
358
-
359
- protected function setCache($expression, $value) {
360
- if ($value instanceof DPDFranceRelais_Os_Result) {
361
- $this->_formula_cache[$expression] = $value;
362
- self::debug(' cache <span class="osh-replacement">'.$expression.'</span> = <span class="osh-formula">'.$this->_toString($this->_formula_cache[$expression]).'</span>',10);
363
- } else {
364
- $value = $this->_toString($value);
365
- $this->_expression_cache[$expression] = $value;
366
- self::debug(' cache <span class="osh-replacement">'.$expression.'</span> = <span class="osh-formula">'.$value.'</span>',10);
367
- }
368
- }
369
-
370
- protected function _prepareFormula($process, $row, $property_key, $formula_string, $is_checking, $use_cache=true)
371
- {
372
- if ($use_cache && isset($this->_formula_cache[$formula_string])) {
373
- $result = $this->_formula_cache[$formula_string];
374
- self::debug(' get cached formula <span class="osh-replacement">'.$formula_string.'</span> = <span class="osh-formula">'.$this->_toString($result->result).'</span>',10);
375
- return $result;
376
- }
377
-
378
- $formula = $formula_string;
379
- //self::debug(' formula = <span class="osh-formula">'.$formula.'</span>',10);
380
-
381
- while (preg_match("#{foreach product\.((?:attribute|option)\.(?:[a-z0-9_]+))}(.*){/foreach}#i",$formula,$result)) {
382
- $original = $result[0];
383
- if ($use_cache && isset($this->_expression_cache[$original])) {
384
- $replacement = $this->_expression_cache[$original];
385
- self::debug(' get cached expression <span class="osh-replacement">'.$original.'</span> = <span class="osh-formula">'.$replacement.'</span>',10);
386
- }
387
- else {
388
- $replacement = 0;
389
- list($filter_property_type,$filter_property_name) = explode('.',$result[1]);
390
- $selections = array();
391
- self::debug(' :: foreach <span class="osh-key">'.$filter_property_type.'</span>.<span class="osh-key">'.$filter_property_name.'</span>',10);
392
- foreach ($process['products'] as $product) {
393
- $tmp_value = $this->_getProductProperty($product,$filter_property_type,$filter_property_name,$get_by_id=false);
394
- self::debug(' products[<span class="osh-formula">'.$product->getName().'</span>].<span class="osh-key">'.$filter_property_type.'</span>.<span class="osh-key">'.$filter_property_name.'</span> = <span class="osh-formula">'.$this->_toString($tmp_value).'</span>',10);
395
- $key = 'val_'.$tmp_value;
396
- $sel = isset($selections[$key]) ? $selections[$key] : null;
397
- $selections[$key]['products'][] = $product;
398
- $selections[$key]['weight'] = (isset($sel['weight']) ? $sel['weight'] : 0)+$product->getAttribute('weight')*$product->getQuantity();
399
- $selections[$key]['quantity'] = (isset($sel['quantity']) ? $sel['quantity'] : 0)+$product->getQuantity();
400
- }
401
- self::debug(' :: start foreach',10);
402
- foreach ($selections as $selection) {
403
- $process2 = $process;
404
- $process2['products'] = $selection['products'];
405
- $process2['data']['selection.quantity'] = $selection['quantity'];
406
- $process2['data']['selection.weight'] = $selection['weight'];
407
- $process_result = $this->_processFormula($process2,$row,$property_key,$result[2],$is_checking,$tmp_use_cache=false);
408
- $replacement += $process_result->result;
409
- }
410
- self::debug(' :: end foreach <span class="osh-key">'.$filter_property_type.'</span>.<span class="osh-key">'.$filter_property_name.'</span>',10);
411
- if ($use_cache) $this->setCache($original,$replacement);
412
- }
413
- $formula = $this->replace($original,$replacement,$formula);
414
- }
415
-
416
- $formula = str_replace(array("\n","\t"),array('',''),$formula);
417
-
418
- while (preg_match("#{customvar\.([a-z0-9_]+)}#i",$formula,$result)) {
419
- $original = $result[0];
420
- $replacement = Mage::getModel('core/variable')->loadByCode($result[1])->getValue('plain');
421
- $formula = $this->replace($original,$replacement,$formula);
422
- }
423
-
424
- $first_product = isset($process['products'][0]) ? $process['products'][0] : null;
425
- if (!isset($process['data']['selection.weight'])) $process['data']['selection.weight'] = $process['data']['cart.weight'];
426
- if (!isset($process['data']['selection.quantity'])) $process['data']['selection.quantity'] = $process['data']['cart.quantity'];
427
- $process['data']['product.weight'] = isset($first_product) ? $first_product->getAttribute('weight') : 0;
428
- $process['data']['product.quantity'] = isset($first_product) ? $first_product->getQuantity() : 0;
429
-
430
- foreach ($process['data'] as $original => $replacement) {
431
- $formula = $this->replace('{'.$original.'}',$replacement,$formula);
432
- }
433
-
434
- if (isset($first_product)) {
435
- while (preg_match("#{product\.(attribute|option|stock)\.([a-z0-9_]+)}#i",$formula,$result)) {
436
- $original = $result[0];
437
- switch ($result[1]) {
438
- case 'attribute': $replacement = $first_product->getAttribute($result[2]); break;
439
- case 'option': $replacement = $first_product->getOption($result[2]); break;
440
- case 'stock': $replacement = $first_product->getStockData($result[2]); break;
441
- }
442
- $formula = $this->replace($original,$replacement,$formula);
443
- }
444
- }
445
-
446
- //while (preg_match("/{(count|all|any) (attribute|option) '([^'\)]+)' ?(==|<=|>=|<|>|!=) ?(".self::$FLOAT_REGEX."|true|false|'[^'\)]*')}/",$formula,$result)
447
- // || preg_match("/{(sum|count distinct) (attribute|option) '([^'\)]+)'}/",$formula,$result))
448
- while (preg_match("/{(count) products(?: where ([^}]+))?}/i",$formula,$result)
449
- || preg_match("/{(sum|count distinct) product\.(attribute|option)\.([a-z0-9_]+)(?: where ([^}]+))?}/i",$formula,$result)) {
450
- $original = $result[0];
451
- if ($use_cache && isset($this->_expression_cache[$original])) {
452
- $replacement = $this->_expression_cache[$original];
453
- self::debug(' get cached expression <span class="osh-replacement">'.$original.'</span> = <span class="osh-formula">'.$replacement.'</span>',10);
454
- }
455
- else {
456
- $replacement = $this->_processProductProperty($process['products'],$result);
457
- if ($use_cache) $this->setCache($result[0],$replacement);
458
- }
459
- $formula = $this->replace($original,$replacement,$formula);
460
- }
461
-
462
- //while (preg_match("/{table '([^']+)' ([^}]+)}/",$formula,$result))
463
- while (preg_match("/{table ([^}]+) in ([0-9\.:,\*\[\] ]+)}/i",$formula,$result)) {
464
- $original = $result[0];
465
- if ($use_cache && isset($this->_expression_cache[$original])) {
466
- $replacement = $this->_expression_cache[$original];
467
- self::debug(' get cached expression <span class="osh-replacement">'.$original.'</span> = <span class="osh-formula">'.$replacement.'</span>',10);
468
- } else {
469
- $reference_value = $this->_evalFormula($result[1]);
470
- if (isset($reference_value)) {
471
- $fees_table_string = $result[2];
472
-
473
- if (!preg_match('#^'.self::$COUPLE_REGEX.'(?:, *'.self::$COUPLE_REGEX.')*$#',$fees_table_string)) {
474
- $this->addMessage('error',$row,$property_key,'Error in table %s','<span class="osh-formula">'.htmlentities($result[0]).'</span>');
475
- $result = new DPDFranceRelais_Os_Result(false);
476
- if ($use_cache) $this->setCache($formula_string,$result);
477
- return $result;
478
- }
479
- $fees_table = explode(',',$fees_table_string);
480
-
481
- $replacement = null;
482
- foreach ($fees_table as $item) {
483
- $fee_data = explode(':',$item);
484
-
485
- $fee = trim($fee_data[1]);
486
- $max_value = trim($fee_data[0]);
487
-
488
- $last_char = $max_value{strlen($max_value)-1};
489
- if ($last_char=='[') $including_max_value = false;
490
- else if ($last_char==']') $including_max_value = true;
491
- else $including_max_value = true;
492
-
493
- $max_value = str_replace(array('[',']'),'',$max_value);
494
-
495
- if ($max_value=='*' || $including_max_value && $reference_value<=$max_value || !$including_max_value && $reference_value<$max_value) {
496
- $replacement = $fee;//$this->_calculateFee($process,$fee,$var);
497
- break;
498
- }
499
- }
500
- }
501
- $replacement = $this->_toString($replacement);
502
- if ($use_cache) $this->setCache($original,$replacement);
503
- }
504
- $formula = $this->replace($original,$replacement,$formula);
505
- }
506
- $result = new DPDFranceRelais_Os_Result(true,$formula);
507
- return $result;
508
- }
509
-
510
- protected function _evalFormula($formula) {
511
- if (is_bool($formula)) return $formula;
512
- if (!preg_match('/^(?:floor|ceil|round|max|min|rand|pow|pi|sqrt|log|exp|abs|int|float|true|false|null|and|or|in|substr|strtolower'
513
- .'|in_array\(\'(?:[^\']*)\', *array\( *(?:\'(?:[^\']+)\') *(?: *, *\'(?:[^\']+)\')* *\) *\)'
514
- .'|\'[^\']*\'|[0-9,\'\.\-\(\)\*\/\?\:\+\<\>\=\&\|%! ])*$/',$formula)) {
515
- self::debug(' doesn\'t match',10);
516
- return null;
517
- }
518
- $formula = str_replace(
519
- array('min','max'),
520
- array('$this->_min','$this->_max'),
521
- $formula
522
- );
523
- $eval_result = null;
524
- @eval('$eval_result = ('.$formula.');');
525
- return $eval_result;
526
- }
527
-
528
- protected function _getOptionsAndData($string) {
529
- if (preg_match('/^(\\s*\(\\s*([^\] ]*)\\s*\)\\s*)/',$string,$result)) {
530
- $options = $result[2];
531
- $data = str_replace($result[1],'',$string);
532
- } else {
533
- $options = '';
534
- $data = $string;
535
- }
536
- return array(
537
- 'options' => $options,
538
- 'data' => $data,
539
- );
540
- }
541
-
542
- public function compress($input) {
543
- if (preg_match_all("/{table (.*) in (".self::$COUPLE_REGEX."(?:, *".self::$COUPLE_REGEX.")*)}/imsU",$input,$result,PREG_SET_ORDER)) {
544
- foreach ($result as $result_i) {
545
- $fees_table = explode(',',$result_i[2]);
546
- $value = null;
547
- foreach ($fees_table as $index => $item) {
548
- list($max_value,$fee) = explode(':',$item);
549
- $last_char = $max_value{strlen($max_value)-1};
550
- if (in_array($last_char,array('[',']'))) {
551
- $including_char = $last_char;
552
- $max_value = str_replace(array('[',']'),'',$max_value);
553
- } else $including_char = '';
554
- $fees_table[$index] = ((float)$max_value).$including_char.':'.((float)$fee);
555
- }
556
- $input = str_replace($result_i[2],implode(',',$fees_table),$input);
557
- $input = str_replace($result_i[1],trim($result_i[1]),$input);
558
- }
559
- }
560
- if (preg_match_all("#{foreach ([^}]*)}(.*){/foreach}#imsU",$input,$result,PREG_SET_ORDER)) {
561
- foreach ($result as $result_i) {
562
- $input = str_replace($result_i[1],trim($result_i[1]),$input);
563
- $input = str_replace($result_i[2],trim($result_i[2]),$input);
564
- }
565
- }
566
- return '$$'.str_replace(
567
- self::$UNCOMPRESSED_STRINGS,
568
- self::$COMPRESSED_STRINGS,
569
- $input
570
- );
571
- }
572
-
573
- public function uncompress($input) {
574
- if (preg_match_all("/{table (.*) in (".self::$COUPLE_REGEX."(?:, *".self::$COUPLE_REGEX.")*)}/iU",$input,$result,PREG_SET_ORDER)) {
575
- foreach ($result as $result_i) {
576
- $fees_table = explode(',',$result_i[2]);
577
- $value = null;
578
- foreach ($fees_table as $index => $item) {
579
- list($max_value,$fee) = explode(':',$item);
580
- $last_char = $max_value{strlen($max_value)-1};
581
- if (in_array($last_char,array('[',']'))) {
582
- $including_char = $last_char;
583
- $max_value = str_replace(array('[',']'),'',$max_value);
584
- } else $including_char = '';
585
- $max_value = (float)$max_value;
586
- $fee = (float)$fee;
587
- $new_max_value = number_format($max_value,2,'.','');
588
- $new_fee = number_format($fee,2,'.','');
589
- $fees_table[$index] = (((float)$new_max_value)==$max_value ? $new_max_value : $max_value).$including_char.':'
590
- .(((float)$new_fee)==$fee ? $new_fee : $fee);
591
- }
592
- $input = str_replace($result_i[2],implode(', ',$fees_table),$input);
593
- $input = str_replace($result_i[1],trim($result_i[1]),$input);
594
- }
595
- }
596
- if (preg_match_all("#{foreach ([^}]*)}(.*){/foreach}#iU",$input,$result,PREG_SET_ORDER)) {
597
- foreach ($result as $result_i) {
598
- $input = str_replace($result_i[1],trim($result_i[1]),$input);
599
- $input = str_replace($result_i[2],trim($result_i[2]),$input);
600
- }
601
- }
602
- return str_replace(
603
- self::$COMPRESSED_STRINGS,
604
- self::$UNCOMPRESSED_STRINGS,
605
- $input
606
- );
607
- }
608
-
609
- public function parseProperty($input) {
610
- $value = $input==='false' || $input==='true' ? $input=='true' : str_replace('\"','"',preg_replace('/^(?:"|\')(.*)(?:"|\')$/s','$1',$input));
611
- return $value==='' ? null : $value;
612
- }
613
-
614
- public function cleanProperty(&$row, $key) {
615
- $input = $row[$key]['value'];
616
- if (is_string($input)) {
617
- $input = str_replace(array("\n"),array(''),$input);
618
- while (preg_match('/({TABLE |{SUM |{COUNT | DISTINCT | IN )/',$input,$resi)) {
619
- $input = str_replace($resi[0],strtolower($resi[0]),$input);
620
- }
621
-
622
- while (preg_match('/{{customVar code=([a-zA-Z0-9_-]+)}}/',$input,$resi)) {
623
- $input = str_replace($resi[0],'{customvar.'.$resi[1].'}',$input);
624
- }
625
-
626
- $regex = "{(weight|products_quantity|price_including_tax|price_excluding_tax|country)}";
627
- if (preg_match('/'.$regex.'/',$input,$resi)) {
628
- $this->addMessage('warning',$row,$key,'Usage of deprecated syntax %s','<span class="osh-formula">'.$resi[0].'</span>');
629
- while (preg_match('/'.$regex.'/',$input,$resi)) {
630
- switch ($resi[1]) {
631
- case 'price_including_tax':
632
- case 'price_excluding_tax':
633
- case 'weight':
634
- $input = str_replace($resi[0],"{cart.".$resi[1]."}",$input);
635
- break;
636
- case 'products_quantity': $input = str_replace($resi[0],"{cart.quantity}",$input); break;
637
- case 'country': $input = str_replace($resi[0],"{destination.country.name}",$input); break;
638
- }
639
- }
640
- }
641
-
642
- $regex1 = "{copy '([a-zA-Z0-9_]+)'\.'([a-zA-Z0-9_]+)'}";
643
- if (preg_match('/'.$regex1.'/',$input,$resi)) {
644
- $this->addMessage('warning',$row,$key,'Usage of deprecated syntax %s','<span class="osh-formula">'.$resi[0].'</span>');
645
- while (preg_match('/'.$regex1.'/',$input,$resi)) $input = str_replace($resi[0],'{'.$resi[1].'.'.$resi[2].'}',$input);
646
- }
647
-
648
- $regex1 = "{(count|all|any) (attribute|option) '([^'\)]+)' ?((?:==|<=|>=|<|>|!=) ?(?:".self::$FLOAT_REGEX."|true|false|'[^'\)]*'))}";
649
- $regex2 = "{(sum) (attribute|option) '([^'\)]+)'}";
650
- if (preg_match('/'.$regex1.'/',$input,$resi) || preg_match('/'.$regex2.'/',$input,$resi)) {
651
- $this->addMessage('warning',$row,$key,'Usage of deprecated syntax %s','<span class="osh-formula">'.$resi[0].'</span>');
652
- while (preg_match('/'.$regex1.'/',$input,$resi) || preg_match('/'.$regex2.'/',$input,$resi)) {
653
- switch ($resi[1]) {
654
- case 'count': $input = str_replace($resi[0],"{count products where product.".$resi[2]."s.".$resi[3].$resi[4]."}",$input); break;
655
- case 'all': $input = str_replace($resi[0],"{count products where product.".$resi[2]."s.".$resi[3].$resi[4]."}=={products_quantity}",$input); break;
656
- case 'any': $input = str_replace($resi[0],"{count products where product.".$resi[2]."s.".$resi[3].$resi[4]."}>0",$input); break;
657
- case 'sum': $input = str_replace($resi[0],"{sum product.".$resi[2].".".$resi[3]."}",$input); break;
658
- }
659
- }
660
- }
661
-
662
- $regex = "((?:{| )product.(?:attribute|option))s.";
663
- if (preg_match('/'.$regex.'/',$input,$resi)) {
664
- $this->addMessage('warning',$row,$key,'Usage of deprecated syntax %s','<span class="osh-formula">'.$resi[0].'</span>');
665
- while (preg_match('/'.$regex.'/',$input,$resi)) {
666
- $input = str_replace($resi[0],$resi[1].'.',$input);
667
- }
668
- }
669
-
670
- $regex = "{table '([^']+)' (".self::$COUPLE_REGEX."(?:, *".self::$COUPLE_REGEX.")*)}";
671
- if (preg_match('/'.$regex.'/',$input,$resi)) {
672
- $this->addMessage('warning',$row,$key,'Usage of deprecated syntax %s','<span class="osh-formula">'.$resi[0].'</span>');
673
- while (preg_match('/'.$regex.'/',$input,$resi)) {
674
- switch ($resi[1]) {
675
- case 'products_quantity':
676
- $input = str_replace($resi[0],"{table {cart.weight} in ".$resi[2]."}*{cart.quantity}",$input);
677
- break;
678
- default:
679
- $input = str_replace($resi[0],"{table {cart.".$resi[1]."} in ".$resi[2]."}",$input);
680
- break;
681
- }
682
- }
683
- }
684
- }
685
- $row[$key]['value'] = $input;
686
- }
687
-
688
- protected function _parseInput() {
689
- $config_string = str_replace(
690
- array('&gt;','&lt;','“','”',utf8_encode(chr(147)),utf8_encode(chr(148)),'&laquo;','&raquo;',"\r\n"),
691
- array('>','<','"','"','"','"','"','"',"\n"),
692
- $this->_input
693
- );
694
-
695
- if (substr($config_string,0,2)=='$$') $config_string = $this->uncompress(substr($config_string,2,strlen($config_string)));
696
-
697
- $row_regex = '[ \\t]*([a-z0-9_]+)\\s*:\\s*("(?:(?:[^"]|\\\\")*[^\\\\])?"|'.self::$FLOAT_REGEX.'|false|true)\\s*(,)?[ \\t]*(?:\\n)?';
698
- preg_match_all('/((?:#+[^{\\n]*\\s+)*)\\s*(#)?{\\s*('.$row_regex.')+\\s*}/i',$config_string,$result,PREG_SET_ORDER);
699
-
700
- $this->_config = array();
701
- $available_keys = array(
702
- 'code','label','enabled','description','fees','conditions','destination','origin','customer_groups','tracking_url',
703
- 'fees_table','fees_formula','fixed_fees','reference_value',
704
- 'prices_range','weights_range','product_properties',
705
- 'free_shipping__fees_table','free_shipping__fees_formula','free_shipping__fixed_fees','free_shipping__label',
706
- );
707
-
708
- foreach ($result as $block) {
709
- $deprecated_properties = array();
710
- $unknown_properties = array();
711
- $missing_semicolon = array();
712
- $obsolete_disabling_method = array();
713
-
714
- //$before = strstr($config_string,$block[0],true); // Seulement compatible avec PHP 5.3.0
715
- list($before) = explode($block[0],$config_string,2);
716
- if ($before!==false && trim($before)!='') {
717
- $config_string = substr($config_string,strlen($before));
718
- $this->_addIgnoredLines(trim($before));
719
- $this->addMessage('info',$row=null,null,'Ignored lines %s','<div class="code">'.trim($before).'</div>');
720
- }
721
-
722
- $config_string = str_replace($block[0], '', $config_string);
723
- preg_match_all('/'.$row_regex.'/i',$block[0],$result2,PREG_SET_ORDER);
724
- $block_string = $block[0];
725
-
726
- $row = array();
727
- $i = 1;
728
- foreach ($result2 as $data) {
729
- $key = $data[1];
730
- if (in_array($key,$available_keys) || substr($key,0,1)=='_') {
731
- $property = $this->parseProperty($data[2]);
732
- if (isset($property)) {
733
- $row[$key] = array('value' => $property, 'original_value' => $property);
734
- $this->cleanProperty($row,$key);
735
- }
736
- if ($i>2) {
737
- $block_string = str_replace($data[0],$i==3 ? "...\n" : '',$block_string);
738
- }
739
- if ($i!=count($result2) && !isset($data[3]) || isset($data[3]) && $data[3]!=',') {
740
- if (preg_match('/^("|\')(.{40})(.*)("|\')$/s',$data[2],$resultx))
741
- $missing_semicolon[] = trim(str_replace($data[2],$resultx[1].$resultx[2].' ...'.$resultx[4],$data[0]));
742
- else $missing_semicolon[] = trim($data[0]);
743
- }
744
- } else {
745
- if (!in_array($key,$unknown_properties)) $unknown_properties[] = $key;
746
- }
747
- $i++;
748
- }
749
- if ($block[1]!='') $row['*comment']['value'] = $block[1];
750
- if ($block[2]=='#' && !isset($row['enabled'])) {
751
- $row['enabled'] = array('value' => false);
752
- $obsolete_disabling_method[] = $block_string;
753
- }
754
-
755
- $formula_fields_to_check = array();
756
- if (isset($row['conditions'])) $formula_fields_to_check[] = 'conditions';
757
- if (isset($row['fees'])) $formula_fields_to_check[] = 'fees';
758
-
759
- if (count($formula_fields_to_check)>0) {
760
- foreach ($formula_fields_to_check as $property) {
761
- $property_value = $row[$property]['value'];
762
- if (preg_match('/{ +/',$property_value)) {
763
- $this->addMessage('warning',$row,$property,'There are unwanted spaces after char `%s`','{');
764
- $property_value = preg_replace('/{ +/','{',$property_value);
765
- }
766
- if (preg_match('/ +}/',$property_value)) {
767
- $this->addMessage('warning',$row,$property,'There are unwanted spaces before char `%s`','}');
768
- $property_value = preg_replace('/ +}/','}',$property_value);
769
- }
770
- if (preg_match('/ +/',$property_value)) {
771
- $this->addMessage('warning',$row,$property,'There are unwanted multiples spaces `%s`',preg_replace('/( +)/','<span class="osh-formula">*$1*</span>',$property_value));
772
- $property_value = preg_replace('/ +/',' ',$property_value);
773
- }
774
- $row[$property]['value'] = trim($property_value);
775
- }
776
- }
777
-
778
- $float_value_regex = '\\s*('.self::$POSITIVE_FLOAT_REGEX.'|\*)\\s*';
779
- $conditions = array();
780
- if (isset($row['prices_range'])) {
781
- if (!in_array('prices_range',$deprecated_properties)) $deprecated_properties[] = 'prices_range';
782
-
783
- $result = $this->_getOptionsAndData($row['prices_range']['value']);
784
- $options = $result['options'];
785
- $prices_range = $result['data'];
786
-
787
- if (($options=='' || in_array($options,array('incl.tax','ttc')))
788
- && preg_match('/^\\s*(\[|\])?'.$float_value_regex.'=>'.$float_value_regex.'(\[|\])?\\s*$/',$prices_range,$result)) {
789
- $min_price_included = $result[1]=='[';
790
- $min_price = $result[2]=='*' ? -1 : (float)$result[2];
791
- $max_price = $result[3]=='*' ? -1 : (float)$result[3];
792
- $max_price_included = !isset($result[4]) || $result[4]==']' || $result[4]=='';
793
-
794
- $tax_included = $options!='' && in_array($options,array('incl.tax','ttc')) || isset($row['reference_value']) && $row['reference_value']['value']=='price_including_tax';
795
- $price = $tax_included ? '{cart.price_including_tax}' : '{cart.price_excluding_tax}';
796
-
797
- if ($min_price!=-1) $conditions[] = $price.'>'.($min_price_included ? '=' : '').$min_price;
798
- if ($max_price!=-1) $conditions[] = $price.'<'.($max_price_included ? '=' : '').$max_price;
799
- }
800
- else $this->addMessage('error',$row,null,'Unrecognized value of deprecated property %s %s','<span class="osh-key">prices_range</span>','<span class="osh-formula">'.$row['prices_range']['value'].'</span>');
801
- unset($row['prices_range']);
802
- }
803
- if (isset($row['weights_range'])) {
804
- if (!in_array('weights_range',$deprecated_properties)) $deprecated_properties[] = 'weights_range';
805
- if (preg_match('/^\\s*(\[|\])?'.$float_value_regex.'=>'.$float_value_regex.'(\[|\])?\\s*$/',$row['weights_range']['value'],$result)) {
806
- $min_weight_included = $result[1]=='[';
807
- $min_weight = $result[2]=='*' ? -1 : (float)$result[2];
808
- $max_weight = $result[3]=='*' ? -1 : (float)$result[3];
809
- $max_weight_included = !isset($result[4]) || $result[4]==']' || $result[4]=='';
810
-
811
- if ($min_weight!=-1) $conditions[] = '{cart.weight}>'.($min_weight_included ? '=' : '').$min_weight;
812
- if ($max_weight!=-1) $conditions[] = '{cart.weight}<'.($max_weight_included ? '=' : '').$max_weight;
813
- }
814
- else $this->addMessage('error',$row,null,'Unrecognized value of deprecated property %s %s','<span class="osh-key">weights_range</span>','<span class="osh-formula">'.$row['weights_range']['value'].'</span>');
815
- unset($row['weights_range']);
816
- }
817
- if (isset($row['product_properties'])) {
818
- if (!in_array('product_properties',$deprecated_properties)) $deprecated_properties[] = 'product_properties';
819
- $product_property_regex = "\\s*(and|or)? *\((?:(all|any|sum) )?(attribute|option) '([^'\)]+)' ?(==|=|<=|>=|<|>|!=) ?(".self::$FLOAT_REGEX."|true|false|'[^'\)]*')\)\\s*";
820
- if (preg_match('/^('.$product_property_regex.')+$/',$row['product_properties']['value'],$result)) {
821
- preg_match_all('/'.$product_property_regex.'/',$row['product_properties']['value'],$results,PREG_SET_ORDER);
822
- $product_properties_condition = '';
823
- foreach ($results as $result) {
824
- $and_or = $result[1];
825
- if ($and_or=='') $and_or = 'and';
826
- $any_all_sum = $result[2];
827
- if ($any_all_sum=='') $any_all_sum = 'any';
828
- $property_type = $result[3];
829
- $property_name = $result[4];
830
- $cmp_symbol = $result[5];
831
- if ($cmp_symbol=='=') $cmp_symbol = '==';
832
- $cmp_value = $result[6];
833
-
834
- $product_properties_condition .= $product_properties_condition=='' ? '' : ' '.$and_or.' ';
835
- switch ($any_all_sum) {
836
- case 'sum':
837
- $product_properties_condition .= "{sum product.".$property_type.".".$property_name."}".$cmp_symbol.$cmp_value;
838
- break;
839
- case 'all':
840
- $product_properties_condition .= "{count products where product.".$property_type.".".$property_name.$cmp_symbol.$cmp_value."}=={products_quantity}";
841
- break;
842
- case 'any':
843
- $product_properties_condition .= "{count products where product.".$property_type.".".$property_name.$cmp_symbol.$cmp_value."}>0";
844
- break;
845
- }
846
- }
847
- if ($product_properties_condition!='') $conditions[] = $product_properties_condition;
848
- }
849
- else $this->addMessage('error',$row,null,'Unrecognized value of deprecated property %s %s','<span class="osh-key">product_properties</span>','<span class="osh-formula">'.$row['product_properties']['value'].'</span>');
850
- unset($row['product_properties']);
851
- }
852
- if (count($conditions)>0) $row['conditions'] = array('value' => count($conditions)==1 ? $conditions[0] : '('.implode(') && (',$conditions).')');
853
-
854
- $fees = array();
855
- if (isset($row['fees_table'])) {
856
- if (!in_array('fees_table',$deprecated_properties)) $deprecated_properties[] = 'fees_table';
857
- $options_and_data = $this->_getOptionsAndData($row['fees_table']['value']);
858
- $options = $options_and_data['options'];
859
- $fees_table_string = $options_and_data['data'];
860
-
861
- $var = null;
862
- if ($options=='') $var = (isset($row['reference_value']) ? $row['reference_value']['value'] : 'weight');
863
- else if (in_array($options,array('incl.tax','ttc'))) $var = 'price_including_tax';
864
- else if (in_array($options,array('excl.tax','ht'))) $var = 'price_excluding_tax';
865
-
866
- if (isset($var)) {
867
- if ($var=='price') $var = 'price_excluding_tax';
868
- if ($var=='products_quantity') $var = 'quantity';
869
- if (preg_match('/^[[:space:]]*\*[[:space:]]*:[[:space:]]*('.$float_value_regex.')[[:space:]]*$/s',$fees_table_string,$result)) $fees[] = $result[1];
870
- else $fees[] = "{table {cart.".$var."} in ".str_replace(' ','',$fees_table_string)."}".($var=='quantity' ? '*{cart.quantity}' : '');
871
- }
872
- else $this->addMessage('error',$row,null,'Unrecognized value of deprecated property %s %s','<span class="osh-key">fees_table</span>','<span class="osh-formula">'.$row['fees_table']['value'].'</span>');
873
- unset($row['fees_table']);
874
- }
875
- if (isset($row['fees_formula'])) {
876
- if (!in_array('fees_formula',$deprecated_properties)) $deprecated_properties[] = 'fees_formula';
877
- $fees[] = str_replace(' ','',$row['fees_formula']['value']);
878
- unset($row['fees_formula']);
879
- }
880
- if (isset($row['fixed_fees'])) {
881
- if (!in_array('fixed_fees',$deprecated_properties)) $deprecated_properties[] = 'fixed_fees';
882
- if ($row['fixed_fees']['value']!=0 || count($fees)==0) $fees[] = str_replace(' ','',$row['fixed_fees']['value']);
883
- unset($row['fixed_fees']);
884
- }
885
- if (!isset($row['fees']) && count($fees)>0) $row['fees'] = array('value' => implode('+',$fees));
886
-
887
- $fs_fees = array();
888
- if (isset($row['free_shipping__fees_table'])) {
889
- if (!in_array('free_shipping__fees_table',$deprecated_properties)) $deprecated_properties[] = 'free_shipping__fees_table';
890
- $options_and_data = $this->_getOptionsAndData($row['free_shipping__fees_table']['value']);
891
- $options = $options_and_data['options'];
892
- $fees_table_string = $options_and_data['data'];
893
-
894
- $var = null;
895
- if ($options=='') $var = isset($row['reference_value']) ? $row['reference_value']['value'] : 'weight';
896
- else if (in_array($options,array('incl.tax','ttc'))) $var = 'price_including_tax';
897
- else if (in_array($options,array('excl.tax','ht'))) $var = 'price_excluding_tax';
898
- if ($var=='price') $var = 'price_excluding_tax';
899
-
900
- if (isset($var)) {
901
- if ($var=='price') $var = 'price_excluding_tax';
902
- if ($var=='products_quantity') $var = 'quantity';
903
- if (preg_match('/^[[:space:]]*\*[[:space:]]*:[[:space:]]*('.$float_value_regex.')[[:space:]]*$/s',$fees_table_string,$result)) $fs_fees[] = $result[1];
904
- else $fs_fees[] = "{table {cart.".$var."} in ".str_replace(' ','',$fees_table_string)."}".($var=='quantity' ? '*{cart.quantity}' : '');
905
- }
906
- else $this->addMessage('error',$row,null,'Unrecognized value of deprecated property %s %s','<span class="osh-key">free_shipping__fees_table</span>','<span class="osh-formula">'.$row['free_shipping__fees_table']['value'].'</span>');
907
- unset($row['free_shipping__fees_table']);
908
- }
909
- if (isset($row['free_shipping__fees_formula'])) {
910
- if (!in_array('free_shipping__fees_formula',$deprecated_properties)) $deprecated_properties[] = 'free_shipping__fees_formula';
911
- $fs_fees[] = str_replace(' ','',$row['free_shipping__fees_formula']['value']);
912
- unset($row['free_shipping__fees_formula']);
913
- }
914
- if (isset($row['free_shipping__fixed_fees'])) {
915
- if (!in_array('free_shipping__fixed_fees',$deprecated_properties)) $deprecated_properties[] = 'free_shipping__fixed_fees';
916
- if ($row['free_shipping__fixed_fees']['value']!=0 || count($fees)==0) $fs_fees[] = str_replace(' ','',$row['free_shipping__fixed_fees']['value']);
917
- unset($row['free_shipping__fixed_fees']);
918
- }
919
-
920
- if (isset($row['reference_value'])) {
921
- if (!in_array('reference_value',$deprecated_properties)) $deprecated_properties[] = 'reference_value';
922
- unset($row['reference_value']);
923
- }
924
-
925
- if (count($fs_fees)>0) {
926
- $row2 = $row;
927
- if (isset($row['code'])) $row2['code']['value'] = $row['code']['value'].'__free_shipping';
928
- $row2['fees']['value'] = implode('+',$fs_fees);
929
- $row2['conditions']['value'] = isset($row2['conditions']) ? '('.$row2['conditions']+') and {free_shipping}' : '{free_shipping}';
930
- $row['conditions']['value'] = isset($row['conditions']) ? '('.$row['conditions']+') and !{free_shipping}' : '!{free_shipping}';
931
- if (isset($row['free_shipping__label'])) {
932
- if (!in_array('free_shipping__label',$deprecated_properties)) $deprecated_properties[] = 'free_shipping__label';
933
- $row2['label']['value'] = $row['free_shipping__label']['value'];
934
- unset($row['free_shipping__label']);
935
- unset($row2['free_shipping__label']);
936
- }
937
- $this->_addRow($row2);
938
- }
939
- if (count($unknown_properties)>0) $this->addMessage('error',$row,null,'Usage of unknown properties %s',': <span class="osh-key">'.implode('</span>, <span class="osh-key">',$unknown_properties).'</span>');
940
- if (count($deprecated_properties)>0) $this->addMessage('warning',$row,null,'Usage of deprecated properties %s',': <span class="osh-key">'.implode('</span>, <span class="osh-key">',$deprecated_properties).'</span>');
941
- if (count($obsolete_disabling_method)>0) $this->addMessage('warning',$row,null,'Usage of obsolete method to disabling a shipping method (`#` before `{`)%s','<div class="code">'.implode('<br />',$obsolete_disabling_method).'</div>');
942
- if (count($missing_semicolon)>0) $this->addMessage('warning',$row,null,'A semicolon is missing at the end of following lines %s','<div class="code">'.implode('<br />',$missing_semicolon).'</div>');
943
- $this->_addRow($row);
944
- }
945
- if (trim($config_string)!='') {
946
- $this->_addIgnoredLines(trim($config_string));
947
- $row=null;$this->addMessage('info',$row,null,'Ignored lines %s','<div class="code">'.trim($config_string).'</div>');
948
- }
949
- }
950
-
951
- public function addMessage($type, &$row, $property) {
952
- $args = func_get_args();
953
- array_shift($args);
954
- array_shift($args);
955
- array_shift($args);
956
- $message = new DPDFranceRelais_Os_Message($type,$args);
957
- if (isset($row)) {
958
- if (isset($property)) {
959
- $row[$property]['messages'][] = $message;
960
- } else {
961
- $row['*messages'][] = $message;
962
- }
963
- }
964
- $this->_messages[] = $message;
965
- self::debug(' => <span class="osh-'.$message->type.'">'.$message->toString().'</span>',1);
966
- }
967
-
968
- protected function _addRow(&$row) {
969
- if (isset($row['code'])) {
970
- $key = $row['code']['value'];
971
- if (isset($this->_config[$key])) $this->addMessage('error',$row,'code','The property `code` must be unique, `%s` has been found twice',$key);
972
- while (isset($this->_config[$key])) $key .= rand(0,9);
973
- //$row['code'] = $key;
974
- } else {
975
- $i = 1;
976
- do {
977
- $key = 'code_auto'.sprintf('%03d',$i);
978
- $i++;
979
- } while (isset($this->_config[$key]));
980
- }
981
- $row['*code'] = $key;
982
- $this->_config[$key] = $row;
983
- }
984
-
985
- protected function _addIgnoredLines($lines) {
986
- $this->_config[] = array('lines' => $lines);
987
- }
988
-
989
- protected function _addressMatch($address_filter, $address) {
990
- $excluding = false;
991
- if (preg_match('# *\* *- *\((.*)\) *#s',$address_filter,$result)) {
992
- $address_filter = $result[1];
993
- $excluding = true;
994
- }
995
-
996
- $tmp_address_filter_array = explode(',',trim($address_filter));
997
-
998
- $concat = false;
999
- $concatened = '';
1000
- $address_filter_array = array();
1001
- $i = 0;
1002
-
1003
- foreach ($tmp_address_filter_array as $address_filter) {
1004
- if ($concat) $concatened .= ','.$address_filter;
1005
- else {
1006
- if ($i<count($tmp_address_filter_array)-1 && preg_match('#\(#',$address_filter)) {
1007
- $concat = true;
1008
- $concatened .= $address_filter;
1009
- } else $address_filter_array[] = $address_filter;
1010
- }
1011
- if (preg_match('#\)#',$address_filter)) {
1012
- $address_filter_array[] = $concatened;
1013
- $concatened = '';
1014
- $concat = false;
1015
- }
1016
- $i++;
1017
- }
1018
-
1019
- foreach ($address_filter_array as $address_filter) {
1020
- if (preg_match('# *([A-Z]{2}) *(-)? *(?:\( *(-)? *(.*)\))? *#s',$address_filter,$result)) {
1021
- $country_code = $result[1];
1022
- if ($address['country_code']==$country_code) {
1023
- self::debug(' country code <span class="osh-replacement">'.$address['country_code'].'</span> matches',5);
1024
- if (!isset($result[4]) || $result[4]=='') return !$excluding;
1025
- else {
1026
- $region_codes = explode(',',$result[4]);
1027
- $in_array = false;
1028
- for ($i=count($region_codes); --$i>=0;) {
1029
- $code = trim($region_codes[$i]);
1030
- $region_codes[$i] = $code;
1031
- if ($address['region_code']===$code) {
1032
- self::debug(' region code <span class="osh-replacement">'.$address['region_code'].'</span> matches',5);
1033
- $in_array = true;
1034
- } else if ($address['postcode']===$code) {
1035
- self::debug(' postcode <span class="osh-replacement">'.$address['postcode'].'</span> matches',5);
1036
- $in_array = true;
1037
- } else if (strpos($code,'*')!==false && preg_match('/^'.str_replace('*','(?:.*)',$code).'$/',$address['postcode'])) {
1038
- self::debug(' postcode <span class="osh-replacement">'.$address['postcode'].'</span> matches <span class="osh-formula">'.$code.'</span>',5);
1039
- $in_array = true;
1040
- }
1041
- if ($in_array) break;
1042
- }
1043
- if (!$in_array) {
1044
- self::debug(' region code <span class="osh-replacement">'.$address['region_code'].'</span> and postcode <span class="osh-replacement">'.$address['postcode'].'</span> don\'t match',5);
1045
- }
1046
- // Vérification stricte
1047
- // $in_array = in_array($address['region_code'],$region_codes,true) || in_array($address['postcode'],$region_codes,true);
1048
- $excluding_region = $result[2]=='-' || $result[3]=='-';
1049
- if ($excluding_region && !$in_array || !$excluding_region && $in_array) return !$excluding;
1050
- }
1051
- }
1052
- }
1053
- }
1054
- return $excluding;
1055
- }
1056
-
1057
- protected function _getProductProperty($product, $property_type, $property_name, $get_by_id=false) {
1058
- switch ($property_type) {
1059
- case 'attribute':
1060
- case 'attributes': return $product->getAttribute($property_name,$get_by_id);
1061
- case 'option':
1062
- case 'options': return $product->getOption($property_name,$get_by_id);
1063
- case 'stock': return $product->getStockData($property_name);
1064
- }
1065
- return null;
1066
- }
1067
-
1068
- protected function _processProductProperty($products, $regex_result) {
1069
- // COUNT, SUM or COUNT DISTINCT
1070
- $operation = strtolower($regex_result[1]);
1071
- switch ($operation) {
1072
- case 'sum':
1073
- case 'count distinct':
1074
- $property_type = $regex_result[2];
1075
- $property_name = $regex_result[3];
1076
- $conditions = isset($regex_result[4]) ? $regex_result[4] : null;
1077
- break;
1078
- case 'count':
1079
- $conditions = isset($regex_result[2]) ? $regex_result[2] : null;
1080
- break;
1081
- }
1082
-
1083
- self::debug(' :: start <span class="osh-replacement">'.$regex_result[0].'</span>',10);
1084
-
1085
- $return_value = 0;
1086
-
1087
- preg_match_all('/product\.(attribute(?:s)?|option(?:s)?|stock)\.([a-z0-9_]+)(?:\.(id))?/i',$conditions,$properties_regex_result,PREG_SET_ORDER);
1088
- $properties = array();
1089
- foreach ($properties_regex_result as $property_regex_result) {
1090
- $key = $property_regex_result[0];
1091
- if (!isset($properties[$key])) $properties[$key] = $property_regex_result;
1092
- }
1093
-
1094
- foreach ($products as $product) {
1095
- if (isset($conditions) && $conditions!='') {
1096
- $formula = $conditions;
1097
- foreach ($properties as $property) {
1098
- $value = $this->_getProductProperty(
1099
- $product,
1100
- $tmp_property_type = $property[1],
1101
- $tmp_property_name = $property[2],
1102
- $get_by_id = isset($property[3]) && $property[3]=='id'
1103
- );
1104
- //$formula = $this->replace($property[0],$value,$formula);
1105
- $from = $property[0];
1106
- $to = is_string($value) || empty($value) ? "'".$value."'" : $value;
1107
- $formula = str_replace($from,$to,$formula);
1108
- self::debug(' replace <span class="osh-replacement">'.$from.'</span> by <span class="osh-replacement">'.$to.'</span> =&gt; <span class="osh-formula">'.str_replace($from,'<span class="osh-replacement">'.$to.'</span>',$formula).'</span>',5);
1109
- }
1110
- $eval_result = $this->_evalFormula($formula);
1111
- if (!isset($eval_result)) return 'null';
1112
- }
1113
- else $eval_result = true;
1114
-
1115
- if ($eval_result==true) {
1116
- switch ($operation) {
1117
- case 'sum':
1118
- $value = $this->_getProductProperty($product,$property_type,$property_name);
1119
- //self::debug($product->getSku().'.'.$property_type.'.'.$property_name.' = "'.$value.'" x '.$product->getQuantity(),10);
1120
- $return_value += $value*$product->getQuantity();
1121
- break;
1122
- case 'count distinct':
1123
- if (!isset($distinct_values)) $distinct_values = array();
1124
- $value = $this->_getProductProperty($product,$property_type,$property_name);
1125
- if (!in_array($value,$distinct_values)) {
1126
- $distinct_values[] = $value;
1127
- $return_value++;
1128
- }
1129
- break;
1130
- case 'count':
1131
- $return_value += $product->getQuantity();
1132
- break;
1133
- }
1134
- }
1135
- }
1136
-
1137
- self::debug(' :: end <span class="osh-replacement">'.$regex_result[0].'</span>',10);
1138
-
1139
- return $return_value;
1140
- }
1141
-
1142
  }
1143
 
1144
  class DPDFranceRelais_Os_Message {
1145
- public $type;
1146
- public $message;
1147
- public $args;
1148
-
1149
- public function __construct($type, $args) {
1150
- $this->type = $type;
1151
- $this->message = array_shift($args);
1152
- $this->args = $args;
1153
- }
1154
-
1155
- public function toString() {
1156
- return vsprintf($this->message,$this->args);
1157
- }
1158
  }
1159
 
1160
  class DPDFranceRelais_Os_Result {
1161
- public $success;
1162
- public $result;
1163
 
1164
- public function __construct($success, $result=null) {
1165
- $this->success = $success;
1166
- $this->result = $result;
1167
- }
1168
 
1169
- public function __toString() {
1170
- return is_bool($this->result) ? ($this->result ? 'true' : 'false') : (string)$this->result;
1171
- }
1172
  }
1173
 
1174
 
1
  <?php
2
  /**
3
+ * DPD France v5.1.2 shipping module for Magento
4
  *
5
  * @category DPDFrance
6
  * @package DPDFrance_Shipping
7
+ * @author DPD France S.A.S. <ensavoirplus.ecommerce@dpd.fr>
8
+ * @copyright 2015 DPD France S.A.S., société par actions simplifiée, au capital de 18.500.000 euros, dont le siège social est situé 27 Rue du Colonel Pierre Avia - 75015 PARIS, immatriculée au registre du commerce et des sociétés de Paris sous le numéro 444 420 830
9
  * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
10
  */
11
 
12
  class DPDFrance_Relais_Model_Owebia
13
  {
14
+ public static $FLOAT_REGEX = '[-]?\d+(?:[.]\d+)?';
15
+ public static $POSITIVE_FLOAT_REGEX = '\d+(?:[.]\d+)?';
16
+ //public static $COUPLE_REGEX = '(?:[0-9.]+|\*)(?:\[|\])?\:[0-9.]+(?:\:[0-9.]+%?)*';
17
+ public static $COUPLE_REGEX = '(?:[0-9.]+|\*) *(?:\[|\])? *\: *[0-9.]+';
18
+ public static $UNCOMPRESSED_STRINGS = array(
19
+ ' product.attribute.',
20
+ ' product.option.',
21
+ ' product.stock.',
22
+ '{product.attribute.',
23
+ '{product.option.',
24
+ '{product.stock.',
25
+ '{product.weight}',
26
+ '{product.quantity}',
27
+ '{cart.weight}',
28
+ '{cart.quantity}',
29
+ '{cart.coupon}',
30
+ '{cart.price_including_tax}',
31
+ '{cart.price_excluding_tax}',
32
+ '{cart.',
33
+ '{customvar.',
34
+ '{selection.weight}',
35
+ '{selection.quantity}',
36
+ '{selection.',
37
+ '{shipto.country.',
38
+ '{foreach ',
39
+ '{/foreach}',
40
+ );
41
+ public static $COMPRESSED_STRINGS = array(
42
+ ' p.a.',
43
+ ' p.o.',
44
+ ' p.s.',
45
+ '{p.a.',
46
+ '{p.o.',
47
+ '{p.s.',
48
+ '{p.w}',
49
+ '{p.qty}',
50
+ '{c.w}',
51
+ '{c.qty}',
52
+ '{c.cpn}',
53
+ '{c.pit}',
54
+ '{c.pet}',
55
+ '{c.',
56
+ '{v.',
57
+ '{s.w}',
58
+ '{s.qty}',
59
+ '{s.',
60
+ '{dest.ctry.',
61
+ '{each ',
62
+ '{/each}',
63
+ );
64
+
65
+ protected $_input;
66
+ protected $_config;
67
+ protected $_messages;
68
+ protected $_formula_cache;
69
+ protected $_expression_cache;
70
+ protected $_overWeightMessage = 'Over weight';
71
+ public $debug = 0;
72
+ public $debug_output = '';
73
+ public $debug_header = null;
74
+
75
+ public function __construct($input) {
76
+ $this->_formula_cache = array();
77
+ $this->_messages = array();
78
+ $this->_input = $input;
79
+ $this->_config = array();
80
+ $this->_parseInput();
81
+ }
82
+
83
+ private function debug($text, $level=10) {
84
+ if ($this->debug>=$level) $this->debug_output .= "<p>".$text."</p>";
85
+ }
86
+
87
+ public function printDebug() {
88
+ if ($this->debug>0) echo "<style rel=\"stylesheet\" type=\"text/css\">"
89
+ .".osh-formula{color:#f90;} .osh-key{color:#0099f7;}"
90
+ .".osh-error{color:#f00;} .osh-warning{color:#ff0;} .osh-info{color:#7bf700;}"
91
+ .".osh-debug{background:#000;color:#bbb;position:absolute;top:0;left:0;width:100%;z-index:100;-moz-opacity:0.9;opacity:0.9;text-align:left;white-space:pre-wrap;}"
92
+ .".osh-debug-content{padding:10px;}"
93
+ .".osh-replacement{color:#ff3000;}"
94
+ ."</style>"
95
+ ."<div id=\"osh-debug\" class=\"osh-debug\"><pre class=\"osh-debug-content\"><span style=\"float:right;cursor:pointer;\" onclick=\"document.getElementById('osh-debug').style.display = 'none';\">[<span style=\"padding:0 5px;color:#f00;\">X</span>]</span>"
96
+ ."<p>".$this->debug_header."</p>".$this->debug_output."</pre></div>";
97
+ }
98
+
99
+ public function setDebugHeader($process) {
100
+ $header = 'DEBUG ' . __FILE__;//'DEBUG app/code/community/Owebia/Shipping/2/Model/Carrier/OwebiaShippingHelper.php<br/>';
101
+ foreach ($process['data'] as $key => $data) {
102
+ $header .= ' <span class="osh-key">'.$key.'</span> = <span class="osh-formula">'.$this->_toString($data).'</span><br/>';
103
+ }
104
+ $this->debug_header = $header;
105
+ }
106
+
107
+ public function getConfig() {
108
+ return $this->_config;
109
+ }
110
+
111
+ public function getMessages() {
112
+ $messages = $this->_messages;
113
+ $this->_messages = array();
114
+ return $messages;
115
+ }
116
+
117
+ public function formatConfig($compress) {
118
+ $output = '';
119
+ foreach ($this->_config as $code => $row) {
120
+ if (!isset($row['lines'])) {
121
+ if (isset($row['*comment']['value'])) {
122
+ $output .= trim($row['*comment']['value'])."\n";
123
+ }
124
+ $output .= '{'.($compress ? '' : "\n");
125
+ foreach ($row as $key => $property) {
126
+ if (substr($key,0,1)!='*') {
127
+ $value = $property['value'];
128
+ if (isset($property['comment'])) $output .= ($compress ? '' : "\t").'/* '.$property['comment'].' */'.($compress ? '' : "\n");
129
+ $output .= ($compress ? '' : "\t").$key.':'.($compress ? '' : ' ');
130
+ if (is_bool($value)) $output .= $value ? 'true' : 'false';
131
+ else if (is_int($value)) $output .= $value;
132
+ else if ((string)((float)$value)==$value) $output .= $value;
133
+ else $output .= '"'.str_replace('"','\\"',$value).'"';
134
+ $output .= ','.($compress ? '' : "\n");
135
+ }
136
+ }
137
+ if ($compress) $output = preg_replace('/,$/','',$output);
138
+ $output .= "}\n".($compress ? '' : "\n");
139
+ } else {
140
+ $output .= $row['lines']."\n";
141
+ }
142
+ }
143
+ return $compress ? $this->compress($output) : $this->uncompress($output);
144
+ }
145
+
146
+ public function checkConfig() {
147
+ $process = array(
148
+ 'result' => null,
149
+ 'data' => array(
150
+ 'cart.price_excluding_tax' => 0,
151
+ 'cart.price_including_tax' => 0,
152
  'cart.coupon' => '',
153
+ 'shipto.country.code' => '',
154
+ 'shipto.country.name' => '',
155
+ 'shipto.region.code' => '',
156
+ 'shipto.postal.code' => '',
157
+ 'origin.country.code' => '',
158
+ 'origin.country.name' => '',
159
+ 'origin.region.code' => '',
160
+ 'origin.postal.code' => '',
161
+ 'free_shipping' => false,
162
+ 'customer.group.id' => '',
163
+ 'customer.group.code' => '',
164
+ 'cart.weight' => 0,
165
+ 'cart.weight.unit' => 'kg',
166
+ 'cart.quantity' => 0,
167
+ ),
168
+ 'cart.items' => array(),
169
+ 'products' => array(),
170
+ 'config' => $this->_config,
171
+ );
172
+ foreach ($this->_config as $code => &$row) {
173
+ $this->processRow($process,$row,$check_all_conditions=true);
174
+ foreach ($row as $property_key => $property_value) {
175
+ if (substr($property_key,0,1)!='*') $this->getRowProperty($row,$property_key);
176
+ }
177
+ }
178
+ }
179
+
180
+ public function processRow($process, &$row, $is_checking=false) {
181
+ if (!isset($row['*code'])) return;
182
+
183
+ self::debug('process row <span class="osh-key">'.$row['*code'].'</span>',1);
184
+ if (!isset($row['label']['value'])) $row['label']['value'] = '';
185
+
186
+ $enabled = $this->getRowProperty($row,'enabled');
187
+ if (isset($enabled)) {
188
+ if (!$is_checking && !$enabled) {
189
+ $this->addMessage('info',$row,'enabled','Configuration disabled');
190
+ return new DPDFranceRelais_Os_Result(false);
191
+ }
192
+ }
193
+
194
+ $conditions = $this->getRowProperty($row,'conditions');
195
+ if (isset($conditions)) {
196
+ $result = $this->_processFormula($process,$row,'conditions',$conditions,$is_checking);
197
+ if (!$is_checking) {
198
+ if (!$result->success) return $result;
199
+ if (!$result->result) {
200
+ $this->addMessage('info',$row,'conditions',"The cart doesn't match conditions");
201
+ return new DPDFranceRelais_Os_Result(false);
202
+ }
203
+ }
204
+ }
205
+
206
+ $shipto = $this->getRowProperty($row,'shipto');
207
+ if (isset($shipto)) {
208
+ $shipto_match = $this->_addressMatch($shipto,array(
209
+ 'country_code' => $process['data']['shipto.country.code'],
210
+ 'region_code' => $process['data']['shipto.region.code'],
211
+ 'postcode' => $process['data']['shipto.postal.code']
212
+ ));
213
+ if (!$is_checking && !$shipto_match) {
214
+ $this->addMessage('info',$row,'shipto',"The shipping method doesn't cover the zone");
215
+ return new DPDFranceRelais_Os_Result(false);
216
+ }
217
+ }
218
+
219
+ $origin = $this->getRowProperty($row,'origin');
220
+ if (isset($origin)) {
221
+ $origin_match = $this->_addressMatch($origin,array(
222
+ 'country_code' => $process['data']['origin.country.code'],
223
+ 'region_code' => $process['data']['origin.region.code'],
224
+ 'postcode' => $process['data']['origin.postal.code']
225
+ ));
226
+ if (!$is_checking && !$origin_match) {
227
+ $this->addMessage('info',$row,'origin',"The shipping method doesn't match to shipping origin");
228
+ return new DPDFranceRelais_Os_Result(false);
229
+ }
230
+ }
231
+
232
+ $customer_groups = $this->getRowProperty($row,'customer_groups');
233
+ if (isset($customer_groups)) {
234
+ $groups = explode(',',$customer_groups);
235
+ $group_match = false;
236
+ //self::debug('code:'.$process['data']['customer.group.code'].', id:'.$process['data']['customer.group.id']);
237
+ foreach ($groups as $group) {
238
+ $group = trim($group);
239
+ if ($group==$process['data']['customer.group.code'] || is_int($group) && $group==$process['data']['customer.group.id'] || $group=='*') {
240
+ $group_match = true;
241
+ break;
242
+ }
243
+ }
244
+ if (!$is_checking && !$group_match) {
245
+ $this->addMessage('info',$row,'customer_groups',"The shipping method doesn't match to customer group (%s)",$process['data']['customer.group.code']);
246
+ return new DPDFranceRelais_Os_Result(false);
247
+ }
248
+ }
249
+
250
+ $fees = $this->getRowProperty($row,'fees');
251
+ if (isset($fees)) {
252
+ $result = $this->_processFormula($process,$row,'fees',$fees,$is_checking);
253
+ if (!$result->success) return $result;
254
+ self::debug(' => <span class="osh-info">result = <span class="osh-formula">'.$this->_toString($result->result).'</span>',1);
255
+ return new DPDFranceRelais_Os_Result(true,(float)$result->result);
256
+ }
257
+ return new DPDFranceRelais_Os_Result(false);
258
+ }
259
+
260
+ public function getRowProperty($row, $key, $original_row=null, $original_key=null) {
261
+ $property = null;
262
+ $output = null;
263
+ if (isset($original_row) && isset($original_key) && $original_row['*code']==$row['*code'] && $original_key==$key) {
264
+ $this->addMessage('error',$row,$key,'Infinite loop %s',"<span class=\"code\">{".$row['*code'].'.'.$key."}</span>");
265
+ return array('error' => 'Infinite loop');
266
+ }
267
+ if (isset($row[$key]['value'])) {
268
+ $property = $row[$key]['value'];
269
+ $output = $property;
270
+ $code = array_key_exists('*code', $row) ? $row['*code'] : NULL; self::debug(' get <span class="osh-key">'.$code.'</span>.<span class="osh-key">'.$key.'</span> = <span class="osh-formula">'.$this->_toString($property).'</span>',5);
271
+ preg_match_all('/{([a-z0-9_]+)\.([a-z0-9_]+)}/i',$output,$result_set,PREG_SET_ORDER);
272
+ foreach ($result_set as $result) {
273
+ list($original,$ref_code,$ref_key) = $result;
274
+ if (!in_array($ref_code,array('module','date','store','cart','product','selection','customvar'))) {
275
+ if ($ref_code==$row['code']['value'] && $ref_key==$key) {
276
+ $this->addMessage('error',$row,$key,'Infinite loop %s',"<span class=\"code\">".$original."</span>");
277
+ return null;
278
+ }
279
+ if (isset($this->_config[$ref_code][$ref_key]['value'])) {
280
+ $replacement = $this->getRowProperty($this->_config[$ref_code],$ref_key,
281
+ isset($original_row) ? $original_row : $row,isset($original_key) ? $original_key : $key);
282
+ if (is_array($replacement) && isset($replacement['error'])) {
283
+ return isset($original_row) ? $replacement : 'false';
284
+ }
285
+ } else {
286
+ $this->addMessage('error',$row,$key,'Non-existent property %s',"<span class=\"code\">".$original."</span>");
287
+ $replacement = 'null';
288
+ }
289
+ $output = $this->replace($original,$replacement,$output);
290
+ }
291
+ }
292
+ } else {
293
+ $code = array_key_exists('*code', $row) ? $row['*code'] : NULL; self::debug(' get <span class="osh-key">'.$code.'</span>.<span class="osh-key">'.$key.'</span> = <span class="osh-formula">null</span>',5);
294
+ }
295
+ return $output;
296
+ }
297
+
298
+ protected function _toString($value) {
299
+ if (!isset($value)) return 'null';
300
+ else if (is_bool($value)) return $value ? 'true' : 'false';
301
+ else return $value;
302
+ }
303
+
304
+ protected function replace($from, $to, $input) {
305
+ if ($from===$to) return $input;
306
+ if (strpos($input,$from)===false) return $input;
307
+ $to = $this->_toString($to);
308
+ self::debug(' replace <span class="osh-replacement">'.$this->_toString($from).'</span> by <span class="osh-replacement">'.$to.'</span> =&gt; <span class="osh-formula">'.str_replace($from,'<span class="osh-replacement">'.$to.'</span>',$input).'</span>',5);
309
+ return str_replace($from,$to,$input);
310
+ }
311
+
312
+ protected function _min() {
313
+ $args = func_get_args();
314
+ $min = null;
315
+ foreach ($args as $arg) {
316
+ if (isset($arg) && (!isset($min) || $min>$arg)) $min = $arg;
317
+ }
318
+ return $min;
319
+ }
320
+
321
+ protected function _max() {
322
+ $args = func_get_args();
323
+ $max = null;
324
+ foreach ($args as $arg) {
325
+ if (isset($arg) && (!isset($max) || $max<$arg)) $max = $arg;
326
+ }
327
+ return $max;
328
+ }
329
+
330
+ protected function _processFormula($process, &$row, $property_key, $formula_string, $is_checking, $use_cache=true)
331
+ {
332
+ $result = $this->_prepareFormula($process,$row,$property_key,$formula_string,$is_checking,$use_cache);
333
+ if (!$result->success) return $result;
334
+
335
+ $eval_result = $this->_evalFormula($result->result);
336
+ if ($result->result == 'null') {
337
+ $this->addMessage('over_weight',$row,$property_key, $this->_overWeightMessage);
338
+ $result = new DPDFranceRelais_Os_Result(false);
339
+ if ($use_cache) $this->setCache($formula_string,$result);
340
+ return $result;
341
+ }
342
+ if (!isset($eval_result)) {
343
+ $this->addMessage('error',$row,$property_key,'Invalid formula');
344
+ $result = new DPDFranceRelais_Os_Result(false);
345
+ if ($use_cache) $this->setCache($formula_string,$result);
346
+ return $result;
347
+ }
348
+ self::debug(' formula evaluation = <span class="osh-formula">'.$this->_toString($eval_result).'</span>',10);
349
+ $result = new DPDFranceRelais_Os_Result(true,$eval_result);
350
+ if ($use_cache) $this->setCache($formula_string,$result);
351
+ return $result;
352
+ }
353
+
354
+ public function evalInput($process, $row, $property_key, $input) {
355
+ $result = $this->_prepareFormula($process,$row,$property_key,$input,$is_checking=false,$use_cache=true);
356
+ return $result->success ? $result->result : $input;
357
+ }
358
+
359
+ protected function setCache($expression, $value) {
360
+ if ($value instanceof DPDFranceRelais_Os_Result) {
361
+ $this->_formula_cache[$expression] = $value;
362
+ self::debug(' cache <span class="osh-replacement">'.$expression.'</span> = <span class="osh-formula">'.$this->_toString($this->_formula_cache[$expression]).'</span>',10);
363
+ } else {
364
+ $value = $this->_toString($value);
365
+ $this->_expression_cache[$expression] = $value;
366
+ self::debug(' cache <span class="osh-replacement">'.$expression.'</span> = <span class="osh-formula">'.$value.'</span>',10);
367
+ }
368
+ }
369
+
370
+ protected function _prepareFormula($process, $row, $property_key, $formula_string, $is_checking, $use_cache=true)
371
+ {
372
+ if ($use_cache && isset($this->_formula_cache[$formula_string])) {
373
+ $result = $this->_formula_cache[$formula_string];
374
+ self::debug(' get cached formula <span class="osh-replacement">'.$formula_string.'</span> = <span class="osh-formula">'.$this->_toString($result->result).'</span>',10);
375
+ return $result;
376
+ }
377
+
378
+ $formula = $formula_string;
379
+ //self::debug(' formula = <span class="osh-formula">'.$formula.'</span>',10);
380
+
381
+ while (preg_match("#{foreach product\.((?:attribute|option)\.(?:[a-z0-9_]+))}(.*){/foreach}#i",$formula,$result)) {
382
+ $original = $result[0];
383
+ if ($use_cache && isset($this->_expression_cache[$original])) {
384
+ $replacement = $this->_expression_cache[$original];
385
+ self::debug(' get cached expression <span class="osh-replacement">'.$original.'</span> = <span class="osh-formula">'.$replacement.'</span>',10);
386
+ }
387
+ else {
388
+ $replacement = 0;
389
+ list($filter_property_type,$filter_property_name) = explode('.',$result[1]);
390
+ $selections = array();
391
+ self::debug(' :: foreach <span class="osh-key">'.$filter_property_type.'</span>.<span class="osh-key">'.$filter_property_name.'</span>',10);
392
+ foreach ($process['products'] as $product) {
393
+ $tmp_value = $this->_getProductProperty($product,$filter_property_type,$filter_property_name,$get_by_id=false);
394
+ self::debug(' products[<span class="osh-formula">'.$product->getName().'</span>].<span class="osh-key">'.$filter_property_type.'</span>.<span class="osh-key">'.$filter_property_name.'</span> = <span class="osh-formula">'.$this->_toString($tmp_value).'</span>',10);
395
+ $key = 'val_'.$tmp_value;
396
+ $sel = isset($selections[$key]) ? $selections[$key] : null;
397
+ $selections[$key]['products'][] = $product;
398
+ $selections[$key]['weight'] = (isset($sel['weight']) ? $sel['weight'] : 0)+$product->getAttribute('weight')*$product->getQuantity();
399
+ $selections[$key]['quantity'] = (isset($sel['quantity']) ? $sel['quantity'] : 0)+$product->getQuantity();
400
+ }
401
+ self::debug(' :: start foreach',10);
402
+ foreach ($selections as $selection) {
403
+ $process2 = $process;
404
+ $process2['products'] = $selection['products'];
405
+ $process2['data']['selection.quantity'] = $selection['quantity'];
406
+ $process2['data']['selection.weight'] = $selection['weight'];
407
+ $process_result = $this->_processFormula($process2,$row,$property_key,$result[2],$is_checking,$tmp_use_cache=false);
408
+ $replacement += $process_result->result;
409
+ }
410
+ self::debug(' :: end foreach <span class="osh-key">'.$filter_property_type.'</span>.<span class="osh-key">'.$filter_property_name.'</span>',10);
411
+ if ($use_cache) $this->setCache($original,$replacement);
412
+ }
413
+ $formula = $this->replace($original,$replacement,$formula);
414
+ }
415
+
416
+ $formula = str_replace(array("\n","\t"),array('',''),$formula);
417
+
418
+ while (preg_match("#{customvar\.([a-z0-9_]+)}#i",$formula,$result)) {
419
+ $original = $result[0];
420
+ $replacement = Mage::getModel('core/variable')->loadByCode($result[1])->getValue('plain');
421
+ $formula = $this->replace($original,$replacement,$formula);
422
+ }
423
+
424
+ $first_product = isset($process['products'][0]) ? $process['products'][0] : null;
425
+ if (!isset($process['data']['selection.weight'])) $process['data']['selection.weight'] = $process['data']['cart.weight'];
426
+ if (!isset($process['data']['selection.quantity'])) $process['data']['selection.quantity'] = $process['data']['cart.quantity'];
427
+ $process['data']['product.weight'] = isset($first_product) ? $first_product->getAttribute('weight') : 0;
428
+ $process['data']['product.quantity'] = isset($first_product) ? $first_product->getQuantity() : 0;
429
+
430
+ foreach ($process['data'] as $original => $replacement) {
431
+ $formula = $this->replace('{'.$original.'}',$replacement,$formula);
432
+ }
433
+
434
+ if (isset($first_product)) {
435
+ while (preg_match("#{product\.(attribute|option|stock)\.([a-z0-9_]+)}#i",$formula,$result)) {
436
+ $original = $result[0];
437
+ switch ($result[1]) {
438
+ case 'attribute': $replacement = $first_product->getAttribute($result[2]); break;
439
+ case 'option': $replacement = $first_product->getOption($result[2]); break;
440
+ case 'stock': $replacement = $first_product->getStockData($result[2]); break;
441
+ }
442
+ $formula = $this->replace($original,$replacement,$formula);
443
+ }
444
+ }
445
+
446
+ //while (preg_match("/{(count|all|any) (attribute|option) '([^'\)]+)' ?(==|<=|>=|<|>|!=) ?(".self::$FLOAT_REGEX."|true|false|'[^'\)]*')}/",$formula,$result)
447
+ // || preg_match("/{(sum|count distinct) (attribute|option) '([^'\)]+)'}/",$formula,$result))
448
+ while (preg_match("/{(count) products(?: where ([^}]+))?}/i",$formula,$result)
449
+ || preg_match("/{(sum|count distinct) product\.(attribute|option)\.([a-z0-9_]+)(?: where ([^}]+))?}/i",$formula,$result)) {
450
+ $original = $result[0];
451
+ if ($use_cache && isset($this->_expression_cache[$original])) {
452
+ $replacement = $this->_expression_cache[$original];
453
+ self::debug(' get cached expression <span class="osh-replacement">'.$original.'</span> = <span class="osh-formula">'.$replacement.'</span>',10);
454
+ }
455
+ else {
456
+ $replacement = $this->_processProductProperty($process['products'],$result);
457
+ if ($use_cache) $this->setCache($result[0],$replacement);
458
+ }
459
+ $formula = $this->replace($original,$replacement,$formula);
460
+ }
461
+
462
+ //while (preg_match("/{table '([^']+)' ([^}]+)}/",$formula,$result))
463
+ while (preg_match("/{table ([^}]+) in ([0-9\.:,\*\[\] ]+)}/i",$formula,$result)) {
464
+ $original = $result[0];
465
+ if ($use_cache && isset($this->_expression_cache[$original])) {
466
+ $replacement = $this->_expression_cache[$original];
467
+ self::debug(' get cached expression <span class="osh-replacement">'.$original.'</span> = <span class="osh-formula">'.$replacement.'</span>',10);
468
+ } else {
469
+ $reference_value = $this->_evalFormula($result[1]);
470
+ if (isset($reference_value)) {
471
+ $fees_table_string = $result[2];
472
+
473
+ if (!preg_match('#^'.self::$COUPLE_REGEX.'(?:, *'.self::$COUPLE_REGEX.')*$#',$fees_table_string)) {
474
+ $this->addMessage('error',$row,$property_key,'Error in table %s','<span class="osh-formula">'.htmlentities($result[0]).'</span>');
475
+ $result = new DPDFranceRelais_Os_Result(false);
476
+ if ($use_cache) $this->setCache($formula_string,$result);
477
+ return $result;
478
+ }
479
+ $fees_table = explode(',',$fees_table_string);
480
+
481
+ $replacement = null;
482
+ foreach ($fees_table as $item) {
483
+ $fee_data = explode(':',$item);
484
+
485
+ $fee = trim($fee_data[1]);
486
+ $max_value = trim($fee_data[0]);
487
+
488
+ $last_char = $max_value{strlen($max_value)-1};
489
+ if ($last_char=='[') $including_max_value = false;
490
+ else if ($last_char==']') $including_max_value = true;
491
+ else $including_max_value = true;
492
+
493
+ $max_value = str_replace(array('[',']'),'',$max_value);
494
+
495
+ if ($max_value=='*' || $including_max_value && $reference_value<=$max_value || !$including_max_value && $reference_value<$max_value) {
496
+ $replacement = $fee;//$this->_calculateFee($process,$fee,$var);
497
+ break;
498
+ }
499
+ }
500
+ }
501
+ $replacement = $this->_toString($replacement);
502
+ if ($use_cache) $this->setCache($original,$replacement);
503
+ }
504
+ $formula = $this->replace($original,$replacement,$formula);
505
+ }
506
+ $result = new DPDFranceRelais_Os_Result(true,$formula);
507
+ return $result;
508
+ }
509
+
510
+ protected function _evalFormula($formula) {
511
+ if (is_bool($formula)) return $formula;
512
+ if (!preg_match('/^(?:floor|ceil|round|max|min|rand|pow|pi|sqrt|log|exp|abs|int|float|true|false|null|and|or|in|substr|strtolower'
513
+ .'|in_array\(\'(?:[^\']*)\', *array\( *(?:\'(?:[^\']+)\') *(?: *, *\'(?:[^\']+)\')* *\) *\)'
514
+ .'|\'[^\']*\'|[0-9,\'\.\-\(\)\*\/\?\:\+\<\>\=\&\|%! ])*$/',$formula)) {
515
+ self::debug(' doesn\'t match',10);
516
+ return null;
517
+ }
518
+ $formula = str_replace(
519
+ array('min','max'),
520
+ array('$this->_min','$this->_max'),
521
+ $formula
522
+ );
523
+ $eval_result = null;
524
+ @eval('$eval_result = ('.$formula.');');
525
+ return $eval_result;
526
+ }
527
+
528
+ protected function _getOptionsAndData($string) {
529
+ if (preg_match('/^(\\s*\(\\s*([^\] ]*)\\s*\)\\s*)/',$string,$result)) {
530
+ $options = $result[2];
531
+ $data = str_replace($result[1],'',$string);
532
+ } else {
533
+ $options = '';
534
+ $data = $string;
535
+ }
536
+ return array(
537
+ 'options' => $options,
538
+ 'data' => $data,
539
+ );
540
+ }
541
+
542
+ public function compress($input) {
543
+ if (preg_match_all("/{table (.*) in (".self::$COUPLE_REGEX."(?:, *".self::$COUPLE_REGEX.")*)}/imsU",$input,$result,PREG_SET_ORDER)) {
544
+ foreach ($result as $result_i) {
545
+ $fees_table = explode(',',$result_i[2]);
546
+ $value = null;
547
+ foreach ($fees_table as $index => $item) {
548
+ list($max_value,$fee) = explode(':',$item);
549
+ $last_char = $max_value{strlen($max_value)-1};
550
+ if (in_array($last_char,array('[',']'))) {
551
+ $including_char = $last_char;
552
+ $max_value = str_replace(array('[',']'),'',$max_value);
553
+ } else $including_char = '';
554
+ $fees_table[$index] = ((float)$max_value).$including_char.':'.((float)$fee);
555
+ }
556
+ $input = str_replace($result_i[2],implode(',',$fees_table),$input);
557
+ $input = str_replace($result_i[1],trim($result_i[1]),$input);
558
+ }
559
+ }
560
+ if (preg_match_all("#{foreach ([^}]*)}(.*){/foreach}#imsU",$input,$result,PREG_SET_ORDER)) {
561
+ foreach ($result as $result_i) {
562
+ $input = str_replace($result_i[1],trim($result_i[1]),$input);
563
+ $input = str_replace($result_i[2],trim($result_i[2]),$input);
564
+ }
565
+ }
566
+ return '$$'.str_replace(
567
+ self::$UNCOMPRESSED_STRINGS,
568
+ self::$COMPRESSED_STRINGS,
569
+ $input
570
+ );
571
+ }
572
+
573
+ public function uncompress($input) {
574
+ if (preg_match_all("/{table (.*) in (".self::$COUPLE_REGEX."(?:, *".self::$COUPLE_REGEX.")*)}/iU",$input,$result,PREG_SET_ORDER)) {
575
+ foreach ($result as $result_i) {
576
+ $fees_table = explode(',',$result_i[2]);
577
+ $value = null;
578
+ foreach ($fees_table as $index => $item) {
579
+ list($max_value,$fee) = explode(':',$item);
580
+ $last_char = $max_value{strlen($max_value)-1};
581
+ if (in_array($last_char,array('[',']'))) {
582
+ $including_char = $last_char;
583
+ $max_value = str_replace(array('[',']'),'',$max_value);
584
+ } else $including_char = '';
585
+ $max_value = (float)$max_value;
586
+ $fee = (float)$fee;
587
+ $new_max_value = number_format($max_value,2,'.','');
588
+ $new_fee = number_format($fee,2,'.','');
589
+ $fees_table[$index] = (((float)$new_max_value)==$max_value ? $new_max_value : $max_value).$including_char.':'
590
+ .(((float)$new_fee)==$fee ? $new_fee : $fee);
591
+ }
592
+ $input = str_replace($result_i[2],implode(', ',$fees_table),$input);
593
+ $input = str_replace($result_i[1],trim($result_i[1]),$input);
594
+ }
595
+ }
596
+ if (preg_match_all("#{foreach ([^}]*)}(.*){/foreach}#iU",$input,$result,PREG_SET_ORDER)) {
597
+ foreach ($result as $result_i) {
598
+ $input = str_replace($result_i[1],trim($result_i[1]),$input);
599
+ $input = str_replace($result_i[2],trim($result_i[2]),$input);
600
+ }
601
+ }
602
+ return str_replace(
603
+ self::$COMPRESSED_STRINGS,
604
+ self::$UNCOMPRESSED_STRINGS,
605
+ $input
606
+ );
607
+ }
608
+
609
+ public function parseProperty($input) {
610
+ $value = $input==='false' || $input==='true' ? $input=='true' : str_replace('\"','"',preg_replace('/^(?:"|\')(.*)(?:"|\')$/s','$1',$input));
611
+ return $value==='' ? null : $value;
612
+ }
613
+
614
+ public function cleanProperty(&$row, $key) {
615
+ $input = $row[$key]['value'];
616
+ if (is_string($input)) {
617
+ $input = str_replace(array("\n"),array(''),$input);
618
+ while (preg_match('/({TABLE |{SUM |{COUNT | DISTINCT | IN )/',$input,$resi)) {
619
+ $input = str_replace($resi[0],strtolower($resi[0]),$input);
620
+ }
621
+
622
+ while (preg_match('/{{customVar code=([a-zA-Z0-9_-]+)}}/',$input,$resi)) {
623
+ $input = str_replace($resi[0],'{customvar.'.$resi[1].'}',$input);
624
+ }
625
+
626
+ $regex = "{(weight|products_quantity|price_including_tax|price_excluding_tax|country)}";
627
+ if (preg_match('/'.$regex.'/',$input,$resi)) {
628
+ $this->addMessage('warning',$row,$key,'Usage of deprecated syntax %s','<span class="osh-formula">'.$resi[0].'</span>');
629
+ while (preg_match('/'.$regex.'/',$input,$resi)) {
630
+ switch ($resi[1]) {
631
+ case 'price_including_tax':
632
+ case 'price_excluding_tax':
633
+ case 'weight':
634
+ $input = str_replace($resi[0],"{cart.".$resi[1]."}",$input);
635
+ break;
636
+ case 'products_quantity': $input = str_replace($resi[0],"{cart.quantity}",$input); break;
637
+ case 'country': $input = str_replace($resi[0],"{shipto.country.name}",$input); break;
638
+ }
639
+ }
640
+ }
641
+
642
+ $regex1 = "{copy '([a-zA-Z0-9_]+)'\.'([a-zA-Z0-9_]+)'}";
643
+ if (preg_match('/'.$regex1.'/',$input,$resi)) {
644
+ $this->addMessage('warning',$row,$key,'Usage of deprecated syntax %s','<span class="osh-formula">'.$resi[0].'</span>');
645
+ while (preg_match('/'.$regex1.'/',$input,$resi)) $input = str_replace($resi[0],'{'.$resi[1].'.'.$resi[2].'}',$input);
646
+ }
647
+
648
+ $regex1 = "{(count|all|any) (attribute|option) '([^'\)]+)' ?((?:==|<=|>=|<|>|!=) ?(?:".self::$FLOAT_REGEX."|true|false|'[^'\)]*'))}";
649
+ $regex2 = "{(sum) (attribute|option) '([^'\)]+)'}";
650
+ if (preg_match('/'.$regex1.'/',$input,$resi) || preg_match('/'.$regex2.'/',$input,$resi)) {
651
+ $this->addMessage('warning',$row,$key,'Usage of deprecated syntax %s','<span class="osh-formula">'.$resi[0].'</span>');
652
+ while (preg_match('/'.$regex1.'/',$input,$resi) || preg_match('/'.$regex2.'/',$input,$resi)) {
653
+ switch ($resi[1]) {
654
+ case 'count': $input = str_replace($resi[0],"{count products where product.".$resi[2]."s.".$resi[3].$resi[4]."}",$input); break;
655
+ case 'all': $input = str_replace($resi[0],"{count products where product.".$resi[2]."s.".$resi[3].$resi[4]."}=={products_quantity}",$input); break;
656
+ case 'any': $input = str_replace($resi[0],"{count products where product.".$resi[2]."s.".$resi[3].$resi[4]."}>0",$input); break;
657
+ case 'sum': $input = str_replace($resi[0],"{sum product.".$resi[2].".".$resi[3]."}",$input); break;
658
+ }
659
+ }
660
+ }
661
+
662
+ $regex = "((?:{| )product.(?:attribute|option))s.";
663
+ if (preg_match('/'.$regex.'/',$input,$resi)) {
664
+ $this->addMessage('warning',$row,$key,'Usage of deprecated syntax %s','<span class="osh-formula">'.$resi[0].'</span>');
665
+ while (preg_match('/'.$regex.'/',$input,$resi)) {
666
+ $input = str_replace($resi[0],$resi[1].'.',$input);
667
+ }
668
+ }
669
+
670
+ $regex = "{table '([^']+)' (".self::$COUPLE_REGEX."(?:, *".self::$COUPLE_REGEX.")*)}";
671
+ if (preg_match('/'.$regex.'/',$input,$resi)) {
672
+ $this->addMessage('warning',$row,$key,'Usage of deprecated syntax %s','<span class="osh-formula">'.$resi[0].'</span>');
673
+ while (preg_match('/'.$regex.'/',$input,$resi)) {
674
+ switch ($resi[1]) {
675
+ case 'products_quantity':
676
+ $input = str_replace($resi[0],"{table {cart.weight} in ".$resi[2]."}*{cart.quantity}",$input);
677
+ break;
678
+ default:
679
+ $input = str_replace($resi[0],"{table {cart.".$resi[1]."} in ".$resi[2]."}",$input);
680
+ break;
681
+ }
682
+ }
683
+ }
684
+ }
685
+ $row[$key]['value'] = $input;
686
+ }
687
+
688
+ protected static function json_decode($input)
689
+ {
690
+ if (function_exists('json_decode')) { // PHP >= 5.2.0
691
+ $output = json_decode($input);
692
+ if (function_exists('json_last_error')) { // PHP >= 5.3.0
693
+ $error = json_last_error();
694
+ if ($error!=JSON_ERROR_NONE) throw new Exception($error);
695
+ }
696
+ return $output;
697
+ } else {
698
+ return Zend_Json::decode($input);
699
+ }
700
+ }
701
+
702
+ protected function _parseInput() {
703
+ $config_string = str_replace(
704
+ array('&gt;','&lt;','','”',utf8_encode(chr(147)),utf8_encode(chr(148)),'&laquo;','&raquo;',"\r\n"),
705
+ array('>','<','"','"','"','"','"','"',"\n"),
706
+ $this->_input
707
+ );
708
+
709
+ if (substr($config_string,0,2)=='$$') $config_string = $this->uncompress(substr($config_string,2,strlen($config_string)));
710
+
711
+ $config = self::json_decode($config_string);
712
+ $config = (array)$config;
713
+
714
+ $this->_config = array();
715
+ $available_keys = array('type', 'label', 'enabled', 'fees', 'conditions', 'shipto', 'origin', 'customer_groups');
716
+ $reserved_keys = array('*code');
717
+
718
+ $deprecated_properties = array();
719
+ $unknown_properties = array();
720
+
721
+ foreach ($config as $code => $object) {
722
+ $object = (array)$object;
723
+ $row = array();
724
+ $i = 1;
725
+ foreach ($object as $property_name => $property_value)
726
+ {
727
+ if (in_array($property_name, $reserved_keys))
728
+ continue;
729
+ if (in_array($property_name, $available_keys)
730
+ || substr($property_name, 0, 1)=='_'
731
+ || in_array($object['type'], array('data', 'meta')))
732
+ {
733
+ if (isset($property_value))
734
+ $row[$property_name] = array('value' => $property_value, 'original_value' => $property_value);
735
+ }
736
+ else
737
+ if (!in_array($property_name, $unknown_properties)) $unknown_properties[] = $property_name;
738
+ $i++;
739
+ }
740
+ $this->_addRow($row);
741
+ }
742
+ $row = null;
743
+ if (count($unknown_properties)>0)
744
+ $this->addMessage('error', $row, null, 'Usage of unknown properties %s', ': <span class=osh-key>'.implode('</span>, <span class=osh-key>', $unknown_properties).'</span>');
745
+ if (count($deprecated_properties)>0)
746
+ $this->addMessage('warning', $row, null, 'Usage of deprecated properties %s', ': <span class=osh-key>'.implode('</span>, <span class=osh-key>', $deprecated_properties).'</span>');
747
+ }
748
+
749
+ public function addMessage($type, &$row, $property) {
750
+ $args = func_get_args();
751
+ array_shift($args);
752
+ array_shift($args);
753
+ array_shift($args);
754
+ $message = new DPDFranceRelais_Os_Message($type,$args);
755
+ if (isset($row)) {
756
+ if (isset($property)) {
757
+ $row[$property]['messages'][] = $message;
758
+ } else {
759
+ $row['*messages'][] = $message;
760
+ }
761
+ }
762
+ $this->_messages[] = $message;
763
+ self::debug(' => <span class="osh-'.$message->type.'">'.$message->toString().'</span>',1);
764
+ }
765
+
766
+ protected function _addRow(&$row) {
767
+ if (isset($row['code'])) {
768
+ $key = $row['code']['value'];
769
+ if (isset($this->_config[$key])) $this->addMessage('error',$row,'code','The property `code` must be unique, `%s` has been found twice',$key);
770
+ while (isset($this->_config[$key])) $key .= rand(0,9);
771
+ //$row['code'] = $key;
772
+ } else {
773
+ $i = 1;
774
+ do {
775
+ $key = 'code_auto'.sprintf('%03d',$i);
776
+ $i++;
777
+ } while (isset($this->_config[$key]));
778
+ }
779
+ $row['*code'] = $key;
780
+ $this->_config[$key] = $row;
781
+ }
782
+
783
+ protected function _addIgnoredLines($lines) {
784
+ $this->_config[] = array('lines' => $lines);
785
+ }
786
+
787
+ protected function _addressMatch($address_filter, $address) {
788
+ $excluding = false;
789
+ if (preg_match('# *\* *- *\((.*)\) *#s',$address_filter,$result)) {
790
+ $address_filter = $result[1];
791
+ $excluding = true;
792
+ }
793
+
794
+ $tmp_address_filter_array = explode(',',trim($address_filter));
795
+
796
+ $concat = false;
797
+ $concatened = '';
798
+ $address_filter_array = array();
799
+ $i = 0;
800
+
801
+ foreach ($tmp_address_filter_array as $address_filter) {
802
+ if ($concat) $concatened .= ','.$address_filter;
803
+ else {
804
+ if ($i<count($tmp_address_filter_array)-1 && preg_match('#\(#',$address_filter)) {
805
+ $concat = true;
806
+ $concatened .= $address_filter;
807
+ } else $address_filter_array[] = $address_filter;
808
+ }
809
+ if (preg_match('#\)#',$address_filter)) {
810
+ $address_filter_array[] = $concatened;
811
+ $concatened = '';
812
+ $concat = false;
813
+ }
814
+ $i++;
815
+ }
816
+
817
+ foreach ($address_filter_array as $address_filter) {
818
+ if (preg_match('# *([A-Z]{2}) *(-)? *(?:\( *(-)? *(.*)\))? *#s',$address_filter,$result)) {
819
+ $country_code = $result[1];
820
+ if ($address['country_code']==$country_code) {
821
+ self::debug(' country code <span class="osh-replacement">'.$address['country_code'].'</span> matches',5);
822
+ if (!isset($result[4]) || $result[4]=='') return !$excluding;
823
+ else {
824
+ $region_codes = explode(',',$result[4]);
825
+ $in_array = false;
826
+ for ($i=count($region_codes); --$i>=0;) {
827
+ $code = trim($region_codes[$i]);
828
+ $region_codes[$i] = $code;
829
+ if ($address['region_code']===$code) {
830
+ self::debug(' region code <span class="osh-replacement">'.$address['region_code'].'</span> matches',5);
831
+ $in_array = true;
832
+ } else if ($address['postcode']===$code) {
833
+ self::debug(' postcode <span class="osh-replacement">'.$address['postcode'].'</span> matches',5);
834
+ $in_array = true;
835
+ } else if (strpos($code,'*')!==false && preg_match('/^'.str_replace('*','(?:.*)',$code).'$/',$address['postcode'])) {
836
+ self::debug(' postcode <span class="osh-replacement">'.$address['postcode'].'</span> matches <span class="osh-formula">'.$code.'</span>',5);
837
+ $in_array = true;
838
+ }
839
+ if ($in_array) break;
840
+ }
841
+ if (!$in_array) {
842
+ self::debug(' region code <span class="osh-replacement">'.$address['region_code'].'</span> and postcode <span class="osh-replacement">'.$address['postcode'].'</span> don\'t match',5);
843
+ }
844
+ // Vérification stricte
845
+ // $in_array = in_array($address['region_code'],$region_codes,true) || in_array($address['postcode'],$region_codes,true);
846
+ $excluding_region = $result[2]=='-' || $result[3]=='-';
847
+ if ($excluding_region && !$in_array || !$excluding_region && $in_array) return !$excluding;
848
+ }
849
+ }
850
+ }
851
+ }
852
+ return $excluding;
853
+ }
854
+
855
+ protected function _getProductProperty($product, $property_type, $property_name, $get_by_id=false) {
856
+ switch ($property_type) {
857
+ case 'attribute':
858
+ case 'attributes': return $product->getAttribute($property_name,$get_by_id);
859
+ case 'option':
860
+ case 'options': return $product->getOption($property_name,$get_by_id);
861
+ case 'stock': return $product->getStockData($property_name);
862
+ }
863
+ return null;
864
+ }
865
+
866
+ protected function _processProductProperty($products, $regex_result) {
867
+ // COUNT, SUM or COUNT DISTINCT
868
+ $operation = strtolower($regex_result[1]);
869
+ switch ($operation) {
870
+ case 'sum':
871
+ case 'count distinct':
872
+ $property_type = $regex_result[2];
873
+ $property_name = $regex_result[3];
874
+ $conditions = isset($regex_result[4]) ? $regex_result[4] : null;
875
+ break;
876
+ case 'count':
877
+ $conditions = isset($regex_result[2]) ? $regex_result[2] : null;
878
+ break;
879
+ }
880
+
881
+ self::debug(' :: start <span class="osh-replacement">'.$regex_result[0].'</span>',10);
882
+
883
+ $return_value = 0;
884
+
885
+ preg_match_all('/product\.(attribute(?:s)?|option(?:s)?|stock)\.([a-z0-9_]+)(?:\.(id))?/i',$conditions,$properties_regex_result,PREG_SET_ORDER);
886
+ $properties = array();
887
+ foreach ($properties_regex_result as $property_regex_result) {
888
+ $key = $property_regex_result[0];
889
+ if (!isset($properties[$key])) $properties[$key] = $property_regex_result;
890
+ }
891
+
892
+ foreach ($products as $product) {
893
+ if (isset($conditions) && $conditions!='') {
894
+ $formula = $conditions;
895
+ foreach ($properties as $property) {
896
+ $value = $this->_getProductProperty(
897
+ $product,
898
+ $tmp_property_type = $property[1],
899
+ $tmp_property_name = $property[2],
900
+ $get_by_id = isset($property[3]) && $property[3]=='id'
901
+ );
902
+ //$formula = $this->replace($property[0],$value,$formula);
903
+ $from = $property[0];
904
+ $to = is_string($value) || empty($value) ? "'".$value."'" : $value;
905
+ $formula = str_replace($from,$to,$formula);
906
+ self::debug(' replace <span class="osh-replacement">'.$from.'</span> by <span class="osh-replacement">'.$to.'</span> =&gt; <span class="osh-formula">'.str_replace($from,'<span class="osh-replacement">'.$to.'</span>',$formula).'</span>',5);
907
+ }
908
+ $eval_result = $this->_evalFormula($formula);
909
+ if (!isset($eval_result)) return 'null';
910
+ }
911
+ else $eval_result = true;
912
+
913
+ if ($eval_result==true) {
914
+ switch ($operation) {
915
+ case 'sum':
916
+ $value = $this->_getProductProperty($product,$property_type,$property_name);
917
+ //self::debug($product->getSku().'.'.$property_type.'.'.$property_name.' = "'.$value.'" x '.$product->getQuantity(),10);
918
+ $return_value += $value*$product->getQuantity();
919
+ break;
920
+ case 'count distinct':
921
+ if (!isset($distinct_values)) $distinct_values = array();
922
+ $value = $this->_getProductProperty($product,$property_type,$property_name);
923
+ if (!in_array($value,$distinct_values)) {
924
+ $distinct_values[] = $value;
925
+ $return_value++;
926
+ }
927
+ break;
928
+ case 'count':
929
+ $return_value += $product->getQuantity();
930
+ break;
931
+ }
932
+ }
933
+ }
934
+
935
+ self::debug(' :: end <span class="osh-replacement">'.$regex_result[0].'</span>',10);
936
+
937
+ return $return_value;
938
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
939
  }
940
 
941
  class DPDFranceRelais_Os_Message {
942
+ public $type;
943
+ public $message;
944
+ public $args;
945
+
946
+ public function __construct($type, $args) {
947
+ $this->type = $type;
948
+ $this->message = array_shift($args);
949
+ $this->args = $args;
950
+ }
951
+
952
+ public function toString() {
953
+ return vsprintf($this->message,$this->args);
954
+ }
955
  }
956
 
957
  class DPDFranceRelais_Os_Result {
958
+ public $success;
959
+ public $result;
960
 
961
+ public function __construct($success, $result=null) {
962
+ $this->success = $success;
963
+ $this->result = $result;
964
+ }
965
 
966
+ public function __toString() {
967
+ return is_bool($this->result) ? ($this->result ? 'true' : 'false') : (string)$this->result;
968
+ }
969
  }
970
 
971
 
app/code/community/DPDFrance/Relais/controllers/PickupController.php CHANGED
@@ -1,11 +1,11 @@
1
  <?php
2
  /**
3
- * DPD France v5.1.0 shipping module for Magento
4
  *
5
  * @category DPDFrance
6
  * @package DPDFrance_Shipping
7
- * @author DPD S.A.S. <ensavoirplus.ecommerce@dpd.fr>
8
- * @copyright 2015 DPD S.A.S., société par actions simplifiée, au capital de 18.500.000 euros, dont le siège social est situé 27 Rue du Colonel Pierre Avia - 75015 PARIS, immatriculée au registre du commerce et des sociétés de Paris sous le numéro 444 420 830
9
  * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
10
  */
11
 
1
  <?php
2
  /**
3
+ * DPD France v5.1.2 shipping module for Magento
4
  *
5
  * @category DPDFrance
6
  * @package DPDFrance_Shipping
7
+ * @author DPD France S.A.S. <ensavoirplus.ecommerce@dpd.fr>
8
+ * @copyright 2015 DPD France S.A.S., société par actions simplifiée, au capital de 18.500.000 euros, dont le siège social est situé 27 Rue du Colonel Pierre Avia - 75015 PARIS, immatriculée au registre du commerce et des sociétés de Paris sous le numéro 444 420 830
9
  * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
10
  */
11
 
app/code/community/DPDFrance/Relais/etc/config.xml CHANGED
@@ -1,12 +1,12 @@
1
  <?xml version="1.0" encoding="UTF-8"?>
2
  <!--
3
  /**
4
- * DPD France v5.1.0 shipping module for Magento
5
  *
6
  * @category DPDFrance
7
  * @package DPDFrance_Shipping
8
- * @author DPD S.A.S. <ensavoirplus.ecommerce@dpd.fr>
9
- * @copyright 2015 DPD S.A.S., société par actions simplifiée, au capital de 18.500.000 euros, dont le siège social est situé 27 Rue du Colonel Pierre Avia - 75015 PARIS, immatriculée au registre du commerce et des sociétés de Paris sous le numéro 444 420 830
10
  * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
11
  */
12
  -->
@@ -24,50 +24,31 @@
24
  <indentifier>EXA</indentifier>
25
  <key>deecd7bc81b71fcc0e292b53e826c48f</key>
26
  <expense>
27
- # Franco de port à 89€ sauf Corse
28
  {
29
- destination: "FR-(2A,2B),MC",
30
- conditions: "{cart.price_including_tax}>=89",
31
- fees: 0.00
32
- }
33
- # Zones de montagne
34
- {
35
- destination: "FR(04120,04130,04140,04160,04170,04200,04240,04260,04300,04310,04330,04360,04370,04400,04510,04530,04600,04700,04850,05100,05110,05120,05130,05150,05160,05170,05200,05220,05240,05250,05260,05290,05300,05310,05320,05330,05340,05350,05400,05460,05470,05500,05560,05600,05700,05800,06140,06380,06390,06410,06420,06430,06450,06470,06530,06540,06620,06710,06750,06910,09110,09140,09300,09460,25120,25140,25240,25370,25450,25500,25650,30570,31110,38112,38114,38142,38190,38250,38350,38380,38410,38580,38660,38700,38750,38860,38880,39220,39310,39400,63113,63210,63240,63610,63660,63690,63840,63850,64440,64490,64560,64570,65110,65120,65170,65200,65240,65400,65510,65710,66210,66760,66800,68140,68610,68650,73110,73120,73130,73140,73150,73160,73170,73190,73210,73220,73230,73250,73260,73270,73300,73320,73340,73350,73390,73400,73440,73450,73460,73470,73500,73530,73550,73590,73600,73620,73630,73640,73710,73720,73870,74110,74120,74170,74220,74230,74260,74310,74340,74350,74360,74390,74400,74420,74430,74440,74450,74470,74480,74660,74740,74920,83111,83440,83530,83560,83630,83690,83830,83840,84390,88310,88340,88370,88400,90200)",
36
- fees: "5+{table {cart.weight} in
37
- 0.5:5.30,
38
- 1.0:6.50,
39
- 2.0:7.40,
40
- 3.0:8.30,
41
- 5.0:10.10,
42
- 10.0:12.50,
43
- 20.0:15.00,
44
- 30.0:18.00}",
45
- }
46
- # Zones Iles et Corse
47
- {
48
- destination: "FR(20*,17111,17123,17190,17310,17370,17410,17480,17550,17580,17590,17630,17650,17670,17740,17840,17880,17940,22870,29242,29253,29259,29980,29990,56360,56590,56780,56840,85350)",
49
- fees: "16+{table {cart.weight} in
50
- 0.5:5.30,
51
- 1.0:6.50,
52
- 2.0:7.40,
53
- 3.0:8.30,
54
- 5.0:10.10,
55
- 10.0:12.50,
56
- 20.0:15.00,
57
- 30.0:18.00}",
58
- }
59
- # Zone France et Monaco
60
- {
61
- destination: "FR,MC",
62
- fees: "{table {cart.weight} in
63
- 0.5:5.30,
64
- 1.0:6.50,
65
- 2.0:7.40,
66
- 3.0:8.30,
67
- 5.0:10.10,
68
- 10.0:12.50,
69
- 20.0:15.00,
70
- 30.0:18.00}",
71
  }
72
  </expense>
73
  </dpdfrrelais>
@@ -75,7 +56,7 @@
75
  </default>
76
  <modules>
77
  <DPDFrance_Relais>
78
- <version>5.1.1</version>
79
  <depends>
80
  <Mage_Shipping/>
81
  </depends>
1
  <?xml version="1.0" encoding="UTF-8"?>
2
  <!--
3
  /**
4
+ * DPD France v5.1.2 shipping module for Magento
5
  *
6
  * @category DPDFrance
7
  * @package DPDFrance_Shipping
8
+ * @author DPD France S.A.S. <ensavoirplus.ecommerce@dpd.fr>
9
+ * @copyright 2015 DPD France S.A.S., société par actions simplifiée, au capital de 18.500.000 euros, dont le siège social est situé 27 Rue du Colonel Pierre Avia - 75015 PARIS, immatriculée au registre du commerce et des sociétés de Paris sous le numéro 444 420 830
10
  * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
11
  */
12
  -->
24
  <indentifier>EXA</indentifier>
25
  <key>deecd7bc81b71fcc0e292b53e826c48f</key>
26
  <expense>
 
27
  {
28
+ "Franco de port à 89€ sauf Corse":
29
+ {
30
+ "shipto": "FR-(2A,2B),MC",
31
+ "conditions": "{cart.price_including_tax}>=89",
32
+ "fees": 0.00
33
+ },
34
+
35
+ "Zones de montagne":
36
+ {
37
+ "shipto": "FR(04120,04130,04140,04160,04170,04200,04240,04260,04300,04310,04330,04360,04370,04400,04510,04530,04600,04700,04850,05100,05110,05120,05130,05150,05160,05170,05200,05220,05240,05250,05260,05290,05300,05310,05320,05330,05340,05350,05400,05460,05470,05500,05560,05600,05700,05800,06140,06380,06390,06410,06420,06430,06450,06470,06530,06540,06620,06710,06750,06910,09110,09140,09300,09460,25120,25140,25240,25370,25450,25500,25650,30570,31110,38112,38114,38142,38190,38250,38350,38380,38410,38580,38660,38700,38750,38860,38880,39220,39310,39400,63113,63210,63240,63610,63660,63690,63840,63850,64440,64490,64560,64570,65110,65120,65170,65200,65240,65400,65510,65710,66210,66760,66800,68140,68610,68650,73110,73120,73130,73140,73150,73160,73170,73190,73210,73220,73230,73250,73260,73270,73300,73320,73340,73350,73390,73400,73440,73450,73460,73470,73500,73530,73550,73590,73600,73620,73630,73640,73710,73720,73870,74110,74120,74170,74220,74230,74260,74310,74340,74350,74360,74390,74400,74420,74430,74440,74450,74470,74480,74660,74740,74920,83111,83440,83530,83560,83630,83690,83830,83840,84390,88310,88340,88370,88400,90200)",
38
+ "fees": "5+{table {cart.weight} in 0.5:5.30, 1.0:6.50, 2.0:7.40, 3.0:8.30, 5.0:10.10, 10.0:12.50, 20.0:15.00, 30.0:18.00}"
39
+ },
40
+
41
+ "Zones Iles et Corse":
42
+ {
43
+ "shipto": "FR(20*,17111,17123,17190,17310,17370,17410,17480,17550,17580,17590,17630,17650,17670,17740,17840,17880,17940,22870,29242,29253,29259,29980,29990,56360,56590,56780,56840,85350)",
44
+ "fees": "16+{table {cart.weight} in 0.5:5.30, 1.0:6.50, 2.0:7.40, 3.0:8.30, 5.0:10.10, 10.0:12.50, 20.0:15.00, 30.0:18.00}"
45
+ },
46
+
47
+ "Zone France et Monaco":
48
+ {
49
+ "shipto": "FR,MC",
50
+ "fees": "{table {cart.weight} in 0.5:5.30, 1.0:6.50, 2.0:7.40, 3.0:8.30, 5.0:10.10, 10.0:12.50, 20.0:15.00, 30.0:18.00}"
51
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
52
  }
53
  </expense>
54
  </dpdfrrelais>
56
  </default>
57
  <modules>
58
  <DPDFrance_Relais>
59
+ <version>5.1.2</version>
60
  <depends>
61
  <Mage_Shipping/>
62
  </depends>
app/code/community/DPDFrance/Relais/etc/system.xml CHANGED
@@ -1,12 +1,12 @@
1
  <?xml version="1.0" encoding="UTF-8"?>
2
  <!--
3
  /**
4
- * DPD France v5.1.0 shipping module for Magento
5
  *
6
  * @category DPDFrance
7
  * @package DPDFrance_Shipping
8
- * @author DPD S.A.S. <ensavoirplus.ecommerce@dpd.fr>
9
- * @copyright 2015 DPD S.A.S., société par actions simplifiée, au capital de 18.500.000 euros, dont le siège social est situé 27 Rue du Colonel Pierre Avia - 75015 PARIS, immatriculée au registre du commerce et des sociétés de Paris sous le numéro 444 420 830
10
  * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
11
  */
12
  -->
1
  <?xml version="1.0" encoding="UTF-8"?>
2
  <!--
3
  /**
4
+ * DPD France v5.1.2 shipping module for Magento
5
  *
6
  * @category DPDFrance
7
  * @package DPDFrance_Shipping
8
+ * @author DPD France S.A.S. <ensavoirplus.ecommerce@dpd.fr>
9
+ * @copyright 2015 DPD France S.A.S., société par actions simplifiée, au capital de 18.500.000 euros, dont le siège social est situé 27 Rue du Colonel Pierre Avia - 75015 PARIS, immatriculée au registre du commerce et des sociétés de Paris sous le numéro 444 420 830
10
  * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
11
  */
12
  -->
app/design/frontend/base/default/layout/dpdfrpredict.xml CHANGED
@@ -1,12 +1,12 @@
1
  <?xml version="1.0" encoding="UTF-8"?>
2
  <!--
3
  /**
4
- * DPD France v5.1.0 shipping module for Magento
5
  *
6
  * @category DPDFrance
7
  * @package DPDFrance_Shipping
8
- * @author DPD S.A.S. <ensavoirplus.ecommerce@dpd.fr>
9
- * @copyright 2015 DPD S.A.S., société par actions simplifiée, au capital de 18.500.000 euros, dont le siège social est situé 27 Rue du Colonel Pierre Avia - 75015 PARIS, immatriculée au registre du commerce et des sociétés de Paris sous le numéro 444 420 830
10
  * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
11
  */
12
  -->
1
  <?xml version="1.0" encoding="UTF-8"?>
2
  <!--
3
  /**
4
+ * DPD France v5.1.2 shipping module for Magento
5
  *
6
  * @category DPDFrance
7
  * @package DPDFrance_Shipping
8
+ * @author DPD France S.A.S. <ensavoirplus.ecommerce@dpd.fr>
9
+ * @copyright 2015 DPD France S.A.S., société par actions simplifiée, au capital de 18.500.000 euros, dont le siège social est situé 27 Rue du Colonel Pierre Avia - 75015 PARIS, immatriculée au registre du commerce et des sociétés de Paris sous le numéro 444 420 830
10
  * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
11
  */
12
  -->
app/design/frontend/base/default/layout/dpdfrrelais.xml CHANGED
@@ -1,12 +1,12 @@
1
  <?xml version="1.0" encoding="UTF-8"?>
2
  <!--
3
  /**
4
- * DPD France v5.1.0 shipping module for Magento
5
  *
6
  * @category DPDFrance
7
  * @package DPDFrance_Shipping
8
- * @author DPD S.A.S. <ensavoirplus.ecommerce@dpd.fr>
9
- * @copyright 2015 DPD S.A.S., société par actions simplifiée, au capital de 18.500.000 euros, dont le siège social est situé 27 Rue du Colonel Pierre Avia - 75015 PARIS, immatriculée au registre du commerce et des sociétés de Paris sous le numéro 444 420 830
10
  * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
11
  */
12
  -->
1
  <?xml version="1.0" encoding="UTF-8"?>
2
  <!--
3
  /**
4
+ * DPD France v5.1.2 shipping module for Magento
5
  *
6
  * @category DPDFrance
7
  * @package DPDFrance_Shipping
8
+ * @author DPD France S.A.S. <ensavoirplus.ecommerce@dpd.fr>
9
+ * @copyright 2015 DPD France S.A.S., société par actions simplifiée, au capital de 18.500.000 euros, dont le siège social est situé 27 Rue du Colonel Pierre Avia - 75015 PARIS, immatriculée au registre du commerce et des sociétés de Paris sous le numéro 444 420 830
10
  * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
11
  */
12
  -->
app/design/frontend/base/default/template/dpdfrpredict/checkout/onepage/progress/shipping.phtml CHANGED
@@ -1,11 +1,11 @@
1
  <?php
2
  /**
3
- * DPD France v5.1.0 shipping module for Magento
4
  *
5
  * @category DPDFrance
6
  * @package DPDFrance_Shipping
7
- * @author DPD S.A.S. <ensavoirplus.ecommerce@dpd.fr>
8
- * @copyright 2015 DPD S.A.S., société par actions simplifiée, au capital de 18.500.000 euros, dont le siège social est situé 27 Rue du Colonel Pierre Avia - 75015 PARIS, immatriculée au registre du commerce et des sociétés de Paris sous le numéro 444 420 830
9
  * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
10
  */
11
  ?>
1
  <?php
2
  /**
3
+ * DPD France v5.1.2 shipping module for Magento
4
  *
5
  * @category DPDFrance
6
  * @package DPDFrance_Shipping
7
+ * @author DPD France S.A.S. <ensavoirplus.ecommerce@dpd.fr>
8
+ * @copyright 2015 DPD France S.A.S., société par actions simplifiée, au capital de 18.500.000 euros, dont le siège social est situé 27 Rue du Colonel Pierre Avia - 75015 PARIS, immatriculée au registre du commerce et des sociétés de Paris sous le numéro 444 420 830
9
  * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
10
  */
11
  ?>
app/design/frontend/base/default/template/dpdfrpredict/checkout/onepage/progress/shipping_method.phtml CHANGED
@@ -1,11 +1,11 @@
1
  <?php
2
  /**
3
- * DPD France v5.1.0 shipping module for Magento
4
  *
5
  * @category DPDFrance
6
  * @package DPDFrance_Shipping
7
- * @author DPD S.A.S. <ensavoirplus.ecommerce@dpd.fr>
8
- * @copyright 2015 DPD S.A.S., société par actions simplifiée, au capital de 18.500.000 euros, dont le siège social est situé 27 Rue du Colonel Pierre Avia - 75015 PARIS, immatriculée au registre du commerce et des sociétés de Paris sous le numéro 444 420 830
9
  * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
10
  */
11
  ?>
1
  <?php
2
  /**
3
+ * DPD France v5.1.2 shipping module for Magento
4
  *
5
  * @category DPDFrance
6
  * @package DPDFrance_Shipping
7
+ * @author DPD France S.A.S. <ensavoirplus.ecommerce@dpd.fr>
8
+ * @copyright 2015 DPD France S.A.S., société par actions simplifiée, au capital de 18.500.000 euros, dont le siège social est situé 27 Rue du Colonel Pierre Avia - 75015 PARIS, immatriculée au registre du commerce et des sociétés de Paris sous le numéro 444 420 830
9
  * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
10
  */
11
  ?>
app/design/frontend/base/default/template/dpdfrpredict/checkout/onepage/shipping_method.phtml CHANGED
@@ -1,11 +1,11 @@
1
  <?php
2
  /**
3
- * DPD France v5.1.0 shipping module for Magento
4
  *
5
  * @category DPDFrance
6
  * @package DPDFrance_Shipping
7
- * @author DPD S.A.S. <ensavoirplus.ecommerce@dpd.fr>
8
- * @copyright 2015 DPD S.A.S., société par actions simplifiée, au capital de 18.500.000 euros, dont le siège social est situé 27 Rue du Colonel Pierre Avia - 75015 PARIS, immatriculée au registre du commerce et des sociétés de Paris sous le numéro 444 420 830
9
  * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
10
  */
11
  ?>
1
  <?php
2
  /**
3
+ * DPD France v5.1.2 shipping module for Magento
4
  *
5
  * @category DPDFrance
6
  * @package DPDFrance_Shipping
7
+ * @author DPD France S.A.S. <ensavoirplus.ecommerce@dpd.fr>
8
+ * @copyright 2015 DPD France S.A.S., société par actions simplifiée, au capital de 18.500.000 euros, dont le siège social est situé 27 Rue du Colonel Pierre Avia - 75015 PARIS, immatriculée au registre du commerce et des sociétés de Paris sous le numéro 444 420 830
9
  * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
10
  */
11
  ?>
app/design/frontend/base/default/template/dpdfrpredict/checkout/onepage/shipping_method/available.phtml CHANGED
@@ -1,11 +1,11 @@
1
  <?php
2
  /**
3
- * DPD France v5.1.0 shipping module for Magento
4
  *
5
  * @category DPDFrance
6
  * @package DPDFrance_Shipping
7
- * @author DPD S.A.S. <ensavoirplus.ecommerce@dpd.fr>
8
- * @copyright 2015 DPD S.A.S., société par actions simplifiée, au capital de 18.500.000 euros, dont le siège social est situé 27 Rue du Colonel Pierre Avia - 75015 PARIS, immatriculée au registre du commerce et des sociétés de Paris sous le numéro 444 420 830
9
  * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
10
  */
11
  ?>
1
  <?php
2
  /**
3
+ * DPD France v5.1.2 shipping module for Magento
4
  *
5
  * @category DPDFrance
6
  * @package DPDFrance_Shipping
7
+ * @author DPD France S.A.S. <ensavoirplus.ecommerce@dpd.fr>
8
+ * @copyright 2015 DPD France S.A.S., société par actions simplifiée, au capital de 18.500.000 euros, dont le siège social est situé 27 Rue du Colonel Pierre Avia - 75015 PARIS, immatriculée au registre du commerce et des sociétés de Paris sous le numéro 444 420 830
9
  * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
10
  */
11
  ?>
app/design/frontend/base/default/template/dpdfrrelais/checkout/onepage/progress/shipping.phtml CHANGED
@@ -1,11 +1,11 @@
1
  <?php
2
  /**
3
- * DPD France v5.1.0 shipping module for Magento
4
  *
5
  * @category DPDFrance
6
  * @package DPDFrance_Shipping
7
- * @author DPD S.A.S. <ensavoirplus.ecommerce@dpd.fr>
8
- * @copyright 2015 DPD S.A.S., société par actions simplifiée, au capital de 18.500.000 euros, dont le siège social est situé 27 Rue du Colonel Pierre Avia - 75015 PARIS, immatriculée au registre du commerce et des sociétés de Paris sous le numéro 444 420 830
9
  * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
10
  */
11
  ?>
1
  <?php
2
  /**
3
+ * DPD France v5.1.2 shipping module for Magento
4
  *
5
  * @category DPDFrance
6
  * @package DPDFrance_Shipping
7
+ * @author DPD France S.A.S. <ensavoirplus.ecommerce@dpd.fr>
8
+ * @copyright 2015 DPD France S.A.S., société par actions simplifiée, au capital de 18.500.000 euros, dont le siège social est situé 27 Rue du Colonel Pierre Avia - 75015 PARIS, immatriculée au registre du commerce et des sociétés de Paris sous le numéro 444 420 830
9
  * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
10
  */
11
  ?>
app/design/frontend/base/default/template/dpdfrrelais/checkout/onepage/progress/shipping_method.phtml CHANGED
@@ -1,11 +1,11 @@
1
  <?php
2
  /**
3
- * DPD France v5.1.0 shipping module for Magento
4
  *
5
  * @category DPDFrance
6
  * @package DPDFrance_Shipping
7
- * @author DPD S.A.S. <ensavoirplus.ecommerce@dpd.fr>
8
- * @copyright 2015 DPD S.A.S., société par actions simplifiée, au capital de 18.500.000 euros, dont le siège social est situé 27 Rue du Colonel Pierre Avia - 75015 PARIS, immatriculée au registre du commerce et des sociétés de Paris sous le numéro 444 420 830
9
  * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
10
  */
11
  ?>
1
  <?php
2
  /**
3
+ * DPD France v5.1.2 shipping module for Magento
4
  *
5
  * @category DPDFrance
6
  * @package DPDFrance_Shipping
7
+ * @author DPD France S.A.S. <ensavoirplus.ecommerce@dpd.fr>
8
+ * @copyright 2015 DPD France S.A.S., société par actions simplifiée, au capital de 18.500.000 euros, dont le siège social est situé 27 Rue du Colonel Pierre Avia - 75015 PARIS, immatriculée au registre du commerce et des sociétés de Paris sous le numéro 444 420 830
9
  * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
10
  */
11
  ?>
app/design/frontend/base/default/template/dpdfrrelais/checkout/onepage/shipping_method.phtml CHANGED
@@ -1,11 +1,11 @@
1
  <?php
2
  /**
3
- * DPD France v5.1.0 shipping module for Magento
4
  *
5
  * @category DPDFrance
6
  * @package DPDFrance_Shipping
7
- * @author DPD S.A.S. <ensavoirplus.ecommerce@dpd.fr>
8
- * @copyright 2015 DPD S.A.S., société par actions simplifiée, au capital de 18.500.000 euros, dont le siège social est situé 27 Rue du Colonel Pierre Avia - 75015 PARIS, immatriculée au registre du commerce et des sociétés de Paris sous le numéro 444 420 830
9
  * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
10
  */
11
  ?>
1
  <?php
2
  /**
3
+ * DPD France v5.1.2 shipping module for Magento
4
  *
5
  * @category DPDFrance
6
  * @package DPDFrance_Shipping
7
+ * @author DPD France S.A.S. <ensavoirplus.ecommerce@dpd.fr>
8
+ * @copyright 2015 DPD France S.A.S., société par actions simplifiée, au capital de 18.500.000 euros, dont le siège social est situé 27 Rue du Colonel Pierre Avia - 75015 PARIS, immatriculée au registre du commerce et des sociétés de Paris sous le numéro 444 420 830
9
  * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
10
  */
11
  ?>
app/design/frontend/base/default/template/dpdfrrelais/checkout/onepage/shipping_method/available.phtml CHANGED
@@ -1,11 +1,11 @@
1
  <?php
2
  /**
3
- * DPD France v5.1.0 shipping module for Magento
4
  *
5
  * @category DPDFrance
6
  * @package DPDFrance_Shipping
7
- * @author DPD S.A.S. <ensavoirplus.ecommerce@dpd.fr>
8
- * @copyright 2015 DPD S.A.S., société par actions simplifiée, au capital de 18.500.000 euros, dont le siège social est situé 27 Rue du Colonel Pierre Avia - 75015 PARIS, immatriculée au registre du commerce et des sociétés de Paris sous le numéro 444 420 830
9
  * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
10
  */
11
  ?>
1
  <?php
2
  /**
3
+ * DPD France v5.1.2 shipping module for Magento
4
  *
5
  * @category DPDFrance
6
  * @package DPDFrance_Shipping
7
+ * @author DPD France S.A.S. <ensavoirplus.ecommerce@dpd.fr>
8
+ * @copyright 2015 DPD France S.A.S., société par actions simplifiée, au capital de 18.500.000 euros, dont le siège social est situé 27 Rue du Colonel Pierre Avia - 75015 PARIS, immatriculée au registre du commerce et des sociétés de Paris sous le numéro 444 420 830
9
  * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
10
  */
11
  ?>
media/dpdfrance/readme_dpdfrance_magento.pdf CHANGED
Binary file
package.xml CHANGED
@@ -1,7 +1,7 @@
1
  <?xml version="1.0"?>
2
  <package>
3
  <name>DPDFrance_Shipping</name>
4
- <version>5.1.1</version>
5
  <stability>stable</stability>
6
  <license uri="http://opensource.org/licenses/osl-3.0.php">Open Software License (OSL)</license>
7
  <channel>community</channel>
@@ -11,9 +11,9 @@
11
  Il est destin&#xE9; aux e-commer&#xE7;ants situ&#xE9;s en France m&#xE9;tropolitaine et d&#xE9;tenteurs d'un contrat de transport chez DPD.</description>
12
  <notes>DPDFrance_Shipping for Magento CE 1.4 - 1.9</notes>
13
  <authors><author><name>DPD France S.A.S.</name><user>DSI</user><email>support.ecommerce@dpd.fr</email></author></authors>
14
- <date>2015-04-10</date>
15
- <time>14:36:41</time>
16
- <contents><target name="magecommunity"><dir name="DPDFrance"><dir name="Classic"><dir name="Helper"><file name="Data.php" hash="cfa2d8cf36a41f14ec1971b0407d2360"/></dir><dir name="Model"><dir name="Carrier"><file name="DPDFranceClassicShipping.php" hash="8841cc024ce0022faecfbeb25a5fb81c"/></dir><file name="Owebia.php" hash="d15ddf3d66f3a7712e0422165b8e88cd"/></dir><dir name="etc"><file name="config.xml" hash="1571b05a2fd0f6a8afb0def459a3dff7"/><file name="system.xml" hash="a08a0b981998e81d1477e86a31a4a0dc"/></dir></dir><dir name="Export"><dir name="Block"><dir name="Export"><dir name="Orders"><file name="Grid.php" hash="517cb396294ce8ec1d911dcd72b4459e"/></dir><file name="Orders.php" hash="c5fe378d1a9e4e3152803b9aae98b95c"/></dir><dir name="Tracking"><dir name="Orders"><file name="Grid.php" hash="3c548f639b97a1cb59634e32f5212a4c"/></dir><file name="Orders.php" hash="0727142364db150a3993afeb4dacd197"/></dir></dir><dir name="Helper"><file name="Data.php" hash="428d1b543f2550aedde558b6753eb832"/></dir><dir name="controllers"><file name="ExportController.php" hash="b9adffa016f7700a58c7ea67c3480629"/><file name="TrackingController.php" hash="d16659a6668988ad3e5773a921558238"/></dir><dir name="etc"><file name="config.xml" hash="db209afe4e185b6ff0fcba8d764313e6"/></dir></dir><dir name="Predict"><dir name="Helper"><file name="Data.php" hash="a38b8d10c687205740b99f0831ba9718"/></dir><dir name="Model"><dir name="Carrier"><file name="DPDFrancePredictShipping.php" hash="1c2ef6b5e79f5f25d495670d9e07c8af"/></dir><file name="Observer.php" hash="303925d00db6e1187803965e4bfb5331"/><file name="Owebia.php" hash="bff0ef2121438663f13e7ec24ec741e8"/></dir><dir name="etc"><file name="config.xml" hash="ea4cbc13ce499fdcd555f058be887f48"/><file name="system.xml" hash="1c0b8b0be33879df1c7ff5944da29afe"/></dir></dir><dir name="Relais"><dir name="Helper"><file name="Data.php" hash="d0d47baa19f1415f8aa2046658f9b094"/></dir><dir name="Model"><dir name="Carrier"><file name="DPDFranceRelaisShipping.php" hash="0351edcfbd38f7131af3579d2773faba"/></dir><file name="Observer.php" hash="e89d9e7d2af396c56f3b1731f3cf4ebe"/><file name="Outputs.php" hash="d4752d22b5044ce3bc29c15617832a2b"/><file name="Owebia.php" hash="f45517e834fa786d97a130b9d92474bd"/></dir><dir name="controllers"><file name="PickupController.php" hash="58116e151a1d3dd0e90879cfca2c69e5"/></dir><dir name="etc"><file name="config.xml" hash="217e12435923430da1921cbbfc5a271a"/><file name="system.xml" hash="a8c6d4e7c23832defa2d5abd7b3acb60"/></dir></dir></dir></target><target name="magemedia"><dir name="dpdfrance"><dir name="admin"><file name="logo.png" hash="e7b47272859a42f42d41339f6a2cd346"/><file name="rss_icon.png" hash="5df63e9d18e8af642108289ae2f1749b"/><file name="service_dom.png" hash="658f00232b8bcae034954b19c8681e6c"/><file name="service_predict.png" hash="31c279f0025ccd80ad427706a1614d0e"/><file name="service_relais.png" hash="93ea3df8e255fce572fe38ea114a6ce0"/><file name="service_world.png" hash="6b0a33dec808c936c4340a742f325796"/></dir><dir name="fonts"><file name="PlutoSansDPDExtraLight-Web.ttf" hash="133a30691494add15177142cd9fa9d28"/><file name="PlutoSansDPDLight-Web.ttf" hash="3b7b428b357ae09836153e4814352af1"/><file name="PlutoSansDPDRegular-Web.ttf" hash="7638f688c25d2268a6f5b2e70b949bbf"/><file name="PlutoSansDPDThin-Web.ttf" hash="2291598279cff8ed31fdc6af39dba22a"/></dir><dir name="front"><dir name="predict"><file name="carrier_logo.jpg" hash="2f65b000e843aca95fd1de9ee2ab06fe"/><file name="carrier_logo_alt.jpg" hash="692de3c50f19ca126f0d3f5dd469fa3e"/><file name="dpd_logo.png" hash="3a03db004b6105d9c499d5d9c64ab5d0"/><file name="dpd_predict_logo.png" hash="b562a9641ca4e90c31d263f41c3f637b"/><file name="predict_receive.jpg" hash="cbc5309345d1196f88d657d68ac7f908"/></dir><dir name="relais"><file name="DPD_Logo.png" hash="747d0dbdbc6df6afabf9698a389557d5"/><file name="carrier_logo.jpg" hash="2f98ce3752c2d7a055a7c19e43b0abf5"/><file name="carrier_logo_alt.jpg" hash="118958c4e3e0be20548c05a068fe3e7b"/><file name="horaires.png" hash="0ce51016d04a27600113e3762107fc15"/><file name="info.png" hash="e42e3b90b5611aaf3c170b569add2d93"/><file name="loader.gif" hash="6c322059292b30838a50f15a939a0200"/><file name="logo-max-png.png" hash="b80e78588624115fe3d8067107da8866"/><file name="pointrelais.png" hash="3ece61e5e6505b941fb318280b4040ce"/><file name="warning.png" hash="e1055c336abc2e5d76805c380f2b0134"/></dir></dir><file name="readme_dpdfrance_magento.pdf" hash="b016d9187ac1a4923a5f399b7a83fe38"/></dir></target><target name="mageetc"><dir name="modules"><file name="DPDFrance_Classic.xml" hash="a028196822d67576427c45f463311ac4"/><file name="DPDFrance_Export.xml" hash="ee030b0a83049695ddb6ec19db36e304"/><file name="DPDFrance_Predict.xml" hash="3f816b679509f1d67d707c60c7f99cb5"/><file name="DPDFrance_Relais.xml" hash="1411953b5c7abf08e231c02b35b5def4"/></dir></target><target name="magelocale"><dir><dir name="en_US"><file name="DPDFrance_Classic.csv" hash="c01554087d5bafd2af36faf4101d682b"/><file name="DPDFrance_Export.csv" hash="cdc0421a6d7d1510272241249f229607"/><file name="DPDFrance_Predict.csv" hash="9bf03682e6614c490f2924dd76fbc5cb"/><file name="DPDFrance_Relais.csv" hash="827b1971092f0d31fb599c41544c87ce"/></dir><dir name="fr_FR"><file name="DPDFrance_Classic.csv" hash="261b0c9ef9d958665f690617021f51c3"/><file name="DPDFrance_Export.csv" hash="f483d063866b3729b992f7433af1a5db"/><file name="DPDFrance_Predict.csv" hash="3a46cff3925afcee31125cd1c7c3f443"/><file name="DPDFrance_Relais.csv" hash="dca527e399bc74ab91389aac0101a667"/></dir></dir></target><target name="magedesign"><dir name="frontend"><dir name="base"><dir name="default"><dir name="layout"><file name="dpdfrpredict.xml" hash="19876f7ce2842a19ed32e4f1ab79ecb9"/><file name="dpdfrrelais.xml" hash="4fb280b9ce764c7918a9da3bbc7d7171"/></dir><dir name="template"><dir name="dpdfrpredict"><dir name="checkout"><dir name="onepage"><dir name="progress"><file name="shipping.phtml" hash="217f4563764644f476cff918917906fb"/><file name="shipping_method.phtml" hash="9dcf148b32aae41860edc7f970732174"/></dir><dir name="shipping_method"><file name="available.phtml" hash="f88fdd53c9778d4c0d65627a2bc1b2d7"/></dir><file name="shipping_method.phtml" hash="09e9c8a50c7f27358eae55cd8b3fb55b"/></dir></dir></dir><dir name="dpdfrrelais"><dir name="checkout"><dir name="onepage"><dir name="progress"><file name="shipping.phtml" hash="217f4563764644f476cff918917906fb"/><file name="shipping_method.phtml" hash="9dcf148b32aae41860edc7f970732174"/></dir><dir name="shipping_method"><file name="available.phtml" hash="e7a0d13205e5cebcd102c106b45e9c49"/></dir><file name="shipping_method.phtml" hash="95e653732828a28d3be1ff20ff0199dd"/></dir></dir></dir></dir></dir></dir></dir></target><target name="mageskin"><dir name="frontend"><dir name="base"><dir name="default"><dir name="css"><dir name="dpdfrance"><file name="dpdfrpredict.css" hash="9e03b7f9597e3e32bf70179a7c778a43"/><file name="dpdfrrelais.css" hash="82e15d0d2ea496235c47ce712f06a637"/></dir></dir><dir name="js"><dir name="dpdfrance"><file name="dpdfrpredict.js" hash="778a88ce7e382dfd1417022b48da276b"/><file name="dpdfrrelais.js" hash="8dbd5aceb1662cbe6efaa4d04229f3bb"/></dir></dir></dir></dir></dir></target></contents>
17
  <compatible/>
18
  <dependencies><required><php><min>5.0.0</min><max>6.0.0</max></php><extension><name>soap</name><min>1.0</min><max></max></extension></required></dependencies>
19
  </package>
1
  <?xml version="1.0"?>
2
  <package>
3
  <name>DPDFrance_Shipping</name>
4
+ <version>5.1.2</version>
5
  <stability>stable</stability>
6
  <license uri="http://opensource.org/licenses/osl-3.0.php">Open Software License (OSL)</license>
7
  <channel>community</channel>
11
  Il est destin&#xE9; aux e-commer&#xE7;ants situ&#xE9;s en France m&#xE9;tropolitaine et d&#xE9;tenteurs d'un contrat de transport chez DPD.</description>
12
  <notes>DPDFrance_Shipping for Magento CE 1.4 - 1.9</notes>
13
  <authors><author><name>DPD France S.A.S.</name><user>DSI</user><email>support.ecommerce@dpd.fr</email></author></authors>
14
+ <date>2015-06-02</date>
15
+ <time>15:00:35</time>
16
+ <contents><target name="magecommunity"><dir name="DPDFrance"><dir name="Classic"><dir name="Helper"><file name="Data.php" hash="5d65439f057aadb2b6220a6bdbcc54ac"/></dir><dir name="Model"><dir name="Carrier"><file name="DPDFranceClassicShipping.php" hash="2493fc8d03b6d3e9f110c2d7ab6085e6"/></dir><file name="Owebia.php" hash="4f3fbbb45fc26b8219365de47dfba8c7"/></dir><dir name="etc"><file name="config.xml" hash="142a607ef07a0fabce127b07464037c0"/><file name="system.xml" hash="209aeb0fd5d3c30eb9ad75bee0bd3f19"/></dir></dir><dir name="Export"><dir name="Block"><dir name="Export"><dir name="Orders"><file name="Grid.php" hash="f361f7707419d4b7db4478b759194830"/></dir><file name="Orders.php" hash="e619c30dcc59f4ed5be517c6f24dccef"/></dir><dir name="Tracking"><dir name="Orders"><file name="Grid.php" hash="00a337bae0cba9e80eb0e2ae22174ce2"/></dir><file name="Orders.php" hash="ebcbdd3cb35c39ba4f3f6765879d1f8e"/></dir></dir><dir name="Helper"><file name="Data.php" hash="cf52b695b8211970e470de6cdb893e4b"/></dir><dir name="controllers"><file name="ExportController.php" hash="5bf1605a40c422a94a1fc2dbbf3fa9a7"/><file name="TrackingController.php" hash="53ccecbcb47757438515348b81e469b5"/></dir><dir name="etc"><file name="config.xml" hash="73470943aa836d0c9847dddb092717d5"/></dir></dir><dir name="Predict"><dir name="Helper"><file name="Data.php" hash="40200748607ec169d01a79cae88fbf6d"/></dir><dir name="Model"><dir name="Carrier"><file name="DPDFrancePredictShipping.php" hash="b958baffa030ef58d6103441791b837e"/></dir><file name="Observer.php" hash="62d6296545e31e6aa28ad7e83f5b3bf1"/><file name="Owebia.php" hash="8f0ba92473f70e55edf731b717878e54"/></dir><dir name="etc"><file name="config.xml" hash="d910f26af52913033374748c2c6e15e3"/><file name="system.xml" hash="80ef69da51b6bb00bfc36f3c8b84edf4"/></dir></dir><dir name="Relais"><dir name="Helper"><file name="Data.php" hash="9c98514c4a85e83db2ccd8d65d259aac"/></dir><dir name="Model"><dir name="Carrier"><file name="DPDFranceRelaisShipping.php" hash="d689a4e692ff8660864cceb1d7c166d8"/></dir><file name="Observer.php" hash="4c7ca82454d4e3f8e6dfa00604889ec0"/><file name="Outputs.php" hash="17fb2f0f8d48ce222787d6d4ac5bedd8"/><file name="Owebia.php" hash="7b410e0b3d4563e3b2152113e13f79de"/></dir><dir name="controllers"><file name="PickupController.php" hash="ddace16b5d8615b3560507b6a5b18750"/></dir><dir name="etc"><file name="config.xml" hash="0be37cf453d7cf5589fd7b8499b79fbf"/><file name="system.xml" hash="790b525abbe4499e4bcbaaa5ae1bec62"/></dir></dir></dir></target><target name="magemedia"><dir name="dpdfrance"><dir name="admin"><file name="logo.png" hash="e7b47272859a42f42d41339f6a2cd346"/><file name="rss_icon.png" hash="5df63e9d18e8af642108289ae2f1749b"/><file name="service_dom.png" hash="658f00232b8bcae034954b19c8681e6c"/><file name="service_predict.png" hash="31c279f0025ccd80ad427706a1614d0e"/><file name="service_relais.png" hash="93ea3df8e255fce572fe38ea114a6ce0"/><file name="service_world.png" hash="6b0a33dec808c936c4340a742f325796"/></dir><dir name="fonts"><file name="PlutoSansDPDExtraLight-Web.ttf" hash="133a30691494add15177142cd9fa9d28"/><file name="PlutoSansDPDLight-Web.ttf" hash="3b7b428b357ae09836153e4814352af1"/><file name="PlutoSansDPDRegular-Web.ttf" hash="7638f688c25d2268a6f5b2e70b949bbf"/><file name="PlutoSansDPDThin-Web.ttf" hash="2291598279cff8ed31fdc6af39dba22a"/></dir><dir name="front"><dir name="predict"><file name="carrier_logo.jpg" hash="2f65b000e843aca95fd1de9ee2ab06fe"/><file name="carrier_logo_alt.jpg" hash="692de3c50f19ca126f0d3f5dd469fa3e"/><file name="dpd_logo.png" hash="3a03db004b6105d9c499d5d9c64ab5d0"/><file name="dpd_predict_logo.png" hash="b562a9641ca4e90c31d263f41c3f637b"/><file name="predict_receive.jpg" hash="cbc5309345d1196f88d657d68ac7f908"/></dir><dir name="relais"><file name="DPD_Logo.png" hash="747d0dbdbc6df6afabf9698a389557d5"/><file name="carrier_logo.jpg" hash="2f98ce3752c2d7a055a7c19e43b0abf5"/><file name="carrier_logo_alt.jpg" hash="118958c4e3e0be20548c05a068fe3e7b"/><file name="horaires.png" hash="0ce51016d04a27600113e3762107fc15"/><file name="info.png" hash="e42e3b90b5611aaf3c170b569add2d93"/><file name="loader.gif" hash="6c322059292b30838a50f15a939a0200"/><file name="logo-max-png.png" hash="b80e78588624115fe3d8067107da8866"/><file name="pointrelais.png" hash="3ece61e5e6505b941fb318280b4040ce"/><file name="warning.png" hash="e1055c336abc2e5d76805c380f2b0134"/></dir></dir><file name="readme_dpdfrance_magento.pdf" hash="64195149fdec687f5bd3e5b7e9385228"/></dir></target><target name="mageetc"><dir name="modules"><file name="DPDFrance_Classic.xml" hash="a028196822d67576427c45f463311ac4"/><file name="DPDFrance_Export.xml" hash="ee030b0a83049695ddb6ec19db36e304"/><file name="DPDFrance_Predict.xml" hash="3f816b679509f1d67d707c60c7f99cb5"/><file name="DPDFrance_Relais.xml" hash="1411953b5c7abf08e231c02b35b5def4"/></dir></target><target name="magelocale"><dir><dir name="en_US"><file name="DPDFrance_Classic.csv" hash="c01554087d5bafd2af36faf4101d682b"/><file name="DPDFrance_Export.csv" hash="cdc0421a6d7d1510272241249f229607"/><file name="DPDFrance_Predict.csv" hash="9bf03682e6614c490f2924dd76fbc5cb"/><file name="DPDFrance_Relais.csv" hash="827b1971092f0d31fb599c41544c87ce"/></dir><dir name="fr_FR"><file name="DPDFrance_Classic.csv" hash="261b0c9ef9d958665f690617021f51c3"/><file name="DPDFrance_Export.csv" hash="f483d063866b3729b992f7433af1a5db"/><file name="DPDFrance_Predict.csv" hash="3a46cff3925afcee31125cd1c7c3f443"/><file name="DPDFrance_Relais.csv" hash="dca527e399bc74ab91389aac0101a667"/></dir></dir></target><target name="magedesign"><dir name="frontend"><dir name="base"><dir name="default"><dir name="layout"><file name="dpdfrpredict.xml" hash="b8b01c0c0fb333be9ba126757129c16b"/><file name="dpdfrrelais.xml" hash="8ad0de86adf8174fc3ba702c643b65b1"/></dir><dir name="template"><dir name="dpdfrpredict"><dir name="checkout"><dir name="onepage"><dir name="progress"><file name="shipping.phtml" hash="709398b58c7fbea1b52f8674f1dcf192"/><file name="shipping_method.phtml" hash="4fe6c70dbbce0b483a12c78ca7353f02"/></dir><dir name="shipping_method"><file name="available.phtml" hash="ed2347b6f310fb41aca7d305d2ca1bb3"/></dir><file name="shipping_method.phtml" hash="8724fb61d0665be09cec67c67bdc9b11"/></dir></dir></dir><dir name="dpdfrrelais"><dir name="checkout"><dir name="onepage"><dir name="progress"><file name="shipping.phtml" hash="709398b58c7fbea1b52f8674f1dcf192"/><file name="shipping_method.phtml" hash="4fe6c70dbbce0b483a12c78ca7353f02"/></dir><dir name="shipping_method"><file name="available.phtml" hash="48b243c6b89e7fefd228cf1d38f235cb"/></dir><file name="shipping_method.phtml" hash="a87488e951caa5fa80a545d07f628cfe"/></dir></dir></dir></dir></dir></dir></dir></target><target name="mageskin"><dir name="frontend"><dir name="base"><dir name="default"><dir name="css"><dir name="dpdfrance"><file name="dpdfrpredict.css" hash="b3f075a9f40c73144558fb01e45f5a76"/><file name="dpdfrrelais.css" hash="a3f0e24a3efd713ad8581c790031de5f"/></dir></dir><dir name="js"><dir name="dpdfrance"><file name="dpdfrpredict.js" hash="f645f0ccc6160fd3a5d3a69438f81f18"/><file name="dpdfrrelais.js" hash="ff829bea008b957e5e651ce2b52d771d"/></dir></dir></dir></dir></dir></target></contents>
17
  <compatible/>
18
  <dependencies><required><php><min>5.0.0</min><max>6.0.0</max></php><extension><name>soap</name><min>1.0</min><max></max></extension></required></dependencies>
19
  </package>
skin/frontend/base/default/css/dpdfrance/dpdfrpredict.css CHANGED
@@ -1,10 +1,10 @@
1
  /**
2
- * DPD France v5.1.0 shipping module for Magento
3
  *
4
  * @category DPDFrance
5
  * @package DPDFrance_Shipping
6
- * @author DPD S.A.S. <ensavoirplus.ecommerce@dpd.fr>
7
- * @copyright 2015 DPD S.A.S., société par actions simplifiée, au capital de 18.500.000 euros, dont le siège social est situé 27 Rue du Colonel Pierre Avia - 75015 PARIS, immatriculée au registre du commerce et des sociétés de Paris sous le numéro 444 420 830
8
  * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
9
  */
10
 
1
  /**
2
+ * DPD France v5.1.2 shipping module for Magento
3
  *
4
  * @category DPDFrance
5
  * @package DPDFrance_Shipping
6
+ * @author DPD France S.A.S. <ensavoirplus.ecommerce@dpd.fr>
7
+ * @copyright 2015 DPD France S.A.S., société par actions simplifiée, au capital de 18.500.000 euros, dont le siège social est situé 27 Rue du Colonel Pierre Avia - 75015 PARIS, immatriculée au registre du commerce et des sociétés de Paris sous le numéro 444 420 830
8
  * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
9
  */
10
 
skin/frontend/base/default/css/dpdfrance/dpdfrrelais.css CHANGED
@@ -1,10 +1,10 @@
1
  /**
2
- * DPD France v5.1.0 shipping module for Magento
3
  *
4
  * @category DPDFrance
5
  * @package DPDFrance_Shipping
6
- * @author DPD S.A.S. <ensavoirplus.ecommerce@dpd.fr>
7
- * @copyright 2015 DPD S.A.S., société par actions simplifiée, au capital de 18.500.000 euros, dont le siège social est situé 27 Rue du Colonel Pierre Avia - 75015 PARIS, immatriculée au registre du commerce et des sociétés de Paris sous le numéro 444 420 830
8
  * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
9
  */
10
 
1
  /**
2
+ * DPD France v5.1.2 shipping module for Magento
3
  *
4
  * @category DPDFrance
5
  * @package DPDFrance_Shipping
6
+ * @author DPD France S.A.S. <ensavoirplus.ecommerce@dpd.fr>
7
+ * @copyright 2015 DPD France S.A.S., société par actions simplifiée, au capital de 18.500.000 euros, dont le siège social est situé 27 Rue du Colonel Pierre Avia - 75015 PARIS, immatriculée au registre du commerce et des sociétés de Paris sous le numéro 444 420 830
8
  * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
9
  */
10
 
skin/frontend/base/default/js/dpdfrance/dpdfrpredict.js CHANGED
@@ -1,10 +1,10 @@
1
  /**
2
- * DPD France v5.1.0 shipping module for Magento
3
  *
4
  * @category DPDFrance
5
  * @package DPDFrance_Shipping
6
- * @author DPD S.A.S. <ensavoirplus.ecommerce@dpd.fr>
7
- * @copyright 2015 DPD S.A.S., société par actions simplifiée, au capital de 18.500.000 euros, dont le siège social est situé 27 Rue du Colonel Pierre Avia - 75015 PARIS, immatriculée au registre du commerce et des sociétés de Paris sous le numéro 444 420 830
8
  * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
9
  */
10
 
1
  /**
2
+ * DPD France v5.1.2 shipping module for Magento
3
  *
4
  * @category DPDFrance
5
  * @package DPDFrance_Shipping
6
+ * @author DPD France S.A.S. <ensavoirplus.ecommerce@dpd.fr>
7
+ * @copyright 2015 DPD France S.A.S., société par actions simplifiée, au capital de 18.500.000 euros, dont le siège social est situé 27 Rue du Colonel Pierre Avia - 75015 PARIS, immatriculée au registre du commerce et des sociétés de Paris sous le numéro 444 420 830
8
  * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
9
  */
10
 
skin/frontend/base/default/js/dpdfrance/dpdfrrelais.js CHANGED
@@ -1,10 +1,10 @@
1
  /**
2
- * DPD France v5.1.0 shipping module for Magento
3
  *
4
  * @category DPDFrance
5
  * @package DPDFrance_Shipping
6
- * @author DPD S.A.S. <ensavoirplus.ecommerce@dpd.fr>
7
- * @copyright 2015 DPD S.A.S., société par actions simplifiée, au capital de 18.500.000 euros, dont le siège social est situé 27 Rue du Colonel Pierre Avia - 75015 PARIS, immatriculée au registre du commerce et des sociétés de Paris sous le numéro 444 420 830
8
  * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
9
  */
10
 
1
  /**
2
+ * DPD France v5.1.2 shipping module for Magento
3
  *
4
  * @category DPDFrance
5
  * @package DPDFrance_Shipping
6
+ * @author DPD France S.A.S. <ensavoirplus.ecommerce@dpd.fr>
7
+ * @copyright 2015 DPD France S.A.S., société par actions simplifiée, au capital de 18.500.000 euros, dont le siège social est situé 27 Rue du Colonel Pierre Avia - 75015 PARIS, immatriculée au registre du commerce et des sociétés de Paris sous le numéro 444 420 830
8
  * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
9
  */
10