DPDFrance_Shipping - Version 5.1.0

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.0
Comparing to
See all releases


Version 5.1.0

Files changed (79) hide show
  1. app/code/community/DPDFrance/Classic/Helper/Data.php +14 -0
  2. app/code/community/DPDFrance/Classic/Model/Carrier/DPDFranceClassicShipping.php +401 -0
  3. app/code/community/DPDFrance/Classic/Model/Owebia.php +1174 -0
  4. app/code/community/DPDFrance/Classic/etc/config.xml +235 -0
  5. app/code/community/DPDFrance/Classic/etc/system.xml +107 -0
  6. app/code/community/DPDFrance/Export/Block/Export/Orders.php +22 -0
  7. app/code/community/DPDFrance/Export/Block/Export/Orders/Grid.php +427 -0
  8. app/code/community/DPDFrance/Export/Block/Tracking/Orders.php +22 -0
  9. app/code/community/DPDFrance/Export/Block/Tracking/Orders/Grid.php +212 -0
  10. app/code/community/DPDFrance/Export/Helper/Data.php +14 -0
  11. app/code/community/DPDFrance/Export/controllers/ExportController.php +466 -0
  12. app/code/community/DPDFrance/Export/controllers/TrackingController.php +238 -0
  13. app/code/community/DPDFrance/Export/etc/config.xml +115 -0
  14. app/code/community/DPDFrance/Predict/Helper/Data.php +14 -0
  15. app/code/community/DPDFrance/Predict/Model/Carrier/DPDFrancePredictShipping.php +401 -0
  16. app/code/community/DPDFrance/Predict/Model/Observer.php +41 -0
  17. app/code/community/DPDFrance/Predict/Model/Owebia.php +1174 -0
  18. app/code/community/DPDFrance/Predict/etc/config.xml +186 -0
  19. app/code/community/DPDFrance/Predict/etc/system.xml +107 -0
  20. app/code/community/DPDFrance/Relais/Helper/Data.php +15 -0
  21. app/code/community/DPDFrance/Relais/Model/Carrier/DPDFranceRelaisShipping.php +402 -0
  22. app/code/community/DPDFrance/Relais/Model/Observer.php +113 -0
  23. app/code/community/DPDFrance/Relais/Model/Outputs.php +85 -0
  24. app/code/community/DPDFrance/Relais/Model/Owebia.php +1175 -0
  25. app/code/community/DPDFrance/Relais/controllers/DPDFranceRelaisController.php +232 -0
  26. app/code/community/DPDFrance/Relais/etc/config.xml +189 -0
  27. app/code/community/DPDFrance/Relais/etc/system.xml +131 -0
  28. app/design/frontend/base/default/layout/dpdfrpredict.xml +49 -0
  29. app/design/frontend/base/default/layout/dpdfrrelais.xml +53 -0
  30. app/design/frontend/base/default/template/dpdfrpredict/checkout/onepage/progress/shipping.phtml +13 -0
  31. app/design/frontend/base/default/template/dpdfrpredict/checkout/onepage/progress/shipping_method.phtml +65 -0
  32. app/design/frontend/base/default/template/dpdfrpredict/checkout/onepage/shipping_method.phtml +31 -0
  33. app/design/frontend/base/default/template/dpdfrpredict/checkout/onepage/shipping_method/available.phtml +112 -0
  34. app/design/frontend/base/default/template/dpdfrrelais/checkout/onepage/progress/shipping.phtml +13 -0
  35. app/design/frontend/base/default/template/dpdfrrelais/checkout/onepage/progress/shipping_method.phtml +65 -0
  36. app/design/frontend/base/default/template/dpdfrrelais/checkout/onepage/shipping_method.phtml +31 -0
  37. app/design/frontend/base/default/template/dpdfrrelais/checkout/onepage/shipping_method/available.phtml +112 -0
  38. app/etc/modules/DPDFrance_Classic.xml +9 -0
  39. app/etc/modules/DPDFrance_Export.xml +9 -0
  40. app/etc/modules/DPDFrance_Predict.xml +9 -0
  41. app/etc/modules/DPDFrance_Relais.xml +9 -0
  42. app/locale/en_US/DPDFrance_Classic.csv +11 -0
  43. app/locale/en_US/DPDFrance_Export.csv +9 -0
  44. app/locale/en_US/DPDFrance_Predict.csv +25 -0
  45. app/locale/en_US/DPDFrance_Relais.csv +55 -0
  46. app/locale/fr_FR/DPDFrance_Classic.csv +11 -0
  47. app/locale/fr_FR/DPDFrance_Export.csv +9 -0
  48. app/locale/fr_FR/DPDFrance_Predict.csv +24 -0
  49. app/locale/fr_FR/DPDFrance_Relais.csv +54 -0
  50. media/dpdfrance/admin/logo.png +0 -0
  51. media/dpdfrance/admin/rss_icon.png +0 -0
  52. media/dpdfrance/admin/service_dom.png +0 -0
  53. media/dpdfrance/admin/service_predict.png +0 -0
  54. media/dpdfrance/admin/service_relais.png +0 -0
  55. media/dpdfrance/admin/service_world.png +0 -0
  56. media/dpdfrance/fonts/PlutoSansDPDExtraLight-Web.ttf +0 -0
  57. media/dpdfrance/fonts/PlutoSansDPDLight-Web.ttf +0 -0
  58. media/dpdfrance/fonts/PlutoSansDPDRegular-Web.ttf +0 -0
  59. media/dpdfrance/fonts/PlutoSansDPDThin-Web.ttf +0 -0
  60. media/dpdfrance/front/predict/carrier_logo.jpg +0 -0
  61. media/dpdfrance/front/predict/carrier_logo_alt.jpg +0 -0
  62. media/dpdfrance/front/predict/dpd_logo.png +0 -0
  63. media/dpdfrance/front/predict/dpd_predict_logo.png +0 -0
  64. media/dpdfrance/front/predict/predict_receive.jpg +0 -0
  65. media/dpdfrance/front/relais/DPD_Logo.png +0 -0
  66. media/dpdfrance/front/relais/carrier_logo.jpg +0 -0
  67. media/dpdfrance/front/relais/carrier_logo_alt.jpg +0 -0
  68. media/dpdfrance/front/relais/horaires.png +0 -0
  69. media/dpdfrance/front/relais/info.png +0 -0
  70. media/dpdfrance/front/relais/loader.gif +0 -0
  71. media/dpdfrance/front/relais/logo-max-png.png +0 -0
  72. media/dpdfrance/front/relais/pointrelais.png +0 -0
  73. media/dpdfrance/front/relais/warning.png +0 -0
  74. media/dpdfrance/readme_dpdfrance_magento.pdf +0 -0
  75. package.xml +19 -0
  76. skin/frontend/base/default/css/dpdfrance/dpdfrpredict.css +224 -0
  77. skin/frontend/base/default/css/dpdfrance/dpdfrrelais.css +799 -0
  78. skin/frontend/base/default/js/dpdfrance/dpdfrpredict.js +78 -0
  79. skin/frontend/base/default/js/dpdfrance/dpdfrrelais.js +128 -0
