Owebia_Shipping_2 - Version 2.4.0

Version Notes

[2.4.0 - 27 juin 2011]
Correction d'un bug lorsque plusieurs produits identiques avec des options différentes sont présents dans le panier (la valeur de l'option était toujours égale à celle du premier produit)
Ajout de la possibilité d'utiliser les expressions régulières dans les champs "destination" et "origin"
Ajout de la variable {car.weight.for-charge}
Mise à jour de la documentation en français
Mise à jour de l'éditeur
Correction d'un bug de l'éditeur lorsqu'on éditait une destination puis qu'on cliquait sur Annuler

Download this release

Release Info

Developer Magento Core Team
Extension Owebia_Shipping_2
Version 2.4.0
Comparing to
See all releases


Version 2.4.0

app/code/community/Owebia/Shipping2/Block/Adminhtml/System/Config/Form/Field/Config.php ADDED
@@ -0,0 +1,46 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Owebia_Shipping2_Block_Adminhtml_System_Config_Form_Field_Config extends Mage_Adminhtml_Block_System_Config_Form_Field
4
+ {
5
+ private static $JS_INCLUDED = false;
6
+
7
+ private function label($input) {
8
+ return str_replace(array("\r\n","\r","\n","'"),array("\\n","\\n","\\n","\\'"),$this->__($input));
9
+ }
10
+
11
+ protected function _getElementHtml(Varien_Data_Form_Element_Abstract $element) {
12
+ $output = '';
13
+ if (!self::$JS_INCLUDED) {
14
+ $include_path = Mage::getBaseUrl('js').'owebia/shipping2';
15
+ $output = "<script type=\"text/javascript\" src=\"http://ajax.googleapis.com/ajax/libs/jquery/1.4.3/jquery.min.js\"></script>\n"
16
+ ."<script type=\"text/javascript\" src=\"".$include_path."/os2editor.js?t=".time()."\"></script>\n"
17
+ ."<script type=\"text/javascript\">\n"
18
+ ."//<![CDATA[\n"
19
+ ."jQuery.noConflict();\n"
20
+ ."var os2editor = new OS2Editor({\n"
21
+ ."ajax_url: '".$this->getUrl('owebia-shipping2/ajax')."?isAjax=true',\n"
22
+ ."form_key: FORM_KEY,\n"
23
+ ."menu_item_dissociate_label: '".$this->label('Dissociate')."',\n"
24
+ ."menu_item_remove_label: '".$this->label('Remove')."',\n"
25
+ ."menu_item_edit_label: '".$this->label('Edit')."',\n"
26
+ ."prompt_new_value_label: '".$this->label('Enter the new value:')."',\n"
27
+ ."default_row_label: '".$this->label('[No label]')."',\n"
28
+ ."loading_label: '".$this->label('Loading...')."'\n"
29
+ ."});\n"
30
+ ."//]]>\n"
31
+ ."</script>\n"
32
+ ."<link type=\"text/css\" href=\"".$include_path."/os2editor.css?t=".time()."\" rel=\"stylesheet\" media=\"all\"/>\n"
33
+ ;
34
+ self::$JS_INCLUDED = true;
35
+ }
36
+
37
+ $shipping_code = preg_replace('/^groups\[([^\]]*)\].*$/','\1',$element->getName());
38
+ return $output
39
+ .'<div style="margin-bottom:1px;">'
40
+ .'<button type="button" class="scalable" onclick="os2editor.open(this,\''.$shipping_code.'\');"><span>'.$this->__("Open editor").'</span></button>'
41
+ .'&nbsp;<button type="button" class="scalable" onclick="os2editor.help(\'summary\',this,\''.$shipping_code.'\');"><span>'.$this->__("Help").'</span></button>'
42
+ .'</div>'
43
+ .$element->getElementHtml().'<br/>'
44
+ ;
45
+ }
46
+ }
app/code/community/Owebia/Shipping2/Controller/Abstract.php ADDED
@@ -0,0 +1,130 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Magento Owebia Shipping2 Module
5
+ *
6
+ * NOTICE OF LICENSE
7
+ *
8
+ * This source file is subject to the Open Software License (OSL 3.0)
9
+ * that is bundled with this package in the file LICENSE.txt.
10
+ * It is also available through the world-wide-web at this URL:
11
+ * http://opensource.org/licenses/osl-3.0.php
12
+ * If you did not receive a copy of the license and are unable to
13
+ * obtain it through the world-wide-web, please send an email
14
+ * to license@magentocommerce.com so we can send you a copy immediately.
15
+ *
16
+ * @category Owebia
17
+ * @package Owebia_Shipping2
18
+ * @copyright Copyright (c) 2008-10 Owebia (http://www.owebia.com/)
19
+ * @author Antoine Lemoine
20
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
21
+ */
22
+
23
+ class Owebia_Shipping2_Controller_Abstract extends Mage_Adminhtml_Controller_Action
24
+ {
25
+ public function __() {
26
+ $args = func_get_args();
27
+ $message = array_shift($args);
28
+ if ($message instanceof OS_Message) {
29
+ $args = $message->args;
30
+ $message = $message->message;
31
+ }
32
+
33
+ $output = Mage::helper('shipping')->__($message);
34
+ if (count($args)==0) return $output;
35
+
36
+ if (!isset($this->_translate_inline)) $this->_translate_inline = Mage::getSingleton('core/translate')->getTranslateInline();
37
+ if ($this->_translate_inline) {
38
+ $parts = explode('}}{{',$output);
39
+ $parts[0] = vsprintf($parts[0],$args);
40
+ return implode('}}{{',$parts);
41
+ }
42
+ else return vsprintf($output,$args);
43
+ }
44
+
45
+ protected function getModulePath($path) {
46
+ if (file_exists(dirname(__FILE__).'/Owebia_Shipping2_'.str_replace('/','_',$path))) {
47
+ return 'Owebia_Shipping2_'.str_replace('/','_',$path);
48
+ } else {
49
+ return Mage::getBaseDir('code').'/community/Owebia/Shipping2/'.$path;
50
+ }
51
+ }
52
+
53
+ protected function getMimeType($extension) {
54
+ $mime_type_array = array(
55
+ '.gz' => 'application/x-gzip',
56
+ '.tgz' => 'application/x-gzip',
57
+ '.zip' => 'application/zip',
58
+ '.pdf' => 'application/pdf',
59
+ '.png' => 'image/png',
60
+ '.gif' => 'image/gif',
61
+ '.jpg' => 'image/jpeg',
62
+ '.jpeg' => 'image/jpeg',
63
+ '.txt' => 'text/plain',
64
+ '.htm' => 'text/html',
65
+ '.html' => 'text/html',
66
+ '.mpg' => 'video/mpeg',
67
+ '.avi' => 'video/x-msvideo',
68
+ );
69
+ return isset($mime_type_array[$extension]) ? $mime_type_array[$extension] : 'application/octet-stream';
70
+ }
71
+
72
+ protected function forceDownload($filename, $content) {
73
+ if (headers_sent()) {
74
+ trigger_error('forceDownload($filename) - Headers have already been sent',E_USER_ERROR);
75
+ return false;
76
+ }
77
+
78
+ $extension = strrchr($filename,'.');
79
+ $mime_type = $this->getMimeType($extension);
80
+
81
+ header('Content-disposition: attachment; filename="'.$filename.'"');
82
+ header('Content-Type: application/force-download');
83
+ header('Content-Transfer-Encoding: '.$mime_type."\n"); // Surtout ne pas enlever le \n
84
+ //header('Content-Length: '.filesize($filename));
85
+ header('Pragma: no-cache');
86
+ header('Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0');
87
+ header('Expires: 0');
88
+ echo $content;
89
+ return true;
90
+ }
91
+
92
+ protected function jsEscape($input) {
93
+ return str_replace(array("\r\n","\r","\n","'"),array("\\n","\\n","\\n","\\'"),$input);
94
+ }
95
+
96
+ protected function cleanKey($key) {
97
+ return preg_replace('/[^a-z0-9-_]/i','_-_',$key);
98
+ }
99
+
100
+ protected function page($id, $title, $content) {
101
+ return "<div id=\"os2editor-".$id."-page\" class=\"os2editor-page\">"
102
+ .$this->pageHeader($title,$this->button('Close',"os2editor.closePage(this);",'cancel'))
103
+ ."<div class=\"page-content\">".$content."</div>"
104
+ ."</div>"
105
+ ;
106
+ }
107
+
108
+ protected function pageHeader($title, $buttons) {
109
+ return "<div class=\"content-header\">"
110
+ ."<table cellspacing=\"0\"><tr>"
111
+ ."<td><h3>".$this->__($title)."</h3></td>"
112
+ ."<td class=\"form-buttons\">"
113
+ .$buttons
114
+ ."</td>"
115
+ ."</tr></table>"
116
+ ."</div>"
117
+ ;
118
+ }
119
+
120
+ protected function untranslated_button($label, $onclick, $class_name='') {
121
+ $class_name = 'scalable'.($class_name!='' ? ' '.$class_name : '');
122
+ return "<button type=\"button\" class=\"".$class_name."\" onclick=\"".$onclick."\"><span>".$label."</span></button>";
123
+ }
124
+
125
+ protected function button($label, $onclick, $class_name='') {
126
+ return $this->untranslated_button($this->__($label),$onclick,$class_name);
127
+ }
128
+ }
129
+
130
+ ?>
app/code/community/Owebia/Shipping2/Model/Carrier/AbstractOwebiaShipping.php ADDED
@@ -0,0 +1,512 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Magento Owebia Shipping 2 Module
5
+ *
6
+ * NOTICE OF LICENSE
7
+ *
8
+ * This source file is subject to the Open Software License (OSL 3.0)
9
+ * that is bundled with this package in the file LICENSE.txt.
10
+ * It is also available through the world-wide-web at this URL:
11
+ * http://opensource.org/licenses/osl-3.0.php
12
+ * If you did not receive a copy of the license and are unable to
13
+ * obtain it through the world-wide-web, please send an email
14
+ * to license@magentocommerce.com so we can send you a copy immediately.
15
+ *
16
+ * @category Owebia
17
+ * @package Owebia_Shipping2
18
+ * @copyright Copyright (c) 2008-10 Owebia (http://www.owebia.com/)
19
+ * @author Antoine Lemoine
20
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
21
+ */
22
+
23
+ // Pour g�rer les cas o� il y a eu compilation
24
+ if (file_exists(dirname(__FILE__).'/Owebia_Shipping2_includes_OwebiaShippingHelper.php')) include_once 'Owebia_Shipping2_includes_OwebiaShippingHelper.php';
25
+ else include_once Mage::getBaseDir('code').'/community/Owebia/Shipping2/includes/OwebiaShippingHelper.php';
26
+
27
+
28
+
29
+ class Magento_Product implements OS_Product {
30
+ private $parent_cart_item;
31
+ private $cart_item;
32
+ private $cart_product;
33
+ private $loaded_product;
34
+ private $quantity;
35
+ private $options;
36
+
37
+ public function Magento_Product($cart_item, $parent_cart_item) {
38
+ $this->cart_item = $cart_item;
39
+ $this->cart_product = $cart_item->getProduct();
40
+ $this->parent_cart_item = $parent_cart_item;
41
+ $this->quantity = isset($parent_cart_item) ? $parent_cart_item->getQty() : $cart_item->getQty();
42
+ }
43
+
44
+ private function getProductOptions() {
45
+ if (isset($this->options)) return $this->options;
46
+ $item = $this->cart_item;
47
+ $options = array();
48
+ if ($optionIds = $item->getOptionByCode('option_ids')) {
49
+ foreach (explode(',', $optionIds->getValue()) as $optionId) {
50
+ if ($option = $item->getProduct()->getOptionById($optionId)) {
51
+ $quoteItemOption = $item->getOptionByCode('option_' . $option->getId());
52
+
53
+ $group = $option->groupFactory($option->getType())
54
+ ->setOption($option)
55
+ ->setQuoteItemOption($quoteItemOption);
56
+
57
+ $label = $option->getTitle();
58
+ $options[$label] = array(
59
+ 'label' => $label,
60
+ 'value' => $group->getFormattedOptionValue($quoteItemOption->getValue()),
61
+ 'print_value' => $group->getPrintableOptionValue($quoteItemOption->getValue()),
62
+ 'value_id' => $quoteItemOption->getValue(),
63
+ 'option_id' => $option->getId(),
64
+ 'option_type' => $option->getType(),
65
+ 'custom_view' => $group->isCustomizedView()
66
+ );
67
+ }
68
+ }
69
+ }
70
+ if ($addOptions = $item->getOptionByCode('additional_options')) {
71
+ $options = array_merge($options, unserialize($addOptions->getValue()));
72
+ }
73
+ $this->options = $options;
74
+ return $this->options;
75
+ }
76
+
77
+ public function getOption($option_name, $get_by_id=false) {
78
+ $value = null;
79
+ $product = $this->cart_product;
80
+ $options = $this->getProductOptions();
81
+ if (isset($options[$option_name])) return $get_by_id ? $options[$option_name]['value_id'] : $options[$option_name]['value'];
82
+ else return $value;
83
+ /*
84
+ foreach ($product->getOptions() as $option) {
85
+ if ($option->getTitle()==$option_name) {
86
+ $custom_option = $product->getCustomOption('option_'.$option->getId());
87
+ if ($custom_option) {
88
+ $value = $custom_option->getValue();
89
+ if ($option->getType()=='drop_down' && !$get_by_id) {
90
+ $option_value = $option->getValueById($value);
91
+ if ($option_value) $value = $option_value->getTitle();
92
+ }
93
+ }
94
+ break;
95
+ }
96
+ }
97
+ */
98
+ }
99
+
100
+ public function getAttribute($attribute_name, $get_by_id=false) {
101
+ $value = null;
102
+ $product = $this->_getLoadedProduct();
103
+
104
+ if ($attribute_name=='price-tax+discount') {
105
+ return $this->cart_item['base_original_price']-$this->cart_item['discount_amount']/$this->quantity;
106
+ } else if ($attribute_name=='price-tax-discount') {
107
+ return $this->cart_item['base_original_price'];
108
+ } else if ($attribute_name=='price+tax+discount') {
109
+ return $this->cart_item['base_original_price']+($this->cart_item['tax_amount']-$this->cart_item['discount_amount'])/$this->quantity;
110
+ } else if ($attribute_name=='price+tax-discount') {
111
+ return $this->cart_item['price_incl_tax'];
112
+ //return Mage::helper('checkout')->getPriceInclTax($this->cart_item);
113
+ }
114
+ $attribute = $product->getResource()->getAttribute($attribute_name);
115
+ if ($attribute) {
116
+ $input_type = $attribute->getFrontend()->getInputType();
117
+ switch ($input_type) {
118
+ case 'select' :
119
+ $value = $get_by_id ? $product->getData($attribute_name) : $product->getAttributeText($attribute_name);
120
+ break;
121
+ default :
122
+ $value = $product->getData($attribute_name);
123
+ break;
124
+ }
125
+ }
126
+ return $value;
127
+ }
128
+
129
+ private function _getLoadedProduct() {
130
+ if (!isset($this->loaded_product)) $this->loaded_product = Mage::getModel('catalog/product')->load($this->cart_product->getId());
131
+ return $this->loaded_product;
132
+ }
133
+
134
+ public function getQuantity() {
135
+ return $this->quantity;
136
+ }
137
+
138
+ public function getName() {
139
+ return $this->cart_product->getName();
140
+ }
141
+
142
+ public function getWeight() {
143
+ return $this->cart_product->getWeight();
144
+ }
145
+
146
+ public function getSku() {
147
+ return $this->cart_product->getSku();
148
+ }
149
+
150
+ public function getStockData($key) {
151
+ $stock = $this->cart_product->getStockItem();
152
+ switch ($key) {
153
+ case 'is_in_stock':
154
+ return (bool)$stock->getIsInStock();
155
+ case 'quantity':
156
+ $quantity = $stock->getQty();
157
+ return $stock->getIsQtyDecimal() ? (float)$quantity : (int)$quantity;
158
+ }
159
+ return null;
160
+ }
161
+ }
162
+
163
+ abstract class Owebia_Shipping2_Model_Carrier_AbstractOwebiaShipping
164
+ extends Mage_Shipping_Model_Carrier_Abstract
165
+ {
166
+ protected $_translate_inline;
167
+ protected $_result;
168
+ protected $_config;
169
+ protected $_countries;
170
+ protected $_helper;
171
+ protected $_messages;
172
+
173
+ /**
174
+ * Collect rates for this shipping method based on information in $request
175
+ *
176
+ * @param Mage_Shipping_Model_Rate_Request $data
177
+ * @return Mage_Shipping_Model_Rate_Result
178
+ */
179
+ public function collectRates(Mage_Shipping_Model_Rate_Request $request) {
180
+ // skip if not enabled
181
+ if (!$this->__getConfigData('active')) return false;
182
+
183
+ //$this->display($request->_data);
184
+
185
+ $process = $this->__getDefaultProcess();
186
+ $process['data'] = array_merge($this->__getDefaultProcessData($request->_data['store_id']),array(
187
+ 'cart.price-tax+discount' => $request->_data['package_value_with_discount'],
188
+ 'cart.price-tax-discount' => $request->_data['package_value'],
189
+ 'cart.weight' => $request->_data['package_weight'],
190
+ 'cart.quantity' => $request->_data['package_qty'],
191
+ 'destination.country.code' => $request->_data['dest_country_id'],
192
+ 'destination.region.code' => $request->_data['dest_region_code'],
193
+ 'destination.postcode' => $request->_data['dest_postcode'],
194
+ 'origin.country.code' => $request->_data['country_id'],
195
+ 'origin.region.code' => $request->_data['region_id'],
196
+ 'origin.postcode' => $request->_data['postcode'],
197
+ 'free_shipping' => $request->getFreeShipping(),
198
+ ));
199
+
200
+ $tax_amount = 0;
201
+ $full_price = 0;
202
+ $cart_items = array();
203
+ $items = $request->getAllItems();
204
+ $quote_total_collected = false;
205
+ for ($i=0, $n=count($items); $i<$n; $i++) {
206
+ $item = $items[$i];
207
+ if ($item->getProduct() instanceof Mage_Catalog_Model_Product) {
208
+ switch (get_class($item)) {
209
+ case 'Mage_Sales_Model_Quote_Address_Item': // Multishipping
210
+ $key = $item->getQuoteItemId();
211
+ break;
212
+ case 'Mage_Sales_Model_Quote_Item': // Onepage checkout
213
+ default:
214
+ $key = $item->getId();
215
+ break;
216
+ }
217
+
218
+ $cart_items[$key] = $item;
219
+ $tax_amount += $item->getData('tax_amount');
220
+ $full_price += Mage::helper('checkout')->getSubtotalInclTax($item); // ok
221
+ }
222
+ }
223
+
224
+ $process['data']['cart.price+tax+discount'] = $tax_amount+$process['data']['cart.price-tax+discount'];
225
+ $process['data']['cart.price+tax-discount'] = $full_price;
226
+ $process['data']['cart.price_excluding_tax'] = $process['data']['cart.price-tax+discount'];
227
+ $process['data']['cart.price_including_tax'] = $process['data']['cart.price+tax+discount'];
228
+ $process['data']['cart.weight.for-charge'] = $process['data']['cart.weight'];
229
+
230
+ foreach ($cart_items as $item) {
231
+ if ($item->getProduct()->getTypeId()!='configurable') {
232
+ $parent_item_id = $item->getParentItemId();
233
+ $magento_product = new Magento_Product($item, isset($cart_items[$parent_item_id]) ? $cart_items[$parent_item_id] : null);
234
+ $process['cart.products'][] = $magento_product;
235
+ if ($item->getFreeShipping()) $process['data']['cart.weight.for-charge'] -= $magento_product->getWeight() * $magento_product->getQuantity();
236
+ }
237
+ }
238
+
239
+ if (!$process['data']['free_shipping']) {
240
+ foreach ($cart_items as $item) {
241
+ if ($item->getProduct() instanceof Mage_Catalog_Model_Product) {
242
+ if ($item->getFreeShipping()) $process['data']['free_shipping'] = true;
243
+ else {
244
+ $process['data']['free_shipping'] = false;
245
+ break;
246
+ }
247
+ }
248
+ }
249
+ }
250
+
251
+ return $this->getRates($process);
252
+ }
253
+
254
+ public function display($var) {
255
+ $i = 0;
256
+ foreach ($var as $name => $value) {
257
+ //if ($i>20)
258
+ echo "{$name} => {$value}<br/>";
259
+ //$this->_helper->debug($name.' => '.$value.'<br/>');
260
+ $i++;
261
+ }
262
+ }
263
+
264
+ public function getRates($process) {
265
+ $this->_process($process);
266
+ return $process['result'];
267
+ }
268
+
269
+ public function getAllowedMethods() {
270
+ $process = array();
271
+ $config = $this->_getConfig();
272
+ $allowed_methods = array();
273
+ if (count($config)>0) {
274
+ foreach ($config as $row) $allowed_methods[$row['*code']] = isset($row['label']) ? $row['label']['value'] : 'No label';
275
+ }
276
+ return $allowed_methods;
277
+ }
278
+
279
+ public function isTrackingAvailable() {
280
+ return true;
281
+ }
282
+
283
+ public function getTrackingInfo($tracking_number) {
284
+ $tracking_url = $this->__getConfigData('tracking_view_url');
285
+ $parts = explode(':',$tracking_number);
286
+ if (count($parts)>=2) {
287
+ $tracking_number = $parts[1];
288
+
289
+ $process = array();
290
+ $config = $this->_getConfig();
291
+
292
+ if (isset($config[$parts[0]]['tracking_url'])) {
293
+ $row = $config[$parts[0]];
294
+ $tmp_tracking_url = $this->_helper->getRowProperty($row,'tracking_url');
295
+ if (isset($tmp_tracking_url)) $tracking_url = $tmp_tracking_url;
296
+ }
297
+ }
298
+
299
+ $tracking_status = Mage::getModel('shipping/tracking_result_status')
300
+ ->setCarrier($this->_code)
301
+ ->setCarrierTitle($this->__getConfigData('title'))
302
+ ->setTracking($tracking_number)
303
+ ->addData(
304
+ array(
305
+ 'status'=>'<a target="_blank" href="'.str_replace('{tracking_number}',$tracking_number,$tracking_url).'">'.__('track the package').'</a>'
306
+ )
307
+ )
308
+ ;
309
+ $tracking_result = Mage::getModel('shipping/tracking_result')
310
+ ->append($tracking_status)
311
+ ;
312
+
313
+ if ($trackings = $tracking_result->getAllTrackings()) return $trackings[0];
314
+ return false;
315
+ }
316
+
317
+ /***************************************************************************************************************************/
318
+
319
+ protected function _process(&$process) {
320
+ $process['data'] = array_merge($process['data'],array(
321
+ 'destination.country.name' => $this->__getCountryName($process['data']['destination.country.code']),
322
+ 'origin.country.name' => $this->__getCountryName($process['data']['origin.country.code']),
323
+ ));
324
+
325
+ $debug = (bool)(isset($_GET['debug']) ? $_GET['debug'] : $this->__getConfigData('debug'));
326
+ if ($debug) $this->_helper->initDebug($this->_code,$process['data']);
327
+
328
+ $value_found = false;
329
+ foreach ($process['config'] as $row) {
330
+ $result = $this->_helper->processRow($process,$row);
331
+ $this->_addMessages($this->_helper->getMessages());
332
+ if ($result->success) {
333
+ $value_found = true;
334
+ $this->__appendMethod($process,$row,$result->result);
335
+ if ($process['stop_to_first_match']) break;
336
+ }
337
+ }
338
+
339
+ $http_request = Mage::app()->getFrontController()->getRequest();
340
+ if ($debug && $this->_checkRequest($http_request,'checkout/cart/index')) {
341
+ Mage::getSingleton('core/session')->addNotice('DEBUG'.$this->_helper->getDebug());
342
+ }
343
+
344
+ //$this->_appendErrors($process,$this->_messages);
345
+ //if (!$value_found) $this->__appendError($process,$this->__('No match found'));
346
+ }
347
+
348
+ protected function _checkRequest($http_request, $path) {
349
+ list($router,$controller,$action) = explode('/',$path);
350
+ return $http_request->getRouteName()==$router && $http_request->getControllerName()==$controller && $http_request->getActionName()==$action;
351
+ }
352
+
353
+ protected function _getConfig() {
354
+ if (!isset($this->_config)) {
355
+ $this->_helper = new OwebiaShippingHelper($this->__getConfigData('config'));
356
+ $this->_config = $this->_helper->getConfig();
357
+ $this->_addMessages($this->_helper->getMessages());
358
+ }
359
+ return $this->_config;
360
+ }
361
+
362
+ protected function _getMethodText($process, $row, $property) {
363
+ if (!isset($row[$property])) return '';
364
+
365
+ $output = '';
366
+ return $output . ' '.$this->_helper->evalInput($process,$row,$property,str_replace(
367
+ array(
368
+ '{cart.weight}',
369
+ '{cart.price_including_tax}',
370
+ '{cart.price_excluding_tax}',
371
+ '{cart.price-tax+discount}',
372
+ '{cart.price-tax-discount}',
373
+ '{cart.price+tax+discount}',
374
+ '{cart.price+tax-discount}',
375
+ ),
376
+ array(
377
+ $process['data']['cart.weight'].$process['data']['cart.weight.unit'],
378
+ $this->__formatPrice($process['data']['cart.price_including_tax']),
379
+ $this->__formatPrice($process['data']['cart.price_excluding_tax']),
380
+ $this->__formatPrice($process['data']['cart.price-tax+discount']),
381
+ $this->__formatPrice($process['data']['cart.price-tax-discount']),
382
+ $this->__formatPrice($process['data']['cart.price+tax+discount']),
383
+ $this->__formatPrice($process['data']['cart.price+tax-discount']),
384
+ ),
385
+ $this->_helper->getRowProperty($row, $property)
386
+ ));
387
+ }
388
+
389
+ protected function _addMessages($messages) {
390
+ if (!is_array($messages)) $messages = array($messages);
391
+ if (!is_array($this->_messages)) $this->_messages = $messages;
392
+ else $this->_messages = array_merge($this->_messages,$messages);
393
+ }
394
+
395
+ protected function _appendErrors(&$process, $messages) {
396
+ if (is_array($messages)) {
397
+ foreach ($messages as $message) {
398
+ $this->__appendError($process,$this->__($message));
399
+ }
400
+ }
401
+ }
402
+
403
+ /***************************************************************************************************************************/
404
+
405
+ protected function __getDefaultProcess() {
406
+ $process = array(
407
+ 'cart.products' => array(),
408
+ 'config' => $this->_getConfig(),
409
+ 'data' => null,
410
+ 'result' => Mage::getModel('shipping/rate_result'),
411
+ 'stop_to_first_match' => $this->__getConfigData('stop_to_first_match'),
412
+ );
413
+ return $process;
414
+ }
415
+
416
+ protected function __getDefaultProcessData($store_id=null) {
417
+ if (!isset($store_id)) $store = Mage::app()->getStore();
418
+ else $store = Mage::app()->getStore($store_id);
419
+
420
+ $mage_config = Mage::getConfig();
421
+ $customer_group_id = Mage::getSingleton('customer/session')->getCustomerGroupId();
422
+ if ($customer_group_id==0) { // Pour les commandes depuis Adminhtml
423
+ $customer_group_id2 = Mage::getSingleton('adminhtml/session_quote')->getQuote()->getCustomerGroupId();
424
+ if (isset($customer_group_id2)) $customer_group_id = $customer_group_id2;
425
+ }
426
+ $customer_group_code = Mage::getSingleton('customer/group')->load($customer_group_id)->getCode();
427
+ $timestamp = Mage::getModel('core/date')->timestamp();
428
+
429
+ $properties = array_merge(OwebiaShippingHelper::getDefaultProcessData(),array(
430
+ 'info.magento.version' => Mage::getVersion(),
431
+ 'info.module.version' => (string)$mage_config->getNode('modules/Owebia_Shipping2/version'),
432
+ 'info.carrier.code' => $this->_code,
433
+ 'cart.weight.unit' => Mage::getStoreConfig('owebia/shipping/weight_unit'),
434
+ 'cart.coupon' => Mage::getSingleton('checkout/session')->getQuote()->getCouponCode(),
435
+ 'customer.group.id' => $customer_group_id,
436
+ 'customer.group.code' => $customer_group_code,
437
+ 'store.id' => $store->getId(),
438
+ 'store.code' => $store->getCode(),
439
+ 'store.name' => $store->getConfig('general/store_information/name'),
440
+ 'store.address' => $store->getConfig('general/store_information/address'),
441
+ 'store.phone' => $store->getConfig('general/store_information/phone'),
442
+ 'date.timestamp' => $timestamp,
443
+ 'date.year' => (int)date('Y',$timestamp),
444
+ 'date.month' => (int)date('m',$timestamp),
445
+ 'date.day' => (int)date('d',$timestamp),
446
+ 'date.hour' => (int)date('H',$timestamp),
447
+ 'date.minute' => (int)date('i',$timestamp),
448
+ 'date.second' => (int)date('s',$timestamp),
449
+ ));
450
+ return $properties;
451
+ }
452
+
453
+ protected function __getConfigData($key) {
454
+ return $this->getConfigData($key);
455
+ }
456
+
457
+ protected function __appendMethod(&$process, $row, $fees) {
458
+ $method = Mage::getModel('shipping/rate_result_method')
459
+ ->setCarrier($this->_code)
460
+ ->setCarrierTitle($this->__getConfigData('title'))
461
+ ->setMethod($row['*code'])
462
+ ->setMethodTitle($this->_getMethodText($process,$row,'label'))
463
+ ->setMethodDescription($this->_getMethodText($process,$row,'description'))
464
+ ->setPrice($fees)
465
+ ->setCost($fees)
466
+ ;
467
+
468
+ $process['result']->append($method);
469
+ }
470
+
471
+ protected function __appendError(&$process, $message) {
472
+ if (isset($process['result'])) {
473
+ $error = Mage::getModel('shipping/rate_result_error')
474
+ ->setCarrier($this->_code)
475
+ ->setCarrierTitle($this->__getConfigData('title'))
476
+ ->setErrorMessage($message)
477
+ ;
478
+ $process['result']->append($error);
479
+ }
480
+ }
481
+
482
+ protected function __formatPrice($price) {
483
+ if (!isset($this->_core_helper)) $this->_core_helper = Mage::helper('core');
484
+ return $this->_core_helper->currency($price);
485
+ }
486
+
487
+ protected function __($message) {
488
+ $args = func_get_args();
489
+ $message = array_shift($args);
490
+ if ($message instanceof OS_Message) {
491
+ $args = $message->args;
492
+ $message = $message->message;
493
+ }
494
+
495
+ $output = Mage::helper('shipping')->__($message);
496
+ if (count($args)==0) return $output;
497
+
498
+ if (!isset($this->_translate_inline)) $this->_translate_inline = Mage::getSingleton('core/translate')->getTranslateInline();
499
+ if ($this->_translate_inline) {
500
+ $parts = explode('}}{{',$output);
501
+ $parts[0] = vsprintf($parts[0],$args);
502
+ return implode('}}{{',$parts);
503
+ }
504
+ else return vsprintf($output,$args);
505
+ }
506
+
507
+ protected function __getCountryName($country_code) {
508
+ return Mage::getModel('directory/country')->load($country_code)->getName();
509
+ }
510
+ }
511
+
512
+ ?>
app/code/community/Owebia/Shipping2/Model/Carrier/OwebiaShipping1.php ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Magento Owebia Shipping Module
5
+ *
6
+ * NOTICE OF LICENSE
7
+ *
8
+ * This source file is subject to the Open Software License (OSL 3.0)
9
+ * that is bundled with this package in the file LICENSE.txt.
10
+ * It is also available through the world-wide-web at this URL:
11
+ * http://opensource.org/licenses/osl-3.0.php
12
+ * If you did not receive a copy of the license and are unable to
13
+ * obtain it through the world-wide-web, please send an email
14
+ * to license@magentocommerce.com so we can send you a copy immediately.
15
+ *
16
+ * @category Owebia
17
+ * @package Owebia_Shipping_2
18
+ * @copyright Copyright (c) 2008-09 Owebia (http://www.owebia.com/)
19
+ * @author Antoine Lemoine
20
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
21
+ */
22
+
23
+ class Owebia_Shipping2_Model_Carrier_OwebiaShipping1
24
+ extends Owebia_Shipping2_Model_Carrier_AbstractOwebiaShipping
25
+ {
26
+ protected $_code = 'owebiashipping1';
27
+ }
28
+
29
+ ?>
app/code/community/Owebia/Shipping2/Model/Carrier/OwebiaShipping2.php ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Magento Owebia Shipping Module
5
+ *
6
+ * NOTICE OF LICENSE
7
+ *
8
+ * This source file is subject to the Open Software License (OSL 3.0)
9
+ * that is bundled with this package in the file LICENSE.txt.
10
+ * It is also available through the world-wide-web at this URL:
11
+ * http://opensource.org/licenses/osl-3.0.php
12
+ * If you did not receive a copy of the license and are unable to
13
+ * obtain it through the world-wide-web, please send an email
14
+ * to license@magentocommerce.com so we can send you a copy immediately.
15
+ *
16
+ * @category Owebia
17
+ * @package Owebia_Shipping_2
18
+ * @copyright Copyright (c) 2008-09 Owebia (http://www.owebia.com/)
19
+ * @author Antoine Lemoine
20
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
21
+ */
22
+
23
+ class Owebia_Shipping2_Model_Carrier_OwebiaShipping2
24
+ extends Owebia_Shipping2_Model_Carrier_AbstractOwebiaShipping
25
+ {
26
+ protected $_code = 'owebiashipping2';
27
+ }
28
+
29
+ ?>
app/code/community/Owebia/Shipping2/Model/Carrier/OwebiaShipping3.php ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Magento Owebia Shipping Module
5
+ *
6
+ * NOTICE OF LICENSE
7
+ *
8
+ * This source file is subject to the Open Software License (OSL 3.0)
9
+ * that is bundled with this package in the file LICENSE.txt.
10
+ * It is also available through the world-wide-web at this URL:
11
+ * http://opensource.org/licenses/osl-3.0.php
12
+ * If you did not receive a copy of the license and are unable to
13
+ * obtain it through the world-wide-web, please send an email
14
+ * to license@magentocommerce.com so we can send you a copy immediately.
15
+ *
16
+ * @category Owebia
17
+ * @package Owebia_Shipping_2
18
+ * @copyright Copyright (c) 2008-09 Owebia (http://www.owebia.com/)
19
+ * @author Antoine Lemoine
20
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
21
+ */
22
+
23
+ class Owebia_Shipping2_Model_Carrier_OwebiaShipping3
24
+ extends Owebia_Shipping2_Model_Carrier_AbstractOwebiaShipping
25
+ {
26
+ protected $_code = 'owebiashipping3';
27
+ }
28
+
29
+ ?>
app/code/community/Owebia/Shipping2/changelog ADDED
@@ -0,0 +1,223 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ [2.4.0 - 27 juin 2011]
2
+ Correction d'un bug lorsque plusieurs produits identiques avec des options diff�rentes sont pr�sents dans le panier (la valeur de l'option �tait toujours �gale � celle du premier produit)
3
+ Ajout de la possibilit� d'utiliser les expressions r�guli�res dans les champs "destination" et "origin"
4
+ Ajout de la variable {car.weight.for-charge}
5
+ Mise � jour de la documentation en fran�ais
6
+ Mise � jour de l'�diteur
7
+ Correction d'un bug de l'�diteur lorsqu'on �ditait une destination puis qu'on cliquait sur Annuler
8
+
9
+ [2.3.11 - 28 avril 2011]
10
+ Correction d'un probl�me d'encodage/d�codage entre le javascript et le php via ajax (les signes "+" disparaissaient)
11
+ Surcharge du fichier Mage/Checkout/controllers/CartController.php pour corriger un probl�me avec Magento : les champs Mage_Sales_Quote_Item->_data['tax_amount'] n'�taient pas mis � jour correctement, ce qui cr�ait un d�calage et faussait la variable {cart.price+tax+discount}
12
+
13
+ [2.3.10 - 12 avril 2011]
14
+ Correction d'un probl�me dans AjaxController.php : passage direct d'un tableau par r�f�rence, il faut d'abord cr�er le tableau dans une variable puis passer la variable par r�f�rence
15
+ Ajout de la variable {cart.coupon}
16
+ Ajout des variables {cart.price-tax+discount}, {cart.price-tax-discount}, {cart.price+tax+discount}, {cart.price+tax-discount} qui permettent d'avoir le montant que l'on d�sire, avec ou sans prise en compte des taxes et des remises
17
+ Gestion semblable pour les attributs des produits : product.attribute.price-tax+discount utilisable dans une structure {sum} par exemple
18
+ Ajout de la possibilit� de r�cup�rer la valeur minimum ou maximum d'un attribut ou d'une option (utilisation identique � sum)
19
+
20
+ [2.3.9 - 20 janvier 2011]
21
+ Correction d'un probl�me avec le fichier adminhtml.xml (il y avait un commentaire avant l'en-t�te XML)
22
+
23
+ [2.3.8 - 14 janvier 2011]
24
+ Correction d'un bug avec la propri�t� "customer_groups" lorsqu'on utilisait les id's (is_int remplac� par ctype_digit)
25
+ Modifications des champs de configuration :
26
+ - Le champ "debug" devient de type Oui/Non
27
+ - Le champ "auto-compression" devient "compression" de type Oui/Non
28
+ Impl�mentation d'une compression efficace :
29
+ - La configuration est compress�e � l'aide de la fonction gzcompress() puis encod�e en base 64 afin d'�tre facilement plac�e dans un champ textarea
30
+ - La longueur de configuration peut �tre divis�e par 4 gr�ce � la compression
31
+ - La compression peut �tre utile sur certaines configurations o� la longueur des champs est limit�e
32
+ Am�lioration de l'�diteur :
33
+ - R�cup�ration des groupes utilisateurs de Magento et cr�ation d'un bouton pour chacun d'eux
34
+ - Ajout d'un bouton "Aide" (qui ouvre l'aide de l'�diteur) � droite du bouton "Ouvrir l'�diteur"
35
+ - Centralisation du changelog dans un fichier app/code/community/Owebia/Shipping2/changelog plut�t que dans les fichiers de langue
36
+ - L'�diteur compresse/d�compresse la configuration (si la compression est activ�e)
37
+ Am�lioration du debug
38
+ - Ajout des versions de PHP et de Magento
39
+ - Correction du chemin du fichier OwebiaShippingHelper.php
40
+ - Affichage du debug par la commande Mage::getSingleton('core/session')->addNotice() afin d'avoir un affichage plus propre (� l'int�rieur des balises html)
41
+ - Affichage du debug seulement sur la page checkout/cart/index
42
+ Cr�ation d'un fichier app/code/community/Owebia/Shipping2/etc/adminhtml.xml (pour r�soudre les probl�mes d'acc�s � la section de configuration Owebia)
43
+ Mise � jour des tarifs par d�faut avec les tarifs Colissimo Particuliers 2010 et Chronopost web 2010
44
+
45
+ [2.3.7 - 11 janvier 2011]
46
+ Modification de la r�cup�ration du timestamp courant en tenant compte du fuseau horaire s�lectionn�
47
+ Modification du CSS de l'�diteur pour palier � une modification du CSS du backoffice (sur les balises legend)
48
+ Ajout de contr�les isset dans le fichier app/code/community/Owebia/Shipping2/controllersAjaxController.php (merci � Damien C.)
49
+ �chappement des guillemets doubles dans la m�thode _getConfig() dans le fichier js/owebia/shipping2/os2editor.js (merci � Damien C.)
50
+ Ajout de la m�thode getRates() dans la classe Owebia_Shipping2_Model_Carrier_AbstractOwebiaShipping qui permet de r�cup�rer les frais de port en injectant les donn�es que l'on souhaite en param�tre
51
+ R��criture de la m�thode collectRates()
52
+
53
+ [2.3.6 - 23 novembre 2010]
54
+ Ajout d'un fichier app/etc/modules/Owebia_Shipping_2.xml vide pour �craser celui des versions pr�c�dentes � la 2.3.0 afin d'�viter une cohabitation de deux versions
55
+ Am�lioration du traitement des commentaires avec l'�diteur (gestion des caract�res #)
56
+
57
+ [2.3.5 - 08 novembre 2010]
58
+ Correction d'un probl�me chez les utilisateurs ayant une version de PHP ant�rieure � 5.3.0
59
+
60
+ [2.3.4 - 06 novembre 2010]
61
+ Correction d'un bug introduit dans la version 2.3.2 lors de l'utilisation des attributs et options avec les fonctions sum, count et count distinct
62
+
63
+ [2.3.3 - 05 novembre 2010]
64
+ Possibilit� de faire des copie de propri�t�s de fa�on r�cursive avec contr�le de boucle infinie
65
+
66
+ [2.3.2 - 05 novembre 2010]
67
+ Am�lioration de l'�diteur :
68
+ - Ajout de l'aide en langue anglais
69
+ - Ajout d'informations dans l'aide
70
+ - Ajout des messages d'erreur de la configuration, avec possibilit� de correction rapide
71
+ - Ajout de champs pour les lignes ignor�es : on peut ainsi les modifier et appliquer les modifications
72
+ Ajout de la possibilit� d'acc�der aux informations sur le stock d'un produit gr�ce aux variables {product.stock.is_in_stock} et {product.stock.quantity}
73
+ Suppression de l'affichage du message d'erreur ""Correspondance non trouv�e""
74
+ Correction d'un bug avec les groupes utilisateur ($id==null retournait true lorsque $id �tait �gal � 0)
75
+ Correction d'une erreur de r�cup�ration de l'unit� de poids
76
+ Am�liorations diverses
77
+
78
+ [2.3.1 - 29 octobre 2010]
79
+ Correction d'un bug dans le fichier AjaxController : une variable n'�tait pas d�finie, ce qui g�n�rait une erreur avec certaines configurations PHP
80
+
81
+ [2.3.0 - 28 octobre 2010]
82
+ Correction d'un bug avec le caract�re * dans les champs ""destination"" et ""origin"" comme jocker
83
+ Ajout d'un �diteur pour faciliter la modification des configurations Owebia Shipping
84
+ L'�diteur contient �galement une aide
85
+ D�placement de certains fichiers pour mieux correspondre � la structure de Magento
86
+
87
+ [2.2.8 - 20 octobre 2010]
88
+ Correction d'une erreur dans l'include d'OwebiaShippingHelper lorsqu'on utilise le Compiler
89
+ Correction d'un bug de calcul du prix TTC dans certains cas ('row_total_with_discount' est �gal � 0)
90
+ Ajout de la possibilit� d'utiliser le caract�re * dans les champs ""destination"" et ""origin"" comme jocker (par exemple ""FR(25*)"" retournera vrai pour tous les codes postaux du d�partement du Doubs)
91
+ Ajout d'un bouton pour fermer la console de debug
92
+ Ajout d'informations dans le debug (tests sur la destination et l'origine, liste des variables pass�es en param�tre)
93
+ Affichage du debug uniquement sur la page panier (pas sur les pages en ajax)
94
+ R�cup�ration du bon customer group lors d'une commande cr��e depuis le backoffice de Magento
95
+
96
+ [2.2.7 - 27 ao�t 2010]
97
+ Possibilit� d'utiliser les variables personnalis�es (custom variables) de Magento gr�ce � la syntaxe {customvar.my_var} ou � la syntaxe standard {{customVar code=my_var}}
98
+
99
+ [2.2.6 - 25 ao�t 2010]
100
+ Correction d'un bug avec la fonction getRowProperty() : utilisation de preg_match_all() � la place de while(preg_match()) et utilisation de continue � la place de break
101
+
102
+ [2.2.5 - 22 ao�t 2010]
103
+ Correction d'un bug avec les propri�t�s de type bool�enne sp�cifi�es sans les guillemets (comme la propri�t� enabled)
104
+ Correction d'un bug avec la propri�t� customer_groups
105
+
106
+ [2.2.4 - 10 ao�t 2010]
107
+ Utilisation de Mage::getModel('directory/country')->load($country_code)->getName() � la place de Mage::getModel('core/locale')->getLocale()->getTranslationList('territory',null,2) pour r�cup�rer le nom d'un pays dans la langue courante (la premi�re solution semble retourner le nom du pays dans la langue principale de la boutique), merci � coolshop pour la solution propos�e
108
+ Remplacement de la valeur de configuration ""Afficher quand indisponible"" par la valeur ""Debug"" car la solution pr�c�dente posait des probl�mes avec Magento 1.4.0
109
+ Am�lioration de la clart� du debug (utilisation de couleurs et d'indentations)
110
+ Correction de bugs l�gers
111
+ Mise � jour de la syntaxe de la configuration propos�e par d�faut
112
+
113
+ [2.2.3 - 29 juillet 2010]
114
+ Correction d'un bug avec le traitement de formules dont le r�sultat est false
115
+
116
+ [2.2.2 - 29 juillet 2010]
117
+ Am�lioration du syst�me de cache des formules
118
+
119
+ [2.2.1 - 27 juillet 2010]
120
+ Correction de petits bugs
121
+
122
+ [2.2.0 - 22 juillet 2010]
123
+ Possibilit� de compression/d�compression de la configuration
124
+ Modification de certaines propri�t�s ({weight} => {cart.weight}, {price_excluding_tax} => {cart.price_excluding_tax}, {price_including_tax} => {cart.price_including_tax}, {products_quantity} => {cart.quantity},{contry} => {destination.country.name})
125
+ Syntaxe l�g�rement modifi� pour {product.attribute.xxx} et {product.option.xxx} (pas de s)
126
+ Ajout de nouvelles propri�t�s utilisables dans le foreach : {selection.weight}, {selection.quantity}, {product.weight}, {product.quantity}
127
+ Possibilit� d'utiliser {product.attribute.xxx} et {product.option.xxx} dans le foreach
128
+
129
+ [2.1.9 - 20 juillet 2010]
130
+ �valuation des formules contenues dans les propri�t�s ""label"" et ""description""
131
+
132
+ [2.1.8 - 20 juillet 2010]
133
+ Correction d'une erreur dans le foreach (l'attribut �tait toujours ""name"")
134
+
135
+ [2.1.7 - 19 juillet 2010]
136
+ Ajout de la syntaxe foreach product.attribute.xxx
137
+
138
+ [2.1.6 - 28 d�cembre 2009]
139
+ Correction d'une erreur dans le nom d'une variable qui entrainait un plantage dans certaines situations
140
+
141
+ [2.1.5 - 28 d�cembre 2009]
142
+ Modification de la syntaxe des tables (pour offrir plus de souplesse)
143
+
144
+ [2.1.4 - 24 d�cembre 2009]
145
+ Modification de la syntaxe d'utilisation des propri�t�s des produits (pour offrir beaucoup plus de souplesse)
146
+ Possibilit� de filtrer les produits dont on veut utiliser les propri�t�s.
147
+ Ajout de 'COUNT DISTINCT'
148
+
149
+ [2.1.3 - 17 d�cembre 2009]
150
+ Correction du calcul du nombre de produits dont les propri�t�s correspondent ""{count ..."" : prise en compte de la quantit�
151
+ Simplification de la syntaxe de copie de propri�t�
152
+
153
+ [2.1.2 - 27 novembre 2009]
154
+ Correction d'un probl�me de priorit� entre l'op�rateur ""="" et l'op�rateur ""and"" dans l'�valuation des formules : ajout de parenth�ses autour de la formule
155
+
156
+ [2.1.1 - 26 novembre 2009]
157
+ Suppression de la propri�t� 'product_properties' qui doit �tre utilis�e dans la propri�t� 'conditions'
158
+ Am�liorations diverses
159
+
160
+ [2.1.0 - 24 novembre 2009]
161
+ Regroupement des propri�t�s 'fees_table', 'fees_formula' et 'fixed_fees' dans une unique propri�t� 'fees'
162
+ Regroupement des propri�t�s 'prices_range' et 'weights_range' dans une unique propri�t� 'conditions'
163
+ Suppression de la propri�t� 'reference_value'
164
+ Suppression des propri�t�s 'free_shipping__fees_table', 'free_shipping__fees_formula' et 'free_shipping__fixed_fees' (utiliser '{free_shipping}' dans la propri�t� 'conditions' � la place)
165
+ Ajout d'un analyseur de syntaxe de la configuration pour indiquer l'utilisation de propri�t�s non reconnues ou de propri�t�s obsol�tes, les valeurs non reconnues, les virgules manquantes en fin de ligne, les doublons des propri�t�s 'code'
166
+ Utilisation des valeurs des propri�t�s obsol�tes dans leur nouvel �quivalent
167
+ Possibilit� de copier une propri�t� avec la syntaxe ""{copy 'colissimo'.'fees'}""
168
+ Nouvelle syntaxe pour les tables (ancienne propri�t� 'fees_table') : ""{table 'weight' 1.0:2.50, 2.0:3.00}"" qui peuvent d�sormais �tre int�gr�es dans des formules
169
+ S�paration des m�thodes publique, priv�es g�n�riques (pr�fixe '_'), priv�es sp�cifiques � Magento (pr�fixe '__') pour faciliter le portage du module vers un autre syst�me de boutique en ligne que Magento
170
+
171
+ [2.0.12 - 19 novembre 2009]
172
+ Am�lioration de la transmission des variables entre les m�thodes de la classe
173
+
174
+ [2.0.11 - 19 novembre 2009]
175
+ Correction du filtrage en fonction des options et des attributs des produits en pr�sence de produits configurables
176
+
177
+ [2.0.10 - 13 novembre 2009]
178
+ Am�lioration du filtrage en fonction des options et des attributs des produits
179
+ Correction du filtrage en fonction des options des produits
180
+
181
+ [2.0.9 - 12 novembre 2009]
182
+ Correction du filtrage en fonction des options des produits
183
+
184
+ [2.0.8 - 12 novembre 2009]
185
+ Possibilit� de filtrer en fonction des options des produits
186
+
187
+ [2.0.7 - 04 novembre 2009]
188
+ Possibilit� de filtrer en fonction de l'origine de livraison
189
+ Possibilit� de filtrer en fonction des attributs de produits
190
+ Possibilit� de sp�cifier un code postal dans le filtrage de la destination
191
+ Compatibilit� avec Magento 1.4.* : utilisation de la fonction getTranslationList au lieu de getCountryTranslationList qui est d�pr�ci�e
192
+
193
+ [2.0.6 - 02 octobre 2009]
194
+ Possibilit� de sp�cifier des groupes de clients
195
+
196
+ [2.0.5 - 18 ao�t 2009]
197
+ Ajout de la possibilit� de sp�cifier dans la destination le monde entier sauf certains pays
198
+ Correction d'un probl�me de parsing de la destination lorsqu'il n'y avait qu'un seul code r�gion entre parenth�ses
199
+ Possibilit� d'avoir des codes r�gion comprenant des espaces
200
+
201
+ [2.0.4 - 28 juillet 2009]
202
+ Suppression des options ""Unit� de poids"" et ""Utiliser le montant TTC"" de chaque mode de livraison
203
+ Possibilit� d'inclure ou d'exclure les valeurs limites dans les champs 'prices_range', 'weights_range' et 'fees_table' gr�ce aux caract�res '[' et ']'
204
+ Possibilit� de sp�cifier dans les champs 'prices_range' et 'fees_table' si on utilise le montant HT ou TTC
205
+ Ajout du champ 'enabled' et suppression de la possibilit� de d�sactiver un bloc de configuration avec le caract�re '#'
206
+ Modification du message d'erreur par d�faut
207
+ Ajout d'un message d'erreur en cas d'erreur d'interpr�tation d'une formule de calcul de frais
208
+
209
+ [2.0.3 - 27 juillet 2009]
210
+ Correction d'une erreur dans l'interpr�tation des formules avec des fonctions � arguments multiples (min, max, rand)
211
+
212
+ [2.0.2 - 27 juin 2009]
213
+ Correction d'une erreur d'expression r�guli�re
214
+
215
+ [2.0.1 - 25 juin 2009]
216
+ Uniformisation du nom des variables dans les valeurs de r�f�rence : 'price_excluding_tax' et 'price_including_tax' � la place de la valeur 'price'
217
+ Correction d'un probl�me de Magento qui ne semble pas retourner la bonne valeur lors de l'appel � la m�thode $request->getFreeShipping()
218
+ Ajout du champ 'description' qui permet d'ajouter une description � une m�thode de livraison qui peut �tre r�cup�r�e gr�ce � la m�thode $_rate->getMethodDescription()
219
+ Corrections de bugs
220
+
221
+ [2.0 - 3 avril 2009]
222
+ Cr�ation de la version 2.0 du module Owebia Shipping qui n'est plus compatible avec les anciennes versions
223
+
app/code/community/Owebia/Shipping2/controllers/AjaxController.php ADDED
@@ -0,0 +1,469 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Magento Owebia Shipping2 Module
5
+ *
6
+ * NOTICE OF LICENSE
7
+ *
8
+ * This source file is subject to the Open Software License (OSL 3.0)
9
+ * that is bundled with this package in the file LICENSE.txt.
10
+ * It is also available through the world-wide-web at this URL:
11
+ * http://opensource.org/licenses/osl-3.0.php
12
+ * If you did not receive a copy of the license and are unable to
13
+ * obtain it through the world-wide-web, please send an email
14
+ * to license@magentocommerce.com so we can send you a copy immediately.
15
+ *
16
+ * @category Owebia
17
+ * @package Owebia_Shipping2
18
+ * @copyright Copyright (c) 2008-10 Owebia (http://www.owebia.com/)
19
+ * @author Antoine Lemoine
20
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
21
+ */
22
+
23
+ class Owebia_Shipping2_AjaxController extends Owebia_Shipping2_Controller_Abstract
24
+ {
25
+ private function getPropertyHelper($row_id, $property_key, $property) {
26
+ $cleaned_property = $this->cleanKey($property_key);
27
+ $prefix = "r-".$row_id."-p-".$cleaned_property;
28
+ $value = isset($property['original_value']) ? $property['original_value'] : (isset($property['value']) ? $property['value'] : '');
29
+
30
+ switch ($property_key) {
31
+ case 'enabled':
32
+ $enabled = $value!==false;
33
+ return "<p><select id=\"".$prefix."\" class=\"field\">"
34
+ ."<option value=\"0\"".($enabled ? '' : ' selected="selected"').">".$this->__('Disabled')."</option>"
35
+ ."<option value=\"1\"".($enabled ? ' selected="selected"' : '').">".$this->__('Enabled')."</option>"
36
+ ."</select><p>";
37
+ break;
38
+ case 'label':
39
+ case 'description':
40
+ return "<textarea id=\"".$prefix."\" class=\"field\">".$value."</textarea>"
41
+ ."<fieldset class=\"buttons-set\"><legend>".$this->__('Insert')."</legend>"
42
+ ."<p>"
43
+ .$this->button('Destination country',"os2editor.insertAtCaret(this,'{destination.country.name}');")
44
+ .$this->button('Cart weight',"os2editor.insertAtCaret(this,'{cart.weight}');")
45
+ .$this->button('Cart quantity',"os2editor.insertAtCaret(this,'{cart.quantity}');")
46
+ .$this->button('Price including tax',"os2editor.insertAtCaret(this,'{cart.price_including_tax}');")
47
+ .$this->button('Price excluding tax',"os2editor.insertAtCaret(this,'{cart.price_excluding_tax}');")
48
+ ."</p>"
49
+ ."</fieldset>";
50
+ break;
51
+ case 'fees':
52
+ return "<textarea id=\"".$prefix."\" class=\"field\">".$value."</textarea>"
53
+ ."<fieldset class=\"buttons-set\"><legend>".$this->__('Insert')."</legend>"
54
+ ."<p><span class=\"buttons-set-label\">".$this->__('Cart')."</span>"
55
+ .$this->button('Weight',"os2editor.insertAtCaret(this,'{cart.weight}');")
56
+ .$this->button('Products quantity',"os2editor.insertAtCaret(this,'{cart.quantity}');")
57
+ .$this->button('Price including tax',"os2editor.insertAtCaret(this,'{cart.price_including_tax}');")
58
+ .$this->button('Price excluding tax',"os2editor.insertAtCaret(this,'{cart.price_excluding_tax}');")
59
+ ."</p>"
60
+ ."<p><span class=\"buttons-set-label\">".$this->__('Selection')."</span>"
61
+ .$this->button('Weight',"os2editor.insertAtCaret(this,'{selection.weight}');")
62
+ .$this->button('Products quantity',"os2editor.insertAtCaret(this,'{selection.quantity}');")
63
+ ."</p>"
64
+ ."<p><span class=\"buttons-set-label\">".$this->__('Product')."</span>"
65
+ .$this->button('Weight',"os2editor.insertAtCaret(this,'{product.weight}');")
66
+ .$this->button('Quantity',"os2editor.insertAtCaret(this,'{product.quantity}');")
67
+ ."</p>"
68
+ ."</fieldset>";
69
+ break;
70
+ case 'conditions':
71
+ return "<textarea id=\"".$prefix."\" class=\"field\">".$value."</textarea>"
72
+ ."<fieldset class=\"buttons-set\"><legend>".$this->__('Insert')."</legend>"
73
+ ."<p><span class=\"buttons-set-label\">".$this->__('Cart')."</span>"
74
+ .$this->button('Weight',"os2editor.insertAtCaret(this,'{cart.weight}');")
75
+ .$this->button('Products quantity',"os2editor.insertAtCaret(this,'{cart.quantity}');")
76
+ .$this->button('Price including tax',"os2editor.insertAtCaret(this,'{cart.price_including_tax}');")
77
+ .$this->button('Price excluding tax',"os2editor.insertAtCaret(this,'{cart.price_excluding_tax}');")
78
+ ."</p>"
79
+ ."</fieldset>";
80
+ break;
81
+ case 'customer_groups':
82
+ $groups = CustomerGroup::getCustomerGroups();
83
+ $output = '';
84
+ foreach ($groups as $group) {
85
+ $output .= $this->untranslated_button(htmlentities($group->getCode()),"os2editor.insertAtCaret(this,'".$this->jsEscape($group->getId())."');");
86
+ }
87
+ return "<textarea id=\"".$prefix."\" class=\"field\">".$value."</textarea>"
88
+ ."<fieldset class=\"buttons-set\"><legend>".$this->__('Display')."</legend>"
89
+ ."<p>"
90
+ .$this->button('Display original input',"os2editor.updatePropertyValue('original-value',this,false);")
91
+ .$this->button('Display names',"os2editor.updatePropertyValue('full-value',this,false);")
92
+ .$this->button('Display identifiers',"os2editor.updatePropertyValue('compact-value',this,true);")
93
+ ."</p>"
94
+ ."</fieldset>"
95
+ ."<fieldset class=\"buttons-set\"><legend>".$this->__('Insert')."</legend>"
96
+ ."<p>"
97
+ //.$this->button('Not logged in',"os2editor.insertAtCaret(this,'NOT LOGGED IN');")
98
+ .$output
99
+ ."</p>"
100
+ ."</fieldset>"
101
+ ."<fieldset class=\"buttons-set\"><legend>".$this->__('Preview')."</legend>"
102
+ ."<div class=\"preview-items-list customer-group-list\">".$this->getCustomerGroupsPreview($value)."</div>"
103
+ ."</fieldset>"
104
+ ;
105
+ break;
106
+ case 'tracking_url':
107
+ return "<textarea id=\"".$prefix."\" class=\"field\">".$value."</textarea>"
108
+ ."<fieldset class=\"buttons-set\"><legend>".$this->__('Insert')."</legend>"
109
+ ."<p>"
110
+ .$this->button('Tracking number',"os2editor.insertAtCaret(this,'{tracking_number}');")
111
+ ."</p>"
112
+ ."</fieldset>";
113
+ break;
114
+ case 'destination':
115
+ case 'origin':
116
+ $parsed_value = $this->parseAddressFilter($value);
117
+ $excluding = $parsed_value['excluding'];
118
+ return "<div class=\"address-filters-property\"><p>"
119
+ ."<input type=\"radio\" class=\"excluding\" id=\"".$prefix."-exluding-0\" name=\"".$prefix."-exluding\""
120
+ ." value=\"0\"".(!$excluding ? " checked=\"checked\"" : '')." onclick=\"os2editor.updateAddressFilterPreview(this);\"/>"
121
+ ."<label for=\"".$prefix."-exluding-0\"> ".$this->__('Limit to')."</label> &nbsp; "
122
+ ."<input type=\"radio\" class=\"excluding\" id=\"".$prefix."-exluding-1\" name=\"".$prefix."-exluding\""
123
+ ." value=\"1\"".($excluding ? " checked=\"checked\"" : '')." onclick=\"os2editor.updateAddressFilterPreview(this);\"/>"
124
+ ."<label for=\"".$prefix."-exluding-1\"> ".$this->__('Exclude')."</label></p>"
125
+ ."<textarea id=\"".$prefix."\" class=\"field\">".$value."</textarea>"
126
+ ."<fieldset class=\"buttons-set\"><legend>".$this->__('Display')."</legend>"
127
+ ."<p>"
128
+ .$this->button('Display original input',"os2editor.updatePropertyValue('original-value',this,false);")
129
+ .$this->button('Display corrected names',"os2editor.updatePropertyValue('full-value',this,false);")
130
+ .$this->button('Display codes',"os2editor.updatePropertyValue('compact-value',this,true);")
131
+ ."</p>"
132
+ ."</fieldset>"
133
+ ."<fieldset class=\"buttons-set\"><legend>".$this->__('Preview')."</legend>"
134
+ ."<div class=\"preview-items-list address-filter-list\">".$this->getAddressFiltersPreview($parsed_value)."</div>"
135
+ ."</fieldset>"
136
+ ."</div>"
137
+ ;
138
+ break;
139
+ case '*comment' :
140
+ $lines = explode("\n",trim($value));
141
+ for ($i=0; $i<count($lines); $i++) {
142
+ $lines[$i] = preg_replace('/^# ?/','',$lines[$i]);
143
+ }
144
+ $value = implode("\n",$lines);
145
+ return "<textarea id=\"".$prefix."\" class=\"field\">".$value."</textarea>";
146
+ default :
147
+ return "<textarea id=\"".$prefix."\" class=\"field\">".$value."</textarea>";
148
+ }
149
+ }
150
+
151
+ private function getCustomerGroupsPreview($input) {
152
+ if (trim($input)=='') return '';
153
+ $elems = explode(',',$input);
154
+ $customer_groups = array();
155
+ foreach ($elems as $elem) {
156
+ $customer_groups[] = new CustomerGroup($elem);
157
+ }
158
+ return implode('',$customer_groups);
159
+ }
160
+
161
+ private function getAddressFiltersPreview($data) {
162
+ $address_filters = array();
163
+ foreach ($data['countries'] as $country) {
164
+ $address_filters[] = new AddressFilter($country);
165
+ }
166
+ return implode('',$address_filters);
167
+ }
168
+
169
+ private function parseAddressFilter($address_filter) {
170
+ $output = array(
171
+ 'excluding' => false,
172
+ 'countries' => array(),
173
+ 'original' => $address_filter,
174
+ );
175
+
176
+ $address_filter = str_replace(
177
+ array('\(', '\)', '\,'),
178
+ array('__opening_parenthesis__', '__closing_parenthesis__', '__comma__'),
179
+ $address_filter
180
+ );
181
+ $address_filter = str_replace(array("\r\n","\r","\n"),array(',',',',','),$address_filter);
182
+
183
+ if (preg_match('# *\* *- *\((.*)\) *#s',$address_filter,$result)) {
184
+ $address_filter = $result[1];
185
+ $output['excluding'] = true;
186
+ }
187
+
188
+ $tmp_address_filter_array = explode(',',trim($address_filter));
189
+
190
+ $concat = false;
191
+ $concatened = '';
192
+ $address_filter_array = array();
193
+ $i = 0;
194
+
195
+ foreach ($tmp_address_filter_array as $address_filter) {
196
+ if ($concat) $concatened .= ','.$address_filter;
197
+ else {
198
+ if ($i<count($tmp_address_filter_array)-1 && preg_match('#\(#',$address_filter)) {
199
+ $concat = true;
200
+ $concatened .= $address_filter;
201
+ } else $address_filter_array[] = $address_filter;
202
+ }
203
+ if (preg_match('#\)#',$address_filter)) {
204
+ $address_filter_array[] = $concatened;
205
+ $concatened = '';
206
+ $concat = false;
207
+ }
208
+ $i++;
209
+ }
210
+
211
+ foreach ($address_filter_array as $address_filter) {
212
+ $address_filter = trim($address_filter);
213
+ $original_address_filter = str_replace(
214
+ array('__opening_parenthesis__', '__closing_parenthesis__', '__comma__'),
215
+ array('\(', '\)', '\,'),
216
+ $address_filter
217
+ );
218
+ if (trim($address_filter)!='') {
219
+ if (preg_match('# *([^,(]+) *(-)? *(?:\( *(-)? *(.*)\))? *#s', $address_filter,$result)) {
220
+ $country_code = $result[1];
221
+
222
+ $region_codes = isset($result[4]) ? explode(',',$result[4]) : array();
223
+ $in_array = false;
224
+ for ($i=count($region_codes); --$i>=0;) {
225
+ $code = trim(str_replace(
226
+ array('__opening_parenthesis__', '__closing_parenthesis__', '__comma__'),
227
+ array('\(', '\)', '\,'),
228
+ $region_codes[$i]
229
+ ));
230
+ $region_codes[$i] = $code;
231
+ }
232
+ /*$in_array = in_array($address['region_code'],$region_codes,true) || in_array($address['postcode'],$region_codes,true);*/
233
+ $excluding_region = isset($result[2]) && $result[2]=='-' || isset($result[3]) && $result[3]=='-';
234
+ $output['countries'][] = array(
235
+ 'excluding' => $excluding_region,
236
+ 'country_code' => $country_code,
237
+ 'region_codes' => implode(',',$region_codes),
238
+ 'original' => $original_address_filter,
239
+ );
240
+ } else {
241
+ $output['countries'][] = array(
242
+ 'excluding' => null,
243
+ 'country_code' => $original_address_filter,
244
+ 'region_codes' => null,
245
+ 'original' => $original_address_filter,
246
+ );
247
+ }
248
+ }
249
+ }
250
+ return $output;
251
+ }
252
+
253
+ private function getRowUI(&$row, $selected) {
254
+ $row['_ID_']['value'] = isset($row['_ID_']['value']) ? $row['_ID_']['value'] : uniqid('c');
255
+ $row_id = $row['_ID_']['value'];
256
+
257
+ if (isset($row['lines'])) {
258
+ $output = "<div id=\"r-".$row_id."-container\" class=\"row-container has-error ignored-lines".($selected ? ' selected' : '')."\">"
259
+ ."<div class=\"row-header\" onclick=\"os2editor.selectRow('".$row_id."');\">"
260
+ ."<div class=\"row-actions\">"
261
+ .$this->button('Apply changes',"os2editor.applyChanges();")
262
+ .$this->button('Delete',"os2editor.removeRow(this);",'delete')
263
+ ."</div>"
264
+ ."<div class=\"row-title\">".$this->__('Ignored lines')."</div></div>"
265
+ ."<div class=\"properties-container\"><textarea class=\"field\">".$row['lines']."</textarea></div></div>";
266
+ return $output;
267
+ }
268
+
269
+ if (!isset($row['label'])) {
270
+ $row['label']['value'] = $this->__('New shipping method');
271
+ }
272
+
273
+ $properties = array(
274
+ 'enabled' => 'Enabled',
275
+ 'code' => 'Code',
276
+ 'label' => 'Label',
277
+ 'description' => 'Description',
278
+ 'destination' => 'Destination',
279
+ 'origin' => 'Origin',
280
+ 'conditions' => 'Conditions',
281
+ 'fees' => 'Fees',
282
+ 'customer_groups' => 'Customer groups',
283
+ 'tracking_url' => 'Tracking url',
284
+ '*comment' => 'Comment',
285
+ );
286
+
287
+ $label = $row['label']['value'];
288
+ $output = "<div id=\"r-".$row_id."-container\" class=\"row-container".($selected ? ' selected' : '')."\">"
289
+ ."<div class=\"row-header\" onclick=\"os2editor.selectRow('".$row_id."');\">"
290
+ ."<div class=\"row-actions\">".$this->button('Delete',"os2editor.removeRow(this);",'delete')."</div><div class=\"row-title\">".$label."</div></div>"
291
+ ."<div class=\"properties-container\">";
292
+ $list = "<ul class=\"properties-list\">";
293
+ $j = 0;
294
+ foreach ($properties as $property_key => $label) {
295
+ $cleaned_property = $this->cleanKey($property_key);
296
+ $value = isset($row[$property_key]) ? trim($row[$property_key]['value']) : '';
297
+ $list .= "<li id=\"r-".$row_id."-p-".$cleaned_property."-item\" class=\"property-item".($j==0 ? ' selected' : '')
298
+ .($value==='' ? ' empty' : '')
299
+ ."\" onclick=\"os2editor.selectProperty('".$row_id."','".$cleaned_property."');\">".$this->__($label)."</li>";
300
+ $output .= "<div id=\"r-".$row_id."-p-".$cleaned_property."-container\" class=\"property-container"
301
+ .($j==0 ? ' selected' : '')."\" property-name=\"".$property_key."\">"
302
+ ."<div class=\"buttons-set\" style=\"text-align:right;\">".$this->button('Help',"os2editor.help('property.".$property_key."');",'help')."</div>"
303
+ .$this->getPropertyHelper($row_id,$property_key,isset($row[$property_key]) ? $row[$property_key] : array())."</div>";
304
+ $j++;
305
+ }
306
+ foreach ($row as $property_key => $property) {
307
+ if (!isset($properties[$property_key]) && substr($property_key,0,1)!='*') {
308
+ $label = $property_key;
309
+ $cleaned_property = $this->cleanKey($property_key);
310
+ $value = isset($row[$property_key]) ? trim($row[$property_key]['value']) : '';
311
+ $list .= "<li id=\"r-".$row_id."-p-".$cleaned_property."-item\" class=\"property-item".($j==0 ? ' selected' : '')
312
+ .(empty($value) ? ' empty' : '').($cleaned_property=='_ID_' ? ' hide' : '')
313
+ ."\" onclick=\"os2editor.selectProperty('".$row_id."','".$cleaned_property."');\">".$this->__($label)."</li>";
314
+ $output .= "<div id=\"r-".$row_id."-p-".$cleaned_property."-container\" class=\"property-container"
315
+ .($j==0 ? ' selected' : '')."\" property-name=\"".$property_key."\">"
316
+ ."<div class=\"buttons-set\" style=\"text-align:right;\">".$this->button('Help',"os2editor.help('property.".$property_key."');",'help')."</div>"
317
+ .$this->getPropertyHelper($row_id,$property_key,$property)."</div>";
318
+ $j++;
319
+ }
320
+ }
321
+ $output .= $list."</div></div>";
322
+ return $output;
323
+ }
324
+
325
+ private function getConfigErrors($config) {
326
+ $script = "os2editor.resetErrors();";
327
+ foreach ($config as $row_code => $row) {
328
+ if (isset($row['*messages'])) {
329
+ $error = '';
330
+ foreach ($row['*messages'] as $message) {
331
+ $error .= "<p>".$this->__($message)."</p>";
332
+ }
333
+ if ($error!='') $script .= "os2editor.setError('".$row['_ID_']['value']."','','".$this->jsEscape($error)."');";
334
+ }
335
+ foreach ($row as $property_key => $property) {
336
+ if (isset($property['messages']) && is_array($property['messages'])) {
337
+ $error = '';
338
+ foreach ($property['messages'] as $message) {
339
+ $error .= "<p>".$this->__($message)."</p>";
340
+ }
341
+ if ($error!='') {
342
+ $script .= "os2editor.setError('".$row['_ID_']['value']."','".$property_key."','"
343
+ .$this->jsEscape($error
344
+ .($property['value']!=$property['original_value'] ?
345
+ "<p>"
346
+ .$this->button('Correct',"os2editor.correct('".$row['_ID_']['value']."','".$property_key."','".$this->jsEscape($property['value'])."');")
347
+ ."</p>" : '')
348
+ )."');";
349
+ }
350
+ }
351
+ }
352
+ }
353
+ //$script .= "alert('".str_replace(array("\r\n","\n","\'","'"),array(" "," ","\\\'","\'"),$script)."');";
354
+ return $script;
355
+ }
356
+
357
+ private function loadConfig($input) {
358
+ include_once $this->getModulePath('includes/OwebiaShippingHelper.php');
359
+
360
+ $helper = new OwebiaShippingHelper($input);
361
+ $helper->checkConfig();
362
+ $config = $helper->getConfig();
363
+ //print_r($config);
364
+
365
+ $output = "<div class=\"buttons-set\">"
366
+ .$this->button('Add a shipping method',"os2editor.addRow();",'add')
367
+ ."</div><div class=\"config-container\">";
368
+ $i = 0;
369
+ foreach ($config as &$row) {
370
+ $output .= $this->getRowUI($row,$i==0);
371
+ $i++;
372
+ }
373
+ $output .= "</div><script type=\"text/javascript\">".$this->getConfigErrors($config)."</script>";
374
+ return $output;
375
+ }
376
+
377
+ public function indexAction() {
378
+ header('Content-Type: text/html; charset=UTF-8');
379
+
380
+ include_once $this->getModulePath('includes/OS2_AddressFilter.php');
381
+ include_once $this->getModulePath('includes/OS2_CustomerGroup.php');
382
+
383
+ switch ($_POST['what']) {
384
+ case 'open':
385
+ $output = ""
386
+ // Donate page
387
+ .$this->page('donate',"Support the development of Owebia Shipping 2 extension",$this->__('{os2editor.donate-page.content}'))
388
+ // Help page
389
+ .$this->page('help',"Owebia Shipping 2 extension help",'')
390
+ // Main page
391
+ .$this->pageHeader("Owebia Shipping 2 configuration editor",
392
+ $this->button('Save',"os2editor.save();",'save')
393
+ .$this->button('Export',"os2editor.saveToFile();",'')
394
+ .$this->button('Load',"os2editor.showConfigLoader();",'')
395
+ .$this->button('Close',"os2editor.close();",'cancel')
396
+ )
397
+ ."<div id=\"os2-editor-config-loader\">"
398
+ ."<textarea></textarea>"
399
+ ."<div class=\"buttons-set\">"
400
+ .$this->button('Load',"os2editor.loadConfig();",'')
401
+ .$this->button('Cancel',"os2editor.hideConfigLoader();",'cancel')
402
+ ."</div>"
403
+ ."</div>"
404
+ ."<div id=\"os2-editor-config-container\">".$this->loadConfig($_POST['input'])."</div>"
405
+ ."<div class=\"donate-container\">"
406
+ ."<table cellspacing=\"0\"><tr>"
407
+ ."<td>".$this->__('You appreciate this extension and would like to help?')."</td>"
408
+ ."<td class=\"form-buttons\">"
409
+ .$this->button('Donate',"os2editor.openPage('donate');",'donate')
410
+ ."</td>"
411
+ ."</tr></table>"
412
+ ."</div>"
413
+ ;
414
+ echo $output;
415
+ exit;
416
+ case 'help':
417
+ $output = $this->__('{os2editor.help.'.$_POST['input'].'}');
418
+ if ($_POST['input']=='changelog') {
419
+ $changelog = @file_get_contents($this->getModulePath('changelog'));
420
+ $output = str_replace('{changelog}',mb_convert_encoding($changelog,'UTF-8','ISO-8859-1'),$output);
421
+ }
422
+ echo $output;
423
+ exit;
424
+ case 'add-row':
425
+ $row = array(); // Passage par r�f�rence
426
+ echo $this->getRowUI($row,true);
427
+ exit;
428
+ case 'load-config':
429
+ echo $this->loadConfig($_POST['config']);
430
+ exit;
431
+ case 'check-config':
432
+ include_once $this->getModulePath('includes/OwebiaShippingHelper.php');
433
+
434
+ $helper = new OwebiaShippingHelper($_POST['config']);
435
+ $helper->checkConfig();
436
+ //print_r($helper->getConfig(),$out);
437
+ //$script = "alert('".$this->jsEscape($_POST['config'])."');";
438
+ $script = $this->getConfigErrors($helper->getConfig());
439
+ //$script = "alert('".$this->jsEscape($this->getConfigErrors($helper->getConfig()))."');";
440
+ break;
441
+ case 'save-config':
442
+ include_once $this->getModulePath('includes/OwebiaShippingHelper.php');
443
+
444
+ $helper = new OwebiaShippingHelper($_POST['config']);
445
+ $compress = (bool)Mage::getStoreConfig('carriers/'.$_POST['shipping_code'].'/compression');
446
+ $output = $helper->formatConfig($compress,$keys_to_remove=array('_ID_'));
447
+ //Mage::getConfig()->saveConfig('carriers/'.$_POST['shipping_code'].'/config',$output);
448
+ echo $output;
449
+ exit;
450
+ case 'save-to-file':
451
+ include_once $this->getModulePath('includes/OwebiaShippingHelper.php');
452
+
453
+ $helper = new OwebiaShippingHelper(urldecode($_POST['config']));
454
+ $formatted_config = $helper->formatConfig(false,$keys_to_remove=array('_ID_'));
455
+ $this->forceDownload('owebia-shipping-config.txt',$formatted_config);
456
+ exit;
457
+ case 'get-address-filters':
458
+ $result = $this->parseAddressFilter($_POST['input']);
459
+ echo $this->getAddressFiltersPreview($result);
460
+ exit;
461
+ case 'get-customer-groups':
462
+ echo $this->getCustomerGroupsPreview($_POST['input']);
463
+ exit;
464
+ }
465
+
466
+ echo "<script type=\"text/javascript\">".$script."</script>";
467
+ exit;
468
+ }
469
+ }
app/code/community/Owebia/Shipping2/controllers/Checkout/CartController.php ADDED
@@ -0,0 +1,33 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ if (file_exists(dirname(__FILE__).'/Mage_Checkout_CartController.php')) include_once 'Mage_Checkout_CartController.php';
4
+ else include_once Mage::getBaseDir('code').'/core/Mage/Checkout/controllers/CartController.php';
5
+
6
+ class Owebia_Shipping2_Checkout_CartController extends Mage_Checkout_CartController
7
+ {
8
+ /**
9
+ * Initialize shipping information
10
+ */
11
+ public function estimatePostAction()
12
+ {
13
+ $country = (string) $this->getRequest()->getParam('country_id');
14
+ $postcode = (string) $this->getRequest()->getParam('estimate_postcode');
15
+ $city = (string) $this->getRequest()->getParam('estimate_city');
16
+ $regionId = (string) $this->getRequest()->getParam('region_id');
17
+ $region = (string) $this->getRequest()->getParam('region');
18
+
19
+ $this->_getQuote()->getShippingAddress()
20
+ ->setCountryId($country)
21
+ ->setCity($city)
22
+ ->setPostcode($postcode)
23
+ ->setRegionId($regionId)
24
+ ->setRegion($region)
25
+ ->setCollectShippingRates(true);
26
+
27
+ // Recalcul des totaux
28
+ $this->_getQuote()->collectTotals();
29
+
30
+ $this->_getQuote()->save();
31
+ $this->_goBack();
32
+ }
33
+ }
app/code/community/Owebia/Shipping2/etc/adminhtml.xml ADDED
@@ -0,0 +1,33 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0" ?>
2
+ <!-- Magento 1.4.0 and upper -->
3
+ <config>
4
+ <acl>
5
+ <resources>
6
+ <admin>
7
+ <children>
8
+ <system>
9
+ <children>
10
+ <config>
11
+ <children>
12
+ <owebia>
13
+ <title>Owebia Section</title>
14
+ <sort_order>100</sort_order>
15
+ </owebia>
16
+ </children>
17
+ </config>
18
+ </children>
19
+ </system>
20
+ </children>
21
+ </admin>
22
+ </resources>
23
+ </acl>
24
+ <translate>
25
+ <modules>
26
+ <Mage_Shipping>
27
+ <files>
28
+ <owebia-shipping2>Owebia_Shipping2.csv</owebia-shipping2>
29
+ </files>
30
+ </Mage_Shipping>
31
+ </modules>
32
+ </translate>
33
+ </config>
app/code/community/Owebia/Shipping2/etc/config.xml ADDED
@@ -0,0 +1,519 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <!--
3
+ /**
4
+ * Magento Owebia Shipping Module
5
+ *
6
+ * NOTICE OF LICENSE
7
+ *
8
+ * This source file is subject to the Open Software License (OSL 3.0)
9
+ * that is bundled with this package in the file LICENSE.txt.
10
+ * It is also available through the world-wide-web at this URL:
11
+ * http://opensource.org/licenses/osl-3.0.php
12
+ * If you did not receive a copy of the license and are unable to
13
+ * obtain it through the world-wide-web, please send an email
14
+ * to license@magentocommerce.com so we can send you a copy immediately.
15
+ *
16
+ * @category Owebia
17
+ * @package Owebia_Shipping
18
+ * @copyright Copyright (c) 2008-10 Owebia (http://www.owebia.com/)
19
+ * @author Antoine Lemoine
20
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
21
+ */
22
+ -->
23
+ <config>
24
+ <modules>
25
+ <Owebia_Shipping2>
26
+ <version>2.3.8</version>
27
+ <depends>
28
+ <Mage_Shipping />
29
+ </depends>
30
+ </Owebia_Shipping2>
31
+ </modules>
32
+
33
+ <global>
34
+ <models>
35
+ <owebia-shipping2>
36
+ <class>Owebia_Shipping2_Model</class>
37
+ </owebia-shipping2>
38
+ </models>
39
+ <blocks>
40
+ <owebia-shipping2>
41
+ <class>Owebia_Shipping2_Block</class>
42
+ </owebia-shipping2>
43
+ </blocks>
44
+
45
+ <!--
46
+ <helpers>
47
+ <owebia-shipping2>
48
+ <class>Owebia_Shipping2_Helper</class>
49
+ </owebia-shipping2>
50
+ </helpers>
51
+ -->
52
+
53
+ <resources>
54
+ <sales>
55
+ <shipping>
56
+ <carriers>
57
+ <owebiashipping1>
58
+ <class>Owebia_Shipping2_Model_Carrier_OwebiaShipping1</class>
59
+ </owebiashipping1>
60
+ <owebiashipping2>
61
+ <class>Owebia_Shipping2_Model_Carrier_OwebiaShipping2</class>
62
+ </owebiashipping2>
63
+ <owebiashipping3>
64
+ <class>Owebia_Shipping2_Model_Carrier_OwebiaShipping3</class>
65
+ </owebiashipping3>
66
+ </carriers>
67
+ </shipping>
68
+ </sales>
69
+ </resources>
70
+ </global>
71
+
72
+ <admin>
73
+ <routers>
74
+ <owebia-shipping2>
75
+ <use>admin</use>
76
+ <args>
77
+ <module>Owebia_Shipping2</module>
78
+ <frontName>owebia-shipping2</frontName>
79
+ </args>
80
+ </owebia-shipping2>
81
+ </routers>
82
+ </admin>
83
+ <adminhtml>
84
+ <!--
85
+ <menu>
86
+ <owebia translate="title" module="adminhtml">
87
+ <title>Owebia</title>
88
+ <sort_order>100</sort_order>
89
+ <children>
90
+ <owebiashipping2>
91
+ <title>Owebia Shipping 2</title>
92
+ <action>owebia-shipping2/index</action>
93
+ </owebiashipping2>
94
+ <ajax>
95
+ <title>Owebia Shipping 2 ajax</title>
96
+ <action>owebia-shipping2/ajax</action>
97
+ </ajax>
98
+ </children>
99
+ </owebia>
100
+ </menu>
101
+ -->
102
+ <!-- Magento lower than 1.4.0 -->
103
+ <acl>
104
+ <resources>
105
+ <admin>
106
+ <children>
107
+ <system>
108
+ <children>
109
+ <config>
110
+ <children>
111
+ <owebia>
112
+ <title>Owebia Section</title>
113
+ <sort_order>100</sort_order>
114
+ </owebia>
115
+ </children>
116
+ </config>
117
+ </children>
118
+ </system>
119
+ </children>
120
+ </admin>
121
+ </resources>
122
+ </acl>
123
+ <translate>
124
+ <modules>
125
+ <Mage_Shipping>
126
+ <files>
127
+ <owebia-shipping2>Owebia_Shipping2.csv</owebia-shipping2>
128
+ </files>
129
+ </Mage_Shipping>
130
+ </modules>
131
+ </translate>
132
+ </adminhtml>
133
+
134
+ <frontend>
135
+ <translate>
136
+ <modules>
137
+ <Mage_Shipping>
138
+ <files>
139
+ <owebia-shipping2>Owebia_Shipping2.csv</owebia-shipping2>
140
+ </files>
141
+ </Mage_Shipping>
142
+ </modules>
143
+ </translate>
144
+ <routers>
145
+ <checkout>
146
+ <args>
147
+ <modules>
148
+ <owebia-shipping2 before="Mage_Checkout">Owebia_Shipping2_Checkout</owebia-shipping2>
149
+ </modules>
150
+ </args>
151
+ </checkout>
152
+ </routers>
153
+ </frontend>
154
+
155
+ <default>
156
+ <owebia>
157
+ <shipping>
158
+ <weight_unit>kg</weight_unit>
159
+ </shipping>
160
+ </owebia>
161
+ <carriers>
162
+ <owebiashipping1>
163
+ <active>0</active>
164
+ <title>Colissimo / Chronopost / Export 3J</title>
165
+ <model>Owebia_Shipping2_Model_Carrier_OwebiaShipping1</model>
166
+ <tracking_view_url></tracking_view_url>
167
+ <config><![CDATA[
168
+ #####
169
+ # Colissimo
170
+ #
171
+ # Validité
172
+ # Tarifs du 1er mars 2010
173
+ # Crédits
174
+ # Configuration réalisée par owebia
175
+
176
+ # Colissimo National (France, Monaco, Andorre)
177
+ {
178
+ label: "Colissimo National",
179
+ code: "colissimo",
180
+ tracking_url: "http://www.coliposte.net/particulier/suivi_particulier.jsp?colispart={tracking_number}",
181
+ destination: "FR,MC,AD",
182
+ fees: "{table {cart.weight} in 0.5:5.55, 1.0:6.80, 2.0:7.75, 3.0:8.70, 5.0:10.60, 7.0:12.50, 10.0:15.35, 15.0:17.45, 30.0:23.75}",
183
+ }
184
+ # Colissimo National + Recommandé R1
185
+ {
186
+ label: "Colissimo National Recommandé R1",
187
+ code: "colissimo_r1",
188
+ tracking_url: "{colissimo.tracking_url}",
189
+ destination: "{colissimo.destination}",
190
+ conditions: "{cart.price_excluding_tax}<=50.00",
191
+ fees: "{table {cart.weight} in 0.5:7.85, 1.0:9.10, 2.0:10.05, 3.0:11.00, 5.0:12.90, 7.0:14.80, 10.0:17.65, 15.0:19.75, 30.0:26.05}",
192
+ }
193
+ # Colissimo National + Recommandé R2
194
+ {
195
+ label: "Colissimo National Recommandé R2",
196
+ code: "colissimo_r2",
197
+ tracking_url: "{colissimo.tracking_url}",
198
+ destination: "{colissimo.destination}",
199
+ conditions: "({cart.price_excluding_tax}>50.00) and ({cart.price_excluding_tax}<=200.00)",
200
+ fees: "{table {cart.weight} in 0.5:8.75, 1.0:10.00, 2.0:10.95, 3.0:11.90, 5.0:13.80, 7.0:15.70, 10.0:18.55, 15.0:20.65, 30.0:26.95}",
201
+ }
202
+ # Colissimo National + Recommandé R3
203
+ {
204
+ label: "Colissimo National Recommandé R3",
205
+ code: "colissimo_r3",
206
+ tracking_url: "{colissimo.tracking_url}",
207
+ destination: "{colissimo.destination}",
208
+ conditions: "({cart.price_excluding_tax}>200.00) and ({cart.price_excluding_tax}<=400.00)",
209
+ fees: "{table {cart.weight} in 0.5:9.95, 1.0:11.20, 2.0:12.15, 3.0:13.10, 5.0:15.00, 7.0:16.90, 10.0:19.75, 15.0:21.85, 30.0:28.15}",
210
+ }
211
+ # Colissimo National + Recommandé R4
212
+ {
213
+ label: "Colissimo National Recommandé R4",
214
+ code: "colissimo_r4",
215
+ tracking_url: "{colissimo.tracking_url}",
216
+ destination: "{colissimo.destination}",
217
+ conditions: "({cart.price_excluding_tax}>400.00) and ({cart.price_excluding_tax}<=600.00)",
218
+ fees: "{table {cart.weight} in 0.5:11.15, 1.0:12.40, 2.0:13.35, 3.0:14.30, 5.0:16.20, 7.0:18.10, 10.0:20.95, 15.0:23.05, 30.0:29.35}",
219
+ }
220
+ # Colissimo National + Recommandé R5
221
+ {
222
+ label: "Colissimo National Recommandé R5",
223
+ code: "colissimo_r5",
224
+ tracking_url: "{colissimo.tracking_url}",
225
+ destination: "{colissimo.destination}",
226
+ conditions: "{cart.price_excluding_tax}>600.00",
227
+ fees: "1.30+{table {cart.weight} in 0.5:12.35, 1.0:13.60, 2.0:14.55, 3.0:15.50, 5.0:17.40, 7.0:19.30, 10.0:22.15, 15.0:24.25, 30.0:30.55}",
228
+ }
229
+
230
+ # Colissimo National + Accusé réception
231
+ {
232
+ enabled: false,
233
+ label: "Colissimo National",
234
+ code: "colissimo_ar",
235
+ tracking_url: "{colissimo.tracking_url}",
236
+ destination: "{colissimo.destination}",
237
+ fees: "1.30+{colissimo.fees}",
238
+ }
239
+ # Colissimo National + Recommandé R1 + Accusé réception
240
+ {
241
+ enabled: false,
242
+ label: "Colissimo National Recommandé R1",
243
+ code: "colissimo_ar_r1",
244
+ tracking_url: "{colissimo.tracking_url}",
245
+ destination: "{colissimo.destination}",
246
+ conditions: "{colissimo_r1.conditions}",
247
+ fees: "1.30+{colissimo_r1.fees}",
248
+ }
249
+ # Colissimo National + Recommandé R2 + Accusé réception
250
+ {
251
+ enabled: false,
252
+ label: "Colissimo National Recommandé R2",
253
+ code: "colissimo_ar_r2",
254
+ tracking_url: "{colissimo.tracking_url}",
255
+ destination: "{colissimo.destination}",
256
+ conditions: "{colissimo_r2.conditions}",
257
+ fees: "1.30+{colissimo_r2.fees}",
258
+ }
259
+ # Colissimo National + Recommandé R3 + Accusé réception
260
+ {
261
+ enabled: false,
262
+ label: "Colissimo National Recommandé R3",
263
+ code: "colissimo_ar_r3",
264
+ tracking_url: "{colissimo.tracking_url}",
265
+ destination: "{colissimo.destination}",
266
+ conditions: "{colissimo_r3.conditions}",
267
+ fees: "1.30+{colissimo_r3.fees}",
268
+ }
269
+ # Colissimo National + Recommandé R4 + Accusé réception
270
+ {
271
+ enabled: false,
272
+ label: "Colissimo National Recommandé R4",
273
+ code: "colissimo_ar_r4",
274
+ tracking_url: "{colissimo.tracking_url}",
275
+ destination: "{colissimo.destination}",
276
+ conditions: "{colissimo_r4.conditions}",
277
+ fees: "1.30+{colissimo_r4.fees}",
278
+ }
279
+ # Colissimo National + Recommandé R5 + Accusé réception
280
+ {
281
+ enabled: false,
282
+ label: "Colissimo National Recommandé R5",
283
+ code: "colissimo_ar_r5",
284
+ tracking_url: "{colissimo.tracking_url}",
285
+ destination: "{colissimo.destination}",
286
+ conditions: "{colissimo_r5.conditions}",
287
+ fees: "1.30+{colissimo_r5.fees}",
288
+ }
289
+
290
+ # Colissimo International OM1 (Départements et collectivités d'outre-mer)
291
+ # Guadeloupe, Martinique, Guyane, Réunion, Mayotte,
292
+ # Saint-Pierre et Miquelon, Saint-Martin, Saint-Barthélémy
293
+ {
294
+ label: "Colissimo OM1 Assuré",
295
+ code: "colissimo_om1",
296
+ tracking_url: "{colissimo.tracking_url}",
297
+ destination: "GP,MQ,GF,RE,YT,PM,MF,BL",
298
+ fees: "{table {cart.weight} in 0.5:8.45, 1.0:12.70, 2.0:17.35, 3.0:22.00, 4.0:26.65, 5.0:31.30, 6.0:35.95, 7.0:40.60, 8.0:45.25, 9.0:49.90, 10.0:54.55, 15.0:77.75, 20.0:100.95, 25.0:124.15, 30.0:147.35}",
299
+ }
300
+ # Colissimo International OM1 + Recommandé R1
301
+ {
302
+ label: "Colissimo OM1 Recommandé R1",
303
+ code: "colissimo_om1_r1",
304
+ tracking_url: "{colissimo.tracking_url}",
305
+ destination: "{colissimo_om1.destination}",
306
+ conditions: "{colissimo_r1.conditions}",
307
+ fees: "{table {cart.weight} in 0.5:10.75, 1.0:15.00, 2.0:19.65, 3.0:24.30, 4.0:28.95, 5.0:33.60, 6.0:38.25, 7.0:42.90, 8.0:47.55, 9.0:52.20, 10.0:56.85, 15.0:80.05, 20.0:103.25, 25.0:126.45, 30.0:149.65}",
308
+ }
309
+ # Colissimo International OM1 + Recommandé R2
310
+ {
311
+ label: "Colissimo OM1 Recommandé R2",
312
+ code: "colissimo_om1_r2",
313
+ tracking_url: "{colissimo.tracking_url}",
314
+ destination: "{colissimo_om1.destination}",
315
+ conditions: "{colissimo_r2.conditions}",
316
+ fees: "{table {cart.weight} in 0.5:11.65, 1.0:15.90, 2.0:20.55, 3.0:25.20, 4.0:29.85, 5.0:34.50, 6.0:39.15, 7.0:43.80, 8.0:48.45, 9.0:53.10, 10.0:57.75, 15.0:80.95, 20.0:104.15, 25.0:127.35, 30.0:150.55}",
317
+ }
318
+ # Colissimo International OM1 + Recommandé R3
319
+ {
320
+ label: "Colissimo OM1 Recommandé R3",
321
+ code: "colissimo_om1_r3",
322
+ tracking_url: "{colissimo.tracking_url}",
323
+ destination: "{colissimo_om1.destination}",
324
+ conditions: "{colissimo_r3.conditions}",
325
+ fees: "{table {cart.weight} in 0.5:12.85, 1.0:17.10, 2.0:21.75, 3.0:26.40, 4.0:31.05, 5.0:35.70, 6.0:40.35, 7.0:45.00, 8.0:49.65, 9.0:54.30, 10.0:58.95, 15.0:82.15, 20.0:105.35, 25.0:128.55, 30.0:151.75}",
326
+ }
327
+ # Colissimo International OM1 + Recommandé R4
328
+ {
329
+ label: "Colissimo OM1 Recommandé R4",
330
+ code: "colissimo_om1_r4",
331
+ tracking_url: "{colissimo.tracking_url}",
332
+ destination: "{colissimo_om1.destination}",
333
+ conditions: "{colissimo_r4.conditions}",
334
+ fees: "{table {cart.weight} in 0.5:14.05, 1.0:18.30, 2.0:22.95, 3.0:27.60, 4.0:32.25, 5.0:36.90, 6.0:41.55, 7.0:46.20, 8.0:50.85, 9.0:55.50, 10.0:60.15, 15.0:83.35, 20.0:106.55, 25.0:129.75, 30.0:152.95}",
335
+ }
336
+ # Colissimo International OM1 + Recommandé R5
337
+ {
338
+ label: "Colissimo OM1 Recommandé R5",
339
+ code: "colissimo_om1_r5",
340
+ tracking_url: "{colissimo.tracking_url}",
341
+ destination: "{colissimo_om1.destination}",
342
+ conditions: "{colissimo_r5.conditions}",
343
+ fees: "{table {cart.weight} in 0.5:15.25, 1.0:19.50, 2.0:24.15, 3.0:28.80, 4.0:33.45, 5.0:38.10, 6.0:42.75, 7.0:47.40, 8.0:52.05, 9.0:56.70, 10.0:61.35, 15.0:84.55, 20.0:107.75, 25.0:130.95, 30.0:154.15}",
344
+ }
345
+
346
+ # Colissimo International OM2 (Collectivités d'outre-mer)
347
+ # Nouvelle Calédonie, Polynésie Française, Wallis et Futuna,
348
+ # les Terres Australes et Antarctiques Françaises
349
+ {
350
+ label: "Colissimo OM2 Assuré",
351
+ code: "colissimo_om2",
352
+ tracking_url: "{colissimo.tracking_url}",
353
+ destination: "NC,PF,WF,TF",
354
+ fees: "{table {cart.weight} in 0.5:10.10, 1.0:15.20, 2.0:26.80, 3.0:38.40, 4.0:50.00, 5.0:61.60, 6.0:73.20, 7.0:84.80, 8.0:96.40, 9.0:108.00, 10.0:119.60, 15.0:177.60, 20.0:235.60, 25.0:293.60, 30.0:351.60}",
355
+ }
356
+ # Colissimo International OM2 + Recommandé R1
357
+ {
358
+ label: "Colissimo OM2 Recommandé R1",
359
+ code: "colissimo_om2_r1",
360
+ tracking_url: "{colissimo.tracking_url}",
361
+ destination: "{colissimo_om2.destination}",
362
+ conditions: "{colissimo_r1.conditions}",
363
+ fees: "{table {cart.weight} in 0.5:12.40, 1.0:17.50, 2.0:29.10, 3.0:40.70, 4.0:52.30, 5.0:63.90, 6.0:75.50, 7.0:87.10, 8.0:98.70, 9.0:110.30, 10.0:121.90, 15.0:179.90, 20.0:237.90, 25.0:295.90, 30.0:353.90}",
364
+ }
365
+ # Colissimo International OM2 + Recommandé R2
366
+ {
367
+ label: "Colissimo OM2 Recommandé R2",
368
+ code: "colissimo_om2_r2",
369
+ tracking_url: "{colissimo.tracking_url}",
370
+ destination: "{colissimo_om2.destination}",
371
+ conditions: "{colissimo_r2.conditions}",
372
+ fees: "{table {cart.weight} in 0.5:13.30, 1.0:18.40, 2.0:30.00, 3.0:41.60, 4.0:53.20, 5.0:64.80, 6.0:76.40, 7.0:88.00, 8.0:99.60, 9.0:111.20, 10.0:122.80, 15.0:180.80, 20.0:238.80, 25.0:296.80, 30.0:354.80}",
373
+ }
374
+ # Colissimo International OM2 + Recommandé R3
375
+ {
376
+ label: "Colissimo OM2 Recommandé R3",
377
+ code: "colissimo_om2_r3",
378
+ tracking_url: "{colissimo.tracking_url}",
379
+ destination: "{colissimo_om2.destination}",
380
+ conditions: "{colissimo_r3.conditions}",
381
+ fees: "{table {cart.weight} in 0.5:14.50, 1.0:19.60, 2.0:31.20, 3.0:42.80, 4.0:54.40, 5.0:66.00, 6.0:77.60, 7.0:89.20, 8.0:100.80, 9.0:112.40, 10.0:124.00, 15.0:182.00, 20.0:240.00, 25.0:298.00, 30.0:356.00}",
382
+ }
383
+ # Colissimo International OM2 + Recommandé R4
384
+ {
385
+ label: "Colissimo OM2 Recommandé R4",
386
+ code: "colissimo_om2_r4",
387
+ tracking_url: "{colissimo.tracking_url}",
388
+ destination: "{colissimo_om2.destination}",
389
+ conditions: "{colissimo_r4.conditions}",
390
+ fees: "{table {cart.weight} in 0.5:15.70, 1.0:20.80, 2.0:32.40, 3.0:44.00, 4.0:55.60, 5.0:67.20, 6.0:78.80, 7.0:90.40, 8.0:102.00, 9.0:113.60, 10.0:125.20, 15.0:183.20, 20.0:241.20, 25.0:299.20, 30.0:357.20}",
391
+ }
392
+ # Colissimo International OM2 + Recommandé R5
393
+ {
394
+ label: "Colissimo OM2 Recommandé R5",
395
+ code: "colissimo_om2_r5",
396
+ tracking_url: "{colissimo.tracking_url}",
397
+ destination: "{colissimo_om2.destination}",
398
+ conditions: "{colissimo_r5.conditions}",
399
+ fees: "{table {cart.weight} in 0.5:16.90, 1.0:22.00, 2.0:33.60, 3.0:45.20, 4.0:56.80, 5.0:68.40, 6.0:80.00, 7.0:91.60, 8.0:103.20, 9.0:114.80, 10.0:126.40, 15.0:184.40, 20.0:242.40, 25.0:300.40, 30.0:358.40}",
400
+ }
401
+
402
+ # Colissimo International Zone A max 30 kg
403
+ {
404
+ label: "Colissimo International Zone A",
405
+ code: "colissimo_a30",
406
+ tracking_url: "{colissimo.tracking_url}",
407
+ destination: "BE,BG,CH,CY,DE,DK,FI,GB,HU,IE,IT,LT,LU,LV,NO,PT,SI,AT,CZ,EE,ES,GI,GR,MT,NL,PL,SE,SM,VA,SK",
408
+ fees: "{table {cart.weight} in 1.0:16.05, 2.0:17.65, 3.0:21.30, 4.0:24.95, 5.0:28.60, 6.0:32.25, 7.0:35.90, 8.0:39.55, 9.0:43.20, 10.0:46.85, 15.0:53.85, 20.0:60.85, 25.0:67.85, 30.0:74.85}",
409
+ }
410
+
411
+ # Colissimo International Zone B max 20 kg
412
+ {
413
+ label: "Colissimo International Zone B",
414
+ code: "colissimo_b20",
415
+ tracking_url: "{colissimo.tracking_url}",
416
+ destination: "AZ,BY,DZ,HR,IS,MA,ME,RO,RS,TR,AL,AM,BA,GE,MD,MK,RU,UA,TN",
417
+ fees: "{table {cart.weight} in 1.0:19.40, 2.0:21.30, 3.0:25.75, 4.0:30.20, 5.0:34.65, 6.0:39.10, 7.0:43.55, 8.0:48.00, 9.0:52.45, 10.0:56.90, 15.0:67.10, 20.0:77.30}",
418
+ }
419
+
420
+ # Colissimo International Zone C max 20 kg
421
+ {
422
+ label: "Colissimo International Zone C",
423
+ code: "colissimo_c20",
424
+ tracking_url: "{colissimo.tracking_url}",
425
+ destination: "AE,BF,BI,BJ,BW,CA,CD,CI,CM,CV,EG,ET,GH,GN,IR,JO,KE,KW,LB,MG,MU,NE,NG,OM,QA,RW,SA,SC,SY,UG,US,YE,ZA,ZM,AO,BH,CF,CG,DJ,ER,GA,GW,IL,KM,LR,LS,LY,ML,MR,MW,MZ,NA,PR,SD,SH,SL,SN,ST,SZ,TD,TG,TZ,ZW,GM,GQ",
426
+ fees: "{table {cart.weight} in 1.0:22.50, 2.0:30.10, 3.0:39.50, 4.0:48.90, 5.0:58.30, 6.0:67.70, 7.0:77.10, 8.0:86.50, 9.0:95.90, 10.0:105.30, 15.0:128.80, 20.0:152.30}",
427
+ }
428
+ # Colissimo International Zone D max 20 kg
429
+ {
430
+ label: "Colissimo International Zone D",
431
+ code: "colissimo_d20",
432
+ tracking_url: "{colissimo.tracking_url}",
433
+ destination: "AU,BD,BO,BR,CK,CN,CR,EC,HK,JP,KH,LK,MV,NI,NZ,PA,PE,PK,PY,SG,UY,HT,TV,AF,AN,AR,BB,BM,BN,BS,BZ,CL,CO,CU,DM,DO,FJ,FK,GS,GT,GY,HN,ID,IN,KG,KI,KP,KR,KY,KZ,LA,LC,MM,MO,MS,MX,MY,NP,NR,PG,PH,SB,SR,SV,TH,TJ,TL,TO,TT,TW,UZ,VE,VG,VN,VU,AG,AI,GD,GU,JM,MN,PN,TM,VC,WS,TC",
434
+ fees: "{table {cart.weight} in 1.0:25.40, 2.0:38.10, 3.0:50.80, 4.0:63.50, 5.0:76.20, 6.0:88.90, 7.0:101.60, 8.0:114.30, 9.0:127.00, 10.0:139.70, 15.0:164.70, 20.0:189.70}",
435
+ }
436
+
437
+
438
+ #####
439
+ # Chronopost
440
+ #
441
+ # Validité
442
+ # Tarifs web du 1er septembre 2010
443
+ # Crédits
444
+ # Configuration réalisée par owebia
445
+
446
+ {
447
+ label: "Chronopost France Chrono 13",
448
+ code: "chronopost_france",
449
+ tracking_url: "http://www.fr.chronopost.com/fr/tracking/result?listeNumeros={tracking_number}",
450
+ destination: "FR",
451
+ fees: "{table {cart.weight} in 2.0:18.20, 5.0:18.70, 6.0:19.50, 7.0:20.20, 8.0:20.85, 9.0:21.50, 10.0:22.15, 11.0:22.80, 12.0:23.45, 13.0:24.10, 14.0:24.75, 15.0:25.40, 16.0:26.05, 17.0:26.70, 18.0:27.35, 19.0:28.00, 20.0:28.65, 21.0:29.30, 22.0:29.95, 23.0:30.60, 24.0:31.25, 25.0:31.90, 26.0:32.55, 27.0:33.20, 28.0:33.85, 29.0:34.50, 30:35.15}",
452
+ }
453
+ {
454
+ label: "Chronopost Classic Zone 1",
455
+ code: "chronopost_classic_zone_1",
456
+ tracking_url: "{chronopost_france.tracking_url}",
457
+ destination: "DE,BE,LU,NL",
458
+ fees: "{table {cart.weight} in 1.0:29.90, 2.0:32.10, 3.0:34.30, 4.0:36.50, 5.0:38.70, 6.0:40.90, 7.0:43.10, 8.0:45.30, 9.0:47.50, 10.0:49.70}+({cart.weight}>10.0 ? ceil({cart.weight}-10.0)*2.30 : 0.00)",
459
+ }
460
+ {
461
+ label: "Chronopost Classic Zone 2",
462
+ code: "chronopost_classic_zone_2",
463
+ tracking_url: "{chronopost_france.tracking_url}",
464
+ destination: "AT,DK,ES,FI,GB,GR,IE,IT,PT,SE",
465
+ fees: "{table {cart.weight} in 1.0:33.60, 2.0:36.10, 3.0:38.60, 4.0:41.10, 5.0:43.60, 6.0:46.10, 7.0:48.60, 8.0:51.10, 9.0:53.60, 10.0:56.10}+({cart.weight}>10.0 ? ceil({cart.weight}-10.0)*2.60 : 0.00)",
466
+ }
467
+ {
468
+ label: "Chronopost Classic Zone 3",
469
+ code: "chronopost_classic_zone_3",
470
+ tracking_url: "{chronopost_france.tracking_url}",
471
+ destination: "BG,EE,HU,LV,LT,PL,RO,SK,SI,CZ",
472
+ fees: "{table {cart.weight} in 1.0:40.30, 2.0:43.10, 3.0:45.90, 4.0:48.70, 5.0:51.50, 6.0:54.30, 7.0:57.10, 8.0:59.90, 9.0:62.70, 10.0:65.50}+({cart.weight}>10.0 ? ceil({cart.weight}-10.0)*2.90 : 0.00)",
473
+ }
474
+ {
475
+ label: "Chronopost Classic Zone 4",
476
+ code: "chronopost_classic_zone_4",
477
+ tracking_url: "{chronopost_france.tracking_url}",
478
+ destination: "LI,CH",
479
+ fees: "{table {cart.weight} in 1.0:55.30, 2.0:57.90, 3.0:60.50, 4.0:63.10, 5.0:65.70, 6.0:68.30, 7.0:70.90, 8.0:73.50, 9.0:76.10, 10.0:78.70}+({cart.weight}>10.0 ? ceil({cart.weight}-10.0)*2.80 : 0.00)",
480
+ }
481
+
482
+ ###
483
+ # Export 3J
484
+ {
485
+ label: "Export 3J",
486
+ code: "export_3j",
487
+ tracking_url: "http://212.157.222.70/webSearch?client=Entreprise&barco={tracking_number}",
488
+ destination: "DE,DK,ES,FI,GB,IE,NL,PT,SE,CH",
489
+ fees: "{table {cart.weight} in 0.05:3.75, 0.10:4.00, 0.20:6.50, 0.50:8.50, 1.00:11.00, 1.50:13.00, 2.00:14.80}",
490
+ }
491
+ ]]>
492
+ </config>
493
+ <debug>0</debug>
494
+ <stop_to_first_match>0</stop_to_first_match>
495
+ <sort_order>1</sort_order>
496
+ </owebiashipping1>
497
+ <owebiashipping2>
498
+ <active>0</active>
499
+ <title>Owebia Shipping - Mode de livraison 2</title>
500
+ <model>Owebia_Shipping2_Model_Carrier_OwebiaShipping2</model>
501
+ <tracking_view_url></tracking_view_url>
502
+ <config></config>
503
+ <debug>0</debug>
504
+ <stop_to_first_match>0</stop_to_first_match>
505
+ <sort_order>2</sort_order>
506
+ </owebiashipping2>
507
+ <owebiashipping3>
508
+ <active>0</active>
509
+ <title>Owebia Shipping - Mode de livraison 3</title>
510
+ <model>Owebia_Shipping2_Model_Carrier_OwebiaShipping3</model>
511
+ <tracking_view_url></tracking_view_url>
512
+ <config></config>
513
+ <debug>0</debug>
514
+ <stop_to_first_match>0</stop_to_first_match>
515
+ <sort_order>3</sort_order>
516
+ </owebiashipping3>
517
+ </carriers>
518
+ </default>
519
+ </config>
app/code/community/Owebia/Shipping2/etc/system.xml ADDED
@@ -0,0 +1,306 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <!--
3
+ /**
4
+ * Magento Owebia Shipping Module
5
+ *
6
+ * NOTICE OF LICENSE
7
+ *
8
+ * This source file is subject to the Open Software License (OSL 3.0)
9
+ * that is bundled with this package in the file LICENSE.txt.
10
+ * It is also available through the world-wide-web at this URL:
11
+ * http://opensource.org/licenses/osl-3.0.php
12
+ * If you did not receive a copy of the license and are unable to
13
+ * obtain it through the world-wide-web, please send an email
14
+ * to license@magentocommerce.com so we can send you a copy immediately.
15
+ *
16
+ * @category Owebia
17
+ * @package Owebia_Shipping
18
+ * @copyright Copyright (c) 2008-10 Owebia (http://www.owebia.com/)
19
+ * @author Antoine Lemoine
20
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
21
+ */
22
+ -->
23
+
24
+ <config>
25
+ <sections>
26
+ <carriers>
27
+ <show_in_store>1</show_in_store>
28
+ <groups>
29
+ <owebiashipping1 translate="label" module="shipping">
30
+ <label>Owebia Shipping - Mode de livraison 1</label>
31
+ <frontend_type>text</frontend_type>
32
+ <sort_order>-19</sort_order>
33
+ <show_in_default>1</show_in_default>
34
+ <show_in_website>1</show_in_website>
35
+ <show_in_store>1</show_in_store>
36
+ <fields>
37
+ <active translate="label">
38
+ <label>Enabled</label>
39
+ <frontend_type>select</frontend_type>
40
+ <source_model>adminhtml/system_config_source_yesno</source_model>
41
+ <sort_order>1</sort_order>
42
+ <show_in_default>1</show_in_default>
43
+ <show_in_website>1</show_in_website>
44
+ <show_in_store>1</show_in_store>
45
+ </active>
46
+ <title translate="label">
47
+ <label>Title</label>
48
+ <frontend_type>text</frontend_type>
49
+ <sort_order>2</sort_order>
50
+ <show_in_default>1</show_in_default>
51
+ <show_in_website>1</show_in_website>
52
+ <show_in_store>1</show_in_store>
53
+ </title>
54
+ <config translate="label">
55
+ <label>Configuration</label>
56
+ <frontend_model>owebia-shipping2/adminhtml_system_config_form_field_config</frontend_model>
57
+ <frontend_type>textarea</frontend_type>
58
+ <sort_order>3</sort_order>
59
+ <show_in_default>1</show_in_default>
60
+ <show_in_website>1</show_in_website>
61
+ <show_in_store>1</show_in_store>
62
+ </config>
63
+ <tracking_view_url translate="label">
64
+ <label>Tracking URL</label>
65
+ <frontend_type>text</frontend_type>
66
+ <sort_order>4</sort_order>
67
+ <show_in_default>1</show_in_default>
68
+ <show_in_website>1</show_in_website>
69
+ <show_in_store>1</show_in_store>
70
+ </tracking_view_url>
71
+ <debug>
72
+ <label>Debug</label>
73
+ <comment>{debug_help}</comment>
74
+ <frontend_type>select</frontend_type>
75
+ <source_model>adminhtml/system_config_source_yesno</source_model>
76
+ <sort_order>5</sort_order>
77
+ <show_in_default>1</show_in_default>
78
+ <show_in_website>1</show_in_website>
79
+ <show_in_store>1</show_in_store>
80
+ </debug>
81
+ <compression>
82
+ <label>Compression</label>
83
+ <comment>{compression_help}</comment>
84
+ <frontend_type>select</frontend_type>
85
+ <source_model>adminhtml/system_config_source_yesno</source_model>
86
+ <sort_order>6</sort_order>
87
+ <show_in_default>1</show_in_default>
88
+ <show_in_website>1</show_in_website>
89
+ <show_in_store>1</show_in_store>
90
+ </compression>
91
+ <stop_to_first_match translate="label">
92
+ <label>Stop to first match</label>
93
+ <frontend_type>select</frontend_type>
94
+ <source_model>adminhtml/system_config_source_yesno</source_model>
95
+ <sort_order>8</sort_order>
96
+ <show_in_default>1</show_in_default>
97
+ <show_in_website>1</show_in_website>
98
+ <show_in_store>1</show_in_store>
99
+ </stop_to_first_match>
100
+ <sort_order translate="label">
101
+ <label>Sort order</label>
102
+ <frontend_type>text</frontend_type>
103
+ <sort_order>100</sort_order>
104
+ <show_in_default>1</show_in_default>
105
+ <show_in_website>1</show_in_website>
106
+ <show_in_store>1</show_in_store>
107
+ </sort_order>
108
+ </fields>
109
+ </owebiashipping1>
110
+ <owebiashipping2 translate="label" module="shipping">
111
+ <label>Owebia Shipping - Mode de livraison 2</label>
112
+ <frontend_type>text</frontend_type>
113
+ <sort_order>-18</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
+ <fields>
118
+ <active translate="label">
119
+ <label>Enabled</label>
120
+ <frontend_type>select</frontend_type>
121
+ <source_model>adminhtml/system_config_source_yesno</source_model>
122
+ <sort_order>1</sort_order>
123
+ <show_in_default>1</show_in_default>
124
+ <show_in_website>1</show_in_website>
125
+ <show_in_store>1</show_in_store>
126
+ </active>
127
+ <title translate="label">
128
+ <label>Title</label>
129
+ <frontend_type>text</frontend_type>
130
+ <sort_order>2</sort_order>
131
+ <show_in_default>1</show_in_default>
132
+ <show_in_website>1</show_in_website>
133
+ <show_in_store>1</show_in_store>
134
+ </title>
135
+ <config translate="label">
136
+ <label>Configuration</label>
137
+ <frontend_model>owebia-shipping2/adminhtml_system_config_form_field_config</frontend_model>
138
+ <frontend_type>textarea</frontend_type>
139
+ <sort_order>3</sort_order>
140
+ <show_in_default>1</show_in_default>
141
+ <show_in_website>1</show_in_website>
142
+ <show_in_store>1</show_in_store>
143
+ </config>
144
+ <tracking_view_url translate="label">
145
+ <label>Tracking URL</label>
146
+ <frontend_type>text</frontend_type>
147
+ <sort_order>4</sort_order>
148
+ <show_in_default>1</show_in_default>
149
+ <show_in_website>1</show_in_website>
150
+ <show_in_store>1</show_in_store>
151
+ </tracking_view_url>
152
+ <debug>
153
+ <label>Debug</label>
154
+ <comment>{debug_help}</comment>
155
+ <frontend_type>select</frontend_type>
156
+ <source_model>adminhtml/system_config_source_yesno</source_model>
157
+ <sort_order>5</sort_order>
158
+ <show_in_default>1</show_in_default>
159
+ <show_in_website>1</show_in_website>
160
+ <show_in_store>1</show_in_store>
161
+ </debug>
162
+ <compression>
163
+ <label>Compression</label>
164
+ <comment>{compression_help}</comment>
165
+ <frontend_type>select</frontend_type>
166
+ <source_model>adminhtml/system_config_source_yesno</source_model>
167
+ <sort_order>6</sort_order>
168
+ <show_in_default>1</show_in_default>
169
+ <show_in_website>1</show_in_website>
170
+ <show_in_store>1</show_in_store>
171
+ </compression>
172
+ <stop_to_first_match translate="label">
173
+ <label>Stop to first match</label>
174
+ <frontend_type>select</frontend_type>
175
+ <source_model>adminhtml/system_config_source_yesno</source_model>
176
+ <sort_order>8</sort_order>
177
+ <show_in_default>1</show_in_default>
178
+ <show_in_website>1</show_in_website>
179
+ <show_in_store>1</show_in_store>
180
+ </stop_to_first_match>
181
+ <sort_order translate="label">
182
+ <label>Sort order</label>
183
+ <frontend_type>text</frontend_type>
184
+ <sort_order>100</sort_order>
185
+ <show_in_default>1</show_in_default>
186
+ <show_in_website>1</show_in_website>
187
+ <show_in_store>1</show_in_store>
188
+ </sort_order>
189
+ </fields>
190
+ </owebiashipping2>
191
+ <owebiashipping3 translate="label" module="shipping">
192
+ <label>Owebia Shipping - Mode de livraison 3</label>
193
+ <frontend_type>text</frontend_type>
194
+ <sort_order>-17</sort_order>
195
+ <show_in_default>1</show_in_default>
196
+ <show_in_website>1</show_in_website>
197
+ <show_in_store>1</show_in_store>
198
+ <fields>
199
+ <active translate="label">
200
+ <label>Enabled</label>
201
+ <frontend_type>select</frontend_type>
202
+ <source_model>adminhtml/system_config_source_yesno</source_model>
203
+ <sort_order>1</sort_order>
204
+ <show_in_default>1</show_in_default>
205
+ <show_in_website>1</show_in_website>
206
+ <show_in_store>1</show_in_store>
207
+ </active>
208
+ <title translate="label">
209
+ <label>Title</label>
210
+ <frontend_type>text</frontend_type>
211
+ <sort_order>2</sort_order>
212
+ <show_in_default>1</show_in_default>
213
+ <show_in_website>1</show_in_website>
214
+ <show_in_store>1</show_in_store>
215
+ </title>
216
+ <config translate="label">
217
+ <label>Configuration</label>
218
+ <frontend_model>owebia-shipping2/adminhtml_system_config_form_field_config</frontend_model>
219
+ <frontend_type>textarea</frontend_type>
220
+ <sort_order>3</sort_order>
221
+ <show_in_default>1</show_in_default>
222
+ <show_in_website>1</show_in_website>
223
+ <show_in_store>1</show_in_store>
224
+ </config>
225
+ <tracking_view_url translate="label">
226
+ <label>Tracking URL</label>
227
+ <frontend_type>text</frontend_type>
228
+ <sort_order>4</sort_order>
229
+ <show_in_default>1</show_in_default>
230
+ <show_in_website>1</show_in_website>
231
+ <show_in_store>1</show_in_store>
232
+ </tracking_view_url>
233
+ <debug>
234
+ <label>Debug</label>
235
+ <comment>{debug_help}</comment>
236
+ <frontend_type>select</frontend_type>
237
+ <source_model>adminhtml/system_config_source_yesno</source_model>
238
+ <sort_order>5</sort_order>
239
+ <show_in_default>1</show_in_default>
240
+ <show_in_website>1</show_in_website>
241
+ <show_in_store>1</show_in_store>
242
+ </debug>
243
+ <compression>
244
+ <label>Compression</label>
245
+ <comment>{compression_help}</comment>
246
+ <frontend_type>select</frontend_type>
247
+ <source_model>adminhtml/system_config_source_yesno</source_model>
248
+ <sort_order>6</sort_order>
249
+ <show_in_default>1</show_in_default>
250
+ <show_in_website>1</show_in_website>
251
+ <show_in_store>1</show_in_store>
252
+ </compression>
253
+ <stop_to_first_match translate="label">
254
+ <label>Stop to first match</label>
255
+ <frontend_type>select</frontend_type>
256
+ <source_model>adminhtml/system_config_source_yesno</source_model>
257
+ <sort_order>8</sort_order>
258
+ <show_in_default>1</show_in_default>
259
+ <show_in_website>1</show_in_website>
260
+ <show_in_store>1</show_in_store>
261
+ </stop_to_first_match>
262
+ <sort_order translate="label">
263
+ <label>Sort order</label>
264
+ <frontend_type>text</frontend_type>
265
+ <sort_order>100</sort_order>
266
+ <show_in_default>1</show_in_default>
267
+ <show_in_website>1</show_in_website>
268
+ <show_in_store>1</show_in_store>
269
+ </sort_order>
270
+ </fields>
271
+ </owebiashipping3>
272
+ </groups>
273
+ </carriers>
274
+ </sections>
275
+ <sections>
276
+ <owebia translate="label">
277
+ <label>Owebia</label>
278
+ <tab>general</tab>
279
+ <frontend_type>text</frontend_type>
280
+ <sort_order>330</sort_order>
281
+ <show_in_default>1</show_in_default>
282
+ <show_in_website>1</show_in_website>
283
+ <show_in_store>1</show_in_store>
284
+ <groups>
285
+ <shipping translate="label">
286
+ <label>Owebia Shipping module</label>
287
+ <frontend_type>text</frontend_type>
288
+ <sort_order>2</sort_order>
289
+ <show_in_default>1</show_in_default>
290
+ <show_in_website>1</show_in_website>
291
+ <show_in_store>1</show_in_store>
292
+ <fields>
293
+ <weight_unit translate="label">
294
+ <label>Weight unit</label>
295
+ <frontend_type>text</frontend_type>
296
+ <sort_order>1</sort_order>
297
+ <show_in_default>1</show_in_default>
298
+ <show_in_website>1</show_in_website>
299
+ <show_in_store>1</show_in_store>
300
+ </weight_unit>
301
+ </fields>
302
+ </shipping>
303
+ </groups>
304
+ </owebia>
305
+ </sections>
306
+ </config>
app/code/community/Owebia/Shipping2/includes/OS2_AddressFilter.php ADDED
@@ -0,0 +1,522 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+
4
+ class Country
5
+ {
6
+ private static $LOADED = false;
7
+ private static $COUNTRIES = array(
8
+ 'code2name' => array(
9
+ 'AF' => 'Afghanistan',
10
+ 'ZA' => 'Afrique du Sud',
11
+ 'AX' => 'Åland',
12
+ 'AL' => 'Albanie',
13
+ 'DZ' => 'Algérie',
14
+ 'DE' => 'Allemagne',
15
+ 'AD' => 'Andorre',
16
+ 'AO' => 'Angola',
17
+ 'AI' => 'Anguilla',
18
+ 'AQ' => 'Antarctique',
19
+ 'AG' => 'Antigua-et-Barbuda',
20
+ 'AN' => 'Antilles néerlandaises',
21
+ 'SA' => 'Arabie saoudite',
22
+ 'AR' => 'Argentine',
23
+ 'AM' => 'Arménie',
24
+ 'AW' => 'Aruba',
25
+ 'AU' => 'Australie',
26
+ 'AT' => 'Autriche',
27
+ 'AZ' => 'Azerbaïdjan',
28
+ 'BS' => 'Bahamas',
29
+ 'BH' => 'Bahreïn',
30
+ 'BD' => 'Bangladesh',
31
+ 'BB' => 'Barbade',
32
+ 'BY' => 'Biélorussie',
33
+ 'BE' => 'Belgique',
34
+ 'BZ' => 'Belize',
35
+ 'BJ' => 'Bénin',
36
+ 'BM' => 'Bermudes',
37
+ 'BT' => 'Bhoutan',
38
+ 'BO' => 'Bolivie',
39
+ 'BA' => 'Bosnie-Herzégovine',
40
+ 'BW' => 'Botswana',
41
+ 'BV' => 'Île Bouvet',
42
+ 'BR' => 'Brésil',
43
+ 'BN' => 'Brunei',
44
+ 'BG' => 'Bulgarie',
45
+ 'BF' => 'Burkina Faso',
46
+ 'BI' => 'Burundi',
47
+ 'KY' => 'Îles Caïmans',
48
+ 'KH' => 'Cambodge',
49
+ 'CM' => 'Cameroun',
50
+ 'CA' => 'Canada',
51
+ 'CV' => 'Cap-Vert',
52
+ 'CF' => 'République centrafricaine',
53
+ 'CL' => 'Chili',
54
+ 'CN' => 'Chine',
55
+ 'CX' => 'Île Christmas',
56
+ 'CY' => 'Chypre',
57
+ 'CC' => 'Îles Cocos',
58
+ 'CO' => 'Colombie',
59
+ 'KM' => 'Comores',
60
+ 'CG' => 'Congo',
61
+ 'CD' => 'République démocratique du Congo',
62
+ 'CK' => 'Îles Cook',
63
+ 'KR' => 'Corée du Sud',
64
+ 'KP' => 'Corée du Nord',
65
+ 'CR' => 'Costa Rica',
66
+ 'CI' => "Côte d'Ivoire",
67
+ 'HR' => 'Croatie',
68
+ 'CU' => 'Cuba',
69
+ 'DK' => 'Danemark',
70
+ 'DJ' => 'Djibouti',
71
+ 'DO' => 'République dominicaine',
72
+ 'DM' => 'Dominique',
73
+ 'EG' => 'Égypte',
74
+ 'SV' => 'Salvador',
75
+ 'AE' => 'Émirats arabes unis',
76
+ 'EC' => 'Équateur',
77
+ 'ER' => 'Érythrée',
78
+ 'ES' => 'Espagne',
79
+ 'EE' => 'Estonie',
80
+ 'US' => 'États-Unis',
81
+ 'ET' => 'Éthiopie',
82
+ 'FK' => 'Îles Malouines',
83
+ 'FO' => 'Îles Féroé',
84
+ 'FJ' => 'Fidji',
85
+ 'FI' => 'Finlande',
86
+ 'FR' => 'France',
87
+ 'GA' => 'Gabon',
88
+ 'GM' => 'Gambie',
89
+ 'GE' => 'Géorgie',
90
+ 'GS' => 'Géorgie du Sud-et-les Îles Sandwich du Sud',
91
+ 'GH' => 'Ghana',
92
+ 'GI' => 'Gibraltar',
93
+ 'GR' => 'Grèce',
94
+ 'GD' => 'Grenade',
95
+ 'GL' => 'Groenland',
96
+ 'GP' => 'Guadeloupe',
97
+ 'GU' => 'Guam',
98
+ 'GT' => 'Guatemala',
99
+ 'GG' => 'Guernesey',
100
+ 'GN' => 'Guinée',
101
+ 'GW' => 'Guinée-Bissau',
102
+ 'GQ' => 'Guinée équatoriale',
103
+ 'GY' => 'Guyana',
104
+ 'GF' => 'Guyane Française',
105
+ 'HT' => 'Haïti',
106
+ 'HM' => 'Îles Heard-et-MacDonald',
107
+ 'HN' => 'Honduras',
108
+ 'HK' => 'Hong Kong',
109
+ 'HU' => 'Hongrie',
110
+ 'IM' => 'Île de Man',
111
+ 'UM' => 'Îles mineures éloignées des États-Unis',
112
+ 'VG' => 'Îles Vierges britanniques',
113
+ 'VI' => 'Îles Vierges américaines',
114
+ 'IN' => 'Inde',
115
+ 'ID' => 'Indonésie',
116
+ 'IR' => 'Iran',
117
+ 'IQ' => 'Irak',
118
+ 'IE' => 'Irlande',
119
+ 'IS' => 'Islande',
120
+ 'IL' => 'Israël',
121
+ 'IT' => 'Italie',
122
+ 'JM' => 'Jamaïque',
123
+ 'JP' => 'Japon',
124
+ 'JE' => 'Jersey',
125
+ 'JO' => 'Jordanie',
126
+ 'KZ' => 'Kazakhstan',
127
+ 'KE' => 'Kenya',
128
+ 'KG' => 'Kirghizistan',
129
+ 'KI' => 'Kiribati',
130
+ 'KW' => 'Koweït',
131
+ 'LA' => 'Laos',
132
+ 'LS' => 'Lesotho',
133
+ 'LV' => 'Lettonie',
134
+ 'LB' => 'Liban',
135
+ 'LR' => 'Libéria',
136
+ 'LY' => 'Libye',
137
+ 'LI' => 'Liechtenstein',
138
+ 'LT' => 'Lituanie',
139
+ 'LU' => 'Luxembourg',
140
+ 'MO' => 'Macao',
141
+ 'MK' => 'Macédoine',
142
+ 'MG' => 'Madagascar',
143
+ 'MY' => 'Malaisie',
144
+ 'MW' => 'Malawi',
145
+ 'MV' => 'Maldives',
146
+ 'ML' => 'Mali',
147
+ 'MT' => 'Malte',
148
+ 'MP' => 'Îles Mariannes du Nord',
149
+ 'MA' => 'Maroc',
150
+ 'MH' => 'Îles Marshall',
151
+ 'MQ' => 'Martinique',
152
+ 'MU' => 'Île Maurice',
153
+ 'MR' => 'Mauritanie',
154
+ 'YT' => 'Mayotte',
155
+ 'MX' => 'Mexique',
156
+ 'FM' => 'Micronésie',
157
+ 'MD' => 'Moldavie',
158
+ 'MC' => 'Monaco',
159
+ 'MN' => 'Mongolie',
160
+ 'ME' => 'Monténégro',
161
+ 'MS' => 'Montserrat',
162
+ 'MZ' => 'Mozambique',
163
+ 'MM' => 'Birmanie',
164
+ 'NA' => 'Namibie',
165
+ 'NR' => 'Nauru',
166
+ 'NP' => 'Népal',
167
+ 'NI' => 'Nicaragua',
168
+ 'NE' => 'Niger',
169
+ 'NG' => 'Nigéria',
170
+ 'NU' => 'Niué',
171
+ 'NF' => 'Île Norfolk',
172
+ 'NO' => 'Norvège',
173
+ 'NC' => 'Nouvelle-Calédonie',
174
+ 'NZ' => 'Nouvelle-Zélande',
175
+ 'IO' => "Territoire britannique de l'océan Indien",
176
+ 'OM' => 'Oman',
177
+ 'UG' => 'Ouganda',
178
+ 'UZ' => 'Ouzbékistan',
179
+ 'PK' => 'Pakistan',
180
+ 'PW' => 'Palaos',
181
+ 'PS' => 'Palestine',
182
+ 'PA' => 'Panamá',
183
+ 'PG' => 'Papouasie-Nouvelle-Guinée',
184
+ 'PY' => 'Paraguay',
185
+ 'NL' => 'Pays-Bas',
186
+ 'PE' => 'Pérou',
187
+ 'PH' => 'Philippines',
188
+ 'PN' => 'Îles Pitcairn',
189
+ 'PL' => 'Pologne',
190
+ 'PF' => 'Polynésie Française',
191
+ 'PR' => 'Porto Rico',
192
+ 'PT' => 'Portugal',
193
+ 'QA' => 'Qatar',
194
+ 'RE' => 'La Réunion',
195
+ 'RO' => 'Roumanie',
196
+ 'GB' => 'Royaume-Uni',
197
+ 'RU' => 'Russie',
198
+ 'RW' => 'Rwanda',
199
+ 'EH' => 'Sahara occidental',
200
+ 'BL' => 'Saint-Barthélemy',
201
+ 'KN' => 'Saint-Christophe-et-Niévès',
202
+ 'SM' => 'Saint-Marin',
203
+ 'MF' => 'Saint-Martin',
204
+ 'PM' => 'Saint-Pierre-et-Miquelon',
205
+ 'VA' => 'Vatican',
206
+ 'VC' => 'Saint-Vincent-et-les Grenadines',
207
+ 'SH' => 'Sainte-Hélène',
208
+ 'LC' => 'Sainte-Lucie',
209
+ 'SB' => 'Îles Salomon',
210
+ 'WS' => 'Samoa',
211
+ 'AS' => 'Samoa américaines',
212
+ 'ST' => 'São Tomé-et-Principe',
213
+ 'SN' => 'Sénégal',
214
+ 'RS' => 'Serbie',
215
+ 'SC' => 'Seychelles',
216
+ 'SL' => 'Sierra Leone',
217
+ 'SG' => 'Singapour',
218
+ 'SK' => 'Slovaquie',
219
+ 'SI' => 'Slovénie',
220
+ 'SO' => 'Somalie',
221
+ 'SD' => 'Soudan',
222
+ 'LK' => 'Sri Lanka',
223
+ 'SE' => 'Suède',
224
+ 'CH' => 'Suisse',
225
+ 'SR' => 'Suriname',
226
+ 'SJ' => 'Svalbard et île Jan Mayen',
227
+ 'SZ' => 'Swaziland',
228
+ 'SY' => 'Syrie',
229
+ 'TJ' => 'Tadjikistan',
230
+ 'TW' => 'Taïwan',
231
+ 'TZ' => 'Tanzanie',
232
+ 'TD' => 'Tchad',
233
+ 'CZ' => 'République tchèque',
234
+ 'TF' => 'Terres Australes et Antarctiques Françaises',
235
+ 'TH' => 'Thaïlande',
236
+ 'TL' => 'Timor oriental',
237
+ 'TG' => 'Togo',
238
+ 'TK' => 'Tokelau',
239
+ 'TO' => 'Tonga',
240
+ 'TT' => 'Trinité-et-Tobago',
241
+ 'TN' => 'Tunisie',
242
+ 'TM' => 'Turkménistan',
243
+ 'TC' => 'Îles Turques-et-Caïques',
244
+ 'TR' => 'Turquie',
245
+ 'TV' => 'Tuvalu',
246
+ 'UA' => 'Ukraine',
247
+ 'UY' => 'Uruguay',
248
+ 'VU' => 'Vanuatu',
249
+ 'VE' => 'Venezuela',
250
+ 'VN' => 'Viêt Nam',
251
+ 'WF' => 'Wallis-et-Futuna',
252
+ 'YE' => 'Yémen',
253
+ 'ZM' => 'Zambie',
254
+ 'ZW' => 'Zimbabwe',
255
+ ),
256
+ 'code2soft-cleaned-name' => null,
257
+ 'code2hard-cleaned-name' => null,
258
+ 'replacement' => array(
259
+ 'reunion' => 'RE',
260
+ 'france-metropolitaine' => 'FR',
261
+ 'guyane' => 'GF',
262
+ 'taaf' => 'TF',
263
+ 'terres-australes-francaises' => 'TF',
264
+ 'usa' => 'US',
265
+ 'hollande' => 'NL',
266
+ 'grande-bretagne' => 'GB',
267
+ 'vietnam' => 'VN',
268
+ 'belarus' => 'BY',
269
+ 'brunei-darussalam' => 'BN',
270
+ 'cayman' => 'KY',
271
+ 'caiman' => 'KY',
272
+ 'caimanes' => 'KY',
273
+ 'cocos-keeling' => 'CC',
274
+ 'keeling' => 'CC',
275
+ 'centrafrique' => 'CF',
276
+ 'congo-brazzaville' => 'CG',
277
+ 'congo-kinshasa' => 'CD',
278
+ 'zaire' => 'CD',
279
+ 'san-marin' => 'SM',
280
+ 'surinam' => 'SR',
281
+ 'myanmar' => 'MM',
282
+ 'saint-christophe-nevis' => 'KN',
283
+ 'saint-kitts-nevis' => 'KN',
284
+ 'falkland' => 'FK',
285
+ 'el-salvador' => 'SV',
286
+ 'lithuanie' => 'LT',
287
+ 'turks-caiques' => 'TC',
288
+ 'vierges-des-etats-unis' => 'VI',
289
+ 'etat-de-la-cite-du-vatican' => 'VA',
290
+ 'etats-federes-de-micronesie' => 'FM',
291
+ 'r-a-s-chinoise-de-hong-kong' => 'HK',
292
+ 'r-a-s-chinoise-de-macao' => 'MO',
293
+ ),
294
+ );
295
+
296
+ public static function loadCache() {
297
+ $filename = 'cache/countries';
298
+ if (!file_exists($filename)) {
299
+ self::$COUNTRIES['code2soft-cleaned-name'] = array();
300
+ self::$COUNTRIES['code2hard-cleaned-name'] = array();
301
+ foreach (self::$COUNTRIES['code2name'] as $_code => $_name) {
302
+ $soft_cleaned = self::softClean($_name);
303
+ self::$COUNTRIES['code2soft-cleaned-name'][$_code] = $soft_cleaned;
304
+ self::$COUNTRIES['code2hard-cleaned-name'][$_code] = self::hardClean($soft_cleaned);
305
+ }
306
+ file_put_contents('cache/countries',serialize(self::$COUNTRIES));
307
+ } else {
308
+ self::$COUNTRIES = unserialize(file_get_contents('cache/countries'));
309
+ }
310
+ }
311
+
312
+ public static function getCountryNameByCode($code) {
313
+ return isset(self::$COUNTRIES['code2name'][$code]) ? self::$COUNTRIES['code2name'][$code] : null;
314
+ }
315
+
316
+ public static function getCountryCodeByName($name, $name_type=null) {
317
+ $suffix = isset($name_type) ? $name_type.'-' : '';
318
+ if (!self::$LOADED) self::loadCache();
319
+ $code = array_search($name, self::$COUNTRIES['code2'.$suffix.'name']);
320
+ return $code!==false ? $code : null;
321
+ }
322
+
323
+ public static function getCountryCodeByReplacedName($cleaned_name) {
324
+ if (isset(self::$COUNTRIES['replacement'][$cleaned_name])) return self::$COUNTRIES['replacement'][$cleaned_name];
325
+ return null;
326
+ }
327
+
328
+ public static function softClean($input) {
329
+ $input = mb_strtolower($input,'UTF-8');
330
+ $input = preg_replace('/[ -\.]+/','-',trim($input));
331
+ //echo '"'.$input.'" => ';
332
+ $input = str_replace(
333
+ array(' ','ç','é','è','ê','ë','à','á','â','ä','ã','å','ô','ö','ù','û','ü','î','ï','ÿ'),
334
+ array('-','c','e','e','e','e','a','a','a','a','a','a','o','o','u','u','u','i','i','y'),
335
+ $input
336
+ );
337
+ //echo '"'.$input.'", ';
338
+ $input = preg_replace("/^st-/",'saint-',$input);
339
+ $input = preg_replace("/^ste-/",'sainte-',$input);
340
+ $input = preg_replace("/-&-/",'-et-',$input);
341
+ return $input;
342
+ }
343
+
344
+ public static function hardClean($input) {
345
+ //$output = preg_match('/ivoire/',$input);
346
+ //if ($output) echo '"'.$input.'" => ';
347
+ $input = preg_replace("/^(?:les|le|la|l'|ile|iles)-/",'',$input);
348
+ $input = preg_replace("/-(?:ile|iles)$/",'',$input);
349
+ $input = preg_replace("/-(?:(?:et|les)-)+/",'-',$input);
350
+ $input = preg_replace("/(?:[^a-z0-9]+)/",'-',$input);
351
+ //if ($output) echo '"'.$input.'",<br/>';
352
+ return $input;
353
+ }
354
+
355
+ }
356
+
357
+ class AddressFilter extends Country
358
+ {
359
+ private $data;
360
+ private $code;
361
+ private $name;
362
+ private $classes;
363
+ private $label;
364
+ private $arranged;
365
+ private $address_filters_list;
366
+
367
+ public function AddressFilter($data) {
368
+ $this->data = $data;
369
+ $this->classes = array();
370
+ $this->address_filters_list = null;
371
+ $this->parse();
372
+ }
373
+
374
+ public function parse($recursive=true) {
375
+ if (strlen($this->data['country_code'])==2) {
376
+ $code = strtoupper($this->data['country_code']);
377
+ $name = Country::getCountryNameByCode($code);
378
+
379
+ if (isset($name)) {
380
+ $this->code = $code;
381
+ $this->name = $name;
382
+ $this->classes[] = 'known';
383
+ }
384
+ }
385
+ if (!isset($this->name)) {
386
+ $code = Country::getCountryCodeByName($this->data['country_code']);
387
+ if (!isset($code)) {
388
+ $this->classes[] = 'soft-cleaned';
389
+ $cleaned_name = Country::softClean($this->data['country_code']);
390
+ $code = Country::getCountryCodeByName($cleaned_name,'soft-cleaned');
391
+ }
392
+ if (!isset($code)) {
393
+ $this->classes[] = 'replaced';
394
+ $code = Country::getCountryCodeByReplacedName($cleaned_name);
395
+ }
396
+ if (!isset($code)) {
397
+ $this->classes[] = 'hard-cleaned';
398
+ $cleaned_name = Country::hardClean($cleaned_name);
399
+ $code = Country::getCountryCodeByName($cleaned_name,'hard-cleaned');
400
+ }
401
+ if (!isset($code)) {
402
+ $this->classes[] = 'replaced';
403
+ $code = Country::getCountryCodeByReplacedName($cleaned_name);
404
+ }
405
+ if (isset($code)) {
406
+ $this->code = $code;
407
+ $this->name = Country::getCountryNameByCode($code);
408
+ $this->classes[] = 'known';
409
+ } else {
410
+ $this->classes[] = 'unknown';
411
+ }
412
+ }
413
+
414
+ if ($recursive && $this->hasClass('unknown')) {
415
+ if (!isset($cleaned_name)) $cleaned_name = Country::hardClean(Country::softClean($this->data['original']));
416
+ switch ($cleaned_name) {
417
+ case 'corse':
418
+ $this->data = array(
419
+ 'exclusion' => false,
420
+ 'country_code' => 'FR',
421
+ 'region_codes' => '2A,2B',
422
+ 'original' => $this->data['original'],
423
+ );
424
+ $this->classes = array('replaced');
425
+ $this->parse(false);
426
+ break;
427
+ case 'uk':
428
+ $this->data = array(
429
+ 'exclusion' => false,
430
+ 'country_code' => 'GB',
431
+ 'region_codes' => '',
432
+ 'original' => $this->data['original'],
433
+ );
434
+ $this->classes = array('replaced');
435
+ $this->parse(false);
436
+ break;
437
+ case 'union-europeenne':
438
+ case 'ue':
439
+ $this->createAddressFilterGroup(
440
+ array('DE','AT','BE','BG','CY','DK','ES','EE','FI','FR','GR','HU','IE','IT','LV','LT','LU','MT','NL','PL','PT','CZ','RO','GB','SK','SI','SE'),
441
+ $code = 'UE',
442
+ $name = 'Union européenne'
443
+ );
444
+ break;
445
+ case 'dom':
446
+ $this->createAddressFilterGroup(
447
+ array('GP','MQ','GF','RE'),
448
+ $code = 'DOM',
449
+ $name = "Département d'Outre-Mer"
450
+ );
451
+ break;
452
+ case 'com':
453
+ $this->createAddressFilterGroup(
454
+ array('PF','PM','WF','YT','MF','BL'),
455
+ $code = 'COM',
456
+ $name = "Collectivités d'Outre-Mer"
457
+ );
458
+ break;
459
+ case 'outre-mer':
460
+ $this->createAddressFilterGroup(
461
+ array('DOM','COM','NC','TF'),
462
+ $code = "Outre-Mer",
463
+ $name = "Outre-Mer"
464
+ );
465
+ break;
466
+ }
467
+ }
468
+
469
+ if ($this->hasClass('known')) {
470
+ if ($this->hasClass('replaced') || $this->hasClass('hard-cleaned')) $this->label = '<span class="bad">'.$this->data['original'].'</span> '.$this->name;
471
+ else $this->label = $this->name;
472
+ if (isset($this->data['region_codes']) && $this->data['region_codes']!='') {
473
+ $this->label .= ' ('.$this->data['region_codes'].')';
474
+ }
475
+ } else {
476
+ $this->label = $this->data['original'];
477
+ }
478
+ }
479
+
480
+ public function createAddressFilterGroup($countries, $code, $name) {
481
+ $this->address_filters_list = array();
482
+ foreach ($countries as $country_code) {
483
+ $this->address_filters_list[] = new AddressFilter(array('country_code' => $country_code, 'original' => $country_code));
484
+ }
485
+ $this->classes = array('known');
486
+ $this->code = $code;
487
+ $this->name = $name;
488
+ }
489
+
490
+ public function hasClass($class) {
491
+ return in_array($class,$this->classes);
492
+ }
493
+
494
+ public function __toString() {
495
+ $output = '';
496
+ if (isset($this->address_filters_list)) {
497
+ $compact_value = $this->code;
498
+ $full_value = $this->name;
499
+ $output .= '<span class="preview-item address-filter preview-item-group"'
500
+ .' full-value="'.$full_value.'" compact-value="'.$compact_value.'" original-value="'.$this->data['original'].'"><span class="preview-item-group-label">'.$this->label.'</span>';
501
+ foreach ($this->address_filters_list as $address_filter) {
502
+ $output .= $address_filter;
503
+ }
504
+ $output .= '</span>';
505
+ } else {
506
+ if (isset($this->code)) {
507
+ $compact_value = $this->code.(isset($this->data['region_codes']) && $this->data['region_codes']!='' ? '('.$this->data['region_codes'].')' : '');
508
+ $full_value = $this->name.(isset($this->data['region_codes']) && $this->data['region_codes']!='' ? ' ('.$this->data['region_codes'].')' : '');
509
+ } else {
510
+ $compact_value = $this->data['original'];
511
+ $full_value = $this->data['original'];
512
+ }
513
+ $output .= '<span class="preview-item address-filter country-'.$this->code.' '.implode(' ',$this->classes)
514
+ .'" country-code="'.$this->code.'" full-value="'.$full_value.'" compact-value="'.$compact_value.'" original-value="'.$this->data['original'].'">'
515
+ .$this->label.'</span>';
516
+ }
517
+ return $output;
518
+ }
519
+ }
520
+
521
+
522
+ ?>
app/code/community/Owebia/Shipping2/includes/OS2_CustomerGroup.php ADDED
@@ -0,0 +1,79 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+
4
+ class CustomerGroup
5
+ {
6
+ private static $CUSTOMER_GROUP_COLLECTION;
7
+
8
+ private $input;
9
+ private $customer_group;
10
+ private $classes;
11
+ private $label;
12
+
13
+ public static function getCustomerGroups() {
14
+ if (isset(self::$CUSTOMER_GROUP_COLLECTION)) return self::$CUSTOMER_GROUP_COLLECTION;
15
+ else return self::$CUSTOMER_GROUP_COLLECTION = Mage::getResourceModel('customer/group_collection');
16
+ }
17
+
18
+ public function CustomerGroup($input) {
19
+ $this->input = $input;
20
+ $this->label = null;
21
+ $this->classes = array();
22
+ $this->customer_group = null;
23
+ $this->parse();
24
+ }
25
+
26
+ private function setCustomerGroup($customer_group) {
27
+ $this->customer_group = $customer_group;
28
+ $this->classes = array('known');
29
+ $this->label = $customer_group->getCode();
30
+ }
31
+
32
+ public function parse() {
33
+ $input = trim($this->input);
34
+ $customer_groups = self::getCustomerGroups();
35
+ if (ctype_digit($input)) {
36
+ $customer_id = (int)$input;
37
+ foreach ($customer_groups as $group) {
38
+ if ($group->getId()==$customer_id) {
39
+ $this->setCustomerGroup($group);
40
+ break;
41
+ }
42
+ }
43
+ }
44
+ if (!isset($this->customer_group)) {
45
+ $customer_code = $input;
46
+ foreach ($customer_groups as $group) {
47
+ if ($group->getCode()==$customer_code) {
48
+ $this->setCustomerGroup($group);
49
+ break;
50
+ }
51
+ }
52
+ }
53
+ if (!isset($this->customer_group)) {
54
+ $this->classes = array('unknown');
55
+ $this->label = $this->input;
56
+ }
57
+ }
58
+
59
+ public function hasClass($class) {
60
+ return in_array($class,$this->classes);
61
+ }
62
+
63
+ public function __toString() {
64
+ $output = '';
65
+ if (isset($this->customer_group)) {
66
+ $compact_value = $this->customer_group->getId();
67
+ $full_value = $this->customer_group->getCode();
68
+ } else {
69
+ $compact_value = $this->input;
70
+ $full_value = $this->input;
71
+ }
72
+ $output .= '<span class="preview-item customer-group '.implode(' ',$this->classes)
73
+ .'" full-value="'.$full_value.'" compact-value="'.$compact_value.'" original-value="'.$this->input.'">'
74
+ .$this->label.'</span>';
75
+ return $output;
76
+ }
77
+ }
78
+
79
+ ?>
app/code/community/Owebia/Shipping2/includes/OwebiaShippingHelper.php ADDED
@@ -0,0 +1,1281 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Magento Owebia Shipping Module
5
+ *
6
+ * NOTICE OF LICENSE
7
+ *
8
+ * This source file is subject to the Open Software License (OSL 3.0)
9
+ * that is bundled with this package in the file LICENSE.txt.
10
+ * It is also available through the world-wide-web at this URL:
11
+ * http://opensource.org/licenses/osl-3.0.php
12
+ * If you did not receive a copy of the license and are unable to
13
+ * obtain it through the world-wide-web, please send an email
14
+ * to license@magentocommerce.com so we can send you a copy immediately.
15
+ *
16
+ * @category Owebia
17
+ * @copyright Copyright (c) 2008-10 Owebia (http://www.owebia.com)
18
+ * @author Antoine Lemoine
19
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
20
+ */
21
+
22
+ class OwebiaShippingHelper
23
+ {
24
+ public static $DEBUG_INDEX_COUNTER = 0;
25
+ public static $FLOAT_REGEX = '[-]?\d+(?:[.]\d+)?';
26
+ public static $POSITIVE_FLOAT_REGEX = '\d+(?:[.]\d+)?';
27
+ //public static $COUPLE_REGEX = '(?:[0-9.]+|\*)(?:\[|\])?\:[0-9.]+(?:\:[0-9.]+%?)*';
28
+ public static $COUPLE_REGEX = '(?:[0-9.]+|\*) *(?:\[|\])? *\: *[0-9.]+';
29
+ public static $UNCOMPRESSED_STRINGS = array(
30
+ ' product.attribute.',
31
+ ' product.option.',
32
+ ' product.stock.',
33
+ '{product.attribute.',
34
+ '{product.option.',
35
+ '{product.stock.',
36
+ '{product.weight}',
37
+ '{product.quantity}',
38
+ '{cart.weight}',
39
+ '{cart.quantity}',
40
+ '{cart.price_including_tax}',
41
+ '{cart.price_excluding_tax}',
42
+ '{cart.',
43
+ '{customvar.',
44
+ '{selection.weight}',
45
+ '{selection.quantity}',
46
+ '{selection.',
47
+ '{destination.country.',
48
+ '{foreach ',
49
+ '{/foreach}',
50
+ );
51
+ public static $COMPRESSED_STRINGS = array(
52
+ ' p.a.',
53
+ ' p.o.',
54
+ ' p.s.',
55
+ '{p.a.',
56
+ '{p.o.',
57
+ '{p.s.',
58
+ '{p.w}',
59
+ '{p.qty}',
60
+ '{c.w}',
61
+ '{c.qty}',
62
+ '{c.pit}',
63
+ '{c.pet}',
64
+ '{c.',
65
+ '{v.',
66
+ '{s.w}',
67
+ '{s.qty}',
68
+ '{s.',
69
+ '{dest.ctry.',
70
+ '{each ',
71
+ '{/each}',
72
+ );
73
+
74
+ public static function getDefaultProcessData() {
75
+ $timestamp = time();
76
+ $properties = array(
77
+ 'info.php.version' => PHP_VERSION,
78
+ 'info.magento.version' => '',
79
+ 'info.module.version' => '',
80
+ 'info.carrier.code' => '',
81
+ 'cart.price_excluding_tax' => 0,
82
+ 'cart.price_including_tax' => 0,
83
+ 'cart.price-tax+discount' => 0,
84
+ 'cart.price-tax-discount' => 0,
85
+ 'cart.price+tax+discount' => 0,
86
+ 'cart.price+tax-discount' => 0,
87
+ 'cart.weight' => 0,
88
+ 'cart.weight.for-charge' => 0,
89
+ 'cart.weight.unit' => 'kg',
90
+ 'cart.quantity' => 0,
91
+ 'destination.country.code' => '',
92
+ 'destination.country.name' => '',
93
+ 'destination.region.code' => '',
94
+ 'destination.postcode' => '',
95
+ 'origin.country.code' => '',
96
+ 'origin.country.name' => '',
97
+ 'origin.region.code' => '',
98
+ 'origin.postcode' => '',
99
+ 'customer.group.id' => '',
100
+ 'customer.group.code' => '',
101
+ 'free_shipping' => false,
102
+ 'store.id' => '',
103
+ 'store.code' => '',
104
+ 'store.name' => '',
105
+ 'store.address' => '',
106
+ 'store.phone' => '',
107
+ 'date.timestamp' => $timestamp,
108
+ 'date.year' => (int)date('Y',$timestamp),
109
+ 'date.month' => (int)date('m',$timestamp),
110
+ 'date.day' => (int)date('d',$timestamp),
111
+ 'date.hour' => (int)date('H',$timestamp),
112
+ 'date.minute' => (int)date('i',$timestamp),
113
+ 'date.second' => (int)date('s',$timestamp),
114
+ );
115
+ return $properties;
116
+ }
117
+
118
+ protected $_input;
119
+ protected $_config;
120
+ protected $_messages;
121
+ protected $_formula_cache;
122
+ protected $_expression_cache;
123
+ public $debug_code = null;
124
+ public $debug_output = '';
125
+ public $debug_header = null;
126
+
127
+ public function OwebiaShippingHelper($input) {
128
+ $this->_formula_cache = array();
129
+ $this->_messages = array();
130
+ $this->_input = $input;
131
+ $this->_config = array();
132
+ $this->_parseInput();
133
+ }
134
+
135
+ public function debug($text) {
136
+ $this->debug_output .= "<p>".$text."</p>";
137
+ }
138
+
139
+ public function getDebug() {
140
+ $index = $this->debug_code.'-'.self::$DEBUG_INDEX_COUNTER++;
141
+ $output = "<style rel=\"stylesheet\" type=\"text/css\">"
142
+ .".osh-debug{background:#000;color:#bbb;-webkit-opacity:0.9;-moz-opacity:0.9;opacity:0.9;text-align:left;white-space:pre-wrap;}"
143
+ .".osh-debug p{margin:2px 0;}"
144
+ .".osh-debug .osh-formula{color:#f90;} .osh-key{color:#0099f7;}"
145
+ .".osh-debug .osh-error{color:#f00;} .osh-warning{color:#ff0;} .osh-info{color:#7bf700;}"
146
+ .".osh-debug .osh-debug-content{padding:10px;}"
147
+ .".osh-debug .osh-replacement{color:#ff3000;}"
148
+ ."</style>"
149
+ ."<div id=\"osh-debug-".$index."\" class=\"osh-debug\"><pre class=\"osh-debug-content\"><span style=\"float:right;cursor:pointer;\" onclick=\"document.getElementById('osh-debug-".$index."').style.display = 'none';\">[<span style=\"padding:0 5px;color:#f00;\">X</span>]</span>"
150
+ ."<p>".$this->debug_header."</p>".$this->debug_output."</pre></div>";
151
+ return $output;
152
+ }
153
+
154
+ public function initDebug($code, $data) {
155
+ $header = 'DEBUG app/code/community/Owebia/Shipping2/includes/OwebiaShippingHelper.php<br/>';
156
+ foreach ($data as $key => $data) {
157
+ $header .= ' <span class="osh-key">'.str_replace('.','</span>.<span class="osh-key">',$key).'</span> = <span class="osh-formula">'.$this->_toString($data).'</span><br/>';
158
+ }
159
+ $this->debug_code = $code;
160
+ $this->debug_header = $header;
161
+ }
162
+
163
+ public function getConfig() {
164
+ return $this->_config;
165
+ }
166
+
167
+ public function getMessages() {
168
+ $messages = $this->_messages;
169
+ $this->_messages = array();
170
+ return $messages;
171
+ }
172
+
173
+ public function formatConfig($compress,$keys_to_remove=array()) {
174
+ $output = '';
175
+ foreach ($this->_config as $code => $row) {
176
+ if (!isset($row['lines'])) {
177
+ if (isset($row['*comment']['value'])) {
178
+ $output .= trim($row['*comment']['value'])."\n";
179
+ }
180
+ $output .= '{'.($compress ? '' : "\n");
181
+ foreach ($row as $key => $property) {
182
+ if (substr($key,0,1)!='*' && !in_array($key,$keys_to_remove)) {
183
+ $value = $property['value'];
184
+ if (isset($property['comment'])) $output .= ($compress ? '' : "\t").'/* '.$property['comment'].' */'.($compress ? '' : "\n");
185
+ $output .= ($compress ? '' : "\t").$key.':'.($compress ? '' : ' ');
186
+ if (is_bool($value)) $output .= $value ? 'true' : 'false';
187
+ else if ((string)((int)$value)==$value) $output .= $value;
188
+ else if ((string)((float)$value)==$value) $output .= ($compress ? (float)$value : $value);
189
+ else $output .= '"'.str_replace('"','\\"',$value).'"';
190
+ $output .= ','.($compress ? '' : "\n");
191
+ }
192
+ }
193
+ if ($compress) $output = preg_replace('/,$/','',$output);
194
+ $output .= "}\n".($compress ? '' : "\n");
195
+ } else {
196
+ $output .= $row['lines']."\n";
197
+ }
198
+ }
199
+ return $compress ? $this->compress($output) : $this->uncompress($output);
200
+ }
201
+
202
+ public function checkConfig() {
203
+ $timestamp = time();
204
+ $process = array(
205
+ 'cart.products' => array(),
206
+ 'config' => $this->_config,
207
+ 'data' => self::getDefaultProcessData(),
208
+ 'result' => null,
209
+ );
210
+ foreach ($this->_config as $code => &$row) {
211
+ $this->processRow($process,$row,$check_all_conditions=true);
212
+ foreach ($row as $property_key => $property_value) {
213
+ if (substr($property_key,0,1)!='*') $this->getRowProperty($row,$property_key);
214
+ }
215
+ }
216
+ }
217
+
218
+ public function processRow($process, &$row, $is_checking=false) {
219
+ if (!isset($row['*code'])) return;
220
+
221
+ self::debug('process row <span class="osh-key">'.$row['*code'].'</span>');
222
+ if (!isset($row['label']['value'])) $row['label']['value'] = '***';
223
+
224
+ $enabled = $this->getRowProperty($row,'enabled');
225
+ if (isset($enabled)) {
226
+ if (!$is_checking && !$enabled) {
227
+ $this->addMessage('info',$row,'enabled','Configuration disabled');
228
+ return new OS_Result(false);
229
+ }
230
+ }
231
+
232
+ $conditions = $this->getRowProperty($row,'conditions');
233
+ if (isset($conditions)) {
234
+ $result = $this->_processFormula($process,$row,'conditions',$conditions,$is_checking);
235
+ if (!$is_checking) {
236
+ if (!$result->success) return $result;
237
+ if (!$result->result) {
238
+ $this->addMessage('info',$row,'conditions',"The cart doesn't match conditions");
239
+ return new OS_Result(false);
240
+ }
241
+ }
242
+ }
243
+
244
+ $destination = $this->getRowProperty($row,'destination');
245
+ if (isset($destination)) {
246
+ $destination_match = $this->_addressMatch($destination,array(
247
+ 'country_code' => $process['data']['destination.country.code'],
248
+ 'region_code' => $process['data']['destination.region.code'],
249
+ 'postcode' => $process['data']['destination.postcode']
250
+ ));
251
+ if (!$is_checking && !$destination_match) {
252
+ $this->addMessage('info',$row,'destination',"The shipping method doesn't cover the zone");
253
+ return new OS_Result(false);
254
+ }
255
+ }
256
+
257
+ $origin = $this->getRowProperty($row,'origin');
258
+ if (isset($origin)) {
259
+ $origin_match = $this->_addressMatch($origin,array(
260
+ 'country_code' => $process['data']['origin.country.code'],
261
+ 'region_code' => $process['data']['origin.region.code'],
262
+ 'postcode' => $process['data']['origin.postcode']
263
+ ));
264
+ if (!$is_checking && !$origin_match) {
265
+ $this->addMessage('info',$row,'origin',"The shipping method doesn't match to shipping origin");
266
+ return new OS_Result(false);
267
+ }
268
+ }
269
+
270
+ $customer_groups = $this->getRowProperty($row,'customer_groups');
271
+ if (isset($customer_groups)) {
272
+ $groups = explode(',',$customer_groups);
273
+ $group_match = false;
274
+ //self::debug('code:'.$process['data']['customer.group.code'].', id:'.$process['data']['customer.group.id']);
275
+ foreach ($groups as $group) {
276
+ $group = trim($group);
277
+ if ($group=='*' || $group==$process['data']['customer.group.code'] || ctype_digit($group) && $group==$process['data']['customer.group.id']) {
278
+ self::debug(' group <span class="osh-replacement">'.$process['data']['customer.group.code'].'</span>'
279
+ .' (id:<span class="osh-replacement">'.$process['data']['customer.group.id'].'</span>) matches');
280
+ $group_match = true;
281
+ break;
282
+ }
283
+ }
284
+ if (!$is_checking && !$group_match) {
285
+ $this->addMessage('info',$row,'customer_groups',"The shipping method doesn't match to customer group (%s)",$process['data']['customer.group.code']);
286
+ return new OS_Result(false);
287
+ }
288
+ }
289
+
290
+ $fees = $this->getRowProperty($row,'fees');
291
+ if (isset($fees)) {
292
+ $result = $this->_processFormula($process,$row,'fees',$fees,$is_checking);
293
+ if (!$result->success) return $result;
294
+ self::debug(' => <span class="osh-info">result = <span class="osh-formula">'.$this->_toString($result->result).'</span>');
295
+ return new OS_Result(true,(float)$result->result);
296
+ }
297
+ return new OS_Result(false);
298
+ }
299
+
300
+ public function getRowProperty(&$row, $key, $original_row=null, $original_key=null) {
301
+ $property = null;
302
+ $output = null;
303
+ if (isset($original_row) && isset($original_key) && $original_row['*code']==$row['*code'] && $original_key==$key) {
304
+ $this->addMessage('error',$row,$key,'Infinite loop %s',"<span class=\"code\">{".$row['*code'].'.'.$key."}</span>");
305
+ return array('error' => 'Infinite loop');
306
+ }
307
+ if (isset($row[$key]['value'])) {
308
+ $property = $row[$key]['value'];
309
+ $output = $property;
310
+ self::debug(' get <span class="osh-key">'.$row['*code'].'</span>.<span class="osh-key">'.$key.'</span> = <span class="osh-formula">'.$this->_toString($property).'</span>');
311
+ preg_match_all('/{([a-z0-9_]+)\.([a-z0-9_]+)}/i',$output,$result_set,PREG_SET_ORDER);
312
+ foreach ($result_set as $result) {
313
+ list($original,$ref_code,$ref_key) = $result;
314
+ if (!in_array($ref_code,array('module','date','store','cart','product','selection','customvar'))) {
315
+ if ($ref_code==$row['code']['value'] && $ref_key==$key) {
316
+ $this->addMessage('error',$row,$key,'Infinite loop %s',"<span class=\"code\">".$original."</span>");
317
+ return null;
318
+ }
319
+ if (isset($this->_config[$ref_code][$ref_key]['value'])) {
320
+ $replacement = $this->getRowProperty($this->_config[$ref_code],$ref_key,
321
+ isset($original_row) ? $original_row : $row,isset($original_key) ? $original_key : $key);
322
+ if (is_array($replacement) && isset($replacement['error'])) {
323
+ return isset($original_row) ? $replacement : 'false';
324
+ }
325
+ } else {
326
+ //$this->addMessage('error',$row,$key,'Non-existent property %s',"<span class=\"code\">".$original."</span>");
327
+ $replacement = $original;//'null';
328
+ }
329
+ $output = $this->replace($original,$replacement,$output);
330
+ }
331
+ }
332
+ } else {
333
+ self::debug(' get <span class="osh-key">'.$row['*code'].'</span>.<span class="osh-key">'.$key.'</span> = <span class="osh-formula">null</span>');
334
+ }
335
+ return $output;
336
+ }
337
+
338
+ protected function _toString($value) {
339
+ if (!isset($value)) return 'null';
340
+ else if (is_bool($value)) return $value ? 'true' : 'false';
341
+ else return $value;
342
+ }
343
+
344
+ protected function replace($from, $to, $input) {
345
+ if ($from===$to) return $input;
346
+ if (strpos($input,$from)===false) return $input;
347
+ $to = $this->_toString($to);
348
+ 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>');
349
+ return str_replace($from,$to,$input);
350
+ }
351
+
352
+ protected function _min() {
353
+ $args = func_get_args();
354
+ $min = null;
355
+ foreach ($args as $arg) {
356
+ if (isset($arg) && (!isset($min) || $min>$arg)) $min = $arg;
357
+ }
358
+ return $min;
359
+ }
360
+
361
+ protected function _max() {
362
+ $args = func_get_args();
363
+ $max = null;
364
+ foreach ($args as $arg) {
365
+ if (isset($arg) && (!isset($max) || $max<$arg)) $max = $arg;
366
+ }
367
+ return $max;
368
+ }
369
+
370
+ protected function _processFormula($process, &$row, $property_key, $formula_string, $is_checking, $use_cache=true)
371
+ {
372
+ $result = $this->_prepareFormula($process,$row,$property_key,$formula_string,$is_checking,$use_cache);
373
+ if (!$result->success) return $result;
374
+
375
+ $eval_result = $this->_evalFormula($result->result);
376
+ if (!isset($eval_result)) {
377
+ $this->addMessage('error',$row,$property_key,'Invalid formula');
378
+ $result = new OS_Result(false);
379
+ if ($use_cache) $this->setCache($formula_string,$result);
380
+ return $result;
381
+ }
382
+ self::debug(' formula evaluation = <span class="osh-formula">'.$this->_toString($eval_result).'</span>');
383
+ $result = new OS_Result(true,$eval_result);
384
+ if ($use_cache) $this->setCache($formula_string,$result);
385
+ return $result;
386
+ }
387
+
388
+ public function evalInput($process, $row, $property_key, $input) {
389
+ $result = $this->_prepareFormula($process,$row,$property_key,$input,$is_checking=false,$use_cache=true);
390
+ return $result->success ? $result->result : $input;
391
+ }
392
+
393
+ protected function setCache($expression, $value) {
394
+ if ($value instanceof OS_Result) {
395
+ $this->_formula_cache[$expression] = $value;
396
+ self::debug(' cache <span class="osh-replacement">'.$expression.'</span> = <span class="osh-formula">'.$this->_toString($this->_formula_cache[$expression]).'</span>');
397
+ } else {
398
+ $value = $this->_toString($value);
399
+ $this->_expression_cache[$expression] = $value;
400
+ self::debug(' cache <span class="osh-replacement">'.$expression.'</span> = <span class="osh-formula">'.$value.'</span>');
401
+ }
402
+ }
403
+
404
+ protected function _prepareFormula($process, $row, $property_key, $formula_string, $is_checking, $use_cache=true)
405
+ {
406
+ if ($use_cache && isset($this->_formula_cache[$formula_string])) {
407
+ $result = $this->_formula_cache[$formula_string];
408
+ self::debug(' get cached formula <span class="osh-replacement">'.$formula_string.'</span> = <span class="osh-formula">'.$this->_toString($result->result).'</span>');
409
+ return $result;
410
+ }
411
+
412
+ $formula = $formula_string;
413
+ //self::debug(' formula = <span class="osh-formula">'.$formula.'</span>');
414
+
415
+ while (preg_match("#{foreach product\.((?:attribute|option)\.(?:[a-z0-9_]+))}(.*){/foreach}#i",$formula,$result)) {
416
+ $original = $result[0];
417
+ if ($use_cache && isset($this->_expression_cache[$original])) {
418
+ $replacement = $this->_expression_cache[$original];
419
+ self::debug(' get cached expression <span class="osh-replacement">'.$original.'</span> = <span class="osh-formula">'.$replacement.'</span>');
420
+ }
421
+ else {
422
+ $replacement = 0;
423
+ list($filter_property_type,$filter_property_name) = explode('.',$result[1]);
424
+ $selections = array();
425
+ self::debug(' :: foreach <span class="osh-key">'.$filter_property_type.'</span>.<span class="osh-key">'.$filter_property_name.'</span>');
426
+ foreach ($process['cart.products'] as $product) {
427
+ $tmp_value = $this->_getProductProperty($product,$filter_property_type,$filter_property_name,$get_by_id=false);
428
+ 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>');
429
+ $key = 'val_'.$tmp_value;
430
+ $sel = isset($selections[$key]) ? $selections[$key] : null;
431
+ $selections[$key]['products'][] = $product;
432
+ $selections[$key]['weight'] = (isset($sel['weight']) ? $sel['weight'] : 0)+$product->getAttribute('weight')*$product->getQuantity();
433
+ $selections[$key]['quantity'] = (isset($sel['quantity']) ? $sel['quantity'] : 0)+$product->getQuantity();
434
+ }
435
+ self::debug(' :: start foreach');
436
+ foreach ($selections as $selection) {
437
+ $process2 = $process;
438
+ $process2['cart.products'] = $selection['products'];
439
+ $process2['data']['selection.quantity'] = $selection['quantity'];
440
+ $process2['data']['selection.weight'] = $selection['weight'];
441
+ $process_result = $this->_processFormula($process2,$row,$property_key,$result[2],$is_checking,$tmp_use_cache=false);
442
+ $replacement += $process_result->result;
443
+ }
444
+ self::debug(' :: end foreach <span class="osh-key">'.$filter_property_type.'</span>.<span class="osh-key">'.$filter_property_name.'</span>');
445
+ if ($use_cache) $this->setCache($original,$replacement);
446
+ }
447
+ $formula = $this->replace($original,$replacement,$formula);
448
+ }
449
+
450
+ $formula = str_replace(array("\n","\t"),array('',''),$formula);
451
+
452
+ while (preg_match("#{customvar\.([a-z0-9_]+)}#i",$formula,$result)) {
453
+ $original = $result[0];
454
+ $replacement = Mage::getModel('core/variable')->loadByCode($result[1])->getValue('plain');
455
+ $formula = $this->replace($original,$replacement,$formula);
456
+ }
457
+
458
+ $first_product = isset($process['cart.products'][0]) ? $process['cart.products'][0] : null;
459
+ if (!isset($process['data']['selection.weight'])) $process['data']['selection.weight'] = $process['data']['cart.weight'];
460
+ if (!isset($process['data']['selection.quantity'])) $process['data']['selection.quantity'] = $process['data']['cart.quantity'];
461
+ $process['data']['product.weight'] = isset($first_product) ? $first_product->getAttribute('weight') : 0;
462
+ $process['data']['product.quantity'] = isset($first_product) ? $first_product->getQuantity() : 0;
463
+
464
+ foreach ($process['data'] as $original => $replacement) {
465
+ $formula = $this->replace('{'.$original.'}',$replacement,$formula);
466
+ }
467
+
468
+ if (isset($first_product)) {
469
+ while (preg_match("#{product\.(attribute|option|stock)\.([a-z0-9_+-]+)}#i",$formula,$result)) {
470
+ $original = $result[0];
471
+ switch ($result[1]) {
472
+ case 'attribute': $replacement = $first_product->getAttribute($result[2]); break;
473
+ case 'option': $replacement = $first_product->getOption($result[2]); break;
474
+ case 'stock': $replacement = $first_product->getStockData($result[2]); break;
475
+ }
476
+ $formula = $this->replace($original,$replacement,$formula);
477
+ }
478
+ }
479
+
480
+ while (preg_match("/{(count) products(?: where ([^}]+))?}/i",$formula,$result)
481
+ || preg_match("/{(sum|min|max|count distinct) product\.(attribute|option|stock)\.([a-z0-9_+-]+)(?: where ([^}]+))?}/i",$formula,$result)) {
482
+ $original = $result[0];
483
+ if ($use_cache && isset($this->_expression_cache[$original])) {
484
+ $replacement = $this->_expression_cache[$original];
485
+ self::debug(' get cached expression <span class="osh-replacement">'.$original.'</span> = <span class="osh-formula">'.$replacement.'</span>');
486
+ }
487
+ else {
488
+ $replacement = $this->_processProductProperty($process['cart.products'],$result);
489
+ if ($use_cache) $this->setCache($result[0],$replacement);
490
+ }
491
+ $formula = $this->replace($original,$replacement,$formula);
492
+ }
493
+
494
+ //while (preg_match("/{table '([^']+)' ([^}]+)}/",$formula,$result))
495
+ while (preg_match("/{table ([^}]+) in ([0-9\.:,\*\[\] ]+)}/i",$formula,$result)) {
496
+ $original = $result[0];
497
+ if ($use_cache && isset($this->_expression_cache[$original])) {
498
+ $replacement = $this->_expression_cache[$original];
499
+ self::debug(' get cached expression <span class="osh-replacement">'.$original.'</span> = <span class="osh-formula">'.$replacement.'</span>');
500
+ } else {
501
+ $reference_value = $this->_evalFormula($result[1]);
502
+ if (isset($reference_value)) {
503
+ $fees_table_string = $result[2];
504
+
505
+ if (!preg_match('#^'.self::$COUPLE_REGEX.'(?:, *'.self::$COUPLE_REGEX.')*$#',$fees_table_string)) {
506
+ $this->addMessage('error',$row,$property_key,'Error in table %s','<span class="osh-formula">'.htmlentities($result[0]).'</span>');
507
+ $result = new OS_Result(false);
508
+ if ($use_cache) $this->setCache($formula_string,$result);
509
+ return $result;
510
+ }
511
+ $fees_table = explode(',',$fees_table_string);
512
+
513
+ $replacement = null;
514
+ foreach ($fees_table as $item) {
515
+ $fee_data = explode(':',$item);
516
+
517
+ $fee = trim($fee_data[1]);
518
+ $max_value = trim($fee_data[0]);
519
+
520
+ $last_char = $max_value{strlen($max_value)-1};
521
+ if ($last_char=='[') $including_max_value = false;
522
+ else if ($last_char==']') $including_max_value = true;
523
+ else $including_max_value = true;
524
+
525
+ $max_value = str_replace(array('[',']'),'',$max_value);
526
+
527
+ if ($max_value=='*' || $including_max_value && $reference_value<=$max_value || !$including_max_value && $reference_value<$max_value) {
528
+ $replacement = $fee;//$this->_calculateFee($process,$fee,$var);
529
+ break;
530
+ }
531
+ }
532
+ }
533
+ $replacement = $this->_toString($replacement);
534
+ if ($use_cache) $this->setCache($original,$replacement);
535
+ }
536
+ $formula = $this->replace($original,$replacement,$formula);
537
+ }
538
+ $result = new OS_Result(true,$formula);
539
+ return $result;
540
+ }
541
+
542
+ protected function _evalFormula($formula) {
543
+ if (is_bool($formula)) return $formula;
544
+ 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'
545
+ .'|in_array\(\'(?:[^\']*)\', *array\( *(?:\'(?:[^\']+)\') *(?: *, *\'(?:[^\']+)\')* *\) *\)'
546
+ .'|\'[^\']*\'|[0-9,\'\.\-\(\)\*\/\?\:\+\<\>\=\&\|%! ])*$/',$formula)) {
547
+ $errors = array(
548
+ PREG_NO_ERROR => 'PREG_NO_ERROR',
549
+ PREG_INTERNAL_ERROR => 'PREG_INTERNAL_ERROR',
550
+ PREG_BACKTRACK_LIMIT_ERROR => 'PREG_BACKTRACK_LIMIT_ERROR',
551
+ PREG_RECURSION_LIMIT_ERROR => 'PREG_RECURSION_LIMIT_ERROR',
552
+ PREG_BAD_UTF8_ERROR => 'PREG_BAD_UTF8_ERROR',
553
+ defined('PREG_BAD_UTF8_OFFSET_ERROR') ? PREG_BAD_UTF8_OFFSET_ERROR : 'PREG_BAD_UTF8_OFFSET_ERROR' => 'PREG_BAD_UTF8_OFFSET_ERROR',
554
+ );
555
+ $error = preg_last_error();
556
+ if (isset($errors[$error])) $error = $errors[$error];
557
+ self::debug(' doesn\'t match ('.$error.')');
558
+ return null;
559
+ }
560
+ $formula = str_replace(
561
+ array('min','max'),
562
+ array('$this->_min','$this->_max'),
563
+ $formula
564
+ );
565
+ $eval_result = null;
566
+ @eval('$eval_result = ('.$formula.');');
567
+ return $eval_result;
568
+ }
569
+
570
+ protected function _getOptionsAndData($string) {
571
+ if (preg_match('/^(\\s*\(\\s*([^\] ]*)\\s*\)\\s*)/',$string,$result)) {
572
+ $options = $result[2];
573
+ $data = str_replace($result[1],'',$string);
574
+ } else {
575
+ $options = '';
576
+ $data = $string;
577
+ }
578
+ return array(
579
+ 'options' => $options,
580
+ 'data' => $data,
581
+ );
582
+ }
583
+
584
+ public function compress($input) {
585
+ /*if (preg_match_all("/{table (.*) in (".self::$COUPLE_REGEX."(?:, *".self::$COUPLE_REGEX.")*)}/imsU",$input,$result,PREG_SET_ORDER)) {
586
+ foreach ($result as $result_i) {
587
+ $fees_table = explode(',',$result_i[2]);
588
+ $value = null;
589
+ foreach ($fees_table as $index => $item) {
590
+ list($max_value,$fee) = explode(':',$item);
591
+ $last_char = $max_value{strlen($max_value)-1};
592
+ if (in_array($last_char,array('[',']'))) {
593
+ $including_char = $last_char;
594
+ $max_value = str_replace(array('[',']'),'',$max_value);
595
+ } else $including_char = '';
596
+ $fees_table[$index] = ((float)$max_value).$including_char.':'.((float)$fee);
597
+ }
598
+ $input = str_replace($result_i[2],implode(',',$fees_table),$input);
599
+ $input = str_replace($result_i[1],trim($result_i[1]),$input);
600
+ }
601
+ }
602
+ if (preg_match_all("#{foreach ([^}]*)}(.*){/foreach}#imsU",$input,$result,PREG_SET_ORDER)) {
603
+ foreach ($result as $result_i) {
604
+ $input = str_replace($result_i[1],trim($result_i[1]),$input);
605
+ $input = str_replace($result_i[2],trim($result_i[2]),$input);
606
+ }
607
+ }
608
+ */
609
+ $input = str_replace(
610
+ self::$UNCOMPRESSED_STRINGS,
611
+ self::$COMPRESSED_STRINGS,
612
+ $input
613
+ );
614
+
615
+ if (function_exists('gzcompress') && function_exists('base64_encode')) {
616
+ $input = 'gz64'.base64_encode(gzcompress($input));
617
+ }
618
+ return '$$'.$input;
619
+ }
620
+
621
+ public function uncompress($input) {
622
+ if (substr($input,0,4)=='gz64' && function_exists('gzuncompress') && function_exists('base64_decode')) {
623
+ $input = gzuncompress(base64_decode(substr($input,4,strlen($input))));
624
+ }
625
+
626
+ /*if (preg_match_all("/{table (.*) in (".self::$COUPLE_REGEX."(?:, *".self::$COUPLE_REGEX.")*)}/iU",$input,$result,PREG_SET_ORDER)) {
627
+ foreach ($result as $result_i) {
628
+ $fees_table = explode(',',$result_i[2]);
629
+ $value = null;
630
+ foreach ($fees_table as $index => $item) {
631
+ list($max_value,$fee) = explode(':',$item);
632
+ $last_char = $max_value{strlen($max_value)-1};
633
+ if (in_array($last_char,array('[',']'))) {
634
+ $including_char = $last_char;
635
+ $max_value = str_replace(array('[',']'),'',$max_value);
636
+ } else $including_char = '';
637
+ $max_value = (float)$max_value;
638
+ $fee = (float)$fee;
639
+ $new_max_value = number_format($max_value,2,'.','');
640
+ $new_fee = number_format($fee,2,'.','');
641
+ $fees_table[$index] = (((float)$new_max_value)==$max_value ? $new_max_value : $max_value).$including_char.':'
642
+ .(((float)$new_fee)==$fee ? $new_fee : $fee);
643
+ }
644
+ $input = str_replace($result_i[2],implode(', ',$fees_table),$input);
645
+ $input = str_replace($result_i[1],trim($result_i[1]),$input);
646
+ }
647
+ }
648
+ if (preg_match_all("#{foreach ([^}]*)}(.*){/foreach}#iU",$input,$result,PREG_SET_ORDER)) {
649
+ foreach ($result as $result_i) {
650
+ $input = str_replace($result_i[1],trim($result_i[1]),$input);
651
+ $input = str_replace($result_i[2],trim($result_i[2]),$input);
652
+ }
653
+ }*/
654
+ return str_replace(
655
+ self::$COMPRESSED_STRINGS,
656
+ self::$UNCOMPRESSED_STRINGS,
657
+ $input
658
+ );
659
+ }
660
+
661
+ public function parseProperty($input) {
662
+ $value = $input==='false' || $input==='true' ? $input=='true' : str_replace('\"','"',preg_replace('/^(?:"|\')(.*)(?:"|\')$/s','$1',$input));
663
+ return $value==='' ? null : $value;
664
+ }
665
+
666
+ public function cleanProperty(&$row, $key) {
667
+ $input = $row[$key]['value'];
668
+ if (is_string($input)) {
669
+ $input = str_replace(array("\n"),array(''),$input);
670
+ while (preg_match('/({TABLE |{SUM |{COUNT | DISTINCT | IN )/',$input,$resi)) {
671
+ $input = str_replace($resi[0],strtolower($resi[0]),$input);
672
+ }
673
+
674
+ while (preg_match('/{{customVar code=([a-zA-Z0-9_-]+)}}/',$input,$resi)) {
675
+ $input = str_replace($resi[0],'{customvar.'.$resi[1].'}',$input);
676
+ }
677
+
678
+ $regex = "{(weight|products_quantity|price_including_tax|price_excluding_tax|country)}";
679
+ if (preg_match('/'.$regex.'/',$input,$resi)) {
680
+ $this->addMessage('warning',$row,$key,'Usage of deprecated syntax %s','<span class="osh-formula">'.$resi[0].'</span>');
681
+ while (preg_match('/'.$regex.'/',$input,$resi)) {
682
+ switch ($resi[1]) {
683
+ case 'price_including_tax':
684
+ case 'price_excluding_tax':
685
+ case 'weight':
686
+ $input = str_replace($resi[0],"{cart.".$resi[1]."}",$input);
687
+ break;
688
+ case 'products_quantity': $input = str_replace($resi[0],"{cart.quantity}",$input); break;
689
+ case 'country': $input = str_replace($resi[0],"{destination.country.name}",$input); break;
690
+ }
691
+ }
692
+ }
693
+
694
+ $regex1 = "{copy '([a-zA-Z0-9_]+)'\.'([a-zA-Z0-9_]+)'}";
695
+ if (preg_match('/'.$regex1.'/',$input,$resi)) {
696
+ $this->addMessage('warning',$row,$key,'Usage of deprecated syntax %s','<span class="osh-formula">'.$resi[0].'</span>');
697
+ while (preg_match('/'.$regex1.'/',$input,$resi)) $input = str_replace($resi[0],'{'.$resi[1].'.'.$resi[2].'}',$input);
698
+ }
699
+
700
+ $regex1 = "{(count|all|any) (attribute|option) '([^'\)]+)' ?((?:==|<=|>=|<|>|!=) ?(?:".self::$FLOAT_REGEX."|true|false|'[^'\)]*'))}";
701
+ $regex2 = "{(sum) (attribute|option) '([^'\)]+)'}";
702
+ if (preg_match('/'.$regex1.'/',$input,$resi) || preg_match('/'.$regex2.'/',$input,$resi)) {
703
+ $this->addMessage('warning',$row,$key,'Usage of deprecated syntax %s','<span class="osh-formula">'.$resi[0].'</span>');
704
+ while (preg_match('/'.$regex1.'/',$input,$resi) || preg_match('/'.$regex2.'/',$input,$resi)) {
705
+ switch ($resi[1]) {
706
+ case 'count': $input = str_replace($resi[0],"{count products where product.".$resi[2]."s.".$resi[3].$resi[4]."}",$input); break;
707
+ case 'all': $input = str_replace($resi[0],"{count products where product.".$resi[2]."s.".$resi[3].$resi[4]."}=={products_quantity}",$input); break;
708
+ case 'any': $input = str_replace($resi[0],"{count products where product.".$resi[2]."s.".$resi[3].$resi[4]."}>0",$input); break;
709
+ case 'sum': $input = str_replace($resi[0],"{sum product.".$resi[2].".".$resi[3]."}",$input); break;
710
+ }
711
+ }
712
+ }
713
+
714
+ $regex = "((?:{| )product.(?:attribute|option))s.";
715
+ if (preg_match('/'.$regex.'/',$input,$resi)) {
716
+ $this->addMessage('warning',$row,$key,'Usage of deprecated syntax %s','<span class="osh-formula">'.$resi[0].'</span>');
717
+ while (preg_match('/'.$regex.'/',$input,$resi)) {
718
+ $input = str_replace($resi[0],$resi[1].'.',$input);
719
+ }
720
+ }
721
+
722
+ $regex = "{table '([^']+)' (".self::$COUPLE_REGEX."(?:, *".self::$COUPLE_REGEX.")*)}";
723
+ if (preg_match('/'.$regex.'/',$input,$resi)) {
724
+ $this->addMessage('warning',$row,$key,'Usage of deprecated syntax %s','<span class="osh-formula">'.$resi[0].'</span>');
725
+ while (preg_match('/'.$regex.'/',$input,$resi)) {
726
+ switch ($resi[1]) {
727
+ case 'products_quantity':
728
+ $input = str_replace($resi[0],"{table {cart.weight} in ".$resi[2]."}*{cart.quantity}",$input);
729
+ break;
730
+ default:
731
+ $input = str_replace($resi[0],"{table {cart.".$resi[1]."} in ".$resi[2]."}",$input);
732
+ break;
733
+ }
734
+ }
735
+ }
736
+ }
737
+ $row[$key]['value'] = $input;
738
+ }
739
+
740
+ protected function _parseInput() {
741
+ $config_string = str_replace(
742
+ array('&gt;','&lt;','“','”',utf8_encode(chr(147)),utf8_encode(chr(148)),'&laquo;','&raquo;',"\r\n","\t"),
743
+ array('>','<','"','"','"','"','"','"',"\n",' '),
744
+ $this->_input
745
+ );
746
+
747
+ if (substr($config_string,0,2)=='$$') $config_string = $this->uncompress(substr($config_string,2,strlen($config_string)));
748
+
749
+ //echo ini_get('pcre.backtrack_limit');
750
+ //exit;
751
+
752
+ $row_regex = ' *([a-z0-9_]+)\\s*:\\s*("(?:(?:[^"]|\\\\")*[^\\\\])?"|'.self::$FLOAT_REGEX.'|false|true)\\s*(,)? *(?:\\n)?';
753
+ if (!preg_match_all('/((?:#+[^{\\n]*\\s+)*)\\s*(#)?{\\s*('.$row_regex.')+\\s*}/i',$config_string,$result,PREG_SET_ORDER)) {
754
+ $errors = array(
755
+ PREG_NO_ERROR => 'PREG_NO_ERROR',
756
+ PREG_INTERNAL_ERROR => 'PREG_INTERNAL_ERROR',
757
+ PREG_BACKTRACK_LIMIT_ERROR => 'PREG_BACKTRACK_LIMIT_ERROR',
758
+ PREG_RECURSION_LIMIT_ERROR => 'PREG_RECURSION_LIMIT_ERROR',
759
+ PREG_BAD_UTF8_ERROR => 'PREG_BAD_UTF8_ERROR',
760
+ defined('PREG_BAD_UTF8_OFFSET_ERROR') ? PREG_BAD_UTF8_OFFSET_ERROR : 'PREG_BAD_UTF8_OFFSET_ERROR' => 'PREG_BAD_UTF8_OFFSET_ERROR',
761
+ );
762
+ $error = preg_last_error();
763
+ if (isset($errors[$error])) $error = $errors[$error];
764
+ self::debug(' preg_match_all error ('.$error.')');
765
+ }
766
+
767
+ $this->_config = array();
768
+ $available_keys = array(
769
+ 'code','label','enabled','description','fees','conditions','destination','origin','customer_groups','tracking_url',
770
+ 'fees_table','fees_formula','fixed_fees','reference_value',
771
+ 'prices_range','weights_range','product_properties',
772
+ 'free_shipping__fees_table','free_shipping__fees_formula','free_shipping__fixed_fees','free_shipping__label',
773
+ );
774
+
775
+ foreach ($result as $block) {
776
+ $deprecated_properties = array();
777
+ $unknown_properties = array();
778
+ $missing_semicolon = array();
779
+ $obsolete_disabling_method = array();
780
+
781
+ //$before = strstr($config_string,$block[0],true); // Seulement compatible avec PHP 5.3.0
782
+ list($before) = explode($block[0],$config_string,2);
783
+ if ($before!==false && trim($before)!='') {
784
+ $config_string = substr($config_string,strlen($before));
785
+ $this->_addIgnoredLines(trim($before));
786
+ $this->addMessage('info',$row=null,null,'Ignored lines %s','<div class="code">'.trim($before).'</div>');
787
+ }
788
+
789
+ $config_string = str_replace($block[0], '', $config_string);
790
+ preg_match_all('/'.$row_regex.'/i',$block[0],$result2,PREG_SET_ORDER);
791
+ $block_string = $block[0];
792
+
793
+ $row = array();
794
+ $i = 1;
795
+ foreach ($result2 as $data) {
796
+ $key = $data[1];
797
+ if (in_array($key,$available_keys) || substr($key,0,1)=='_') {
798
+ $property = $this->parseProperty($data[2]);
799
+ if (isset($property)) {
800
+ $row[$key] = array('value' => $property, 'original_value' => $property);
801
+ $this->cleanProperty($row,$key);
802
+ }
803
+ if ($i>2) {
804
+ $block_string = str_replace($data[0],$i==3 ? "...\n" : '',$block_string);
805
+ }
806
+ if ($i!=count($result2) && !isset($data[3]) || isset($data[3]) && $data[3]!=',') {
807
+ if (preg_match('/^("|\')(.{40})(.*)("|\')$/s',$data[2],$resultx))
808
+ $missing_semicolon[] = trim(str_replace($data[2],$resultx[1].$resultx[2].' ...'.$resultx[4],$data[0]));
809
+ else $missing_semicolon[] = trim($data[0]);
810
+ }
811
+ } else {
812
+ if (!in_array($key,$unknown_properties)) $unknown_properties[] = $key;
813
+ }
814
+ $i++;
815
+ }
816
+ if ($block[1]!='') $row['*comment']['value'] = $block[1];
817
+ if ($block[2]=='#' && !isset($row['enabled'])) {
818
+ $row['enabled'] = array('value' => false);
819
+ $obsolete_disabling_method[] = $block_string;
820
+ }
821
+
822
+ $formula_fields_to_check = array();
823
+ if (isset($row['conditions'])) $formula_fields_to_check[] = 'conditions';
824
+ if (isset($row['fees'])) $formula_fields_to_check[] = 'fees';
825
+
826
+ if (count($formula_fields_to_check)>0) {
827
+ foreach ($formula_fields_to_check as $property) {
828
+ $property_value = $row[$property]['value'];
829
+ if (preg_match('/{ +/',$property_value)) {
830
+ $this->addMessage('warning',$row,$property,'There are unwanted spaces after char `%s`','{');
831
+ $property_value = preg_replace('/{ +/','{',$property_value);
832
+ }
833
+ if (preg_match('/ +}/',$property_value)) {
834
+ $this->addMessage('warning',$row,$property,'There are unwanted spaces before char `%s`','}');
835
+ $property_value = preg_replace('/ +}/','}',$property_value);
836
+ }
837
+ if (preg_match('/ +/',$property_value)) {
838
+ $this->addMessage('warning',$row,$property,'There are unwanted multiples spaces `%s`',preg_replace('/( +)/','<span class="osh-formula">*$1*</span>',$property_value));
839
+ $property_value = preg_replace('/ +/',' ',$property_value);
840
+ }
841
+ $row[$property]['value'] = trim($property_value);
842
+ }
843
+ }
844
+
845
+ $float_value_regex = '\\s*('.self::$POSITIVE_FLOAT_REGEX.'|\*)\\s*';
846
+ $conditions = array();
847
+ if (isset($row['prices_range'])) {
848
+ if (!in_array('prices_range',$deprecated_properties)) $deprecated_properties[] = 'prices_range';
849
+
850
+ $result = $this->_getOptionsAndData($row['prices_range']['value']);
851
+ $options = $result['options'];
852
+ $prices_range = $result['data'];
853
+
854
+ if (($options=='' || in_array($options,array('incl.tax','ttc')))
855
+ && preg_match('/^\\s*(\[|\])?'.$float_value_regex.'=>'.$float_value_regex.'(\[|\])?\\s*$/',$prices_range,$result)) {
856
+ $min_price_included = $result[1]=='[';
857
+ $min_price = $result[2]=='*' ? -1 : (float)$result[2];
858
+ $max_price = $result[3]=='*' ? -1 : (float)$result[3];
859
+ $max_price_included = !isset($result[4]) || $result[4]==']' || $result[4]=='';
860
+
861
+ $tax_included = $options!='' && in_array($options,array('incl.tax','ttc')) || isset($row['reference_value']) && $row['reference_value']['value']=='price_including_tax';
862
+ $price = $tax_included ? '{cart.price_including_tax}' : '{cart.price_excluding_tax}';
863
+
864
+ if ($min_price!=-1) $conditions[] = $price.'>'.($min_price_included ? '=' : '').$min_price;
865
+ if ($max_price!=-1) $conditions[] = $price.'<'.($max_price_included ? '=' : '').$max_price;
866
+ }
867
+ 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>');
868
+ unset($row['prices_range']);
869
+ }
870
+ if (isset($row['weights_range'])) {
871
+ if (!in_array('weights_range',$deprecated_properties)) $deprecated_properties[] = 'weights_range';
872
+ if (preg_match('/^\\s*(\[|\])?'.$float_value_regex.'=>'.$float_value_regex.'(\[|\])?\\s*$/',$row['weights_range']['value'],$result)) {
873
+ $min_weight_included = $result[1]=='[';
874
+ $min_weight = $result[2]=='*' ? -1 : (float)$result[2];
875
+ $max_weight = $result[3]=='*' ? -1 : (float)$result[3];
876
+ $max_weight_included = !isset($result[4]) || $result[4]==']' || $result[4]=='';
877
+
878
+ if ($min_weight!=-1) $conditions[] = '{cart.weight}>'.($min_weight_included ? '=' : '').$min_weight;
879
+ if ($max_weight!=-1) $conditions[] = '{cart.weight}<'.($max_weight_included ? '=' : '').$max_weight;
880
+ }
881
+ 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>');
882
+ unset($row['weights_range']);
883
+ }
884
+ if (isset($row['product_properties'])) {
885
+ if (!in_array('product_properties',$deprecated_properties)) $deprecated_properties[] = 'product_properties';
886
+ $product_property_regex = "\\s*(and|or)? *\((?:(all|any|sum) )?(attribute|option) '([^'\)]+)' ?(==|=|<=|>=|<|>|!=) ?(".self::$FLOAT_REGEX."|true|false|'[^'\)]*')\)\\s*";
887
+ if (preg_match('/^('.$product_property_regex.')+$/',$row['product_properties']['value'],$result)) {
888
+ preg_match_all('/'.$product_property_regex.'/',$row['product_properties']['value'],$results,PREG_SET_ORDER);
889
+ $product_properties_condition = '';
890
+ foreach ($results as $result) {
891
+ $and_or = $result[1];
892
+ if ($and_or=='') $and_or = 'and';
893
+ $any_all_sum = $result[2];
894
+ if ($any_all_sum=='') $any_all_sum = 'any';
895
+ $property_type = $result[3];
896
+ $property_name = $result[4];
897
+ $cmp_symbol = $result[5];
898
+ if ($cmp_symbol=='=') $cmp_symbol = '==';
899
+ $cmp_value = $result[6];
900
+
901
+ $product_properties_condition .= $product_properties_condition=='' ? '' : ' '.$and_or.' ';
902
+ switch ($any_all_sum) {
903
+ case 'sum':
904
+ $product_properties_condition .= "{sum product.".$property_type.".".$property_name."}".$cmp_symbol.$cmp_value;
905
+ break;
906
+ case 'all':
907
+ $product_properties_condition .= "{count products where product.".$property_type.".".$property_name.$cmp_symbol.$cmp_value."}=={products_quantity}";
908
+ break;
909
+ case 'any':
910
+ $product_properties_condition .= "{count products where product.".$property_type.".".$property_name.$cmp_symbol.$cmp_value."}>0";
911
+ break;
912
+ }
913
+ }
914
+ if ($product_properties_condition!='') $conditions[] = $product_properties_condition;
915
+ }
916
+ 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>');
917
+ unset($row['product_properties']);
918
+ }
919
+ if (count($conditions)>0) $row['conditions'] = array('value' => count($conditions)==1 ? $conditions[0] : '('.implode(') && (',$conditions).')');
920
+
921
+ $fees = array();
922
+ if (isset($row['fees_table'])) {
923
+ if (!in_array('fees_table',$deprecated_properties)) $deprecated_properties[] = 'fees_table';
924
+ $options_and_data = $this->_getOptionsAndData($row['fees_table']['value']);
925
+ $options = $options_and_data['options'];
926
+ $fees_table_string = $options_and_data['data'];
927
+
928
+ $var = null;
929
+ if ($options=='') $var = (isset($row['reference_value']) ? $row['reference_value']['value'] : 'weight');
930
+ else if (in_array($options,array('incl.tax','ttc'))) $var = 'price_including_tax';
931
+ else if (in_array($options,array('excl.tax','ht'))) $var = 'price_excluding_tax';
932
+
933
+ if (isset($var)) {
934
+ if ($var=='price') $var = 'price_excluding_tax';
935
+ if ($var=='products_quantity') $var = 'quantity';
936
+ if (preg_match('/^[[:space:]]*\*[[:space:]]*:[[:space:]]*('.$float_value_regex.')[[:space:]]*$/s',$fees_table_string,$result)) $fees[] = $result[1];
937
+ else $fees[] = "{table {cart.".$var."} in ".str_replace(' ','',$fees_table_string)."}".($var=='quantity' ? '*{cart.quantity}' : '');
938
+ }
939
+ 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>');
940
+ unset($row['fees_table']);
941
+ }
942
+ if (isset($row['fees_formula'])) {
943
+ if (!in_array('fees_formula',$deprecated_properties)) $deprecated_properties[] = 'fees_formula';
944
+ $fees[] = str_replace(' ','',$row['fees_formula']['value']);
945
+ unset($row['fees_formula']);
946
+ }
947
+ if (isset($row['fixed_fees'])) {
948
+ if (!in_array('fixed_fees',$deprecated_properties)) $deprecated_properties[] = 'fixed_fees';
949
+ if ($row['fixed_fees']['value']!=0 || count($fees)==0) $fees[] = str_replace(' ','',$row['fixed_fees']['value']);
950
+ unset($row['fixed_fees']);
951
+ }
952
+ if (!isset($row['fees']) && count($fees)>0) $row['fees'] = array('value' => implode('+',$fees));
953
+
954
+ $fs_fees = array();
955
+ if (isset($row['free_shipping__fees_table'])) {
956
+ if (!in_array('free_shipping__fees_table',$deprecated_properties)) $deprecated_properties[] = 'free_shipping__fees_table';
957
+ $options_and_data = $this->_getOptionsAndData($row['free_shipping__fees_table']['value']);
958
+ $options = $options_and_data['options'];
959
+ $fees_table_string = $options_and_data['data'];
960
+
961
+ $var = null;
962
+ if ($options=='') $var = isset($row['reference_value']) ? $row['reference_value']['value'] : 'weight';
963
+ else if (in_array($options,array('incl.tax','ttc'))) $var = 'price_including_tax';
964
+ else if (in_array($options,array('excl.tax','ht'))) $var = 'price_excluding_tax';
965
+ if ($var=='price') $var = 'price_excluding_tax';
966
+
967
+ if (isset($var)) {
968
+ if ($var=='price') $var = 'price_excluding_tax';
969
+ if ($var=='products_quantity') $var = 'quantity';
970
+ if (preg_match('/^[[:space:]]*\*[[:space:]]*:[[:space:]]*('.$float_value_regex.')[[:space:]]*$/s',$fees_table_string,$result)) $fs_fees[] = $result[1];
971
+ else $fs_fees[] = "{table {cart.".$var."} in ".str_replace(' ','',$fees_table_string)."}".($var=='quantity' ? '*{cart.quantity}' : '');
972
+ }
973
+ 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>');
974
+ unset($row['free_shipping__fees_table']);
975
+ }
976
+ if (isset($row['free_shipping__fees_formula'])) {
977
+ if (!in_array('free_shipping__fees_formula',$deprecated_properties)) $deprecated_properties[] = 'free_shipping__fees_formula';
978
+ $fs_fees[] = str_replace(' ','',$row['free_shipping__fees_formula']['value']);
979
+ unset($row['free_shipping__fees_formula']);
980
+ }
981
+ if (isset($row['free_shipping__fixed_fees'])) {
982
+ if (!in_array('free_shipping__fixed_fees',$deprecated_properties)) $deprecated_properties[] = 'free_shipping__fixed_fees';
983
+ if ($row['free_shipping__fixed_fees']['value']!=0 || count($fees)==0) $fs_fees[] = str_replace(' ','',$row['free_shipping__fixed_fees']['value']);
984
+ unset($row['free_shipping__fixed_fees']);
985
+ }
986
+
987
+ if (isset($row['reference_value'])) {
988
+ if (!in_array('reference_value',$deprecated_properties)) $deprecated_properties[] = 'reference_value';
989
+ unset($row['reference_value']);
990
+ }
991
+
992
+ if (count($fs_fees)>0) {
993
+ $row2 = $row;
994
+ if (isset($row['code'])) $row2['code']['value'] = $row['code']['value'].'__free_shipping';
995
+ $row2['fees']['value'] = implode('+',$fs_fees);
996
+ $row2['conditions']['value'] = isset($row2['conditions']) ? '('.$row2['conditions']+') and {free_shipping}' : '{free_shipping}';
997
+ $row['conditions']['value'] = isset($row['conditions']) ? '('.$row['conditions']+') and !{free_shipping}' : '!{free_shipping}';
998
+ if (isset($row['free_shipping__label'])) {
999
+ if (!in_array('free_shipping__label',$deprecated_properties)) $deprecated_properties[] = 'free_shipping__label';
1000
+ $row2['label']['value'] = $row['free_shipping__label']['value'];
1001
+ unset($row['free_shipping__label']);
1002
+ unset($row2['free_shipping__label']);
1003
+ }
1004
+ $this->_addRow($row2);
1005
+ }
1006
+ 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>');
1007
+ 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>');
1008
+ 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>');
1009
+ 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>');
1010
+ $this->_addRow($row);
1011
+ }
1012
+ if (trim($config_string)!='') {
1013
+ $this->_addIgnoredLines(trim($config_string));
1014
+ $this->addMessage('info',$row=null,null,'Ignored lines %s','<div class="code">'.trim($config_string).'</div>');
1015
+ }
1016
+ }
1017
+
1018
+ public function addMessage($type, &$row, $property) {
1019
+ $args = func_get_args();
1020
+ array_shift($args);
1021
+ array_shift($args);
1022
+ array_shift($args);
1023
+ $message = new OS_Message($type,$args);
1024
+ if (isset($row)) {
1025
+ if (isset($property)) {
1026
+ $row[$property]['messages'][] = $message;
1027
+ } else {
1028
+ $row['*messages'][] = $message;
1029
+ }
1030
+ }
1031
+ $this->_messages[] = $message;
1032
+ self::debug(' => <span class="osh-'.$message->type.'">'.$message->toString().'</span>');
1033
+ }
1034
+
1035
+ protected function _addRow(&$row) {
1036
+ if (isset($row['code'])) {
1037
+ $key = $row['code']['value'];
1038
+ if (isset($this->_config[$key])) $this->addMessage('error',$row,'code','The property `code` must be unique, `%s` has been found twice',$key);
1039
+ while (isset($this->_config[$key])) $key .= rand(0,9);
1040
+ //$row['code'] = $key;
1041
+ } else {
1042
+ $i = 1;
1043
+ do {
1044
+ $key = 'code_auto'.sprintf('%03d',$i);
1045
+ $i++;
1046
+ } while (isset($this->_config[$key]));
1047
+ }
1048
+ $row['*code'] = $key;
1049
+ $this->_config[$key] = $row;
1050
+ }
1051
+
1052
+ protected function _addIgnoredLines($lines) {
1053
+ $this->_config[] = array('lines' => $lines);
1054
+ }
1055
+
1056
+ protected function _addressMatch($address_filter, $address) {
1057
+ $excluding = false;
1058
+
1059
+ $address_filter = trim($address_filter);
1060
+ $address_filter = str_replace(
1061
+ array('\(', '\)', '\,'),
1062
+ array('__opening_parenthesis__', '__closing_parenthesis__', '__comma__'),
1063
+ $address_filter
1064
+ );
1065
+
1066
+ if ($address_filter=='*') {
1067
+ self::debug(' country code <span class="osh-replacement">'.$address['country_code'].'</span> matches');
1068
+ return true;
1069
+ }
1070
+
1071
+ if (preg_match('#\* *- *\((.*)\)#s',$address_filter,$result)) {
1072
+ $address_filter = $result[1];
1073
+ $excluding = true;
1074
+ }
1075
+
1076
+ $tmp_address_filter_array = explode(',',trim($address_filter));
1077
+
1078
+ $concat = false;
1079
+ $concatened = '';
1080
+ $address_filter_array = array();
1081
+ $i = 0;
1082
+
1083
+ foreach ($tmp_address_filter_array as $address_filter) {
1084
+ if ($concat) $concatened .= ','.$address_filter;
1085
+ else {
1086
+ if ($i<count($tmp_address_filter_array)-1 && preg_match('#\(#',$address_filter)) {
1087
+ $concat = true;
1088
+ $concatened .= $address_filter;
1089
+ } else $address_filter_array[] = $address_filter;
1090
+ }
1091
+ if (preg_match('#\)#',$address_filter)) {
1092
+ $address_filter_array[] = $concatened;
1093
+ $concatened = '';
1094
+ $concat = false;
1095
+ }
1096
+ $i++;
1097
+ }
1098
+
1099
+ foreach ($address_filter_array as $address_filter) {
1100
+ $address_filter = trim($address_filter);
1101
+ if (preg_match('#([A-Z]{2}) *(-)? *(?:\( *(-)? *(.*)\))?#s', $address_filter, $result)) {
1102
+ $country_code = $result[1];
1103
+ if ($address['country_code']==$country_code) {
1104
+ self::debug(' country code <span class="osh-replacement">'.$address['country_code'].'</span> matches');
1105
+ if (!isset($result[4]) || $result[4]=='') return !$excluding;
1106
+ else {
1107
+ $region_codes = explode(',',$result[4]);
1108
+ $in_array = false;
1109
+ for ($i=count($region_codes); --$i>=0;) {
1110
+ $code = trim(str_replace(
1111
+ array('__opening_parenthesis__', '__closing_parenthesis__', '__comma__'),
1112
+ array('(', ')', ','),
1113
+ $region_codes[$i]
1114
+ ));
1115
+ $region_codes[$i] = $code;
1116
+ if ($address['region_code']===$code) {
1117
+ self::debug(' region code <span class="osh-replacement">'.$address['region_code'].'</span> matches');
1118
+ $in_array = true;
1119
+ } else if ($address['postcode']===$code) {
1120
+ self::debug(' postcode <span class="osh-replacement">'.$address['postcode'].'</span> matches');
1121
+ $in_array = true;
1122
+ } else if (mb_substr($code,0,1)=='/' && mb_substr($code,mb_strlen($code)-1,1)=='/' && @preg_match($code, $address['postcode'])) {
1123
+ self::debug(' postcode <span class="osh-replacement">'.$address['postcode'].'</span> matches <span class="osh-formula">'.htmlentities($code).'</span>');
1124
+ $in_array = true;
1125
+ } else if (strpos($code,'*')!==false && preg_match('/^'.str_replace('*','(?:.*)',$code).'$/',$address['postcode'])) {
1126
+ self::debug(' postcode <span class="osh-replacement">'.$address['postcode'].'</span> matches <span class="osh-formula">'.htmlentities($code).'</span>');
1127
+ $in_array = true;
1128
+ }
1129
+ if ($in_array) break;
1130
+ }
1131
+ if (!$in_array) {
1132
+ self::debug(' region code <span class="osh-replacement">'.$address['region_code'].'</span> and postcode <span class="osh-replacement">'.$address['postcode'].'</span> don\'t match');
1133
+ }
1134
+ // Vérification stricte
1135
+ /*$in_array = in_array($address['region_code'],$region_codes,true) || in_array($address['postcode'],$region_codes,true);*/
1136
+ $excluding_region = $result[2]=='-' || $result[3]=='-';
1137
+ if ($excluding_region && !$in_array || !$excluding_region && $in_array) return !$excluding;
1138
+ }
1139
+ }
1140
+ }
1141
+ }
1142
+ return $excluding;
1143
+ }
1144
+
1145
+ protected function _getProductProperty($product, $property_type, $property_name, $get_by_id=false) {
1146
+ switch ($property_type) {
1147
+ case 'attribute':
1148
+ case 'attributes': return $product->getAttribute($property_name,$get_by_id);
1149
+ case 'option':
1150
+ case 'options': return $product->getOption($property_name,$get_by_id);
1151
+ case 'stock': return $product->getStockData($property_name);
1152
+ }
1153
+ return null;
1154
+ }
1155
+
1156
+ protected function _processProductProperty($products, $regex_result) {
1157
+ // count, sum, min, max, count distinct
1158
+ $operation = strtolower($regex_result[1]);
1159
+ switch ($operation) {
1160
+ case 'sum':
1161
+ case 'min':
1162
+ case 'max':
1163
+ case 'count distinct':
1164
+ $property_type = $regex_result[2];
1165
+ $property_name = $regex_result[3];
1166
+ $conditions = isset($regex_result[4]) ? $regex_result[4] : null;
1167
+ break;
1168
+ case 'count':
1169
+ $conditions = isset($regex_result[2]) ? $regex_result[2] : null;
1170
+ break;
1171
+ }
1172
+
1173
+ self::debug(' :: start <span class="osh-replacement">'.$regex_result[0].'</span>');
1174
+
1175
+ $return_value = null;
1176
+
1177
+ preg_match_all('/product\.(attribute(?:s)?|option(?:s)?|stock)\.([a-z0-9_+-]+)(?:\.(id))?/i',$conditions,$properties_regex_result,PREG_SET_ORDER);
1178
+ $properties = array();
1179
+ foreach ($properties_regex_result as $property_regex_result) {
1180
+ $key = $property_regex_result[0];
1181
+ if (!isset($properties[$key])) $properties[$key] = $property_regex_result;
1182
+ }
1183
+
1184
+ foreach ($products as $product) {
1185
+ if (isset($conditions) && $conditions!='') {
1186
+ $formula = $conditions;
1187
+ foreach ($properties as $property) {
1188
+ $value = $this->_getProductProperty(
1189
+ $product,
1190
+ $tmp_property_type = $property[1],
1191
+ $tmp_property_name = $property[2],
1192
+ $get_by_id = isset($property[3]) && $property[3]=='id'
1193
+ );
1194
+ //$formula = $this->replace($property[0],$value,$formula);
1195
+ $from = $property[0];
1196
+ $to = is_string($value) || empty($value) ? "'".$value."'" : $value;
1197
+ $formula = str_replace($from,$to,$formula);
1198
+ 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>');
1199
+ }
1200
+ $eval_result = $this->_evalFormula($formula);
1201
+ if (!isset($eval_result)) return 'null';
1202
+ }
1203
+ else $eval_result = true;
1204
+
1205
+ if ($eval_result==true) {
1206
+ if ($operation=='count') {
1207
+ $return_value = (isset($return_value) ? $return_value : 0) + $product->getQuantity();
1208
+ } else {
1209
+ $value = $this->_getProductProperty($product,$property_type,$property_name);
1210
+ switch ($operation) {
1211
+ case 'min':
1212
+ if (!isset($return_value) || $value<$return_value) $return_value = $value;
1213
+ break;
1214
+ case 'max':
1215
+ if (!isset($return_value) || $value>$return_value) $return_value = $value;
1216
+ break;
1217
+ case 'sum':
1218
+ //self::debug($product->getSku().'.'.$property_type.'.'.$property_name.' = "'.$value.'" x '.$product->getQuantity());
1219
+ $return_value = (isset($return_value) ? $return_value : 0) + $value*$product->getQuantity();
1220
+ break;
1221
+ case 'count distinct':
1222
+ if (!isset($return_value)) $return_value = 0;
1223
+ if (!isset($distinct_values)) $distinct_values = array();
1224
+ if (!in_array($value,$distinct_values)) {
1225
+ $distinct_values[] = $value;
1226
+ $return_value++;
1227
+ }
1228
+ break;
1229
+ }
1230
+ }
1231
+ }
1232
+ }
1233
+
1234
+ self::debug(' :: end <span class="osh-replacement">'.$regex_result[0].'</span>');
1235
+
1236
+ return $return_value;
1237
+ }
1238
+
1239
+ }
1240
+
1241
+ interface OS_Product {
1242
+ public function getOption($option);
1243
+ public function getAttribute($attribute);
1244
+ public function getName();
1245
+ public function getSku();
1246
+ public function getQuantity();
1247
+ public function getStockData($key);
1248
+ }
1249
+
1250
+ class OS_Message {
1251
+ public $type;
1252
+ public $message;
1253
+ public $args;
1254
+
1255
+ public function OS_Message($type, $args) {
1256
+ $this->type = $type;
1257
+ $this->message = array_shift($args);
1258
+ $this->args = $args;
1259
+ }
1260
+
1261
+ public function toString() {
1262
+ return vsprintf($this->message,$this->args);
1263
+ }
1264
+ }
1265
+
1266
+ class OS_Result {
1267
+ public $success;
1268
+ public $result;
1269
+
1270
+ public function OS_Result($success, $result=null) {
1271
+ $this->success = $success;
1272
+ $this->result = $result;
1273
+ }
1274
+
1275
+ public function __toString() {
1276
+ return is_bool($this->result) ? ($this->result ? 'true' : 'false') : (string)$this->result;
1277
+ }
1278
+ }
1279
+
1280
+
1281
+ ?>
app/code/community/Owebia/Shipping2/includes/cache/countries ADDED
@@ -0,0 +1 @@
 
1
+ a:4:{s:9:"code2name";a:246:{s:2:"AF";s:11:"Afghanistan";s:2:"ZA";s:14:"Afrique du Sud";s:2:"AX";s:6:"Åland";s:2:"AL";s:7:"Albanie";s:2:"DZ";s:8:"Algérie";s:2:"DE";s:9:"Allemagne";s:2:"AD";s:7:"Andorre";s:2:"AO";s:6:"Angola";s:2:"AI";s:8:"Anguilla";s:2:"AQ";s:11:"Antarctique";s:2:"AG";s:18:"Antigua-et-Barbuda";s:2:"AN";s:23:"Antilles néerlandaises";s:2:"SA";s:15:"Arabie saoudite";s:2:"AR";s:9:"Argentine";s:2:"AM";s:8:"Arménie";s:2:"AW";s:5:"Aruba";s:2:"AU";s:9:"Australie";s:2:"AT";s:8:"Autriche";s:2:"AZ";s:12:"Azerbaïdjan";s:2:"BS";s:7:"Bahamas";s:2:"BH";s:8:"Bahreïn";s:2:"BD";s:10:"Bangladesh";s:2:"BB";s:7:"Barbade";s:2:"BY";s:12:"Biélorussie";s:2:"BE";s:8:"Belgique";s:2:"BZ";s:6:"Belize";s:2:"BJ";s:6:"Bénin";s:2:"BM";s:8:"Bermudes";s:2:"BT";s:7:"Bhoutan";s:2:"BO";s:7:"Bolivie";s:2:"BA";s:19:"Bosnie-Herzégovine";s:2:"BW";s:8:"Botswana";s:2:"BV";s:11:"Île Bouvet";s:2:"BR";s:7:"Brésil";s:2:"BN";s:6:"Brunei";s:2:"BG";s:8:"Bulgarie";s:2:"BF";s:12:"Burkina Faso";s:2:"BI";s:7:"Burundi";s:2:"KY";s:14:"Îles Caïmans";s:2:"KH";s:8:"Cambodge";s:2:"CM";s:8:"Cameroun";s:2:"CA";s:6:"Canada";s:2:"CV";s:8:"Cap-Vert";s:2:"CF";s:26:"République centrafricaine";s:2:"CL";s:5:"Chili";s:2:"CN";s:5:"Chine";s:2:"CX";s:14:"Île Christmas";s:2:"CY";s:6:"Chypre";s:2:"CC";s:11:"Îles Cocos";s:2:"CO";s:8:"Colombie";s:2:"KM";s:7:"Comores";s:2:"CG";s:5:"Congo";s:2:"CD";s:34:"République démocratique du Congo";s:2:"CK";s:10:"Îles Cook";s:2:"KR";s:13:"Corée du Sud";s:2:"KP";s:14:"Corée du Nord";s:2:"CR";s:10:"Costa Rica";s:2:"CI";s:14:"Côte d'Ivoire";s:2:"HR";s:7:"Croatie";s:2:"CU";s:4:"Cuba";s:2:"DK";s:8:"Danemark";s:2:"DJ";s:8:"Djibouti";s:2:"DO";s:23:"République dominicaine";s:2:"DM";s:9:"Dominique";s:2:"EG";s:7:"Égypte";s:2:"SV";s:8:"Salvador";s:2:"AE";s:20:"Émirats arabes unis";s:2:"EC";s:9:"Équateur";s:2:"ER";s:10:"Érythrée";s:2:"ES";s:7:"Espagne";s:2:"EE";s:7:"Estonie";s:2:"US";s:11:"États-Unis";s:2:"ET";s:9:"Éthiopie";s:2:"FK";s:15:"Îles Malouines";s:2:"FO";s:13:"Îles Féroé";s:2:"FJ";s:5:"Fidji";s:2:"FI";s:8:"Finlande";s:2:"FR";s:6:"France";s:2:"GA";s:5:"Gabon";s:2:"GM";s:6:"Gambie";s:2:"GE";s:8:"Géorgie";s:2:"GS";s:44:"Géorgie du Sud-et-les Îles Sandwich du Sud";s:2:"GH";s:5:"Ghana";s:2:"GI";s:9:"Gibraltar";s:2:"GR";s:6:"Grèce";s:2:"GD";s:7:"Grenade";s:2:"GL";s:9:"Groenland";s:2:"GP";s:10:"Guadeloupe";s:2:"GU";s:4:"Guam";s:2:"GT";s:9:"Guatemala";s:2:"GG";s:9:"Guernesey";s:2:"GN";s:7:"Guinée";s:2:"GW";s:14:"Guinée-Bissau";s:2:"GQ";s:20:"Guinée équatoriale";s:2:"GY";s:6:"Guyana";s:2:"GF";s:17:"Guyane Française";s:2:"HT";s:6:"Haïti";s:2:"HM";s:24:"Îles Heard-et-MacDonald";s:2:"HN";s:8:"Honduras";s:2:"HK";s:9:"Hong Kong";s:2:"HU";s:7:"Hongrie";s:2:"IM";s:11:"Île de Man";s:2:"UM";s:42:"Îles mineures éloignées des États-Unis";s:2:"VG";s:26:"Îles Vierges britanniques";s:2:"VI";s:26:"Îles Vierges américaines";s:2:"IN";s:4:"Inde";s:2:"ID";s:10:"Indonésie";s:2:"IR";s:4:"Iran";s:2:"IQ";s:4:"Irak";s:2:"IE";s:7:"Irlande";s:2:"IS";s:7:"Islande";s:2:"IL";s:7:"Israël";s:2:"IT";s:6:"Italie";s:2:"JM";s:9:"Jamaïque";s:2:"JP";s:5:"Japon";s:2:"JE";s:6:"Jersey";s:2:"JO";s:8:"Jordanie";s:2:"KZ";s:10:"Kazakhstan";s:2:"KE";s:5:"Kenya";s:2:"KG";s:12:"Kirghizistan";s:2:"KI";s:8:"Kiribati";s:2:"KW";s:7:"Koweït";s:2:"LA";s:4:"Laos";s:2:"LS";s:7:"Lesotho";s:2:"LV";s:8:"Lettonie";s:2:"LB";s:5:"Liban";s:2:"LR";s:8:"Libéria";s:2:"LY";s:5:"Libye";s:2:"LI";s:13:"Liechtenstein";s:2:"LT";s:8:"Lituanie";s:2:"LU";s:10:"Luxembourg";s:2:"MO";s:5:"Macao";s:2:"MK";s:10:"Macédoine";s:2:"MG";s:10:"Madagascar";s:2:"MY";s:8:"Malaisie";s:2:"MW";s:6:"Malawi";s:2:"MV";s:8:"Maldives";s:2:"ML";s:4:"Mali";s:2:"MT";s:5:"Malte";s:2:"MP";s:23:"Îles Mariannes du Nord";s:2:"MA";s:5:"Maroc";s:2:"MH";s:14:"Îles Marshall";s:2:"MQ";s:10:"Martinique";s:2:"MU";s:12:"Île Maurice";s:2:"MR";s:10:"Mauritanie";s:2:"YT";s:7:"Mayotte";s:2:"MX";s:7:"Mexique";s:2:"FM";s:11:"Micronésie";s:2:"MD";s:8:"Moldavie";s:2:"MC";s:6:"Monaco";s:2:"MN";s:8:"Mongolie";s:2:"ME";s:12:"Monténégro";s:2:"MS";s:10:"Montserrat";s:2:"MZ";s:10:"Mozambique";s:2:"MM";s:8:"Birmanie";s:2:"NA";s:7:"Namibie";s:2:"NR";s:5:"Nauru";s:2:"NP";s:6:"Népal";s:2:"NI";s:9:"Nicaragua";s:2:"NE";s:5:"Niger";s:2:"NG";s:8:"Nigéria";s:2:"NU";s:5:"Niué";s:2:"NF";s:12:"Île Norfolk";s:2:"NO";s:8:"Norvège";s:2:"NC";s:19:"Nouvelle-Calédonie";s:2:"NZ";s:17:"Nouvelle-Zélande";s:2:"IO";s:41:"Territoire britannique de l'océan Indien";s:2:"OM";s:4:"Oman";s:2:"UG";s:7:"Ouganda";s:2:"UZ";s:12:"Ouzbékistan";s:2:"PK";s:8:"Pakistan";s:2:"PW";s:6:"Palaos";s:2:"PS";s:9:"Palestine";s:2:"PA";s:7:"Panamá";s:2:"PG";s:26:"Papouasie-Nouvelle-Guinée";s:2:"PY";s:8:"Paraguay";s:2:"NL";s:8:"Pays-Bas";s:2:"PE";s:6:"Pérou";s:2:"PH";s:11:"Philippines";s:2:"PN";s:14:"Îles Pitcairn";s:2:"PL";s:7:"Pologne";s:2:"PF";s:21:"Polynésie Française";s:2:"PR";s:10:"Porto Rico";s:2:"PT";s:8:"Portugal";s:2:"QA";s:5:"Qatar";s:2:"RE";s:11:"La Réunion";s:2:"RO";s:8:"Roumanie";s:2:"GB";s:11:"Royaume-Uni";s:2:"RU";s:6:"Russie";s:2:"RW";s:6:"Rwanda";s:2:"EH";s:17:"Sahara occidental";s:2:"BL";s:17:"Saint-Barthélemy";s:2:"KN";s:28:"Saint-Christophe-et-Niévès";s:2:"SM";s:11:"Saint-Marin";s:2:"MF";s:12:"Saint-Martin";s:2:"PM";s:24:"Saint-Pierre-et-Miquelon";s:2:"VA";s:7:"Vatican";s:2:"VC";s:31:"Saint-Vincent-et-les Grenadines";s:2:"SH";s:15:"Sainte-Hélène";s:2:"LC";s:12:"Sainte-Lucie";s:2:"SB";s:13:"Îles Salomon";s:2:"WS";s:5:"Samoa";s:2:"AS";s:18:"Samoa américaines";s:2:"ST";s:22:"São Tomé-et-Principe";s:2:"SN";s:9:"Sénégal";s:2:"RS";s:6:"Serbie";s:2:"SC";s:10:"Seychelles";s:2:"SL";s:12:"Sierra Leone";s:2:"SG";s:9:"Singapour";s:2:"SK";s:9:"Slovaquie";s:2:"SI";s:9:"Slovénie";s:2:"SO";s:7:"Somalie";s:2:"SD";s:6:"Soudan";s:2:"LK";s:9:"Sri Lanka";s:2:"SE";s:6:"Suède";s:2:"CH";s:6:"Suisse";s:2:"SR";s:8:"Suriname";s:2:"SJ";s:26:"Svalbard et île Jan Mayen";s:2:"SZ";s:9:"Swaziland";s:2:"SY";s:5:"Syrie";s:2:"TJ";s:11:"Tadjikistan";s:2:"TW";s:7:"Taïwan";s:2:"TZ";s:8:"Tanzanie";s:2:"TD";s:5:"Tchad";s:2:"CZ";s:20:"République tchèque";s:2:"TF";s:44:"Terres Australes et Antarctiques Françaises";s:2:"TH";s:10:"Thaïlande";s:2:"TL";s:14:"Timor oriental";s:2:"TG";s:4:"Togo";s:2:"TK";s:7:"Tokelau";s:2:"TO";s:5:"Tonga";s:2:"TT";s:18:"Trinité-et-Tobago";s:2:"TN";s:7:"Tunisie";s:2:"TM";s:13:"Turkménistan";s:2:"TC";s:25:"Îles Turques-et-Caïques";s:2:"TR";s:7:"Turquie";s:2:"TV";s:6:"Tuvalu";s:2:"UA";s:7:"Ukraine";s:2:"UY";s:7:"Uruguay";s:2:"VU";s:7:"Vanuatu";s:2:"VE";s:9:"Venezuela";s:2:"VN";s:9:"Viêt Nam";s:2:"WF";s:16:"Wallis-et-Futuna";s:2:"YE";s:6:"Yémen";s:2:"ZM";s:6:"Zambie";s:2:"ZW";s:8:"Zimbabwe";}s:22:"code2soft-cleaned-name";a:246:{s:2:"AF";s:11:"afghanistan";s:2:"ZA";s:14:"afrique-du-sud";s:2:"AX";s:5:"aland";s:2:"AL";s:7:"albanie";s:2:"DZ";s:7:"algerie";s:2:"DE";s:9:"allemagne";s:2:"AD";s:7:"andorre";s:2:"AO";s:6:"angola";s:2:"AI";s:8:"anguilla";s:2:"AQ";s:11:"antarctique";s:2:"AG";s:18:"antigua-et-barbuda";s:2:"AN";s:22:"antilles-neerlandaises";s:2:"SA";s:15:"arabie-saoudite";s:2:"AR";s:9:"argentine";s:2:"AM";s:7:"armenie";s:2:"AW";s:5:"aruba";s:2:"AU";s:9:"australie";s:2:"AT";s:8:"autriche";s:2:"AZ";s:11:"azerbaidjan";s:2:"BS";s:7:"bahamas";s:2:"BH";s:7:"bahrein";s:2:"BD";s:10:"bangladesh";s:2:"BB";s:7:"barbade";s:2:"BY";s:11:"bielorussie";s:2:"BE";s:8:"belgique";s:2:"BZ";s:6:"belize";s:2:"BJ";s:5:"benin";s:2:"BM";s:8:"bermudes";s:2:"BT";s:7:"bhoutan";s:2:"BO";s:7:"bolivie";s:2:"BA";s:18:"bosnie-herzegovine";s:2:"BW";s:8:"botswana";s:2:"BV";s:10:"ile-bouvet";s:2:"BR";s:6:"bresil";s:2:"BN";s:6:"brunei";s:2:"BG";s:8:"bulgarie";s:2:"BF";s:12:"burkina-faso";s:2:"BI";s:7:"burundi";s:2:"KY";s:12:"iles-caimans";s:2:"KH";s:8:"cambodge";s:2:"CM";s:8:"cameroun";s:2:"CA";s:6:"canada";s:2:"CV";s:8:"cap-vert";s:2:"CF";s:25:"republique-centrafricaine";s:2:"CL";s:5:"chili";s:2:"CN";s:5:"chine";s:2:"CX";s:13:"ile-christmas";s:2:"CY";s:6:"chypre";s:2:"CC";s:10:"iles-cocos";s:2:"CO";s:8:"colombie";s:2:"KM";s:7:"comores";s:2:"CG";s:5:"congo";s:2:"CD";s:32:"republique-democratique-du-congo";s:2:"CK";s:9:"iles-cook";s:2:"KR";s:12:"coree-du-sud";s:2:"KP";s:13:"coree-du-nord";s:2:"CR";s:10:"costa-rica";s:2:"CI";s:13:"cote-d-ivoire";s:2:"HR";s:7:"croatie";s:2:"CU";s:4:"cuba";s:2:"DK";s:8:"danemark";s:2:"DJ";s:8:"djibouti";s:2:"DO";s:22:"republique-dominicaine";s:2:"DM";s:9:"dominique";s:2:"EG";s:6:"egypte";s:2:"SV";s:8:"salvador";s:2:"AE";s:19:"emirats-arabes-unis";s:2:"EC";s:8:"equateur";s:2:"ER";s:8:"erythree";s:2:"ES";s:7:"espagne";s:2:"EE";s:7:"estonie";s:2:"US";s:10:"etats-unis";s:2:"ET";s:8:"ethiopie";s:2:"FK";s:14:"iles-malouines";s:2:"FO";s:10:"iles-feroe";s:2:"FJ";s:5:"fidji";s:2:"FI";s:8:"finlande";s:2:"FR";s:6:"france";s:2:"GA";s:5:"gabon";s:2:"GM";s:6:"gambie";s:2:"GE";s:7:"georgie";s:2:"GS";s:42:"georgie-du-sud-et-les-iles-sandwich-du-sud";s:2:"GH";s:5:"ghana";s:2:"GI";s:9:"gibraltar";s:2:"GR";s:5:"grece";s:2:"GD";s:7:"grenade";s:2:"GL";s:9:"groenland";s:2:"GP";s:10:"guadeloupe";s:2:"GU";s:4:"guam";s:2:"GT";s:9:"guatemala";s:2:"GG";s:9:"guernesey";s:2:"GN";s:6:"guinee";s:2:"GW";s:13:"guinee-bissau";s:2:"GQ";s:18:"guinee-equatoriale";s:2:"GY";s:6:"guyana";s:2:"GF";s:16:"guyane-francaise";s:2:"HT";s:5:"haiti";s:2:"HM";s:23:"iles-heard-et-macdonald";s:2:"HN";s:8:"honduras";s:2:"HK";s:9:"hong-kong";s:2:"HU";s:7:"hongrie";s:2:"IM";s:10:"ile-de-man";s:2:"UM";s:38:"iles-mineures-eloignees-des-etats-unis";s:2:"VG";s:25:"iles-vierges-britanniques";s:2:"VI";s:24:"iles-vierges-americaines";s:2:"IN";s:4:"inde";s:2:"ID";s:9:"indonesie";s:2:"IR";s:4:"iran";s:2:"IQ";s:4:"irak";s:2:"IE";s:7:"irlande";s:2:"IS";s:7:"islande";s:2:"IL";s:6:"israel";s:2:"IT";s:6:"italie";s:2:"JM";s:8:"jamaique";s:2:"JP";s:5:"japon";s:2:"JE";s:6:"jersey";s:2:"JO";s:8:"jordanie";s:2:"KZ";s:10:"kazakhstan";s:2:"KE";s:5:"kenya";s:2:"KG";s:12:"kirghizistan";s:2:"KI";s:8:"kiribati";s:2:"KW";s:6:"koweit";s:2:"LA";s:4:"laos";s:2:"LS";s:7:"lesotho";s:2:"LV";s:8:"lettonie";s:2:"LB";s:5:"liban";s:2:"LR";s:7:"liberia";s:2:"LY";s:5:"libye";s:2:"LI";s:13:"liechtenstein";s:2:"LT";s:8:"lituanie";s:2:"LU";s:10:"luxembourg";s:2:"MO";s:5:"macao";s:2:"MK";s:9:"macedoine";s:2:"MG";s:10:"madagascar";s:2:"MY";s:8:"malaisie";s:2:"MW";s:6:"malawi";s:2:"MV";s:8:"maldives";s:2:"ML";s:4:"mali";s:2:"MT";s:5:"malte";s:2:"MP";s:22:"iles-mariannes-du-nord";s:2:"MA";s:5:"maroc";s:2:"MH";s:13:"iles-marshall";s:2:"MQ";s:10:"martinique";s:2:"MU";s:11:"ile-maurice";s:2:"MR";s:10:"mauritanie";s:2:"YT";s:7:"mayotte";s:2:"MX";s:7:"mexique";s:2:"FM";s:10:"micronesie";s:2:"MD";s:8:"moldavie";s:2:"MC";s:6:"monaco";s:2:"MN";s:8:"mongolie";s:2:"ME";s:10:"montenegro";s:2:"MS";s:10:"montserrat";s:2:"MZ";s:10:"mozambique";s:2:"MM";s:8:"birmanie";s:2:"NA";s:7:"namibie";s:2:"NR";s:5:"nauru";s:2:"NP";s:5:"nepal";s:2:"NI";s:9:"nicaragua";s:2:"NE";s:5:"niger";s:2:"NG";s:7:"nigeria";s:2:"NU";s:4:"niue";s:2:"NF";s:11:"ile-norfolk";s:2:"NO";s:7:"norvege";s:2:"NC";s:18:"nouvelle-caledonie";s:2:"NZ";s:16:"nouvelle-zelande";s:2:"IO";s:40:"territoire-britannique-de-l-ocean-indien";s:2:"OM";s:4:"oman";s:2:"UG";s:7:"ouganda";s:2:"UZ";s:11:"ouzbekistan";s:2:"PK";s:8:"pakistan";s:2:"PW";s:6:"palaos";s:2:"PS";s:9:"palestine";s:2:"PA";s:6:"panama";s:2:"PG";s:25:"papouasie-nouvelle-guinee";s:2:"PY";s:8:"paraguay";s:2:"NL";s:8:"pays-bas";s:2:"PE";s:5:"perou";s:2:"PH";s:11:"philippines";s:2:"PN";s:13:"iles-pitcairn";s:2:"PL";s:7:"pologne";s:2:"PF";s:19:"polynesie-francaise";s:2:"PR";s:10:"porto-rico";s:2:"PT";s:8:"portugal";s:2:"QA";s:5:"qatar";s:2:"RE";s:10:"la-reunion";s:2:"RO";s:8:"roumanie";s:2:"GB";s:11:"royaume-uni";s:2:"RU";s:6:"russie";s:2:"RW";s:6:"rwanda";s:2:"EH";s:17:"sahara-occidental";s:2:"BL";s:16:"saint-barthelemy";s:2:"KN";s:26:"saint-christophe-et-nieves";s:2:"SM";s:11:"saint-marin";s:2:"MF";s:12:"saint-martin";s:2:"PM";s:24:"saint-pierre-et-miquelon";s:2:"VA";s:7:"vatican";s:2:"VC";s:31:"saint-vincent-et-les-grenadines";s:2:"SH";s:13:"sainte-helene";s:2:"LC";s:12:"sainte-lucie";s:2:"SB";s:12:"iles-salomon";s:2:"WS";s:5:"samoa";s:2:"AS";s:17:"samoa-americaines";s:2:"ST";s:20:"sao-tome-et-principe";s:2:"SN";s:7:"senegal";s:2:"RS";s:6:"serbie";s:2:"SC";s:10:"seychelles";s:2:"SL";s:12:"sierra-leone";s:2:"SG";s:9:"singapour";s:2:"SK";s:9:"slovaquie";s:2:"SI";s:8:"slovenie";s:2:"SO";s:7:"somalie";s:2:"SD";s:6:"soudan";s:2:"LK";s:9:"sri-lanka";s:2:"SE";s:5:"suede";s:2:"CH";s:6:"suisse";s:2:"SR";s:8:"suriname";s:2:"SJ";s:25:"svalbard-et-ile-jan-mayen";s:2:"SZ";s:9:"swaziland";s:2:"SY";s:5:"syrie";s:2:"TJ";s:11:"tadjikistan";s:2:"TW";s:6:"taiwan";s:2:"TZ";s:8:"tanzanie";s:2:"TD";s:5:"tchad";s:2:"CZ";s:18:"republique-tcheque";s:2:"TF";s:43:"terres-australes-et-antarctiques-francaises";s:2:"TH";s:9:"thailande";s:2:"TL";s:14:"timor-oriental";s:2:"TG";s:4:"togo";s:2:"TK";s:7:"tokelau";s:2:"TO";s:5:"tonga";s:2:"TT";s:17:"trinite-et-tobago";s:2:"TN";s:7:"tunisie";s:2:"TM";s:12:"turkmenistan";s:2:"TC";s:23:"iles-turques-et-caiques";s:2:"TR";s:7:"turquie";s:2:"TV";s:6:"tuvalu";s:2:"UA";s:7:"ukraine";s:2:"UY";s:7:"uruguay";s:2:"VU";s:7:"vanuatu";s:2:"VE";s:9:"venezuela";s:2:"VN";s:8:"viet-nam";s:2:"WF";s:16:"wallis-et-futuna";s:2:"YE";s:5:"yemen";s:2:"ZM";s:6:"zambie";s:2:"ZW";s:8:"zimbabwe";}s:22:"code2hard-cleaned-name";a:246:{s:2:"AF";s:11:"afghanistan";s:2:"ZA";s:14:"afrique-du-sud";s:2:"AX";s:5:"aland";s:2:"AL";s:7:"albanie";s:2:"DZ";s:7:"algerie";s:2:"DE";s:9:"allemagne";s:2:"AD";s:7:"andorre";s:2:"AO";s:6:"angola";s:2:"AI";s:8:"anguilla";s:2:"AQ";s:11:"antarctique";s:2:"AG";s:15:"antigua-barbuda";s:2:"AN";s:22:"antilles-neerlandaises";s:2:"SA";s:15:"arabie-saoudite";s:2:"AR";s:9:"argentine";s:2:"AM";s:7:"armenie";s:2:"AW";s:5:"aruba";s:2:"AU";s:9:"australie";s:2:"AT";s:8:"autriche";s:2:"AZ";s:11:"azerbaidjan";s:2:"BS";s:7:"bahamas";s:2:"BH";s:7:"bahrein";s:2:"BD";s:10:"bangladesh";s:2:"BB";s:7:"barbade";s:2:"BY";s:11:"bielorussie";s:2:"BE";s:8:"belgique";s:2:"BZ";s:6:"belize";s:2:"BJ";s:5:"benin";s:2:"BM";s:8:"bermudes";s:2:"BT";s:7:"bhoutan";s:2:"BO";s:7:"bolivie";s:2:"BA";s:18:"bosnie-herzegovine";s:2:"BW";s:8:"botswana";s:2:"BV";s:6:"bouvet";s:2:"BR";s:6:"bresil";s:2:"BN";s:6:"brunei";s:2:"BG";s:8:"bulgarie";s:2:"BF";s:12:"burkina-faso";s:2:"BI";s:7:"burundi";s:2:"KY";s:7:"caimans";s:2:"KH";s:8:"cambodge";s:2:"CM";s:8:"cameroun";s:2:"CA";s:6:"canada";s:2:"CV";s:8:"cap-vert";s:2:"CF";s:25:"republique-centrafricaine";s:2:"CL";s:5:"chili";s:2:"CN";s:5:"chine";s:2:"CX";s:9:"christmas";s:2:"CY";s:6:"chypre";s:2:"CC";s:5:"cocos";s:2:"CO";s:8:"colombie";s:2:"KM";s:7:"comores";s:2:"CG";s:5:"congo";s:2:"CD";s:32:"republique-democratique-du-congo";s:2:"CK";s:4:"cook";s:2:"KR";s:12:"coree-du-sud";s:2:"KP";s:13:"coree-du-nord";s:2:"CR";s:10:"costa-rica";s:2:"CI";s:13:"cote-d-ivoire";s:2:"HR";s:7:"croatie";s:2:"CU";s:4:"cuba";s:2:"DK";s:8:"danemark";s:2:"DJ";s:8:"djibouti";s:2:"DO";s:22:"republique-dominicaine";s:2:"DM";s:9:"dominique";s:2:"EG";s:6:"egypte";s:2:"SV";s:8:"salvador";s:2:"AE";s:19:"emirats-arabes-unis";s:2:"EC";s:8:"equateur";s:2:"ER";s:8:"erythree";s:2:"ES";s:7:"espagne";s:2:"EE";s:7:"estonie";s:2:"US";s:10:"etats-unis";s:2:"ET";s:8:"ethiopie";s:2:"FK";s:9:"malouines";s:2:"FO";s:5:"feroe";s:2:"FJ";s:5:"fidji";s:2:"FI";s:8:"finlande";s:2:"FR";s:6:"france";s:2:"GA";s:5:"gabon";s:2:"GM";s:6:"gambie";s:2:"GE";s:7:"georgie";s:2:"GS";s:35:"georgie-du-sud-iles-sandwich-du-sud";s:2:"GH";s:5:"ghana";s:2:"GI";s:9:"gibraltar";s:2:"GR";s:5:"grece";s:2:"GD";s:7:"grenade";s:2:"GL";s:9:"groenland";s:2:"GP";s:10:"guadeloupe";s:2:"GU";s:4:"guam";s:2:"GT";s:9:"guatemala";s:2:"GG";s:9:"guernesey";s:2:"GN";s:6:"guinee";s:2:"GW";s:13:"guinee-bissau";s:2:"GQ";s:18:"guinee-equatoriale";s:2:"GY";s:6:"guyana";s:2:"GF";s:16:"guyane-francaise";s:2:"HT";s:5:"haiti";s:2:"HM";s:15:"heard-macdonald";s:2:"HN";s:8:"honduras";s:2:"HK";s:9:"hong-kong";s:2:"HU";s:7:"hongrie";s:2:"IM";s:6:"de-man";s:2:"UM";s:33:"mineures-eloignees-des-etats-unis";s:2:"VG";s:20:"vierges-britanniques";s:2:"VI";s:19:"vierges-americaines";s:2:"IN";s:4:"inde";s:2:"ID";s:9:"indonesie";s:2:"IR";s:4:"iran";s:2:"IQ";s:4:"irak";s:2:"IE";s:7:"irlande";s:2:"IS";s:7:"islande";s:2:"IL";s:6:"israel";s:2:"IT";s:6:"italie";s:2:"JM";s:8:"jamaique";s:2:"JP";s:5:"japon";s:2:"JE";s:6:"jersey";s:2:"JO";s:8:"jordanie";s:2:"KZ";s:10:"kazakhstan";s:2:"KE";s:5:"kenya";s:2:"KG";s:12:"kirghizistan";s:2:"KI";s:8:"kiribati";s:2:"KW";s:6:"koweit";s:2:"LA";s:4:"laos";s:2:"LS";s:7:"lesotho";s:2:"LV";s:8:"lettonie";s:2:"LB";s:5:"liban";s:2:"LR";s:7:"liberia";s:2:"LY";s:5:"libye";s:2:"LI";s:13:"liechtenstein";s:2:"LT";s:8:"lituanie";s:2:"LU";s:10:"luxembourg";s:2:"MO";s:5:"macao";s:2:"MK";s:9:"macedoine";s:2:"MG";s:10:"madagascar";s:2:"MY";s:8:"malaisie";s:2:"MW";s:6:"malawi";s:2:"MV";s:8:"maldives";s:2:"ML";s:4:"mali";s:2:"MT";s:5:"malte";s:2:"MP";s:17:"mariannes-du-nord";s:2:"MA";s:5:"maroc";s:2:"MH";s:8:"marshall";s:2:"MQ";s:10:"martinique";s:2:"MU";s:7:"maurice";s:2:"MR";s:10:"mauritanie";s:2:"YT";s:7:"mayotte";s:2:"MX";s:7:"mexique";s:2:"FM";s:10:"micronesie";s:2:"MD";s:8:"moldavie";s:2:"MC";s:6:"monaco";s:2:"MN";s:8:"mongolie";s:2:"ME";s:10:"montenegro";s:2:"MS";s:10:"montserrat";s:2:"MZ";s:10:"mozambique";s:2:"MM";s:8:"birmanie";s:2:"NA";s:7:"namibie";s:2:"NR";s:5:"nauru";s:2:"NP";s:5:"nepal";s:2:"NI";s:9:"nicaragua";s:2:"NE";s:5:"niger";s:2:"NG";s:7:"nigeria";s:2:"NU";s:4:"niue";s:2:"NF";s:7:"norfolk";s:2:"NO";s:7:"norvege";s:2:"NC";s:18:"nouvelle-caledonie";s:2:"NZ";s:16:"nouvelle-zelande";s:2:"IO";s:40:"territoire-britannique-de-l-ocean-indien";s:2:"OM";s:4:"oman";s:2:"UG";s:7:"ouganda";s:2:"UZ";s:11:"ouzbekistan";s:2:"PK";s:8:"pakistan";s:2:"PW";s:6:"palaos";s:2:"PS";s:9:"palestine";s:2:"PA";s:6:"panama";s:2:"PG";s:25:"papouasie-nouvelle-guinee";s:2:"PY";s:8:"paraguay";s:2:"NL";s:8:"pays-bas";s:2:"PE";s:5:"perou";s:2:"PH";s:11:"philippines";s:2:"PN";s:8:"pitcairn";s:2:"PL";s:7:"pologne";s:2:"PF";s:19:"polynesie-francaise";s:2:"PR";s:10:"porto-rico";s:2:"PT";s:8:"portugal";s:2:"QA";s:5:"qatar";s:2:"RE";s:7:"reunion";s:2:"RO";s:8:"roumanie";s:2:"GB";s:11:"royaume-uni";s:2:"RU";s:6:"russie";s:2:"RW";s:6:"rwanda";s:2:"EH";s:17:"sahara-occidental";s:2:"BL";s:16:"saint-barthelemy";s:2:"KN";s:23:"saint-christophe-nieves";s:2:"SM";s:11:"saint-marin";s:2:"MF";s:12:"saint-martin";s:2:"PM";s:21:"saint-pierre-miquelon";s:2:"VA";s:7:"vatican";s:2:"VC";s:24:"saint-vincent-grenadines";s:2:"SH";s:13:"sainte-helene";s:2:"LC";s:12:"sainte-lucie";s:2:"SB";s:7:"salomon";s:2:"WS";s:5:"samoa";s:2:"AS";s:17:"samoa-americaines";s:2:"ST";s:17:"sao-tome-principe";s:2:"SN";s:7:"senegal";s:2:"RS";s:6:"serbie";s:2:"SC";s:10:"seychelles";s:2:"SL";s:12:"sierra-leone";s:2:"SG";s:9:"singapour";s:2:"SK";s:9:"slovaquie";s:2:"SI";s:8:"slovenie";s:2:"SO";s:7:"somalie";s:2:"SD";s:6:"soudan";s:2:"LK";s:9:"sri-lanka";s:2:"SE";s:5:"suede";s:2:"CH";s:6:"suisse";s:2:"SR";s:8:"suriname";s:2:"SJ";s:22:"svalbard-ile-jan-mayen";s:2:"SZ";s:9:"swaziland";s:2:"SY";s:5:"syrie";s:2:"TJ";s:11:"tadjikistan";s:2:"TW";s:6:"taiwan";s:2:"TZ";s:8:"tanzanie";s:2:"TD";s:5:"tchad";s:2:"CZ";s:18:"republique-tcheque";s:2:"TF";s:40:"terres-australes-antarctiques-francaises";s:2:"TH";s:9:"thailande";s:2:"TL";s:14:"timor-oriental";s:2:"TG";s:4:"togo";s:2:"TK";s:7:"tokelau";s:2:"TO";s:5:"tonga";s:2:"TT";s:14:"trinite-tobago";s:2:"TN";s:7:"tunisie";s:2:"TM";s:12:"turkmenistan";s:2:"TC";s:15:"turques-caiques";s:2:"TR";s:7:"turquie";s:2:"TV";s:6:"tuvalu";s:2:"UA";s:7:"ukraine";s:2:"UY";s:7:"uruguay";s:2:"VU";s:7:"vanuatu";s:2:"VE";s:9:"venezuela";s:2:"VN";s:8:"viet-nam";s:2:"WF";s:13:"wallis-futuna";s:2:"YE";s:5:"yemen";s:2:"ZM";s:6:"zambie";s:2:"ZW";s:8:"zimbabwe";}s:11:"replacement";a:34:{s:7:"reunion";s:2:"RE";s:21:"france-metropolitaine";s:2:"FR";s:6:"guyane";s:2:"GF";s:4:"taaf";s:2:"TF";s:27:"terres-australes-francaises";s:2:"TF";s:3:"usa";s:2:"US";s:8:"hollande";s:2:"NL";s:15:"grande-bretagne";s:2:"GB";s:7:"vietnam";s:2:"VN";s:7:"belarus";s:2:"BY";s:17:"brunei-darussalam";s:2:"BN";s:6:"cayman";s:2:"KY";s:6:"caiman";s:2:"KY";s:8:"caimanes";s:2:"KY";s:13:"cocos-keeling";s:2:"CC";s:7:"keeling";s:2:"CC";s:12:"centrafrique";s:2:"CF";s:17:"congo-brazzaville";s:2:"CG";s:14:"congo-kinshasa";s:2:"CD";s:5:"zaire";s:2:"CD";s:9:"san-marin";s:2:"SM";s:7:"surinam";s:2:"SR";s:7:"myanmar";s:2:"MM";s:22:"saint-christophe-nevis";s:2:"KN";s:17:"saint-kitts-nevis";s:2:"KN";s:8:"falkland";s:2:"FK";s:11:"el-salvador";s:2:"SV";s:9:"lithuanie";s:2:"LT";s:13:"turks-caiques";s:2:"TC";s:22:"vierges-des-etats-unis";s:2:"VI";s:26:"etat-de-la-cite-du-vatican";s:2:"VA";s:27:"etats-federes-de-micronesie";s:2:"FM";s:27:"r-a-s-chinoise-de-hong-kong";s:2:"HK";s:23:"r-a-s-chinoise-de-macao";s:2:"MO";}}
app/etc/modules/Owebia_Shipping2.xml ADDED
@@ -0,0 +1,30 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <!--
3
+ /**
4
+ * Magento Owebia Shipping Module
5
+ *
6
+ * NOTICE OF LICENSE
7
+ *
8
+ * This source file is subject to the Open Software License (OSL 3.0)
9
+ * that is bundled with this package in the file LICENSE.txt.
10
+ * It is also available through the world-wide-web at this URL:
11
+ * http://opensource.org/licenses/osl-3.0.php
12
+ * If you did not receive a copy of the license and are unable to
13
+ * obtain it through the world-wide-web, please send an email
14
+ * to license@magentocommerce.com so we can send you a copy immediately.
15
+ *
16
+ * @category Owebia
17
+ * @package Owebia_Shipping
18
+ * @copyright Copyright (c) 2008-2010 Owebia (http://www.owebia.com)
19
+ * @author Antoine Lemoine
20
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
21
+ */
22
+ -->
23
+ <config>
24
+ <modules>
25
+ <Owebia_Shipping2>
26
+ <active>true</active>
27
+ <codePool>community</codePool>
28
+ </Owebia_Shipping2>
29
+ </modules>
30
+ </config>
app/etc/modules/Owebia_Shipping_2.xml ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <!--
3
+ /**
4
+ * Magento Owebia Shipping Module
5
+ *
6
+ * NOTICE OF LICENSE
7
+ *
8
+ * This source file is subject to the Open Software License (OSL 3.0)
9
+ * that is bundled with this package in the file LICENSE.txt.
10
+ * It is also available through the world-wide-web at this URL:
11
+ * http://opensource.org/licenses/osl-3.0.php
12
+ * If you did not receive a copy of the license and are unable to
13
+ * obtain it through the world-wide-web, please send an email
14
+ * to license@magentocommerce.com so we can send you a copy immediately.
15
+ *
16
+ * @category Owebia
17
+ * @package Owebia_Shipping
18
+ * @copyright Copyright (c) 2008-2010 Owebia (http://www.owebia.com)
19
+ * @author Antoine Lemoine
20
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
21
+ */
22
+ -->
23
+ <config>
24
+ <!-- empty to override old file -->
25
+ </config>
app/locale/en_US/Owebia_Shipping2.csv ADDED
@@ -0,0 +1,871 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # en-US
2
+ "No match found","No match found"
3
+ "Configuration disabled","Configuration disabled"
4
+ "The cart doesn't match conditions","The cart doesn't match conditions"
5
+ "The shipping method doesn't cover the zone","The shipping method doesn't cover the zone"
6
+ "The shipping method doesn't match to shipping origin","The shipping method doesn't match to shipping origin"
7
+ "The shipping method doesn't match to customer group (%s)","The shipping method doesn't match to customer group (%s)"
8
+ "Infinite loop %s","Infinite loop %s"
9
+ "Non-existent property %s","Non-existent property %s"
10
+ "Error in table %s","Error in table %s"
11
+ "Invalid formula","Invalid formula"
12
+ "Unrecognized value of deprecated property %s %s","Unrecognized value of deprecated property %s %s"
13
+ "Usage of deprecated syntax %s","Usage of deprecated syntax %s"
14
+ "Usage of unknown properties %s","Usage of unknown properties %s"
15
+ "Usage of deprecated properties %s","Usage of deprecated properties %s"
16
+ "Usage of obsolete method to disabling a shipping method (`#` before `{`)%s","Usage of obsolete method to disabling a shipping method (`#` before `{`)%s"
17
+ "A semicolon is missing at the end of following lines %s","A semicolon is missing at the end of following lines %s"
18
+ "Ignored lines %s","Ignored lines %s"
19
+ "The property `code` must be unique, `%s` has been found twice","The property `code` must be unique, `%s` has been found twice"
20
+ "There are unwanted spaces after char `%s`","There are unwanted spaces after char `%s`"
21
+ "There are unwanted spaces before char `%s`","There are unwanted spaces before char `%s`"
22
+ "There are multiples spaces","There are multiples spaces"
23
+
24
+ "track the package","track the package"
25
+
26
+ "Configuration","Configuration"
27
+ "{debug_help}","Debug displayed on cart while making a shipping estimation"
28
+ "{compression_help}","Gz + base64 compression. This is the editor that compress/uncompress."
29
+ "Tracking URL","Tracking URL"
30
+ "Debug","Debug"
31
+ "Compression","Compression"
32
+ "Stop to first match","Stop to first match"
33
+ "Owebia Shipping module","Owebia Shipping module"
34
+ "Weight unit","Weight unit"
35
+
36
+ # OS2Editor
37
+ # Owebia_Shipping2_Block_Adminhtml_System_Config_Form_Field_Config
38
+ "Open editor","Open editor"
39
+ "Help","Help"
40
+ # Owebia_Shipping2_AjaxController
41
+ "Owebia Shipping 2 configuration editor","Owebia Shipping 2 configuration editor"
42
+ "Save","Save"
43
+ "Cancel","Cancel"
44
+ "Close","Close"
45
+ "Load","Load"
46
+ "Export","Export"
47
+ "Add a shipping method","Add a shipping method"
48
+ "New shipping method","New shipping method"
49
+ "Delete","Delete"
50
+ "Weight","Weight"
51
+ "Products quantity","Products quantity"
52
+ "Quantity","Quantity"
53
+ "Price including tax","Price including tax"
54
+ "Price excluding tax","Price excluding tax"
55
+ "Not logged in","Not logged in"
56
+ "Tracking number","Tracking number"
57
+ "Insert","Insert"
58
+ "Cart","Cart"
59
+ "Selection","Selection"
60
+ "Product","Product"
61
+ "Display","Display"
62
+ "Display original input","Display original input"
63
+ "Display corrected names","Display corrected names"
64
+ "Display codes","Display codes"
65
+ "Limit to","Limit to"
66
+ "Exclude","Exclude"
67
+ "Destination country","Destination country"
68
+ "Cart weight","Cart weight"
69
+ "Cart quantity","Cart quantity"
70
+ "Disabled","Disabled"
71
+ "Ignored lines","Ignored lines"
72
+ "Correct","Correct"
73
+ "Apply changes","Apply changes"
74
+ # Fields
75
+ "Enabled","Enabled"
76
+ "Code","Code"
77
+ "Label","Label"
78
+ "Description","Description"
79
+ "Destination","Destination"
80
+ "Origin","Origin"
81
+ "Conditions","Conditions"
82
+ "Fees","Fees"
83
+ "Customer groups","Customer groups"
84
+ "Tracking url","Tracking url"
85
+ "Comment","Comment"
86
+ # Donate
87
+ "You appreciate this extension and would like to help?","You appreciate this extension and would like to help?"
88
+ "Donate","Donate"
89
+ "Support the development of Owebia Shipping 2 extension","Support the development of Owebia Shipping 2 extension"
90
+ "{os2editor.donate-page.content}","<p>L'extension Owebia Shipping 2 est développée bénévolement par l'entreprise Owebia (<a href=""http://www.owebia.com/"">http://www.owebia.com/</a>).<br/>Si vous souhaitez soutenir financièrement le développement de l'extension, vous pouvez faire un &laquo;&nbsp;don&nbsp;&raquo;.</p><p>En France, seules certaines associations peuvent recevoir des dons, c'est pourquoi nous ne pouvons recevoir une somme d'argent sans qu'elle soit déclarée.<br/>Pour cela, nous enverrons à chaque &laquo;&nbsp;donateur&nbsp;&raquo; une facture (acquitée) du montant du &laquo;&nbsp;don&nbsp;&raquo;.</p><p>Cela permettra à chacun de garder une trace de ces &laquo;&nbsp;dons&nbsp;&raquo;.</p><p><strong>Pour effectuer un &laquo;&nbsp;don&nbsp;&raquo;, merci d'envoyer un chèque à l'adresse suivante :</strong></p><p class=""owebia-address"">Owebia<br/>4, Rue du Collège<br/>25500 Morteau (France)</p><p><strong>N'oubliez pas de joindre à ce chèque les coordonnées qui doivent figurer sur la facture qui vous sera envoyée.</strong></p><p>Merci à tous les donateurs.</p>"
91
+ # JS
92
+ "Dissociate","Dissociate"
93
+ "Remove","Remove"
94
+ "Edit","Edit"
95
+ "Enter the new value:","Enter the new value:"
96
+ "[No label]","[No label]"
97
+ "Loading...","Loading..."
98
+ # Help
99
+ "Owebia Shipping 2 extension help","Owebia Shipping 2 extension help"
100
+ "{os2editor.help.summary}","
101
+ <h4>Summary</h4>
102
+ <p>
103
+ The english version of the documentation is not up to date. If you can read french, please use the french version.
104
+ </p>
105
+ <div class=""table-of-contents"">
106
+ <ul>
107
+ <li><a href=""#"" onclick=""os2editor.help('introduction');"">Introduction</a></li>
108
+ <li><a href=""#"" onclick=""os2editor.help('property.label');"">The label : `label`</a></li>
109
+ <li><a href=""#"" onclick=""os2editor.help('property.fees');"">Shipping fees : `fees`</a>
110
+ <ul>
111
+ <li><a href=""#"" onclick=""os2editor.help('more.formulas');"">Introduction to formulas</a></li>
112
+ <li><a href=""#"" onclick=""os2editor.help('more.tables');"">Use of rate tables</a></li>
113
+ <li><a href=""#"" onclick=""os2editor.help('more.copy');"">Make a copy of a property of another method</a></li>
114
+ <li><a href=""#"" onclick=""os2editor.help('more.special-functions');"">Special functions in formulas</a></li>
115
+ <li class=""new""><a href=""#"" onclick=""os2editor.help('more.attributes-options');"">Usage of product's attributes or options</a> (stock data added in version 2.3.2)</li>
116
+ <li class=""new""><a href=""#"" onclick=""os2editor.help('more.foreach');"">Usage of foreach loops</a> (added in version 2.1.7)</li>
117
+ <li class=""new""><a href=""#"" onclick=""os2editor.help('more.custom-variables');"">Usage of Magento's custom variables</a> (added in version 2.2.7)</li>
118
+ </ul>
119
+ </li>
120
+ <li><a href=""#"" onclick=""os2editor.help('property.conditions');"">The conditions : `conditions`</a></li>
121
+ <li><a href=""#"" onclick=""os2editor.help('property.destination');"">The destination : `destination`</a></li>
122
+ <li><a href=""#"" onclick=""os2editor.help('property.code');"">The code : `code`</a></li>
123
+ <li><a href=""#"" onclick=""os2editor.help('property.description');"">The description : `description`</a></li>
124
+ <li><a href=""#"" onclick=""os2editor.help('property.origin');"">The origin : `origin`</a></li>
125
+ <li><a href=""#"" onclick=""os2editor.help('property.customer_groups');"">Customer groups : `customer_groups`</a></li>
126
+ <li><a href=""#"" onclick=""os2editor.help('property.tracking_url');"">Tracking URL : `tracking_url`</a></li>
127
+ <li><a href=""#"" onclick=""os2editor.help('property.*comment');"">Comments</a></li>
128
+ <li><a href=""#"" onclick=""os2editor.help('changelog');"">Changelog</a></li>
129
+ </ul>
130
+ </div>
131
+
132
+ "
133
+ "{os2editor.help.introduction}","
134
+ <div class=""help-header"">
135
+ <p><a href=""#"" onclick=""os2editor.help('summary');"">Summary</a></p>
136
+ </div>
137
+
138
+ <h4>Introduction</h4>
139
+ <p>
140
+ If you have a question, use the following topic : <a href=""http://www.magentocommerce.com/boards/viewthread/38223/"" target=\"_blank\">http://www.magentocommerce.com/boards/viewthread/38223/</a>
141
+ </p>
142
+
143
+ <p>
144
+ The configuration syntax is similar to JSON syntax.
145
+ </p>
146
+ <p>
147
+
148
+ Example :
149
+ </p>
150
+ <div class=""code""><span class=""comment""># National</span><br/>
151
+ {<br/>
152
+ &nbsp;&nbsp;&nbsp;label: <span class=""string"">""National""</span>,<br/>
153
+ &nbsp;&nbsp;&nbsp;destination: <span class=""string"">""AD,FR,MC""</span>,<br/>
154
+ &nbsp;&nbsp;&nbsp;conditions: <span class=""string"">""{cart.price_excluding_tax}&lt;1000.00""</span>,<br/>
155
+
156
+ &nbsp;&nbsp;&nbsp;fees: <span class=""string"">""1.30 + {table {cart.weight} in 0.5:5.30, 1.0:6.50, 2.0:7.40, 3.0:8.30, 5.0:10.10}""</span>,<br/>
157
+ }</div>
158
+
159
+ <p>
160
+ The character `#` at the beginning of a line indicates a comment.<br/>
161
+ A configuration element begins with the character `{` and ends with `}`.<br/>
162
+ A configuration element contains several properties associated with values.<br/>
163
+
164
+ The properties are alphanumeric (a-z0-9_), the separator property/value is the character `:`, values are numeric, boolean or string delimited by quotation marks. At the end of a line, a comma is the separator between the various properties.
165
+ </p>
166
+ <p>
167
+ List of properties:
168
+ </p>
169
+ <ul>
170
+ <li><b>label</b>: name (label)</li>
171
+ <li><b>description</b>: description (only visible if template show it)</li>
172
+ <li><b>code</b>: shipping method's code (optional but if specified it must be unique)</li>
173
+ <li><b>enabled</b>: configuration bloc activated or not (ex: <span class=""value"">true</span> or <span class=""value"">false</span>)</li>
174
+ <li class=""new""><b>fees</b>: shipping fees (ex: <span class=""value"">""15.00""</span> or <span class=""value"">""{table {cart.weight} in 0.5:5.30, 1.0:6.50}""</span> or <span class=""value"">""100 * {cart.weight}""</span>)</li>
175
+ <li class=""new""><b>conditions</b>: activation conditions (ex: <span class=""value"">""{cart.weight}&gt;=1.0""</span> or <span class=""value"">""{cart.price_excluding_tax}&lt;100.00""</span> or <span class=""value"">""({cart.weight}&lt;=1.0) and ({cart.weight}&gt;3.0) and {free_shipping}""</span> or <span class=""value"">""{count products where product.attribute.color=='Bleu'}>1 or {count products where product.option.size=='2m'}>2""</span>)</li>
176
+ <li><b>destination</b>: countries (possibly regions) authorized in destination (ex: <span class=""value"">""FR,DE,US""</span> or <span class=""value"">""FR(2A,2B,25000)""</span> or <span class=""value"">""FR-(2A,2B)""</span> or <span class=""value"">""FR(01,02,39600),CH,DE""</span>)</li>
177
+ <li class=""new""><b>origin</b>: countries (possibly regions) authorized in origin (ex: <span class=""value"">""FR,DE,US""</span> or <span class=""value"">""FR(2A,2B,25000)""</span> or <span class=""value"">""FR-(2A,2B)""</span> or <span class=""value"">""FR(01,02,39600),CH,DE""</span>)</li>
178
+ <li class=""new""><b>customer_groups</b>: customer groups authorized (ex: <span class=""value"">""NOT LOGGED IN,Retailer""</span> or <span class=""value"">""0,3""</span>)</li>
179
+ </ul>
180
+
181
+ <div class=""help-footer"">
182
+ <p><a href=""#"" onclick=""os2editor.help('summary');"">Summary</a></p>
183
+ </div>
184
+
185
+ "
186
+ "{os2editor.help.property.label}","
187
+ <div class=""help-header"">
188
+ <p><a href=""#"" onclick=""os2editor.help('summary');"">Summary</a></p>
189
+ </div>
190
+
191
+ <h4>The label : `label`</h4>
192
+ <p>This will be the name given to the shipping method.</p>
193
+ <p>Elements such as the weight of goods can be inserted in the label.<br/>
194
+ To do this, use the following variables:</p>
195
+ <ul>
196
+ <li><b>{destination.country.name}</b>: destination country name</li>
197
+ <li><b>{destination.country.code}</b>: destination country code</li>
198
+ <li><b>{destination.region.code}</b>: destination region code</li>
199
+ <li><b>{destination.postcode}</b>: destination postcode</li>
200
+ <li><b>{origin.country.name}</b>: origin country name</li>
201
+ <li><b>{origin.country.code}</b>: origin country code</li>
202
+ <li><b>{origin.region.code}</b>: origin region code</li>
203
+ <li><b>{origin.postcode}</b>: origin postcode</li>
204
+ <li><b>{cart.weight}</b>: weight of goods</li>
205
+ <li><b>{cart.weight.unit}</b>: weight unit</li>
206
+ <li><b>{cart.quantity}</b>: products quantity</li>
207
+ <li><b>{cart.price_including_tax}</b>: price including tax</li>
208
+ <li><b>{cart.price_excluding_tax}</b>: price excluding tax</li>
209
+ <li><b>{store.code}</b>: store code</li>
210
+ <li><b>{store.name}</b>: store name</li>
211
+ <li><b>{store.address}</b>: store address</li>
212
+ <li><b>{store.phone}</b>: store phone</li>
213
+ <li><b>{date.timestamp}</b>: UNIX timestamp of current date</li>
214
+ <li><b>{date.year}</b>: year of current date</li>
215
+ <li><b>{date.month}</b>: month of current date</li>
216
+ <li><b>{date.day}</b>: day of current date</li>
217
+ <li><b>{date.hour}</b>: hour of current date</li>
218
+ <li><b>{date.minute}</b>: minute of current date</li>
219
+ <li><b>{date.second}</b>: second of current date</li>
220
+ </ul>
221
+ <div class=""code"">label: <span class=""string"">""Colissimo ({cart.weight} / {destination.country.name})""</span>,</div>
222
+ <p>This line will display for example ""Colissimo (3.0kg / France)"".</p>
223
+
224
+ <div class=""help-footer"">
225
+ <p><a href=""#"" onclick=""os2editor.help('summary');"">Summary</a></p>
226
+ </div>
227
+ "
228
+ "{os2editor.help.property.fees}","
229
+ <div class=""help-header"">
230
+ <p><a href=""#"" onclick=""os2editor.help('summary');"">Summary</a></p>
231
+ </div>
232
+
233
+ <h4>Shipping fees : `fees`</h4>
234
+ <p>
235
+ The property `fees` is specified as a <a href=""#"" onclick=""os2editor.help('more.formulas');"">formula (see introduction to formulas)</a>.
236
+ </p>
237
+
238
+ <div class=""code""><span class=""comment""># Fixed fees</span><br/>fees: 10.00,<br/>
239
+ <br/>
240
+ <span class=""comment""># Rates table</span><br/>fees: <span class=""string"">""{table {cart.weight} in 0.5:5.30, 1.0:6.50}""</span>,<br/>
241
+ <br/>
242
+ <span class=""comment""># Formula</span><br/>fees: <span class=""string"">""0.1 * {cart.price_excluding_tax} + 10.00""</span>,<br/>
243
+ <br/>
244
+ <span class=""comment""># Combination</span><br/>fees: <span class=""string"">""0.1 * {cart.price_excluding_tax} + {table {cart.weight} in 0.5:5.30, 1.0:6.50} + 10.00""</span>,
245
+ </div>
246
+
247
+ <div class=""help-footer"">
248
+ <p><a href=""#"" onclick=""os2editor.help('summary');"">Summary</a></p>
249
+ </div>
250
+ "
251
+ "{os2editor.help.more.formulas}","
252
+ <div class=""help-header"">
253
+ <p><a href=""#"" onclick=""os2editor.help('summary');"">Summary</a></p>
254
+ </div>
255
+
256
+ <h4>Introduction to formulas</h4>
257
+ <p>
258
+ Properties `fees` and `conditions` are specified as formulas.
259
+ </p>
260
+ <p>
261
+ Mathematical signs available:
262
+ </p>
263
+ <ul>
264
+ <li>operators: *, /, + et -</li>
265
+ <li>modulo: %</li>
266
+ <li>brackets: ( et )</li>
267
+ <li>boolean operators &amp;&amp;, and, ||, or, ==, &lt;, &gt;, &lt;=, &gt;=</li>
268
+ <li>binary operators &amp; et |</li>
269
+ <li>operators group C ? X : Y (ex: ""{cart.price_exluding_tax}&gt;100 ? 15*{cart.weight} : 20*{cart.weight}"")</li>
270
+ </ul>
271
+ <p>
272
+ Functions available:
273
+ </p>
274
+ <ul>
275
+ <li>rounds: round(x), floor(x), ceil(x)</li>
276
+ <li>absolute value: abs(x)</li>
277
+ <li>maximum: max(x,y)</li>
278
+ <li>minimum: min(x,y)</li>
279
+ <li>random integer: rand(min,max)</li>
280
+ <li>power: pow(x,puissance)</li>
281
+ <li>PI number: pi()</li>
282
+ <li>square root: sqrt(x)</li>
283
+ <li>logarithm: log(x) for the natural logarithm or log(x,base)</li>
284
+ <li>exponential: exp(x)</li>
285
+ </ul>
286
+ <p>
287
+ Ability to use advanced features like: casting to integer (int) casting to floating number (float), comparison with null or boolean values true and false.
288
+ </p>
289
+ <p>
290
+ Variables available:
291
+ </p>
292
+ <ul>
293
+
294
+ <li><b>{cart.weight}</b>: full package weight</li>
295
+ <li><b>{cart.price_including_tax}</b>: price including tax</li>
296
+ <li><b>{cart.price_excluding_tax}</b>: price excluding tax</li>
297
+ <li><b>{cart.quantity}</b>: items count in cart</li>
298
+ <li><b>{date.timestamp}</b>: UNIX timestamp of current date</li>
299
+ <li><b>{date.year}</b>: year of current date</li>
300
+ <li><b>{date.month}</b>: month of current date</li>
301
+ <li><b>{date.day}</b>: day of current date</li>
302
+ <li><b>{date.hour}</b>: hour of current date</li>
303
+ <li><b>{date.minute}</b>: minute of current date</li>
304
+ <li><b>{date.second}</b>: second of current date</li>
305
+ <li><b>{free_shipping}</b>: free shipping (offered by a Magento rule) [true/false]</li>
306
+ </ul>
307
+ <p>
308
+ You can put spaces and line returns in formulas (to air).
309
+ </p>
310
+ <p class=""new"" style=""font-weight: bold;"">
311
+ You can also use advanced features such as rates tables, copy of a property of another method,
312
+ special functions, usage of product's attributes and options or usage of custom variables.
313
+ </p>
314
+
315
+ <div class=""help-footer"">
316
+ <p><a href=""#"" onclick=""os2editor.help('summary');"">Summary</a></p>
317
+ </div>
318
+ "
319
+ "{os2editor.help.more.tables}","
320
+ <div class=""help-header"">
321
+ <p><a href=""#"" onclick=""os2editor.help('summary');"">Summary</a></p>
322
+ </div>
323
+
324
+ <h4>Usage of rates tables</h4>
325
+ <p>
326
+ In a table, you can include or exclude a limit value with characters '[' and ']' :
327
+ </p>
328
+ <div class=""code""><span class=""comment""># Upper limit 1.0 included</span><br/>
329
+ fees: <span class=""string"">""{table {cart.weight} in 1.0]:5.00}""</span>,<br/>
330
+ <br/>
331
+ <span class=""comment""># Upper limit 1.0 excluded</span><br/>
332
+ fees: <span class=""string"">""{table {cart.weight} in 1.0[:5.00}""</span>,</div>
333
+
334
+ <p>
335
+ In a table, you must specify the reference value. For this, we can use one of the available variables.<br/>
336
+ You can also use a formula to define another reference variable.
337
+ </p>
338
+
339
+ <div class=""code""><span class=""comment""># Limit values are compared to the cart's weight</span><br/>
340
+ fees: <span class=""string"">""{table {cart.weight} in 0.5:5.30, 1.0:6.50}""</span>,<br/>
341
+ <br/>
342
+ <span class=""comment""># Limit values are compared to the items count</span><br/>
343
+ fees: <span class=""string"">""{table {cart.quantity} in 10:5.30, 20:6.50}""</span>,<br/>
344
+ <br/>
345
+ <span class=""comment""># Limit values are compared to the prixe including tax</span><br/>
346
+ fees: <span class=""string"">""{table {cart.price_including_tax} in 15.00:5.30, 30.00:6.50}""</span>,<br/>
347
+ <br/>
348
+ <span class=""comment""># Limit values are compared to the prixe excluding tax</span><br/>
349
+ fees: <span class=""string"">""{table {cart.price_excluding_tax} in 15.00:5.30, 30.00:6.50}""</span>,<br/>
350
+ <br/>
351
+ <span class=""comment""># Limit values are compared to an user defined reference value</span><br/>
352
+ fees: <span class=""string"">""{table ceil({cart.weight}/10) in 1:5.30, 2:6.50}""</span>,
353
+ </div>
354
+
355
+ <div class=""help-footer"">
356
+ <p><a href=""#"" onclick=""os2editor.help('summary');"">Summary</a></p>
357
+ </div>
358
+ "
359
+ "{os2editor.help.more.copy}","
360
+ <div class=""help-header"">
361
+ <p><a href=""#"" onclick=""os2editor.help('summary');"">Summary</a></p>
362
+ </div>
363
+
364
+ <h4>Make a copy of a property of another method</h4>
365
+ <p>
366
+ It is possible to make a copy of a property in another using the syntax below.
367
+ </p>
368
+ <p>
369
+ You can use this technique in the properties 'conditions', 'fees',
370
+ 'enabled', 'label', 'description', 'destination', 'origin', 'customer_groups' and 'tracking_url'
371
+ <strong>but not in property 'code'</strong>.
372
+ </p>
373
+
374
+ <div class=""code""><span class=""comment""># Colissimo</span><br/>
375
+ {<br/>
376
+ &nbsp;&nbsp;&nbsp;code: <span class=""string"">""colissimo""</span>,<br/>
377
+ &nbsp;&nbsp;&nbsp;label: <span class=""string"">""Colissimo""</span>,<br/>
378
+ &nbsp;&nbsp;&nbsp;destination: <span class=""string"">""AD,FR,MC""</span>,<br/>
379
+ &nbsp;&nbsp;&nbsp;conditions: <span class=""string"">""{cart.price_excluding_tax}&lt;1000.00""</span>,<br/>
380
+ &nbsp;&nbsp;&nbsp;fees: <span class=""string"">""1.30 + {table {cart.weight} in 0.5:5.30, 1.0:6.50, 2.0:7.40, 3.0:8.30, 5.0:10.10}""</span>,<br/>
381
+ }<br/>
382
+ ...<br/>
383
+ &nbsp;&nbsp;&nbsp;<span class=""comment""># Copy conditions of another method</span><br/>
384
+ &nbsp;&nbsp;&nbsp;conditions: <span class=""string"">""({colissimo.conditions}) and ({cart.weight}&gt;10.0)""</span>,<br/>
385
+ ...<br/>
386
+ &nbsp;&nbsp;&nbsp;<span class=""comment""># Copy shipping fees of another method</span><br/>
387
+ &nbsp;&nbsp;&nbsp;fees: <span class=""string"">""({colissimo.fees}) + 15.00""</span>,<br/>
388
+ ...
389
+ </div>
390
+
391
+ <div class=""help-footer"">
392
+ <p><a href=""#"" onclick=""os2editor.help('summary');"">Summary</a></p>
393
+ </div>
394
+ "
395
+ "{os2editor.help.more.special-functions}","
396
+ <div class=""help-header"">
397
+ <p><a href=""#"" onclick=""os2editor.help('summary');"">Summary</a></p>
398
+ </div>
399
+
400
+ <h4>Special functions in formulas</h4>
401
+
402
+ <p>
403
+ You can use special functions in formulas.
404
+ </p>
405
+ <p>
406
+ List of special functions :
407
+ </p>
408
+ <ul>
409
+ <li><b>min(x,y) :</b> calculate the minimum of several values (possibly more than two values). If one value is null, it is ignored.</li>
410
+ <li><b>max(x,y) :</b> calculate the maximum of several values (possibly more than two values). If one value is null, it is ignored.</li>
411
+ </ul>
412
+
413
+ <div class=""code""><span class=""comment""># Example of usage of the min function to propose Free shipping<br/>
414
+ # and supplements for faster shipping methods</span><br/>
415
+ {<br/>
416
+ &nbsp;&nbsp;&nbsp;code: <span class=""string"">""courrier_suivi""</span>,<br/>
417
+ &nbsp;&nbsp;&nbsp;label: <span class=""string"">""Courrier suivi""</span>,<br/>
418
+ &nbsp;&nbsp;&nbsp;destination: <span class=""string"">""FR""</span>,<br/>
419
+ &nbsp;&nbsp;&nbsp;conditions: <span class=""string"">""{cart.price_including_tax}&lt;80""</span>,<br/>
420
+ &nbsp;&nbsp;&nbsp;fees: <span class=""string"">""{table {cart.weight} in 0.050:2.21, 0.100:2.77, 0.500:4.60}""</span>,<br/>
421
+ }<br/>
422
+ <br/>
423
+ {<br/>
424
+ &nbsp;&nbsp;&nbsp;code: <span class=""string"">""courrier_suivi_offert""</span>,<br/>
425
+ &nbsp;&nbsp;&nbsp;label: <span class=""string"">""Free shipping - Courrier suivi""</span>,<br/>
426
+ &nbsp;&nbsp;&nbsp;destination: <span class=""string"">""{courrier_suivi.destination}""</span>,<br/>
427
+ &nbsp;&nbsp;&nbsp;conditions: <span class=""string"">""{cart.price_including_tax}&gt;=80 and {cart.weight}&lt;=0.500""</span>,<br/>
428
+ &nbsp;&nbsp;&nbsp;fees: 0.00,<br/>
429
+ }<br/>
430
+ <br/>
431
+ {<br/>
432
+ &nbsp;&nbsp;&nbsp;code: <span class=""string"">""lettre_recommandee""</span>,<br/>
433
+ &nbsp;&nbsp;&nbsp;label: <span class=""string"">""Lettre Recommandée""</span>,<br/>
434
+ &nbsp;&nbsp;&nbsp;destination: <span class=""string"">""FR""</span>,<br/>
435
+ &nbsp;&nbsp;&nbsp;conditions: <span class=""string"">""{cart.price_including_tax}&lt;80""</span>,<br/>
436
+ &nbsp;&nbsp;&nbsp;fees: <span class=""string"">""{TABLE {cart.weight} IN 0.050:4.3,0.100:4.75,0.250:5.62,0.500:6.42,1.000:7.32,2.000:8.56,10.000:10.30}""</span>,<br/>
437
+ }<br/>
438
+ <br/>
439
+ {<br/>
440
+ &nbsp;&nbsp;&nbsp;code: <span class=""string"">""lettre_recommandee_offert""</span>,<br/>
441
+ &nbsp;&nbsp;&nbsp;label: <span class=""string"">""Free shipping - Lettre Recommandée""</span>,<br/>
442
+ &nbsp;&nbsp;&nbsp;destination: <span class=""string"">""{lettre_recommandee.destination}""</span>,<br/>
443
+ &nbsp;&nbsp;&nbsp;conditions: <span class=""string"">""{cart.price_including_tax}&gt;=80 and {cart.weight}&gt;0.500 and {cart.weight}&lt;=10.000""</span>,<br/>
444
+ &nbsp;&nbsp;&nbsp;fees: 0.00,<br/>
445
+ }<br/>
446
+ <br/>
447
+ {<br/>
448
+ &nbsp;&nbsp;&nbsp;code: <span class=""string"">""supplement_lettre_recommandee""</span>,<br/>
449
+ &nbsp;&nbsp;&nbsp;label: <span class=""string"">""Lettre Recommandée supplement""</span>,<br/>
450
+ &nbsp;&nbsp;&nbsp;destination: <span class=""string"">""{lettre_recommandee.destination}""</span>,<br/>
451
+ &nbsp;&nbsp;&nbsp;conditions: <span class=""string"">""{courrier_suivi_offert.conditions}""</span>,<br/>
452
+ &nbsp;&nbsp;&nbsp;fees: <span class=""string"">""{lettre_recommandee.fees} - {courrier_suivi.fees}""</span>,<br/>
453
+ }<br/>
454
+ <br/>
455
+ {<br/>
456
+ &nbsp;&nbsp;&nbsp;code: <span class=""string"">""colissimo""</span>,<br/>
457
+ &nbsp;&nbsp;&nbsp;label: <span class=""string"">""Colissimo""</span>,<br/>
458
+ &nbsp;&nbsp;&nbsp;destination: <span class=""string"">""FR""</span>,<br/>
459
+ &nbsp;&nbsp;&nbsp;conditions: <span class=""string"">""{cart.price_including_tax}&lt;80""</span>,<br/>
460
+ &nbsp;&nbsp;&nbsp;fees: <span class=""string"">""{table {cart.weight} in 0.3:8.7,0.8:9.9,1.8:10.85,2.8:11.8,4.8:13.7,6.8:15.6,9.8:18.45,14.8:20.45,29.8:26.45}""</span>,<br/>
461
+ }<br/>
462
+ <br/>
463
+ {<br/>
464
+ &nbsp;&nbsp;&nbsp;code: <span class=""string"">""colissimo_offert""</span>,<br/>
465
+ &nbsp;&nbsp;&nbsp;label: <span class=""string"">""Free shipping - Colissimo""</span>,<br/>
466
+ &nbsp;&nbsp;&nbsp;destination: <span class=""string"">""{colissimo.destination}""</span>,<br/>
467
+ &nbsp;&nbsp;&nbsp;conditions: <span class=""string"">""{cart.price_including_tax}&gt;=80 and {cart.weight}&gt;10 and {cart.weight}&lt;=29.8""</span>,<br/>
468
+ &nbsp;&nbsp;&nbsp;fees: 0.00,<br/>
469
+ }<br/>
470
+ <br/>
471
+ {<br/>
472
+ &nbsp;&nbsp;&nbsp;code: <span class=""string"">""supplement_colissimo""</span>,<br/>
473
+ &nbsp;&nbsp;&nbsp;label: <span class=""string"">""Colissimo supplement""</span>,<br/>
474
+ &nbsp;&nbsp;&nbsp;destination: <span class=""string"">""{colissimo.destination}""</span>,<br/>
475
+ &nbsp;&nbsp;&nbsp;conditions: <span class=""string"">""{courrier_suivi_offert.conditions} or {lettre_recommandee_offert.conditions}""</span>,<br/>
476
+ &nbsp;&nbsp;&nbsp;fees: <span class=""string"">""{colissimo.fees} - min({courrier_suivi.fees},{lettre_recommandee.fees})""</span>,<br/>
477
+ }<br/>
478
+ <br/>
479
+ {<br/>
480
+ &nbsp;&nbsp;&nbsp;code: <span class=""string"">""chronopost""</span>,<br/>
481
+ &nbsp;&nbsp;&nbsp;label: <span class=""string"">""Chronopost""</span>,<br/>
482
+ &nbsp;&nbsp;&nbsp;destination: <span class=""string"">""FR""</span>,<br/>
483
+ &nbsp;&nbsp;&nbsp;conditions: <span class=""string"">""{cart.price_including_tax}&lt;80""</span>,<br/>
484
+ &nbsp;&nbsp;&nbsp;fees: <span class=""string"">""{TABLE {cart.weight} IN 1:13.29, 2:13.99, 3:18.4, 4:19.24, 5:20.08, 6:20.92, 7:21.76, 8:22.6, 9:23.44, 10:24.28, 15:28.48, 20:32.68, 25:36.88, 30:41.08}""</span>,<br/>
485
+ }<br/>
486
+ <br/>
487
+ {<br/>
488
+ &nbsp;&nbsp;&nbsp;code: <span class=""string"">""chronopost_offert""</span>,<br/>
489
+ &nbsp;&nbsp;&nbsp;label: <span class=""string"">""Free shipping - Chronopost""</span>,<br/>
490
+ &nbsp;&nbsp;&nbsp;destination: <span class=""string"">""FR""</span>,<br/>
491
+ &nbsp;&nbsp;&nbsp;conditions: <span class=""string"">""{cart.price_including_tax}&lt;80 and {cart.weight}&gt;29.8 and {cart.weight}&lt;=30""</span>,<br/>
492
+ &nbsp;&nbsp;&nbsp;fees: 0.00,<br/>
493
+ }<br/>
494
+ <br/>
495
+ {<br/>
496
+ &nbsp;&nbsp;&nbsp;code: <span class=""string"">""supplement_chronopost""</span>,<br/>
497
+ &nbsp;&nbsp;&nbsp;label: <span class=""string"">""Chronopost supplement""</span>,<br/>
498
+ &nbsp;&nbsp;&nbsp;destination: <span class=""string"">""{chronopost.destination}""</span>,<br/>
499
+ &nbsp;&nbsp;&nbsp;conditions: <span class=""string"">""{courrier_suivi_offert.conditions} or {lettre_recommandee_offert.conditions} or {colissimo_offert.conditions}""</span>,<br/>
500
+ &nbsp;&nbsp;&nbsp;fees: <span class=""string"">""{chronopost.fees} - min({courrier_suivi.fees},{lettre_recommandee.fees},{colissimo.fees})""</span>,<br/>
501
+ }
502
+ </div>
503
+
504
+ <div class=""help-footer"">
505
+ <p><a href=""#"" onclick=""os2editor.help('summary');"">Summary</a></p>
506
+ </div>
507
+ "
508
+ "{os2editor.help.more.attributes-options}","
509
+ <div class=""help-header"">
510
+ <p><a href=""#"" onclick=""os2editor.help('summary');"">Summary</a></p>
511
+ </div>
512
+
513
+ <h4>Usage of product's attributes or options</h4>
514
+
515
+ <p>
516
+ It is possible to use product's attributes or options with the syntax below.
517
+ </p>
518
+ <p>
519
+ You can use this technique in the properties 'conditions' and 'fees'.
520
+ </p>
521
+
522
+ <div class=""code""><span class=""comment""># If at least one product has the attribute 'color' equal to 'Blue'<br/></span>
523
+ conditions: <span class=""string"">""{count products where product.attribute.color=='Bleu'}&gt;0""</span>,<br/>
524
+ ...<br/>
525
+ <span class=""comment""># If all products have the option 'size' greater or equal to '1'<br/></span>
526
+ conditions: <span class=""string"">""{count products where product.option.size&gt;='1'}=={cart.quantity}""</span>,<br/>
527
+ ...<br/>
528
+ <span class=""comment""># Different SKU count<br/></span>
529
+ conditions: <span class=""string"">""{count distinct product.attribute.sku}""</span>,<br/>
530
+ ...<br/>
531
+ <span class=""comment""># The sum of all options 'size' is greater than '1'<br/></span>
532
+ conditions: <span class=""string"">""{sum product.option.size}&gt;30""</span>,<br/>
533
+ ...<br/>
534
+ <span class=""comment""># Count of products in stock<br/></span>
535
+ conditions: <span class=""string"">""{count products where product.stock.is_in_stock==true}""</span>,<br/>
536
+ ...</div>
537
+
538
+ <p>
539
+ Available prefixes list:
540
+ </p>
541
+ <ul>
542
+ <li><b>count:</b> count (always followed by 'products')</li>
543
+ <li><b>count distinct:</b> distinct count (always followed by a property)</li>
544
+ <li><b>sum:</b> sum (always followed by a property)</li>
545
+ </ul>
546
+ <p>
547
+ Available properties list:
548
+ </p>
549
+ <ul>
550
+ <li><b>product.attribute.* :</b> attribute<br/>Interesting attributes:
551
+ <ul>
552
+ <li><b>sku :</b> the sku</li>
553
+ <li><b>name :</b> the name</li>
554
+ <li><b>weight :</b> the weight</li>
555
+ <li><b>price :</b> the price (as filled in product's card)</li>
556
+ <li><b>special_price :</b> the special price (as filled in product's card)</li>
557
+ </ul>
558
+ </li>
559
+ <li><b>product.option.* :</b> option</li>
560
+ <li><b>product.stock.is_in_stock :</b> product availability</li>
561
+ <li><b>product.stock.quantity :</b> stock quantity of the product</li>
562
+ </ul>
563
+ <p>
564
+ It's possible to specify conditions that must be met by products to be taken into account. To do this, simply add <span class=""code""> where </span> followed by a formula.
565
+ </p>
566
+ <p>
567
+ If the property type is <strong>Yes/No</strong>, you should use <span class=""code"">true</span>/<span class=""code"">false</span> or <span class=""code"">1</span>/<span class=""code"">0</span> without quotes.
568
+ </p>
569
+ <div class=""code""><span class=""comment""># Property Yes/No</span><br/>
570
+ conditions: <span class=""string"">""{count products where product.attribute.colissimo_allowed==1}""</span>,<br/>
571
+ <span class=""comment""># or</span><br/>
572
+ conditions: <span class=""string"">""{count products where product.attribute.colissimo_allowed==true}""</span>,</div>
573
+
574
+ <p>
575
+ If the property type is <strong>Drop-down</strong> and you want to make a comparison with the id rather than with the value, you must use the following syntax:
576
+ </p>
577
+
578
+ <div class=""code""><span class=""comment""># Condition validated if the attribute 'color' is equal to the value whose id is 1</span><br/>
579
+ conditions: <span class=""string"">""{count products where product.attribute.color.id==1}""</span>,</div>
580
+
581
+ <div class=""help-footer"">
582
+ <p><a href=""#"" onclick=""os2editor.help('summary');"">Summary</a></p>
583
+ </div>
584
+ "
585
+ "{os2editor.help.more.foreach}","
586
+ <div class=""help-header"">
587
+ <p><a href=""#"" onclick=""os2editor.help('summary');"">Summary</a></p>
588
+ </div>
589
+
590
+ <h4>Usage of foreach loops</h4>
591
+ <p>
592
+ Foreach loops can perform calculations on groups of products rather than consider all the products in the basket.<br/>
593
+ The overall result of a foreach loop is the sum of the results of each pass through the loop.
594
+ </p>
595
+ <p>
596
+ Inside a foreach loop, it is possible to use new variables:
597
+ </p>
598
+ <ul>
599
+ <li><b>{selection.weight}</b>: selection weight</li>
600
+ <li><b>{selection.quantity}</b>: items count in the selection</li>
601
+ </ul>
602
+ <p>
603
+ When the selection is done on the sku, each selection is composed of a single article. We can use other variables:
604
+ </p>
605
+ <ul>
606
+ <li><b>{product.weight}</b>: weight of selected product</li>
607
+ <li><b>{product.quantity}</b>: quantity of selected product</li>
608
+ <li><b>{product.attribute.*}</b>: attribute of the selected product</li>
609
+ <li><b>{product.option.*}</b>: option of the selected product</li>
610
+ </ul>
611
+
612
+ <div class=""code""><span class=""comment""># Grouping products by origin and treat groups seperatly</span><br/>
613
+ fees: <span class=""string"">""{foreach product.attribute.code_origin}{table {selection.weight} in 0.0:0.00, 1.0:11.00, 3.0:12.00, 5.0:13.00}{/foreach}""</span>,<br/>
614
+ <br/>
615
+ <span class=""comment""># Individual calculation of shipping fees</span><br/>
616
+ fees: <span class=""string"">""{foreach product.attribute.sku}{product.attribute.shipping}*{product.quantity}{/foreach}""</span>,<br/>
617
+ </div>
618
+
619
+ <div class=""help-footer"">
620
+ <p><a href=""#"" onclick=""os2editor.help('summary');"">Summary</a></p>
621
+ </div>
622
+ "
623
+ "{os2editor.help.more.custom-variables}","
624
+ <div class=""help-header"">
625
+ <p><a href=""#"" onclick=""os2editor.help('summary');"">Summary</a></p>
626
+ </div>
627
+
628
+ <h4>Usage of Magento's Custom Variables</h4>
629
+ <p>
630
+ Since version 1.4.0.1 of Magento, it is possible to define custom variables.
631
+ </p>
632
+ <p>
633
+ Version 2.2.7 of Owebia Shipping allows you to use these custom variables using the following syntax:
634
+ </p>
635
+ <div class=""code""><span class=""comment""># Usage of custom variable my_var<br/></span>
636
+ fees: <span class=""string"">""{customvar.my_var}*5.00""</span>,<br/>
637
+ ...<br/>
638
+ <span class=""comment""># The same using the standard syntax of Magento<br/></span>
639
+ fees: <span class=""string"">""{{customVar code=my_var}}*5.00""</span>,<br/>
640
+ ...</div>
641
+
642
+ <div class=""help-footer"">
643
+ <p><a href=""#"" onclick=""os2editor.help('summary');"">Summary</a></p>
644
+ </div>
645
+ "
646
+ "{os2editor.help.property.conditions}","
647
+ <div class=""help-header"">
648
+ <p><a href=""#"" onclick=""os2editor.help('summary');"">Summary</a></p>
649
+ </div>
650
+
651
+ <h4>The conditions : `conditions`</h4>
652
+ <p>
653
+ The property `conditions` is specified as a <a href=""#"" onclick=""os2editor.help('more.formulas');"">formula (see introduction to formulas)</a>
654
+ that must return a boolean value (true or false).
655
+ </p>
656
+
657
+ <div class=""code""><span class=""comment""># Prices range</span><br/>
658
+ <br/>
659
+ &nbsp;&nbsp;&nbsp;<span class=""comment""># From 0 to 70 including tax</span><br/>
660
+ &nbsp;&nbsp;&nbsp;conditions: <span class=""string"">""{cart.price_including_tax}&lt;=70""</span>,<br/>
661
+
662
+ <br/>
663
+ &nbsp;&nbsp;&nbsp;<span class=""comment""># From 0 to 70 excluding tax</span><br/>
664
+ &nbsp;&nbsp;&nbsp;conditions: <span class=""string"">""{cart.price_excluding_tax}&lt;=70""</span>,<br/>
665
+ <br/>
666
+ &nbsp;&nbsp;&nbsp;<span class=""comment""># From 20 excluded to 70 included</span><br/>
667
+ &nbsp;&nbsp;&nbsp;conditions: <span class=""string"">""({cart.price_excluding_tax} &gt; 20) and ({cart.price_excluding_tax} &lt;= 70)""</span>,<br/>
668
+ <br/>
669
+ &nbsp;&nbsp;&nbsp;<span class=""comment""># From 10 included to 50 excluded</span><br/>
670
+ &nbsp;&nbsp;&nbsp;conditions: <span class=""string"">""({cart.price_excluding_tax} &gt;= 10) and ({cart.price_excluding_tax} &lt; 50)""</span>,<br/>
671
+
672
+ <br/>
673
+ <br/>
674
+ <span class=""comment""># Weights range</span><br/>
675
+ <br/>
676
+ &nbsp;&nbsp;&nbsp;<span class=""comment""># From 0.5 excluded to 3 included</span><br/>
677
+ &nbsp;&nbsp;&nbsp;conditions: <span class=""string"">""({cart.weight} &gt; 0.5) and ({cart.weight} &lt;= 3.0)""</span>,<br/>
678
+ <br/>
679
+ &nbsp;&nbsp;&nbsp;<span class=""comment""># From 1 included to 5 excluded</span><br/>
680
+ &nbsp;&nbsp;&nbsp;conditions: <span class=""string"">""({cart.weight} &gt;= 1.0) and ({cart.weight} &lt; 5.0)""</span>,<br/>
681
+ <br/>
682
+ <br/>
683
+ <span class=""comment""># Frais de port offerts</span><br/>
684
+
685
+ <br/>
686
+ &nbsp;&nbsp;&nbsp;<span class=""comment""># Uniquement si frais de port offerts</span><br/>
687
+ &nbsp;&nbsp;&nbsp;conditions: <span class=""string"">""{free_shipping}""</span>,<br/>
688
+ <br/>
689
+ &nbsp;&nbsp;&nbsp;<span class=""comment""># Uniquement si frais de port non offerts</span><br/>
690
+ &nbsp;&nbsp;&nbsp;conditions: <span class=""string"">""!{free_shipping}""</span>,<br/>
691
+ <br/>
692
+ <br/>
693
+ <span class=""comment""># Product's attribute or option</span><br/>
694
+ <br/>
695
+ &nbsp;&nbsp;&nbsp;<span class=""comment""># If at least one product has the attribute 'color' equal to 'Blue'</span><br/>
696
+ &nbsp;&nbsp;&nbsp;conditions: <span class=""string"">""{count products where product.attribute.color=='Bleu'}&gt;1""</span>,<br/>
697
+ <br/>
698
+ &nbsp;&nbsp;&nbsp;<span class=""comment""># If all products have the option 'size' greater or equal to '1'</span><br/>
699
+ &nbsp;&nbsp;&nbsp;conditions: <span class=""string"">""{count products where product.option.size&gt;='1'}=={cart.quantity}""</span>,</div>
700
+
701
+ <div class=""help-footer"">
702
+ <p><a href=""#"" onclick=""os2editor.help('summary');"">Summary</a></p>
703
+ </div>
704
+
705
+ "
706
+ "{os2editor.help.property.destination}","
707
+ <div class=""help-header"">
708
+ <p><a href=""#"" onclick=""os2editor.help('summary');"">Summary</a></p>
709
+ </div>
710
+
711
+ <h4>The destination : `destination`</h4>
712
+ <p>
713
+ The country codes used are those of Magento (it seem that they are the same as the codes ISO 3166-1 alpha-2).<br/>
714
+ It is possible to specify region codes <span class=""new"">or postcodes</span> that you want to filter or exclude.
715
+ </p>
716
+
717
+ <div class=""code""><span class=""comment""># France, Germany, Switzerland, Spain, Italy</span><br/>
718
+ destination: <span class=""string"">""FR,DE,CH,ES,IT""</span>,<br/>
719
+ <br/>
720
+ <span class=""comment""># France without Corsica</span><br/>
721
+ destination: <span class=""string"">""FR-(2A,2B)""</span>,<br/>
722
+
723
+ <br/>
724
+ <span class=""comment""># Corsica</span><br/>
725
+ destination: <span class=""string"">""FR(2A,2B)""</span>,<br/>
726
+ <br/>
727
+ <span class=""comment""># World without Germany and Corsica</span><br/>
728
+ destination: <span class=""string"">""* - ( DE, FR(2A,2B) )""</span>,</div>
729
+
730
+ <div class=""tips"">
731
+ <p><strong>Tip</strong><br/>In the editor, you can use countries codes but countries names and shortcuts to insert a group of countries too.</p>
732
+ <ul>
733
+ <li><strong>UE</strong> or <strong>Union Européenne</strong> : adds the European Union countries.</li>
734
+ <li><strong>DOM</strong> : adds French Overseas Departments.</li>
735
+ <li><strong>COM</strong> : adds French Overseas Communities.</li>
736
+ <li><strong>Outre-Mer</strong> : adds the whole French Overseas.</li>
737
+ <li><strong>Corse</strong> : adds Corsica (""FR(2A,2B)"").</li>
738
+ </ul>
739
+ <p>
740
+ You can interract with countries in the Preview. If you click on one of them, a menu gives you the possibility to perform some operations.
741
+ </p>
742
+ </div>
743
+
744
+ <div class=""help-footer"">
745
+ <p><a href=""#"" onclick=""os2editor.help('summary');"">Summary</a></p>
746
+ </div>
747
+ "
748
+ "{os2editor.help.property.enabled}","
749
+ <div class=""help-header"">
750
+ <p><a href=""#"" onclick=""os2editor.help('summary');"">Summary</a></p>
751
+ </div>
752
+
753
+ <h4>The activation : `enabled`</h4>
754
+ <p>Enable or disable the shipping method.</p>
755
+ <p>The value must be boolean.</p>
756
+
757
+ <div class=""help-footer"">
758
+ <p><a href=""#"" onclick=""os2editor.help('summary');"">Summary</a></p>
759
+ </div>
760
+ "
761
+ "{os2editor.help.property.code}","
762
+ <div class=""help-header"">
763
+ <p><a href=""#"" onclick=""os2editor.help('summary');"">Summary</a></p>
764
+ </div>
765
+
766
+ <h4>The code : `code`</h4>
767
+ <p>This is the identifier of the shipping method.</p>
768
+ <p>It must be unique. If not unique, it will be changed.</p>
769
+
770
+ <div class=""help-footer"">
771
+ <p><a href=""#"" onclick=""os2editor.help('summary');"">Summary</a></p>
772
+ </div>
773
+ "
774
+ "{os2editor.help.property.description}","
775
+ <div class=""help-header"">
776
+ <p>See the property <a href=""#"" onclick=""os2editor.help('property.label');"">label</a>.</p>
777
+ <p><a href=""#"" onclick=""os2editor.help('summary');"">Summary</a></p>
778
+ </div>
779
+
780
+ <h4>The description : `description`</h4>
781
+ <p>This will be the description given to the shipping method.</p>
782
+ <p>The usage is the same as the property <a href=""#"" onclick=""os2editor.help('property.label');"">label</a>.</p>
783
+
784
+ <div class=""help-footer"">
785
+ <p>See the property <a href=""#"" onclick=""os2editor.help('property.label');"">label</a>.</p>
786
+ <p><a href=""#"" onclick=""os2editor.help('summary');"">Summary</a></p>
787
+ </div>
788
+ "
789
+ "{os2editor.help.property.origin}","
790
+ <div class=""help-header"">
791
+ <p>See the property <a href=""#"" onclick=""os2editor.help('property.destination');"">destination</a>.</p>
792
+ <p><a href=""#"" onclick=""os2editor.help('summary');"">Summary</a></p>
793
+ </div>
794
+
795
+ <h4>The origin : `origin`</h4>
796
+ <p>
797
+ Same than destination but to filter shipping origin.<br/>
798
+ The syntax is the same as for <a href=""#"" onclick=""os2editor.help('property.destination');"">destination</a> filtering.
799
+ </p>
800
+
801
+ <div class=""help-footer"">
802
+ <p>See the property <a href=""#"" onclick=""os2editor.help('property.destination');"">destination</a>.</p>
803
+ <p><a href=""#"" onclick=""os2editor.help('summary');"">Summary</a></p>
804
+ </div>
805
+ "
806
+ "{os2editor.help.property.customer_groups}","
807
+ <div class=""help-header"">
808
+ <p><a href=""#"" onclick=""os2editor.help('summary');"">Summary</a></p>
809
+ </div>
810
+
811
+ <h4>Customer groups : `customer_groups`</h4>
812
+ <p>
813
+ You can use the name or the ID of customer groups.
814
+ </p>
815
+
816
+ <div class=""code""><span class=""comment""># Groups NOT LOGGED IN and General</span><br/>
817
+ customer_groups: <span class=""string"">""NOT LOGGED IN,General""</span>,<br/>
818
+
819
+ <br/>
820
+ <span class=""comment""># Groups NOT LOGGED IN and General by ID</span><br/>
821
+ customer_groups: <span class=""string"">""0,1""</span>,<br/>
822
+ <br/>
823
+ <span class=""comment""># Group Retailer</span><br/>
824
+ customer_groups: <span class=""string"">""Retailer""</span>,</div>
825
+
826
+ <div class=""help-footer"">
827
+ <p><a href=""#"" onclick=""os2editor.help('summary');"">Summary</a></p>
828
+ </div>
829
+ "
830
+ "{os2editor.help.property.tracking_url}","
831
+ <div class=""help-header"">
832
+ <p><a href=""#"" onclick=""os2editor.help('summary');"">Summary</a></p>
833
+ </div>
834
+
835
+ <h4>Tracking URL : `tracking_url`</h4>
836
+ <p>
837
+ Documentation is coming.
838
+ </p>
839
+
840
+ <div class=""help-footer"">
841
+ <p><a href=""#"" onclick=""os2editor.help('summary');"">Summary</a></p>
842
+ </div>
843
+ "
844
+ "{os2editor.help.property.*comment}","
845
+ <div class=""help-header"">
846
+ <p><a href=""#"" onclick=""os2editor.help('summary');"">Summary</a></p>
847
+ </div>
848
+
849
+ <h4>Comments</h4>
850
+ <p>
851
+ You can add a comment on the shipping method. It will not be shown anywhere but you can put annotations.
852
+ </p>
853
+
854
+ <div class=""help-footer"">
855
+ <p><a href=""#"" onclick=""os2editor.help('summary');"">Summary</a></p>
856
+ </div>
857
+ "
858
+ "{os2editor.help.changelog}","
859
+ <div class=""help-header"">
860
+ <p><a href=""#"" onclick=""os2editor.help('summary');"">Summary</a></p>
861
+ </div>
862
+
863
+ <h4>Changelog (in french)</h4>
864
+ <div class=""code""><pre>
865
+ {changelog}
866
+ </pre></div>
867
+
868
+ <div class=""help-footer"">
869
+ <p><a href=""#"" onclick=""os2editor.help('summary');"">Summary</a></p>
870
+ </div>
871
+ "
app/locale/fr_FR/Owebia_Shipping2.csv ADDED
@@ -0,0 +1,941 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # fr-FR
2
+ "No match found","Aucune correspondance trouvée"
3
+ "Configuration disabled","Configuration désactivée"
4
+ "The cart doesn't match conditions","Le panier ne correspond pas aux conditions"
5
+ "The shipping method doesn't cover the zone","Le mode de livraison ne couvre pas la zone"
6
+ "The shipping method doesn't match to shipping origin","Le mode de livraison ne correspond pas à l'origine de livraison"
7
+ "The shipping method doesn't match to customer group (%s)","Le mode de livraison ne correspond pas au groupe client (%s)"
8
+ "Infinite loop %s","Boucle infinie %s"
9
+ "Non-existent property %s","Propriété inexistante %s"
10
+ "Error in table %s","Erreur dans la table %s"
11
+ "Invalid formula","Formule invalide"
12
+ "Unrecognized value of deprecated property %s %s","Valeur non reconnue de la propriété obsolète %s %s"
13
+ "Usage of deprecated syntax %s","Utilisation d'une syntaxe obsolète %s"
14
+ "Usage of unknown properties %s","Utilisation de propriétés non reconnues %s"
15
+ "Usage of deprecated properties %s","Utilisation de propriétés obsolètes %s"
16
+ "Usage of obsolete method to disabling a shipping method (`#` before `{`)%s","Utilisation d'une méthode obsolète pour désactiver une méthode de livraison (`#` avant `{`)%s"
17
+ "A semicolon is missing at the end of following lines %s","Il manque une virgule à la fin des lignes suivantes %s"
18
+ "Ignored lines %s","Lignes ignorées %s"
19
+ "The property `code` must be unique, `%s` has been found twice","La propriété `code` doit être unique, la valeur `%s` a été trouvée plusieurs fois"
20
+ "There are unwanted spaces after char `%s`","Il y a des espaces indésirables après le caractère `%s`"
21
+ "There are unwanted spaces before char `%s`","Il y a des espaces indésirables avant le caractère `%s`"
22
+ "There are unwanted multiples spaces `%s`","Il y a des espaces indésirables multiples `%s`"
23
+
24
+ "track the package","suivre le colis"
25
+
26
+ "Configuration","Configuration"
27
+ "{debug_help}","Affichage du debug sur le panier lors d'une estimation de livraison"
28
+ "{compression_help}","Compression gz + base64 pour que la configuration prenne moins de place (utile avec certaines configurations). C'est l'éditeur qui effectue la compression/décompression."
29
+ "Tracking URL","URL de suivi"
30
+ "Debug","Debug"
31
+ "Compression","Compression"
32
+ "Stop to first match","Arrêt à la première correspondance trouvée"
33
+ "Owebia Shipping module","Module Owebia Shipping"
34
+ "Weight unit","Unité de poids"
35
+
36
+ # OS2Editor
37
+ # Owebia_Shipping2_Block_Adminhtml_System_Config_Form_Field_Config
38
+ "Open editor","Ouvrir l'éditeur"
39
+ "Help","Aide"
40
+ # Owebia_Shipping2_AjaxController
41
+ "Owebia Shipping 2 configuration editor","Éditeur de configuration Owebia Shipping 2"
42
+ "Save","Sauvegarder"
43
+ "Cancel","Annuler"
44
+ "Close","Fermer"
45
+ "Load","Charger"
46
+ "Export","Exporter"
47
+ "Add a shipping method","Ajouter une méthode de livraison"
48
+ "New shipping method","Nouvelle méthode de livraison"
49
+ "Delete","Supprimer"
50
+ "Weight","Poids"
51
+ "Products quantity","Quantité d'articles"
52
+ "Quantity","Quantité"
53
+ "Price including tax","Prix TTC"
54
+ "Price excluding tax","Prix HT"
55
+ "Not logged in","Non connecté"
56
+ "Tracking number","Numéro de suivi"
57
+ "Insert","Insérer"
58
+ "Cart","Panier"
59
+ "Selection","Sélection"
60
+ "Product","Produit"
61
+ "Display","Affichage"
62
+ "Display original input","Afficher la saisie originale"
63
+ "Display corrected names","Afficher les noms corrigés"
64
+ "Display codes","Afficher les codes"
65
+ "Display names","Afficher les noms"
66
+ "Display identifiers","Afficher les identifiants"
67
+ "Limit to","Limiter à"
68
+ "Exclude","Exclure"
69
+ "Destination country","Pays de destination"
70
+ "Cart weight","Poids du panier"
71
+ "Cart quantity","Nombre d'articles dans le panier"
72
+ "Disabled","Désactivé"
73
+ "Ignored lines","Lignes ignorées"
74
+ "Correct","Corriger"
75
+ "Apply changes","Appliquer les modifications"
76
+ # Fields
77
+ "Enabled","Activé"
78
+ "Code","Code"
79
+ "Label","Libellé"
80
+ "Description","Description"
81
+ "Destination","Destination"
82
+ "Origin","Origine"
83
+ "Conditions","Conditions"
84
+ "Fees","Coûts"
85
+ "Customer groups","Groupes utilisateur"
86
+ "Tracking url","URL de suivi"
87
+ "Comment","Commentaire"
88
+ # Donate
89
+ "You appreciate this extension and would like to help?","Vous appréciez cette extension et vous aimeriez apporter votre soutien ?"
90
+ "Donate","Faire un don"
91
+ "Support the development of Owebia Shipping 2 extension","Soutenir le développement de l'extension Owebia Shipping 2"
92
+ "{os2editor.donate-page.content}","<p>L'extension Owebia Shipping 2 est développée bénévolement par l'entreprise Owebia (<a href=""http://www.owebia.com/"">http://www.owebia.com/</a>).<br/>Si vous souhaitez soutenir financièrement le développement de l'extension, vous pouvez faire un &laquo;&nbsp;don&nbsp;&raquo;.</p><p>En France, seules certaines associations peuvent recevoir des dons, c'est pourquoi nous ne pouvons recevoir une somme d'argent sans qu'elle soit déclarée.<br/>Pour cela, nous enverrons à chaque &laquo;&nbsp;donateur&nbsp;&raquo; une facture (acquitée) du montant du &laquo;&nbsp;don&nbsp;&raquo;.</p><p>Cela permettra à chacun de garder une trace de ces &laquo;&nbsp;dons&nbsp;&raquo;.</p><p><strong>Pour effectuer un &laquo;&nbsp;don&nbsp;&raquo;, merci d'envoyer un chèque à l'adresse suivante :</strong></p><p class=""owebia-address"">Owebia<br/>4, Rue du Collège<br/>25500 Morteau (France)</p><p><strong>N'oubliez pas de joindre à ce chèque les coordonnées qui doivent figurer sur la facture qui vous sera envoyée.</strong></p><p>Merci à tous les donateurs.</p>"
93
+ # JS
94
+ "Dissociate","Dissocier"
95
+ "Remove","Supprimer"
96
+ "Edit","Modifier"
97
+ "Enter the new value:","Veuillez saisir la nouvelle valeur :"
98
+ "[No label]","[Pas de libellé]"
99
+ "Loading...","En cours de chargement..."
100
+ # Help
101
+ "Owebia Shipping 2 extension help","Aide de l'extension Owebia Shipping 2"
102
+ "{os2editor.help.summary}","
103
+ <h4>Sommaire</h4>
104
+ <div class=""table-of-contents"">
105
+ <ul>
106
+ <li><a href=""#"" onclick=""os2editor.help('introduction');"">Introduction</a></li>
107
+ <li><a href=""#"" onclick=""os2editor.help('property.label');"">Le libellé : `label`</a></li>
108
+ <li><a href=""#"" onclick=""os2editor.help('property.fees');"">Les frais de port : `fees`</a>
109
+ <ul>
110
+ <li><a href=""#"" onclick=""os2editor.help('more.formulas');"">Initiation aux formules</a></li>
111
+ <li><a href=""#"" onclick=""os2editor.help('more.tables');"">Utilisation des tables de tarifs</a></li>
112
+ <li><a href=""#"" onclick=""os2editor.help('more.copy');"">Faire une copie d'une propriété d'une autre méthode</a></li>
113
+ <li><a href=""#"" onclick=""os2editor.help('more.special-functions');"">Fonctions spéciales dans les formules</a></li>
114
+ <li class=""new""><a href=""#"" onclick=""os2editor.help('more.attributes-options');"">Utilisation des attributs ou des options des produits</a> (amélioration dans la version 2.3.10)</li>
115
+ <li><a href=""#"" onclick=""os2editor.help('more.foreach');"">Utilisation des boucles foreach</a></li>
116
+ <li><a href=""#"" onclick=""os2editor.help('more.custom-variables');"">Utilisation des variables personnalisées de Magento (Custom Variables)</a></li>
117
+ </ul>
118
+ </li>
119
+ <li><a href=""#"" onclick=""os2editor.help('property.conditions');"">Les conditions : `conditions`</a></li>
120
+ <li class=""new""><a href=""#"" onclick=""os2editor.help('property.destination');"">La destination : `destination`</a> (amélioration dans la version 2.4.0)</li>
121
+ <li><a href=""#"" onclick=""os2editor.help('property.enabled');"">L'activation : `enabled`</a></li>
122
+ <li><a href=""#"" onclick=""os2editor.help('property.code');"">Le code : `code`</a></li>
123
+ <li><a href=""#"" onclick=""os2editor.help('property.description');"">La description : `description`</a></li>
124
+ <li><a href=""#"" onclick=""os2editor.help('property.origin');"">L'origine : `origin`</a></li>
125
+ <li><a href=""#"" onclick=""os2editor.help('property.customer_groups');"">Les groupes client : `customer_groups`</a></li>
126
+ <li class=""new""><a href=""#"" onclick=""os2editor.help('property.tracking_url');"">L'URL de suivi : `tracking_url`</a> (documentation plus complète depuis la version 2.4.0)</li>
127
+ <li><a href=""#"" onclick=""os2editor.help('property.*comment');"">Commentaires</a></li>
128
+ <li><a href=""#"" onclick=""os2editor.help('changelog');"">Changelog</a></li>
129
+ </ul>
130
+ </div>
131
+ "
132
+ "{os2editor.help.introduction}","
133
+ <div class=""help-header"">
134
+ <p><a href=""#"" onclick=""os2editor.help('summary');"">Sommaire</a></p>
135
+ </div>
136
+
137
+ <h4>Introduction</h4>
138
+ <p>
139
+ Si vous souhaitez poser une question, utilisez le sujet suivant : <a href=""http://www.magentocommerce.com/boards/viewthread/38223/"">http://www.magentocommerce.com/boards/viewthread/38223/</a>
140
+ </p>
141
+
142
+ <p>
143
+ La syntaxe de configuration est une syntaxe proche de la syntaxe JSON.
144
+ </p>
145
+ <p>
146
+
147
+ Exemple :
148
+ </p>
149
+ <div class=""code""><span class=""comment""># National</span><br/>
150
+ {<br/>
151
+ &nbsp;&nbsp;&nbsp;label: <span class=""string"">""National""</span>,<br/>
152
+ &nbsp;&nbsp;&nbsp;destination: <span class=""string"">""AD,FR,MC""</span>,<br/>
153
+ &nbsp;&nbsp;&nbsp;conditions: <span class=""string"">""{cart.price_excluding_tax}&lt;1000.00""</span>,<br/>
154
+
155
+ &nbsp;&nbsp;&nbsp;fees: <span class=""string"">""1.30 + {table {cart.weight} in 0.5:5.30, 1.0:6.50, 2.0:7.40, 3.0:8.30, 5.0:10.10}""</span>,<br/>
156
+ }</div>
157
+
158
+ <p>
159
+ Le caractère `#` en début de ligne indique un commentaire.<br/>
160
+ Un élément de configuration débute par le caractère `{` et se termine par `}`.<br/>
161
+ Un élément de configuration contient plusieurs propriétés associées à des valeurs.<br/>
162
+
163
+ Les propriétés sont alphanumériques (a-z0-9_), le séparateur propriété/valeur est le caractère `:`, les valeurs sont numériques, booléennes ou des chaînes de caractères délimitées par des guillemets. En fin de ligne, une virgule sert de séparateur entre les différentes propriétés.
164
+ </p>
165
+ <p>
166
+ Liste des propriétés :
167
+ </p>
168
+ <ul>
169
+ <li><b>label</b>: nom (libellé)</li>
170
+ <li><b>description</b>: description (visible seulement si le template l'affiche)</li>
171
+ <li><b>code</b>: code de la méthode de livraison (facultatif mais s'il est spécifié il doit être unique)</li>
172
+ <li><b>enabled</b>: bloc de configuration activé ou non (ex: <span class=""value"">true</span> ou <span class=""value"">false</span>)</li>
173
+ <li class=""new""><b>fees</b>: frais de port (ex: <span class=""value"">""15.00""</span> ou <span class=""value"">""{table {cart.weight} in 0.5:5.30, 1.0:6.50}""</span> ou <span class=""value"">""100 * {cart.weight}""</span>)</li>
174
+ <li class=""new""><b>conditions</b>: conditions d'activation (ex: <span class=""value"">""{cart.weight}&gt;=1.0""</span> ou <span class=""value"">""{cart.price_excluding_tax}&lt;100.00""</span> ou <span class=""value"">""({cart.weight}&lt;=1.0) and ({cart.weight}&gt;3.0) and {free_shipping}""</span> ou <span class=""value"">""{count products where product.attribute.color=='Bleu'}&gt;1 or {count products where product.option.size=='2m'}&gt;2""</span>)</li>
175
+ <li><b>destination</b>: pays (éventuellement régions) autorisés en destination (ex: <span class=""value"">""FR,DE,US""</span> ou <span class=""value"">""FR(2A,2B,25000)""</span> ou <span class=""value"">""FR-(2A,2B)""</span> ou <span class=""value"">""FR(01,02,39600),CH,DE""</span>)</li>
176
+ <li class=""new""><b>origin</b>: pays (éventuellement régions) autorisés en origine (ex: <span class=""value"">""FR,DE,US""</span> ou <span class=""value"">""FR(2A,2B,25000)""</span> ou <span class=""value"">""FR-(2A,2B)""</span> ou <span class=""value"">""FR(01,02,39600),CH,DE""</span>)</li>
177
+ <li class=""new""><b>customer_groups</b>: groupes de client autorisés (ex: <span class=""value"">""NOT LOGGED IN,Retailer""</span> ou <span class=""value"">""0,3""</span>)</li>
178
+ </ul>
179
+
180
+ <div class=""help-footer"">
181
+ <p><a href=""#"" onclick=""os2editor.help('summary');"">Sommaire</a></p>
182
+ </div>
183
+
184
+ "
185
+ "{os2editor.help.property.label}","
186
+ <div class=""help-header"">
187
+ <p><a href=""#"" onclick=""os2editor.help('summary');"">Sommaire</a></p>
188
+ </div>
189
+
190
+ <h4>Le libellé : `label`</h4>
191
+ <p>Il s'agit du nom qui sera donné à la méthode de livraison.</p>
192
+ <p>On peut insérer certains éléments comme le poids des marchandises dans le libellé.<br/>
193
+ Pour ce faire, utiliser les variables suivantes :</p>
194
+ <ul>
195
+ <li><b>{destination.country.name}</b>: le pays de destination</li>
196
+ <li><b>{destination.country.code}</b>: le code du pays de destination</li>
197
+ <li><b>{destination.region.code}</b>: le code de la région de destination</li>
198
+ <li><b>{destination.postcode}</b>: le code postal de destination</li>
199
+ <li><b>{origin.country.name}</b>: le pays d'envoi</li>
200
+ <li><b>{origin.country.code}</b>: le code du pays d'envoi</li>
201
+ <li><b>{origin.region.code}</b>: le code de la région d'envoi</li>
202
+ <li><b>{origin.postcode}</b>: le code postal d'envoi</li>
203
+ <li><b>{cart.weight}</b>: poids des marchandises</li>
204
+ <li><b>{cart.weight.unit}</b>: l'unité de poids</li>
205
+ <li><b>{cart.quantity}</b>: la quantité d'articles</li>
206
+ <li><b>{cart.price_excluding_tax}</b>: prix HT (équivaut à <b>{cart.price-tax+discount}</b>)</li>
207
+ <li><b>{cart.price_including_tax}</b>: prix TTC (équivaut à <b>{cart.price+tax+discount}</b>)</li>
208
+ <li class=""new""><b>{cart.price-tax+discount}</b>: prix HT avec remise</li>
209
+ <li class=""new""><b>{cart.price-tax-discount}</b>: prix HT sans remise</li>
210
+ <li class=""new""><b>{cart.price+tax+discount}</b>: prix TTC avec remise</li>
211
+ <li class=""new""><b>{cart.price+tax-discount}</b>: prix TTC sans remise</li>
212
+ <li class=""new""><b>{cart.coupon}</b>: coupon de réduction</li>
213
+ <li><b>{store.code}</b>: code du magasin</li>
214
+ <li><b>{store.name}</b>: nom du magasin</li>
215
+ <li><b>{store.address}</b>: adresse du magasin</li>
216
+ <li><b>{store.phone}</b>: téléphone du magasin</li>
217
+ <li><b>{date.timestamp}</b>: timestamp UNIX de la date actuelle</li>
218
+ <li><b>{date.year}</b>: année de la date actuelle</li>
219
+ <li><b>{date.month}</b>: mois de la date actuelle</li>
220
+ <li><b>{date.day}</b>: jour de la date actuelle</li>
221
+ <li><b>{date.hour}</b>: heure de la date actuelle</li>
222
+ <li><b>{date.minute}</b>: minute de la date actuelle</li>
223
+ <li><b>{date.second}</b>: seconde de la date actuelle</li>
224
+ </ul>
225
+ <div class=""code"">label: <span class=""string"">""Colissimo ({cart.weight} / {destination.country.name})""</span>,</div>
226
+ <p>La ligne ci-dessus affichera par exemple ""Colissimo (3.0kg / France)"".</p>
227
+
228
+ <div class=""help-footer"">
229
+ <p><a href=""#"" onclick=""os2editor.help('summary');"">Sommaire</a></p>
230
+ </div>
231
+ "
232
+ "{os2editor.help.property.fees}","
233
+ <div class=""help-header"">
234
+ <p><a href=""#"" onclick=""os2editor.help('summary');"">Sommaire</a></p>
235
+ </div>
236
+
237
+ <h4>Les frais de port : `fees`</h4>
238
+ <p>
239
+ La propriété `fees` se spécifie sous la forme d'une <a href=""#"" onclick=""os2editor.help('more.formulas');"">formule (voir l'initiation aux formules)</a>.
240
+ </p>
241
+ <div class=""code""><span class=""comment""># Frais fixes</span><br/>fees: 10.00,<br/>
242
+ <br/>
243
+ <span class=""comment""># Table de prix</span><br/>fees: <span class=""string"">""{table {cart.weight} in 0.5:5.30, 1.0:6.50}""</span>,<br/>
244
+ <br/>
245
+ <span class=""comment""># Formule</span><br/>fees: <span class=""string"">""0.1 * {cart.price_excluding_tax} + 10.00""</span>,<br/>
246
+ <br/>
247
+ <span class=""comment""># Combinaison</span><br/>fees: <span class=""string"">""0.1 * {cart.price_excluding_tax} + {table {cart.weight} in 0.5:5.30, 1.0:6.50} + 10.00""</span>,
248
+ </div>
249
+
250
+ <div class=""help-footer"">
251
+ <p><a href=""#"" onclick=""os2editor.help('summary');"">Sommaire</a></p>
252
+ </div>
253
+ "
254
+ "{os2editor.help.more.formulas}","
255
+ <div class=""help-header"">
256
+ <p><a href=""#"" onclick=""os2editor.help('summary');"">Sommaire</a></p>
257
+ </div>
258
+
259
+ <h4>Initiation aux formules</h4>
260
+ <p>
261
+ Les propriétés `fees` et `conditions` sont spécifiées sous la forme de formules.
262
+ </p>
263
+ <p>
264
+ Signes mathématiques disponibles :
265
+ </p>
266
+ <ul>
267
+ <li>opérateurs : *, /, + et -</li>
268
+ <li>modulo : %</li>
269
+ <li>parenthèses : ( et )</li>
270
+ <li>les opérateurs booléens &amp;&amp;, and, ||, or, ==, &lt;, &gt;, &lt;=, &gt;=</li>
271
+ <li>les opérateurs binaires &amp; et |</li>
272
+ <li>le groupe d'opérateur C ? X : Y (ex: ""{cart.price_exluding_tax}&gt;100 ? 15*{cart.weight} : 20*{cart.weight}"")</li>
273
+ </ul>
274
+ <p>
275
+ Fonctions disponibles :
276
+ </p>
277
+ <ul>
278
+ <li>arrondis : round(x), floor(x), ceil(x)</li>
279
+ <li>valeur absolue : abs(x)</li>
280
+ <li>maximum : max(x,y)</li>
281
+ <li>minimum : min(x,y)</li>
282
+ <li>entier aléatoire : rand(min,max)</li>
283
+ <li>puissance : pow(x,puissance)</li>
284
+ <li>nombre PI : pi()</li>
285
+ <li>racine carrée : sqrt(x)</li>
286
+ <li>logarithme : log(x) pour le logarithme népérien ou log(x,base)</li>
287
+ <li>exponentiel : exp(x)</li>
288
+ </ul>
289
+ <p>
290
+ Possibilité d'utiliser les fonctionnalités avancées suivantes : casting en entier (int) ou en nombre flottant (float),
291
+ comparaison avec la valeur null ou les valeurs booléennes true et false.
292
+ </p>
293
+ <p>
294
+ Variables disponibles :
295
+ </p>
296
+ <ul>
297
+
298
+ <li><b>{cart.weight}</b>: poids des marchandises</li>
299
+ <li class=""new""><b>{cart.weight.for-charge}</b>: poids des marchandises dont la livraison n'est pas offerte (par les règles de prix panier de Magento)</li>
300
+ <li><b>{cart.price_excluding_tax}</b>: prix HT (équivaut à <b>{cart.price-tax+discount}</b>)</li>
301
+ <li><b>{cart.price_including_tax}</b>: prix TTC (équivaut à <b>{cart.price+tax+discount}</b>)</li>
302
+ <li class=""new""><b>{cart.price-tax+discount}</b>: prix HT avec remise</li>
303
+ <li class=""new""><b>{cart.price-tax-discount}</b>: prix HT sans remise</li>
304
+ <li class=""new""><b>{cart.price+tax+discount}</b>: prix TTC avec remise</li>
305
+ <li class=""new""><b>{cart.price+tax-discount}</b>: prix TTC sans remise</li>
306
+ <li><b>{cart.quantity}</b>: nombre d'articles dans le panier</li>
307
+ <li class=""new""><b>{cart.coupon}</b>: coupon de réduction</li>
308
+ <li><b>{date.timestamp}</b>: timestamp UNIX de la date actuelle</li>
309
+ <li><b>{date.year}</b>: année de la date actuelle</li>
310
+ <li><b>{date.month}</b>: mois de la date actuelle</li>
311
+ <li><b>{date.day}</b>: jour de la date actuelle</li>
312
+ <li><b>{date.hour}</b>: heure de la date actuelle</li>
313
+ <li><b>{date.minute}</b>: minute de la date actuelle</li>
314
+ <li><b>{date.second}</b>: seconde de la date actuelle</li>
315
+ <li><b>{free_shipping}</b>: frais de port offert (par une règle dans Magento) [true/false]</li>
316
+ </ul>
317
+ <p>
318
+ Vous avez la possibilité de mettre des espaces et des retours à la ligne dans les formules (pour aérer).
319
+ </p>
320
+ <p class=""new"" style=""font-weight: bold;"">
321
+ Vous pouvez également utiliser des fonctionnalités avancées telles que les tables de tarifs, la copie d'une propriété d'une autre méthode,
322
+ les fonctions spéciales, l'utilisation des attributs et des options des produits ou encore l'utilisation des variables personnalisées.
323
+ </p>
324
+
325
+ <div class=""help-footer"">
326
+ <p><a href=""#"" onclick=""os2editor.help('summary');"">Sommaire</a></p>
327
+ </div>
328
+ "
329
+ "{os2editor.help.more.tables}","
330
+ <div class=""help-header"">
331
+ <p><a href=""#"" onclick=""os2editor.help('summary');"">Sommaire</a></p>
332
+ </div>
333
+
334
+ <h4>Utilisation des tables de tarifs</h4>
335
+ <p>
336
+ Dans une table, on peut inclure ou exclure une valeur limite avec les caractères '[' et ']' :
337
+ </p>
338
+ <div class=""code""><span class=""comment""># Limite supérieure 1.0 incluse</span><br/>
339
+ fees: <span class=""string"">""{table {cart.weight} in 1.0]:5.00}""</span>,<br/>
340
+
341
+ <br/>
342
+ <span class=""comment""># Limite supérieure 1.0 exclue</span><br/>
343
+ fees: <span class=""string"">""{table {cart.weight} in 1.0[:5.00}""</span>,</div>
344
+
345
+ <p>
346
+ Dans une table, on doit spécifier la valeur de référence. Pour cela, on peut utiliser une des variables disponibles.<br/>
347
+ Vous pouvez aussi utiliser une formule afin de définir une autre variable de référence.
348
+ </p>
349
+
350
+ <div class=""code""><span class=""comment""># Les valeurs limites sont comparées au poids du panier</span><br/>
351
+ fees: <span class=""string"">""{table {cart.weight} in 0.5:5.30, 1.0:6.50}""</span>,<br/>
352
+ <br/>
353
+ <span class=""comment""># Les valeurs limites sont comparées à la quantité d'articles</span><br/>
354
+ fees: <span class=""string"">""{table {cart.quantity} in 10:5.30, 20:6.50}""</span>,<br/>
355
+ <br/>
356
+ <span class=""comment""># Les valeurs limites sont comparées au prix TTC</span><br/>
357
+ fees: <span class=""string"">""{table {cart.price_including_tax} in 15.00:5.30, 30.00:6.50}""</span>,<br/>
358
+ <br/>
359
+ <span class=""comment""># Les valeurs limites sont comparées au prix HT</span><br/>
360
+ fees: <span class=""string"">""{table {cart.price_excluding_tax} in 15.00:5.30, 30.00:6.50}""</span>,<br/>
361
+ <br/>
362
+ <span class=""comment""># Les valeurs limites sont comparées à une valeur de référence définie par l'utilisateur</span><br/>
363
+ fees: <span class=""string"">""{table ceil({cart.weight}/10) in 1:5.30, 2:6.50}""</span>,
364
+ </div>
365
+
366
+ <div class=""help-footer"">
367
+ <p><a href=""#"" onclick=""os2editor.help('summary');"">Sommaire</a></p>
368
+ </div>
369
+ "
370
+ "{os2editor.help.more.copy}","
371
+ <div class=""help-header"">
372
+ <p><a href=""#"" onclick=""os2editor.help('summary');"">Sommaire</a></p>
373
+ </div>
374
+
375
+ <h4>Faire une copie d'une propriété d'une autre méthode</h4>
376
+ <p>
377
+ Il est possible de faire une copie d'une propriété dans une autre à l'aide de la syntaxe ci-dessous.
378
+ </p>
379
+ <p>
380
+ Vous pouvez utiliser cette technique dans les propriétés 'conditions', 'fees',
381
+ 'enabled', 'label', 'description', 'destination', 'origin', 'customer_groups' et 'tracking_url'
382
+ <strong>mais pas dans la propriété 'code'</strong>.
383
+ </p>
384
+
385
+ <div class=""code""><span class=""comment""># Colissimo</span><br/>
386
+ {<br/>
387
+ &nbsp;&nbsp;&nbsp;code: <span class=""string"">""colissimo""</span>,<br/>
388
+ &nbsp;&nbsp;&nbsp;label: <span class=""string"">""Colissimo""</span>,<br/>
389
+ &nbsp;&nbsp;&nbsp;destination: <span class=""string"">""AD,FR,MC""</span>,<br/>
390
+ &nbsp;&nbsp;&nbsp;conditions: <span class=""string"">""{cart.price_excluding_tax}&lt;1000.00""</span>,<br/>
391
+ &nbsp;&nbsp;&nbsp;fees: <span class=""string"">""1.30 + {table {cart.weight} in 0.5:5.30, 1.0:6.50, 2.0:7.40, 3.0:8.30, 5.0:10.10}""</span>,<br/>
392
+ }<br/>
393
+ ...<br/>
394
+ &nbsp;&nbsp;&nbsp;<span class=""comment""># Copie des conditions d'une autre méthode</span><br/>
395
+ &nbsp;&nbsp;&nbsp;conditions: <span class=""string"">""({colissimo.conditions}) and ({cart.weight}&gt;10.0)""</span>,<br/>
396
+ ...<br/>
397
+ &nbsp;&nbsp;&nbsp;<span class=""comment""># Copie des frais de port d'une autre méthode</span><br/>
398
+ &nbsp;&nbsp;&nbsp;fees: <span class=""string"">""({colissimo.fees}) + 15.00""</span>,<br/>
399
+ ...
400
+ </div>
401
+
402
+ <div class=""help-footer"">
403
+ <p><a href=""#"" onclick=""os2editor.help('summary');"">Sommaire</a></p>
404
+ </div>
405
+ "
406
+ "{os2editor.help.more.special-functions}","
407
+ <div class=""help-header"">
408
+ <p><a href=""#"" onclick=""os2editor.help('summary');"">Sommaire</a></p>
409
+ </div>
410
+
411
+ <h4>Fonctions spéciales dans les formules</h4>
412
+
413
+ <p>
414
+ Vous pouvez utiliser dans les formules des fonctions spéciales.
415
+ </p>
416
+ <p>
417
+ Liste des fonctions spéciales :
418
+ </p>
419
+ <ul>
420
+ <li><b>min(x,y) :</b> calcule le minimum entre plusieurs valeurs (éventuellement plus de deux valeurs). Si l'une des valeurs est nulle, elle est ignorée.</li>
421
+ <li><b>max(x,y) :</b> calcule le maximum entre plusieurs valeurs (éventuellement plus de deux valeurs). Si l'une des valeurs est nulle, elle est ignorée.</li>
422
+ </ul>
423
+
424
+ <div class=""code""><span class=""comment""># Exemple d'utilisation de la fonction min pour proposé des frais de port gratuits<br/>
425
+ # et un supplément pour les méthodes de transport plus rapides</span><br/>
426
+ {<br/>
427
+ &nbsp;&nbsp;&nbsp;code: <span class=""string"">""courrier_suivi""</span>,<br/>
428
+ &nbsp;&nbsp;&nbsp;label: <span class=""string"">""Courrier suivi""</span>,<br/>
429
+ &nbsp;&nbsp;&nbsp;destination: <span class=""string"">""FR""</span>,<br/>
430
+ &nbsp;&nbsp;&nbsp;conditions: <span class=""string"">""{cart.price_including_tax}&lt;80""</span>,<br/>
431
+ &nbsp;&nbsp;&nbsp;fees: <span class=""string"">""{table {cart.weight} in 0.050:2.21, 0.100:2.77, 0.500:4.60}""</span>,<br/>
432
+ }<br/>
433
+ <br/>
434
+ {<br/>
435
+ &nbsp;&nbsp;&nbsp;code: <span class=""string"">""courrier_suivi_offert""</span>,<br/>
436
+ &nbsp;&nbsp;&nbsp;label: <span class=""string"">""Frais de port offerts - Courrier suivi""</span>,<br/>
437
+ &nbsp;&nbsp;&nbsp;destination: <span class=""string"">""{courrier_suivi.destination}""</span>,<br/>
438
+ &nbsp;&nbsp;&nbsp;conditions: <span class=""string"">""{cart.price_including_tax}&gt;=80 and {cart.weight}&lt;=0.500""</span>,<br/>
439
+ &nbsp;&nbsp;&nbsp;fees: 0.00,<br/>
440
+ }<br/>
441
+ <br/>
442
+ {<br/>
443
+ &nbsp;&nbsp;&nbsp;code: <span class=""string"">""lettre_recommandee""</span>,<br/>
444
+ &nbsp;&nbsp;&nbsp;label: <span class=""string"">""Lettre Recommandée""</span>,<br/>
445
+ &nbsp;&nbsp;&nbsp;destination: <span class=""string"">""FR""</span>,<br/>
446
+ &nbsp;&nbsp;&nbsp;conditions: <span class=""string"">""{cart.price_including_tax}&lt;80""</span>,<br/>
447
+ &nbsp;&nbsp;&nbsp;fees: <span class=""string"">""{table {cart.weight} in 0.050:4.3,0.100:4.75,0.250:5.62,0.500:6.42,1.000:7.32,2.000:8.56,10.000:10.30}""</span>,<br/>
448
+ }<br/>
449
+ <br/>
450
+ {<br/>
451
+ &nbsp;&nbsp;&nbsp;code: <span class=""string"">""lettre_recommandee_offert""</span>,<br/>
452
+ &nbsp;&nbsp;&nbsp;label: <span class=""string"">""Frais de port offerts - Lettre Recommandée""</span>,<br/>
453
+ &nbsp;&nbsp;&nbsp;destination: <span class=""string"">""{lettre_recommandee.destination}""</span>,<br/>
454
+ &nbsp;&nbsp;&nbsp;conditions: <span class=""string"">""{cart.price_including_tax}&gt;=80 and {cart.weight}&gt;0.500 and {cart.weight}&lt;=10.000""</span>,<br/>
455
+ &nbsp;&nbsp;&nbsp;fees: 0.00,<br/>
456
+ }<br/>
457
+ <br/>
458
+ {<br/>
459
+ &nbsp;&nbsp;&nbsp;code: <span class=""string"">""supplement_lettre_recommandee""</span>,<br/>
460
+ &nbsp;&nbsp;&nbsp;label: <span class=""string"">""Supplément Lettre Recommandée""</span>,<br/>
461
+ &nbsp;&nbsp;&nbsp;destination: <span class=""string"">""{lettre_recommandee.destination}""</span>,<br/>
462
+ &nbsp;&nbsp;&nbsp;conditions: <span class=""string"">""{courrier_suivi_offert.conditions}""</span>,<br/>
463
+ &nbsp;&nbsp;&nbsp;fees: <span class=""string"">""{lettre_recommandee.fees} - {courrier_suivi.fees}""</span>,<br/>
464
+ }<br/>
465
+ <br/>
466
+ {<br/>
467
+ &nbsp;&nbsp;&nbsp;code: <span class=""string"">""colissimo""</span>,<br/>
468
+ &nbsp;&nbsp;&nbsp;label: <span class=""string"">""Colissimo""</span>,<br/>
469
+ &nbsp;&nbsp;&nbsp;destination: <span class=""string"">""FR""</span>,<br/>
470
+ &nbsp;&nbsp;&nbsp;conditions: <span class=""string"">""{cart.price_including_tax}&lt;80""</span>,<br/>
471
+ &nbsp;&nbsp;&nbsp;fees: <span class=""string"">""{table {cart.weight} in 0.3:8.7,0.8:9.9,1.8:10.85,2.8:11.8,4.8:13.7,6.8:15.6,9.8:18.45,14.8:20.45,29.8:26.45}""</span>,<br/>
472
+ }<br/>
473
+ <br/>
474
+ {<br/>
475
+ &nbsp;&nbsp;&nbsp;code: <span class=""string"">""colissimo_offert""</span>,<br/>
476
+ &nbsp;&nbsp;&nbsp;label: <span class=""string"">""Frais de port offerts - Colissimo""</span>,<br/>
477
+ &nbsp;&nbsp;&nbsp;destination: <span class=""string"">""{colissimo.destination}""</span>,<br/>
478
+ &nbsp;&nbsp;&nbsp;conditions: <span class=""string"">""{cart.price_including_tax}&gt;=80 and {cart.weight}&gt;10 and {cart.weight}&lt;=29.8""</span>,<br/>
479
+ &nbsp;&nbsp;&nbsp;fees: 0.00,<br/>
480
+ }<br/>
481
+ <br/>
482
+ {<br/>
483
+ &nbsp;&nbsp;&nbsp;code: <span class=""string"">""supplement_colissimo""</span>,<br/>
484
+ &nbsp;&nbsp;&nbsp;label: <span class=""string"">""Supplément Colissimo""</span>,<br/>
485
+ &nbsp;&nbsp;&nbsp;destination: <span class=""string"">""{colissimo.destination}""</span>,<br/>
486
+ &nbsp;&nbsp;&nbsp;conditions: <span class=""string"">""{courrier_suivi_offert.conditions} or {lettre_recommandee_offert.conditions}""</span>,<br/>
487
+ &nbsp;&nbsp;&nbsp;fees: <span class=""string"">""{colissimo.fees} - min({courrier_suivi.fees},{lettre_recommandee.fees})""</span>,<br/>
488
+ }<br/>
489
+ <br/>
490
+ {<br/>
491
+ &nbsp;&nbsp;&nbsp;code: <span class=""string"">""chronopost""</span>,<br/>
492
+ &nbsp;&nbsp;&nbsp;label: <span class=""string"">""Chronopost""</span>,<br/>
493
+ &nbsp;&nbsp;&nbsp;destination: <span class=""string"">""FR""</span>,<br/>
494
+ &nbsp;&nbsp;&nbsp;conditions: <span class=""string"">""{cart.price_including_tax}&lt;80""</span>,<br/>
495
+ &nbsp;&nbsp;&nbsp;fees: <span class=""string"">""{table {cart.weight} in 1:13.29, 2:13.99, 3:18.4, 4:19.24, 5:20.08, 6:20.92, 7:21.76, 8:22.6, 9:23.44, 10:24.28, 15:28.48, 20:32.68, 25:36.88, 30:41.08}""</span>,<br/>
496
+ }<br/>
497
+ <br/>
498
+ {<br/>
499
+ &nbsp;&nbsp;&nbsp;code: <span class=""string"">""chronopost_offert""</span>,<br/>
500
+ &nbsp;&nbsp;&nbsp;label: <span class=""string"">""Frais de port offerts - Chronopost""</span>,<br/>
501
+ &nbsp;&nbsp;&nbsp;destination: <span class=""string"">""FR""</span>,<br/>
502
+ &nbsp;&nbsp;&nbsp;conditions: <span class=""string"">""{cart.price_including_tax}&lt;80 and {cart.weight}&gt;29.8 and {cart.weight}&lt;=30""</span>,<br/>
503
+ &nbsp;&nbsp;&nbsp;fees: 0.00,<br/>
504
+ }<br/>
505
+ <br/>
506
+ {<br/>
507
+ &nbsp;&nbsp;&nbsp;code: <span class=""string"">""supplement_chronopost""</span>,<br/>
508
+ &nbsp;&nbsp;&nbsp;label: <span class=""string"">""Supplément Chronopost""</span>,<br/>
509
+ &nbsp;&nbsp;&nbsp;destination: <span class=""string"">""{chronopost.destination}""</span>,<br/>
510
+ &nbsp;&nbsp;&nbsp;conditions: <span class=""string"">""{courrier_suivi_offert.conditions} or {lettre_recommandee_offert.conditions} or {colissimo_offert.conditions}""</span>,<br/>
511
+ &nbsp;&nbsp;&nbsp;fees: <span class=""string"">""{chronopost.fees} - min({courrier_suivi.fees},{lettre_recommandee.fees},{colissimo.fees})""</span>,<br/>
512
+ }
513
+ </div>
514
+
515
+ <div class=""help-footer"">
516
+ <p><a href=""#"" onclick=""os2editor.help('summary');"">Sommaire</a></p>
517
+ </div>
518
+ "
519
+ "{os2editor.help.more.attributes-options}","
520
+ <div class=""help-header"">
521
+ <p><a href=""#"" onclick=""os2editor.help('summary');"">Sommaire</a></p>
522
+ </div>
523
+
524
+ <h4>Utilisation des attributs ou des options des produits</h4>
525
+
526
+ <p>
527
+ Il est possible d'utiliser les attributs ou les options des produits à l'aide de la syntaxe ci-dessous.
528
+ </p>
529
+ <p>
530
+ Vous pouvez utiliser cette technique dans les propriétés 'conditions' et 'fees'.
531
+ </p>
532
+
533
+ <div class=""code""><span class=""comment""># Si au moins un produit possède l'attribut 'color' égal à 'Bleu'<br/></span>
534
+ conditions: <span class=""string"">""{count products where product.attribute.color=='Bleu'}&gt;0""</span>,<br/>
535
+ ...<br/>
536
+ <span class=""comment""># Si tous les produits possèdent l'option 'size' supérieure ou égal à '1'<br/></span>
537
+ conditions: <span class=""string"">""{count products where product.option.size&gt;='1'}=={cart.quantity}""</span>,<br/>
538
+ ...<br/>
539
+ <span class=""comment""># Le nombre de SKU différents<br/></span>
540
+ conditions: <span class=""string"">""{count distinct product.attribute.sku}""</span>,<br/>
541
+ ...<br/>
542
+ <span class=""comment""># La somme de toutes les options 'size' est supérieure à 30<br/></span>
543
+ conditions: <span class=""string"">""{sum product.option.size}&gt;30""</span>,<br/>
544
+ ...<br/>
545
+ <span class=""comment""># Le prix HT sans remise minimum des produits dans le panier est supérieur à 10<br/></span>
546
+ conditions: <span class=""string"">""{min product.attribute.price-tax-discount}>10""</span>,<br/>
547
+ ...<br/>
548
+ <span class=""comment""># La valeur maximum de l'option 'size' des produits dans le panier est inférieure à 50<br/></span>
549
+ conditions: <span class=""string"">""{max product.option.size}<50""</span>,<br/>
550
+ ...<br/>
551
+ <span class=""comment""># Le nombre de produits en stock<br/></span>
552
+ conditions: <span class=""string"">""{count products where product.stock.is_in_stock==true}""</span>,<br/>
553
+ ...
554
+ </div>
555
+
556
+ <p>
557
+ Liste des préfixes possibles :
558
+ </p>
559
+ <ul>
560
+ <li><b>count :</b> nombre (toujours suivi de 'products')</li>
561
+ <li><b>count distinct :</b> nombre distinct (toujours suivi d'une propriété)</li>
562
+ <li><b>sum :</b> somme (toujours suivi d'une propriété)</li>
563
+ <li class=""new""><b>min :</b> minimum (toujours suivi d'une propriété)</li>
564
+ <li class=""new""><b>max :</b> maximum (toujours suivi d'une propriété)</li>
565
+ </ul>
566
+ <p>
567
+ Liste des propriétés possibles :
568
+ </p>
569
+ <ul>
570
+ <li><b>product.attribute.* :</b> attribut<br/>Liste d'attributs intéressants :
571
+ <ul>
572
+ <li><b>sku :</b> la référence</li>
573
+ <li><b>name :</b> le nom</li>
574
+ <li><b>weight :</b> le poids</li>
575
+ <li><b>price :</b> le prix (tel qu'il a été saisi sur la fiche du produit)</li>
576
+ <li><b>special_price :</b> le prix promotionnel (tel qu'il a été saisi sur la fiche du produit)</li>
577
+ </ul>
578
+ <span class=""new"">Quelques pseudos-attributs sont également disponibles pour faciliter certains calculs :
579
+ <ul>
580
+ <li><b>price-tax+discount :</b> le prix HT avec remise</li>
581
+ <li><b>price-tax-discount :</b> le prix HT sans remise</li>
582
+ <li><b>price+tax+discount :</b> le prix TTC avec remise</li>
583
+ <li><b>price+tax-discount :</b> le prix TTC sans remise</li>
584
+ </ul></span>
585
+ </li>
586
+ <li><b>product.option.* :</b> option</li>
587
+ <li><b>product.stock.is_in_stock :</b> disponibilité du produit</li>
588
+ <li><b>product.stock.quantity :</b> stock du produit</li>
589
+ </ul>
590
+ <p>
591
+ Il est possible de spécifier des conditions que doivent remplir les produits pour être pris en compte. Pour cela, il suffit d'ajouter <span class=""code""> where </span> suivi d'une formule.
592
+ </p>
593
+ <p>
594
+ Si la propriété est de type <strong>Oui/Non</strong>, vous devez utiliser les valeurs <span class=""code"">true</span>/<span class=""code"">false</span> ou <span class=""code"">1</span>/<span class=""code"">0</span> sans les guillemets.
595
+ </p>
596
+ <div class=""code""><span class=""comment""># Propriété de type Oui/Non</span><br/>
597
+ conditions: <span class=""string"">""{count products where product.attribute.colissimo_allowed==1}""</span>,<br/>
598
+ <span class=""comment""># ou</span><br/>
599
+ conditions: <span class=""string"">""{count products where product.attribute.colissimo_allowed==true}""</span>,</div>
600
+
601
+ <p>
602
+ Si la propriété est de type <strong>Liste de sélection</strong> et que vous souhaitez faire une comparaison avec l'id plutôt qu'avec la valeur, vous devez utiliser la syntaxe suivante :
603
+ </p>
604
+
605
+ <div class=""code""><span class=""comment""># Condition validée si l'attribut 'color' est égale à la valeur dont l'id est 1</span><br/>
606
+ conditions: <span class=""string"">""{count products where product.attribute.color.id==1}""</span>,</div>
607
+
608
+ <div class=""help-footer"">
609
+ <p><a href=""#"" onclick=""os2editor.help('summary');"">Sommaire</a></p>
610
+ </div>
611
+ "
612
+ "{os2editor.help.more.foreach}","
613
+ <div class=""help-header"">
614
+ <p><a href=""#"" onclick=""os2editor.help('summary');"">Sommaire</a></p>
615
+ </div>
616
+
617
+ <h4>Utilisation des boucles foreach</h4>
618
+
619
+ <p>
620
+ Les boucles foreach permettent d'effectuer un calcul sur des groupes de produits plutôt que de tenir compte de tous les produits du panier.<br/>
621
+ Le résultat global d'une boucle foreach est la somme des résultats de chaque passage dans la boucle.
622
+ </p>
623
+ <p>
624
+ A l'intérieur d'une boucle foreach, il est possible d'utiliser de nouvelles variables :
625
+ </p>
626
+ <ul>
627
+ <li><b>{selection.weight}</b>: poids de la sélection</li>
628
+ <li><b>{selection.quantity}</b>: nombre d'articles dans la sélection</li>
629
+ </ul>
630
+ <p>
631
+ Lorsque la sélection se fait sur le sku, chaque sélection est composée d'un seul article. On peut donc utiliser d'autres variables :
632
+ </p>
633
+ <ul>
634
+ <li><b>{product.weight}</b>: poids de l'article sélectionné</li>
635
+ <li><b>{product.quantity}</b>: quantité de l'article sélectionné</li>
636
+ <li><b>{product.attribute.*}</b>: attribut de l'article sélectionné<br/>
637
+ <span class=""new"">Quelques pseudos-attributs sont également disponibles pour faciliter certains calculs :
638
+ <ul>
639
+ <li><b>price-tax+discount :</b> le prix HT avec remise</li>
640
+ <li><b>price-tax-discount :</b> le prix HT sans remise</li>
641
+ <li><b>price+tax+discount :</b> le prix TTC avec remise</li>
642
+ <li><b>price+tax-discount :</b> le prix TTC sans remise</li>
643
+ </ul></span>
644
+ </li>
645
+ <li><b>{product.option.*}</b>: option de l'article sélectionné</li>
646
+ </ul>
647
+
648
+ <div class=""code""><span class=""comment""># Regroupement des produits par origine puis traitement des groupes séparémment</span><br/>
649
+ fees: <span class=""string"">""{foreach product.attribute.code_origin}{table {selection.weight} in 0.0:0.00, 1.0:11.00, 3.0:12.00, 5.0:13.00}{/foreach}""</span>,<br/>
650
+ <br/>
651
+ <span class=""comment""># Calcul individuel des frais de port</span><br/>
652
+ fees: <span class=""string"">""{foreach product.attribute.sku}{product.attribute.shipping}*{product.quantity}{/foreach}""</span>,<br/>
653
+ </div>
654
+
655
+ <div class=""help-footer"">
656
+ <p><a href=""#"" onclick=""os2editor.help('summary');"">Sommaire</a></p>
657
+ </div>
658
+ "
659
+ "{os2editor.help.more.custom-variables}","
660
+ <div class=""help-header"">
661
+ <p><a href=""#"" onclick=""os2editor.help('summary');"">Sommaire</a></p>
662
+ </div>
663
+
664
+ <h4>Utilisation des variables personnalisées de Magento (Custom Variables)</h4>
665
+ <p>
666
+ Depuis la version 1.4.0.1 de Magento, il est possible de définir des variables personnalisées.
667
+ </p>
668
+ <p>
669
+ La version 2.2.7 d'Owebia Shipping vous permet d'utiliser ces variables personnalisées grâce à la syntaxe suivante :
670
+ </p>
671
+ <div class=""code""><span class=""comment""># Utilisation de la variable personnalisée my_var<br/></span>
672
+ fees: <span class=""string"">""{customvar.my_var}*5.00""</span>,<br/>
673
+ ...<br/>
674
+ <span class=""comment""># Idem en utilisant la syntaxe standard de Magento<br/></span>
675
+ fees: <span class=""string"">""{{customVar code=my_var}}*5.00""</span>,<br/>
676
+ ...</div>
677
+
678
+ <div class=""help-footer"">
679
+ <p><a href=""#"" onclick=""os2editor.help('summary');"">Sommaire</a></p>
680
+ </div>
681
+ "
682
+ "{os2editor.help.property.conditions}","
683
+ <div class=""help-header"">
684
+ <p><a href=""#"" onclick=""os2editor.help('summary');"">Sommaire</a></p>
685
+ </div>
686
+
687
+ <h4>Les conditions : `conditions`</h4>
688
+ <p>
689
+ La propriété `conditions` se spécifie sous la forme d'une <a href=""#"" onclick=""os2editor.help('more.formulas');"">formule (voir l'initiation aux formules)</a>
690
+ qui doit retourner une valeur booléenne (true ou false).
691
+ </p>
692
+
693
+ <div class=""code""><span class=""comment""># Tranches de prix</span><br/>
694
+ <br/>
695
+ &nbsp;&nbsp;&nbsp;<span class=""comment""># De 0 à 70 TTC</span><br/>
696
+ &nbsp;&nbsp;&nbsp;conditions: <span class=""string"">""{cart.price_including_tax}&lt;=70""</span>,<br/>
697
+ <br/>
698
+ &nbsp;&nbsp;&nbsp;<span class=""comment""># De 0 à 70 HT</span><br/>
699
+ &nbsp;&nbsp;&nbsp;conditions: <span class=""string"">""{cart.price_excluding_tax}&lt;=70""</span>,<br/>
700
+ <br/>
701
+ &nbsp;&nbsp;&nbsp;<span class=""comment""># De 20 exclu à 70 inclu</span><br/>
702
+ &nbsp;&nbsp;&nbsp;conditions: <span class=""string"">""({cart.price_excluding_tax} &gt; 20) and ({cart.price_excluding_tax} &lt;= 70)""</span>,<br/>
703
+ <br/>
704
+ &nbsp;&nbsp;&nbsp;<span class=""comment""># De 10 inclu à 50 exclu</span><br/>
705
+ &nbsp;&nbsp;&nbsp;conditions: <span class=""string"">""({cart.price_excluding_tax} &gt;= 10) and ({cart.price_excluding_tax} &lt; 50)""</span>,<br/>
706
+ <br/>
707
+ <br/>
708
+ <span class=""comment""># Tranches de poids</span><br/>
709
+ <br/>
710
+ &nbsp;&nbsp;&nbsp;<span class=""comment""># De 0.5 exclu à 3 inclu</span><br/>
711
+ &nbsp;&nbsp;&nbsp;conditions: <span class=""string"">""({cart.weight} &gt; 0.5) and ({cart.weight} &lt;= 3.0)""</span>,<br/>
712
+ <br/>
713
+ &nbsp;&nbsp;&nbsp;<span class=""comment""># De 1 inclu à 5 exclu</span><br/>
714
+ &nbsp;&nbsp;&nbsp;conditions: <span class=""string"">""({cart.weight} &gt;= 1.0) and ({cart.weight} &lt; 5.0)""</span>,<br/>
715
+ <br/>
716
+ <br/>
717
+ <span class=""comment""># Free shipping</span><br/>
718
+ <br/>
719
+ &nbsp;&nbsp;&nbsp;<span class=""comment""># Only when free shipping</span><br/>
720
+ &nbsp;&nbsp;&nbsp;conditions: <span class=""string"">""{free_shipping}""</span>,<br/>
721
+ <br/>
722
+ &nbsp;&nbsp;&nbsp;<span class=""comment""># Only when no free shipping</span><br/>
723
+ &nbsp;&nbsp;&nbsp;conditions: <span class=""string"">""!{free_shipping}""</span>,<br/>
724
+ <br/>
725
+ <br/>
726
+ <span class=""comment""># Attribut ou option des produits</span><br/>
727
+ <br/>
728
+ &nbsp;&nbsp;&nbsp;<span class=""comment""># Si au moins un produit possède l'attribut 'color' égal à 'Bleu'</span><br/>
729
+ &nbsp;&nbsp;&nbsp;conditions: <span class=""string"">""{count products where product.attribute.color=='Bleu'}&gt;1""</span>,<br/>
730
+ <br/>
731
+ &nbsp;&nbsp;&nbsp;<span class=""comment""># Si tous les produits possèdent l'option 'size' supérieure ou égal à '1'</span><br/>
732
+ &nbsp;&nbsp;&nbsp;conditions: <span class=""string"">""{count products where product.option.size&gt;='1'}=={cart.quantity}""</span>,</div>
733
+
734
+ <div class=""help-footer"">
735
+ <p><a href=""#"" onclick=""os2editor.help('summary');"">Sommaire</a></p>
736
+ </div>
737
+
738
+ "
739
+ "{os2editor.help.property.destination}","
740
+ <div class=""help-header"">
741
+ <p><a href=""#"" onclick=""os2editor.help('summary');"">Sommaire</a></p>
742
+ </div>
743
+
744
+ <h4>La destination : `destination`</h4>
745
+ <p>
746
+ Les codes pays utilisés sont ceux de Magento (à priori ils sont les mêmes que les codes ISO 3166-1 alpha-2).<br/>
747
+ Il est possible de spécifier les codes régions ou les codes postaux que l'on veut filtrer ou exclure.
748
+ </p>
749
+ <p class=""new"">
750
+ Vous pouvez utiliser le caractère jocker <span class=""code"">*</span> ou les expressions régulières pour les codes postaux.<br/>
751
+ Une expression régulière doit commencer et se terminer par le caractère <span class=""code"">/</span>. Si vous souhaitez utiliser les caractères <span class=""code"">(</span>, <span class=""code"">)</span> ou <span class=""code"">,</span>, vous devez les échapper avec le caractère <span class=""code"">\</span> (ex: <span class=""code""><span class=""string"">""FR(/^25\([0-9]{3}\)$/)""</span></span>).
752
+ </p>
753
+
754
+ <div class=""code""><span class=""comment""># France, Allemagne, Suisse, Espagne, Italie</span><br/>
755
+ destination: <span class=""string"">""FR,DE,CH,ES,IT""</span>,<br/>
756
+ <br/>
757
+ <span class=""comment""># France sauf la Corse</span><br/>
758
+ destination: <span class=""string"">""FR-(2A,2B)""</span>,<br/>
759
+
760
+ <br/>
761
+ <span class=""comment""># Corse</span><br/>
762
+ destination: <span class=""string"">""FR(2A,2B)""</span>,<br/>
763
+ <br/>
764
+ <span class=""comment""># Le monde entier sauf l'Allemagne et la Corse</span><br/>
765
+ destination: <span class=""string"">""* - ( DE, FR(2A,2B) )""</span>,<br/>
766
+
767
+ <br/>
768
+ <span class=""comment""># Tous les codes postaux commençant par 25 en utilisant le caractère jocker</span><br/>
769
+ destination: <span class=""string"">""FR(25*)""</span>,<br/>
770
+ <br/>
771
+ <span class=""comment""># Tous les codes postaux commençant par 25 en utilisant une expression régulière</span><br/>
772
+ destination: <span class=""string"">""FR(/^25[0-9]{3}$/)""</span>,</div>
773
+
774
+ <div class=""tips"">
775
+ <p><strong>Astuce</strong><br/>Dans l'éditeur, vous pouvez utiliser les code pays mais aussi les noms des pays ainsi que des raccourcis pour insérer des groupes de pays.</p>
776
+ <ul>
777
+ <li><strong>UE</strong> ou <strong>Union Européenne</strong> : ajoute les pays de l'Union Européenne.</li>
778
+ <li><strong>DOM</strong> : ajoute les Départements d'Outre-Mer Français.</li>
779
+ <li><strong>COM</strong> : ajoute les Collectivités d'Outre-Mer Françaises.</li>
780
+ <li><strong>Outre-Mer</strong> : ajoute tout l'Outre-Mer Français.</li>
781
+ <li><strong>Corse</strong> : ajoute la corse (<span class=""code""><span class=""string"">""FR(2A,2B)""</span></span>).</li>
782
+ </ul>
783
+ <p>
784
+ Vous pouvez interragir avec les pays se trouvant dans l'Aperçu. Si vous cliquez sur l'un d'eux, un menu vous offre la possibilité d'effectuer certaines actions.
785
+ </p>
786
+ </div>
787
+
788
+ <div class=""help-footer"">
789
+ <p><a href=""#"" onclick=""os2editor.help('summary');"">Sommaire</a></p>
790
+ </div>
791
+ "
792
+ "{os2editor.help.property.enabled}","
793
+ <div class=""help-header"">
794
+ <p><a href=""#"" onclick=""os2editor.help('summary');"">Sommaire</a></p>
795
+ </div>
796
+
797
+ <h4>L'activation : `enabled`</h4>
798
+ <p>Permet d'activer ou de désactiver la méthode de livraison.</p>
799
+ <p>La valeur doit être booléenne.</p>
800
+
801
+ <div class=""help-footer"">
802
+ <p><a href=""#"" onclick=""os2editor.help('summary');"">Sommaire</a></p>
803
+ </div>
804
+ "
805
+ "{os2editor.help.property.code}","
806
+ <div class=""help-header"">
807
+ <p><a href=""#"" onclick=""os2editor.help('summary');"">Sommaire</a></p>
808
+ </div>
809
+
810
+ <h4>Le code : `code`</h4>
811
+ <p>C'est l'identifiant de la méthode de livraison.</p>
812
+ <p>Il doit être unique. S'il n'est pas unique, il sera modifié.</p>
813
+
814
+ <div class=""help-footer"">
815
+ <p><a href=""#"" onclick=""os2editor.help('summary');"">Sommaire</a></p>
816
+ </div>
817
+ "
818
+ "{os2editor.help.property.description}","
819
+ <div class=""help-header"">
820
+ <p>Voir également la propriété <a href=""#"" onclick=""os2editor.help('property.label');"">label</a>.</p>
821
+ <p><a href=""#"" onclick=""os2editor.help('summary');"">Sommaire</a></p>
822
+ </div>
823
+
824
+ <h4>La description : `description`</h4>
825
+ <p>Il s'agit de la description de la méthode de livraison.</p>
826
+ <p>Le fonctionnement est identique à la propriété <a href=""#"" onclick=""os2editor.help('property.label');"">label</a>.</p>
827
+
828
+ <div class=""help-footer"">
829
+ <p>Voir également la propriété <a href=""#"" onclick=""os2editor.help('property.label');"">label</a>.</p>
830
+ <p><a href=""#"" onclick=""os2editor.help('summary');"">Sommaire</a></p>
831
+ </div>
832
+ "
833
+ "{os2editor.help.property.origin}","
834
+ <div class=""help-header"">
835
+ <p>Voir également la propriété <a href=""#"" onclick=""os2editor.help('property.destination');"">destination</a>.</p>
836
+ <p><a href=""#"" onclick=""os2editor.help('summary');"">Sommaire</a></p>
837
+ </div>
838
+
839
+ <h4>L'origine : `origin`</h4>
840
+ <p>
841
+ Idem que la destination mais pour filtrer l'origine de livraison.<br/>
842
+ La syntaxe est identique au filtrage de la <a href=""#"" onclick=""os2editor.help('property.destination');"">destination</a>.
843
+ </p>
844
+
845
+ <div class=""help-footer"">
846
+ <p>Voir également la propriété <a href=""#"" onclick=""os2editor.help('property.destination');"">destination</a>.</p>
847
+ <p><a href=""#"" onclick=""os2editor.help('summary');"">Sommaire</a></p>
848
+ </div>
849
+ "
850
+ "{os2editor.help.property.customer_groups}","
851
+ <div class=""help-header"">
852
+ <p><a href=""#"" onclick=""os2editor.help('summary');"">Sommaire</a></p>
853
+ </div>
854
+
855
+ <h4>Les groupes client : `customer_groups`</h4>
856
+ <p>
857
+ On peut utiliser le nom ou l'ID des groupes client.
858
+ </p>
859
+
860
+ <div class=""code""><span class=""comment""># Groupes NOT LOGGED IN et General</span><br/>
861
+ customer_groups: <span class=""string"">""NOT LOGGED IN,General""</span>,<br/>
862
+
863
+ <br/>
864
+ <span class=""comment""># Groupes NOT LOGGED IN et General par leur ID</span><br/>
865
+ customer_groups: <span class=""string"">""0,1""</span>,<br/>
866
+ <br/>
867
+ <span class=""comment""># Groupe Retailer</span><br/>
868
+ customer_groups: <span class=""string"">""Retailer""</span>,</div>
869
+
870
+ <div class=""help-footer"">
871
+ <p><a href=""#"" onclick=""os2editor.help('summary');"">Sommaire</a></p>
872
+ </div>
873
+ "
874
+ "{os2editor.help.property.tracking_url}","
875
+ <div class=""help-header"">
876
+ <p><a href=""#"" onclick=""os2editor.help('summary');"">Sommaire</a></p>
877
+ </div>
878
+
879
+ <h4>L'URL de suivi : `tracking_url`</h4>
880
+ <p>
881
+ <strong>L'utilisation de la propriété `tracking_url` est réservée aux utilisateurs expérimentés. Si vous ne comprenez pas les indications ci-dessous, il est préférable que vous évitiez d'utiliser cette fonctionnalité.</strong>
882
+ </p>
883
+ <p>
884
+ La propriété `tracking_url` permet de surcharger le champ ""URL de suivi"" d'un mode de livraison Owebia Shipping et ainsi de spécifier une URL de suivi <strong>par méthode de livraison</strong> plutôt qu'une pour tout le mode de livraison.
885
+ </p>
886
+ <p>
887
+ Pour insérer automatiquement le numéro de colis dans l'URL de suivi, vous devez utiliser <span class=""code"">{tracking_number}</span>.
888
+ </p>
889
+
890
+ <div class=""code""><span class=""comment""># URL de suivi pour le transporteur Colissimo</span><br/>
891
+ tracking_url: <span class=""string"">""http://www.coliposte.net/particulier/suivi_particulier.jsp?colispart={tracking_number}""</span>,</div>
892
+
893
+ <p>
894
+ Magento ne gère pas les liens de tracking mais un statut de tracking. L'extension Owebia Shipping 2 fournit un lien HTML à la place du statut, lien qui permet d'aller sur le site du transporteur et de suivre l'avancement de la livraison du colis.
895
+ </p>
896
+ <p>
897
+ Lorsque l'URL de suivi est construite par l'extension, la seule information disponible est le numéro de colis et on n'a nul part accès à la méthode de livraison sélectionnée. Afin de pouvoir retrouver l'url de suivi dans la configuration, il faut spécifier la méthode de livraison dans le numéro de tracking, par exemple : <span class=""code"">colissimo:8Lxxxxxxxxxxx</span> où <span class=""code"">colissimo</span> est le code de la méthode de livraison sélectionnée.<br/>
898
+ Si aucun code n'est spécifié (si vous saisissez uniquement le numéro de tracking), l'url utilisée sera celle globale au mode de livraison.
899
+ </p>
900
+ <p>
901
+ Pour répondre à une question récurrente, Magento affiche le statut de livraison depuis le back office ou le front office. <strong>Si vous souhaitez insérer l'URL de suivi dans les mails d'expédition, vous devrez développer vous même la récupération de l'URL de suivi et son insertion dans le mail, en effet, l'extension Owebia Shipping 2 se contente de fournir des modes de livraison paramétrables sans apporter de grande modification au coeur de Magento afin de réduire les problèmes d'incompatibilité et de mise à jour.</strong>
902
+ </p>
903
+ <p>
904
+ Si vous obtenez un popup vide lorsque vous cliquez sur le lien de suivi, votre problème est très certainement lié au fait que vous n'avez pas spécifié le code de la méthode de livraison dans le numéro de suivi (voir indications plus haut) et que votre champ global ""URL de suivi"" est vide.
905
+ </p>
906
+ <p>
907
+ Il n'est actuellement pas prévu de modifier les fonctionnalitées de l'extension liées à l'URL de suivi.
908
+ </p>
909
+
910
+ <div class=""help-footer"">
911
+ <p><a href=""#"" onclick=""os2editor.help('summary');"">Sommaire</a></p>
912
+ </div>
913
+ "
914
+ "{os2editor.help.property.*comment}","
915
+ <div class=""help-header"">
916
+ <p><a href=""#"" onclick=""os2editor.help('summary');"">Sommaire</a></p>
917
+ </div>
918
+
919
+ <h4>Commentaires</h4>
920
+ <p>
921
+ Vous pouvez ajouter un commentaire sur la méthode de livraison. Celui-ci ne sera affiché nul part mais vous pouvez y mettre des annotations.
922
+ </p>
923
+
924
+ <div class=""help-footer"">
925
+ <p><a href=""#"" onclick=""os2editor.help('summary');"">Sommaire</a></p>
926
+ </div>
927
+ "
928
+ "{os2editor.help.changelog}","
929
+ <div class=""help-header"">
930
+ <p><a href=""#"" onclick=""os2editor.help('summary');"">Sommaire</a></p>
931
+ </div>
932
+
933
+ <h4>Changelog</h4>
934
+ <div class=""code""><pre>
935
+ {changelog}
936
+ </pre></div>
937
+
938
+ <div class=""help-footer"">
939
+ <p><a href=""#"" onclick=""os2editor.help('summary');"">Sommaire</a></p>
940
+ </div>
941
+ "
js/owebia/shipping2/os2editor.css ADDED
@@ -0,0 +1,469 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #os2-editor #os2-editor-config-loader {
2
+ padding: 5px;
3
+ border: solid 1px #6f8992;
4
+ background: #e7efef;
5
+ display: none;
6
+ }
7
+
8
+ #os2-editor #os2-editor-config-loader textarea {
9
+ height: 100px;
10
+ }
11
+
12
+ #os2-editor #os-config-helper {
13
+ }
14
+ #os2-editor .buttons-set-label {
15
+ padding: 2px 10px 2px 0;
16
+ display: inline-block;
17
+ font-weight: bold;
18
+ }
19
+ #os2-editor div.buttons-set {
20
+ padding: 0;
21
+ margin: 2px 0;
22
+ }
23
+ #os2-editor fieldset {
24
+ display: block;
25
+ border: solid 1px #6f8992;
26
+ margin: 2px 0;
27
+ padding: 0 8px 2px 8px;
28
+ }
29
+ #os2-editor fieldset.buttons-set {
30
+ margin: 2px 0;
31
+ }
32
+ #os2-editor legend {
33
+ display: inline;
34
+ font-weight: bold;
35
+ margin-left: 15px;
36
+ padding: 0 5px;
37
+ line-height: normal;
38
+ height: auto;
39
+ width: auto;
40
+ visibility: visible;
41
+ }
42
+
43
+ #os2-editor .config-container {
44
+ border-top: solid 1px #6f8992;
45
+ }
46
+
47
+ #os2-editor .properties-container {
48
+ position: relative;
49
+ display: none;
50
+ }
51
+
52
+ #os2-editor .row-container.selected .properties-container {
53
+ display: block;
54
+ background: #d1dedf;
55
+ }
56
+
57
+ #os2-editor .row-container.has-error .properties-container {
58
+ background: #f3c6c6;
59
+ }
60
+
61
+ #os2-editor .properties-list {
62
+ position: relative;
63
+ height: 350px;
64
+ list-style: none;
65
+ width: 20%;
66
+ z-index: 2;
67
+ padding: 5px 0;
68
+ -webkit-box-sizing: border-box; /* Safari/Chrome, other WebKit */
69
+ -khtml-box-sizing: border-box;
70
+ -moz-box-sizing: border-box; /* Firefox, other Gecko */
71
+ box-sizing: border-box; /* Opera/IE 8+ */
72
+ }
73
+
74
+ #os2-editor .properties-list li {
75
+ margin-left: 10px;
76
+ padding: 5px 0;
77
+ cursor: pointer;
78
+ font-weight: bold;
79
+ }
80
+
81
+ #os2-editor .properties-list li.selected {
82
+ font-weight: bold;
83
+ border-left: solid 1px #6f8992;
84
+ border-top: solid 1px #6f8992;
85
+ border-bottom: solid 1px #6f8992;
86
+ background: #e7efef;
87
+ padding: 7px 10px;
88
+ position: relative;
89
+ left: 1px;
90
+ }
91
+
92
+ #os2-editor .row-container.has-error .properties-list li.selected {
93
+ border-color: #af2c2c;
94
+ background: #f7e8e8;
95
+ }
96
+
97
+ #os2-editor .properties-list li.has-error {
98
+ font-weight: bold;
99
+ color: #d40707;
100
+ }
101
+
102
+ #os2-editor .properties-list li.empty {
103
+ font-weight: normal;
104
+ -webkit-opacity: 0.8;
105
+ -khtml-opacity: 0.8;
106
+ -moz-opacity: 0.8;
107
+ opacity: 0.8;
108
+ }
109
+
110
+ #os2-editor .properties-list li.hide {
111
+ display: none;
112
+ }
113
+
114
+ #os2-editor .property-container {
115
+ position: absolute;
116
+ top: 0;
117
+ right: 0;
118
+ height: 350px;
119
+ overflow: auto;
120
+ width: 80%;
121
+ padding: 8px;
122
+ -webkit-box-sizing: border-box; /* Safari/Chrome, other WebKit */
123
+ -khtml-box-sizing: border-box;
124
+ -moz-box-sizing: border-box; /* Firefox, other Gecko */
125
+ box-sizing: border-box; /* Opera/IE 8+ */
126
+ display: none;
127
+ border-left: solid 1px #6f8992;
128
+ background: #e7efef;
129
+ z-index: 1;
130
+ }
131
+
132
+ #os2-editor .property-container.selected {
133
+ display: block;
134
+ }
135
+
136
+ #os2-editor .row-container.has-error .property-container {
137
+ border-color: #af2c2c;
138
+ background: #f7e8e8;
139
+ }
140
+
141
+ #os2-editor .row-header {
142
+ padding: 3px;
143
+ background: #d1dedf;
144
+ color: #6f8992;
145
+ }
146
+
147
+ #os2-editor .row-header .error {
148
+ padding: 0 10px;
149
+ }
150
+
151
+ #os2-editor .row-container.selected .row-header .error {
152
+ color: #fff !important;
153
+ }
154
+
155
+ #os2-editor .row-title {
156
+ padding: 2px 9px;
157
+ cursor: pointer;
158
+ font-weight: bold;
159
+ font-size: 1.3em;
160
+ }
161
+
162
+ #os2-editor .row-actions {
163
+ float: right;
164
+ opacity: 0.7;
165
+ -moz-opacity: 0.7;
166
+ -webkit-opacity: 0.7;
167
+ -khtml-opacity: 0.7;
168
+ }
169
+ #os2-editor .row-actions button {
170
+ margin-left: 5px;
171
+ }
172
+
173
+ #os2-editor .row-container {
174
+ border: solid 1px #6f8992;
175
+ border-top: 0;
176
+ }
177
+
178
+ #os2-editor .row-container.selected .row-header {
179
+ background: #6f8992;
180
+ color: #fff;
181
+ }
182
+
183
+ #os2-editor .row-container.selected .row-actions {
184
+ opacity: 1;
185
+ -moz-opacity: 1;
186
+ -webkit-opacity: 1;
187
+ -khtml-opacity: 1;
188
+ }
189
+
190
+ #os2-editor .row-container.has-error {
191
+ border: solid 1px #af2c2c;
192
+ }
193
+
194
+ #os2-editor .row-container.has-error .row-header {
195
+ background: #f3c6c6;
196
+ color: #af2c2c;
197
+ }
198
+
199
+ #os2-editor .row-container.selected.has-error .row-header {
200
+ background: #af2c2c;
201
+ color: #fff;
202
+ }
203
+
204
+ #os2-editor textarea {
205
+ border: 0;
206
+ background: #fff;
207
+ display: block;
208
+ overflow: visible;
209
+ width: 100%;
210
+ height: auto;
211
+ -webkit-box-sizing: border-box; /* Safari/Chrome, other WebKit */
212
+ -moz-box-sizing: border-box; /* Firefox, other Gecko */
213
+ -khtml-box-sizing: border-box;
214
+ box-sizing: border-box; /* Opera/IE 8+ */
215
+ padding: 2px 0 2px 5px;
216
+ }
217
+
218
+ #os2-editor .row-container textarea {
219
+ height: 100px;
220
+ }
221
+
222
+ #os2-editor .field-container{
223
+ background: #666;
224
+ padding: 2px;
225
+ }
226
+
227
+ #os2-editor .preview-items-list {
228
+ font-size: 0.9em;
229
+ padding: 2px 0 5px 0;
230
+ line-height: normal;
231
+ }
232
+
233
+ #os2-editor .preview-item {
234
+ display: inline-block;
235
+ padding: 2px 7px;
236
+ margin: 1px;
237
+ cursor: pointer;
238
+ -webkit-border-radius: 5px;
239
+ -khtml-border-radius: 5px;
240
+ -moz-border-radius: 5px;
241
+ border-radius: 5px;
242
+ }
243
+
244
+ #os2-editor .preview-item-group-label {
245
+ padding: 2px 7px;
246
+ margin: 1px;
247
+ cursor: pointer;
248
+ border: solid 1px #6f8992;
249
+ background: #6f8992;
250
+ display: inline-block;
251
+ }
252
+
253
+ #os2-editor .preview-item-group {
254
+ padding: 2px;
255
+ color: #fff;
256
+ border: 0;
257
+ background: #6f8992;
258
+ display: block;
259
+ }
260
+
261
+ #os2-editor .preview-item.known {
262
+ color: #000;
263
+ border: solid 1px #000;
264
+ background: #7f0;
265
+ }
266
+
267
+ #os2-editor .preview-item.soft-cleaned {
268
+ /*color: #000;
269
+ border: solid 1px #000;
270
+ background: #f90;*/
271
+ }
272
+
273
+ #os2-editor .preview-item.hard-cleaned {
274
+ color: #000;
275
+ border: solid 1px #000;
276
+ background: #f90;
277
+ }
278
+
279
+ #os2-editor .preview-item.replaced {
280
+ color: #000;
281
+ border: solid 1px #000;
282
+ background: #f90;
283
+ }
284
+
285
+ #os2-editor .preview-item.warning {
286
+ color: #000;
287
+ border: solid 1px #000;
288
+ background: #f90;
289
+ }
290
+
291
+ #os2-editor .preview-item.unknown {
292
+ color: #000;
293
+ border: solid 1px #000;
294
+ background: #f00;
295
+ font-weight: bold;
296
+ }
297
+ #os2-editor .preview-item.error {
298
+ color: #f00;
299
+ border: solid 1px #f00;
300
+ background: #dcc;
301
+ font-weight: bold;
302
+ }
303
+
304
+ #os2-editor .bad {
305
+ text-decoration: line-through;
306
+ }
307
+
308
+ #os2-editor .donate-container {
309
+ position: absolute;
310
+ bottom: 0;
311
+ border-top: solid 4px #dfdfdf;
312
+ padding: 0.25em 0 0 0;
313
+ width: 100%;
314
+ color: #eb5e00;
315
+ font-size: 1.25em;
316
+ font-weight: bold;
317
+ background: #fff;
318
+ }
319
+ #os2-editor .donate-container table {
320
+ width: 100%;
321
+ }
322
+
323
+ #os2-editor .donate-container .form-buttons {
324
+ text-align: right;
325
+ margin-bottom: 0;
326
+ white-space: nowrap;
327
+ }
328
+
329
+ #os2-editor .os2editor-page {
330
+ position: absolute;
331
+ top: 0;
332
+ left: 0;
333
+ width: 100%;
334
+ height: 100%;
335
+ z-index: 300;
336
+ display: none;
337
+ background: #fff;
338
+ }
339
+
340
+ #os2-editor .owebia-address {
341
+ padding-left: 50px;
342
+ font-family: monospace;
343
+ }
344
+
345
+ #os2-contextual-menu {
346
+ -webkit-box-shadow: 2px 2px 5px #000;
347
+ -khtml-box-shadow: 2px 2px 5px #000;
348
+ -moz-box-shadow: 2px 2px 5px #000;
349
+ box-shadow: 2px 2px 5px #000;
350
+ background: #d1dedf;
351
+ list-style: none;
352
+ margin: 0;
353
+ display: none;
354
+ border: solid 1px #6f8992;
355
+ padding-bottom: 1px;
356
+ }
357
+ #os2-contextual-menu li {
358
+ font-size: 0.9em;
359
+ }
360
+
361
+ #os2-contextual-menu a {
362
+ padding: 3px 7px;
363
+ display: block;
364
+ color: #000;
365
+ text-decoration: none;
366
+ }
367
+
368
+ #os2-contextual-menu a:hover {
369
+ background: #6f8992;
370
+ color: #fff;
371
+ }
372
+
373
+ #os2-contextual-menu span {
374
+ padding: 2px 7px;
375
+ display: block;
376
+ color: #000;
377
+ border-bottom: solid 1px #6f8992;
378
+ font-weight: bold;
379
+ margin-bottom: 1px;
380
+ }
381
+
382
+ #os2-editor .os2editor-page .code {
383
+ font-family: monospace;
384
+ word-wrap: break-word;
385
+ }
386
+ #os2-editor .os2editor-page div.code {
387
+ background-color: #efe8de;
388
+ border: solid 1px #5c5248;
389
+ border-left: solid 3px #5c5248;
390
+ padding: 10px 5px;
391
+ overflow: auto;
392
+ }
393
+ #os2-editor .os2editor-page span.code {
394
+ padding: 0 3px;
395
+ color: #522;
396
+ font-weight: bold;
397
+ }
398
+ #os2-editor .os2editor-page .code .comment {
399
+ color: #666;
400
+ }
401
+ #os2-editor .os2editor-page .code .string {
402
+ color: #009f00;
403
+ }
404
+ #os2-editor .os2editor-page p {
405
+ margin: 7px 0;
406
+ }
407
+
408
+ #os2-editor .os2editor-page ul {
409
+ margin: 0 0 15px 20px;
410
+ list-style: disc;
411
+ }
412
+
413
+ #os2-editor .os2editor-page h4 {
414
+ padding: 0 0 2px 0;
415
+ margin: 0;
416
+ border-bottom: solid 1px #dfdfdf;
417
+ }
418
+ #os2-editor .tips {
419
+ background: #ffdb6f;
420
+ padding: 3px 10px;
421
+ margin: 10px 0;
422
+ }
423
+ #os2-editor .tips p {
424
+ margin: 4px 0;
425
+ }
426
+ #os2-editor .help-header, #os2-editor .help-footer {
427
+ background: #d1dedf;
428
+ padding: 3px 10px;
429
+ margin: 0 0 10px 0;
430
+ }
431
+ #os2-editor .help-footer {
432
+ margin: 10px 0 0 0;
433
+ }
434
+ #os2-editor .help-header p, #os2-editor .help-footer p {
435
+ margin: 4px 0;
436
+ }
437
+ #os2-editor .help-header a, #os2-editor .help-footer a {
438
+ color: #444;
439
+ }
440
+ #os2-editor .os2editor-page .new {
441
+ color: #0221a9;
442
+ }
443
+ #os2-editor .table-of-contents {
444
+ margin: 15px 0;
445
+ padding: 15px;
446
+ background-color: #d1dedf;
447
+ }
448
+ #os2-editor .table-of-contents ul {
449
+ padding: 0;
450
+ margin: 0;
451
+ list-style: none;
452
+ }
453
+ #os2-editor .table-of-contents ul ul {
454
+ margin: 3px 0 5px 15px;
455
+ }
456
+ #os2-editor .table-of-contents li {
457
+ padding: 2px 0;
458
+ margin: 0;
459
+ }
460
+ #os2-editor .table-of-contents a {
461
+ color: #444;
462
+ }
463
+ #os2-editor .table-of-contents li.new a {
464
+ color: #0221a9;
465
+ font-weight: bold;
466
+ }
467
+ #os2-editor .table-of-contents a.deprecated {
468
+ color: #8f6e47;
469
+ }
js/owebia/shipping2/os2editor.js ADDED
@@ -0,0 +1,735 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * Magento Owebia Shipping2 Module
3
+ *
4
+ * NOTICE OF LICENSE
5
+ *
6
+ * This source file is subject to the Open Software License (OSL 3.0)
7
+ * that is bundled with this package in the file LICENSE.txt.
8
+ * It is also available through the world-wide-web at this URL:
9
+ * http://opensource.org/licenses/osl-3.0.php
10
+ * If you did not receive a copy of the license and are unable to
11
+ * obtain it through the world-wide-web, please send an email
12
+ * to license@magentocommerce.com so we can send you a copy immediately.
13
+ *
14
+ * @category Owebia
15
+ * @package Owebia_Shipping2
16
+ * @copyright Copyright (c) 2008-10 Owebia (http://www.owebia.com/)
17
+ * @author Antoine Lemoine
18
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
19
+ */
20
+
21
+ /**
22
+ * @constructor
23
+ */
24
+ OS2Editor = function (options) {
25
+ this.options = options;
26
+
27
+ this.jwindow = jQuery(window);
28
+ this.jeditor = null;
29
+ this.jeditor_content = null;
30
+ this.jtextarea = null;
31
+ this.jcontextualmenu = null;
32
+ this.mouse_event_owner = null;
33
+ this.dialog_v_padding = 10;
34
+ this.dialog_h_padding = 15;
35
+ this.opened = false;
36
+ this.shipping_code = null;
37
+ }
38
+
39
+ OS2Editor.prototype = {
40
+ /**
41
+ * @private
42
+ */
43
+ _init: function () {
44
+ var jeditor = this._dialog('os2-editor',"<div style=\"width:100%;height:100%;position:relative;\" id=\"os2-editor-content\"></div>");
45
+ this.jeditor = jeditor;
46
+ var jdialogbox = jeditor.find('.dialog-box');
47
+ this.jeditor_content = jeditor.find('#os2-editor-content');
48
+ this.jeditor_content.css({width: jdialogbox.innerWidth()-this.dialog_h_padding*2, height: jdialogbox.innerHeight()-this.dialog_v_padding*2, border: '0'});
49
+
50
+ var self = this;
51
+ jQuery('#os2-editor .preview-items-list > .preview-item').live('click',function (event) {
52
+ var caller = jQuery(this);
53
+ if (caller.hasClass('address-filter')) self._contextualMenu('address-filter',caller);
54
+ else if (caller.hasClass('customer-group')) self._contextualMenu('customer-group',caller);
55
+ jQuery('#os2-contextual-menu').css({position: 'absolute', 'z-index': 100, left: event.pageX-7, top: event.pageY}).show();
56
+ event.preventDefault();
57
+ event.stopPropagation();
58
+ });
59
+ jQuery('#os2-editor .property-container .field').live('blur',function (event) {
60
+ self._updateProperty(this);
61
+ event.preventDefault();
62
+ event.stopPropagation();
63
+ });
64
+ },
65
+
66
+ /**
67
+ * @private
68
+ */
69
+ _dialog: function (id, content) {
70
+ var w = this.jwindow.width();
71
+ var h = this.jwindow.height();
72
+ var margin = 50;
73
+ var v_padding = this.dialog_v_padding;
74
+ var h_padding = this.dialog_h_padding;
75
+ var width = w-2*margin;
76
+ var height = h-2*margin;
77
+ var dialog_w = Math.max(width+2*h_padding,350);
78
+ var dialog_h = Math.max(height+2*v_padding,250);
79
+ var top = (h-dialog_h)/2;
80
+ var left = (w-dialog_w)/2;
81
+ var margin_top = (dialog_h-height)/2-v_padding;
82
+ var margin_left = (dialog_w-width)/2-h_padding;
83
+ var jdialog = jQuery("<div style=\"position:fixed;top:0;left:0;width:100%;height:100%;z-index:100;\" id=\""+id+"\">"
84
+ +"<div class=\"dialog-bg\" style=\"position:fixed;top:0;left:0;z-index:100;width:100%;height:100%;background:#000;\"></div>"
85
+ +"<div class=\"dialog-box\" style=\"position:fixed;background:#fff;-moz-box-shadow: #000 0 0 10px;top:"+top+"px;left:"+left+"px;width:"+dialog_w+"px;"
86
+ +"height:"+dialog_h+"px;z-index:200;\"><div style=\"padding:"+v_padding+"px "+h_padding+"px;margin:"+margin_top+"px 0 0 "+margin_left+"px;\">"
87
+ +content+'</div></div></div>');
88
+ jdialog.find('.dialog-bg').click(function(event){
89
+ jdialog.fadeOut(function(){jdialog.hide();});
90
+ })
91
+ .css({
92
+ opacity: '0.7'
93
+ })
94
+ ;
95
+ jQuery('body').append(jdialog);
96
+ return jdialog;
97
+ },
98
+
99
+ /**
100
+ * @private
101
+ */
102
+ _contextualMenu: function (which, caller) {
103
+ var self = this;
104
+ this.mouse_event_owner = caller;
105
+
106
+ if (this.jcontextualmenu==null) {
107
+ var jcontextualmenu = jQuery('<ul id="os2-contextual-menu" style="display:none;"></ul>');
108
+ jcontextualmenu.click(function (event) {
109
+ jcontextualmenu.hide();
110
+ event.preventDefault();
111
+ event.stopPropagation();
112
+ });
113
+ jQuery('body').append(jcontextualmenu);
114
+ jQuery(document).mouseup(function (event) {
115
+ if (self.mouse_event_owner!=null && self.mouse_event_owner.hasClass('files-container')) {
116
+ self.mouse_event_owner.trigger(event);
117
+ }
118
+ jcontextualmenu.hide();
119
+ });
120
+ this.jcontextualmenu = jcontextualmenu;
121
+ }
122
+
123
+ switch (which) {
124
+ case 'address-filter':
125
+ this.jcontextualmenu.html(
126
+ "<li><span>"+caller.attr('full-value')+"</span></li>"
127
+ +(caller.hasClass('preview-item-group') ?
128
+ "<li><a id=\"ungroup-link\" href=\"#\">"+this.options.menu_item_dissociate_label+"</a></li>"
129
+ :
130
+ ''
131
+ )
132
+ +"<li><a id=\"edit-link\" href=\"#\">"+this.options.menu_item_edit_label+"</a></li>"
133
+ +"<li><a id=\"remove-link\" href=\"#\" onclick=\"\">"+this.options.menu_item_remove_label+"</a></li>"
134
+ );
135
+ jQuery('#remove-link').click(function (event) {
136
+ self._remove_click(event,caller);
137
+ });
138
+ jQuery('#edit-link').click(function (event) {
139
+ self._edit_click(event,caller,'get-address-filters');
140
+ });
141
+ jQuery('#ungroup-link').click(function (event) {
142
+ self._dissociateAddressFiltersGroup(caller,100);
143
+ event.preventDefault();
144
+ });
145
+ break;
146
+ case 'customer-group':
147
+ this.jcontextualmenu.html(
148
+ "<li><span>"+caller.attr('full-value')+"</span></li>"
149
+ +"<li><a id=\"edit-link\" href=\"#\">"+this.options.menu_item_edit_label+"</a></li>"
150
+ +"<li><a id=\"remove-link\" href=\"#\" onclick=\"\">"+this.options.menu_item_remove_label+"</a></li>"
151
+ );
152
+ jQuery('#remove-link').click(function (event) {
153
+ self._remove_click(event,caller);
154
+ });
155
+ jQuery('#edit-link').click(function (event) {
156
+ self._edit_click(event,caller,'get-customer-groups');
157
+ });
158
+ break;
159
+ }
160
+ },
161
+
162
+ /**
163
+ * @private
164
+ */
165
+ _remove_click: function (event, caller) {
166
+ var self = this;
167
+ caller.fadeOut(null,function(){
168
+ var parent = caller.parents('.property-container');
169
+ caller.remove();
170
+ self.updatePropertyFromPreview(parent);
171
+ });
172
+ event.preventDefault();
173
+ },
174
+
175
+ /**
176
+ * @private
177
+ */
178
+ _edit_click: function (event, caller, what) {
179
+ var self = this;
180
+ var new_value = prompt(this.options.prompt_new_value_label,caller.attr('original-value'));
181
+ if (new_value) {
182
+ this._ajax({
183
+ data: {
184
+ what: what,
185
+ input: new_value
186
+ },
187
+ success: function (msg) {
188
+ var parent = caller.parents('.property-container');
189
+ caller.replaceWith(msg);
190
+ self.updatePropertyFromPreview(parent);
191
+ }
192
+ });
193
+ }
194
+ event.preventDefault();
195
+ },
196
+
197
+ /**
198
+ * @private
199
+ */
200
+ _ajax: function (args) {
201
+ args.data.form_key = this.options.form_key;
202
+ jQuery.ajax({
203
+ type: 'POST',
204
+ url: this.options.ajax_url,
205
+ data: args.data,
206
+ success: args.success
207
+ });
208
+ },
209
+
210
+ /**
211
+ * @private
212
+ */
213
+ _download: function (data) {
214
+ data.form_key = this.options.form_key;
215
+ data = jQuery.param(data);
216
+ var inputs = '';
217
+ jQuery.each(data.split('&'),function(){
218
+ var tmp = this.split('=');
219
+ inputs += '<input type="hidden" name="'+tmp[0]+'" value="'+tmp[1]+'"/>';
220
+ });
221
+ jQuery('<form action="'+this.options.ajax_url+'" method="post">'+inputs+'</form>').appendTo('body').submit().remove();
222
+ },
223
+
224
+ /**
225
+ * @private
226
+ */
227
+ _checkCountries: function (parent) {
228
+ var output = '';
229
+ parent.find('.address-filter').each(function () {
230
+ var country_code = jQuery(this).attr('country-code');
231
+ output += country_code+',';
232
+ if (country_code!='') {
233
+ var tmp = parent.find('.country-'+country_code);
234
+ if (tmp.size()>1) {
235
+ tmp.addClass('warning');
236
+ } else {
237
+ tmp.removeClass('warning');
238
+ }
239
+ }
240
+ });
241
+ },
242
+
243
+ /**
244
+ * @private
245
+ */
246
+ _getConfig: function () {
247
+ var self = this;
248
+ var config = '';
249
+ this.jeditor_content.find('.row-container').each(function(){
250
+ var jrowcontainer = jQuery(this);
251
+ if (jrowcontainer.hasClass('ignored-lines')) {
252
+ config += jrowcontainer.find('.field').val()+"\n";
253
+ } else {
254
+ var comment = jrowcontainer.find('.property-container[property-name="*comment"] .field').val();
255
+ if (comment!='') {
256
+ var lines = comment.replace(/(?:\r\n|\n|\r)/,"\n").split("\n");
257
+ for (var i=0; i<lines.length; i++) {
258
+ if (lines[i].substr(0,1)!='#') lines[i] = '# '+lines[i];
259
+ else lines[i] = '#'+lines[i];
260
+ }
261
+ config += lines.join("\n")+"\n";
262
+ }
263
+ config += "{\n";
264
+ jrowcontainer.find('.property-container').each(function(){
265
+ var jpropertycontainer = jQuery(this);
266
+ var property = jpropertycontainer.attr('property-name');
267
+ if (property!='*comment') {
268
+ var value = null;
269
+ if (property=='destination' || property=='origin') {
270
+ value = self._getCompleteValue('compact-value',this,true,true);
271
+ }
272
+ else value = jpropertycontainer.find('.field').val();
273
+ var property = jpropertycontainer.attr('property-name');
274
+
275
+ switch (property) {
276
+ case 'enabled':
277
+ if (value!='1') config += "\t"+property+': false,'+"\n";
278
+ break;
279
+ default:
280
+ if (value!='') {
281
+ config += "\t"+property+': "'+value.replace(/\"/g,"\\\"")+'",'+"\n";
282
+ }
283
+ break;
284
+ }
285
+
286
+ }
287
+ });
288
+ config += "}\n";
289
+ }
290
+ });
291
+ return config;
292
+ },
293
+
294
+ /**
295
+ * @private
296
+ */
297
+ _dissociateAddressFiltersGroup: function (caller, delay) {
298
+ var self = this;
299
+ var childs = caller.children('.address-filter');
300
+ if (delay>0) {
301
+ childs.each(function (i) {
302
+ var child = jQuery(this);
303
+ child.delay(i*delay).fadeOut(null,function(){
304
+ child.insertBefore(caller);
305
+ child.fadeIn();
306
+ if (i==childs.size()-1) {
307
+ caller.fadeOut(null,function(){
308
+ caller.remove();
309
+ self.updatePropertyFromPreview(parent);
310
+ });
311
+ }
312
+ });
313
+ });
314
+ } else {
315
+ childs.insertBefore(caller);
316
+ caller.remove();
317
+ self.updatePropertyFromPreview(parent);
318
+ }
319
+ },
320
+
321
+ /**
322
+ * @private
323
+ */
324
+ _updatePropertyPreview: function (object, what) {
325
+ if (!(object instanceof jQuery)) object = jQuery(object);
326
+ if (!object.hasClass('property-container')) object = object.parents('.property-container');
327
+
328
+ var self = this;
329
+ this._ajax({
330
+ data: {
331
+ what: what,
332
+ input: object.find('textarea').val()
333
+ },
334
+ success: function (msg) {
335
+ object.find('.preview-items-list').html(msg);
336
+ }
337
+ });
338
+ },
339
+
340
+ /**
341
+ * @private
342
+ */
343
+ _updateProperty: function (object) {
344
+ if (!(object instanceof jQuery)) object = jQuery(object);
345
+
346
+ var property_container = object.parents('.property-container');
347
+ var property_name = property_container.attr('property-name');
348
+ switch (property_name) {
349
+ case 'destination':
350
+ case 'origin':
351
+ this._updatePropertyPreview(object,'get-address-filters');
352
+ break;
353
+ case 'customer_groups':
354
+ this._updatePropertyPreview(object,'get-customer-groups');
355
+ break;
356
+ case 'label':
357
+ this._updateRowTitle(object,property_container);
358
+ break;
359
+ }
360
+ this._ajax({
361
+ data: {
362
+ what: 'check-config',
363
+ config: this._getConfig(),
364
+ },
365
+ success: function (msg) {
366
+ jQuery('body').append(msg);
367
+ }
368
+ });
369
+ var id = object.attr('id')+'-item';
370
+ if (object.val().trim()=='') jQuery('#'+id).addClass('empty');
371
+ else jQuery('#'+id).removeClass('empty');
372
+ },
373
+
374
+ /**
375
+ * @private
376
+ */
377
+ _updateRowTitle: function (jtextarea) {
378
+ var title = jtextarea.val().trim();
379
+ if (title=='') title = this.options.default_row_label;
380
+ jtextarea.parents('.row-container').find('.row-title').html(title);
381
+ },
382
+
383
+ /**
384
+ * @private
385
+ */
386
+ _updateRowsUI: function () {
387
+ var jrows = this.jeditor.find('.row-container');
388
+ if (jrows.filter('.selected').size()==0) {
389
+ jrows.eq(0).addClass('selected');
390
+ }
391
+ if (jrows.size()<=1) {
392
+ jrows.find('.row-actions .delete').hide();
393
+ } else {
394
+ jrows.find('.row-actions .delete').show();
395
+ }
396
+ },
397
+
398
+ /**
399
+ * @private
400
+ */
401
+ /*_linearizeAddressFilters: function (object) {
402
+ if (!(object instanceof jQuery)) object = jQuery(object);
403
+ if (!object.hasClass('property-container')) object = object.parents('.property-container');
404
+
405
+ var self = this;
406
+ object.find('.address-filter-list .address-filter-group').each(function () {
407
+ self._dissociateAddressFiltersGroup(jQuery(this),0);
408
+ });
409
+ },*/
410
+
411
+ /**
412
+ * @public
413
+ */
414
+ insertAtCaret: function (object, text_to_insert) {
415
+ if (!(object instanceof jQuery)) {
416
+ object = jQuery(object);
417
+ if (object[0].nodeName!='textarea') object = object.parents('.property-container');
418
+ }
419
+ if (object.hasClass('property-container')) object = object.find('textarea');
420
+
421
+ object.each(function (i) {
422
+ if (document.selection) {
423
+ this.focus();
424
+ var sel = document.selection.createRange();
425
+ sel.text = text_to_insert;
426
+ this.focus();
427
+ } else if (this.selectionStart || this.selectionStart=='0') {
428
+ var start_index = this.selectionStart;
429
+ var end_index = this.selectionEnd;
430
+ var scroll_top = this.scrollTop;
431
+ this.value = this.value.substring(0,start_index)+text_to_insert+this.value.substring(end_index,this.value.length);
432
+ this.focus();
433
+ this.selectionStart = start_index + text_to_insert.length;
434
+ this.selectionEnd = start_index + text_to_insert.length;
435
+ this.scrollTop = scroll_top;
436
+ } else {
437
+ this.value += text_to_insert;
438
+ this.focus();
439
+ }
440
+ });
441
+ },
442
+
443
+ /**
444
+ * @public
445
+ */
446
+ updatePropertyFromPreview: function (object) {
447
+ if (!(object instanceof jQuery)) object = jQuery(object);
448
+ if (!object.hasClass('property-container')) object = object.parents('.property-container');
449
+
450
+ var list = object.find('.address-filter-list');
451
+ var displayed_field = list.attr('displayed-field');
452
+ if (displayed_field==null) displayed_field = 'original-value';
453
+ var compact = list.attr('compact');
454
+ if (compact==null) compact = false;
455
+ else compact = compact=='1';
456
+ this.updatePropertyValue(displayed_field,object,compact);
457
+ },
458
+
459
+ /**
460
+ * @private
461
+ */
462
+ _getCompleteValue: function (field, object, compact, linearize_groups) {
463
+ if (!(object instanceof jQuery)) object = jQuery(object);
464
+ if (!object.hasClass('property-container')) object = object.parents('.property-container');
465
+
466
+ var values = [];
467
+ object.find('.preview-items-list').attr('displayed-field',field).attr('compact',compact?'1':'0');
468
+
469
+ if (linearize_groups) {
470
+ object.find('.preview-items-list .preview-item').each(function () {
471
+ var jitem = jQuery(this);
472
+ if (!jitem.hasClass('preview-item-group')) values.push(jitem.attr(field));
473
+ });
474
+ } else {
475
+ object.find('.preview-items-list > .preview-item').each(function () {
476
+ values.push(jQuery(this).attr(field));
477
+ });
478
+ }
479
+ var excluding = object.find('.excluding:checked').val()=='1';
480
+ return (excluding ? '* - (' : '')+values.join(','+(compact ? '' : ' '))+(excluding ? ')' : '');
481
+ },
482
+
483
+ /**
484
+ * @public
485
+ */
486
+ updatePropertyValue: function (field, object, compact) {
487
+ if (!(object instanceof jQuery)) object = jQuery(object);
488
+ if (!object.hasClass('property-container')) object = object.parents('.property-container');
489
+
490
+ object.find('.field').val(this._getCompleteValue(field,object,compact,false));
491
+ var property_name = object.attr('property-name');
492
+ if (property_name=='destination' || property_name=='origin') {
493
+ this._checkCountries(object);
494
+ }
495
+ },
496
+
497
+ /**
498
+ * @public
499
+ */
500
+ selectProperty: function (code, property) {
501
+ jQuery('#r-'+code+'-container .property-item, #r-'+code+'-container .property-container').removeClass('selected');
502
+ jQuery('#r-'+code+'-p-'+property+'-item, #r-'+code+'-p-'+property+'-container').addClass('selected');
503
+ },
504
+
505
+ /**
506
+ * @public
507
+ */
508
+ selectRow: function (code) {
509
+ jQuery('#os2-editor .row-container').removeClass('selected');
510
+ jQuery('#r-'+code+'-container').addClass('selected');
511
+ },
512
+
513
+ /**
514
+ * @public
515
+ */
516
+ resetErrors: function (code, property, error) {
517
+ this.jeditor.find('.has-error').not('.ignored-lines').removeClass('has-error');
518
+ this.jeditor.find('div.error').remove();
519
+ },
520
+
521
+ /**
522
+ * @public
523
+ */
524
+ setError: function (code, property, error) {
525
+ if (property=='') {
526
+ jQuery('#r-'+code+'-container .row-header').append("<div class=\"error\">"+error+"</div>");
527
+ } else {
528
+ jQuery('#r-'+code+'-container').addClass('has-error');
529
+ jQuery('#r-'+code+'-p-'+property+'-item').addClass('has-error');
530
+ jQuery('#r-'+code+'-p-'+property+'-container').prepend("<div class=\"error\">"+error+"</div>");
531
+ }
532
+ },
533
+
534
+ /**
535
+ * @public
536
+ */
537
+ correct: function (code, property, value) {
538
+ var jfield = jQuery('#r-'+code+'-p-'+property);
539
+ jfield.val(value);
540
+ this._updateProperty(jfield);
541
+ },
542
+
543
+ /**
544
+ * @public
545
+ */
546
+ removeRow: function (object) {
547
+ var self = this;
548
+ var jrow = jQuery(object).parents('.row-container');
549
+ jrow.fadeOut(null,function(){
550
+ jrow.remove();
551
+ self._updateRowsUI();
552
+ });
553
+ },
554
+
555
+ /**
556
+ * @public
557
+ */
558
+ addRow: function () {
559
+ var self = this;
560
+ this._ajax({
561
+ data: {
562
+ what: 'add-row'
563
+ },
564
+ success: function (msg) {
565
+ var jcontainer = self.jeditor.find('.config-container');
566
+ jcontainer.find('.row-container.selected').removeClass('selected');
567
+ jcontainer.append(msg);
568
+ self._updateRowsUI();
569
+ }
570
+ });
571
+ },
572
+
573
+ /**
574
+ * @public
575
+ */
576
+ saveToFile: function () {
577
+ this._download({
578
+ what: 'save-to-file',
579
+ config: this._getConfig(),
580
+ });
581
+ },
582
+
583
+ /**
584
+ * @public
585
+ */
586
+ save: function () {
587
+ var self = this;
588
+ this._ajax({
589
+ data: {
590
+ what: 'save-config',
591
+ config: this._getConfig(),
592
+ shipping_code: this.shipping_code
593
+ },
594
+ success: function (msg) {
595
+ self.jtextarea.val(msg);
596
+ self.close();
597
+ }
598
+ });
599
+ /*
600
+ this.jtextarea.val(this._getConfig());
601
+ this.close();
602
+ */
603
+ },
604
+
605
+ /**
606
+ * @public
607
+ */
608
+ applyChanges: function () {
609
+ this.loadConfig(this._getConfig());
610
+ },
611
+
612
+ /**
613
+ * @public
614
+ */
615
+ loadConfig: function (config) {
616
+ if (typeof config=='undefined') {
617
+ config = jQuery('#os2-editor-config-loader textarea').val()
618
+ }
619
+ var self = this;
620
+ this._ajax({
621
+ data: {
622
+ what: 'load-config',
623
+ config: config
624
+ },
625
+ success: function (msg) {
626
+ jQuery('#os2-editor-config-container').html(msg);
627
+ self.jeditor.find('.address-filter-list').each(function(){
628
+ self._checkCountries(jQuery(this));
629
+ });
630
+ self._updateRowsUI();
631
+ jQuery('#os2-editor-config-loader').slideUp().find('textarea').val('');
632
+ }
633
+ });
634
+ },
635
+
636
+ /**
637
+ * @public
638
+ */
639
+ showConfigLoader: function () {
640
+ jQuery('#os2-editor-config-loader').slideDown();
641
+ },
642
+
643
+ /**
644
+ * @public
645
+ */
646
+ hideConfigLoader: function () {
647
+ jQuery('#os2-editor-config-loader').slideUp().find('textarea').val('');
648
+ },
649
+
650
+ /**
651
+ * @public
652
+ */
653
+ open: function (object, shipping_code, callback) {
654
+ this.shipping_code = shipping_code;
655
+ this.opened = true;
656
+ if (this.jeditor==null) this._init();
657
+
658
+ var jcell = jQuery(object).parents('td.value');
659
+ this.jtextarea = jcell.find('textarea');
660
+
661
+ this.jeditor_content.html('<div class=\"loading rule-param-wait\">'+this.options.loading_label+'</div>');
662
+ this.jeditor.fadeIn();
663
+
664
+ var self = this;
665
+ this._ajax({
666
+ data: {
667
+ what: 'open',
668
+ input: this.jtextarea.val()
669
+ },
670
+ success: function (msg) {
671
+ self.jeditor_content.html(msg);
672
+ var jconfig_container = self.jeditor.find('#os2-editor-config-container');
673
+ var height = self.jeditor_content.height() - jconfig_container.position().top - self.jeditor.find('.donate-container').height() - 15;
674
+ jconfig_container.css({
675
+ overflow: 'auto',
676
+ height: height
677
+ });
678
+ self._updateRowsUI();
679
+ if (typeof callback!='undefined') callback();
680
+ }
681
+ });
682
+ },
683
+
684
+ /**
685
+ * @public
686
+ */
687
+ close: function () {
688
+ this.opened = false;
689
+ this.jeditor.fadeOut();
690
+ },
691
+
692
+ /**
693
+ * @public
694
+ */
695
+ openPage: function (page) {
696
+ jQuery('#os2editor-'+page+'-page').fadeIn();
697
+ },
698
+
699
+ /**
700
+ * @public
701
+ */
702
+ closePage: function (object) {
703
+ jQuery(object).parents('.os2editor-page').fadeOut();
704
+ },
705
+
706
+ /**
707
+ * @public
708
+ */
709
+ help: function (help_section, object, shipping_code) {
710
+ var self = this;
711
+ if (!this.opened) {
712
+ this.open(object,shipping_code,function(){self.help(help_section);});
713
+ return;
714
+ }
715
+ this._ajax({
716
+ data: {
717
+ what: 'help',
718
+ input: help_section
719
+ },
720
+ success: function (msg) {
721
+ var jhelp_page = jQuery('#os2editor-help-page');
722
+ var jpage_content = jhelp_page.find('.page-content');
723
+ var height = jhelp_page.height() - jpage_content.position().top - 15;
724
+ jpage_content.css({
725
+ overflow: 'auto',
726
+ height: height
727
+ });
728
+ jpage_content.html(msg);
729
+ }
730
+ });
731
+ jQuery('#os2editor-help-page .page-content').html('<div class=\"loading rule-param-wait\">'+this.options.loading_label+'</div>');
732
+ this.openPage('help');
733
+ }
734
+ }
735
+
package.xml ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <package>
3
+ <name>Owebia_Shipping_2</name>
4
+ <version>2.4.0</version>
5
+ <stability>stable</stability>
6
+ <license uri="http://www.opensource.org/licenses/osl-3.0.php">Open Software License (OSL 3.0)</license>
7
+ <channel>community</channel>
8
+ <extends/>
9
+ <summary>Shipping Methods / Modes de livraison : Colissimo, Chronopost, Export 3J</summary>
10
+ <description>[EN] This module provides 3 shipping modes configurable with a very flexible syntax. The first method of delivery allows by default the management of Colissimo, Chronopost and Export 3J.
11
+
12
+ [FR] Ce module met &#xE0; disposition 3 modes de livraison configurables avec une syntaxe tr&#xE8;s souple. Le premier mode de livraison permet par d&#xE9;faut la gestion des modes de livraison Colissimo, Chronopost et Export 3J.</description>
13
+ <notes>[2.4.0 - 27 juin 2011]
14
+ Correction d'un bug lorsque plusieurs produits identiques avec des options diff&#xE9;rentes sont pr&#xE9;sents dans le panier (la valeur de l'option &#xE9;tait toujours &#xE9;gale &#xE0; celle du premier produit)
15
+ Ajout de la possibilit&#xE9; d'utiliser les expressions r&#xE9;guli&#xE8;res dans les champs "destination" et "origin"
16
+ Ajout de la variable {car.weight.for-charge}
17
+ Mise &#xE0; jour de la documentation en fran&#xE7;ais
18
+ Mise &#xE0; jour de l'&#xE9;diteur
19
+ Correction d'un bug de l'&#xE9;diteur lorsqu'on &#xE9;ditait une destination puis qu'on cliquait sur Annuler</notes>
20
+ <authors><author><name>owebia</name><user>auto-converted</user><email>antoine.lemoine@owebia.com</email></author></authors>
21
+ <date>2011-06-27</date>
22
+ <time>14:59:41</time>
23
+ <contents><target name="magelocale"><dir name="en_US"><file name="Owebia_Shipping2.csv" hash="4267e8feae738a7e06d06eed97d414fc"/></dir><dir name="fr_FR"><file name="Owebia_Shipping2.csv" hash="1a542f4ec3253e6ab8f2f2949da683b6"/></dir></target><target name="mage"><dir name="js"><dir name="owebia"><dir name="shipping2"><file name="os2editor.css" hash="1c1b01fcf4971a50e730ad0588c0eb5b"/><file name="os2editor.js" hash="83f8726e9d8dc2edf8f9f00bb29d9045"/></dir></dir></dir></target><target name="mageetc"><dir name="modules"><file name="Owebia_Shipping2.xml" hash="586171bce13c5fb46298a7033f62bab6"/><file name="Owebia_Shipping_2.xml" hash="2f84a53934b37c860e25bc0c6217467f"/></dir></target><target name="magecommunity"><dir name="Owebia"><dir name="Shipping2"><dir name="Block"><dir name="Adminhtml"><dir name="System"><dir name="Config"><dir name="Form"><dir name="Field"><file name="Config.php" hash="b121bfb0d699d50440762146b135b319"/></dir></dir></dir></dir></dir></dir><dir name="Controller"><file name="Abstract.php" hash="c2cbd0a032ca5665b31e0cfcdc1638ec"/></dir><dir name="controllers"><dir name="Checkout"><file name="CartController.php" hash="ef72b286e9adda29f1dfd68ad0fa42ec"/></dir><file name="AjaxController.php" hash="9855dc8c9950cbe1b5af1662a8f7d096"/></dir><dir name="etc"><file name="adminhtml.xml" hash="2a52eee2531db2e285716c9523c7cbf6"/><file name="config.xml" hash="64dcbdf449fe9592c16707172808e8cb"/><file name="system.xml" hash="c09780f68357ca1caf28b51fda4772eb"/></dir><dir name="includes"><dir name="cache"><file name="countries" hash="6b1a5494b6dddcc65f2946dbf0226c29"/></dir><file name="OS2_AddressFilter.php" hash="659c7155951b8415a963dfb778c782e5"/><file name="OS2_CustomerGroup.php" hash="c3aaf48316869ce51491c7e3af73f565"/><file name="OwebiaShippingHelper.php" hash="886cdc3ddefd661c223720e57797900c"/></dir><dir name="Model"><dir name="Carrier"><file name="AbstractOwebiaShipping.php" hash="89153068a0b94f21ea9d0a2e63787f63"/><file name="OwebiaShipping1.php" hash="e74757493b646425af9342b43997ff4e"/><file name="OwebiaShipping2.php" hash="cd9b8722ae65702f14435518f2c31af8"/><file name="OwebiaShipping3.php" hash="89d069078172aacc5b298e0bf68e575b"/></dir></dir><file name="changelog" hash="cee32cd6088245f075bf842e56e766d2"/></dir></dir></target></contents>
24
+ <compatible/>
25
+ <dependencies/>
26
+ </package>