app/code/community/DPDFrance/Classic/Helper/Data.php ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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_Helper_Data extends Mage_Core_Helper_Abstract {
13
+ }
14
+ ?>
app/code/community/DPDFrance/Classic/Model/Carrier/DPDFranceClassicShipping.php ADDED
@@ -0,0 +1,401 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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();
32
+ $config = $this->_getConfig();
33
+ $allowed_methods = array();
34
+ if (count($config)>0) {
35
+ foreach ($config as $row){
36
+ $allowed_methods[$row['*code']] = isset($row['label']['value']) ? $row['label']['value'] : 'No label';
37
+ }
38
+ }
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;
65
+ // $items_in_cart = $process->getData('all_items');
66
+ $tax_amount = 0;
67
+ if (count($items_in_cart)>0)
68
+ {
69
+ foreach ($items_in_cart as $item)
70
+ {
71
+ $calc = Mage::getSingleton('tax/calculation');
72
+ $rates = $calc->getRatesForAllProductTaxClasses($calc->getRateRequest());
73
+ $vat_rate = isset($rates[$item->getProduct()->getTaxClassId()]) ? $rates[$item->getProduct()->getTaxClassId()] : 0;
74
+ // var_dump($calc, $rates, $vat_rate);exit;
75
+ if ($vat_rate > 0){
76
+ $vat_to_add = $item->getData('row_total')*$vat_rate/100;
77
+ // var_dump($vat_to_add);exit;
78
+ } else {
79
+ $vat_to_add = $item->getData('tax_amount');
80
+ }
81
+ $tax_amount += $vat_to_add;
82
+ }
83
+ }
84
+ // var_dump($tax_amount);exit;
85
+ return $tax_amount;
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');
280
+ $longueurcargo = strlen($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)
288
+ ->addData(array('status'=>'<script type="text/javascript">window.resizeTo(1280,800);</script><iframe src="'.$trackingUrlByRef.'" style="border: none;" width="1024" height="800"/>'));
289
+
290
+ $trackingResult = Mage::getModel('shipping/tracking_result')
291
+ ->append($trackingStatus);
292
+ if($trackings = $trackingResult->getAllTrackings())
293
+ return $trackings[0];
294
+ return false;
295
+ }else{
296
+ $trackingStatus = Mage::getModel('shipping/tracking_result_status')
297
+ ->setCarrier('dpdfrclassic')
298
+ ->setCarrierTitle('DPD Classic')
299
+ ->setTracking($trackingNumber)
300
+ ->addData(array('status'=>'<script type="text/javascript">window.resizeTo(1280,800);</script><iframe src="'.$trackingUrlByNb.'" style="border: none;" width="1024" height="800"/>'));
301
+
302
+ $trackingResult = Mage::getModel('shipping/tracking_result')
303
+ ->append($trackingStatus);
304
+ if($trackings = $trackingResult->getAllTrackings())
305
+ return $trackings[0];
306
+ return false;
307
+ }
308
+ }
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 ADDED
@@ -0,0 +1,1174 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
+
1174
+ ?>
app/code/community/DPDFrance/Classic/etc/config.xml ADDED
@@ -0,0 +1,235 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
+ <default>
15
+ <carriers>
16
+ <dpdfrclassic>
17
+ <group>dpdfrclassic</group>
18
+ <sallowspecific>0</sallowspecific>
19
+ <model>dpdfrclassic/carrier_DPDFranceClassicShipping</model>
20
+ <name>DPD Classic</name>
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>
131
+ </carriers>
132
+ </default>
133
+ <modules>
134
+ <DPDFrance_Classic>
135
+ <version>5.0.0</version>
136
+ <depends>
137
+ <Mage_Shipping/>
138
+ </depends>
139
+ </DPDFrance_Classic>
140
+ </modules>
141
+ <global>
142
+ <blocks>
143
+ <dpdfrclassic>
144
+ <class>DPDFrance_Classic_Block</class>
145
+ </dpdfrclassic>
146
+ </blocks>
147
+ <helpers>
148
+ <dpdfrclassic>
149
+ <class>DPDFrance_Classic_Helper</class>
150
+ </dpdfrclassic>
151
+ </helpers>
152
+ <models>
153
+ <dpdfrclassic>
154
+ <class>DPDFrance_Classic_Model</class>
155
+ </dpdfrclassic>
156
+ </models>
157
+ <resources>
158
+ <dpdfrclassic_setup>
159
+ <setup>
160
+ <module>DPDFrance_Classic</module>
161
+ </setup>
162
+ <connection>
163
+ <use>core_setup</use>
164
+ </connection>
165
+ </dpdfrclassic_setup>
166
+ <dpdfrclassic_write>
167
+ <connection>
168
+ <use>core_write</use>
169
+ </connection>
170
+ </dpdfrclassic_write>
171
+ <dpdfrclassic_read>
172
+ <connection>
173
+ <use>core_read</use>
174
+ </connection>
175
+ </dpdfrclassic_read>
176
+ </resources>
177
+ </global>
178
+ <adminhtml>
179
+ <translate>
180
+ <modules>
181
+ <Mage_Shipping>
182
+ <files>
183
+ <DPDFrance_Classic>DPDFrance_Classic.csv</DPDFrance_Classic>
184
+ </files>
185
+ </Mage_Shipping>
186
+ </modules>
187
+ </translate>
188
+ <acl>
189
+ <resources>
190
+ <admin>
191
+ <children>
192
+ <system>
193
+ <children>
194
+ <config>
195
+ <children>
196
+ <dpdfrclassic>
197
+ <title>DPD Classic</title>
198
+ </dpdfrclassic>
199
+ </children>
200
+ </config>
201
+ </children>
202
+ </system>
203
+ </children>
204
+ </admin>
205
+ </resources>
206
+ </acl>
207
+ </adminhtml>
208
+ <frontend>
209
+ <layout>
210
+ <updates>
211
+ <dpdfrclassic module="DPDFrance_Classic">
212
+ <file>dpdfrclassic.xml</file>
213
+ </dpdfrclassic>
214
+ </updates>
215
+ </layout>
216
+ <routers>
217
+ <dpdfrclassic>
218
+ <use>standard</use>
219
+ <args>
220
+ <module>DPDFrance_Classic</module>
221
+ <frontName>dpdfrclassic</frontName>
222
+ </args>
223
+ </dpdfrclassic>
224
+ </routers>
225
+ <translate>
226
+ <modules>
227
+ <Mage_Shipping>
228
+ <files>
229
+ <DPDFrance_Classic>DPDFrance_Classic.csv</DPDFrance_Classic>
230
+ </files>
231
+ </Mage_Shipping>
232
+ </modules>
233
+ </translate>
234
+ </frontend>
235
+ </config>
app/code/community/DPDFrance/Classic/etc/system.xml ADDED
@@ -0,0 +1,107 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
+ <sections>
15
+ <carriers>
16
+ <groups>
17
+ <dpdfrclassic translate="label" module="shipping">
18
+ <label>Livraison DPD CLASSIC (France : livraison sur lieu de travail) - DPD CLASSIC Europe et Intercontinental</label>
19
+ <comment><![CDATA[<strong>Veuillez configurer la livraison DPD CLASSIC ci-dessous.</strong><br />Pour de l'aide, veuillez vous référez à la documentation de ce module disponible ici : <a href="../../../../../../../../media/dpdfrance/readme_dpdfrance_magento.pdf" target="_blank">PDF</a>]]></comment>
20
+ <front-type>text</front-type>
21
+ <sort_order>-98</sort_order>
22
+ <show_in_default>1</show_in_default>
23
+ <show_in_website>1</show_in_website>
24
+ <show_in_store>1</show_in_store>
25
+ <fields>
26
+ <active translate="label">
27
+ <label>Enabled</label>
28
+ <frontend_type>select</frontend_type>
29
+ <source_model>adminhtml/system_config_source_yesno</source_model>
30
+ <sort_order>1</sort_order>
31
+ <show_in_default>1</show_in_default>
32
+ <show_in_website>1</show_in_website>
33
+ <show_in_store>1</show_in_store>
34
+ </active>
35
+ <title translate="label">
36
+ <label>Title</label>
37
+ <front_type>text</front_type>
38
+ <sort_order>2</sort_order>
39
+ <show_in_default>1</show_in_default>
40
+ <show_in_website>1</show_in_website>
41
+ <show_in_store>1</show_in_store>
42
+ </title>
43
+ <methodname translate="label">
44
+ <label>Subtitle</label>
45
+ <front_type>text</front_type>
46
+ <sort_order>3</sort_order>
47
+ <show_in_default>1</show_in_default>
48
+ <show_in_website>1</show_in_website>
49
+ <show_in_store>1</show_in_store>
50
+ </methodname>
51
+ <depot translate="label">
52
+ <label>Your DPD Depot #</label>
53
+ <front_type>text</front_type>
54
+ <sort_order>7</sort_order>
55
+ <show_in_default>1</show_in_default>
56
+ <show_in_website>1</show_in_website>
57
+ <show_in_store>1</show_in_store>
58
+ <comment><![CDATA[Sur 3 chiffres (ex.: 013)</a>]]></comment>
59
+ </depot>
60
+ <cargo translate="label">
61
+ <label>Your DPD CLASSIC contract #</label>
62
+ <front_type>text</front_type>
63
+ <sort_order>8</sort_order>
64
+ <show_in_default>1</show_in_default>
65
+ <show_in_website>1</show_in_website>
66
+ <show_in_store>1</show_in_store>
67
+ <comment><![CDATA[Sur 4 ou 5 chiffres, sans code agence, sans espace, sans tiret ni zéros devant</a>]]></comment>
68
+ </cargo>
69
+ <expense translate="label">
70
+ <label>Shipping rates configuration</label>
71
+ <frontend_type>textarea</frontend_type>
72
+ <sort_order>10</sort_order>
73
+ <show_in_default>1</show_in_default>
74
+ <show_in_website>1</show_in_website>
75
+ <show_in_store>1</show_in_store>
76
+ </expense>
77
+ <showerror translate="label">
78
+ <label>Display when unavailable</label>
79
+ <frontend_type>select</frontend_type>
80
+ <source_model>adminhtml/system_config_source_yesno</source_model>
81
+ <sort_order>15</sort_order>
82
+ <show_in_default>1</show_in_default>
83
+ <show_in_website>1</show_in_website>
84
+ <show_in_store>1</show_in_store>
85
+ </showerror>
86
+ <specificerrmsg translate="label">
87
+ <label>Displayed Error Message</label>
88
+ <frontend_type>textarea</frontend_type>
89
+ <sort_order>16</sort_order>
90
+ <show_in_default>1</show_in_default>
91
+ <show_in_website>1</show_in_website>
92
+ <show_in_store>1</show_in_store>
93
+ </specificerrmsg>
94
+ <sort_order translate="label">
95
+ <label>Sort Order</label>
96
+ <frontend_type>text</frontend_type>
97
+ <sort_order>270</sort_order>
98
+ <show_in_default>1</show_in_default>
99
+ <show_in_website>1</show_in_website>
100
+ <show_in_store>0</show_in_store>
101
+ </sort_order>
102
+ </fields>
103
+ </dpdfrclassic>
104
+ </groups>
105
+ </carriers>
106
+ </sections>
107
+ </config>
app/code/community/DPDFrance/Export/Block/Export/Orders.php ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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_Export_Block_Export_Orders extends Mage_Adminhtml_Block_Widget_Grid_Container
13
+ {
14
+ public function __construct()
15
+ {
16
+ $this->_blockGroup = 'export';
17
+ $this->_controller = 'export_orders';
18
+ $this->_headerText = '<img src="'.Mage::getBaseUrl('media').'dpdfrance/admin/logo.png"/> <span style="color:#424143;">'.Mage::helper('export')->__('Orders management').'</span>';
19
+ parent::__construct();
20
+ $this->_removeButton('add');
21
+ }
22
+ }
app/code/community/DPDFrance/Export/Block/Export/Orders/Grid.php ADDED
@@ -0,0 +1,427 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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_Export_Block_Export_Orders_Grid extends Mage_Adminhtml_Block_Widget_Grid
13
+ {
14
+ /**
15
+ * Constructor
16
+ */
17
+ public function __construct()
18
+ {
19
+ parent::__construct();
20
+ $this->setId('export_export_order_grid');
21
+ $this->setDefaultSort('created_at');
22
+ $this->setDefaultDir('DESC');
23
+ $this->setSaveParametersInSession(true);
24
+ }
25
+
26
+ /**
27
+ * Prepare order collection (for different Magento versions)
28
+ * @return DPDFrance_Export_Block_Export_Orders_Grid
29
+ */
30
+ protected function _prepareCollection()
31
+ {
32
+ if (version_compare(Mage::getVersion(), '1.4.1', '>=')) {
33
+ $collection = Mage::getResourceModel('sales/order_grid_collection')
34
+ ->join('order', "main_table.entity_id = order.entity_id AND order.shipping_method like 'dpdfr%' AND order.status != 'complete' AND order.status != 'canceled' AND order.status != 'holded' AND order.status != 'closed'", array('weight', 'shipping_method'))
35
+ ->join('order_address', "main_table.entity_id = order_address.parent_id AND order_address.address_type = 'shipping'", array('postcode as shipping_postcode', 'city as shipping_city', 'company as shipping_company', 'street as shipping_street', 'country_id as shipping_country_id'));
36
+ } else {
37
+ $collection = Mage::getResourceModel('sales/order_collection')
38
+ ->addAttributeToFilter('shipping_method', array('like' => 'dpdfr%'))
39
+ ->addAttributeToFilter('status', array('neq' => 'holded'))
40
+ ->addAttributeToFilter('status', array('neq' => 'complete'))
41
+ ->addAttributeToFilter('status', array('neq' => 'canceled'))
42
+ ->addAttributeToFilter('status', array('neq' => 'closed'))
43
+ ->addAttributeToSelect(array('status', 'shipping_method', 'weight'))
44
+ ->joinAttribute('shipping_company', 'order_address/company', 'shipping_address_id', null, 'left')
45
+ ->joinAttribute('shipping_firstname', 'order_address/firstname', 'shipping_address_id', null, 'left')
46
+ ->joinAttribute('shipping_lastname', 'order_address/lastname', 'shipping_address_id', null, 'left')
47
+ ->joinAttribute('shipping_street', 'order_address/street', 'shipping_address_id', null, 'left')
48
+ ->joinAttribute('shipping_postcode', 'order_address/postcode', 'shipping_address_id', null, 'left')
49
+ ->joinAttribute('shipping_city', 'order_address/city', 'shipping_address_id', null, 'left')
50
+ ->joinAttribute('shipping_country_id', 'order_address/country_id', 'shipping_address_id', null, 'left')
51
+
52
+ ->addExpressionAttributeToSelect(
53
+ 'shipping_name',
54
+ 'CONCAT({{shipping_firstname}}, " ", {{shipping_lastname}})',
55
+ array('shipping_firstname', 'shipping_lastname')
56
+ );
57
+ }
58
+
59
+ $this->setCollection($collection);
60
+ return parent::_prepareCollection();
61
+ }
62
+
63
+ /**
64
+ * Prepare grid columns (for different Magento versions)
65
+ * @return DPDFrance_Export_Block_Export_Orders_Grid
66
+ */
67
+ protected function _prepareColumns(){
68
+
69
+ // Javascript remplacer les modes de livraison par des icones
70
+ echo '
71
+ <body onLoad="LoadMyJs()">
72
+ <style media="screen" type="text/css">
73
+ @font-face
74
+ {
75
+ font-family:DPDPlutoSansExtraLight;
76
+ src:url('.Mage::getBaseUrl('media').'dpdfrance/fonts/PlutoSansDPDExtraLight-Web.ttf);
77
+ }
78
+
79
+ @font-face
80
+ {
81
+ font-family:DPDPlutoSansLight;
82
+ src:url('.Mage::getBaseUrl('media').'dpdfrance/fonts/PlutoSansDPDLight-Web.ttf);
83
+ }
84
+
85
+ @font-face
86
+ {
87
+ font-family:DPDPlutoSansRegular;
88
+ src:url('.Mage::getBaseUrl('media').'dpdfrance/fonts/PlutoSansDPDRegular-Web.ttf);
89
+ }
90
+ #rss_logo p {
91
+ display: inline-block;
92
+ vertical-align: middle;
93
+ }
94
+ #button_hide a {
95
+ margin: 0 auto;
96
+ }
97
+ h3.icon-head.head-export-orders span {
98
+ font-family: DPDPlutoSansRegular !important;
99
+ color: #424143 !important;
100
+ }
101
+ </style>
102
+ <script type="text/javascript">
103
+ function LoadMyJs() {
104
+ var d = document.getElementById("export_export_order_grid_table").children[2]
105
+ if (d)
106
+ {
107
+ for(var i = 0; i < d.childNodes.length; i++)
108
+ {
109
+ if (d.childNodes[i].nodeType == 1)
110
+ if (d.childNodes[i].children[5].innerHTML.search("dpdfrclassic_") > 0 && d.childNodes[i].children[10].innerHTML.search("FR") > 0)
111
+ d.childNodes[i].children[5].innerHTML = "<img title=\"Classic\" alt=\"Classic\" src=\"'.Mage::getBaseUrl('media').'dpdfrance/admin/service_dom.png\"/>";
112
+ else
113
+ if (d.childNodes[i].children[5].innerHTML.search("dpdfrclassic_") > 0 && d.childNodes[i].children[10].innerHTML.search("FR") < 0)
114
+ d.childNodes[i].children[5].innerHTML = "<img title=\"Intercontinental\" alt=\"Intercontinental\" src=\"'.Mage::getBaseUrl('media').'dpdfrance/admin/service_world.png\"/>";
115
+ else
116
+ if (d.childNodes[i].children[5].innerHTML.search("dpdfrrelais_") > 0)
117
+ d.childNodes[i].children[5].innerHTML = "<img title=\"Relais\" alt=\"Relais\" src=\"'.Mage::getBaseUrl('media').'dpdfrance/admin/service_relais.png\"/>";
118
+ else
119
+ if (d.childNodes[i].children[5].innerHTML.search("dpdfrpredict_") > 0)
120
+ d.childNodes[i].children[5].innerHTML = "<img title=\"Predict\" alt=\"Predict\" src=\"'.Mage::getBaseUrl('media').'dpdfrance/admin/service_predict.png\"/>";
121
+ }
122
+ }
123
+ }
124
+ </script>
125
+ ';
126
+
127
+ // Flux RSS
128
+ $rss_location = 'http://www.dpd.fr/extensions/rss/flux_info_dpdfr.xml';
129
+ if (@simplexml_load_file($rss_location))
130
+ {
131
+ $rss = simplexml_load_file($rss_location);
132
+ if (!empty($rss->channel->item))
133
+ {
134
+ echo '
135
+
136
+ <script type="text/javascript">
137
+ function show_rss(){
138
+ document.getElementById("div_rss").style.display="block";
139
+ document.getElementById("button_show").style.display="none";
140
+ document.getElementById("button_hide").style.display="block";
141
+ }
142
+ function hide_rss(){
143
+ document.getElementById("div_rss").style.display = "none";
144
+ document.getElementById("button_show").style.display = "block";
145
+ document.getElementById("button_hide").style.display = "none";
146
+ }
147
+ function setup(){
148
+ $(\'moverlo\').update($(\'moverlo\').innerHTML.times(10));
149
+ }
150
+ function MoveNoticias(){
151
+ new Effect.Move(\'moverlo\', {
152
+ x:-40,
153
+ y:0,
154
+ mode:\'relative\',
155
+ transition:Effect.Transitions.linear,
156
+ afterFinish:MoveNoticias
157
+ });
158
+ }
159
+ Event.observe(window, "load", function(){
160
+ setup();
161
+ MoveNoticias();
162
+ });
163
+ </script>
164
+
165
+ <div id="div_header" style="font-family:DPDPlutoSansLight; width:300px;margin-left: 20px;">
166
+ <div id="rss_logo" style="float:left; width:135px; height:24px; margin-top:-7px;">
167
+ <img src="'.Mage::getBaseUrl('media').'dpdfrance/admin/rss_icon.png" width="24" height="24"/><p> '.Mage::helper('export')->__('DPD News').'</p>
168
+ </div>
169
+ <div id="button_show" style="display:none;">
170
+ <a style="float:left;margin-left:0px;text-decoration: none;color: #424143;height: 24px;width: 24px;font-size: 32px;" href="javascript:void(0)" onclick="show_rss()">+</a>
171
+ </div>
172
+ <div id="button_hide">
173
+ <a style="float:left;margin-left:0px;text-decoration: none;color: #424143;height: 24px;width: 24px;font-size: 32px;" href="javascript:void(0)" onclick="hide_rss()">-</a>
174
+ </div>
175
+ </div>
176
+ <br/>
177
+ ';
178
+ echo '
179
+ <div id="div_rss" style="font-family:DPDPlutoSansLight; display:block; background-color: #e6e7e7; color: #424143; border-style: none; margin-left: 20px; margin-right: 20px; margin-top: 10px; padding: 10px;white-space:nowrap;overflow:hidden"><div id="moverlo">';
180
+ foreach ($rss->channel->item as $item)
181
+ echo '<strong style="font-family:DPDPlutoSansRegular; color:#dc0032;">'.$item->category.' > '.$item->title.' : </strong> '.$item->description.'&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;';
182
+ echo '</div></div></div><br/>';
183
+ }
184
+ }
185
+ // Fin flux RSS
186
+
187
+ $columnData = array(
188
+ 'header'=> Mage::helper('sales')->__('Order #'),
189
+ 'width' => '70px',
190
+ 'type' => 'text',
191
+ 'index' => 'increment_id',
192
+ );
193
+ if (version_compare(Mage::getVersion(), '1.4.1', '>=')) {
194
+ $columnData['filter_index'] = 'main_table.'.$columnData['index'];
195
+ }
196
+ $this->addColumn('real_order_id', $columnData);
197
+
198
+ if (!Mage::app()->isSingleStoreMode()) {
199
+ $this->addColumn(
200
+ 'store_id', array(
201
+ 'header' => Mage::helper('sales')->__('Store'),
202
+ 'index' => 'store_id',
203
+ 'type' => 'store',
204
+ 'store_view'=> true,
205
+ 'display_deleted' => true,
206
+ 'width' => '80px',
207
+ )
208
+ );
209
+ }
210
+
211
+ $columnData = array(
212
+ 'header' => Mage::helper('sales')->__('Purchased On'),
213
+ 'index' => 'created_at',
214
+ 'type' => 'datetime',
215
+ 'width' => '120px',
216
+ );
217
+ if (version_compare(Mage::getVersion(), '1.4.1', '>=')) {
218
+ $columnData['filter_index'] = 'main_table.'.$columnData['index'];
219
+ }
220
+ $this->addColumn('created_at', $columnData);
221
+
222
+ $this->addColumn(
223
+ 'shipping_name', array(
224
+ 'header' => Mage::helper('sales')->__('Ship to Name'),
225
+ 'index' => 'shipping_name',
226
+ 'width' => '150px',
227
+ )
228
+ );
229
+
230
+ $columnData = array(
231
+ 'header' => 'Service',
232
+ 'index' => 'shipping_method',
233
+ 'width' => '30px',
234
+ 'type' => 'options',
235
+ 'options' => $this->getDPDFranceCarriersOnly()
236
+ );
237
+ $this->addColumn('shipping_method', $columnData);
238
+
239
+ $columnData = array(
240
+ 'header' => Mage::helper('sales')->__('Company').' / '.Mage::helper('export')->__('DPD Pickup point'),
241
+ 'index' => 'shipping_company',
242
+ 'width' => '140px',
243
+ );
244
+ if (version_compare(Mage::getVersion(), '1.4.1', '>=')) {
245
+ $columnData['filter_index'] = 'main_table.'.$columnData['index'];
246
+ }
247
+ $this->addColumn('shipping_company', $columnData);
248
+
249
+ $columnData = array(
250
+ 'header' => Mage::helper('sales')->__('Shipping Address'),
251
+ 'index' => 'shipping_street',
252
+ 'width' => '200px',
253
+ );
254
+ if (version_compare(Mage::getVersion(), '1.4.1', '>=')) {
255
+ $columnData['filter_index'] = 'main_table.'.$columnData['index'];
256
+ }
257
+ $this->addColumn('shipping_street', $columnData);
258
+
259
+ $columnData = array(
260
+ 'header' => Mage::helper('sales')->__('Code postal'),
261
+ 'index' => 'shipping_postcode',
262
+ 'width' => '40px',
263
+ );
264
+ if (version_compare(Mage::getVersion(), '1.4.1', '>=')) {
265
+ $columnData['filter_index'] = 'main_table.'.$columnData['index'];
266
+ }
267
+ $this->addColumn('shipping_postcode', $columnData);
268
+
269
+ $columnData = array(
270
+ 'header' => Mage::helper('sales')->__('City'),
271
+ 'index' => 'shipping_city',
272
+ 'width' => '160px',
273
+ );
274
+ if (version_compare(Mage::getVersion(), '1.4.1', '>=')) {
275
+ $columnData['filter_index'] = 'main_table.'.$columnData['index'];
276
+ }
277
+ $this->addColumn('shipping_city', $columnData);
278
+
279
+ $columnData = array(
280
+ 'header' => Mage::helper('sales')->__('Country'),
281
+ 'index' => 'shipping_country_id',
282
+ 'width' => '20px',
283
+ );
284
+ if (version_compare(Mage::getVersion(), '1.4.1', '>=')) {
285
+ $columnData['filter_index'] = 'main_table.'.$columnData['index'];
286
+ }
287
+ $this->addColumn('shipping_country_id', $columnData);
288
+
289
+ $columnData = array(
290
+ 'header' => Mage::helper('sales')->__('G.T. (Base)'),
291
+ 'index' => 'base_grand_total',
292
+ 'type' => 'currency',
293
+ 'currency' => 'base_currency_code'
294
+ );
295
+ if (version_compare(Mage::getVersion(), '1.4.1', '>=')) {
296
+ $columnData['filter_index'] = 'main_table.'.$columnData['index'];
297
+ }
298
+ $this->addColumn('base_grand_total', $columnData);
299
+
300
+ $this->addColumn(
301
+ 'weight', array(
302
+ 'header' => Mage::helper('sales')->__('Weight'),
303
+ 'index' => 'weight',
304
+ 'type' => 'weight',
305
+ 'width' => '40px',
306
+ )
307
+ );
308
+
309
+ $columnData = array(
310
+ 'header' => Mage::helper('sales')->__('Status'),
311
+ 'index' => 'status',
312
+ 'width' => '160px',
313
+ 'type' => 'options',
314
+ 'options' => Mage::getSingleton('sales/order_config')->getStatuses(),
315
+ );
316
+ if (version_compare(Mage::getVersion(), '1.4.1', '>=')) {
317
+ $columnData['filter_index'] = 'main_table.'.$columnData['index'];
318
+ }
319
+ $this->addColumn('status', $columnData);
320
+
321
+ if (Mage::getSingleton('admin/session')->isAllowed('sales/order/actions/view')) {
322
+
323
+ $this->addColumn(
324
+ 'action',
325
+ array(
326
+ 'header' => Mage::helper('sales')->__('Action'),
327
+ 'width' => '50px',
328
+ 'type' => 'action',
329
+ 'getter' => 'getId',
330
+ 'actions' => array(
331
+ array(
332
+ 'caption' => Mage::helper('sales')->__('View'),
333
+ 'url' => array('base'=>'adminhtml/sales_order/view'),
334
+ 'field' => 'order_id'
335
+ )
336
+ ),
337
+ 'filter' => false,
338
+ 'sortable' => false,
339
+ 'index' => 'stores',
340
+ 'is_system' => true,
341
+ )
342
+ );
343
+ }
344
+
345
+ return parent::_prepareColumns();
346
+ }
347
+
348
+ /**
349
+ * Prepare mass action (for different Magento versions)
350
+ * @return DPDFrance_Export_Block_Export_Orders_Grid
351
+ */
352
+ protected function _prepareMassaction()
353
+ {
354
+ $this->setMassactionIdField('entity_id');
355
+ $this->getMassactionBlock()->setFormFieldName('order_ids');
356
+ if (Mage::getVersion() >= '1.4.1') {
357
+ $this->getMassactionBlock()->setUseSelectAll(false);
358
+ }
359
+
360
+ // Menu "exporter les commandes - Assurance intégrée"
361
+ $this->getMassactionBlock()->addItem(
362
+ 'export_order', array(
363
+ 'label'=> Mage::helper('export')->__('Export to DPD Station - Integrated insurance'),
364
+ 'url' => $this->getUrl('*/*/export'),
365
+ )
366
+ );
367
+
368
+ // Menu "exporter les commandes - Assurance Ad Valorem"
369
+ $this->getMassactionBlock()->addItem(
370
+ 'exportav_order', array(
371
+ 'label'=> Mage::helper('export')->__('Export to DPD Station - Ad Valorem insurance'),
372
+ 'url' => $this->getUrl('*/*/exportav'),
373
+ )
374
+ );
375
+
376
+ // Menu "créer les trackings"
377
+ $this->getMassactionBlock()->addItem(
378
+ 'tracking_order', array(
379
+ 'label'=> Mage::helper('export')->__('Update sent orders'),
380
+ 'url' => $this->getUrl('*/tracking/tracking'),
381
+ )
382
+ );
383
+
384
+ return $this;
385
+ }
386
+
387
+ /**
388
+ * Get url called when user click on a grid row
389
+ * @return string|boolean
390
+ */
391
+ public function getRowUrl($row)
392
+ {
393
+ if (Mage::getSingleton('admin/session')->isAllowed('sales/order/actions/view'))
394
+ return $this->getUrl('adminhtml/sales_order/view', array('order_id' => $row->getId()));
395
+ return false;
396
+ }
397
+
398
+ /**
399
+ * Get grid url
400
+ * @return string
401
+ */
402
+ public function getGridUrl()
403
+ {
404
+ return $this->getUrl('*/*/*', array('_current'=>true));
405
+ }
406
+
407
+ /**
408
+ * Filtre les transporteurs possibles.
409
+ *
410
+ * @return array
411
+ */
412
+ public function getDPDFranceCarriersOnly()
413
+ {
414
+ $options = array();
415
+ if (version_compare(Mage::getVersion(), '1.4.1', '>=')) {
416
+ $collection = Mage::getResourceModel('sales/order_grid_collection')
417
+ ->join('order', "main_table.entity_id = order.entity_id AND order.shipping_method like 'dpdfr%'");
418
+ } else{
419
+ $collection = Mage::getResourceModel('sales/order_collection')
420
+ ->addAttributeToFilter('shipping_method', array('like' => 'dpdfr%'));
421
+ }
422
+ $this->setCollection($collection);
423
+ foreach ($collection as $option)
424
+ $options[$option->getShippingMethod()] = $option->getShippingMethod();
425
+ return $options;
426
+ }
427
+ }
app/code/community/DPDFrance/Export/Block/Tracking/Orders.php ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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_Export_Block_Tracking_Orders extends Mage_Adminhtml_Block_Widget_Grid_Container
13
+ {
14
+ public function __construct()
15
+ {
16
+ $this->_blockGroup = 'export';
17
+ $this->_controller = 'tracking_orders';
18
+ $this->_headerText = Mage::helper('export')->__('Suivi des colis DPD France');
19
+ parent::__construct();
20
+ $this->_removeButton('add');
21
+ }
22
+ }
app/code/community/DPDFrance/Export/Block/Tracking/Orders/Grid.php ADDED
@@ -0,0 +1,212 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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_Export_Block_Tracking_Orders_Grid extends Mage_Adminhtml_Block_Widget_Grid
13
+ {
14
+
15
+ /**
16
+ * Constructor
17
+ */
18
+ public function __construct()
19
+ {
20
+ parent::__construct();
21
+ $this->setId('export_tracking_order_grid');
22
+ $this->setDefaultSort('created_at');
23
+ $this->setDefaultDir('DESC');
24
+ $this->setSaveParametersInSession(true);
25
+ }
26
+
27
+ /**
28
+ * Prepare order collection (for different Magento versions)
29
+ * @return DPDFrance_Export_Block_Tracking_Orders_Grid
30
+ */
31
+ protected function _prepareCollection()
32
+ {
33
+ if (version_compare(Mage::getVersion(), '1.4', '>=')) {
34
+ $collection = Mage::getResourceModel('sales/order_grid_collection')
35
+ ->join('order', 'main_table.entity_id = order.entity_id', array('shipping_method'));
36
+
37
+ } else {
38
+ $collection = Mage::getResourceModel('sales/order_collection')
39
+ ->addAttributeToSelect(array('status', 'shipping_method'))
40
+ ->joinAttribute('billing_firstname', 'order_address/firstname', 'billing_address_id', null, 'left')
41
+ ->joinAttribute('billing_lastname', 'order_address/lastname', 'billing_address_id', null, 'left')
42
+ ->joinAttribute('shipping_firstname', 'order_address/firstname', 'shipping_address_id', null, 'left')
43
+ ->joinAttribute('shipping_lastname', 'order_address/lastname', 'shipping_address_id', null, 'left')
44
+ ->addExpressionAttributeToSelect(
45
+ 'billing_name',
46
+ 'CONCAT({{billing_firstname}}, " ", {{billing_lastname}})',
47
+ array('billing_firstname', 'billing_lastname')
48
+ )
49
+ ->addExpressionAttributeToSelect(
50
+ 'shipping_name',
51
+ 'CONCAT({{shipping_firstname}}, " ", {{shipping_lastname}})',
52
+ array('shipping_firstname', 'shipping_lastname')
53
+ );
54
+ }
55
+
56
+ $this->setCollection($collection);
57
+ return parent::_prepareCollection();
58
+ }
59
+
60
+ /**
61
+ * Prepare grid columns (for different Magento versions)
62
+ * @return DPDFrance_Export_Block_Tracking_Orders_Grid
63
+ */
64
+ protected function _prepareColumns()
65
+ {
66
+ $columnData = array(
67
+ 'header'=> Mage::helper('sales')->__('Order #'),
68
+ 'width' => '80px',
69
+ 'type' => 'text',
70
+ 'index' => 'increment_id',
71
+ );
72
+ if (version_compare(Mage::getVersion(), '1.4', '>=')) {
73
+ $columnData['filter_index'] = 'main_table.'.$columnData['index'];
74
+ }
75
+ $this->addColumn('real_order_id', $columnData);
76
+
77
+ if (!Mage::app()->isSingleStoreMode()) {
78
+ $this->addColumn(
79
+ 'store_id', array(
80
+ 'header' => Mage::helper('sales')->__('Purchased from (store)'),
81
+ 'index' => 'store_id',
82
+ 'type' => 'store',
83
+ 'store_view'=> true,
84
+ 'display_deleted' => true,
85
+ )
86
+ );
87
+ }
88
+
89
+ $columnData = array(
90
+ 'header' => Mage::helper('sales')->__('Purchased On'),
91
+ 'index' => 'created_at',
92
+ 'type' => 'datetime',
93
+ 'width' => '100px',
94
+ );
95
+ if (version_compare(Mage::getVersion(), '1.4', '>=')) {
96
+ $columnData['filter_index'] = 'main_table.'.$columnData['index'];
97
+ }
98
+ $this->addColumn('created_at', $columnData);
99
+
100
+ $this->addColumn(
101
+ 'billing_name', array(
102
+ 'header' => Mage::helper('sales')->__('Bill to Name'),
103
+ 'index' => 'billing_name',
104
+ )
105
+ );
106
+
107
+ $this->addColumn(
108
+ 'shipping_name', array(
109
+ 'header' => Mage::helper('sales')->__('Ship to Name'),
110
+ 'index' => 'shipping_name',
111
+ )
112
+ );
113
+
114
+ $columnData = array(
115
+ 'header' => Mage::helper('sales')->__('G.T. (Base)'),
116
+ 'index' => 'base_grand_total',
117
+ 'type' => 'currency',
118
+ 'currency' => 'base_currency_code'
119
+ );
120
+ if (version_compare(Mage::getVersion(), '1.4', '>=')) {
121
+ $columnData['filter_index'] = 'main_table.'.$columnData['index'];
122
+ }
123
+ $this->addColumn('base_grand_total', $columnData);
124
+
125
+ $this->addColumn(
126
+ 'carrier', array(
127
+ 'header' => Mage::helper('sales')->__('Carrier'),
128
+ 'index' => 'shipping_method',
129
+ )
130
+ );
131
+
132
+ $columnData = array(
133
+ 'header' => Mage::helper('sales')->__('Status'),
134
+ 'index' => 'status',
135
+ 'type' => 'options',
136
+ 'options' => Mage::getSingleton('sales/order_config')->getStatuses(),
137
+ );
138
+ if (version_compare(Mage::getVersion(), '1.4', '>=')) {
139
+ $columnData['filter_index'] = 'main_table.'.$columnData['index'];
140
+ }
141
+ $this->addColumn('status', $columnData);
142
+
143
+ if (Mage::getSingleton('admin/session')->isAllowed('sales/order/actions/view')) {
144
+ $this->addColumn(
145
+ 'action',
146
+ array(
147
+ 'header' => Mage::helper('sales')->__('Action'),
148
+ 'width' => '50px',
149
+ 'type' => 'action',
150
+ 'getter' => 'getId',
151
+ 'actions' => array(
152
+ array(
153
+ 'caption' => Mage::helper('sales')->__('View'),
154
+ 'url' => array('base'=>'adminhtml/sales_order/view'),
155
+ 'field' => 'order_id'
156
+ )
157
+ ),
158
+ 'filter' => false,
159
+ 'sortable' => false,
160
+ 'index' => 'stores',
161
+ 'is_system' => true,
162
+ )
163
+ );
164
+ }
165
+
166
+ return parent::_prepareColumns();
167
+ }
168
+
169
+ /**
170
+ * Prepare mass action (for different Magento versions)
171
+ * @return DPDFrance_Export_Block_Tracking_Orders_Grid
172
+ */
173
+ protected function _prepareMassaction()
174
+ {
175
+ $this->setMassactionIdField('entity_id');
176
+ $this->getMassactionBlock()->setFormFieldName('order_ids');
177
+ if (Mage::getVersion() >= '1.4.1') {
178
+ $this->getMassactionBlock()->setUseSelectAll(false);
179
+ }
180
+
181
+ $this->getMassactionBlock()->addItem(
182
+ 'tracking_order', array(
183
+ 'label'=> Mage::helper('export')->__('Generer les trackings'),
184
+ 'url' => $this->getUrl('*/*/tracking'),
185
+ )
186
+ );
187
+
188
+ return $this;
189
+ }
190
+
191
+ /**
192
+ * Get url called when user click on a grid row
193
+ * @return string|boolean
194
+ */
195
+ public function getRowUrl($row)
196
+ {
197
+ if (Mage::getSingleton('admin/session')->isAllowed('sales/order/actions/view')) {
198
+ return $this->getUrl('adminhtml/sales_order/view', array('order_id' => $row->getId()));
199
+ }
200
+ return false;
201
+ }
202
+
203
+ /**
204
+ * Get grid url
205
+ * @return string
206
+ */
207
+ public function getGridUrl()
208
+ {
209
+ return $this->getUrl('*/*/*', array('_current'=>true));
210
+ }
211
+
212
+ }
app/code/community/DPDFrance/Export/Helper/Data.php ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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_Export_Helper_Data extends Mage_Core_Helper_Abstract {
13
+ }
14
+ ?>
app/code/community/DPDFrance/Export/controllers/ExportController.php ADDED
@@ -0,0 +1,466 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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_Export_ExportController extends Mage_Adminhtml_Controller_Action
13
+ {
14
+
15
+ /**
16
+ * Constructor
17
+ */
18
+ protected function _construct()
19
+ {
20
+ $this->setUsedModuleName('DPDFrance_Export');
21
+ }
22
+
23
+ /**
24
+ * Main action : show orders list
25
+ */
26
+ public function indexAction() {
27
+ $this->loadLayout()
28
+ ->_setActiveMenu('sales/export/export')
29
+ ->_addContent($this->getLayout()->createBlock('export/export_orders'))
30
+ ->renderLayout();
31
+ }
32
+
33
+ public static function getIsoCodebyIdCountry($idcountry) // Récupere le code ISO du pays concerné et le convertit au format attendu par la Station DPD
34
+ {
35
+ $isops = array("DE", "AD", "AT", "BE", "BA", "BG", "HR", "DK", "ES", "EE", "FI", "FR", "GB", "GR", "GG", "HU", "IM", "IE", "IT", "JE", "LV", "LI", "LT", "LU", "NO", "NL", "PL", "PT", "CZ", "RO", "RS", "SK", "SI", "SE", "CH");
36
+ $isoep = array("D", "AND", "A", "B", "BA", "BG", "CRO", "DK", "E", "EST", "SF", "F", "GB", "GR", "GG", "H", "IM", "IRL", "I", "JE", "LET", "LIE", "LIT", "L", "N", "NL", "PL", "P", "CZ", "RO", "RS", "SK", "SLO", "S", "CH");
37
+
38
+ if(in_array($idcountry, $isops)){ // Si le code ISO est européen, on le convertit au format Station DPD
39
+ $code_iso = str_replace($isops, $isoep, $idcountry);
40
+ }
41
+ else{
42
+ $code_iso = str_replace($idcountry, "INT", $idcountry); // Si le code ISO n'est pas européen, on le passe en "INT" (intercontinental)
43
+ }
44
+ return $code_iso;
45
+ }
46
+ /**
47
+ * Export Action
48
+ * Generates a CSV file to download
49
+ */
50
+ public function exportAction() {
51
+ /* get the orders */
52
+ $orderIds = $this->getRequest()->getPost('order_ids');
53
+
54
+ /**
55
+ * Get configuration
56
+ */
57
+ $delimiter = '';
58
+ $lineBreak = "\r\n";
59
+
60
+ // Le format .dat est requis pour la Station DPD. Le charset est ASCII
61
+ $fileExtension = '.dat';
62
+ $fileCharset = 'ISO-8859-1';
63
+
64
+ /* set the filename */
65
+ $filename = 'DPDFRANCE_'.Mage::getSingleton('core/date')->date('dmY_His').$fileExtension;
66
+
67
+ /* initialize the content variable */
68
+ $content = '';
69
+
70
+ if (!empty($orderIds)) {
71
+
72
+ $content .= '$VERSION=110'.$lineBreak;
73
+
74
+ foreach ($orderIds as $orderId) {
75
+
76
+ /* get the order */
77
+ $order = Mage::getModel('sales/order')->load($orderId);
78
+
79
+ /* get the billing address */
80
+ $address = $order->getShippingAddress();
81
+
82
+ /* total weight */
83
+ $total_weight = 0;
84
+ $items = $order->getAllItems();
85
+ foreach ($items as $item) {
86
+ $total_weight += $item['row_weight'];
87
+ }
88
+
89
+ /* type of delivery */
90
+ $type = stristr($order->getShippingMethod(),'_', true);
91
+
92
+ /* shipper code determination */
93
+ switch ($type) {
94
+ case 'dpdfrrelais' :
95
+ $shipper_code = Mage::getStoreConfig('carriers/dpdfrrelais/cargo');
96
+ break;
97
+ case 'dpdfrpredict' :
98
+ $shipper_code = Mage::getStoreConfig('carriers/dpdfrpredict/cargo');
99
+ break;
100
+ case 'dpdfrclassic' :
101
+ $shipper_code = Mage::getStoreConfig('carriers/dpdfrclassic/cargo');
102
+ break;
103
+ }
104
+
105
+ $content = $this->_addFieldToCsv($content, $delimiter, $order->getRealOrderId(), 35); // Ref Commande Magento
106
+ $content = $this->_addFieldToCsv($content, $delimiter, '', 2); // Filler
107
+ $content = $this->_addFieldToCsv($content, $delimiter, floor($total_weight*100), 8, true ); // Poids
108
+ $content = $this->_addFieldToCsv($content, $delimiter, '', 15); // Filler
109
+ $firstnamecleaned = $this->_stripAccents($address->getFirstname());
110
+ $lastnamecleaned = $this->_stripAccents($address->getLastname());
111
+ if($type !== 'dpdfrrelais'){
112
+ $content = $this->_addFieldToCsv($content, $delimiter, $lastnamecleaned.' '.$firstnamecleaned, 35); // Nom et prénom (Relais)
113
+ $content = $this->_addFieldToCsv($content, $delimiter, '', 35);
114
+ } else {
115
+ $content = $this->_addFieldToCsv($content, $delimiter, $lastnamecleaned, 35); // Nom
116
+ $content = $this->_addFieldToCsv($content, $delimiter, $firstnamecleaned, 35);} // Prénom
117
+ $addr2cleaned = $this->_stripAccents($address->getCompany());
118
+ $content = $this->_addFieldToCsv($content, $delimiter, $addr2cleaned, 35); // Complément d'adresse 2 : Nom du PR + ID ou société
119
+ $addr3cleaned = $this->_stripAccents($address->getStreet(2));
120
+ $content = $this->_addFieldToCsv($content, $delimiter, $addr3cleaned, 35); // Complément d'adresse 3
121
+ $addr3cleaned = $this->_stripAccents($address->getStreet(3));
122
+ $content = $this->_addFieldToCsv($content, $delimiter, $addr3cleaned, 35); // Complément d'adresse 4
123
+ $addr4cleaned = $this->_stripAccents($address->getStreet(4));
124
+ $content = $this->_addFieldToCsv($content, $delimiter, $addr4cleaned, 35); // Complément d'adresse 5
125
+ $content = $this->_addFieldToCsv($content, $delimiter, $address->getPostcode(), 10); // Code postal
126
+ $city = $this->_stripAccents($address->getCity()); // Ville
127
+ $content = $this->_addFieldToCsv($content, $delimiter, $city, 35);
128
+ $content = $this->_addFieldToCsv($content, $delimiter, '', 10); // Filler
129
+ $addr1cleaned = $this->_stripAccents($address->getStreet(1)); // Rue
130
+ $content = $this->_addFieldToCsv($content, $delimiter, $addr1cleaned, 35);
131
+ $content = $this->_addFieldToCsv($content, $delimiter, '', 10); // Filler
132
+ $content = $this->_addFieldToCsv($content, $delimiter, $this->getIsoCodebyIdCountry($address->getCountry()), 3); // Code pays
133
+ $content = $this->_addFieldToCsv($content, $delimiter, $address->getTelephone(), 30); // Téléphone
134
+ $content = $this->_addFieldToCsv($content, $delimiter, '', 15); // Filler
135
+ $shippername = $this->_stripAccents(Mage::getStoreConfig('general/store_information/name'));
136
+ $content = $this->_addFieldToCsv($content, $delimiter, $shippername, 35); // Nom expéditeur
137
+ $shipperstreet2 = $this->_stripAccents(Mage::getStoreConfig('shipping/origin/street_line2'));
138
+ $content = $this->_addFieldToCsv($content, $delimiter, $shipperstreet2, 35); // Complément adresse 1
139
+ $content = $this->_addFieldToCsv($content, $delimiter, '', 35); // Filler
140
+ $content = $this->_addFieldToCsv($content, $delimiter, '', 35); // Filler
141
+ $content = $this->_addFieldToCsv($content, $delimiter, '', 35); // Filler
142
+ $content = $this->_addFieldToCsv($content, $delimiter, '', 35); // Filler
143
+ $shipperzipcode = $this->_stripAccents(Mage::getStoreConfig('shipping/origin/postcode'));
144
+ $content = $this->_addFieldToCsv($content, $delimiter, $shipperzipcode, 10); // Code postal
145
+ $shippercity = $this->_stripAccents(Mage::getStoreConfig('shipping/origin/city'));
146
+ $content = $this->_addFieldToCsv($content, $delimiter, $shippercity, 35); // Ville
147
+ $content = $this->_addFieldToCsv($content, $delimiter, '', 10); // Filler
148
+ if (version_compare(Mage::getVersion(), '1.5.1', '>='))
149
+ $shipperstreet = $this->_stripAccents(Mage::getStoreConfig('shipping/origin/street_line1'));
150
+ else{
151
+ $shipperstreet = explode(chr(10), $this->_stripAccents(Mage::getStoreConfig('general/store_information/address')));
152
+ $shipperstreet = $shipperstreet[0];
153
+ }
154
+ $content = $this->_addFieldToCsv($content, $delimiter, $shipperstreet, 35); // Rue
155
+ $content = $this->_addFieldToCsv($content, $delimiter, '', 10); // Filler
156
+ $content = $this->_addFieldToCsv($content, $delimiter, 'F', 3); // Code Pays F
157
+ $shipperphone = Mage::getStoreConfig('general/store_information/phone');
158
+ $content = $this->_addFieldToCsv($content, $delimiter, $shipperphone, 30); // Telephone
159
+ $content = $this->_addFieldToCsv($content, $delimiter, '', 35); // Filler
160
+ $content = $this->_addFieldToCsv($content, $delimiter, '', 35); // Filler
161
+ $content = $this->_addFieldToCsv($content, $delimiter, '', 35); // Filler
162
+ $content = $this->_addFieldToCsv($content, $delimiter, '', 35); // Filler
163
+ $content = $this->_addFieldToCsv($content, $delimiter, date('d/m/Y'), 10); // Date d'expédition théorique
164
+ $content = $this->_addFieldToCsv($content, $delimiter, $shipper_code, 8, true); // N° Compte chargeur
165
+ $content = $this->_addFieldToCsv($content, $delimiter, $order->getRealOrderId(), 35); // Code barres
166
+ $content = $this->_addFieldToCsv($content, $delimiter, $order->getRealOrderId(), 35); // N° Commande
167
+ $content = $this->_addFieldToCsv($content, $delimiter, '', 29); // Filler
168
+ $content = $this->_addFieldToCsv($content, $delimiter, '', 9); // Ad Valorem
169
+ $content = $this->_addFieldToCsv($content, $delimiter, '', 8); // Filler
170
+ $content = $this->_addFieldToCsv($content, $delimiter, '', 35); // Ref client 2
171
+ $content = $this->_addFieldToCsv($content, $delimiter, '', 1); // Filler
172
+ $content = $this->_addFieldToCsv($content, $delimiter, '', 35); // Filler
173
+ $content = $this->_addFieldToCsv($content, $delimiter, '', 10); // Filler
174
+ $shipperemail = Mage::getStoreConfig('trans_email/ident_general/email');
175
+ $content = $this->_addFieldToCsv($content, $delimiter, $shipperemail, 80); // E-mail expéditeur
176
+ $content = $this->_addFieldToCsv($content, $delimiter, '', 35); // GSM expéditeur
177
+ $content = $this->_addFieldToCsv($content, $delimiter, $order->getCustomerEmail(), 80); // E-mail destinataire
178
+ $prefixe = substr($address->getTelephone(),0,2);
179
+ if(($type !== 'dpdfrclassic' && $this->getIsoCodebyIdCountry($address->getCountry()) == 'F') && ($prefixe == 06 || $prefixe == 07))
180
+ $content = $this->_addFieldToCsv($content, $delimiter, $address->getTelephone(), 35);
181
+ else if($type == 'dpdfrclassic')
182
+ $content = $this->_addFieldToCsv($content, $delimiter, $address->getTelephone(), 35);
183
+ else
184
+ $content = $this->_addFieldToCsv($content, $delimiter, '', 35); // GSM destinataire
185
+ $content = $this->_addFieldToCsv($content, $delimiter, '', 96); // Filler
186
+ if($type == 'dpdfrrelais'){
187
+ preg_match('/P\d{5}/i', $address->getCompany(), $relayId);
188
+ $content = $this->_addFieldToCsv($content, $delimiter, $relayId[0], 8);} // Id point relais
189
+ else
190
+ $content = $this->_addFieldToCsv($content, $delimiter, '', 8);
191
+ $content = $this->_addFieldToCsv($content, $delimiter, '', 118); // Filler
192
+ /* Flag Predict */
193
+ if($type == 'dpdfrpredict' && $address->getTelephone() && $this->getIsoCodebyIdCountry($address->getCountry()) == 'F')
194
+ $content = $this->_addFieldToCsv($content, $delimiter,'+', 1);
195
+ else
196
+ $content = $this->_addFieldToCsv($content, $delimiter,'', 1);
197
+ /* Nom du contact */
198
+ $content = $this->_addFieldToCsv($content, $delimiter, $lastnamecleaned, 35);
199
+ $content = $this->_addFieldToCsv($content, $delimiter, '', 30); // Filler
200
+ $content .= $lineBreak; // CRLF
201
+ }
202
+
203
+ /* decode the content, depending on the charset */
204
+ if ($fileCharset == 'ISO-8859-1') {
205
+ $content = utf8_decode($content);
206
+ }
207
+
208
+ /* pick file mime type, depending on the extension */
209
+ if ($fileExtension == '.dat') {
210
+ $fileMimeType = 'text/plain';
211
+ } else if ($fileExtension == '.csv') {
212
+ $fileMimeType = 'application/csv';
213
+ } else {
214
+ // default
215
+ $fileMimeType = 'text/plain';
216
+ }
217
+
218
+ /* download the file */
219
+ return $this->_prepareDownloadResponse($filename, $content, $fileMimeType .'; charset="'. $fileCharset .'"');
220
+ }
221
+ else {
222
+ $this->_getSession()->addError($this->__('No Order has been selected'));
223
+ }
224
+ }
225
+
226
+ /**
227
+ * Export Action
228
+ * Generates a CSV file to download
229
+ */
230
+ public function exportavAction() {
231
+ /* get the orders */
232
+ $orderIds = $this->getRequest()->getPost('order_ids');
233
+
234
+ /**
235
+ * Get configuration
236
+ */
237
+ $delimiter = '';
238
+ $lineBreak = "\r\n";
239
+
240
+ // Le format .dat est requis pour la Station DPD. Le charset est ASCII
241
+ $fileExtension = '.dat';
242
+ $fileCharset = 'ISO-8859-1';
243
+
244
+ /* set the filename */
245
+ $filename = 'DPDFRANCE_'.Mage::getSingleton('core/date')->date('Ymd_His').$fileExtension;
246
+
247
+ /* initialize the content variable */
248
+ $content = '';
249
+
250
+ if (!empty($orderIds)) {
251
+
252
+ $content .= '$VERSION=110'.$lineBreak;
253
+
254
+ foreach ($orderIds as $orderId) {
255
+
256
+ /* get the order */
257
+ $order = Mage::getModel('sales/order')->load($orderId);
258
+
259
+ /* get the billing address */
260
+ $address = $order->getShippingAddress();
261
+
262
+ /* total weight */
263
+ $total_weight = 0;
264
+ $items = $order->getAllItems();
265
+ foreach ($items as $item) {
266
+ $total_weight += $item['row_weight'];
267
+ }
268
+
269
+ /* type of delivery */
270
+ $type = stristr($order->getShippingMethod(),'_', true);
271
+
272
+ /* shipper code determination */
273
+ switch ($type) {
274
+ case 'dpdfrrelais' :
275
+ $shipper_code = Mage::getStoreConfig('carriers/dpdfrrelais/cargo');
276
+ break;
277
+ case 'dpdfrpredict' :
278
+ $shipper_code = Mage::getStoreConfig('carriers/dpdfrpredict/cargo');
279
+ break;
280
+ case 'dpdfrclassic' :
281
+ $shipper_code = Mage::getStoreConfig('carriers/dpdfrclassic/cargo');
282
+ break;
283
+ }
284
+
285
+ $content = $this->_addFieldToCsv($content, $delimiter, $order->getRealOrderId(), 35); // Ref Commande Magento
286
+ $content = $this->_addFieldToCsv($content, $delimiter, '', 2); // Filler
287
+ $content = $this->_addFieldToCsv($content, $delimiter, floor($total_weight*100), 8, true ); // Poids
288
+ $content = $this->_addFieldToCsv($content, $delimiter, '', 15); // Filler
289
+ $firstnamecleaned = $this->_stripAccents($address->getFirstname());
290
+ $lastnamecleaned = $this->_stripAccents($address->getLastname());
291
+ if($type !== 'dpdfrrelais'){
292
+ $content = $this->_addFieldToCsv($content, $delimiter, $lastnamecleaned.' '.$firstnamecleaned, 35); // Nom et prénom (Relais)
293
+ $content = $this->_addFieldToCsv($content, $delimiter, '', 35);
294
+ } else {
295
+ $content = $this->_addFieldToCsv($content, $delimiter, $lastnamecleaned, 35); // Nom
296
+ $content = $this->_addFieldToCsv($content, $delimiter, $firstnamecleaned, 35);} // Prénom
297
+ $addr2cleaned = $this->_stripAccents($address->getCompany());
298
+ $content = $this->_addFieldToCsv($content, $delimiter, $addr2cleaned, 35); // Complément d'adresse 2 : Nom du PR + ID ou société
299
+ $addr3cleaned = $this->_stripAccents($address->getStreet(2));
300
+ $content = $this->_addFieldToCsv($content, $delimiter, $addr3cleaned, 35); // Complément d'adresse 3
301
+ $addr3cleaned = $this->_stripAccents($address->getStreet(3));
302
+ $content = $this->_addFieldToCsv($content, $delimiter, $addr3cleaned, 35); // Complément d'adresse 4
303
+ $addr4cleaned = $this->_stripAccents($address->getStreet(4));
304
+ $content = $this->_addFieldToCsv($content, $delimiter, $addr4cleaned, 35); // Complément d'adresse 5
305
+ $content = $this->_addFieldToCsv($content, $delimiter, $address->getPostcode(), 10); // Code postal
306
+ $city = $this->_stripAccents($address->getCity()); // Ville
307
+ $content = $this->_addFieldToCsv($content, $delimiter, $city, 35);
308
+ $content = $this->_addFieldToCsv($content, $delimiter, '', 10); // Filler
309
+ $addr1cleaned = $this->_stripAccents($address->getStreet(1)); // Rue
310
+ $content = $this->_addFieldToCsv($content, $delimiter, $addr1cleaned, 35);
311
+ $content = $this->_addFieldToCsv($content, $delimiter, '', 10); // Filler
312
+ $content = $this->_addFieldToCsv($content, $delimiter, $this->getIsoCodebyIdCountry($address->getCountry()), 3); // Code pays
313
+ $content = $this->_addFieldToCsv($content, $delimiter, $address->getTelephone(), 30); // Téléphone
314
+ $content = $this->_addFieldToCsv($content, $delimiter, '', 15); // Filler
315
+ $shippername = $this->_stripAccents(Mage::getStoreConfig('general/store_information/name'));
316
+ $content = $this->_addFieldToCsv($content, $delimiter, $shippername, 35); // Nom expéditeur
317
+ $shipperstreet2 = $this->_stripAccents(Mage::getStoreConfig('shipping/origin/street_line2'));
318
+ $content = $this->_addFieldToCsv($content, $delimiter, $shipperstreet2, 35); // Complément adresse 1
319
+ $content = $this->_addFieldToCsv($content, $delimiter, '', 35); // Filler
320
+ $content = $this->_addFieldToCsv($content, $delimiter, '', 35); // Filler
321
+ $content = $this->_addFieldToCsv($content, $delimiter, '', 35); // Filler
322
+ $content = $this->_addFieldToCsv($content, $delimiter, '', 35); // Filler
323
+ $shipperzipcode = $this->_stripAccents(Mage::getStoreConfig('shipping/origin/postcode'));
324
+ $content = $this->_addFieldToCsv($content, $delimiter, $shipperzipcode, 10); // Code postal
325
+ $shippercity = $this->_stripAccents(Mage::getStoreConfig('shipping/origin/city'));
326
+ $content = $this->_addFieldToCsv($content, $delimiter, $shippercity, 35); // Ville
327
+ $content = $this->_addFieldToCsv($content, $delimiter, '', 10); // Filler
328
+ if (version_compare(Mage::getVersion(), '1.5.1', '>='))
329
+ $shipperstreet = $this->_stripAccents(Mage::getStoreConfig('shipping/origin/street_line1'));
330
+ else{
331
+ $shipperstreet = explode(chr(10), $this->_stripAccents(Mage::getStoreConfig('general/store_information/address')));
332
+ $shipperstreet = $shipperstreet[0];
333
+ }
334
+ $content = $this->_addFieldToCsv($content, $delimiter, $shipperstreet, 35); // Rue
335
+ $content = $this->_addFieldToCsv($content, $delimiter, '', 10); // Filler
336
+ $content = $this->_addFieldToCsv($content, $delimiter, 'F', 3); // Code Pays F
337
+ $shipperphone = Mage::getStoreConfig('general/store_information/phone');
338
+ $content = $this->_addFieldToCsv($content, $delimiter, $shipperphone, 30); // Telephone
339
+ $content = $this->_addFieldToCsv($content, $delimiter, '', 35); // Filler
340
+ $content = $this->_addFieldToCsv($content, $delimiter, '', 35); // Filler
341
+ $content = $this->_addFieldToCsv($content, $delimiter, '', 35); // Filler
342
+ $content = $this->_addFieldToCsv($content, $delimiter, '', 35); // Filler
343
+ $content = $this->_addFieldToCsv($content, $delimiter, date('d/m/Y'), 10); // Date d'expédition théorique
344
+ $content = $this->_addFieldToCsv($content, $delimiter, $shipper_code, 8, true); // N° Compte chargeur
345
+ $content = $this->_addFieldToCsv($content, $delimiter, $order->getRealOrderId(), 35); // Code barres
346
+ $content = $this->_addFieldToCsv($content, $delimiter, $order->getRealOrderId(), 35); // N° Commande
347
+ $content = $this->_addFieldToCsv($content, $delimiter, '', 29); // Filler
348
+ $content = $this->_addFieldToCsv($content, $delimiter, substr($order->getGrandTotal(), 0, -2), 9, true);// Assurance Ad Valorem
349
+ $content = $this->_addFieldToCsv($content, $delimiter, '', 8); // Filler
350
+ $content = $this->_addFieldToCsv($content, $delimiter, '', 35); // Ref client 2
351
+ $content = $this->_addFieldToCsv($content, $delimiter, '', 1); // Filler
352
+ $content = $this->_addFieldToCsv($content, $delimiter, '', 35); // Filler
353
+ $content = $this->_addFieldToCsv($content, $delimiter, '', 10); // Filler
354
+ $shipperemail = Mage::getStoreConfig('trans_email/ident_general/email');
355
+ $content = $this->_addFieldToCsv($content, $delimiter, $shipperemail, 80); // E-mail expéditeur
356
+ $content = $this->_addFieldToCsv($content, $delimiter, '', 35); // GSM expéditeur
357
+ $content = $this->_addFieldToCsv($content, $delimiter, $order->getCustomerEmail(), 80); // E-mail destinataire
358
+ $prefixe = substr($address->getTelephone(),0,2);
359
+ if(($type !== 'dpdfrclassic' && $this->getIsoCodebyIdCountry($address->getCountry()) == 'F') && ($prefixe == 06 || $prefixe == 07))
360
+ $content = $this->_addFieldToCsv($content, $delimiter, $address->getTelephone(), 35);
361
+ else if($type == 'dpdfrclassic')
362
+ $content = $this->_addFieldToCsv($content, $delimiter, $address->getTelephone(), 35);
363
+ else
364
+ $content = $this->_addFieldToCsv($content, $delimiter, '', 35); // GSM destinataire
365
+ $content = $this->_addFieldToCsv($content, $delimiter, '', 96); // Filler
366
+ if($type == 'dpdfrrelais'){
367
+ preg_match('/P\d{5}/i', $address->getCompany(), $relayId);
368
+ $content = $this->_addFieldToCsv($content, $delimiter, $relayId[0], 8);} // Id point relais
369
+ else
370
+ $content = $this->_addFieldToCsv($content, $delimiter, '', 8);
371
+ $content = $this->_addFieldToCsv($content, $delimiter, '', 118); // Filler
372
+ /* Flag Predict */
373
+ if($type == 'dpdfrpredict' && $address->getTelephone() && $this->getIsoCodebyIdCountry($address->getCountry()) == 'F')
374
+ $content = $this->_addFieldToCsv($content, $delimiter,'+', 1);
375
+ else
376
+ $content = $this->_addFieldToCsv($content, $delimiter,'', 1);
377
+ /* Nom du contact */
378
+ $content = $this->_addFieldToCsv($content, $delimiter, $lastnamecleaned, 35);
379
+ $content = $this->_addFieldToCsv($content, $delimiter, '', 30); // Filler
380
+ $content .= $lineBreak; // CRLF
381
+ }
382
+
383
+ /* decode the content, depending on the charset */
384
+ if ($fileCharset == 'ISO-8859-1') {
385
+ $content = utf8_decode($content);
386
+ }
387
+
388
+ /* pick file mime type, depending on the extension */
389
+ if ($fileExtension == '.dat') {
390
+ $fileMimeType = 'text/plain';
391
+ } else if ($fileExtension == '.csv') {
392
+ $fileMimeType = 'application/csv';
393
+ } else {
394
+ // default
395
+ $fileMimeType = 'text/plain';
396
+ }
397
+
398
+ /* download the file */
399
+ return $this->_prepareDownloadResponse($filename, $content, $fileMimeType .'; charset="'. $fileCharset .'"');
400
+ }
401
+ else {
402
+ $this->_getSession()->addError($this->__('No Order has been selected'));
403
+ }
404
+ }
405
+ /**
406
+ * Add a new field to the csv file
407
+ * @param csvContent : the current csv content
408
+ * @param fieldDelimiter : the delimiter character
409
+ * @param fieldContent : the content to add
410
+ * @return : the concatenation of current content and content to add
411
+ */
412
+ private function _addFieldToCsv($csvContent, $fieldDelimiter, $fieldContent, $size = 0, $isNum = false) {
413
+ if( !$size ) {
414
+ return $csvContent . $fieldDelimiter . $fieldContent . $fieldDelimiter;
415
+ } else {
416
+ $newFieldContent = $fieldContent;
417
+ if( $isNum ) {
418
+ for($i=strlen($fieldContent);$i<$size;$i++) {
419
+ $newFieldContent = '0'.$newFieldContent;
420
+ }
421
+ } else {
422
+ for($i=strlen($fieldContent);$i<$size;$i++) {
423
+ $newFieldContent .= ' ';
424
+ }
425
+ }
426
+ /*if( strlen( $newFieldContent ) != $size ) {
427
+ var_dump('!! FAIL !! '. $newFieldContent);
428
+ }*/
429
+ $newFieldContent = substr( $newFieldContent, 0, $size );
430
+ return $csvContent . $fieldDelimiter . $newFieldContent . $fieldDelimiter;
431
+ }
432
+ }
433
+ // Fonction pour enlever les accents afin d'eliminer les erreurs d'encodage
434
+ private function _stripAccents($str){
435
+ $str = preg_replace('/[\x{00C0}\x{00C1}\x{00C2}\x{00C3}\x{00C4}\x{00C5}]/u','A', $str);
436
+ $str = preg_replace('/[\x{0105}\x{0104}\x{00E0}\x{00E1}\x{00E2}\x{00E3}\x{00E4}\x{00E5}]/u','a', $str);
437
+ $str = preg_replace('/[\x{00C7}\x{0106}\x{0108}\x{010A}\x{010C}]/u','C', $str);
438
+ $str = preg_replace('/[\x{00E7}\x{0107}\x{0109}\x{010B}\x{010D}}]/u','c', $str);
439
+ $str = preg_replace('/[\x{010E}\x{0110}]/u','D', $str);
440
+ $str = preg_replace('/[\x{010F}\x{0111}]/u','d', $str);
441
+ $str = preg_replace('/[\x{00C8}\x{00C9}\x{00CA}\x{00CB}\x{0112}\x{0114}\x{0116}\x{0118}\x{011A}]/u','E', $str);
442
+ $str = preg_replace('/[\x{00E8}\x{00E9}\x{00EA}\x{00EB}\x{0113}\x{0115}\x{0117}\x{0119}\x{011B}]/u','e', $str);
443
+ $str = preg_replace('/[\x{00CC}\x{00CD}\x{00CE}\x{00CF}\x{0128}\x{012A}\x{012C}\x{012E}\x{0130}]/u','I', $str);
444
+ $str = preg_replace('/[\x{00EC}\x{00ED}\x{00EE}\x{00EF}\x{0129}\x{012B}\x{012D}\x{012F}\x{0131}]/u','i', $str);
445
+ $str = preg_replace('/[\x{0142}\x{0141}\x{013E}\x{013A}]/u','l', $str);
446
+ $str = preg_replace('/[\x{00F1}\x{0148}]/u','n', $str);
447
+ $str = preg_replace('/[\x{00D2}\x{00D3}\x{00D4}\x{00D5}\x{00D6}\x{00D8}]/u','O', $str);
448
+ $str = preg_replace('/[\x{00F2}\x{00F3}\x{00F4}\x{00F5}\x{00F6}\x{00F8}]/u','o', $str);
449
+ $str = preg_replace('/[\x{0159}\x{0155}]/u','r', $str);
450
+ $str = preg_replace('/[\x{015B}\x{015A}\x{0161}]/u','s', $str);
451
+ $str = preg_replace('/[\x{00DF}]/u','ss', $str);
452
+ $str = preg_replace('/[\x{0165}]/u','t', $str);
453
+ $str = preg_replace('/[\x{00D9}\x{00DA}\x{00DB}\x{00DC}\x{016E}\x{0170}\x{0172}]/u','U', $str);
454
+ $str = preg_replace('/[\x{00F9}\x{00FA}\x{00FB}\x{00FC}\x{016F}\x{0171}\x{0173}]/u','u', $str);
455
+ $str = preg_replace('/[\x{00FD}\x{00FF}]/u','y', $str);
456
+ $str = preg_replace('/[\x{017C}\x{017A}\x{017B}\x{0179}\x{017E}]/u','z', $str);
457
+ $str = preg_replace('/[\x{00C6}]/u','AE', $str);
458
+ $str = preg_replace('/[\x{00E6}]/u','ae', $str);
459
+ $str = preg_replace('/[\x{0152}]/u','OE', $str);
460
+ $str = preg_replace('/[\x{0153}]/u','oe', $str);
461
+ $str = preg_replace('/[\x{0022}\x{0025}\x{0026}\x{0027}\x{00B0}]/u',' ', $str);
462
+ return $str;
463
+ }
464
+ }
465
+
466
+
app/code/community/DPDFrance/Export/controllers/TrackingController.php ADDED
@@ -0,0 +1,238 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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_Export_TrackingController extends Mage_Adminhtml_Controller_Action
13
+ {
14
+
15
+ /**
16
+ * Constructor
17
+ */
18
+ protected function _construct()
19
+ {
20
+ $this->setUsedModuleName('DPDFrance_Export');
21
+ }
22
+
23
+ /**
24
+ * Main action : show orders list
25
+ */
26
+ public function indexAction() {
27
+ $this->loadLayout()
28
+ ->_setActiveMenu('sales/export/tracking')
29
+ ->_addContent($this->getLayout()->createBlock('export/tracking_orders'))
30
+ ->renderLayout();
31
+ }
32
+ #Method to go to previous page
33
+ function _goback()
34
+ {
35
+ header("Location: {$_SERVER['HTTP_REFERER']}");
36
+ exit;
37
+ }
38
+
39
+
40
+
41
+ /**
42
+ * Importation logic
43
+ * @param string $fileName
44
+ * @param string $trackingTitle
45
+ */
46
+ public function trackingAction() {
47
+
48
+ /* get the orders */
49
+ $orderIds = $this->getRequest()->getPost('order_ids');
50
+ // var_dump($orderIds);exit;
51
+ if (!empty($orderIds)) {
52
+
53
+ foreach ($orderIds as $orderId) {
54
+
55
+ /* get the order */
56
+ $order = Mage::getModel('sales/order')->load($orderId);
57
+ $incrementId = $order->getIncrementID();
58
+ // var_dump($order, $incrementId);exit;
59
+
60
+ /**
61
+ * Try to load the order
62
+ */
63
+ $order = Mage::getModel('sales/order')->loadByIncrementId($incrementId);
64
+ $order2 = Mage::getModel('sales/order')->load($orderId);
65
+ $orderuniqueid = $order->getId();
66
+ // var_dump($order);exit;
67
+ if (!$orderuniqueid) {
68
+ // var_dump($order->getId());exit;
69
+ $this->_getSession()->addError($this->__('La commande %s n\'existe pas', $orderId));
70
+ continue;
71
+ }
72
+
73
+ /* type of delivery */
74
+ $type = stristr($order->getShippingMethod(),'_', true);
75
+
76
+ /* depot code and shipper code determination */
77
+ switch ($type) {
78
+ case 'dpdfrrelais' :
79
+ $depot_code = Mage::getStoreConfig('carriers/dpdfrrelais/depot');
80
+ $shipper_code = Mage::getStoreConfig('carriers/dpdfrrelais/cargo');
81
+ break;
82
+ case 'dpdfrpredict' :
83
+ $depot_code = Mage::getStoreConfig('carriers/dpdfrpredict/depot');
84
+ $shipper_code = Mage::getStoreConfig('carriers/dpdfrpredict/cargo');
85
+ break;
86
+ case 'dpdfrclassic' :
87
+ $depot_code = Mage::getStoreConfig('carriers/dpdfrclassic/depot');
88
+ $shipper_code = Mage::getStoreConfig('carriers/dpdfrclassic/cargo');
89
+ break;
90
+ }
91
+
92
+ /**
93
+ * Try to create a shipment
94
+ */
95
+
96
+ $trackingNumber = $order->getIncrementID().'_'.$depot_code.$shipper_code;
97
+ $trackingTitle = 'DPD France';
98
+ $sendEmail = 1;
99
+ $comment = 'Cher client, vous pouvez suivre l\'acheminement de votre colis par DPD en cliquant sur le lien ci-contre : '.'<a target="_blank" href="http://www.dpd.fr/tracer_'.$trackingNumber.'">Suivre ce colis DPD France</a>';
100
+ $includeComment = 1;
101
+
102
+ $shipmentId = $this->_createTracking($order, $trackingNumber, $trackingTitle, $sendEmail, $comment, $includeComment);
103
+ if ($shipmentId != 0) {
104
+ $this->_getSession()->addSuccess($this->__('Livraison %s créée pour la commande %s, statut mis à jour', $shipmentId, $incrementId, $trackingNumber));
105
+ }
106
+
107
+ }//foreach
108
+ $this->_goback();
109
+ }
110
+ }
111
+
112
+
113
+
114
+ /**
115
+ * Create new shipment for order
116
+ * Inspired by Mage_Sales_Model_Order_Shipment_Api methods
117
+ *
118
+ * @param Mage_Sales_Model_Order $order (it should exist, no control is done into the method)
119
+ * @param string $trackingNumber
120
+ * @param string $trackingTitle
121
+ * @param booleam $email
122
+ * @param string $comment
123
+ * @param boolean $includeComment
124
+ * @return int : shipment real id if creation was ok, else 0
125
+ */
126
+ public function _createTracking($order, $trackingNumber, $trackingTitle, $email, $comment, $includeComment)
127
+ {
128
+ /**
129
+ * Check shipment creation availability
130
+ */
131
+ if (!$order->canShip()) {
132
+ $this->_getSession()->addError($this->__('La commande %s ne peut pas être expédiée, ou a déjà été expédiée.', $order->getRealOrderId()));
133
+ return 0;
134
+ }
135
+
136
+ /**
137
+ * Initialize the Mage_Sales_Model_Order_Shipment object
138
+ */
139
+ $convertor = Mage::getModel('sales/convert_order');
140
+ $shipment = $convertor->toShipment($order);
141
+
142
+ /**
143
+ * Add the items to send
144
+ */
145
+ foreach ($order->getAllItems() as $orderItem) {
146
+ if (!$orderItem->getQtyToShip()) {
147
+ continue;
148
+ }
149
+ if ($orderItem->getIsVirtual()) {
150
+ continue;
151
+ }
152
+
153
+ $item = $convertor->itemToShipmentItem($orderItem);
154
+ $qty = $orderItem->getQtyToShip();
155
+ $item->setQty($qty);
156
+
157
+ $shipment->addItem($item);
158
+ }//foreach
159
+
160
+ $shipment->register();
161
+
162
+
163
+
164
+ /**
165
+ * Tracking number instanciation
166
+ */
167
+ $carrierCode = stristr($order->getShippingMethod(),'_', true);
168
+ if(!$carrierCode) $carrierCode = 'custom';
169
+
170
+ /* depot code and shipper code determination */
171
+ switch ($carrierCode) {
172
+ case 'dpdfrrelais' :
173
+ $depot_code = Mage::getStoreConfig('carriers/dpdfrrelais/depot');
174
+ $shipper_code = Mage::getStoreConfig('carriers/dpdfrrelais/cargo');
175
+ break;
176
+ case 'dpdfrpredict' :
177
+ $depot_code = Mage::getStoreConfig('carriers/dpdfrpredict/depot');
178
+ $shipper_code = Mage::getStoreConfig('carriers/dpdfrpredict/cargo');
179
+ break;
180
+ case 'dpdfrclassic' :
181
+ $depot_code = Mage::getStoreConfig('carriers/dpdfrclassic/depot');
182
+ $shipper_code = Mage::getStoreConfig('carriers/dpdfrclassic/cargo');
183
+ break;
184
+ }
185
+ // Le trackingNumber est composé du n° de commande + le code agence + code cargo, intégré en un bloc dans l'URL
186
+ $trackingNumber = $order->getIncrementID().'_'.$depot_code.$shipper_code;
187
+ $trackingUrl = 'http://www.dpd.fr/tracer_'.$trackingNumber;
188
+
189
+ $track = Mage::getModel('sales/order_shipment_track')
190
+ ->setNumber($trackingNumber)
191
+ ->setCarrierCode($carrierCode)
192
+ ->setTitle($trackingTitle)
193
+ ->setUrl($trackingUrl)
194
+ ->setStatus( '<a target="_blank" href="'.$trackingUrl.'">'.__('Suivre ce colis DPD France').'</a>' );
195
+
196
+
197
+ $shipment->addTrack($track);
198
+
199
+ /**
200
+ * Comment handling
201
+ */
202
+ $shipment->addComment($comment, $email && $includeComment);
203
+
204
+ /**
205
+ * Change order status to Processing
206
+ */
207
+ $shipment->getOrder()->setIsInProcess(true);
208
+
209
+ /**
210
+ * If e-mail, set as sent (must be done before shipment object saving)
211
+ */
212
+ if ($email) {
213
+ $shipment->setEmailSent(true);
214
+ }
215
+
216
+ try {
217
+ // /**
218
+ // * Save the created shipment and the updated order
219
+ // */
220
+ $shipment->save();
221
+ $shipment->getOrder()->save();
222
+
223
+ // /**
224
+ // * Email sending
225
+ // */
226
+ $shipment->sendEmail($email, ($includeComment ? $comment : ''));
227
+ } catch (Mage_Core_Exception $e) {
228
+ $this->_getSession()->addError($this->__('Erreur pendant la création de l\'expédition %s : %s', $orderId, $e->getMessage()));
229
+ return 0;
230
+ }
231
+
232
+ /**
233
+ * Everything was ok : return Shipment real id
234
+ */
235
+ return $shipment->getIncrementId();
236
+
237
+ }
238
+ }
app/code/community/DPDFrance/Export/etc/config.xml ADDED
@@ -0,0 +1,115 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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.0</version>
17
+ <depends>
18
+ <Mage_Shipping/>
19
+ </depends>
20
+ </DPDFrance_Export>
21
+ </modules>
22
+ <global>
23
+ <blocks>
24
+ <export>
25
+ <class>DPDFrance_Export_Block</class>
26
+ </export>
27
+ </blocks>
28
+ <helpers>
29
+ <export>
30
+ <class>DPDFrance_Export_Helper</class>
31
+ </export>
32
+ </helpers>
33
+ <resources>
34
+ <export_setup>
35
+ <setup>
36
+ <module>DPDFrance_Export</module>
37
+ </setup>
38
+ <connection>
39
+ <use>core_setup</use>
40
+ </connection>
41
+ </export_setup>
42
+ <export_write>
43
+ <connection>
44
+ <use>core_write</use>
45
+ </connection>
46
+ </export_write>
47
+ <export_read>
48
+ <connection>
49
+ <use>core_read</use>
50
+ </connection>
51
+ </export_read>
52
+ </resources>
53
+ </global>
54
+ <admin>
55
+ <routers>
56
+ <export>
57
+ <use>admin</use>
58
+ <args>
59
+ <module>DPDFrance_Export</module>
60
+ <frontName>dpdfranceadmin</frontName>
61
+ </args>
62
+ </export>
63
+ </routers>
64
+ </admin>
65
+ <adminhtml>
66
+ <translate>
67
+ <modules>
68
+ <Mage_Shipping>
69
+ <files>
70
+ <DPDFrance_Export>DPDFrance_Export.csv</DPDFrance_Export>
71
+ </files>
72
+ </Mage_Shipping>
73
+ </modules>
74
+ </translate>
75
+ <menu>
76
+ <sales>
77
+ <children>
78
+ <export translate="title">
79
+ <title>DPD France</title>
80
+ <sort_order>1000</sort_order>
81
+ <action>dpdfranceadmin/export</action>
82
+ </export>
83
+ </children>
84
+ </sales>
85
+ </menu>
86
+ <acl>
87
+ <resources>
88
+ <admin>
89
+ <children>
90
+ <sales>
91
+ <children>
92
+ <export translate="title">
93
+ <title>DPD France</title>
94
+ <sort_order>1000</sort_order>
95
+ <action>dpdfranceadmin/export</action>
96
+ </export>
97
+ </children>
98
+ </sales>
99
+ <system>
100
+ <children>
101
+ <config>
102
+ <children>
103
+ <export>
104
+ <title>DPD France</title>
105
+ </export>
106
+ </children>
107
+ </config>
108
+ </children>
109
+ </system>
110
+ </children>
111
+ </admin>
112
+ </resources>
113
+ </acl>
114
+ </adminhtml>
115
+ </config>
app/code/community/DPDFrance/Predict/Helper/Data.php ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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_Helper_Data extends Mage_Core_Helper_Abstract {
13
+ }
14
+ ?>
app/code/community/DPDFrance/Predict/Model/Carrier/DPDFrancePredictShipping.php ADDED
@@ -0,0 +1,401 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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();
32
+ $config = $this->_getConfig();
33
+ $allowed_methods = array();
34
+ if (count($config)>0) {
35
+ foreach ($config as $row){
36
+ $allowed_methods[$row['*code']] = isset($row['label']['value']) ? $row['label']['value'] : 'No label';
37
+ }
38
+ }
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;
65
+ // $items_in_cart = $process->getData('all_items');
66
+ $tax_amount = 0;
67
+ if (count($items_in_cart)>0)
68
+ {
69
+ foreach ($items_in_cart as $item)
70
+ {
71
+ $calc = Mage::getSingleton('tax/calculation');
72
+ $rates = $calc->getRatesForAllProductTaxClasses($calc->getRateRequest());
73
+ $vat_rate = isset($rates[$item->getProduct()->getTaxClassId()]) ? $rates[$item->getProduct()->getTaxClassId()] : 0;
74
+ // var_dump($calc, $rates, $vat_rate);exit;
75
+ if ($vat_rate > 0){
76
+ $vat_to_add = $item->getData('row_total')*$vat_rate/100;
77
+ // var_dump($vat_to_add);exit;
78
+ } else {
79
+ $vat_to_add = $item->getData('tax_amount');
80
+ }
81
+ $tax_amount += $vat_to_add;
82
+ }
83
+ }
84
+ // var_dump($tax_amount);exit;
85
+ return $tax_amount;
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');
280
+ $longueurcargo = strlen($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)
288
+ ->addData(array('status'=>'<script type="text/javascript">window.resizeTo(1280,800);</script><iframe src="'.$trackingUrlByRef.'" style="border: none;" width="1024" height="800"/>'));
289
+
290
+ $trackingResult = Mage::getModel('shipping/tracking_result')
291
+ ->append($trackingStatus);
292
+ if($trackings = $trackingResult->getAllTrackings())
293
+ return $trackings[0];
294
+ return false;
295
+ }else{
296
+ $trackingStatus = Mage::getModel('shipping/tracking_result_status')
297
+ ->setCarrier('dpdfrpredict')
298
+ ->setCarrierTitle('DPD Predict')
299
+ ->setTracking($trackingNumber)
300
+ ->addData(array('status'=>'<script type="text/javascript">window.resizeTo(1280,800);</script><iframe src="'.$trackingUrlByNb.'" style="border: none;" width="1024" height="800"/>'));
301
+
302
+ $trackingResult = Mage::getModel('shipping/tracking_result')
303
+ ->append($trackingStatus);
304
+ if($trackings = $trackingResult->getAllTrackings())
305
+ return $trackings[0];
306
+ return false;
307
+ }
308
+ }
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 ADDED
@@ -0,0 +1,41 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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_Observer extends Mage_Core_Model_Abstract {
13
+
14
+ protected function _construct() {}
15
+
16
+
17
+ public function dpdfrpredictgsmAction() {
18
+
19
+ $current = Mage::getSingleton('checkout/session')->getQuote(); // Récupération de la session checkout
20
+ $modeliv = $current->getShippingAddress()->getShippingMethod(); // Récupération de la methode de livraison choisie par le client
21
+
22
+ if(substr($modeliv,0,12) === 'dpdfrpredict') { // Modifier l'adresse uniquement si la methode de livraison sélectionnée est predict
23
+ $input_tel = Mage::app()->getRequest()->getParam('gsm_dest'); // Saisie GSM utilisateur
24
+
25
+ if($input_tel !='') { // Si un GSM est bien renseigné, l'enregistrer dans l'adresse client
26
+
27
+ $gsm = str_replace(array(' ', '.', '-', ',', ';', '/', '\\', '(', ')'),'',$input_tel); // Nettoyage des symboles et espaces - donne 10 chiffres collés
28
+ $gsm = str_replace('+33','0',$gsm); // Suppression d'un éventuel préfixe +33 en 0
29
+
30
+ if (!(bool)preg_match('/^((\+33|0)[67])(?:[ _.-]?(\d{2})){4}$/', $gsm, $res)){ // Test sur la présence du 06 ou 07, de 10 chiffres
31
+ // Si GSM incorrect, rien car géré par predict.js
32
+ }else{
33
+ $address = $current->getShippingAddress(); // Recupération adresse de livraison
34
+ $billing = $current->getBillingAddress(); // Récupération adresse de facturation
35
+ $address->setTelephone($gsm);
36
+ $address->save();
37
+ }
38
+ }
39
+ }
40
+ }
41
+ }
app/code/community/DPDFrance/Predict/Model/Owebia.php ADDED
@@ -0,0 +1,1174 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
+
1174
+ ?>
app/code/community/DPDFrance/Predict/etc/config.xml ADDED
@@ -0,0 +1,186 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
+ <default>
15
+ <carriers>
16
+ <dpdfrpredict>
17
+ <group>dpdfrpredict</group>
18
+ <sallowspecific>0</sallowspecific>
19
+ <model>dpdfrpredict/carrier_DPDFrancePredictShipping</model>
20
+ <name>Predict par DPD</name>
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>
71
+ </carriers>
72
+ </default>
73
+ <modules>
74
+ <DPDFrance_Predict>
75
+ <version>5.0.0</version>
76
+ <depends>
77
+ <Mage_Shipping/>
78
+ </depends>
79
+ </DPDFrance_Predict>
80
+ </modules>
81
+ <global>
82
+ <blocks>
83
+ <dpdfrpredict>
84
+ <class>DPDFrance_Predict_Block</class>
85
+ </dpdfrpredict>
86
+ </blocks>
87
+ <helpers>
88
+ <dpdfrpredict>
89
+ <class>DPDFrance_Predict_Helper</class>
90
+ </dpdfrpredict>
91
+ </helpers>
92
+ <models>
93
+ <dpdfrpredict>
94
+ <class>DPDFrance_Predict_Model</class>
95
+ </dpdfrpredict>
96
+ </models>
97
+ <resources>
98
+ <dpdfrpredict_setup>
99
+ <setup>
100
+ <module>DPDFrance_Predict</module>
101
+ </setup>
102
+ <connection>
103
+ <use>core_setup</use>
104
+ </connection>
105
+ </dpdfrpredict_setup>
106
+ <dpdfrpredict_write>
107
+ <connection>
108
+ <use>core_write</use>
109
+ </connection>
110
+ </dpdfrpredict_write>
111
+ <dpdfrpredict_read>
112
+ <connection>
113
+ <use>core_read</use>
114
+ </connection>
115
+ </dpdfrpredict_read>
116
+ </resources>
117
+ </global>
118
+ <adminhtml>
119
+ <translate>
120
+ <modules>
121
+ <Mage_Shipping>
122
+ <files>
123
+ <DPDFrance_Predict>DPDFrance_Predict.csv</DPDFrance_Predict>
124
+ </files>
125
+ </Mage_Shipping>
126
+ </modules>
127
+ </translate>
128
+ <acl>
129
+ <resources>
130
+ <admin>
131
+ <children>
132
+ <system>
133
+ <children>
134
+ <config>
135
+ <children>
136
+ <dpdfrpredict>
137
+ <title>DPD Predict</title>
138
+ </dpdfrpredict>
139
+ </children>
140
+ </config>
141
+ </children>
142
+ </system>
143
+ </children>
144
+ </admin>
145
+ </resources>
146
+ </acl>
147
+ </adminhtml>
148
+ <frontend>
149
+ <layout>
150
+ <updates>
151
+ <dpdfrpredict module="DPDFrance_Predict">
152
+ <file>dpdfrpredict.xml</file>
153
+ </dpdfrpredict>
154
+ </updates>
155
+ </layout>
156
+ <routers>
157
+ <dpdfrpredict>
158
+ <use>standard</use>
159
+ <args>
160
+ <module>DPDFrance_Predict</module>
161
+ <frontName>dpdfrpredict</frontName>
162
+ </args>
163
+ </dpdfrpredict>
164
+ </routers>
165
+ <translate>
166
+ <modules>
167
+ <Mage_Shipping>
168
+ <files>
169
+ <DPDFrance_Predict>DPDFrance_Predict.csv</DPDFrance_Predict>
170
+ </files>
171
+ </Mage_Shipping>
172
+ </modules>
173
+ </translate>
174
+ <events>
175
+ <checkout_controller_onepage_save_shipping_method>
176
+ <observers>
177
+ <dpdfrpredict_observer>
178
+ <type>model</type>
179
+ <class>dpdfrpredict/observer</class>
180
+ <method>dpdfrpredictgsmAction</method>
181
+ </dpdfrpredict_observer>
182
+ </observers>
183
+ </checkout_controller_onepage_save_shipping_method>
184
+ </events>
185
+ </frontend>
186
+ </config>
app/code/community/DPDFrance/Predict/etc/system.xml ADDED
@@ -0,0 +1,107 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
+ <sections>
15
+ <carriers>
16
+ <groups>
17
+ <dpdfrpredict translate="label" module="shipping">
18
+ <label>Livraison Predict par DPD (France uniquement)</label>
19
+ <comment><![CDATA[<strong>Veuillez configurer la livraison Predict par DPD ci-dessous.</strong><br />Pour de l'aide, veuillez vous référez à la documentation de ce module disponible ici : <a href="../../../../../../../../media/dpdfrance/readme_dpdfrance_magento.pdf" target="_blank">PDF</a>]]></comment>
20
+ <front-type>text</front-type>
21
+ <sort_order>-99</sort_order>
22
+ <show_in_default>1</show_in_default>
23
+ <show_in_website>1</show_in_website>
24
+ <show_in_store>1</show_in_store>
25
+ <fields>
26
+ <active translate="label">
27
+ <label>Enabled</label>
28
+ <frontend_type>select</frontend_type>
29
+ <source_model>adminhtml/system_config_source_yesno</source_model>
30
+ <sort_order>1</sort_order>
31
+ <show_in_default>1</show_in_default>
32
+ <show_in_website>1</show_in_website>
33
+ <show_in_store>1</show_in_store>
34
+ </active>
35
+ <title translate="label">
36
+ <label>Title</label>
37
+ <front_type>text</front_type>
38
+ <sort_order>2</sort_order>
39
+ <show_in_default>1</show_in_default>
40
+ <show_in_website>1</show_in_website>
41
+ <show_in_store>1</show_in_store>
42
+ </title>
43
+ <methodname translate="label">
44
+ <label>Subtitle</label>
45
+ <front_type>text</front_type>
46
+ <sort_order>3</sort_order>
47
+ <show_in_default>1</show_in_default>
48
+ <show_in_website>1</show_in_website>
49
+ <show_in_store>1</show_in_store>
50
+ </methodname>
51
+ <depot translate="label">
52
+ <label>Your DPD Depot #</label>
53
+ <front_type>text</front_type>
54
+ <sort_order>7</sort_order>
55
+ <show_in_default>1</show_in_default>
56
+ <show_in_website>1</show_in_website>
57
+ <show_in_store>1</show_in_store>
58
+ <comment><![CDATA[Sur 3 chiffres (ex.: 013)</a>]]></comment>
59
+ </depot>
60
+ <cargo translate="label">
61
+ <label>Your Predict by DPD contract #</label>
62
+ <front_type>text</front_type>
63
+ <sort_order>8</sort_order>
64
+ <show_in_default>1</show_in_default>
65
+ <show_in_website>1</show_in_website>
66
+ <show_in_store>1</show_in_store>
67
+ <comment><![CDATA[Sur 4 ou 5 chiffres, sans code agence, sans espace, sans tiret ni zéros devant</a>]]></comment>
68
+ </cargo>
69
+ <expense translate="label">
70
+ <label>Shipping rates configuration</label>
71
+ <frontend_type>textarea</frontend_type>
72
+ <sort_order>10</sort_order>
73
+ <show_in_default>1</show_in_default>
74
+ <show_in_website>1</show_in_website>
75
+ <show_in_store>1</show_in_store>
76
+ </expense>
77
+ <showerror translate="label">
78
+ <label>Display when unavailable</label>
79
+ <frontend_type>select</frontend_type>
80
+ <source_model>adminhtml/system_config_source_yesno</source_model>
81
+ <sort_order>15</sort_order>
82
+ <show_in_default>1</show_in_default>
83
+ <show_in_website>1</show_in_website>
84
+ <show_in_store>1</show_in_store>
85
+ </showerror>
86
+ <specificerrmsg translate="label">
87
+ <label>Displayed Error Message</label>
88
+ <frontend_type>textarea</frontend_type>
89
+ <sort_order>16</sort_order>
90
+ <show_in_default>1</show_in_default>
91
+ <show_in_website>1</show_in_website>
92
+ <show_in_store>1</show_in_store>
93
+ </specificerrmsg>
94
+ <sort_order translate="label">
95
+ <label>Sort Order</label>
96
+ <frontend_type>text</frontend_type>
97
+ <sort_order>270</sort_order>
98
+ <show_in_default>1</show_in_default>
99
+ <show_in_website>1</show_in_website>
100
+ <show_in_store>0</show_in_store>
101
+ </sort_order>
102
+ </fields>
103
+ </dpdfrpredict>
104
+ </groups>
105
+ </carriers>
106
+ </sections>
107
+ </config>
app/code/community/DPDFrance/Relais/Helper/Data.php ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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_Helper_Data extends Mage_Core_Helper_Abstract {
13
+ }
14
+
15
+ ?>
app/code/community/DPDFrance/Relais/Model/Carrier/DPDFranceRelaisShipping.php ADDED
@@ -0,0 +1,402 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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();
32
+ $config = $this->_getConfig();
33
+ $allowed_methods = array();
34
+ if (count($config)>0) {
35
+ foreach ($config as $row){
36
+ $allowed_methods[$row['*code']] = isset($row['label']['value']) ? $row['label']['value'] : 'No label';
37
+ }
38
+ }
39
+ return $allowed_methods;
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;
66
+ // $items_in_cart = $process->getData('all_items');
67
+ $tax_amount = 0;
68
+ if (count($items_in_cart)>0)
69
+ {
70
+ foreach ($items_in_cart as $item)
71
+ {
72
+ $calc = Mage::getSingleton('tax/calculation');
73
+ $rates = $calc->getRatesForAllProductTaxClasses($calc->getRateRequest());
74
+ $vat_rate = isset($rates[$item->getProduct()->getTaxClassId()]) ? $rates[$item->getProduct()->getTaxClassId()] : 0;
75
+ // var_dump($calc, $rates, $vat_rate);exit;
76
+ if ($vat_rate > 0){
77
+ $vat_to_add = $item->getData('row_total')*$vat_rate/100;
78
+ // var_dump($vat_to_add);exit;
79
+ } else {
80
+ $vat_to_add = $item->getData('tax_amount');
81
+ }
82
+ $tax_amount += $vat_to_add;
83
+ }
84
+ }
85
+ // var_dump($tax_amount);exit;
86
+ return $tax_amount;
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');
281
+ $longueurcargo = strlen($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)
289
+ ->addData(array('status'=>'<script type="text/javascript">window.resizeTo(1280,800);</script><iframe src="'.$trackingUrlByRef.'" style="border: none;" width="1024" height="800"/>'));
290
+
291
+ $trackingResult = Mage::getModel('shipping/tracking_result')
292
+ ->append($trackingStatus);
293
+ if($trackings = $trackingResult->getAllTrackings())
294
+ return $trackings[0];
295
+ return false;
296
+ }else{
297
+ $trackingStatus = Mage::getModel('shipping/tracking_result_status')
298
+ ->setCarrier('dpdfrrelais')
299
+ ->setCarrierTitle('DPD Relais')
300
+ ->setTracking($trackingNumber)
301
+ ->addData(array('status'=>'<script type="text/javascript">window.resizeTo(1280,800);</script><iframe src="'.$trackingUrlByNb.'" style="border: none;" width="1024" height="800"/>'));
302
+
303
+ $trackingResult = Mage::getModel('shipping/tracking_result')
304
+ ->append($trackingStatus);
305
+ if($trackings = $trackingResult->getAllTrackings())
306
+ return $trackings[0];
307
+ return false;
308
+ }
309
+ }
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 ADDED
@@ -0,0 +1,113 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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_Observer extends Mage_Core_Model_Abstract {
13
+
14
+ protected function _construct() {}
15
+
16
+ public function changeshippingaddressAction() {
17
+
18
+ $current = Mage::getSingleton('checkout/session')->getQuote(); // Récupération de la session checkout
19
+ $modeliv = $current->getShippingAddress()->getShippingMethod(); // Récupération de la methode de livraison choisie par le client
20
+
21
+ if(substr($modeliv,0,11) === 'dpdfrrelais') { // Modifier l'adresse uniquement si la methode de livraison sélectionnée est DPD Relais
22
+
23
+ $relais_list = Mage::app()->getRequest()->getParam('relay-point'); // Récupération des données du PR choisi par le bouton radio, séparées par §§§, depuis RelaisController.php
24
+
25
+ if($relais_list !='') { // Si un point relais est bien choisi, écraser l'adresse
26
+
27
+ $shippingArray = explode("|||", $relais_list); // Séparation des données du PR dans des variables en majuscules (adresse, nom, code postal, ville)
28
+ $adressePR = strtoupper($shippingArray[0]);
29
+ $nomPR = strtoupper($shippingArray[1]);
30
+ $codepostalPR = $shippingArray[2];
31
+ $villePR = strtoupper($shippingArray[3]);
32
+
33
+ $address = $current->getShippingAddress(); // Recupération adresse de livraison
34
+ $billing = $current->getBillingAddress(); // Récupération adresse de facturation
35
+
36
+ if (substr($codepostalPR,0,2) == 20) // Récupération de la région de destination : Tri spécial sur le code postal pour la Corse, permettant de séparer 2A et 2B
37
+ {
38
+ $regioncode = substr($codepostalPR,0,3);
39
+ switch ($regioncode) {
40
+ case 200 :
41
+ case 201 :
42
+ $regioncode = '2A';
43
+ break;
44
+ case 202 :
45
+ case 206 :
46
+ $regioncode = '2B';
47
+ break;
48
+ }
49
+
50
+ } else { // Si pas en Corse, récupérer les 2 premiers chiffres du CP pour trouver la région.
51
+ $regioncode = substr($codepostalPR,0,2);
52
+ }
53
+
54
+ Mage::app()->getLocale()->setLocaleCode('en_US');
55
+
56
+ if (substr($regioncode,0,1) == 0) {
57
+ $region = Mage::getModel ('directory/region')->loadByCode($regioncode,$address->getCountryId());
58
+ if ($region->getDefaultName() == '') {
59
+ $region = Mage::getModel ('directory/region')->loadByCode(substr($regioncode,1,1),$address->getCountryId());
60
+ }
61
+ }else{
62
+ $region = Mage::getModel ('directory/region')->loadByCode($regioncode,$address->getCountryId());
63
+ }
64
+
65
+ $regionname = $region->getDefaultName();
66
+ $regionid = $region->getRegionId();
67
+
68
+ $address->setRegion($regionname);
69
+ $address->setRegionId($regionid);
70
+ $address->setPostcode($codepostalPR);
71
+ $address->setStreet($adressePR);
72
+ $address->setCity($villePR);
73
+ $address->setCompany($nomPR);
74
+ $address->save();
75
+ $current->setShippingAddress($address);
76
+ $current->save(); // Enregistrement nouvelle adresse
77
+
78
+ } // Si pas de PR choisi : rien
79
+
80
+ } // Cette partie de code permet de remplacer l'adresse de livraison par celle de facturation si la methode de livraison était DPD Relais et qu'elle a ensuite changé.
81
+
82
+ if(substr($modeliv,0,11) !== 'dpdfrrelais') { // Si la methode de livraison sélectionnée n'est pas relaypoint
83
+
84
+ $relais_list = Mage::app()->getRequest()->getParam('relay-point'); // Récupération des données du PR choisi par le bouton radio
85
+
86
+ if($relais_list !='') { // Si un point relais était choisi, écraser l'adresse par celle de facturation
87
+
88
+ $shippingAddress = $current->getShippingAddress(); // Recupération adresse de livraison
89
+ $billingAddress = $current->getBillingAddress(); // Récupération adresse de facturation
90
+
91
+ $shippingAddress->setData('customer_id', $billingAddress->getData('customer_id'));
92
+ $shippingAddress->setData('customer_address_id', $billingAddress->getData('customer_address_id'));
93
+ $shippingAddress->setData('email', $billingAddress->getData('email'));
94
+ $shippingAddress->setData('prefix', $billingAddress->getData('prefix'));
95
+ $shippingAddress->setData('firstname', $billingAddress->getData('firstname'));
96
+ $shippingAddress->setData('middlename', $billingAddress->getData('middlename'));
97
+ $shippingAddress->setData('lastname', $billingAddress->getData('lastname'));
98
+ $shippingAddress->setData('suffix', $billingAddress->getData('suffix'));
99
+ $shippingAddress->setData('company', $billingAddress->getData('company'));
100
+ $shippingAddress->setData('street', $billingAddress->getData('street'));
101
+ $shippingAddress->setData('city', $billingAddress->getData('city'));
102
+ $shippingAddress->setData('region', $billingAddress->getData('region'));
103
+ $shippingAddress->setData('region_id', $billingAddress->getData('region_id'));
104
+ $shippingAddress->setData('postcode', $billingAddress->getData('postcode'));
105
+ $shippingAddress->setData('country_id', $billingAddress->getData('country_id'));
106
+ $shippingAddress->save();
107
+ $current->setShippingAddress($shippingAddress);
108
+ $current->save(); // Enregistrement nouvelle adresse
109
+
110
+ } // Si pas de PR choisi et la méthode de livraison n'est pas relaypoint : rien
111
+ }
112
+ }
113
+ }
app/code/community/DPDFrance/Relais/Model/Outputs.php ADDED
@@ -0,0 +1,85 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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_Outputs extends Mage_Core_Model_Abstract
13
+ {
14
+ private $_status = false;
15
+ private $_result = '';
16
+ private $_periodStatus = array();
17
+
18
+
19
+ public function getPeriod($point)
20
+ {
21
+ $str = "";
22
+ $date_day = "d ";
23
+ $date_month = "M";
24
+
25
+ if(Mage::helper ( 'dpdfrrelais' )->isBetweenClosingPeriod ( $point, 1 )) {
26
+ $start = strtotime(Mage::helper ('dpdfrrelais')->convertdateformat($point['closing_period_start_date_1']));
27
+ $end = strtotime(Mage::helper ('dpdfrrelais')->convertdateformat($point['closing_period_end_date_1']));
28
+ $str .= date($date_day,$start).__(date($date_month,$start))." au ". date($date_day,$end).__(date($date_month,$end));
29
+ }
30
+ if(Mage::helper ( 'dpdfrrelais' )->isBetweenClosingPeriod ( $point, 2 )) {
31
+ $start = strtotime(Mage::helper ('dpdfrrelais')->convertdateformat($point['closing_period_start_date_2']));
32
+ $end = strtotime(Mage::helper ('dpdfrrelais')->convertdateformat($point['closing_period_end_date_2']));
33
+ if($str) {
34
+ $str .= " and ";
35
+ }
36
+ $str .= date($date_day,$start).__(date($date_month,$start))." au ". date($date_day,$end).__(date($date_month,$end));
37
+ }
38
+ if(Mage::helper ( 'dpdfrrelais' )->isBetweenClosingPeriod ( $point, 3 )) {
39
+ $start = strtotime(Mage::helper ('dpdfrrelais')->convertdateformat($point['closing_period_start_date_3']));
40
+ $end = strtotime(Mage::helper ('dpdfrrelais')->convertdateformat($point['closing_period_end_date_3']));
41
+ if($str) {
42
+ $str .= " and ";
43
+ }
44
+ $str .= date($date_day,$start).__(date($date_month,$start))." au ". date($date_day,$end).__(date($date_month,$end));
45
+ }
46
+ if($str) {
47
+ $img = Mage::getDesign()->getSkinUrl('images/i_notice.gif');
48
+ $words = __('Attention, this Pickup point will not be available from')." ".$str;
49
+ $this->_result = <<<EOT
50
+ <div class="noticeICI"><img src="$img" />$words</div>
51
+ EOT;
52
+ }
53
+ return $this;
54
+ }
55
+
56
+
57
+ public function getStatus()
58
+ {
59
+ return $this->_status;
60
+ }
61
+
62
+ public function getResult()
63
+ {
64
+ return $this->_result;
65
+ }
66
+
67
+ public function checkPeriodStatus($point, $num,$flag=false)
68
+ {
69
+ $period = 4*24*60*60;
70
+ $start = strtotime(Mage::helper ('dpdfrrelais')->convertdateformat($point['closing_period_start_date_'.$num]));
71
+ $end = strtotime(Mage::helper ('dpdfrrelais')->convertdateformat($point['closing_period_end_date_'.$num]));
72
+ $closing = $end - $start;
73
+ if($closing <= $period) {
74
+ if($flag && $closing > 0) { Mage::log('period');
75
+ if($this->_result) {
76
+ $this->_result .= " and ";
77
+ }
78
+ $this->_result .= date($date_day,$start).__(date($date_month,$start))." to ". date($date_day,$end).__(date($date_month,$end));
79
+
80
+ }
81
+ return true;
82
+ }
83
+ return false;
84
+ }
85
+ }
app/code/community/DPDFrance/Relais/Model/Owebia.php ADDED
@@ -0,0 +1,1175 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
+
1175
+ ?>
app/code/community/DPDFrance/Relais/controllers/DPDFranceRelaisController.php ADDED
@@ -0,0 +1,232 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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_DPDFranceRelaisController extends Mage_Core_Controller_Front_Action
13
+ {
14
+ public static function stripAccents($str)
15
+ {
16
+ $str = preg_replace('/[\x{00C0}\x{00C1}\x{00C2}\x{00C3}\x{00C4}\x{00C5}]/u','A', $str);
17
+ $str = preg_replace('/[\x{0105}\x{0104}\x{00E0}\x{00E1}\x{00E2}\x{00E3}\x{00E4}\x{00E5}]/u','a', $str);
18
+ $str = preg_replace('/[\x{00C7}\x{0106}\x{0108}\x{010A}\x{010C}]/u','C', $str);
19
+ $str = preg_replace('/[\x{00E7}\x{0107}\x{0109}\x{010B}\x{010D}}]/u','c', $str);
20
+ $str = preg_replace('/[\x{010E}\x{0110}]/u','D', $str);
21
+ $str = preg_replace('/[\x{010F}\x{0111}]/u','d', $str);
22
+ $str = preg_replace('/[\x{00C8}\x{00C9}\x{00CA}\x{00CB}\x{0112}\x{0114}\x{0116}\x{0118}\x{011A}]/u','E', $str);
23
+ $str = preg_replace('/[\x{00E8}\x{00E9}\x{00EA}\x{00EB}\x{0113}\x{0115}\x{0117}\x{0119}\x{011B}]/u','e', $str);
24
+ $str = preg_replace('/[\x{00CC}\x{00CD}\x{00CE}\x{00CF}\x{0128}\x{012A}\x{012C}\x{012E}\x{0130}]/u','I', $str);
25
+ $str = preg_replace('/[\x{00EC}\x{00ED}\x{00EE}\x{00EF}\x{0129}\x{012B}\x{012D}\x{012F}\x{0131}]/u','i', $str);
26
+ $str = preg_replace('/[\x{0142}\x{0141}\x{013E}\x{013A}]/u','l', $str);
27
+ $str = preg_replace('/[\x{00F1}\x{0148}]/u','n', $str);
28
+ $str = preg_replace('/[\x{00D2}\x{00D3}\x{00D4}\x{00D5}\x{00D6}\x{00D8}]/u','O', $str);
29
+ $str = preg_replace('/[\x{00F2}\x{00F3}\x{00F4}\x{00F5}\x{00F6}\x{00F8}]/u','o', $str);
30
+ $str = preg_replace('/[\x{0159}\x{0155}]/u','r', $str);
31
+ $str = preg_replace('/[\x{015B}\x{015A}\x{0161}]/u','s', $str);
32
+ $str = preg_replace('/[\x{00DF}]/u','ss', $str);
33
+ $str = preg_replace('/[\x{0165}]/u','t', $str);
34
+ $str = preg_replace('/[\x{00D9}\x{00DA}\x{00DB}\x{00DC}\x{016E}\x{0170}\x{0172}]/u','U', $str);
35
+ $str = preg_replace('/[\x{00F9}\x{00FA}\x{00FB}\x{00FC}\x{016F}\x{0171}\x{0173}]/u','u', $str);
36
+ $str = preg_replace('/[\x{00FD}\x{00FF}]/u','y', $str);
37
+ $str = preg_replace('/[\x{017C}\x{017A}\x{017B}\x{0179}\x{017E}]/u','z', $str);
38
+ $str = preg_replace('/[\x{00C6}]/u','AE', $str);
39
+ $str = preg_replace('/[\x{00E6}]/u','ae', $str);
40
+ $str = preg_replace('/[\x{0152}]/u','OE', $str);
41
+ $str = preg_replace('/[\x{0153}]/u','oe', $str);
42
+ $str = preg_replace('/[\x{0022}\x{0025}\x{0026}\x{0027}\x{00A1}\x{00A2}\x{00A3}\x{00A4}\x{00A5}\x{00A6}\x{00A7}\x{00A8}\x{00AA}\x{00AB}\x{00AC}\x{00AD}\x{00AE}\x{00AF}\x{00B0}\x{00B1}\x{00B2}\x{00B3}\x{00B4}\x{00B5}\x{00B6}\x{00B7}\x{00B8}\x{00BA}\x{00BB}\x{00BC}\x{00BD}\x{00BE}\x{00BF}]/u',' ', $str);
43
+ return $str;
44
+ }
45
+
46
+ public function indexAction()
47
+ {
48
+ $address = $this->getRequest()->getParam('address');
49
+ $address = mb_convert_encoding(urldecode( $address),'UTF-8');
50
+ $address = self::stripAccents($address);
51
+
52
+ $zipcode = $this->getRequest()->getParam('zipcode');
53
+ $zipcode = trim(urldecode($zipcode));
54
+ $zipcode = mb_convert_encoding($zipcode,'UTF-8');
55
+
56
+ $city = $this->getRequest()->getParam('city');
57
+ $city = mb_convert_encoding(urldecode($city),'UTF-8');
58
+ $city = self::stripAccents($city);
59
+
60
+ if (empty($zipcode))
61
+ echo '<ul class="messages"><li class="warnmsg"><ul><li>'.Mage::helper('dpdfrrelais')->__('The field Postal Code is mandatory!').'</li></ul></li></ul>';
62
+ else
63
+ {
64
+ if (empty($city))
65
+ echo '<ul class="messages"><li class="warnmsg"><ul><li>'.Mage::helper('dpdfrrelais')->__('The field City is mandatory!').'</li></ul></li></ul>';
66
+ else
67
+ {
68
+ $serviceurl = Mage::getStoreConfig('carriers/dpdfrrelais/serviceurl');
69
+ $firmid = Mage::getStoreConfig('carriers/dpdfrrelais/indentifier');
70
+ $key = Mage::getStoreConfig('carriers/dpdfrrelais/key');
71
+
72
+ // Paramètres d'appel au WS MyPudo
73
+ $variables = array( 'carrier' => $firmid,
74
+ 'key' => $key,
75
+ 'address' => $address,
76
+ 'zipCode' => $zipcode,
77
+ 'city' => $city,
78
+ 'countrycode' => 'FR',
79
+ 'requestID' => '1234',
80
+ 'request_id' => '1234',
81
+ 'date_from' => date('d/m/Y'),
82
+ 'max_pudo_number' => '',
83
+ 'max_distance_search'=> '',
84
+ 'weight' => '',
85
+ 'category' => '',
86
+ 'holiday_tolerant' => ''
87
+ );
88
+
89
+ // Message d'erreur si PHP_SOAP manquant
90
+ if (!extension_loaded('soap'))
91
+ echo '<ul class="messages"><li class="warnmsg"><ul><li>'.Mage::helper('dpdfrrelais')->__('ATTENTION! L\'extension PHP SOAP n\'est pas activée sur ce serveur. Vous devez l\'activer pour utiliser le module DPD Relais.').'</li></ul></li></ul>';
92
+ // Appel WS
93
+ try
94
+ {
95
+ ini_set("default_socket_timeout", 3);
96
+ $soappudo = new SoapClient($serviceurl,array('connection_timeout' => 3,'cache_wsdl' => WSDL_CACHE_NONE, 'exceptions' => true));
97
+ $GetPudoList = $soappudo->getPudoList($variables); // appel SOAP a l'applicatif GetPudoList
98
+ }
99
+ catch (Exception $e)
100
+ {
101
+ echo '<ul class="messages"><li class="warnmsg"><ul><li>'.Mage::helper('dpdfrrelais')->__('An error ocurred while fetching the DPD Pickup points. Please try again').'</li></ul></li></ul>';
102
+ exit;
103
+ }
104
+ $doc_xml = new SimpleXMLElement($GetPudoList->GetPudoListResult->any); // parsage XML de la réponse SOAP
105
+
106
+ $quality = (int)$doc_xml->attributes()->quality; // indice de qualité de la réponse SOAP
107
+
108
+ if ($doc_xml->xpath('ERROR')) // si le webservice répond un code erreur, afficher un message d'indisponibilité
109
+ echo '<ul class="messages"><li class="warnmsg"><ul><li>'.Mage::helper('dpdfrrelais')->__('An error ocurred while fetching the DPD Pickup points. Please try again').'</li></ul></li></ul>';
110
+ else
111
+ {
112
+ if ((int)$quality == 0)// Si la qualité de la réponse est 0, "merci d'indiquer une autre adresse"
113
+ echo '<ul class="messages"><li class="warnmsg"><ul><li>'.Mage::helper('dpdfrrelais')->__('There are no DPD Pickup points for the selected adress. Please modify it.').'</li></ul></li></ul>';
114
+ else
115
+ {
116
+ $allpudoitems = $doc_xml->xpath('PUDO_ITEMS'); // acceder a la balise pudo_items
117
+
118
+ foreach ($allpudoitems as $singlepudoitem) // eclatement des données contenues dans pudo_items
119
+ {
120
+ $result = $singlepudoitem->xpath('PUDO_ITEM');
121
+ $i=0;
122
+ foreach($result as $result2)
123
+ {
124
+ $offset = $i;
125
+
126
+ $LATITUDE = (float)str_replace(",",".",(string)$result2->LATITUDE);
127
+ $LONGITUDE = (float)str_replace(",",".",(string)$result2->LONGITUDE);
128
+
129
+ $html = '
130
+ <div>
131
+ <span class="dpdfrrelais_logo"><img src="'.Mage::getBaseUrl('media').'dpdfrance/front/relais/pointrelais.png" alt="-"/></span>
132
+ <span class="s1"><strong>'.self::stripAccents($result2->NAME).'</strong><br/>'.self::stripAccents($result2->ADDRESS1).' <br/> '.$result2->ZIPCODE.' '.self::stripAccents($result2->CITY).'</span>
133
+ <span class="s2">'.sprintf("%01.2f", (int)$result2->DISTANCE/1000).' km </span>
134
+ <span class="s3"><a href="#!" onClick="openDialog(\'relaydetail'.$offset.'\',\'map_canvas'.$offset.'\',\''.$LATITUDE.'\',\''.$LONGITUDE.'\',\''.Mage::getBaseUrl('media').'\')">'.Mage::helper('dpdfrrelais')->__('More details').'</a></span>
135
+ <input type="radio" id="relay-point'.$offset.'" name="relay-point" class="dpdfrrelais_radio" value="'.self::stripAccents($result2->ADDRESS1).' '.self::stripAccents($result2->ADDRESS2).'|||'.self::stripAccents($result2->NAME).' '.(string)$result2->PUDO_ID.'|||'.$result2->ZIPCODE.'|||'.self::stripAccents($result2->CITY).'">
136
+ <label class="dpdfrrelais_button_ici" for="relay-point'.$offset.'"><span><span></span></span><b>ICI</b></label>
137
+ </div>
138
+ ';
139
+
140
+ $days=array(1=>'monday',2=>'tuesday',3=>'wednesday',4=>'thursday',5=>'friday',6=>'saturday',7=>'sunday');
141
+ $point=array();
142
+ $item=(array)$result2;
143
+
144
+ if(count($item['OPENING_HOURS_ITEMS']->OPENING_HOURS_ITEM)>0)foreach($item['OPENING_HOURS_ITEMS']->OPENING_HOURS_ITEM as $k=>$oh_item)
145
+ {
146
+ $oh_item=(array)$oh_item;
147
+ $point[$days[$oh_item['DAY_ID']]][]=$oh_item['START_TM'].' - '.$oh_item['END_TM'];
148
+ }
149
+
150
+ if(empty($point['monday'])){$h1 = Mage::helper ('dpdfrrelais')->__ ('Closed');}
151
+ else{if(empty($point['monday'][1])){$h1 = $point['monday'][0];}
152
+ else{$h1 = $point['monday'][0].' & '.$point['monday'][1];}}
153
+
154
+ if(empty($point['tuesday'])){$h2 = Mage::helper ('dpdfrrelais')->__ ('Closed');}
155
+ else{if(empty($point['tuesday'][1])){$h2 = $point['tuesday'][0];}
156
+ else{$h2 = $point['tuesday'][0].' & '.$point['tuesday'][1];}}
157
+
158
+ if(empty($point['wednesday'])){$h3 = Mage::helper ('dpdfrrelais')->__ ('Closed');}
159
+ else{if(empty($point['wednesday'][1])){$h3 = $point['wednesday'][0];}
160
+ else{$h3 = $point['wednesday'][0].' & '.$point['wednesday'][1];}}
161
+
162
+ if(empty($point['thursday'])){$h4 = Mage::helper ('dpdfrrelais')->__ ('Closed');}
163
+ else{if(empty($point['thursday'][1])){$h4 = $point['thursday'][0];}
164
+ else{$h4 = $point['thursday'][0].' & '.$point['thursday'][1];}}
165
+
166
+ if(empty($point['friday'])){$h5 = Mage::helper ('dpdfrrelais')->__ ('Closed');}
167
+ else{if(empty($point['friday'][1])){$h5 = $point['friday'][0];}
168
+ else{$h5 = $point['friday'][0].' & '.$point['friday'][1];}}
169
+
170
+ if(empty($point['saturday'])){$h6 = Mage::helper ('dpdfrrelais')->__ ('Closed');}
171
+ else{if(empty($point['saturday'][1])){$h6 = $point['saturday'][0];}
172
+ else{$h6 = $point['saturday'][0].' & '.$point['saturday'][1];}}
173
+
174
+ if(empty($point['sunday'])){$h7 = Mage::helper ('dpdfrrelais')->__ ('Closed');}
175
+ else{if(empty($point['sunday'][1])){$h7 = $point['sunday'][0];}
176
+ else{$h7 = $point['sunday'][0].' & '.$point['sunday'][1];}}
177
+
178
+ $html .= '<div id="relaydetail'.$offset.'" style="display:none;">
179
+ <div class="dpdfrrelaisboxcarto" id="map_canvas'.$offset.'" style="width:100%;"></div>
180
+ <div id="dpdfrrelaisboxbottom" class="dpdfrrelaisboxbottom">
181
+ <div id="dpdfrrelaisboxadresse" class="dpdfrrelaisboxadresse">
182
+ <div class="dpdfrrelaisboxadresseheader"><img src="'.Mage::getBaseUrl('media').'dpdfrance/front/relais/pointrelais.png" alt="-" width="32" height="32"/><br/>'.Mage::helper('dpdfrrelais')->__('Your DPD Pickup point').'</div>
183
+ <strong>'.$result2->NAME.'</strong></br>
184
+ '.$result2->ADDRESS1.'</br>';
185
+ if (!empty($result2->ADDRESS2))
186
+ $html .= $result2->ADDRESS2.'</br>';
187
+ $html .= $result2->ZIPCODE.' '.$result2->CITY.'<br/>';
188
+ if (!empty($result2->LOCAL_HINT))
189
+ $html .= '<p>'.Mage::helper('dpdfrrelais')->__('info').' : '.$result2->LOCAL_HINT.'</p>';
190
+ $html .= '</div>';
191
+
192
+ $html .= '<div class="dpdfrrelaisboxhoraires">
193
+ <div class="dpdfrrelaisboxhorairesheader"><img src="'.Mage::getBaseUrl('media').'dpdfrance/front/relais/horaires.png" alt="-" width="32" height="32"/><br/>'.Mage::helper('dpdfrrelais')->__('Opening hours').'</div>
194
+ <p><span>'.Mage::helper('dpdfrrelais')->__('Monday').' : </span>'.$h1.'</p>
195
+ <p><span>'.Mage::helper('dpdfrrelais')->__('Tuesday').' : </span>'.$h2.'</p>
196
+ <p><span>'.Mage::helper('dpdfrrelais')->__('Wednesday').' : </span>'.$h3.'</p>
197
+ <p><span>'.Mage::helper('dpdfrrelais')->__('Thursday').' : </span>'.$h4.'</p>
198
+ <p><span>'.Mage::helper('dpdfrrelais')->__('Friday').' : </span>'.$h5.'</p>
199
+ <p><span>'.Mage::helper('dpdfrrelais')->__('Saturday').' : </span>'.$h6.'</p>
200
+ <p><span>'.Mage::helper('dpdfrrelais')->__('Sunday').' : </span>'.$h7.'</p>
201
+ </div>';
202
+
203
+ $html .= '<div class="dpdfrrelaisboxinfos">
204
+ <div class="dpdfrrelaisboxinfosheader"><img src="'.Mage::getBaseUrl('media').'dpdfrance/front/relais/info.png" alt="-" width="32" height="32"/><br/>'.Mage::helper ('dpdfrrelais')->__('More info').'</div>
205
+ <div><h5>'.Mage::helper('dpdfrrelais')->__('Distance in KM').' : </h5><strong>'.sprintf("%01.2f", $result2->DISTANCE/1000).' km </strong></div>
206
+ <div><h5>'.Mage::helper('dpdfrrelais')->__('DPD Pickup ID#').' : </h5><strong>'.(string)$result2->PUDO_ID.'</strong></div>';
207
+ if (count($result2->HOLIDAY_ITEMS->HOLIDAY_ITEM) > 0)
208
+ {
209
+ foreach ($result2->HOLIDAY_ITEMS->HOLIDAY_ITEM as $holiday_item)
210
+ {
211
+ $holiday_item = (array)$holiday_item;
212
+ $html .= '<div><img id="dpdfrrelaisboxinfoswarning" src="'.Mage::getBaseUrl('media').'dpdfrance/front/relais/warning.png" alt="-" width="16" height="16"/> <h4>'.Mage::helper('dpdfrrelais')->__('Closing period').' : </h4> '.$holiday_item['START_DTM'].' - '.$holiday_item['END_DTM'].'</div>';
213
+ }
214
+ }
215
+ $html .= '</div>';
216
+
217
+ $html .= '</div></div>'; // dpdfrrelaisboxbottom et relaydetail
218
+ echo $html;
219
+
220
+ $i++;
221
+ $hd1 = $hd2 = $hd3 = $hd4 = $hd5 = $hd6 = $hd7 = $h1 = $h2 = $h3 = $h4 = $h5 = $h6 = $h7 = null;
222
+ if($i == 5) // Nombre de points relais à afficher - max 10
223
+ exit();
224
+ }
225
+ }
226
+ }
227
+ }
228
+ }
229
+ }
230
+ }
231
+ }
232
+ ?>
app/code/community/DPDFrance/Relais/etc/config.xml ADDED
@@ -0,0 +1,189 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
+ <default>
15
+ <carriers>
16
+ <dpdfrrelais>
17
+ <group>dpdfrrelais</group>
18
+ <sallowspecific>0</sallowspecific>
19
+ <model>dpdfrrelais/carrier_DPDFranceRelaisShipping</model>
20
+ <name>DPD Relais</name>
21
+ <title>Livraison en relais Pickup</title>
22
+ <methodname>Livraison 24-48h en France vers plus de 5 000 relais Pickup</methodname>
23
+ <serviceurl>http://mypudo.pickup-services.com/mypudo/mypudo.asmx?WSDL</serviceurl>
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>
74
+ </carriers>
75
+ </default>
76
+ <modules>
77
+ <DPDFrance_Relais>
78
+ <version>5.0.0</version>
79
+ <depends>
80
+ <Mage_Shipping/>
81
+ </depends>
82
+ </DPDFrance_Relais>
83
+ </modules>
84
+ <global>
85
+ <blocks>
86
+ <dpdfrrelais>
87
+ <class>DPDFrance_Relais_Block</class>
88
+ </dpdfrrelais>
89
+ </blocks>
90
+ <helpers>
91
+ <dpdfrrelais>
92
+ <class>DPDFrance_Relais_Helper</class>
93
+ </dpdfrrelais>
94
+ </helpers>
95
+ <models>
96
+ <dpdfrrelais>
97
+ <class>DPDFrance_Relais_Model</class>
98
+ </dpdfrrelais>
99
+ </models>
100
+ <resources>
101
+ <dpdfrrelais_setup>
102
+ <setup>
103
+ <module>DPDFrance_Relais</module>
104
+ </setup>
105
+ <connection>
106
+ <use>core_setup</use>
107
+ </connection>
108
+ </dpdfrrelais_setup>
109
+ <dpdfrrelais_write>
110
+ <connection>
111
+ <use>core_write</use>
112
+ </connection>
113
+ </dpdfrrelais_write>
114
+ <dpdfrrelais_read>
115
+ <connection>
116
+ <use>core_read</use>
117
+ </connection>
118
+ </dpdfrrelais_read>
119
+ </resources>
120
+ </global>
121
+ <adminhtml>
122
+ <translate>
123
+ <modules>
124
+ <Mage_Shipping>
125
+ <files>
126
+ <DPDFrance_Relais>DPDFrance_Relais.csv</DPDFrance_Relais>
127
+ </files>
128
+ </Mage_Shipping>
129
+ </modules>
130
+ </translate>
131
+ <acl>
132
+ <resources>
133
+ <admin>
134
+ <children>
135
+ <system>
136
+ <children>
137
+ <config>
138
+ <children>
139
+ <dpdfrrelais>
140
+ <title>DPD Relais</title>
141
+ </dpdfrrelais>
142
+ </children>
143
+ </config>
144
+ </children>
145
+ </system>
146
+ </children>
147
+ </admin>
148
+ </resources>
149
+ </acl>
150
+ </adminhtml>
151
+ <frontend>
152
+ <layout>
153
+ <updates>
154
+ <dpdfrrelais module="DPDFrance_Relais">
155
+ <file>dpdfrrelais.xml</file>
156
+ </dpdfrrelais>
157
+ </updates>
158
+ </layout>
159
+ <routers>
160
+ <dpdfrrelais>
161
+ <use>standard</use>
162
+ <args>
163
+ <module>DPDFrance_Relais</module>
164
+ <frontName>relais</frontName>
165
+ </args>
166
+ </dpdfrrelais>
167
+ </routers>
168
+ <translate>
169
+ <modules>
170
+ <Mage_Shipping>
171
+ <files>
172
+ <DPDFrance_Relais>DPDFrance_Relais.csv</DPDFrance_Relais>
173
+ </files>
174
+ </Mage_Shipping>
175
+ </modules>
176
+ </translate>
177
+ <events>
178
+ <checkout_controller_onepage_save_shipping_method>
179
+ <observers>
180
+ <dpdfrrelais_observer>
181
+ <type>model</type>
182
+ <class>dpdfrrelais/observer</class>
183
+ <method>changeshippingaddressAction</method>
184
+ </dpdfrrelais_observer>
185
+ </observers>
186
+ </checkout_controller_onepage_save_shipping_method>
187
+ </events>
188
+ </frontend>
189
+ </config>
app/code/community/DPDFrance/Relais/etc/system.xml ADDED
@@ -0,0 +1,131 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
+ <sections>
15
+ <carriers>
16
+ <groups>
17
+ <dpdfrrelais translate="label" module="shipping">
18
+ <label>Livraison DPD Relais (France uniquement)</label>
19
+ <comment><![CDATA[<strong>Veuillez configurer la livraison DPD Relais ci-dessous.</strong><br />Pour de l'aide, veuillez vous référez à la documentation de ce module disponible ici : <a href="../../../../../../../../media/dpdfrance/readme_dpdfrance_magento.pdf" target="_blank">PDF</a>]]></comment>
20
+ <front-type>text</front-type>
21
+ <sort_order>-100</sort_order>
22
+ <show_in_default>1</show_in_default>
23
+ <show_in_website>1</show_in_website>
24
+ <show_in_store>1</show_in_store>
25
+ <fields>
26
+ <active translate="label">
27
+ <label>Enabled</label>
28
+ <frontend_type>select</frontend_type>
29
+ <source_model>adminhtml/system_config_source_yesno</source_model>
30
+ <sort_order>1</sort_order>
31
+ <show_in_default>1</show_in_default>
32
+ <show_in_website>1</show_in_website>
33
+ <show_in_store>1</show_in_store>
34
+ </active>
35
+ <title translate="label">
36
+ <label>Title</label>
37
+ <front_type>text</front_type>
38
+ <sort_order>2</sort_order>
39
+ <show_in_default>1</show_in_default>
40
+ <show_in_website>1</show_in_website>
41
+ <show_in_store>1</show_in_store>
42
+ </title>
43
+ <methodname translate="label">
44
+ <label>Subtitle</label>
45
+ <front_type>text</front_type>
46
+ <sort_order>3</sort_order>
47
+ <show_in_default>1</show_in_default>
48
+ <show_in_website>1</show_in_website>
49
+ <show_in_store>1</show_in_store>
50
+ </methodname>
51
+ <serviceurl translate="label">
52
+ <label>URL MyPudo</label>
53
+ <frontend_type>text</frontend_type>
54
+ <sort_order>4</sort_order>
55
+ <show_in_default>1</show_in_default>
56
+ <show_in_website>1</show_in_website>
57
+ <show_in_store>1</show_in_store>
58
+ </serviceurl>
59
+ <indentifier translate="label">
60
+ <label>ID trader</label>
61
+ <front_type>text</front_type>
62
+ <sort_order>5</sort_order>
63
+ <show_in_default>1</show_in_default>
64
+ <show_in_website>1</show_in_website>
65
+ <show_in_store>1</show_in_store>
66
+ </indentifier>
67
+ <key translate="label">
68
+ <label>Security Key</label>
69
+ <front_type>text</front_type>
70
+ <sort_order>6</sort_order>
71
+ <show_in_default>1</show_in_default>
72
+ <show_in_website>1</show_in_website>
73
+ <show_in_store>1</show_in_store>
74
+ </key>
75
+ <depot translate="label">
76
+ <label>Your DPD Depot #</label>
77
+ <front_type>text</front_type>
78
+ <sort_order>7</sort_order>
79
+ <show_in_default>1</show_in_default>
80
+ <show_in_website>1</show_in_website>
81
+ <show_in_store>1</show_in_store>
82
+ <comment><![CDATA[Sur 3 chiffres (ex.: 013)</a>]]></comment>
83
+ </depot>
84
+ <cargo translate="label">
85
+ <label>Your DPD Relais contract #</label>
86
+ <front_type>text</front_type>
87
+ <sort_order>8</sort_order>
88
+ <show_in_default>1</show_in_default>
89
+ <show_in_website>1</show_in_website>
90
+ <show_in_store>1</show_in_store>
91
+ <comment><![CDATA[Sur 4 ou 5 chiffres, sans code agence, sans espace, sans tiret ni zéros devant</a>]]></comment>
92
+ </cargo>
93
+ <expense translate="label">
94
+ <label>Shipping rates configuration</label>
95
+ <frontend_type>textarea</frontend_type>
96
+ <sort_order>10</sort_order>
97
+ <show_in_default>1</show_in_default>
98
+ <show_in_website>1</show_in_website>
99
+ <show_in_store>1</show_in_store>
100
+ </expense>
101
+ <showerror translate="label">
102
+ <label>Display when unavailable</label>
103
+ <frontend_type>select</frontend_type>
104
+ <source_model>adminhtml/system_config_source_yesno</source_model>
105
+ <sort_order>15</sort_order>
106
+ <show_in_default>1</show_in_default>
107
+ <show_in_website>1</show_in_website>
108
+ <show_in_store>1</show_in_store>
109
+ </showerror>
110
+ <specificerrmsg translate="label">
111
+ <label>Displayed Error Message</label>
112
+ <frontend_type>textarea</frontend_type>
113
+ <sort_order>16</sort_order>
114
+ <show_in_default>1</show_in_default>
115
+ <show_in_website>1</show_in_website>
116
+ <show_in_store>1</show_in_store>
117
+ </specificerrmsg>
118
+ <sort_order translate="label">
119
+ <label>Sort Order</label>
120
+ <frontend_type>text</frontend_type>
121
+ <sort_order>270</sort_order>
122
+ <show_in_default>1</show_in_default>
123
+ <show_in_website>1</show_in_website>
124
+ <show_in_store>0</show_in_store>
125
+ </sort_order>
126
+ </fields>
127
+ </dpdfrrelais>
128
+ </groups>
129
+ </carriers>
130
+ </sections>
131
+ </config>
app/design/frontend/base/default/layout/dpdfrpredict.xml ADDED
@@ -0,0 +1,49 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
+ <layout version="0.1.0">
14
+ <checkout_onepage_index>
15
+ <reference name="head">
16
+ <action method="addItem"><type>skin_js</type><script>js/dpdfrance/dpdfrpredict.js</script></action>
17
+ <action method="addItem"><type>skin_css</type><name>css/dpdfrance/dpdfrpredict.css</name><params/></action>
18
+ </reference>
19
+ <reference name="checkout.onepage.shipping_method">
20
+ <action method="setTemplate"><template>dpdfrpredict/checkout/onepage/shipping_method.phtml</template></action>
21
+ <block type="checkout/onepage_shipping_method_available" name="checkout.onepage.shipping_method.available" as="available" template="dpdfrpredict/checkout/onepage/shipping_method/available.phtml"></block>
22
+ </reference>
23
+ </checkout_onepage_index>
24
+
25
+ <checkout_onepage_shippingmethod>
26
+ <block type="checkout/onepage_shipping_method_available" name="root" output="toHtml" template="dpdfrpredict/checkout/onepage/shipping_method/available.phtml"></block>
27
+ </checkout_onepage_shippingmethod>
28
+
29
+ <!-- Magento 1.8 et supérieur : activez ce bloc -->
30
+ <!--
31
+ <checkout_onepage_progress>
32
+ <block type="checkout/onepage_progress" name="shipping.progress" template="checkout/onepage/progress/shipping.phtml"></block>
33
+ <block type="checkout/onepage_progress" name="shippingmethod.progress" template="checkout/onepage/progress/shipping_method.phtml"></block>
34
+ </checkout_onepage_progress>
35
+
36
+ <checkout_onepage_progress_shipping>
37
+ <block type="checkout/onepage_progress" name="root" output="toHtml" template="relaypoint/checkout/onepage/progress/shipping.phtml">
38
+ <action method="setInfoTemplate"><method></method><template></template></action>
39
+ </block>
40
+ </checkout_onepage_progress_shipping>
41
+
42
+ <checkout_onepage_progress_shipping_method>
43
+ <block type="checkout/onepage_progress" name="root" output="toHtml" template="relaypoint/checkout/onepage/progress/shipping_method.phtml">
44
+ <action method="setInfoTemplate"><method></method><template></template></action>
45
+ </block>
46
+ </checkout_onepage_progress_shipping_method>
47
+ -->
48
+
49
+ </layout>
app/design/frontend/base/default/layout/dpdfrrelais.xml ADDED
@@ -0,0 +1,53 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
+ <layout version="0.1.0">
14
+ <checkout_onepage_index>
15
+ <reference name="head">
16
+ <action method="addItem"><type>skin_js</type><script>js/dpdfrance/dpdfrrelais.js</script></action>
17
+ <action method="addJs"><script>prototype/window.js</script></action>
18
+ <action method="addItem"><type>js</type><name>prototype/window_effects.js</name><params/><if>lt IE 7</if></action>
19
+ <action method="addJs"><script>prototype/debug.js</script></action>
20
+ <action method="addItem"><type>skin_css</type><name>css/dpdfrance/dpdfrrelais.css</name><params/></action>
21
+ <block type="core/text" name="map.js"><action method="setText"><text><![CDATA[<script type="text/javascript" src="https://maps.google.com/maps/api/js?sensor=false&region=FR"></script>]]></text></action></block>
22
+ </reference>
23
+ <reference name="checkout.onepage.shipping_method">
24
+ <action method="setTemplate"><template>dpdfrrelais/checkout/onepage/shipping_method.phtml</template></action>
25
+ <block type="checkout/onepage_shipping_method_available" name="checkout.onepage.shipping_method.available" as="available" template="dpdfrrelais/checkout/onepage/shipping_method/available.phtml"></block>
26
+ </reference>
27
+ </checkout_onepage_index>
28
+
29
+ <checkout_onepage_shippingmethod>
30
+ <block type="checkout/onepage_shipping_method_available" name="root" output="toHtml" template="dpdfrrelais/checkout/onepage/shipping_method/available.phtml"></block>
31
+ </checkout_onepage_shippingmethod>
32
+
33
+ <!-- Magento 1.8 et supérieur : activez ce bloc -->
34
+ <!--
35
+ <checkout_onepage_progress>
36
+ <block type="checkout/onepage_progress" name="shipping.progress" template="checkout/onepage/progress/shipping.phtml"></block>
37
+ <block type="checkout/onepage_progress" name="shippingmethod.progress" template="checkout/onepage/progress/shipping_method.phtml"></block>
38
+ </checkout_onepage_progress>
39
+
40
+ <checkout_onepage_progress_shipping>
41
+ <block type="checkout/onepage_progress" name="root" output="toHtml" template="dpdfrrelais/checkout/onepage/progress/shipping.phtml">
42
+ <action method="setInfoTemplate"><method></method><template></template></action>
43
+ </block>
44
+ </checkout_onepage_progress_shipping>
45
+
46
+ <checkout_onepage_progress_shipping_method>
47
+ <block type="checkout/onepage_progress" name="root" output="toHtml" template="dpdfrrelais/checkout/onepage/progress/shipping_method.phtml">
48
+ <action method="setInfoTemplate"><method></method><template></template></action>
49
+ </block>
50
+ </checkout_onepage_progress_shipping_method>
51
+ -->
52
+
53
+ </layout>
app/design/frontend/base/default/template/dpdfrpredict/checkout/onepage/progress/shipping.phtml ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
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
+ <!-- MODIFICATION DPD FRANCE POUR MAGENTO 1.8 : DEPLACEMENT BLOC CHECKOUT PROGRESS SHIPPING VERS SHIPPING_METHOD -->
13
+
app/design/frontend/base/default/template/dpdfrpredict/checkout/onepage/progress/shipping_method.phtml ADDED
@@ -0,0 +1,65 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
+
13
+ <!-- DEBUT MODIFICATION DPD FRANCE POUR MAGENTO 1.8 DEPLACEMENT BLOC PROGRESS CHECKOUT SHIPPING -->
14
+
15
+ <?php if ($this->getCheckout()->getStepData('shipping', 'complete')): ?>
16
+ <?php $completeClass = $this->getCheckout()->getStepData('shipping', 'complete') ? 'complete' : ''; ?>
17
+ <dt class="<?php echo $completeClass ?>">
18
+ <?php echo $this->__('Shipping Address') ?> <span class="changelink"><span class="separator">|</span> <a
19
+ href="#payment"
20
+ onclick="checkout.changeSection('opc-shipping');return false;"><?php echo $this->__('Change') ?></a></span>
21
+ </dt>
22
+ <dd class="<?php echo $completeClass ?>">
23
+ <?php if ($this->getCheckout()->getStepData('shipping', 'complete')): ?>
24
+ <address><?php echo $this->getShipping()->format('html') ?></address>
25
+ <?php endif; ?>
26
+ </dd>
27
+ <?php else: ?>
28
+ <dt>
29
+ <?php echo $this->__('Shipping Address') ?>
30
+ </dt>
31
+ <?php endif; ?>
32
+
33
+ <!-- FIN MODIFICATION DPD FRANCE POUR MAGENTO 1.8 -->
34
+
35
+ <?php if ($this->getCheckout()->getStepData('shipping_method', 'complete')): ?>
36
+ <dt class="complete">
37
+ <?php echo $this->__('Shipping Method') ?> <span class="changelink"><span class="separator">|</span> <a
38
+ href="#shipping_method"
39
+ onclick="checkout.changeSection('opc-shipping_method'); return false;"><?php echo $this->__('Change') ?></a></span>
40
+ </dt>
41
+ <dd class="complete">
42
+ <?php if ($this->getShippingMethod()): ?>
43
+ <?php echo $this->getShippingDescription() ?>
44
+
45
+ <?php $_excl = $this->getShippingPriceExclTax(); ?>
46
+ <?php $_incl = $this->getShippingPriceInclTax(); ?>
47
+ <?php if ($this->helper('tax')->displayShippingPriceIncludingTax()): ?>
48
+ <?php echo $_incl; ?>
49
+ <?php else: ?>
50
+ <?php echo $_excl; ?>
51
+ <?php endif; ?>
52
+ <?php if ($this->helper('tax')->displayShippingBothPrices() && $_incl != $_excl): ?>
53
+ (<?php echo $this->__('Incl. Tax'); ?> <?php echo $_incl; ?>)
54
+ <?php endif; ?>
55
+
56
+ <?php else: ?>
57
+ <?php echo $this->__('Shipping method has not been selected yet') ?>
58
+ <?php endif; ?>
59
+ </dd>
60
+ <?php else: ?>
61
+ <dt>
62
+ <?php echo $this->__('Shipping Method') ?>
63
+ </dt>
64
+ <?php endif; ?>
65
+
app/design/frontend/base/default/template/dpdfrpredict/checkout/onepage/shipping_method.phtml ADDED
@@ -0,0 +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
+ <form id="co-shipping-method-form" action="">
13
+ <div id="checkout-shipping-method-load">
14
+ <?php echo $this->getChildHtml('available') ?>
15
+ </div>
16
+ <script type="text/javascript">
17
+ //<![CDATA[
18
+ var shippingMethod = new ShippingMethod('co-shipping-method-form', "<?php echo $this->getUrl('checkout/onepage/saveShippingMethod') ?>");
19
+ //]]>
20
+ </script>
21
+ <div id="onepage-checkout-shipping-method-additional-load">
22
+ <?php echo $this->getChildHtml('additional') ?>
23
+ </div>
24
+ <div class="buttons-set" id="shipping-method-buttons-container">
25
+ <p class="back-link"><a href="#" onclick="checkout.back(); return false;"><small>&laquo; </small><?php echo $this->__('Back') ?></a></p>
26
+ <button type="button" class="button" onclick="updateshipping('<?php echo substr(Mage::getUrl('relais/dpdfrrelais/changeshippingaddress'),0,-1)?>')"><span><span><?php echo $this->__('Continue') ?></span></span></button>
27
+ <span id="shipping-method-please-wait" class="please-wait" style="display:none;">
28
+ <img src="<?php echo $this->getSkinUrl('images/opc-ajax-loader.gif') ?>" alt="<?php echo $this->__('Loading next step...') ?>" title="<?php echo $this->__('Loading next step...') ?>" class="v-middle" /> <?php echo $this->__('Loading next step...') ?>
29
+ </span>
30
+ </div>
31
+ </form>
app/design/frontend/base/default/template/dpdfrpredict/checkout/onepage/shipping_method/available.phtml ADDED
@@ -0,0 +1,112 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
+ <?php if (!($_shippingRateGroups = $this->getShippingRates())): ?>
13
+ <p><?php echo $this->__('Sorry, no quotes are available for this order at this time.') ?></p>
14
+ <?php else: ?>
15
+ <dl class="sp-methods">
16
+ <?php $_sole = count($_shippingRateGroups) == 1; foreach ($_shippingRateGroups as $code => $_rates): ?>
17
+ <dt><?php echo $this->getCarrierName($code) ?></dt>
18
+ <dd>
19
+ <ul>
20
+ <?php $_sole = $_sole && count($_rates) == 1; foreach ($_rates as $_rate): ?>
21
+ <li>
22
+ <?php if ($_rate->getErrorMessage()): ?>
23
+ <ul class="messages"><li class="error-msg"><ul><li><?php echo $_rate->getErrorMessage() ?></li></ul></li></ul>
24
+ <?php else: ?>
25
+ <?php // Ajout DPD France - ajout onClick="radioCheck()" sur les boutons radio pour afficher/masquer les div DPD Relais et Predict ?>
26
+ <input name="shipping_method" type="radio" value="<?php echo $_rate->getCode() ?>" id="s_method_<?php echo $_rate->getCode() ?>"<?php if($_rate->getCode()===$this->getAddressShippingMethod()) echo ' checked="checked"' ?> class="radio" onClick="radioCheck()" />
27
+ <?php // Fin DPD France ?>
28
+ <label for="s_method_<?php echo $_rate->getCode() ?>"><?php echo $_rate->getMethodTitle() ?>
29
+ <?php $_excl = $this->getShippingPrice($_rate->getPrice(), $this->helper('tax')->displayShippingPriceIncludingTax()); ?>
30
+ <?php $_incl = $this->getShippingPrice($_rate->getPrice(), true); ?>
31
+ <?php echo $_excl; ?>
32
+ <?php if ($this->helper('tax')->displayShippingBothPrices() && $_incl != $_excl): ?>
33
+ (<?php echo $this->__('Incl. Tax'); ?> <?php echo $_incl; ?>)
34
+ <?php endif; ?>
35
+ </label>
36
+
37
+ <?php // Ajout DPD France - Div de sélection DPD Relais ?>
38
+ <?php if (($_rate->getCarrier()=='dpdfrrelais') && ($this->getQuote()->getShippingAddress()->getCountry()== 'FR')):?>
39
+ <div id="dpdfrrelais" style="display:none;" >
40
+ <div class="relaypoint_header">
41
+ <label class="relaypoint_label_header"><?php echo Mage::helper ( 'dpdfrrelais' )->__ ( 'Your Pickup delivery by DPD' )?></label><br>
42
+ </div>
43
+ <div class="relaypoint_search">
44
+
45
+ <div class="relaypoint_logo">
46
+ <label class="relaypoint_label_logo"><img src="<?php echo Mage::getBaseUrl(Mage_Core_Model_Store::URL_TYPE_MEDIA).'dpdfrance/front/relais/carrier_logo.jpg' ?>" alt=""/>
47
+ </div>
48
+
49
+ <div class="relaypoint_input">
50
+ <label class="relaypoint_label_find"><?php echo Mage::helper ( 'dpdfrrelais' )->__ ( 'Find DPD Pickup points near this address : ' )?></label><br/>
51
+ <input id="address" name="address" type="text" class="relaypoint-input-address" value="<?php echo $this->htmlEscape($this->getAddress()->getStreet(1))?>"/><br>
52
+ <input id="zipcode" name="zipcode" type="text" class="relaypoint-input-zipcode" value="<?php echo $this->htmlEscape($this->getAddress()->getPostcode())?>"/>
53
+ <input id="city" name="city" type="text" class="relaypoint-input-city" value="<?php echo $this->htmlEscape($this->getAddress()->getCity())?>"/>
54
+ <button class="dpdfrbutton" onclick="fetchPoint('<?php echo substr(Mage::getUrl('relais/dpdfrancerelais/index', array('_secure' => true)),0,-1)?>','suggestion')" type="button" style="height: 20px;padding: 0;width: 36px;">
55
+ <span>OK</span>
56
+ </button>
57
+ <span id="loadingpointswait" style="display:none;">
58
+ <img src="<?php echo Mage::getBaseUrl(Mage_Core_Model_Store::URL_TYPE_MEDIA).'dpdfrance/front/relais/loader.gif' ?>" alt="" class="v-middle" />
59
+ </span>
60
+ </div>
61
+ <div id="suggestion"></div>
62
+ </div>
63
+ </div>
64
+ <?php endif;?>
65
+ <?php // Fin DPD France ?>
66
+
67
+ <?php // Ajout DPD France - Div de présentation DPD Predict ?>
68
+ <?php if (($_rate->getCarrier()=='dpdfrpredict') && ($this->getQuote()->getShippingAddress()->getCountry()== 'FR')):?>
69
+ <div id="dpdfrpredict" style="display:none;" >
70
+ <div class="predict_header">
71
+ <label class="predict_label_header"><?php echo Mage::helper ( 'dpdfrpredict' )->__ ( 'Your Predict delivery by DPD' )?></label><br>
72
+ </div>
73
+ <div class="predict_search">
74
+ <div class="predict_logo">
75
+ <label class="predict_label_logo"><img src="<?php echo Mage::getBaseUrl(Mage_Core_Model_Store::URL_TYPE_MEDIA).'dpdfrance/front/predict/dpd_predict_logo.png' ?>" alt=""/>
76
+ </div>
77
+ <div class="copy">
78
+ <p><h2><?php echo Mage::helper ( 'dpdfrpredict' )->__ ( 'Predict offers you the following benefits' )?></h2></p>
79
+ <ul>
80
+ <li><b><?php echo Mage::helper ( 'dpdfrpredict' )->__ ( 'A parcel delivery in a 3-hour time window (choice is made by SMS or through our website)' )?></b></li>
81
+ <li><b><?php echo Mage::helper ( 'dpdfrpredict' )->__ ( 'A complete and detailed tracking of your delivery' )?></b></li>
82
+ <li><b><?php echo Mage::helper ( 'dpdfrpredict' )->__ ( 'In case of absence, you can schedule a new delivery when and where you it suits you best' )?></b></li>
83
+ </ul>
84
+ <p><h2><?php echo Mage::helper ( 'dpdfrpredict' )->__ ( 'How does it work?' )?></h2></p>
85
+ <ul>
86
+ <li><?php echo Mage::helper ( 'dpdfrpredict' )->__ ( 'Once your order is ready for shipment, you will receive an SMS proposing various days and time windows for your delivery.' )?></li>
87
+ <li><?php echo Mage::helper ( 'dpdfrpredict' )->__ ( 'You choose the moment which suits you best for the delivery by replying to the SMS (no extra cost) or through our website' )?> <a href="http://www.dpd.fr/destinataires">dpd.fr</a></li>
88
+ <li><?php echo Mage::helper ( 'dpdfrpredict' )->__ ( 'On the day of delivery, a text message will remind you the selected time window.' )?></li>
89
+ </ul>
90
+ </div>
91
+ <br/>
92
+ <div id="div_dpdfrance_dpd_logo"></div>
93
+ </div>
94
+ <div id="dpdfrance_predict_error" class="warnmsg" style="display:none;">
95
+ <?php echo Mage::helper ( 'dpdfrpredict' )->__ ( 'It seems that the GSM number you provided is incorrect. Please provide a french GSM number, starting with 06 or 07, on 10 consecutive digits.')?>
96
+ </div>
97
+ <div id="div_dpdfrance_predict_gsm">
98
+ <?php echo Mage::helper ( 'dpdfrpredict' )->__ ( 'To get all the advantages of DPD\'s Predict service, please provide a french mobile phone number here ')?>
99
+ <input id="gsm_dest" name="gsm_dest" type="text" class="predict-input-text" value="<?php echo $this->htmlEscape($this->getQuote()->getBillingAddress()->getTelephone())?>"/>
100
+ </div>
101
+ </div>
102
+ <?php endif;?>
103
+ <?php // Fin DPD France ?>
104
+
105
+ <?php endif ?>
106
+ </li>
107
+ <?php endforeach; ?>
108
+ </ul>
109
+ </dd>
110
+ <?php endforeach; ?>
111
+ </dl>
112
+ <?php endif; ?>
app/design/frontend/base/default/template/dpdfrrelais/checkout/onepage/progress/shipping.phtml ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
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
+ <!-- MODIFICATION DPD FRANCE POUR MAGENTO 1.8 : DEPLACEMENT BLOC CHECKOUT PROGRESS SHIPPING VERS SHIPPING_METHOD -->
13
+
app/design/frontend/base/default/template/dpdfrrelais/checkout/onepage/progress/shipping_method.phtml ADDED
@@ -0,0 +1,65 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
+
13
+ <!-- DEBUT MODIFICATION DPD FRANCE POUR MAGENTO 1.8 DEPLACEMENT BLOC PROGRESS CHECKOUT SHIPPING -->
14
+
15
+ <?php if ($this->getCheckout()->getStepData('shipping', 'complete')): ?>
16
+ <?php $completeClass = $this->getCheckout()->getStepData('shipping', 'complete') ? 'complete' : ''; ?>
17
+ <dt class="<?php echo $completeClass ?>">
18
+ <?php echo $this->__('Shipping Address') ?> <span class="changelink"><span class="separator">|</span> <a
19
+ href="#payment"
20
+ onclick="checkout.changeSection('opc-shipping');return false;"><?php echo $this->__('Change') ?></a></span>
21
+ </dt>
22
+ <dd class="<?php echo $completeClass ?>">
23
+ <?php if ($this->getCheckout()->getStepData('shipping', 'complete')): ?>
24
+ <address><?php echo $this->getShipping()->format('html') ?></address>
25
+ <?php endif; ?>
26
+ </dd>
27
+ <?php else: ?>
28
+ <dt>
29
+ <?php echo $this->__('Shipping Address') ?>
30
+ </dt>
31
+ <?php endif; ?>
32
+
33
+ <!-- FIN MODIFICATION DPD FRANCE POUR MAGENTO 1.8 -->
34
+
35
+ <?php if ($this->getCheckout()->getStepData('shipping_method', 'complete')): ?>
36
+ <dt class="complete">
37
+ <?php echo $this->__('Shipping Method') ?> <span class="changelink"><span class="separator">|</span> <a
38
+ href="#shipping_method"
39
+ onclick="checkout.changeSection('opc-shipping_method'); return false;"><?php echo $this->__('Change') ?></a></span>
40
+ </dt>
41
+ <dd class="complete">
42
+ <?php if ($this->getShippingMethod()): ?>
43
+ <?php echo $this->getShippingDescription() ?>
44
+
45
+ <?php $_excl = $this->getShippingPriceExclTax(); ?>
46
+ <?php $_incl = $this->getShippingPriceInclTax(); ?>
47
+ <?php if ($this->helper('tax')->displayShippingPriceIncludingTax()): ?>
48
+ <?php echo $_incl; ?>
49
+ <?php else: ?>
50
+ <?php echo $_excl; ?>
51
+ <?php endif; ?>
52
+ <?php if ($this->helper('tax')->displayShippingBothPrices() && $_incl != $_excl): ?>
53
+ (<?php echo $this->__('Incl. Tax'); ?> <?php echo $_incl; ?>)
54
+ <?php endif; ?>
55
+
56
+ <?php else: ?>
57
+ <?php echo $this->__('Shipping method has not been selected yet') ?>
58
+ <?php endif; ?>
59
+ </dd>
60
+ <?php else: ?>
61
+ <dt>
62
+ <?php echo $this->__('Shipping Method') ?>
63
+ </dt>
64
+ <?php endif; ?>
65
+
app/design/frontend/base/default/template/dpdfrrelais/checkout/onepage/shipping_method.phtml ADDED
@@ -0,0 +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
+ <form id="co-shipping-method-form" action="">
13
+ <div id="checkout-shipping-method-load">
14
+ <?php echo $this->getChildHtml('available') ?>
15
+ </div>
16
+ <script type="text/javascript">
17
+ //<![CDATA[
18
+ var shippingMethod = new ShippingMethod('co-shipping-method-form', "<?php echo $this->getUrl('checkout/onepage/saveShippingMethod') ?>");
19
+ //]]>
20
+ </script>
21
+ <div id="onepage-checkout-shipping-method-additional-load">
22
+ <?php echo $this->getChildHtml('additional') ?>
23
+ </div>
24
+ <div class="buttons-set" id="shipping-method-buttons-container">
25
+ <p class="back-link"><a href="#" onclick="checkout.back(); return false;"><small>&laquo; </small><?php echo $this->__('Back') ?></a></p>
26
+ <button type="button" class="button" onclick="updateshipping('<?php echo substr(Mage::getUrl('relais/dpdfrancerelais/changeshippingaddress'),0,-1)?>')"><span><span><?php echo $this->__('Continue') ?></span></span></button>
27
+ <span id="shipping-method-please-wait" class="please-wait" style="display:none;">
28
+ <img src="<?php echo $this->getSkinUrl('images/opc-ajax-loader.gif') ?>" alt="<?php echo $this->__('Loading next step...') ?>" title="<?php echo $this->__('Loading next step...') ?>" class="v-middle" /> <?php echo $this->__('Loading next step...') ?>
29
+ </span>
30
+ </div>
31
+ </form>
app/design/frontend/base/default/template/dpdfrrelais/checkout/onepage/shipping_method/available.phtml ADDED
@@ -0,0 +1,112 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
+ <?php if (!($_shippingRateGroups = $this->getShippingRates())): ?>
13
+ <p><?php echo $this->__('Sorry, no quotes are available for this order at this time.') ?></p>
14
+ <?php else: ?>
15
+ <dl class="sp-methods">
16
+ <?php $_sole = count($_shippingRateGroups) == 1; foreach ($_shippingRateGroups as $code => $_rates): ?>
17
+ <dt><?php echo $this->getCarrierName($code) ?></dt>
18
+ <dd>
19
+ <ul>
20
+ <?php $_sole = $_sole && count($_rates) == 1; foreach ($_rates as $_rate): ?>
21
+ <li>
22
+ <?php if ($_rate->getErrorMessage()): ?>
23
+ <ul class="messages"><li class="error-msg"><ul><li><?php echo $_rate->getErrorMessage() ?></li></ul></li></ul>
24
+ <?php else: ?>
25
+ <?php // Ajout DPD France - ajout onClick="radioCheck()" sur les boutons radio pour afficher/masquer les div DPD Relais et Predict ?>
26
+ <input name="shipping_method" type="radio" value="<?php echo $_rate->getCode() ?>" id="s_method_<?php echo $_rate->getCode() ?>"<?php if($_rate->getCode()===$this->getAddressShippingMethod()) echo ' checked="checked"' ?> class="radio" onClick="radioCheck()" />
27
+ <?php // Fin DPD France ?>
28
+ <label for="s_method_<?php echo $_rate->getCode() ?>"><?php echo $_rate->getMethodTitle() ?>
29
+ <?php $_excl = $this->getShippingPrice($_rate->getPrice(), $this->helper('tax')->displayShippingPriceIncludingTax()); ?>
30
+ <?php $_incl = $this->getShippingPrice($_rate->getPrice(), true); ?>
31
+ <?php echo $_excl; ?>
32
+ <?php if ($this->helper('tax')->displayShippingBothPrices() && $_incl != $_excl): ?>
33
+ (<?php echo $this->__('Incl. Tax'); ?> <?php echo $_incl; ?>)
34
+ <?php endif; ?>
35
+ </label>
36
+
37
+ <?php // Ajout DPD France - Div de sélection DPD Relais ?>
38
+ <?php if (($_rate->getCarrier()=='dpdfrrelais') && ($this->getQuote()->getShippingAddress()->getCountry()== 'FR')):?>
39
+ <div id="dpdfrrelais" style="display:none;" >
40
+ <div class="relaypoint_header">
41
+ <label class="relaypoint_label_header"><?php echo Mage::helper ( 'dpdfrrelais' )->__ ( 'Your Pickup delivery by DPD' )?></label><br>
42
+ </div>
43
+ <div class="relaypoint_search">
44
+
45
+ <div class="relaypoint_logo">
46
+ <label class="relaypoint_label_logo"><img src="<?php echo Mage::getBaseUrl(Mage_Core_Model_Store::URL_TYPE_MEDIA).'dpdfrance/front/relais/carrier_logo.jpg' ?>" alt=""/>
47
+ </div>
48
+
49
+ <div class="relaypoint_input">
50
+ <label class="relaypoint_label_find"><?php echo Mage::helper ( 'dpdfrrelais' )->__ ( 'Find DPD Pickup points near this address : ' )?></label><br/>
51
+ <input id="address" name="address" type="text" class="relaypoint-input-address" value="<?php echo $this->htmlEscape($this->getAddress()->getStreet(1))?>"/><br>
52
+ <input id="zipcode" name="zipcode" type="text" class="relaypoint-input-zipcode" value="<?php echo $this->htmlEscape($this->getAddress()->getPostcode())?>"/>
53
+ <input id="city" name="city" type="text" class="relaypoint-input-city" value="<?php echo $this->htmlEscape($this->getAddress()->getCity())?>"/>
54
+ <button class="dpdfrbutton" onclick="fetchPoint('<?php echo substr(Mage::getUrl('relais/dpdfrancerelais/index', array('_secure' => true)),0,-1)?>','suggestion')" type="button" style="height: 20px;padding: 0;width: 36px;">
55
+ <span>OK</span>
56
+ </button>
57
+ <span id="loadingpointswait" style="display:none;">
58
+ <img src="<?php echo Mage::getBaseUrl(Mage_Core_Model_Store::URL_TYPE_MEDIA).'dpdfrance/front/relais/loader.gif' ?>" alt="" class="v-middle" />
59
+ </span>
60
+ </div>
61
+ <div id="suggestion"></div>
62
+ </div>
63
+ </div>
64
+ <?php endif;?>
65
+ <?php // Fin DPD France ?>
66
+
67
+ <?php // Ajout DPD France - Div de présentation DPD Predict ?>
68
+ <?php if (($_rate->getCarrier()=='dpdfrpredict') && ($this->getQuote()->getShippingAddress()->getCountry()== 'FR')):?>
69
+ <div id="dpdfrpredict" style="display:none;" >
70
+ <div class="predict_header">
71
+ <label class="predict_label_header"><?php echo Mage::helper ( 'dpdfrpredict' )->__ ( 'Your Predict delivery by DPD' )?></label><br>
72
+ </div>
73
+ <div class="predict_search">
74
+ <div class="predict_logo">
75
+ <label class="predict_label_logo"><img src="<?php echo Mage::getBaseUrl(Mage_Core_Model_Store::URL_TYPE_MEDIA).'dpdfrance/front/predict/dpd_predict_logo.png' ?>" alt=""/>
76
+ </div>
77
+ <div class="copy">
78
+ <p><h2><?php echo Mage::helper ( 'dpdfrpredict' )->__ ( 'Predict offers you the following benefits' )?></h2></p>
79
+ <ul>
80
+ <li><b><?php echo Mage::helper ( 'dpdfrpredict' )->__ ( 'A parcel delivery in a 3-hour time window (choice is made by SMS or through our website)' )?></b></li>
81
+ <li><b><?php echo Mage::helper ( 'dpdfrpredict' )->__ ( 'A complete and detailed tracking of your delivery' )?></b></li>
82
+ <li><b><?php echo Mage::helper ( 'dpdfrpredict' )->__ ( 'In case of absence, you can schedule a new delivery when and where you it suits you best' )?></b></li>
83
+ </ul>
84
+ <p><h2><?php echo Mage::helper ( 'dpdfrpredict' )->__ ( 'How does it work?' )?></h2></p>
85
+ <ul>
86
+ <li><?php echo Mage::helper ( 'dpdfrpredict' )->__ ( 'Once your order is ready for shipment, you will receive an SMS proposing various days and time windows for your delivery.' )?></li>
87
+ <li><?php echo Mage::helper ( 'dpdfrpredict' )->__ ( 'You choose the moment which suits you best for the delivery by replying to the SMS (no extra cost) or through our website' )?> <a href="http://www.dpd.fr/destinataires">dpd.fr</a></li>
88
+ <li><?php echo Mage::helper ( 'dpdfrpredict' )->__ ( 'On the day of delivery, a text message will remind you the selected time window.' )?></li>
89
+ </ul>
90
+ </div>
91
+ <br/>
92
+ <div id="div_dpdfrance_dpd_logo"></div>
93
+ </div>
94
+ <div id="dpdfrance_predict_error" class="warnmsg" style="display:none;">
95
+ <?php echo Mage::helper ( 'dpdfrpredict' )->__ ( 'It seems that the GSM number you provided is incorrect. Please provide a french GSM number, starting with 06 or 07, on 10 consecutive digits.')?>
96
+ </div>
97
+ <div id="div_dpdfrance_predict_gsm">
98
+ <?php echo Mage::helper ( 'dpdfrpredict' )->__ ( 'To get all the advantages of DPD\'s Predict service, please provide a french mobile phone number here ')?>
99
+ <input id="gsm_dest" name="gsm_dest" type="text" class="predict-input-text" value="<?php echo $this->htmlEscape($this->getQuote()->getBillingAddress()->getTelephone())?>"/>
100
+ </div>
101
+ </div>
102
+ <?php endif;?>
103
+ <?php // Fin DPD France ?>
104
+
105
+ <?php endif ?>
106
+ </li>
107
+ <?php endforeach; ?>
108
+ </ul>
109
+ </dd>
110
+ <?php endforeach; ?>
111
+ </dl>
112
+ <?php endif; ?>
app/etc/modules/DPDFrance_Classic.xml ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <config>
3
+ <modules>
4
+ <DPDFrance_Classic>
5
+ <active>true</active>
6
+ <codePool>community</codePool>
7
+ </DPDFrance_Classic>
8
+ </modules>
9
+ </config>
app/etc/modules/DPDFrance_Export.xml ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <config>
3
+ <modules>
4
+ <DPDFrance_Export>
5
+ <active>true</active>
6
+ <codePool>community</codePool>
7
+ </DPDFrance_Export>
8
+ </modules>
9
+ </config>
app/etc/modules/DPDFrance_Predict.xml ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <config>
3
+ <modules>
4
+ <DPDFrance_Predict>
5
+ <active>true</active>
6
+ <codePool>community</codePool>
7
+ </DPDFrance_Predict>
8
+ </modules>
9
+ </config>
app/etc/modules/DPDFrance_Relais.xml ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <config>
3
+ <modules>
4
+ <DPDFrance_Relais>
5
+ <active>true</active>
6
+ <codePool>community</codePool>
7
+ </DPDFrance_Relais>
8
+ </modules>
9
+ </config>
app/locale/en_US/DPDFrance_Classic.csv ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ "Enabled","Enabled"
2
+ "Title","Title"
3
+ "Subtitle","Subtitle"
4
+ "Your DPD Depot #","Your DPD Depot #"
5
+ "Your DPD CLASSIC contract #","Your DPD CLASSIC contract #"
6
+ "Shipping rates configuration","Shipping rates configuration"
7
+ "Display when unavailable","Display when unavailable"
8
+ "Yes","Yes"
9
+ "No","No"
10
+ "Displayed Error Message","Displayed Error Message"
11
+ "Sort Order","Sort Order"
app/locale/en_US/DPDFrance_Export.csv ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
1
+ "Orders management","Orders management"
2
+ "DPD News","DPD News"
3
+ "show","show"
4
+ "hide","hide"
5
+ "Export to DPD Station - Integrated insurance","Export to DPD Station - Integrated insurance"
6
+ "Export to DPD Station - Ad Valorem insurance","Export to DPD Station - Ad Valorem insurance"
7
+ "Update sent orders","Update sent orders"
8
+ "DPD Pickup point","DPD Pickup point"
9
+ "Track the package","Track the package"
app/locale/en_US/DPDFrance_Predict.csv ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ "Enabled","Enabled"
2
+ "Title","Title"
3
+ "Subtitle","Subtitle"
4
+ "Your DPD Depot #","Your DPD Depot #"
5
+ "Your Predict by DPD contract #","Your Predict by DPD contract #"
6
+ "Shipping rates configuration","Shipping rates configuration"
7
+ "Display when unavailable","Display when unavailable"
8
+ "Yes","Yes"
9
+ "No","No"
10
+ "Displayed Error Message","Displayed Error Message"
11
+ "Sort Order","Sort Order"
12
+
13
+ "Your Predict delivery by DPD","Your Predict delivery by DPD"
14
+ "Predict offers you the following benefits","Predict offers you the following benefits"
15
+ "A parcel delivery in a 3-hour time window (choice is made by SMS or through our website)","A parcel delivery in a 3-hour time window (choice is made by SMS or through our website)"
16
+ "A complete and detailed tracking of your delivery","A complete and detailed tracking of your delivery"
17
+ "In case of absence, you can schedule a new delivery when and where you it suits you best","In case of absence, you can schedule a new delivery when and where you it suits you best"
18
+ "How does it work?","How does it work?"
19
+ "Once your order is ready for shipment, you will receive an SMS proposing various days and time windows for your delivery.","Once your order is ready for shipment, you will receive an SMS proposing various days and time windows for your delivery."
20
+ "You choose the moment which suits you best for the delivery by replying to the SMS (no extra cost) or through our website","You choose the moment which suits you best for the delivery by replying to the SMS (no extra cost) or through our website"
21
+ "On the day of delivery, a text message will remind you the selected time window.","On the day of delivery, a text message will remind you the selected time window."
22
+ "Get more info in this video ","Get more info in this video "
23
+ "To get all the advantages of DPD's Predict service, please provide a french mobile phone number here ","To get all the advantages of DPD's Predict service, please provide a french mobile phone number here "
24
+ "It seems that the GSM number you provided is incorrect. Please provide a french GSM number, starting with 06 or 07, on 10 consecutive digits.","It seems that the GSM number you provided is incorrect. Please provide a french GSM number, starting with 06 or 07, on 10 consecutive digits."
25
+
app/locale/en_US/DPDFrance_Relais.csv ADDED
@@ -0,0 +1,55 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ "Enabled","Enabled"
2
+ "Title","Title"
3
+ "Subtitle","Subtitle"
4
+ "URL MyPudo","DPD Relais Webservice URL"
5
+ "ID trader","ID trader"
6
+ "Security Key","Security Key"
7
+ "Your DPD Depot #","Your DPD Depot #"
8
+ "Your DPD Relais contract #","Your DPD Relais contract #"
9
+ "Shipping rates configuration","Shipping rates configuration"
10
+ "Display when unavailable","Display when unavailable"
11
+ "Yes","Yes"
12
+ "No","No"
13
+ "Displayed Error Message","Displayed Error Message"
14
+ "Sort Order","Sort Order"
15
+
16
+ "Find DPD Pickup points near this address : ","Find DPD Pickup points near this address : "
17
+ "Your Pickup delivery by DPD","Your Pickup delivery by DPD"
18
+ "More details","More details"
19
+ "You have to choose an address for your shipping!","You have to choose an address for your shipping!"
20
+ "Your shopping cart is too heavy for being shipped in a Pickup point","Your shopping cart is too heavy for being shipped in a Pickup point"
21
+ "An error ocurred while fetching the DPD Pickup points. Please try again","An error ocurred while fetching the DPD Pickup points. Please try again"
22
+ "There are no DPD Pickup points for the selected adress. Please modify it.","There are no DPD Pickup points for the selected adress. Please modify it."
23
+ "The field Postal Code is mandatory!","The field Postal Code is mandatory!"
24
+ "The field City is mandatory!","The field City is mandatory!"
25
+
26
+ "Your DPD Pickup point","Your DPD Pickup point"
27
+ "Method Name","Method Name"
28
+ "Distance in KM","Distance in KM"
29
+ "DPD Pickup ID#","DPD Pickup ID#"
30
+ "Opening hours","Opening hours"
31
+ "More info","More info"
32
+ "Closing period","Closing period"
33
+ "Opening hours","Opening hours"
34
+ "info","info"
35
+ "Monday","Monday"
36
+ "Tuesday","Tuesday"
37
+ "Wednesday","Wednesday"
38
+ "Thursday","Thursday"
39
+ "Friday","Friday"
40
+ "Saturday","Saturday"
41
+ "Sunday","Sunday"
42
+ "Closed","Closed"
43
+ "Attention, this DPD Pickup point will be unavailable from","Attention, this DPD Pickup point will be unavailable from"
44
+ "Jan","Jan"
45
+ "Feb","Feb"
46
+ "Mar","Mar"
47
+ "Apr","Apr"
48
+ "May","May"
49
+ "Jun","Jun"
50
+ "Jul","Jul"
51
+ "Aug","Aug"
52
+ "Sep","Sep"
53
+ "Oct","Oct"
54
+ "Nov","Nov"
55
+ "Dec","Dec"
app/locale/fr_FR/DPDFrance_Classic.csv ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ "Enabled","Activé"
2
+ "Title","Titre"
3
+ "Subtitle","Sous-titre"
4
+ "Your DPD Depot #","Votre n° d'agence DPD"
5
+ "Your DPD CLASSIC contract #","Votre n° de contrat DPD CLASSIC"
6
+ "Shipping rates configuration","Gestion des frais de port"
7
+ "Display when unavailable","Afficher quand non disponible"
8
+ "Yes","Oui"
9
+ "No","Non"
10
+ "Displayed Error Message","Afficher le message d'erreur"
11
+ "Sort Order","Ordre de tri"
app/locale/fr_FR/DPDFrance_Export.csv ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
1
+ "Orders management","Gestion des expéditions"
2
+ "DPD News","Informations DPD"
3
+ "show","afficher"
4
+ "hide","masquer"
5
+ "Export to DPD Station - Integrated insurance","Exporter les commandes sélectionnées - Assurance intégrée"
6
+ "Export to DPD Station - Ad Valorem insurance","Exporter les commandes sélectionnées - Assurance Ad Valorem"
7
+ "Update sent orders","Traiter les commandes expédiées"
8
+ "DPD Pickup point","Relais Pickup"
9
+ "Track the package","Suivre la commande"
app/locale/fr_FR/DPDFrance_Predict.csv ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ "Enabled","Activé"
2
+ "Title","Titre"
3
+ "Subtitle","Sous-titre"
4
+ "Your DPD Depot #","Votre n° d'agence DPD"
5
+ "Your Predict by DPD contract #","Votre n° de contrat Predict par DPD"
6
+ "Shipping rates configuration","Gestion des frais de port"
7
+ "Display when unavailable","Afficher quand non disponible"
8
+ "Yes","Oui"
9
+ "No","Non"
10
+ "Displayed Error Message","Afficher le message d'erreur"
11
+ "Sort Order","Ordre de tri"
12
+
13
+ "Your Predict delivery by DPD","Livraison à domicile Predict sur rendez-vous"
14
+ "Predict offers you the following benefits","Avec Predict, bénéficiez des avantages suivants"
15
+ "A parcel delivery in a 3-hour time window (choice is made by SMS or through our website)","Livraison de votre colis dans un créneau de 3h (choix par SMS ou par notre portail web)"
16
+ "A complete and detailed tracking of your delivery","Suivi complet et détaillé de votre livraison"
17
+ "In case of absence, you can schedule a new delivery when and where you it suits you best","En cas d’absence, vous reprogrammez une livraison où et quand vous le souhaitez"
18
+ "How does it work?","Comment ça fonctionne ?"
19
+ "Once your order is ready for shipment, you will receive an SMS proposing various days and time windows for your delivery.","Une fois votre commande préparée, nous vous envoyons un SMS avec plusieurs choix de dates et créneaux horaires de livraison"
20
+ "You choose the moment which suits you best for the delivery by replying to the SMS (no extra cost) or through our website","Vous sélectionnez la date et le créneau de 3h qui vous conviennent le mieux en répondant directement par SMS (prix d’un SMS standard) ou vous connectant sur l’Espace Destinataire disponible sur"
21
+ "On the day of delivery, a text message will remind you the selected time window.","Le jour de la livraison, vous recevez un SMS vous rappelant le créneau horaire"
22
+ "Get more info in this video ","Plus d'infos en vidéo "
23
+ "To get all the advantages of DPD's Predict service, please provide a french mobile phone number here ","Bénéficiez dès maintenant des avantages de la livraison Predict en renseignant votre n° de mobile ici "
24
+ "It seems that the GSM number you provided is incorrect. Please provide a french GSM number, starting with 06 or 07, on 10 consecutive digits.","Le numéro de mobile renseigné semble incorrect. Merci de préciser un numéro de mobile français, commençant par 06 ou 07, sur 10 chiffres consécutifs."
app/locale/fr_FR/DPDFrance_Relais.csv ADDED
@@ -0,0 +1,54 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ "Enabled","Activé"
2
+ "Title","Titre"
3
+ "Subtitle","Sous-titre"
4
+ "URL MyPudo","URL Webservice DPD Relais"
5
+ "ID trader","ID Marchand"
6
+ "Security Key","Clé de sécurité"
7
+ "Your DPD Depot #","Votre n° d'agence DPD"
8
+ "Your DPD Relais contract #","Votre n° de contrat DPD Relais"
9
+ "Shipping rates configuration","Gestion des frais de port"
10
+ "Display when unavailable","Afficher quand non disponible"
11
+ "Yes","Oui"
12
+ "No","Non"
13
+ "Displayed Error Message","Afficher le message d'erreur"
14
+ "Sort Order","Ordre de tri"
15
+
16
+ "Find DPD Pickup points near this address : ","Recherchez les relais Pickup autour de l'adresse suivante : "
17
+ "Your Pickup delivery by DPD","Livraison en relais Pickup par DPD"
18
+ "More details","Plus de détails"
19
+ "You have to choose an address for your shipping!","Vous devez choisir une adresse de livraison!"
20
+ "Your shopping cart is too heavy for being shipped in a Pickup point","Le poids de votre panier n'est pas compatible avec une livraison en relais Pickup"
21
+ "An error ocurred while fetching the DPD Pickup points. Please try again","DPD Relais est temporairement indisponible, merci de réessayer dans quelques instants."
22
+ "There are no DPD Pickup points for the selected adress. Please modify it.","Il n'y a pas de relais Pickup autour de l'adresse saisie. Merci de modifier votre adresse."
23
+ "The field Postal Code is mandatory!","Le champ Code Postal est obligatoire!"
24
+ "The field City is mandatory!","Le champ Ville est obligatoire!"
25
+
26
+ "Your DPD Pickup point","Votre relais Pickup"
27
+ "Method Name","Méthode de livraison"
28
+ "Distance in KM","Distance en km"
29
+ "DPD Pickup ID#","Identifiant relais"
30
+ "Opening hours","Horaires d'ouverture"
31
+ "More info","Informations"
32
+ "Closing period","Relais fermé le"
33
+ "info","Repère"
34
+ "Monday","Lundi"
35
+ "Tuesday","Mardi"
36
+ "Wednesday","Mercredi"
37
+ "Thursday","Jeudi"
38
+ "Friday","Vendredi"
39
+ "Saturday","Samedi"
40
+ "Sunday","Dimanche"
41
+ "Closed","Fermé"
42
+ "Attention, this DPD Pickup point will be unavailable from","Attention, ce relais Pickup ne sera pas disponible du"
43
+ "Jan","Janv"
44
+ "Feb","Fév"
45
+ "Mar","Mars"
46
+ "Apr","Avr"
47
+ "May","Mai"
48
+ "Jun","Juin"
49
+ "Jul","Juillet"
50
+ "Aug","Août"
51
+ "Sep","Sept"
52
+ "Oct","Oct"
53
+ "Nov","Nov"
54
+ "Dec","Déc"
media/dpdfrance/admin/logo.png ADDED
Binary file
media/dpdfrance/admin/rss_icon.png ADDED
Binary file
media/dpdfrance/admin/service_dom.png ADDED
Binary file
media/dpdfrance/admin/service_predict.png ADDED
Binary file
media/dpdfrance/admin/service_relais.png ADDED
Binary file
media/dpdfrance/admin/service_world.png ADDED
Binary file
media/dpdfrance/fonts/PlutoSansDPDExtraLight-Web.ttf ADDED
Binary file
media/dpdfrance/fonts/PlutoSansDPDLight-Web.ttf ADDED
Binary file
media/dpdfrance/fonts/PlutoSansDPDRegular-Web.ttf ADDED
Binary file
media/dpdfrance/fonts/PlutoSansDPDThin-Web.ttf ADDED
Binary file
media/dpdfrance/front/predict/carrier_logo.jpg ADDED
Binary file
media/dpdfrance/front/predict/carrier_logo_alt.jpg ADDED
Binary file
media/dpdfrance/front/predict/dpd_logo.png ADDED
Binary file
media/dpdfrance/front/predict/dpd_predict_logo.png ADDED
Binary file
media/dpdfrance/front/predict/predict_receive.jpg ADDED
Binary file
media/dpdfrance/front/relais/DPD_Logo.png ADDED
Binary file
media/dpdfrance/front/relais/carrier_logo.jpg ADDED
Binary file
media/dpdfrance/front/relais/carrier_logo_alt.jpg ADDED
Binary file
media/dpdfrance/front/relais/horaires.png ADDED
Binary file
media/dpdfrance/front/relais/info.png ADDED
Binary file
media/dpdfrance/front/relais/loader.gif ADDED
Binary file
media/dpdfrance/front/relais/logo-max-png.png ADDED
Binary file
media/dpdfrance/front/relais/pointrelais.png ADDED
Binary file
media/dpdfrance/front/relais/warning.png ADDED
Binary file
media/dpdfrance/readme_dpdfrance_magento.pdf ADDED
Binary file
package.xml ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <package>
3
+ <name>DPDFrance_Shipping</name>
4
+ <version>5.1.0</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>
8
+ <extends/>
9
+ <summary>DPD shipping module for Magento - France vendors only</summary>
10
+ <description>Ce module permet d'ajouter les offres de livraison DPD Relais, Predict, Classic et Intercontinental sur votre site e-commerce.&#xD;
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 S.A.S.</name><user>DSI</user><email>ensavoirplus.ecommerce@dpd.fr</email></author></authors>
14
+ <date>2015-04-02</date>
15
+ <time>16:47:49</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="fe276023205d3b214203f8615063ddc0"/><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="c479704a758a12d871d1842df62e6870"/></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="522314ea5bd891c531703af4bd9ff243"/><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="DPDFranceRelaisController.php" hash="5caf50c1b2bd3bdc4744690c03a9addf"/></dir><dir name="etc"><file name="config.xml" hash="d2c894bee7705e7c1179bc42d0381598"/><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="2c5c71c2ab45fb16395622a73c6f9995"/></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="038067414584c5fb243e75d844e9bf03"/></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>
skin/frontend/base/default/css/dpdfrance/dpdfrpredict.css ADDED
@@ -0,0 +1,224 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
+
11
+ @font-face {
12
+ font-family: DPDPlutoSansExtraLight;
13
+ src: url(../../../../../../media/dpdfrance/fonts/PlutoSansDPDExtraLight-Web.ttf);
14
+ }
15
+
16
+ @font-face {
17
+ font-family: DPDPlutoSansLight;
18
+ src: url(../../../../../../media/dpdfrance/fonts/PlutoSansDPDLight-Web.ttf);
19
+ }
20
+
21
+ @font-face {
22
+ font-family: DPDPlutoSansRegular;
23
+ src: url(../../../../../../media/dpdfrance/fonts/PlutoSansDPDRegular-Web.ttf);
24
+ }
25
+
26
+ .warnmsg
27
+ {
28
+ background-color:#fff !important;
29
+ box-sizing:border-box !important;
30
+ border-style: solid;
31
+ border-color: #a90034;
32
+ border-width: 2px;
33
+ color:#a90034!important;
34
+ font-family:DPDPlutoSansRegular !important;
35
+ font-size:13px!important;
36
+ font-weight:bold;
37
+ margin:15px 0!important;
38
+ padding:15px 15px 15px 50px !important;
39
+ position:relative!important;
40
+ width:100%!important;
41
+ -webkit-transform-style: preserve-3d;
42
+ -moz-transform-style: preserve-3d;
43
+ transform-style: preserve-3d;
44
+ }
45
+
46
+ .warnmsg::before
47
+ {
48
+ -moz-osx-font-smoothing:grayscale;
49
+ -webkit-font-smoothing:antialiased;
50
+ box-sizing:border-box;
51
+ color:#a90034;
52
+ content:"!";
53
+ font-family:DPDPlutoSansRegular;
54
+ font-size:42px;
55
+ font-style:normal;
56
+ font-weight:400;
57
+ height:25px;
58
+ left:20px;
59
+ line-height:1;
60
+ margin:auto;
61
+ position:absolute;
62
+ width:25px;
63
+ top: 39%;
64
+ -webkit-transform: translateY(-50%);
65
+ -ms-transform: translateY(-50%);
66
+ transform: translateY(-50%);
67
+ }
68
+ .predict_header {
69
+ width: 100%;
70
+ height: 25px;
71
+ line-height: 24px;
72
+ margin: 0;
73
+ padding: 0;
74
+ background-color: #DC0032;
75
+ }
76
+
77
+ label.predict_label_header {
78
+ height: 23px;
79
+ padding: 0 0 0 15px !important;
80
+ font-size: 13px;
81
+ font-family: DPDPlutoSansLight;
82
+ color: #fff !important;
83
+ background-color: #dc0032 !important;
84
+ text-align: left;
85
+ }
86
+
87
+ #dpdfrpredict {
88
+ background-color: #fff;
89
+ font-size: 12px;
90
+ font-family: DPDPlutoSansLight;
91
+ padding: 0;
92
+ margin: 0;
93
+ }
94
+
95
+ .predict_logo {
96
+ width: 100%;
97
+ height: 64px;
98
+ padding: 0;
99
+ text-align:center;
100
+ }
101
+ label.predict_label_logo {
102
+ background-color: transparent !important;
103
+ padding: 10px 0 0 0 !important;
104
+ margin-left: 120px !important;
105
+ }
106
+ #div_dpdfrance_predict_gsm {
107
+ background-color: #cac4be;
108
+ color: #424143;
109
+ display: block;
110
+ font-size: 13px;
111
+ font-family: DPDPlutoSansRegular;
112
+ padding: 15px;
113
+ }
114
+
115
+ #gsm_dest {
116
+ width: 120px;
117
+ font-size: 12px;
118
+ font-weight: 400;
119
+ height: 25px;
120
+ border: none;
121
+ margin-left: 15px;
122
+ font-family: DPDPlutoSansLight;
123
+ }
124
+
125
+ #div_dpdfrance_predict_gsm form {
126
+ margin: 0;
127
+ display: inline-block;
128
+ }
129
+
130
+ div.dpdfrance_predict_error {
131
+ color: #fff;
132
+ background-color: #A90034;
133
+ margin: 0;
134
+ padding: 15px;
135
+ font-size: 13px;
136
+ font-family: DPDPlutoSansRegular;
137
+ }
138
+
139
+ div.predict_search {
140
+ background: url(../../../../../../media/dpdfrance/front/predict/predict_receive.jpg) no-repeat;
141
+ background-size: cover;
142
+ font-size: 12px;
143
+ color: #424143;
144
+ height: auto;
145
+ margin: 0;
146
+ }
147
+
148
+ div.copy {
149
+ min-height: 301px;
150
+ padding-left: 50%;
151
+ padding-right: 10px;
152
+ height: auto;
153
+ font-family: DPDPlutoSansLight;
154
+ margin-bottom: 0;
155
+ padding-bottom: 0;
156
+ margin: 0;
157
+ }
158
+
159
+ div.copy p {
160
+ margin: 10px;
161
+ }
162
+
163
+ div.copy h2 {
164
+ padding: 0;
165
+ font-family: DPDPlutoSansRegular;
166
+ margin: 10px;
167
+ font-size: 16px;
168
+ text-transform: none;
169
+ color: #424143;
170
+ background: transparent;
171
+ }
172
+
173
+ .copy ul li
174
+ {
175
+ list-style-type:none;
176
+ padding-bottom: 5px;
177
+ }
178
+
179
+ .copy ul li:before {
180
+ content: '•';
181
+ margin-right: 8px;
182
+ color: #dc0042;
183
+ }
184
+
185
+ a.dpdfrance_more {
186
+ margin-left: 10px;
187
+ color: #424143;
188
+ }
189
+
190
+ a.dpdfrance_more:hover {
191
+ color: #DC0042;
192
+ }
193
+
194
+ input.predict-input-text {
195
+ padding-left: 5px;
196
+ }
197
+
198
+ #dpdfrance_predict_error {
199
+ color: #fff;
200
+ background-color: #A90034;
201
+ margin: 0;
202
+ padding: 15px;
203
+ font-size: 13px;
204
+ font-family: DPDPlutoSansRegular;
205
+ }
206
+ #div_dpdfrance_dpd_logo
207
+ {
208
+ height: 45px;
209
+ margin-top: -30px;
210
+ width: 99%;
211
+ background:url(../../../../../../media/dpdfrance/front/predict/dpd_logo.png) no-repeat right;
212
+ }
213
+ @media only screen and (max-width: 750px) {
214
+ div.predict_search
215
+ {
216
+ background:#fff;
217
+ }
218
+
219
+ div.copy
220
+ {
221
+ padding-left:10px;
222
+ padding-right:10px;
223
+ }
224
+ }
skin/frontend/base/default/css/dpdfrance/dpdfrrelais.css ADDED
@@ -0,0 +1,799 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
+
11
+ @font-face {
12
+ font-family: DPDPlutoSansExtraLight;
13
+ src: url(../../../../../../media/dpdfrance/fonts/PlutoSansDPDExtraLight-Web.ttf);
14
+ }
15
+
16
+ @font-face {
17
+ font-family: DPDPlutoSansLight;
18
+ src: url(../../../../../../media/dpdfrance/fonts/PlutoSansDPDLight-Web.ttf);
19
+ }
20
+
21
+ @font-face {
22
+ font-family: DPDPlutoSansRegular;
23
+ src: url(../../../../../../media/dpdfrance/fonts/PlutoSansDPDRegular-Web.ttf);
24
+ }
25
+
26
+ .warnmsg
27
+ {
28
+ background-color:#fff !important;
29
+ box-sizing:border-box !important;
30
+ border-style: solid;
31
+ border-color: #a90034;
32
+ border-width: 2px;
33
+ color:#a90034!important;
34
+ font-family:DPDPlutoSansRegular !important;
35
+ font-size:13px!important;
36
+ font-weight:bold;
37
+ margin:15px 0!important;
38
+ padding:15px 15px 15px 50px !important;
39
+ position:relative!important;
40
+ width:100%!important;
41
+ -webkit-transform-style: preserve-3d;
42
+ -moz-transform-style: preserve-3d;
43
+ transform-style: preserve-3d;
44
+ }
45
+ li.warnmsg ul li {
46
+ padding: 0;
47
+ background-color: #fff;
48
+ text-transform: none;
49
+ }
50
+ .warnmsg::before
51
+ {
52
+ -moz-osx-font-smoothing:grayscale;
53
+ -webkit-font-smoothing:antialiased;
54
+ box-sizing:border-box;
55
+ color:#a90034;
56
+ content:"!";
57
+ font-family:DPDPlutoSansRegular;
58
+ font-size:42px;
59
+ font-style:normal;
60
+ font-weight:400;
61
+ height:25px;
62
+ left:20px;
63
+ line-height:1;
64
+ margin:auto;
65
+ position:absolute;
66
+ width:25px;
67
+ top: 39%;
68
+ -webkit-transform: translateY(-50%);
69
+ -ms-transform: translateY(-50%);
70
+ transform: translateY(-50%);
71
+ }
72
+
73
+ .dialog {
74
+ position: absolute
75
+ }
76
+ .alphacube_content {
77
+ color: #424143;
78
+ font-family: 'DPDPlutoSansLight' !important;
79
+ font-size: 12px;
80
+ background: #424143;
81
+ box-shadow: 0px 0px 30px #444;
82
+ -moz-box-shadow: 0px 0px 30px #444;
83
+ -webkit-box-shadow: 0px 0px 30px #444;
84
+ background-color: transparent;
85
+ }
86
+
87
+ .alphacube_buttons {
88
+ font-size: 12px;
89
+ background-color: transparent;
90
+ height: 32px;
91
+ width: 32px;
92
+ border-style: none;
93
+ background: no-repeat;
94
+ cursor: pointer;
95
+ display: block;
96
+ position: fixed;
97
+ top: 5%;
98
+ left: 80.5%;
99
+ z-index: 1111;
100
+ }
101
+ .alphacube_buttons input {
102
+ width: 20%;
103
+ text-align: right;
104
+ border: none;
105
+ background-color: #fff;
106
+ color: #fff;
107
+ font-weight: bold;
108
+ z-index: 9999;
109
+ }
110
+ .overlay_alphacube {
111
+ background-color: #000;
112
+ -moz-opacity: 0.7;
113
+ opacity: 0.7;
114
+ }
115
+ .one-page-checkout .active .box-no-padding {
116
+ padding: 15px 20px
117
+ }
118
+ .one-page-checkout .active .box-no-padding dt {
119
+ clear: both
120
+ }
121
+ #checkout-shipping-method-load dd {
122
+ padding: 0 0 10px
123
+ }
124
+ button.dpdfrbutton {
125
+ background-color: #424143;
126
+ color: white;
127
+ border-style: none;
128
+ height: 25px !important;
129
+ width: 28px !important;
130
+ font-family: DPDPlutoSansRegular;
131
+ font-size: 12px;
132
+ cursor: pointer;
133
+ }
134
+ #dpdfrrelais #suggestion {
135
+ overflow: hidden;
136
+ padding: 20px 0 0 20px;
137
+ clear: both;
138
+ }
139
+ #dpdfrrelais #suggestion input {
140
+ vertical-align: top;
141
+ margin-top: 4px;
142
+ float: left;
143
+ clear: both;
144
+ }
145
+ #dpdfrrelais #suggestion div .s1 {
146
+ display: inline-block;
147
+ width: 55%;
148
+ padding: 0 10px 0 0;
149
+ float: left;
150
+ }
151
+ #dpdfrrelais #suggestion div .s2 {
152
+ display: inline-block;
153
+ width: 50px;
154
+ float: left;
155
+ }
156
+ #dpdfrrelais #suggestion div a {
157
+ float: left
158
+ }
159
+ #dpdfrrelais #suggestion span.s2 {
160
+ font-size: 12px;
161
+ text-transform: lowercase;
162
+ height: 18px;
163
+ width: 50px;
164
+ line-height: 60px;
165
+ margin: 0;
166
+ height: 59px;
167
+ padding: 0;
168
+ background-color: #fff;
169
+ color: #424143;
170
+ }
171
+ #dpdfrrelais #suggestion div a {
172
+ line-height: 40px;
173
+ font-variant: small-caps;
174
+ font-style: normal;
175
+ background-color: #fff;
176
+ height: 60px;
177
+ width: 90px;
178
+ margin: 0;
179
+ padding: 0;
180
+ }
181
+ #dpdfrrelais #suggestion p {
182
+ font-size: 12px;
183
+ font-variant: normal;
184
+ text-transform: none;
185
+ }
186
+ #dpdfrrelais #suggestion div {
187
+ float: left;
188
+ background-color: #fff;
189
+ margin: 0;
190
+ width: 100%;
191
+ height: 60px;
192
+ padding: 0;
193
+ border-style: solid;
194
+ border-bottom-width: 1px;
195
+ border-top-width: 0;
196
+ border-right-width: 0;
197
+ border-left-width: 0;
198
+ border-color: #424143;
199
+ }
200
+ #dpdfrrelais #suggestion div:nth-child(9)
201
+ {
202
+ border:none;
203
+ }
204
+ #dpdfrrelais #suggestion {
205
+ font-family: 'DPDPlutoSansLight', sans-serif;
206
+ text-transform: uppercase;
207
+ font-variant: normal;
208
+ font-size: 10px;
209
+ border-style: none;
210
+ border-width: 1px;
211
+ padding: 0;
212
+ margin: 0;
213
+ width: 100;
214
+ }
215
+ #dpdfrrelais #suggestion span.s1 {
216
+ font-variant: normal;
217
+ text-transform: uppercase;
218
+ font-style: normal;
219
+ font-weight: normal;
220
+ font-size: 12px;
221
+ line-height: 16px;
222
+ width: 48%;
223
+ height: 50px;
224
+ padding-top: 5px;
225
+ padding-bottom: 5px;
226
+ padding-left: 5px;
227
+ background-color: #fff;
228
+ color: #424143;
229
+ }
230
+ #dpdfrrelais #suggestion span.dpdfrrelais_logo img {
231
+ float: left;
232
+ width: 48px;
233
+ height: 48px;
234
+ padding: 0;
235
+ margin-top: 6px;
236
+ margin-left: 8px;
237
+ margin-right: 4px;
238
+ }
239
+ #dpdfrrelais #suggestion input.dpdfrrelais_radio {
240
+ cursor: pointer;
241
+ height: 14px;
242
+ margin: 0;
243
+ padding: 0;
244
+ margin-left: 10px;
245
+ margin-right: 10px;
246
+ margin-top: -10px;
247
+ *margin-top: 22px; /* IE 7 fix */
248
+ margin-top: -36px\0; /* IE 8 fix */
249
+ float: right;
250
+ }
251
+ label.dpdfrrelais_button_ici {
252
+ min-width: 35px !important;
253
+ padding: 0 !important;
254
+ background-color: white !important;
255
+ }
256
+ input[name="relay-point"]:not(old) {
257
+ width: 0px;
258
+ margin: 0;
259
+ padding: 0;
260
+ font-size: 1em;
261
+ opacity: 0;
262
+ }
263
+ /* Bouton */
264
+ input[name="relay-point"]:not(old) + label {
265
+ display: inline-block;
266
+ margin-left: 0px;
267
+ line-height: 1.5em;
268
+ margin-top: -15px;
269
+ }
270
+ input[name="relay-point"]:not(old) + label > span {
271
+ display: inline-block;
272
+ width: 35px;
273
+ height: 25px;
274
+ margin: 0.25em 0.25em 0.25em 0em;
275
+ border: none;
276
+ background: #e6e7e7;
277
+ vertical-align: bottom;
278
+ cursor: pointer;
279
+ }
280
+ /* Bouton gris normal */
281
+ input[name="relay-point"]:not(old):checked + label > span {
282
+ background: #e6e7e7;
283
+ }
284
+ /* Texte ICI blanc sur bouton checked*/
285
+ input[name="relay-point"]:not(old):checked + label > span:before {
286
+ content:'ICI';
287
+ display:block;
288
+ width:35px;
289
+ color:#fff;
290
+ font-size:14px;
291
+ line-height:25px;
292
+ text-align:center;
293
+ }
294
+ /* Overlay rouge sur bouton checked */
295
+ input[name="relay-point"]:not(old):checked + label > span > span {
296
+ display:block;
297
+ width:35px;
298
+ height:25px;
299
+ margin-top:-25px;
300
+ margin-right:0;
301
+ background-color:#DC0032;
302
+ }
303
+ /* Texte ICI gris sur bouton normal */
304
+ input[name="relay-point"]:not(old) + label > span:before {
305
+ content:'ICI';
306
+ display:block;
307
+ width:35px;
308
+ color:#424143;
309
+ font-size:14px;
310
+ line-height:25px;
311
+ text-align:center;
312
+ }
313
+ /* Label d'origine masqué */
314
+ div label b {
315
+ display: none
316
+ }
317
+ #dpdfrrelais #suggestion span.s3 a {
318
+ line-height: 60px;
319
+ height: 59px;
320
+ width: 19%;
321
+ margin: 0;
322
+ background-color: #fff;
323
+ color: #424143;
324
+ text-align: center !important;
325
+ text-decoration: underline;
326
+ text-transform: none;
327
+ font-size: 12px;
328
+ font-variant: normal;
329
+ }
330
+ #dpdfrrelais #suggestion span.s3 a:hover{
331
+ color: #dc0032;
332
+ text-decoration: underline;
333
+ }
334
+ div.relaypoint_header {
335
+ width: 100%;
336
+ height: 25px;
337
+ line-height: 24px;
338
+ margin: 0;
339
+ padding: 0;
340
+ background-color: #DC0032;
341
+ }
342
+ div.relaypoint_header label {
343
+ color: #fff;
344
+ font-weight: normal;
345
+ font-size: 13px;
346
+ font-family: DPDPlutoSansRegular;
347
+ }
348
+ label.relaypoint_label_header {
349
+ height: 23px;
350
+ padding: 0 0 0 15px !important;
351
+ font-size: 13px;
352
+ font-family: DPDPlutoSansLight;
353
+ color: #fff !important;
354
+ background-color: #dc0032 !important;
355
+ text-align: left ;
356
+ }
357
+ div.relaypoint_search {
358
+ margin-bottom: 5px;
359
+ padding: 10px;
360
+ border-style: none;
361
+ background-color: #fff;
362
+ height: auto;
363
+ }
364
+ div.relaypoint_logo {
365
+ width: 100px;
366
+ padding: 0;
367
+ margin: 0;
368
+ float: left;
369
+ margin-top: 10px;
370
+ text-align:center;
371
+ }
372
+ div.relaypoint_logo label {
373
+ min-width: 80px !important;
374
+ padding: 0 !important;
375
+ margin: 0 !important;
376
+ }
377
+ div.relaypoint_logo label img {
378
+ height: 75px;
379
+ width: 75px;
380
+ float: left;
381
+ padding: 0;
382
+ }
383
+ label.relaypoint_label_logo {
384
+ background-color: #fff !important;
385
+ }
386
+ label.relaypoint_label_logo img {
387
+ height: 75px !important;
388
+ width: 75px !important;
389
+ float: left !important;
390
+ background-color: #fff !important;
391
+ padding: 0 !important;
392
+ }
393
+ div.relaypoint_input {
394
+ padding-left: 10px;
395
+ padding-bottom: 15px;
396
+ width: 72%;
397
+ margin-left: 110px;
398
+ margin-top: 10px;
399
+ }
400
+ label.relaypoint_label_find {
401
+ background-color: transparent !important;
402
+ padding: 0 !important;
403
+ font-family: 'DPDPlutoSansLight' !important;
404
+ }
405
+ input.relaypoint-input-address {
406
+ line-height: 19px !important;
407
+ margin-top: 4px !important;
408
+ margin-bottom: 5px !important;
409
+ border-style: none;
410
+ height: 25px !important;
411
+ padding-left: 5px;
412
+ width: 242px !important;
413
+ font-size: 12px;
414
+ font-family: DPDPlutoSansLight !important;
415
+ background-color: #e6e7e7 !important;
416
+ color: #424143 !important;
417
+ }
418
+ input.relaypoint-input-zipcode {
419
+ line-height: 19px !important;
420
+ padding-left: 5px;
421
+ width: 60px !important;
422
+ margin-right: 5px !important;
423
+ height: 25px !important;
424
+ border-style: none!important;
425
+ font-size: 12px!important;
426
+ font-family: DPDPlutoSansLight !important;
427
+ background-color: #e6e7e7 !important;
428
+ color: #424143 !important;
429
+ }
430
+ input.relaypoint-input-city {
431
+ line-height: 19px !important;
432
+ height: 19px !important;
433
+ padding-left: 5px;
434
+ width: 172px !important;
435
+ margin-right: 10px !important;
436
+ height: 25px !important;
437
+ border-style: none!important;
438
+ font-size: 12px!important;
439
+ font-family: DPDPlutoSansLight !important;
440
+ background-color: #e6e7e7 !important;
441
+ color: #424143 !important;
442
+ }
443
+ img.v-middle {
444
+ display:inline;
445
+ vertical-align:middle;
446
+ }
447
+ #suggestion div label {
448
+ margin-top: 15px;
449
+ margin-left: 15px;
450
+ }
451
+ div.alphacube_buttons button {
452
+ font-size: 12px;
453
+ background-color: transparent;
454
+ height: 32px;
455
+ width: 32px;
456
+ border-style: none;
457
+ background: no-repeat;
458
+ cursor: pointer;
459
+ display: block;
460
+ position: fixed;
461
+ top: 5%;
462
+ left: 80.5%;
463
+ z-index: 1111;
464
+ }
465
+ div.alphacube_message {
466
+ font-family: 'DPDPlutoSansLight', sans-serif;
467
+ text-rendering: optimizelegibility;
468
+ display:block;
469
+ border-radius: 6px;
470
+ position:fixed;
471
+ width:60%;
472
+ height:90%;
473
+ background-color:white;
474
+ top:5%;
475
+ left:20%;
476
+ padding: 0px;
477
+ text-align:left;
478
+ z-index:1110;
479
+ }
480
+ div.alphacube_message h4 {
481
+ width: 100;
482
+ height: 10px;
483
+ line-height: 18px;
484
+ background-color: #fff;
485
+ border-bottom: 1px solid #2E93CB;
486
+ font-weight: normal;
487
+ font-size: 16px;
488
+ margin-bottom: 10px;
489
+ color: grey;
490
+ font-variant: normal;
491
+ text-transform: none;
492
+ font-family: DPDPlutoSansLight;
493
+ height: 22px;
494
+ }
495
+ div.header {
496
+ z-index: 0
497
+ }
498
+ /* Pop-in details */
499
+
500
+ #filter {
501
+ display:none;
502
+ position:fixed;
503
+ width:100%;
504
+ height:100%;
505
+ background-color:#424143;
506
+ top:0;
507
+ left:0;
508
+ padding:14px;
509
+ text-align:left;
510
+ z-index:1000;
511
+ opacity:0.85;
512
+ filter:alpha(opacity=85); /*IE8 et avant */
513
+ }
514
+
515
+ .dpdfrrelaisboxcarto {
516
+ width:100%;
517
+ min-height: 62%;
518
+ top: 0px;
519
+ left: 0px;
520
+ border-radius: 6px 6px 0px 0px;
521
+ }
522
+
523
+ div.gm-style-cc div {
524
+ display: none;
525
+ }
526
+
527
+ div.dpdfrrelaisboxbottom {
528
+ position: relative;
529
+ margin: 0 auto;
530
+ width: 800px;
531
+ }
532
+
533
+ .dpdfrrelaisboxadresseheader {
534
+ width: 240px;
535
+ height: 90px;
536
+ background: #fff;
537
+ font-weight:300;
538
+ font-size:12px;
539
+ text-align:center;
540
+ border-style: none;
541
+ line-height: 0px;
542
+ margin: 0;
543
+ padding: 0;
544
+ }
545
+
546
+ .dpdfrrelaisboxadresse {
547
+ min-height:88px;
548
+ height:auto;
549
+ line-height: 22px;
550
+ font-size: 11px;
551
+ width: 240px;
552
+ margin-bottom: 0;
553
+ position: absolute;
554
+ left:0%;
555
+ }
556
+
557
+ div.dpdfrrelaisboxadresse p {
558
+ padding: 0;
559
+ font-style: italic;
560
+ font-size: 12px;
561
+ line-height: 12px;
562
+ margin: 0;
563
+ margin-top: 5px;
564
+ margin-bottom: 5px;
565
+ }
566
+
567
+ div.dpdfrrelaisboxhoraires {
568
+ text-align:left;
569
+ background: #FFF;
570
+ height:auto;
571
+ line-height: 22px;
572
+ font-size: 11px;
573
+ width: 260px;
574
+ left: 250px;
575
+ position: absolute;
576
+ }
577
+ .dpdfrrelaisboxhorairesheader {
578
+ width: 240px;
579
+ height: 90px;
580
+ background: #fff;
581
+ font-weight:300;
582
+ font-size:12px;
583
+ text-align:center;
584
+ border-style: none;
585
+ margin: 0;
586
+ padding: 0;
587
+ line-height: 0px;
588
+ }
589
+
590
+ div.dpdfrrelaisboxhoraires p span {
591
+ font-family: 'DPDPlutoSansLight', sans-serif;
592
+ display: inline-block;
593
+ color: #dc0032;
594
+ font-size: 12px;
595
+ font-weight: 400;
596
+ width: 90px;
597
+ margin: 0;
598
+ }
599
+
600
+ div.dpdfrrelaisboxhoraires p {
601
+ padding: 0;
602
+ padding-top: 5px;
603
+ padding-left: 5px;
604
+ line-height: 11px;
605
+ margin: 0 !important;
606
+ }
607
+
608
+ .dpdfrrelaisboxinfos {
609
+ text-align:left;
610
+ background: #FFF;
611
+ height:auto;
612
+ line-height: 22px;
613
+ font-size: 11px;
614
+ width: 260px;
615
+ margin-right: 10px;
616
+ position: absolute;
617
+ left: 520px;
618
+ }
619
+
620
+ .dpdfrrelaisboxinfosheader {
621
+ width: 260px;
622
+ height: 90px;
623
+ background: #fff;
624
+ font-weight:300;
625
+ font-size:12px;
626
+ text-align:center;
627
+ border-style: none;
628
+ margin: 0;
629
+ padding: 0;
630
+ line-height: 0px;
631
+ }
632
+
633
+ div.dpdfrrelaisboxinfos h5 {
634
+ font-family: 'DPDPlutoSansLight', sans-serif;
635
+ display: inline-block;
636
+ color: #dc0032;
637
+ font-size: 12px;
638
+ font-weight: 400;
639
+ width: 200px;
640
+ margin: 0;
641
+ text-transform: none;
642
+ }
643
+
644
+ div.dpdfrrelaisboxinfos h4 {
645
+ font-family: 'DPDPlutoSansLight', sans-serif;
646
+ display: inline-block;
647
+ color: #dc0032;
648
+ font-size: 12px;
649
+ font-weight: 700;
650
+ width: 110px;
651
+ border-style: none;
652
+ padding: 0;
653
+ margin: 0;
654
+ }
655
+ div.dpdfrrelaisboxadresseheader img {
656
+ height: 64px;
657
+ width: 64px;
658
+ margin: 5px auto;
659
+ }
660
+
661
+ div.dpdfrrelaisboxhorairesheader img {
662
+ height: 64px;
663
+ width: 64px;
664
+ margin: 5px auto;
665
+ }
666
+
667
+ div.dpdfrrelaisboxinfosheader img {
668
+ height: 64px;
669
+ width: 64px;
670
+ margin: 5px auto;
671
+ }
672
+
673
+ #dpdfrrelaisboxinfoswarning {
674
+ display:inline;
675
+ }
676
+
677
+ .dpdfrrelaisboxjour {
678
+ display:inline-block;
679
+ color:#dc0032;
680
+ font-size: 12px;
681
+ font-weight:400;
682
+ min-width:75px;
683
+ }
684
+
685
+ .dpdfrrelaisboxclose {
686
+ background:no-repeat;
687
+ cursor: pointer;
688
+ display:block;
689
+ position:fixed;
690
+ top:5%;
691
+ left:91%;
692
+ z-index:1111;
693
+ }
694
+
695
+ .dpdfrrelaisboxclose img {
696
+ float:right;
697
+ padding-top:2px;
698
+ padding-right:2px;
699
+ }
700
+
701
+ button.ok_button {
702
+ font-size: 24px !important;
703
+ background-color: transparent;
704
+ height: 32px;
705
+ width: 32px;
706
+ cursor: pointer;
707
+ position: fixed;
708
+ z-index: 1111;
709
+ color: #fff;
710
+ font-family: 'DPDPlutoSansLight';
711
+ font-weight: 300;
712
+ transition: all .15s;
713
+ }
714
+ button.ok_button:hover
715
+ {
716
+ transform:rotate(90deg);
717
+ }
718
+ input.ok_button {
719
+ font-size: 40px !important;
720
+ background-color: transparent;
721
+ height: 32px;
722
+ width: 32px;
723
+ cursor: pointer;
724
+ position: fixed;
725
+ z-index: 1111;
726
+ color: #fff;
727
+ font-family: 'DPDPlutoSansLight';
728
+ font-weight: 300;
729
+ top: 5%;
730
+ margin-left: -7px;
731
+ transition: all .15s;
732
+ }
733
+ input.ok_button:hover
734
+ {
735
+ transform:rotate(90deg);
736
+ }
737
+ /* Responsive design */
738
+ /* Condition horizontale (PC) */
739
+
740
+ @media only screen and (max-width: 1350px) {
741
+ div.alphacube_message { width: 80%; left:10%; top:5%;}
742
+ div.alphacube_buttons button { left:91%; top:5%;}
743
+ button.ok_button { left:91%; top:5%;}
744
+ input.ok_button { left:91%; top:5%;}
745
+ }
746
+
747
+ @media only screen and (max-width: 1020px) {
748
+ .dpdfrrelaisboxinfos {display:none;}
749
+ div.dpdfrrelaisboxbottom{width:520px;}
750
+ }
751
+ @media only screen and (max-width: 780px) {
752
+ #dpdfrrelais #suggestion span.dpdfrrelais_logo img {
753
+ display: none
754
+ }
755
+ div.relaypoint_input {
756
+ margin-left: 160px
757
+ }
758
+ }
759
+ @media only screen and (max-width: 750px) {
760
+ #div_dpdfrrelais_header {display:none;}
761
+ td.logodpdfrrelais {display:none;}
762
+ td.adressepr {padding-left:5px;font-size:10px; -webkit-border-radius: 5px 0px 0px 5px; -moz-border-radius: 5px 0px 0px 5px; -ms-border-radius: 5px 0px 0px 5px; -o-border-radius: 5px 0px 0px 5px; border-radius: 5px 0px 0px 5px;}
763
+ td.distancepr {font-size:10px;}
764
+ }
765
+
766
+ @media only screen and (max-width: 680px) {
767
+ td.popinpr {display:none;}
768
+ .dpdfrrelaisboxcarto {min-height:40%;}
769
+ .dpdfrrelaisboxadresse{position: relative;}
770
+ div.dpdfrrelaisboxhoraires{left:0;}
771
+ div.dpdfrrelaisboxbottom{width:250px;}
772
+ }
773
+ @media only screen and (max-width: 640px) {
774
+ #div_relaypoint_header {
775
+ display: none
776
+ }
777
+ #dpdfrrelais #suggestion span.s3 a {
778
+ display: none
779
+ }
780
+ div.relaypoint_input {
781
+ margin-left: 0
782
+ }
783
+ div.relaypoint_logo label img {
784
+ display: none
785
+ }
786
+ #dpdfrrelais #suggestion span.s1 {
787
+ width: 53%;
788
+ font-size: 10px;
789
+ letter-spacing: -0.4px;
790
+ font-weight: normal !important;
791
+ -webkit-border-radius: 8px;
792
+ -moz-border-radius: 8px;
793
+ border-radius: 8px;
794
+ }
795
+ }
796
+ /* Condition verticale (Smartphone) */
797
+ @media only screen and (max-height: 610px) {
798
+ .dpdfrrelaisboxcarto {display:none;}
799
+ }
skin/frontend/base/default/js/dpdfrance/dpdfrpredict.js ADDED
@@ -0,0 +1,78 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
+
11
+ function radioCheck(){
12
+ if (($$("input[id*='s_method_dpdfrpredict_']").length!=0) && ($("dpdfrpredict"))){
13
+ if($$("input[id*='s_method_dpdfrpredict_']")[0].checked){
14
+ $("dpdfrpredict").show();
15
+ }else{
16
+ $("dpdfrpredict").hide();
17
+ }
18
+ }
19
+ if ($$("input[id*='s_method_dpdfrrelais_']").length!=0){
20
+ if($$("input[id*='s_method_dpdfrrelais_']")[0].checked){
21
+ $("dpdfrrelais").show();
22
+ }else{
23
+ $("dpdfrrelais").hide();
24
+ }
25
+ }
26
+ }
27
+
28
+ function in_array(search, array){
29
+ for (i = 0; i < array.length; i++){
30
+ if(array[i] == search ){
31
+ return false;
32
+ }
33
+ }
34
+ return true;
35
+ }
36
+
37
+ function updateshipping(url){
38
+ if ($$("input[id*='s_method_dpdfrrelais_']").length!=0){
39
+ if($$("input[id*='s_method_dpdfrrelais_']")[0].checked){
40
+ var radioGrp = document['forms']['co-shipping-method-form']['relay-point'];
41
+ if (radioGrp){
42
+ for(i=0; i < radioGrp.length; i++){
43
+ if (radioGrp[i].checked == true) {
44
+ var radioValue = radioGrp[i].value;
45
+ }
46
+ }
47
+ }else{
48
+ if (radioValue==null){
49
+ alert ("Votre livraison DPD Relais\n\nMerci de s\xE9lectionner un relais Pickup pour votre livraison");
50
+ return false;
51
+ }
52
+ }
53
+ var shippingstring = new Array();
54
+ if(radioValue){
55
+ shippingstring=radioValue.split("|||");
56
+ }else{
57
+ alert ("Votre livraison DPD Relais\n\nMerci de s\xE9lectionner un relais Pickup pour votre livraison");
58
+ return false;
59
+ }
60
+ }
61
+ }
62
+ if (($$("input[id*='s_method_dpdfrpredict_']").length!=0) && ($("dpdfrpredict"))){
63
+ if($$("input[id*='s_method_dpdfrpredict_']")[0].checked){
64
+ var regex = new RegExp(/^((\+33|0)[67])(?:[ _.-]?(\d{2})){4}$/);
65
+ var gsmDest = document.getElementById('gsm_dest');
66
+ var numbers = gsmDest.value.substr(-8);
67
+ var pattern = new Array('00000000','11111111','22222222','33333333','44444444','55555555','66666666','77777777','88888888','99999999','12345678','23456789','98765432');
68
+
69
+ if (regex.test(gsmDest.value) && in_array(numbers, pattern)){
70
+ document.getElementById('dpdfrance_predict_error').style.display = 'none';
71
+ }else{
72
+ document.getElementById('dpdfrance_predict_error').style.display = 'block';
73
+ return false;
74
+ }
75
+ }
76
+ }
77
+ shippingMethod.save();
78
+ }
skin/frontend/base/default/js/dpdfrance/dpdfrrelais.js ADDED
@@ -0,0 +1,128 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
+
11
+ function radioCheck(){
12
+ if ($$("input[id*='s_method_dpdfrrelais_']").length!=0){
13
+ if($$("input[id*='s_method_dpdfrrelais_']")[0].checked){
14
+ $("dpdfrrelais").show();
15
+ }else{
16
+ $("dpdfrrelais").hide();
17
+ }
18
+ }
19
+ if (($$("input[id*='s_method_dpdfrpredict_']").length!=0) && ($("dpdfrpredict"))){
20
+ if($$("input[id*='s_method_dpdfrpredict_']")[0].checked){
21
+ $("dpdfrpredict").show();
22
+ }else{
23
+ $("dpdfrpredict").hide();
24
+ }
25
+ }
26
+ }
27
+
28
+
29
+ function fetchPoint(url,area){
30
+ var address = escape($("address").value);
31
+ var zipcode = escape($("zipcode").value);
32
+ var city = escape($("city").value);
33
+ new Ajax.Request(url,{
34
+ method:'post',
35
+ parameters:{address:address,zipcode:zipcode,city:city},
36
+ onLoading:function(){
37
+ $("loadingpointswait").show();
38
+ },
39
+ onComplete:function(){
40
+ $("loadingpointswait").hide();
41
+ },
42
+ onSuccess:function(transport){
43
+ $(area).update(transport.responseText);
44
+ }
45
+ }
46
+
47
+ );
48
+ }
49
+
50
+ function in_array(search, array){
51
+ for (i = 0; i < array.length; i++){
52
+ if(array[i] == search ){
53
+ return false;
54
+ }
55
+ }
56
+ return true;
57
+ }
58
+
59
+ function updateshipping(url){
60
+ if ($$("input[id*='s_method_dpdfrrelais_']").length!=0){
61
+ if($$("input[id*='s_method_dpdfrrelais_']")[0].checked){
62
+ var radioGrp = document['forms']['co-shipping-method-form']['relay-point'];
63
+ if (radioGrp){
64
+ for(i=0; i < radioGrp.length; i++){
65
+ if (radioGrp[i].checked == true) {
66
+ var radioValue = radioGrp[i].value;
67
+ }
68
+ }
69
+ }else{
70
+ if (radioValue==null){
71
+ alert ("Votre livraison DPD Relais\n\nMerci de s\xE9lectionner un relais Pickup pour votre livraison");
72
+ return false;
73
+ }
74
+ }
75
+ var shippingstring = new Array();
76
+ if(radioValue){
77
+ shippingstring=radioValue.split("|||");
78
+ }else{
79
+ alert ("Votre livraison DPD Relais\n\nMerci de s\xE9lectionner un relais Pickup pour votre livraison");
80
+ return false;
81
+ }
82
+ }
83
+ }
84
+ if (($$("input[id*='s_method_dpdfrpredict_']").length!=0) && ($("dpdfrpredict"))){
85
+ if($$("input[id*='s_method_dpdfrpredict_']")[0].checked){
86
+ var regex = new RegExp(/^((\+33|0)[67])(?:[ _.-]?(\d{2})){4}$/);
87
+ var gsmDest = document.getElementById('gsm_dest');
88
+ var numbers = gsmDest.value.substr(-8);
89
+ var pattern = new Array('00000000','11111111','22222222','33333333','44444444','55555555','66666666','77777777','88888888','99999999','12345678','23456789','98765432');
90
+
91
+ if (regex.test(gsmDest.value) && in_array(numbers, pattern)){
92
+ document.getElementById('dpdfrance_predict_error').style.display = 'none';
93
+ }else{
94
+ document.getElementById('dpdfrance_predict_error').style.display = 'block';
95
+ return false;
96
+ }
97
+ }
98
+ }
99
+ shippingMethod.save();
100
+ }
101
+
102
+ function openDialog(id,mapid,lat,longti,baseurl){
103
+
104
+ Dialog.alert(document.getElementById(id).innerHTML, {className: "alphacube", width:"60%", height:"90%", okLabel:"X"});
105
+ //alert('breakpoint');
106
+ initialize.delay(0.5,mapid,lat,longti,baseurl);
107
+
108
+ }
109
+
110
+ function initialize(mapid,lat,longti,baseurl){
111
+ var latlng = new google.maps.LatLng(lat, longti);
112
+
113
+ var myOptions = {
114
+ zoom: 15,
115
+ center: latlng,
116
+ mapTypeId: google.maps.MapTypeId.ROADMAP,
117
+ styles:[{"featureType":"landscape","stylers":[{"visibility":"on"},{"color":"#ebebeb"}]},{"featureType":"poi.sports_complex","stylers":[{"visibility":"on"}]},{"featureType":"poi.attraction","stylers":[{"visibility":"off"}]},{"featureType":"poi.government","stylers":[{"visibility":"on"}]},{"featureType":"poi.medical","stylers":[{"visibility":"on"}]},{"featureType":"poi.place_of_worship","stylers":[{"visibility":"on"}]},{"featureType":"poi.school","stylers":[{"visibility":"on"}]},{"featureType":"water","elementType":"geometry","stylers":[{"visibility":"on"},{"color":"#d2e4f3"}]},{"featureType":"water","elementType":"labels","stylers":[{"visibility":"on"}]},{"featureType":"transit","elementType":"labels","stylers":[{"visibility":"off"}]},{"featureType":"road","elementType":"geometry.fill","stylers":[{"visibility":"on"},{"color":"#ffffff"}]},{"featureType":"road","elementType":"geometry.stroke","stylers":[{"visibility":"on"},{"color":"#ebebeb"}]},{"elementType":"labels.text.fill","stylers":[{"visibility":"on"},{"color":"#666666"}]},{"featureType":"poi.business","stylers":[{"visibility":"off"}]},{"featureType":"road","elementType":"labels.icon","stylers":[{"visibility":"off"}]},{"featureType":"poi","elementType":"geometry.fill","stylers":[{"visibility":"on"},{"color":"#dbdbdb"}]},{"featureType":"administrative.locality","elementType":"labels.text.fill","stylers":[{"visibility":"on"},{"color":"#999999"}]},{"featureType":"transit.station","stylers":[{"visibility":"on"}]},{"featureType":"transit","elementType":"geometry","stylers":[{"visibility":"on"},{"color":"#dbdbdb"}]},{"elementType":"labels.icon","stylers":[{"visibility":"on"},{"saturation":-100}]},{"featureType":"road","elementType":"labels.icon","stylers":[{"visibility":"off"}]},{"elementType":"labels.text","stylers":[{"visibility":"on"}]},{"featureType":"transit.line","elementType":"labels.text","stylers":[{"visibility":"off"}]}]
118
+ };
119
+ var map = new google.maps.Map(document.getElementById(mapid), myOptions);
120
+ var markericon = baseurl+'dpdfrance/front/relais/logo-max-png.png';
121
+ var marker = new google.maps.Marker({
122
+ position : latlng,
123
+ map : map,
124
+ animation : google.maps.Animation.DROP,
125
+ icon : markericon
126
+ });
127
+ }
128
+