Chronopost_Chronorelais - Version 0.1.4

Version Notes

New shipping module

Download this release

Release Info

Developer Magento Core Team
Extension Chronopost_Chronorelais
Version 0.1.4
Comparing to
See all releases


Version 0.1.4

Files changed (65) hide show
  1. app/code/community/Chronopost/Chronorelais/Block/Adminhtml/System/Config/Form/Field/Config.php +43 -0
  2. app/code/community/Chronopost/Chronorelais/Block/Checkout/Onepage/Shipping/Method/Chronorelais.php +54 -0
  3. app/code/community/Chronopost/Chronorelais/Block/Detail.php +29 -0
  4. app/code/community/Chronopost/Chronorelais/Block/Export/Orders.php +21 -0
  5. app/code/community/Chronopost/Chronorelais/Block/Export/Orders/Grid.php +236 -0
  6. app/code/community/Chronopost/Chronorelais/Block/Filter.php +53 -0
  7. app/code/community/Chronopost/Chronorelais/Block/Import/Form.php +11 -0
  8. app/code/community/Chronopost/Chronorelais/Block/Sales/Impression.php +16 -0
  9. app/code/community/Chronopost/Chronorelais/Block/Sales/Order/Shipment/View.php +99 -0
  10. app/code/community/Chronopost/Chronorelais/Block/Sales/Shipment/Copy of Grid.php +139 -0
  11. app/code/community/Chronopost/Chronorelais/Block/Sales/Shipment/Grid-bkp-03-02-11.php +143 -0
  12. app/code/community/Chronopost/Chronorelais/Block/Sales/Shipment/Grid.php +185 -0
  13. app/code/community/Chronopost/Chronorelais/Controller/Abstract.php +126 -0
  14. app/code/community/Chronopost/Chronorelais/Helper/Data.php +177 -0
  15. app/code/community/Chronopost/Chronorelais/Model/Carrier/AbstractChronorelais.php +32 -0
  16. app/code/community/Chronopost/Chronorelais/Model/Carrier/AbstractChronorelaisShipping.php +468 -0
  17. app/code/community/Chronopost/Chronorelais/Model/Carrier/Chronoexpress.php +6 -0
  18. app/code/community/Chronopost/Chronorelais/Model/Carrier/Chronopost.php +6 -0
  19. app/code/community/Chronopost/Chronorelais/Model/Carrier/Chronorelais.php +6 -0
  20. app/code/community/Chronopost/Chronorelais/Model/Config/Source/Civility.php +12 -0
  21. app/code/community/Chronopost/Chronorelais/Model/Config/Source/EndOfLineCharacter.php +12 -0
  22. app/code/community/Chronopost/Chronorelais/Model/Config/Source/FieldDelimiter.php +12 -0
  23. app/code/community/Chronopost/Chronorelais/Model/Config/Source/FieldSeparator.php +11 -0
  24. app/code/community/Chronopost/Chronorelais/Model/Config/Source/FileCharset.php +12 -0
  25. app/code/community/Chronopost/Chronorelais/Model/Config/Source/FileExtension.php +12 -0
  26. app/code/community/Chronopost/Chronorelais/Model/Config/Source/PrintMode.php +12 -0
  27. app/code/community/Chronopost/Chronorelais/Model/Sales/Quote/Address/Total/Shipping.php +207 -0
  28. app/code/community/Chronopost/Chronorelais/controllers/AjaxController.php +409 -0
  29. app/code/community/Chronopost/Chronorelais/controllers/Checkout/OnepageController.php +657 -0
  30. app/code/community/Chronopost/Chronorelais/controllers/ExportController.php +446 -0
  31. app/code/community/Chronopost/Chronorelais/controllers/ImportController.php +249 -0
  32. app/code/community/Chronopost/Chronorelais/controllers/RelaisController.php +32 -0
  33. app/code/community/Chronopost/Chronorelais/controllers/Sales/ImpressionController.php +556 -0
  34. app/code/community/Chronopost/Chronorelais/controllers/Sales/Order/ShipmentController.php +268 -0
  35. app/code/community/Chronopost/Chronorelais/etc/config.xml +340 -0
  36. app/code/community/Chronopost/Chronorelais/etc/system.xml +965 -0
  37. app/code/community/Chronopost/Chronorelais/includes/ChronorelaisShippingHelper.php +1245 -0
  38. app/code/community/Chronopost/Chronorelais/includes/countries.inc.php +523 -0
  39. app/code/community/Chronopost/Chronorelais/sql/chronorelais_setup/mysql4-install-0.1.0.php +15 -0
  40. app/code/community/Chronopost/Chronorelais/sql/chronorelais_setup/mysql4-upgrade-0.1.0-0.1.1.php +8 -0
  41. app/code/community/Chronopost/Chronorelais/sql/chronorelais_setup/mysql4-upgrade-0.1.1-0.1.2.php +8 -0
  42. app/code/community/Chronopost/Chronorelais/sql/chronorelais_setup/mysql4-upgrade-0.1.2-0.1.3.php +8 -0
  43. app/code/community/Chronopost/Chronorelais/sql/chronorelais_setup/mysql4-upgrade-0.1.3-0.1.4.php +14 -0
  44. app/design/adminhtml/default/default/template/chronorelais/import/form.phtml +65 -0
  45. app/design/frontend/default/default/layout/chronorelais.xml +44 -0
  46. app/design/frontend/default/default/template/chronorelais/checkout/onepage/shipping_method.phtml +93 -0
  47. app/design/frontend/default/default/template/chronorelais/checkout/onepage/shipping_method/available.phtml +94 -0
  48. app/design/frontend/default/default/template/chronorelais/checkout/onepage/shipping_method/chronorelais.phtml +29 -0
  49. app/design/frontend/default/default/template/chronorelais/sales/order/history.phtml +79 -0
  50. app/design/frontend/default/default/template/chronorelais/sales/order/recent.phtml +78 -0
  51. app/etc/modules/WSChronopost_Chronorelais.xml +31 -0
  52. app/locale/en_US/Chronopost_Chronorelais.csv +1034 -0
  53. app/locale/fr_FR/Chronopost_Chronorelais.csv +1034 -0
  54. js/chronopost/chronorelais/ocseditor.css +465 -0
  55. js/chronopost/chronorelais/ocseditor.js +674 -0
  56. package.xml +20 -0
  57. skin/frontend/default/default/chronorelais/Picto_Chrono_Relais.png +0 -0
  58. skin/frontend/default/default/chronorelais/Thumbs.db +0 -0
  59. skin/frontend/default/default/chronorelais/ac.png +0 -0
  60. skin/frontend/default/default/chronorelais/chronopost.png +0 -0
  61. skin/frontend/default/default/chronorelais/chronorelais.css +46 -0
  62. skin/frontend/default/default/chronorelais/chronorelais.png +0 -0
  63. skin/frontend/default/default/chronorelais/chronorelaismap.js +463 -0
  64. skin/frontend/default/default/chronorelais/home.png +0 -0
  65. skin/frontend/default/default/chronorelais/ico_ac_shaded.gif +0 -0
app/code/community/Chronopost/Chronorelais/Block/Adminhtml/System/Config/Form/Field/Config.php ADDED
@@ -0,0 +1,43 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Chronopost_Chronorelais_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
+ {
13
+ $output = '';
14
+ if (!self::$JS_INCLUDED) {
15
+ $include_path = Mage::getBaseUrl('js').'chronopost/chronorelais';
16
+ $output = "<script type=\"text/javascript\" src=\"http://ajax.googleapis.com/ajax/libs/jquery/1.4.3/jquery.min.js\"></script>\n"
17
+ ."<script type=\"text/javascript\" src=\"".$include_path."/ocseditor.js?t=".time()."\"></script>\n"
18
+ ."<script type=\"text/javascript\">\n"
19
+ ."//<![CDATA[\n"
20
+ ."jQuery.noConflict();\n"
21
+ ."var ocseditor = new OCSEditor({\n"
22
+ ."ajax_url: '".$this->getUrl('chronorelais/ajax')."?isAjax=true',\n"
23
+ ."form_key: FORM_KEY,\n"
24
+ ."menu_item_dissociate_label: '".$this->label('Dissociate')."',\n"
25
+ ."menu_item_remove_label: '".$this->label('Remove')."',\n"
26
+ ."menu_item_edit_label: '".$this->label('Edit')."',\n"
27
+ ."prompt_new_value_label: '".$this->label('Enter the new value:')."',\n"
28
+ ."default_row_label: '".$this->label('[No label]')."',\n"
29
+ ."loading_label: '".$this->label('Loading...')."'\n"
30
+ ."});\n"
31
+ ."//]]>\n"
32
+ ."</script>\n"
33
+ ."<link type=\"text/css\" href=\"".$include_path."/ocseditor.css?t=".time()."\" rel=\"stylesheet\" media=\"all\"/>\n"
34
+ ;
35
+ self::$JS_INCLUDED = true;
36
+ }
37
+
38
+ return $output
39
+ .'<div style="margin-bottom:1px;"><button type="button" class="scalable" onclick="ocseditor.open(this);"><span>'.$this->__("Open editor").'</span></button></div>'
40
+ .$element->getElementHtml().'<br/>'
41
+ ;
42
+ }
43
+ }
app/code/community/Chronopost/Chronorelais/Block/Checkout/Onepage/Shipping/Method/Chronorelais.php ADDED
@@ -0,0 +1,54 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Magento
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Open Software License (OSL 3.0)
8
+ * that is bundled with this package in the file LICENSE.txt.
9
+ * It is also available through the world-wide-web at this URL:
10
+ * http://opensource.org/licenses/osl-3.0.php
11
+ * If you did not receive a copy of the license and are unable to
12
+ * obtain it through the world-wide-web, please send an email
13
+ * to license@magentocommerce.com so we can send you a copy immediately.
14
+ *
15
+ * DISCLAIMER
16
+ *
17
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
18
+ * versions in the future. If you wish to customize Magento for your
19
+ * needs please refer to http://www.magentocommerce.com for more information.
20
+ *
21
+ * @category Mage
22
+ * @package Mage_Checkout
23
+ * @copyright Copyright (c) 2010 Magento Inc. (http://www.magentocommerce.com)
24
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
25
+ */
26
+
27
+ /**
28
+ * One page checkout status
29
+ *
30
+ * @category Mage
31
+ * @category Mage
32
+ * @package Mage_Checkout
33
+ * @author Magento Core Team <core@magentocommerce.com>
34
+ */
35
+ class Chronopost_Chronorelais_Block_Checkout_Onepage_Shipping_Method_Chronorelais extends Mage_Checkout_Block_Onepage_Abstract
36
+ {
37
+ protected $_chronorelais;
38
+
39
+ public function getChronorelais()
40
+ {
41
+ if (empty($this->_chronorelais)) {
42
+ $quote = Mage::getSingleton('checkout/cart')->init()->getQuote();
43
+ $address = $quote->getShippingAddress();
44
+ $postcode = $address->getPostcode();
45
+
46
+ $client = new SoapClient("http://wsshipping.chronopost.fr/soap.point.relais/services/ServiceRechercheBt?wsdl",array('trace'=> 0,'connection_timeout'=>10));
47
+ $webservbt = $client->__call("rechercheBtParCodeproduitEtCodepostalEtDate",array(0,$postcode,0));
48
+ $this->_chronorelais = $webservbt;
49
+ }
50
+
51
+ return $this->_chronorelais;
52
+ }
53
+
54
+ }
app/code/community/Chronopost/Chronorelais/Block/Detail.php ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class Chronopost_Chronorelais_Block_Detail extends Mage_Core_Block_Template
3
+ {
4
+
5
+ public function _prepareLayout()
6
+ {
7
+ return parent::_prepareLayout();
8
+ }
9
+
10
+ public function getRelaisPoint(){
11
+
12
+
13
+ $btcode = $this->getRequest()->getParam ( 'btcode' );
14
+
15
+ if($btcode){
16
+ $result = Mage::getModel('shipping/rate_result');
17
+ ini_set("soap.wsdl_cache_enabled", "0");
18
+ $client = new SoapClient("http://wsshipping.chronopost.fr/soap.point.relais/services/ServiceRechercheBt?wsdl");
19
+ $webservbt = $client->__call("rechercheBtParIdChronopostA2Pas",array($btcode));
20
+
21
+ return $webservbt[0];
22
+ }
23
+ else{
24
+ return false;
25
+ }
26
+ }
27
+
28
+ }
29
+ ?>
app/code/community/Chronopost/Chronorelais/Block/Export/Orders.php ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Chronopost Chronorelais module
4
+ *
5
+ * @category Chronopost
6
+ * @package Chronopost_Chronorelais
7
+ * @license http://www.opensource.org/licenses/gpl-3.0.html GNU General Public License version 3
8
+ */
9
+ class Chronopost_Chronorelais_Block_Export_Orders extends Mage_Adminhtml_Block_Widget_Grid_Container
10
+ {
11
+
12
+ public function __construct()
13
+ {
14
+ $this->_blockGroup = 'chronorelais';
15
+ $this->_controller = 'export_orders';
16
+ $this->_headerText = Mage::helper('chronorelais')->__('Exporter vers ChronoShip Office ou ChronoShip Station');
17
+ parent::__construct();
18
+ $this->_removeButton('add');
19
+ }
20
+
21
+ }
app/code/community/Chronopost/Chronorelais/Block/Export/Orders/Grid.php ADDED
@@ -0,0 +1,236 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class Chronopost_Chronorelais_Block_Export_Orders_Grid extends Mage_Adminhtml_Block_Widget_Grid
3
+ {
4
+
5
+ public function __construct()
6
+ {
7
+ parent::__construct();
8
+ $this->setId('chronorelais_export_order_grid');
9
+ $this->setDefaultSort('created_at');
10
+ $this->setDefaultDir('DESC');
11
+ $this->setSaveParametersInSession(true);
12
+ }
13
+
14
+ /**
15
+ * Retrieve collection class
16
+ *
17
+ * @return string
18
+ */
19
+ protected function _getCollectionClass()
20
+ {
21
+ return 'sales/order_grid_collection';
22
+ }
23
+
24
+ protected function _prepareCollection()
25
+ {
26
+ $_chronopost_deliver_saturday = Mage::helper('chronorelais')->getConfigData('carriers/chronopost/deliver_on_saturday');
27
+ $_chronorelais_deliver_saturday = Mage::helper('chronorelais')->getConfigData('carriers/chronorelais/deliver_on_saturday');
28
+ if($_chronopost_deliver_saturday==1) { $_chronopost_deliver_saturday = 'Yes'; } else { $_chronopost_deliver_saturday = 'No';}
29
+ if($_chronorelais_deliver_saturday==1) { $_chronorelais_deliver_saturday = 'Yes'; } else { $_chronorelais_deliver_saturday = 'No'; }
30
+
31
+ $collection = Mage::getResourceModel($this->_getCollectionClass());
32
+ $collection->join('order', 'main_table.entity_id = order.entity_id', 'shipping_description');
33
+ $collection->join('order_payment', 'main_table.entity_id = order_payment.parent_id', 'method');
34
+ $collection->getSelect()->joinLeft(array('oes' => Mage::getSingleton('core/resource')->getTableName('sales_chronopost_order_export_status')), 'main_table.entity_id = oes.order_id', array("if(isNull(oes.livraison_le_samedi), CASE LOWER(SUBSTRING_INDEX(order.shipping_method,'_','1')) WHEN 'chronopost' THEN '$_chronopost_deliver_saturday' WHEN 'chronorelais' THEN '$_chronorelais_deliver_saturday' WHEN 'chronoexpress' THEN '--' ELSE 'No' END, oes.livraison_le_samedi) as livraison_le_samedi"));
35
+ $collection->getSelect()->where('order.shipping_method LIKE "chronorelais%" OR order.shipping_method LIKE "chronopost%" OR order.shipping_method LIKE "chronoexpress%"');
36
+
37
+ $this->setCollection($collection);
38
+ return parent::_prepareCollection();
39
+ }
40
+
41
+ protected function _prepareColumns()
42
+ {
43
+
44
+ $this->addColumn('real_order_id', array(
45
+ 'header'=> Mage::helper('sales')->__('Order #'),
46
+ 'width' => '80px',
47
+ 'type' => 'text',
48
+ 'index' => 'increment_id',
49
+ 'filter' => false,
50
+ ));
51
+
52
+ if (!Mage::app()->isSingleStoreMode()) {
53
+ $this->addColumn('store_id', array(
54
+ 'header' => Mage::helper('sales')->__('Purchased From (Store)'),
55
+ 'index' => 'store_id',
56
+ 'type' => 'store',
57
+ 'store_view'=> true,
58
+ 'display_deleted' => true,
59
+ 'filter' => false,
60
+ ));
61
+ }
62
+
63
+ $this->addColumn('created_at', array(
64
+ 'header' => Mage::helper('sales')->__('Purchased On'),
65
+ 'index' => 'created_at',
66
+ 'type' => 'datetime',
67
+ 'width' => '100px',
68
+ 'filter' => false,
69
+ ));
70
+
71
+ $this->addColumn('billing_name', array(
72
+ 'header' => Mage::helper('sales')->__('Bill to Name'),
73
+ 'index' => 'billing_name',
74
+ 'filter' => false,
75
+ ));
76
+
77
+ $this->addColumn('shipping_name', array(
78
+ 'header' => Mage::helper('sales')->__('Ship to Name'),
79
+ 'index' => 'shipping_name',
80
+ 'filter' => false,
81
+ ));
82
+
83
+ $this->addColumn('base_grand_total', array(
84
+ 'header' => Mage::helper('sales')->__('G.T. (Base)'),
85
+ 'index' => 'base_grand_total',
86
+ 'type' => 'currency',
87
+ 'currency' => 'base_currency_code',
88
+ 'filter' => false,
89
+ ));
90
+
91
+ $this->addColumn('grand_total', array(
92
+ 'header' => Mage::helper('sales')->__('G.T. (Purchased)'),
93
+ 'index' => 'grand_total',
94
+ 'type' => 'currency',
95
+ 'currency' => 'order_currency_code',
96
+ 'filter' => false,
97
+ ));
98
+
99
+ $this->addColumn('shipping_description', array(
100
+ 'header'=> Mage::helper('sales')->__('Shipping Method'),
101
+ 'width' => '80px',
102
+ 'type' => 'text',
103
+ 'index' => 'shipping_description',
104
+ 'filter' => false,
105
+ 'truncate' => 30,
106
+ 'escape' => true,
107
+ ));
108
+
109
+ $this->addColumn('payment', array(
110
+ 'header' => Mage::helper('sales')->__('Mode de Paiement'),
111
+ 'index' => 'method',
112
+ 'width' => '100px',
113
+ 'type' => 'text',
114
+ 'filter' => false,
115
+ ));
116
+
117
+ if($is_sending_day = Mage::helper('chronorelais')->isSendingDay()) {
118
+ $this->addColumn('livraison_le_samedi', array(
119
+ 'header' => Mage::helper('sales')->__('Livraison le Samedi'),
120
+ 'index' => 'livraison_le_samedi',
121
+ 'width' => '100px',
122
+ 'class' => 'a-center',
123
+ 'filter' => false,
124
+ ));
125
+ }
126
+
127
+ $this->addColumn('main_table.status', array(
128
+ 'header' => Mage::helper('sales')->__('Status'),
129
+ 'index' => 'status',
130
+ 'type' => 'options',
131
+ 'width' => '70px',
132
+ 'options' => Mage::getSingleton('sales/order_config')->getStatuses(),
133
+ ));
134
+
135
+ if (Mage::getSingleton('admin/session')->isAllowed('sales/order/actions/view')) {
136
+ $this->addColumn('action',
137
+ array(
138
+ 'header' => Mage::helper('sales')->__('Action'),
139
+ 'width' => '50px',
140
+ 'type' => 'action',
141
+ 'getter' => 'getId',
142
+ 'actions' => array(
143
+ array(
144
+ 'caption' => Mage::helper('sales')->__('View'),
145
+ 'url' => array('base'=>'adminhtml/sales_order/view'),
146
+ 'field' => 'order_id'
147
+ )
148
+ ),
149
+ 'filter' => false,
150
+ 'sortable' => false,
151
+ 'index' => 'stores',
152
+ 'is_system' => true,
153
+ ));
154
+ }
155
+
156
+ return parent::_prepareColumns();
157
+ }
158
+
159
+ protected function _prepareMassaction111()
160
+ {
161
+ $this->setMassactionIdField('entity_id');
162
+ $this->getMassactionBlock()->setFormFieldName('order_ids');
163
+ $this->getMassactionBlock()->setUseSelectAll(false);
164
+
165
+ $this->getMassactionBlock()->addItem('export_css', array(
166
+ 'label'=> Mage::helper('chronorelais')->__('Export CSS'),
167
+ 'url' => $this->getUrl('*/*/exportcss'),
168
+ ));
169
+ $this->getMassactionBlock()->addItem('export_cso', array(
170
+ 'label'=> Mage::helper('chronorelais')->__('Export CSO'),
171
+ 'url' => $this->getUrl('*/*/exportcso'),
172
+ ));
173
+
174
+ return $this;
175
+ }
176
+
177
+ protected function _prepareMassaction()
178
+ {
179
+ $this->setMassactionIdField('entity_id');
180
+ $this->getMassactionBlock()->setFormFieldName('order_ids');
181
+ $this->getMassactionBlock()->setUseSelectAll(false);
182
+
183
+ if($is_sending_day = Mage::helper('chronorelais')->isSendingDay()) {
184
+ $shipping = array(
185
+ 'Yes' => Mage::helper('chronorelais')->__('Yes'),
186
+ 'No' => Mage::helper('chronorelais')->__('No'));
187
+ $this->getMassactionBlock()->addItem('shipping', array(
188
+ 'label' => Mage::helper('chronorelais')->__('Livraison le Samedi'),
189
+ 'url' => $this->getUrl('*/*/massLivraisonSamediStatus', array('_current'=>true)),
190
+ 'additional' => array(
191
+ 'visibility' => array(
192
+ 'name' => 'status',
193
+ 'type' => 'select',
194
+ 'class' => 'required-entry',
195
+ 'style' => 'width:80px',
196
+ 'label' => Mage::helper('chronorelais')->__('Status'),
197
+ 'values' => $shipping
198
+ )
199
+ )
200
+ ));
201
+ }
202
+
203
+ $export = array(
204
+ 'css' => Mage::helper('chronorelais')->__('CSS Format'),
205
+ 'cso' => Mage::helper('chronorelais')->__('CSO Format'));
206
+ array_unshift($statuses, array('label'=>'', 'value'=>''));
207
+ $this->getMassactionBlock()->addItem('export', array(
208
+ 'label'=> Mage::helper('chronorelais')->__('Export'),
209
+ 'url' => $this->getUrl('*/*/massExport', array('_current'=>true)),
210
+ 'additional' => array(
211
+ 'visibility' => array(
212
+ 'name' => 'format',
213
+ 'type' => 'select',
214
+ 'class' => 'required-entry',
215
+ 'label' => Mage::helper('chronorelais')->__('Format'),
216
+ 'values' => $export
217
+ )
218
+ )
219
+ ));
220
+ return $this;
221
+ }
222
+
223
+ public function getRowUrl($row)
224
+ {
225
+ if (Mage::getSingleton('admin/session')->isAllowed('sales/order/actions/view')) {
226
+ return $this->getUrl('adminhtml/sales_order/view', array('order_id' => $row->getId()));
227
+ }
228
+ return false;
229
+ }
230
+
231
+ public function getGridUrl()
232
+ {
233
+ return $this->getUrl('*/*/*', array('_current'=>true));
234
+ }
235
+
236
+ }
app/code/community/Chronopost/Chronorelais/Block/Filter.php ADDED
@@ -0,0 +1,53 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class Chronopost_Chronorelais_Block_Filter extends Mage_Core_Block_Template
3
+ {
4
+
5
+ public function _prepareLayout()
6
+ {
7
+ return parent::_prepareLayout();
8
+ }
9
+
10
+
11
+ public function getRelaisPoints(){
12
+
13
+ $zipcode = $this->getRequest()->getParam ( 'zipcode' );
14
+
15
+ if( $zipcode && $zipcode!="" ){
16
+ $result = Mage::getModel('shipping/rate_result');
17
+
18
+ try {
19
+ $client = new SoapClient("http://wsshipping.chronopost.fr/soap.point.relais/services/ServiceRechercheBt?wsdl",array('trace'=> 0,'connection_timeout'=>10));
20
+
21
+ $webservbt = $client->__call("rechercheBtParCodeproduitEtCodepostalEtDate",array(0,$zipcode,0));
22
+
23
+ } catch(SoapFault $fault){
24
+
25
+ return false;
26
+ }
27
+
28
+
29
+ return $webservbt;
30
+ }
31
+ else{
32
+ return false;
33
+ }
34
+ }
35
+
36
+ public function getmethodeCode(){
37
+
38
+ $zipcode = $this->getRequest()->getParam ( 'methodecode' );
39
+
40
+ if($zipcode){
41
+ $result = Mage::getModel('shipping/rate_result');
42
+ ini_set("soap.wsdl_cache_enabled", "0");
43
+ $client = new SoapClient("http://wsshipping.chronopost.fr/soap.point.relais/services/ServiceRechercheBt?wsdl");
44
+ $webservbt = $client->__call("rechercheBtParCodeproduitEtCodepostalEtDate",array(0,$zipcode,0));
45
+ return $webservbt;
46
+ }
47
+ else{
48
+ return false;
49
+ }
50
+ }
51
+
52
+ }
53
+ ?>
app/code/community/Chronopost/Chronorelais/Block/Import/Form.php ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class Chronopost_Chronorelais_Block_Import_Form extends Mage_Adminhtml_Block_Widget
3
+ {
4
+
5
+ public function __construct()
6
+ {
7
+ parent::__construct();
8
+ $this->setTemplate('chronorelais/import/form.phtml');
9
+ }
10
+
11
+ }
app/code/community/Chronopost/Chronorelais/Block/Sales/Impression.php ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Chronopost_Chronorelais_Block_Sales_Impression extends Mage_Adminhtml_Block_Widget_Grid_Container
4
+ {
5
+
6
+
7
+ public function __construct()
8
+ {
9
+ $this->_blockGroup = 'chronorelais';
10
+ $this->_controller = 'sales_shipment';
11
+ $this->_headerText = Mage::helper('chronorelais')->__('Impressions des étiquettes Chronopost');
12
+ parent::__construct();
13
+ $this->_removeButton('add');
14
+ }
15
+
16
+ }
app/code/community/Chronopost/Chronorelais/Block/Sales/Order/Shipment/View.php ADDED
@@ -0,0 +1,99 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class Chronopost_Chronorelais_Block_Sales_Order_Shipment_View extends Mage_Adminhtml_Block_Widget_Form_Container
3
+ {
4
+
5
+ public function __construct()
6
+ {
7
+ $this->_objectId = 'shipment_id';
8
+ $this->_controller = 'sales_order_shipment';
9
+ $this->_mode = 'view';
10
+
11
+ parent::__construct();
12
+
13
+ $this->_removeButton('reset');
14
+ $this->_removeButton('delete');
15
+ $this->_updateButton('save', 'label', Mage::helper('sales')->__('Send Tracking Information'));
16
+ $this->_updateButton('save', 'onclick', "setLocation('".$this->getEmailUrl()."')");
17
+
18
+ //Ajout de l'impression de l'étiquette
19
+ $_order = $this->getShipment()->getOrder();
20
+ $_shippingMethod = explode("_",$_order->getShippingMethod());
21
+ if (($_shippingMethod[0] == 'chronorelais' || $_shippingMethod[0] == 'chronopost' || $_shippingMethod[0] == 'chronoexpress')) {
22
+ $this->_addButton('etiquette', array(
23
+ 'label' => Mage::helper('chronorelais')->__('Etiquette Chronopost'),
24
+ 'class' => 'save',
25
+ 'onclick' => 'setLocation(\'' . $this->getPrintMondialRelayUrl() . '\')'
26
+ )
27
+ );
28
+ }
29
+
30
+ if ($this->getShipment()->getId()) {
31
+ $this->_addButton('print', array(
32
+ 'label' => Mage::helper('sales')->__('Print'),
33
+ 'class' => 'save',
34
+ 'onclick' => 'setLocation(\''.$this->getPrintUrl().'\')'
35
+ )
36
+ );
37
+ }
38
+ }
39
+
40
+ /**
41
+ * Retrieve shipment model instance
42
+ *
43
+ * @return Mage_Sales_Model_Order_Shipment
44
+ */
45
+ public function getShipment()
46
+ {
47
+ return Mage::registry('current_shipment');
48
+ }
49
+
50
+ public function getHeaderText()
51
+ {
52
+ if ($this->getShipment()->getEmailSent()) {
53
+ $emailSent = Mage::helper('sales')->__('Shipment email sent');
54
+ }
55
+ else {
56
+ $emailSent = Mage::helper('sales')->__('Shipment email not sent');
57
+ }
58
+
59
+ $header = Mage::helper('sales')->__('Shipment #%s (%s)', $this->getShipment()->getIncrementId(), $emailSent);
60
+ return $header;
61
+ }
62
+
63
+ public function getBackUrl()
64
+ {
65
+ return $this->getUrl(
66
+ '*/sales_order/view',
67
+ array(
68
+ 'order_id' => $this->getShipment()->getOrderId(),
69
+ 'active_tab'=> 'order_shipments'
70
+ ));
71
+ }
72
+
73
+ public function getEmailUrl()
74
+ {
75
+ return $this->getUrl('*/sales_order_shipment/email', array('shipment_id' => $this->getShipment()->getId()));
76
+ }
77
+
78
+ public function getPrintUrl()
79
+ {
80
+ return $this->getUrl('*/*/print', array(
81
+ 'invoice_id' => $this->getShipment()->getId()
82
+ ));
83
+ }
84
+
85
+ public function getPrintMondialRelayUrl()
86
+ {
87
+ return $this->getUrl('chronorelais/sales_impression/print', array(
88
+ 'shipment_id' => $this->getShipment()->getId()
89
+ ));
90
+ }
91
+
92
+ public function updateBackButtonUrl($flag)
93
+ {
94
+ if ($flag) {
95
+ return $this->_updateButton('back', 'onclick', 'setLocation(\'' . $this->getUrl('*/sales_shipment/') . '\')');
96
+ }
97
+ return $this;
98
+ }
99
+ }
app/code/community/Chronopost/Chronorelais/Block/Sales/Shipment/Copy of Grid.php ADDED
@@ -0,0 +1,139 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class Chronopost_Chronorelais_Block_Sales_Shipment_Grid extends Mage_Adminhtml_Block_Widget_Grid
3
+ {
4
+
5
+ public function __construct()
6
+ {
7
+ parent::__construct();
8
+ $this->setId('sales_shipment_grid');
9
+ $this->setDefaultSort('order_created_at');
10
+ $this->setDefaultDir('DESC');
11
+ }
12
+
13
+ /**
14
+ * Retrieve collection class
15
+ *
16
+ * @return string
17
+ */
18
+ protected function _getCollectionClass()
19
+ {
20
+ return 'sales/order_shipment_grid_collection';
21
+ }
22
+
23
+ protected function _prepareCollection()
24
+ {
25
+ $collection = Mage::getResourceModel($this->_getCollectionClass());
26
+ $collection->getSelect()->columns(array('shipment_created_at' => 'main_table.created_at'));
27
+ $collection->getSelect()->columns(array('shipment_increment_id' => 'main_table.increment_id'));
28
+
29
+ $collection->getSelect()->joinLeft(array('ot' => $collection->getTable('sales/order')), 'main_table.order_id = ot.entity_id');
30
+ $collection->getSelect()->joinLeft(array('ost' => $collection->getTable('sales/shipment_track')), 'ot.entity_id = ost.order_id');
31
+
32
+ $collection->getSelect()->where('ot.shipping_method LIKE "chronorelais%" OR ot.shipping_method LIKE "chronopost%"');
33
+ $this->setCollection($collection);
34
+ return parent::_prepareCollection();
35
+ }
36
+
37
+ protected function _prepareColumns()
38
+ {
39
+ $this->addColumn('increment_id', array(
40
+ 'header' => Mage::helper('sales')->__('Shipment #'),
41
+ 'index' => 'shipment_increment_id',
42
+ 'type' => 'text',
43
+ ));
44
+
45
+ $this->addColumn('shipment_created_at', array(
46
+ 'header' => Mage::helper('sales')->__('Date Shipped'),
47
+ 'index' => 'shipment_created_at',
48
+ 'type' => 'datetime',
49
+ ));
50
+
51
+ $this->addColumn('order_increment_id', array(
52
+ 'header' => Mage::helper('sales')->__('Order #'),
53
+ 'index' => 'order_increment_id',
54
+ 'type' => 'number',
55
+ ));
56
+
57
+ $this->addColumn('order_created_at', array(
58
+ 'header' => Mage::helper('sales')->__('Order Date'),
59
+ 'index' => 'order_created_at',
60
+ 'type' => 'datetime',
61
+ ));
62
+
63
+ $this->addColumn('shipping_name', array(
64
+ 'header' => Mage::helper('sales')->__('Ship to Name'),
65
+ 'index' => 'shipping_name',
66
+ ));
67
+
68
+ $this->addColumn('total_qty', array(
69
+ 'header' => Mage::helper('sales')->__('Total Qty'),
70
+ 'index' => 'total_qty',
71
+ 'type' => 'number',
72
+ ));
73
+
74
+ $this->addColumn('number', array(
75
+ 'header' => Mage::helper('sales')->__('Tracking'),
76
+ 'index' => 'number',
77
+ ));
78
+
79
+ $this->addColumn('title', array(
80
+ 'header' => Mage::helper('sales')->__('Mode de transport'),
81
+ 'index' => 'title',
82
+ 'type' => 'text',
83
+ ));
84
+
85
+ $this->addColumn('download', array(
86
+ 'header' => Mage::helper('chronorelais')->__('Etiquettes'),
87
+ 'type' => 'action',
88
+ 'getter' => 'getParentId',
89
+ 'actions' => array(
90
+ array(
91
+ 'caption' => Mage::helper('chronorelais')->__('Imprimer'),
92
+ 'url' => array(
93
+ 'base'=>'chronorelais/sales_impression/print'
94
+ ),
95
+ 'field' => 'shipment_id'
96
+ )
97
+ ),
98
+ 'filter' => false,
99
+ 'sortable' => false,
100
+ 'index' => 'stores'
101
+ ));
102
+
103
+ return parent::_prepareColumns();
104
+ }
105
+
106
+ public function getRowUrl($row)
107
+ {
108
+ if (!Mage::getSingleton('admin/session')->isAllowed('sales/order/shipment')) {
109
+ return false;
110
+ }
111
+
112
+ return $this->getUrl('adminhtml/sales_shipment/view',
113
+ array(
114
+ 'shipment_id'=> $row->getParentId(),
115
+ )
116
+ );
117
+ }
118
+
119
+ protected function _prepareMassaction()
120
+ {
121
+ $this->setMassactionIdField('entity_id');
122
+ $this->getMassactionBlock()->setFormFieldName('shipment_ids');
123
+ $this->getMassactionBlock()->setUseSelectAll(false);
124
+
125
+ // Impression des étiquettes
126
+ /*$this->getMassactionBlock()->addItem('pdfshipments_order', array(
127
+ 'label'=> Mage::helper('sales')->__('Imprimer les étiquettes'),
128
+ 'url' => $this->getUrl('chronorelais/sales_impression/printMass'),
129
+ ));*/
130
+
131
+ return $this;
132
+ }
133
+
134
+ public function getGridUrl()
135
+ {
136
+ return $this->getUrl('*/*/*', array('_current' => true));
137
+ }
138
+
139
+ }
app/code/community/Chronopost/Chronorelais/Block/Sales/Shipment/Grid-bkp-03-02-11.php ADDED
@@ -0,0 +1,143 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class Chronopost_Chronorelais_Block_Sales_Shipment_Grid extends Mage_Adminhtml_Block_Widget_Grid
3
+ {
4
+
5
+ public function __construct()
6
+ {
7
+ parent::__construct();
8
+ $this->setId('sales_shipment_grid');
9
+ $this->setDefaultSort('shipment_created_at');
10
+ $this->setDefaultDir('DESC');
11
+ }
12
+
13
+ /**
14
+ * Retrieve collection class
15
+ *
16
+ * @return string
17
+ */
18
+ protected function _getCollectionClass()
19
+ {
20
+ return 'sales/order_collection';
21
+ }
22
+
23
+ protected function _prepareCollection()
24
+ {
25
+ $collection = Mage::getResourceModel($this->_getCollectionClass());
26
+ $collection->getSelect()->columns(array('shipment_created_at' => 'osg.created_at'));
27
+ $collection->getSelect()->columns(array('shipment_increment_id' => 'osg.increment_id'));
28
+ $collection->getSelect()->columns(array('shipping_method' => 'main_table.shipping_method'));
29
+
30
+ $collection->getSelect()->joinLeft(array('ost' => $collection->getTable('sales/shipment_track')), 'main_table.entity_id = ost.order_id', array('if(isNull(ost.number) , "--" , ost.number) as number', 'if(isNull(ost.title) , "--" , ost.title) as title'));
31
+ $collection->getSelect()->joinRight(array('osg' => $collection->getTable('sales/shipment_grid')), 'osg.order_id = main_table.entity_id');
32
+ $collection->getSelect()->where('shipping_method LIKE "chronorelais%" OR shipping_method LIKE "chronopost%"');
33
+ $collection->getSelect()->group('osg.entity_id');
34
+
35
+
36
+ $this->setCollection($collection);
37
+
38
+ return parent::_prepareCollection();
39
+ }
40
+
41
+ protected function _prepareColumns()
42
+ {
43
+ $this->addColumn('increment_id', array(
44
+ 'header' => Mage::helper('sales')->__('Shipment #'),
45
+ 'index' => 'shipment_increment_id',
46
+ 'type' => 'text',
47
+ ));
48
+
49
+ $this->addColumn('shipment_created_at', array(
50
+ 'header' => Mage::helper('sales')->__('Date Shipped'),
51
+ 'index' => 'shipment_created_at',
52
+ 'type' => 'datetime',
53
+ ));
54
+
55
+ $this->addColumn('order_increment_id', array(
56
+ 'header' => Mage::helper('sales')->__('Order #'),
57
+ 'index' => 'order_increment_id',
58
+ 'type' => 'number',
59
+ ));
60
+
61
+ $this->addColumn('order_created_at', array(
62
+ 'header' => Mage::helper('sales')->__('Order Date'),
63
+ 'index' => 'order_created_at',
64
+ 'type' => 'datetime',
65
+ ));
66
+
67
+ $this->addColumn('shipping_name', array(
68
+ 'header' => Mage::helper('sales')->__('Ship to Name'),
69
+ 'index' => 'shipping_name',
70
+ ));
71
+
72
+ $this->addColumn('total_qty', array(
73
+ 'header' => Mage::helper('sales')->__('Total Qty'),
74
+ 'index' => 'total_qty',
75
+ 'type' => 'number',
76
+ ));
77
+
78
+ $this->addColumn('number', array(
79
+ 'header' => Mage::helper('sales')->__('Tracking'),
80
+ 'index' => 'number',
81
+ ));
82
+
83
+ $this->addColumn('title', array(
84
+ 'header' => Mage::helper('sales')->__('Mode de transport'),
85
+ 'index' => 'title',
86
+ 'type' => 'text',
87
+ ));
88
+
89
+ $this->addColumn('download', array(
90
+ 'header' => Mage::helper('chronorelais')->__('Etiquettes'),
91
+ 'type' => 'action',
92
+ 'getter' => 'getId',
93
+ 'actions' => array(
94
+ array(
95
+ 'caption' => Mage::helper('chronorelais')->__('Imprimer'),
96
+ 'url' => array(
97
+ 'base'=>'chronorelais/sales_impression/print'
98
+ ),
99
+ 'field' => 'shipment_id'
100
+ )
101
+ ),
102
+ 'filter' => false,
103
+ 'sortable' => false,
104
+ 'index' => 'stores'
105
+ ));
106
+
107
+ return parent::_prepareColumns();
108
+ }
109
+
110
+ public function getRowUrl($row)
111
+ {
112
+ if (!Mage::getSingleton('admin/session')->isAllowed('sales/order/shipment')) {
113
+ return false;
114
+ }
115
+
116
+ return $this->getUrl('adminhtml/sales_shipment/view',
117
+ array(
118
+ 'shipment_id'=> $row->getId(),
119
+ )
120
+ );
121
+ }
122
+
123
+ protected function _prepareMassaction()
124
+ {
125
+ $this->setMassactionIdField('entity_id');
126
+ $this->getMassactionBlock()->setFormFieldName('shipment_ids');
127
+ $this->getMassactionBlock()->setUseSelectAll(false);
128
+
129
+ // Impression des étiquettes
130
+ /*$this->getMassactionBlock()->addItem('pdfshipments_order', array(
131
+ 'label'=> Mage::helper('sales')->__('Imprimer les étiquettes'),
132
+ 'url' => $this->getUrl('chronorelais/sales_impression/printMass'),
133
+ ));*/
134
+
135
+ return $this;
136
+ }
137
+
138
+ public function getGridUrl()
139
+ {
140
+ return $this->getUrl('*/*/*', array('_current' => true));
141
+ }
142
+
143
+ }
app/code/community/Chronopost/Chronorelais/Block/Sales/Shipment/Grid.php ADDED
@@ -0,0 +1,185 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class Chronopost_Chronorelais_Block_Sales_Shipment_Grid extends Mage_Adminhtml_Block_Widget_Grid
3
+ {
4
+
5
+ public function __construct()
6
+ {
7
+ parent::__construct();
8
+ $this->setId('sales_order_grid');
9
+ $this->setDefaultSort('created_at');
10
+ $this->setDefaultDir('DESC');
11
+ }
12
+
13
+ /**
14
+ * Retrieve collection class
15
+ *
16
+ * @return string
17
+ */
18
+ protected function _getCollectionClass()
19
+ {
20
+ return 'sales/order_grid_collection';
21
+ }
22
+
23
+ protected function _prepareCollection()
24
+ {
25
+ $_chronopost_deliver_saturday = Mage::helper('chronorelais')->getConfigData('carriers/chronopost/deliver_on_saturday');
26
+ $_chronorelais_deliver_saturday = Mage::helper('chronorelais')->getConfigData('carriers/chronorelais/deliver_on_saturday');
27
+ if($_chronopost_deliver_saturday==1) { $_chronopost_deliver_saturday = 'Yes'; } else { $_chronopost_deliver_saturday = 'No';}
28
+ if($_chronorelais_deliver_saturday==1) { $_chronorelais_deliver_saturday = 'Yes'; } else { $_chronorelais_deliver_saturday = 'No'; }
29
+
30
+ $collection = Mage::getResourceModel($this->_getCollectionClass());
31
+ $collection->getSelect()->joinLeft(array('og' => $collection->getTable('sales/order')), 'main_table.entity_id = og.entity_id', array('CASE LOWER(SUBSTRING_INDEX(og.shipping_method,"_","1")) WHEN "chronoexpress" THEN "Chrono Express" WHEN "chronorelais" THEN "Chrono Relais" ELSE CONCAT(UCASE(SUBSTRING(SUBSTRING_INDEX(og.shipping_method,"_","1"),1,1)),LOWER(SUBSTRING(SUBSTRING_INDEX(og.shipping_method,"_","1"), 2))) END as shipping_method', 'og.total_qty_ordered'));
32
+ $collection->getSelect()->joinLeft(array('osg' => $collection->getTable('sales/shipment_grid')), 'main_table.entity_id = osg.order_id', array('if(isNull(osg.increment_id) , "--" , osg.increment_id) as shipment_increment_id', 'osg.created_at as shipment_created_at'));
33
+ $collection->getSelect()->joinLeft(array('ost' => $collection->getTable('sales/shipment_track')), 'main_table.entity_id = ost.order_id', array('if(isNull(ost.number) , "--" , ost.number) as number', 'if(isNull(ost.title) , "--" , ost.title) as title'));
34
+ $collection->getSelect()->joinLeft(array('oes' => Mage::getSingleton('core/resource')->getTableName('sales_chronopost_order_export_status')), 'main_table.entity_id = oes.order_id', array("if(isNull(oes.livraison_le_samedi), CASE LOWER(SUBSTRING_INDEX(og.shipping_method,'_','1')) WHEN 'chronopost' THEN '$_chronopost_deliver_saturday' WHEN 'chronorelais' THEN '$_chronorelais_deliver_saturday' WHEN 'chronoexpress' THEN '--' ELSE 'No' END, oes.livraison_le_samedi) as livraison_le_samedi"));
35
+ $collection->getSelect()->where('og.shipping_method LIKE "chronorelais%" OR og.shipping_method LIKE "chronopost%" OR og.shipping_method LIKE "chronoexpress%"');
36
+ $collection->getSelect()->group('main_table.entity_id');
37
+ $sql = $collection->getSelectSql(true);
38
+ $collection->getSelect()->reset()->from(
39
+ array('e' =>new Zend_Db_Expr("({$sql})")),
40
+ array('e' => "*")
41
+ );
42
+
43
+ $this->setCollection($collection);
44
+ return parent::_prepareCollection();
45
+ }
46
+
47
+ protected function _prepareColumns()
48
+ {
49
+
50
+ $this->addColumn('real_order_id', array(
51
+ 'header'=> Mage::helper('sales')->__('Order #'),
52
+ 'width' => '100px',
53
+ 'type' => 'text',
54
+ 'index' => 'increment_id',
55
+ 'filter' => false,
56
+ ));
57
+
58
+ $this->addColumn('created_at', array(
59
+ 'header' => Mage::helper('sales')->__('Order Date'),
60
+ 'index' => 'created_at',
61
+ 'type' => 'datetime',
62
+ 'filter' => false,
63
+ ));
64
+
65
+ $this->addColumn('shipment_increment_id', array(
66
+ 'header' => Mage::helper('sales')->__('Shipment #'),
67
+ 'index' => 'shipment_increment_id',
68
+ 'type' => 'text',
69
+ 'width' => '100px',
70
+ 'filter' => false,
71
+ ));
72
+
73
+ $this->addColumn('shipment_created_at', array(
74
+ 'header' => Mage::helper('sales')->__('Date Shipped'),
75
+ 'index' => 'shipment_created_at',
76
+ 'type' => 'datetime',
77
+ 'filter' => false,
78
+ ));
79
+
80
+ $this->addColumn('shipping_name', array(
81
+ 'header' => Mage::helper('sales')->__('Ship to Name'),
82
+ 'index' => 'shipping_name',
83
+ 'filter' => false,
84
+ ));
85
+
86
+ $this->addColumn('total_qty_ordered', array(
87
+ 'header' => Mage::helper('sales')->__('Total Qty'),
88
+ 'index' => 'total_qty_ordered',
89
+ 'type' => 'number',
90
+ 'filter' => false,
91
+ ));
92
+
93
+ $this->addColumn('number', array(
94
+ 'header' => Mage::helper('sales')->__('Tracking'),
95
+ 'index' => 'number',
96
+ 'filter' => false,
97
+ ));
98
+
99
+ $this->addColumn('shipping_method', array(
100
+ 'header' => Mage::helper('sales')->__('Mode de transport'),
101
+ 'index' => 'shipping_method',
102
+ 'type' => 'text',
103
+ 'filter' => false,
104
+ ));
105
+
106
+ if($is_sending_day = Mage::helper('chronorelais')->isSendingDay()) {
107
+ $this->addColumn('livraison_le_samedi', array(
108
+ 'header' => Mage::helper('sales')->__('Livraison le Samedi'),
109
+ 'index' => 'livraison_le_samedi',
110
+ 'width' => '100px',
111
+ 'class' => 'a-center',
112
+ 'filter' => false,
113
+ ));
114
+ }
115
+
116
+ $this->addColumn('download', array(
117
+ 'header' => Mage::helper('chronorelais')->__('Etiquettes'),
118
+ 'type' => 'action',
119
+ 'getter' => 'getId',
120
+ 'actions' => array(
121
+ array(
122
+ 'caption' => Mage::helper('chronorelais')->__('Imprimer'),
123
+ 'url' => array(
124
+ 'base'=>'chronorelais/sales_impression/print'
125
+ ),
126
+ 'target' => '_blank',
127
+ 'field' => 'order_id'
128
+ )
129
+ ),
130
+ 'filter' => false,
131
+ 'sortable' => false,
132
+ 'index' => 'stores'
133
+ ));
134
+
135
+ return parent::_prepareColumns();
136
+ }
137
+
138
+ public function getRowUrl($row)
139
+ {
140
+ if (!Mage::getSingleton('admin/session')->isAllowed('sales/order/shipment')) {
141
+ return false;
142
+ }
143
+
144
+ return $this->getUrl('adminhtml/sales_order/view',
145
+ array(
146
+ 'order_id'=> $row->getId(),
147
+ )
148
+ );
149
+ }
150
+
151
+ protected function _prepareMassaction()
152
+ {
153
+ if($is_sending_day = Mage::helper('chronorelais')->isSendingDay()) {
154
+ $this->setMassactionIdField('entity_id');
155
+ $this->getMassactionBlock()->setFormFieldName('order_ids');
156
+ $this->getMassactionBlock()->setUseSelectAll(false);
157
+
158
+ $shipping = array(
159
+ 'Yes' => Mage::helper('chronorelais')->__('Yes'),
160
+ 'No' => Mage::helper('chronorelais')->__('No'));
161
+ $this->getMassactionBlock()->addItem('shipping', array(
162
+ 'label' => Mage::helper('chronorelais')->__('Livraison le Samedi'),
163
+ 'url' => $this->getUrl('*/*/massLivraisonSamediStatus', array('_current'=>true)),
164
+ 'additional' => array(
165
+ 'visibility' => array(
166
+ 'name' => 'status',
167
+ 'type' => 'select',
168
+ 'class' => 'required-entry',
169
+ 'style' => 'width:80px',
170
+ 'label' => Mage::helper('chronorelais')->__('Status'),
171
+ 'values' => $shipping
172
+ )
173
+ )
174
+ ));
175
+
176
+ return $this;
177
+ }
178
+ }
179
+
180
+ public function getGridUrl()
181
+ {
182
+ return $this->getUrl('*/*/*', array('_current' => true));
183
+ }
184
+
185
+ }
app/code/community/Chronopost/Chronorelais/Controller/Abstract.php ADDED
@@ -0,0 +1,126 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Magento Chronopost Chronorelais 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 Chronopost
17
+ * @package Chronopost_Chronorelais
18
+ * @copyright Copyright (c) 2008-10
19
+ * @author Sundar
20
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
21
+ */
22
+
23
+ class Chronopost_Chronorelais_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 getIncludingPath($path) {
46
+ if (file_exists(dirname(__FILE__).'/Chronopost_Chronorelais_includes_'.$path)) {
47
+ return 'Chronopost_Chronorelais_includes_'.$path;
48
+ } else {
49
+ return Mage::getBaseDir('code').'/community/Chronopost/Chronorelais/includes/'.$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=\"ocseditor-".$id."-page\" class=\"ocseditor-page\">"
102
+ .$this->pageHeader($title,$this->button('Close',"ocseditor.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 button($label, $onclick, $class_name='') {
121
+ $class_name = 'scalable'.($class_name!='' ? ' '.$class_name : '');
122
+ return "<button type=\"button\" class=\"".$class_name."\" onclick=\"".$onclick."\"><span>".$this->__($label)."</span></button>";
123
+ }
124
+ }
125
+
126
+ ?>
app/code/community/Chronopost/Chronorelais/Helper/Data.php ADDED
@@ -0,0 +1,177 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class Chronopost_Chronorelais_Helper_Data extends Mage_Core_Helper_Abstract
3
+ {
4
+ //Choronorelais settings for productCode
5
+ const CHRONO_POST = '01'; // for France
6
+ const CHRONO_EXPRESS = '17'; // for Interantional
7
+ const CHRONORELAIS = '86'; // for Chronorelais
8
+ const CHRONOPOST_13H = '13H'; // for France
9
+ const CHRONOEXPRESS_EI = 'EI'; // for Interantional
10
+ const CHRONORELAIS_PR = 'PR'; // for Chronorelais
11
+ const CHRONOPOST_DEFAULT_COUNTRY = 'FR';
12
+ const CHRONOPOST_TRACKING_URL = 'http://wsshipping.chronopost.fr/shipping/services/getReservedSkybill?reservationNumber={trackingNumber}';
13
+ // if you are in a period outside thursday 18:00 to friday 15:00, there is no shipping on saturday
14
+ var $SaturdayShippingDays = array(
15
+ 'startday' => 'thursday',
16
+ 'endday' => 'friday',
17
+ 'starttime' => '18:00:00',
18
+ 'endtime' => '15:00:00'
19
+ );
20
+
21
+ public function getConfigData($path) {
22
+ return Mage::getStoreConfig($path, Mage::app()->getStore());
23
+ }
24
+ public function getSaturdayShippingDays() {
25
+ return $this->SaturdayShippingDays;
26
+ }
27
+ public function getCurrentTimeByZone($timezone="Europe/Paris", $format="l H:i") {
28
+ $d = new DateTime("now", new DateTimeZone($timezone));
29
+ return $d->format($format);
30
+ }
31
+ public function isSendingDay() {
32
+ $shipping_days = $this->getSaturdayShippingDays();
33
+ $current_day = strtolower($this->getCurrentTimeByZone("Europe/Paris", "l"));
34
+ $current_date = $this->getCurrentTimeByZone("Europe/Paris", "Y-m-d H:i:s");
35
+ $current_datetime = explode(' ',$current_date);
36
+
37
+ //get timestamps
38
+ $start_timestamp = strtotime($current_datetime[0]." ".$shipping_days['starttime']);
39
+ $end_timestamp = strtotime($current_datetime[0]." ".$shipping_days['endtime']);
40
+ $current_timestamp = strtotime($current_date);
41
+
42
+ $sending_day = false;
43
+ if($shipping_days['startday']==$current_day && $current_timestamp>=$start_timestamp) {
44
+ $sending_day = true;
45
+ } elseif($shipping_days['endday']==$current_day && $current_timestamp<=$end_timestamp) {
46
+ $sending_day = true;
47
+ }
48
+ return $sending_day;
49
+ }
50
+
51
+ /**
52
+ * General Shipping configuration
53
+ */
54
+ public function getConfigurationAccountNumber() {
55
+ return $this->getConfigData('chronorelais/shipping/account_number');
56
+ }
57
+ public function getConfigurationSubAccountNumber() {
58
+ return $this->getConfigData('chronorelais/shipping/sub_account_number');
59
+ }
60
+ public function getConfigurationAccountPass() {
61
+ return $this->getConfigData('chronorelais/shipping/account_pass');
62
+ }
63
+ public function getConfigurationTrackingViewUrl() {
64
+ return $this->getConfigData('chronorelais/shipping/tracking_view_url');
65
+ }
66
+ public function getConfigurationGoogleMapAPIKey() {
67
+ return $this->getConfigData('chronorelais/shipping/google_map_api');
68
+ }
69
+ public function getChronoProductCode($country, $code='') {
70
+ $productcode = '';
71
+ $code = strtolower($code);
72
+ if($code=='chronorelais') {
73
+ $productcode = self::CHRONORELAIS;
74
+ } elseif($code=='chronopost') {
75
+ $productcode = self::CHRONO_POST;
76
+ } else {
77
+ $productcode = self::CHRONO_EXPRESS;
78
+ }
79
+ return $productcode;
80
+ }
81
+ public function getChronoProductCodeString($code='') {
82
+ $productcode = '';
83
+ $code = strtolower($code);
84
+ if($code=='chronorelais') {
85
+ $productcode = self::CHRONORELAIS_PR;
86
+ } elseif($code=='chronopost') {
87
+ $productcode = self::CHRONOPOST_13H;
88
+ } else {
89
+ $productcode = self::CHRONOEXPRESS_EI;
90
+ }
91
+ return $productcode;
92
+ }
93
+ public function getConfigurationTrackingUrl() {
94
+ return self::CHRONOPOST_TRACKING_URL;
95
+ }
96
+
97
+ /**
98
+ * Export configuration
99
+ */
100
+ public function getConfigurationFileExtension($export_type='css') {
101
+ return $this->getConfigData('chronorelais/export_'.$export_type.'/file_extension');
102
+ }
103
+ public function getConfigurationFileCharset($export_type='css') {
104
+ return $this->getConfigData('chronorelais/export_'.$export_type.'/file_charset');
105
+ }
106
+ public function getConfigurationEndOfLineCharacter($export_type='css') {
107
+ return $this->getConfigData('chronorelais/export_'.$export_type.'/endofline_character');
108
+ }
109
+ public function getConfigurationFieldDelimiter($export_type='css') {
110
+ return $this->getConfigData('chronorelais/export_'.$export_type.'/field_delimiter');
111
+ }
112
+ public function getConfigurationFieldSeparator($export_type='css') {
113
+ return $this->getConfigData('chronorelais/export_'.$export_type.'/field_separator');
114
+ }
115
+
116
+ /**
117
+ * Import configuration
118
+ */
119
+ public function getConfigurationSendEmail() {
120
+ return $this->getConfigData('chronorelais/import/send_email');
121
+ }
122
+ public function getConfigurationIncludeComment() {
123
+ return $this->getConfigData('chronorelais/import/include_comment');
124
+ }
125
+ public function getConfigurationDefaultTrackingTitle() {
126
+ return $this->getConfigData('chronorelais/import/default_tracking_title');
127
+ }
128
+ public function getConfigurationShippingComment() {
129
+ return $this->getConfigData('chronorelais/import/shipping_comment');
130
+ }
131
+
132
+ /**
133
+ * Shipper Information
134
+ */
135
+ public function getConfigurationShipperInfo($field) {
136
+ $fieldValue = '';
137
+ if($field) {
138
+ if($this->getConfigData('chronorelais/shipperinformation/'.$field)) {
139
+ $fieldValue = $this->getConfigData('chronorelais/shipperinformation/'.$field);
140
+ }
141
+ }
142
+ return $fieldValue;
143
+ }
144
+
145
+ /**
146
+ * Chronopost Customer Information
147
+ */
148
+ public function getConfigurationCustomerInfo($field) {
149
+ $fieldValue = '';
150
+ if($field) {
151
+ if($this->getConfigData('chronorelais/customerinformation/'.$field)) {
152
+ $fieldValue = $this->getConfigData('chronorelais/customerinformation/'.$field);
153
+ }
154
+ }
155
+ return $fieldValue;
156
+ }
157
+
158
+ /**
159
+ * Import configuration
160
+ */
161
+ public function getConfigurationSkybillParam() {
162
+ return $this->getConfigData('chronorelais/skybillparam/mode');
163
+ }
164
+
165
+ /* Get Livraison le Samedi status by orderid */
166
+ public function getLivraisonSamediStatus($order_id)
167
+ {
168
+ $_connection = Mage::getSingleton('core/resource')->getConnection('core_write');
169
+ $_table = Mage::getSingleton('core/resource')->getTableName('sales_chronopost_order_export_status');
170
+ $select = $_connection->select()
171
+ ->from($_table, 'livraison_le_samedi')
172
+ ->where('order_id=?', $order_id);
173
+ $status = $_connection->fetchOne($select);
174
+ return $status;
175
+ }
176
+
177
+ }
app/code/community/Chronopost/Chronorelais/Model/Carrier/AbstractChronorelais.php ADDED
@@ -0,0 +1,32 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ abstract class Chronopost_Chronorelais_Model_Carrier_AbstractChronorelais extends Varien_Object
3
+ {
4
+ protected $_code;
5
+ protected $_rates = null;
6
+ protected $_numBoxes = 1;
7
+
8
+ /**
9
+ * Whether this carrier has fixed rates calculation
10
+ *
11
+ * @var bool
12
+ */
13
+ protected $_isFixed = false;
14
+
15
+ const HANDLING_TYPE_PERCENT = 'P';
16
+ const HANDLING_TYPE_FIXED = 'F';
17
+
18
+ const HANDLING_ACTION_PERPACKAGE = 'P';
19
+ const HANDLING_ACTION_PERORDER = 'O';
20
+
21
+ /**
22
+ * Fields that should be replaced in debug with '***'
23
+ *
24
+ * @var array
25
+ */
26
+ protected $_debugReplacePrivateDataKeys = array();
27
+
28
+ public function __construct()
29
+ {
30
+ }
31
+ }
32
+ ?>
app/code/community/Chronopost/Chronorelais/Model/Carrier/AbstractChronorelaisShipping.php ADDED
@@ -0,0 +1,468 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ // Pour g�rer les cas o� il y a eu compilation
4
+ if (file_exists(dirname(__FILE__).'/Chronopost_Chronorelais_includes_ChronorelaisShippingHelper.php')) include_once 'Chronopost_Chronorelais_includes_ChronorelaisShippingHelper.php';
5
+ else include_once Mage::getBaseDir('code').'/community/Chronopost/Chronorelais/includes/ChronorelaisShippingHelper.php';
6
+
7
+
8
+
9
+ class OCS_Magento_Product implements OCS_Product {
10
+ private $parent_cart_item;
11
+ private $cart_item;
12
+ private $cart_product;
13
+ private $loaded_product;
14
+ private $quantity;
15
+
16
+ public function OCS_Magento_Product($cart_item, $parent_cart_item) {
17
+ $this->cart_item = $cart_item;
18
+ $this->cart_product = $cart_item->getProduct();
19
+ $this->parent_cart_item = $parent_cart_item;
20
+ $this->quantity = isset($parent_cart_item) ? $parent_cart_item->getQty() : $cart_item->getQty();
21
+ }
22
+
23
+ public function getOption($option_name, $get_by_id=false) {
24
+ $value = null;
25
+ $product = $this->cart_product;
26
+ foreach ($product->getOptions() as $option) {
27
+ if ($option->getTitle()==$option_name) {
28
+ $custom_option = $product->getCustomOption('option_'.$option->getId());
29
+ if ($custom_option) {
30
+ $value = $custom_option->getValue();
31
+ if ($option->getType()=='drop_down' && !$get_by_id) {
32
+ $option_value = $option->getValueById($value);
33
+ if ($option_value) $value = $option_value->getTitle();
34
+ }
35
+ }
36
+ break;
37
+ }
38
+ }
39
+ return $value;
40
+ }
41
+
42
+ public function getAttribute($attribute_name, $get_by_id=false) {
43
+ $value = null;
44
+ $product = $this->_getLoadedProduct();
45
+ $attribute = $product->getResource()->getAttribute($attribute_name);
46
+ if ($attribute) {
47
+ $input_type = $attribute->getFrontend()->getInputType();
48
+ switch ($input_type) {
49
+ case 'select' :
50
+ $value = $get_by_id ? $product->getData($attribute_name) : $product->getAttributeText($attribute_name);
51
+ break;
52
+ default :
53
+ $value = $product->getData($attribute_name);
54
+ break;
55
+ }
56
+ }
57
+ return $value;
58
+ }
59
+
60
+ private function _getLoadedProduct() {
61
+ if (!isset($this->loaded_product)) $this->loaded_product = Mage::getModel('catalog/product')->load($this->cart_product->getId());
62
+ return $this->loaded_product;
63
+ }
64
+
65
+ public function getQuantity() {
66
+ return $this->quantity;
67
+ }
68
+
69
+ public function getName() {
70
+ return $this->cart_product->getName();
71
+ }
72
+
73
+ public function getSku() {
74
+ return $this->cart_product->getSku();
75
+ }
76
+
77
+ public function getStockData($key) {
78
+ $stock = $this->cart_product->getStockItem();
79
+ switch ($key) {
80
+ case 'is_in_stock':
81
+ return (bool)$stock->getIsInStock();
82
+ case 'quantity':
83
+ $quantity = $stock->getQty();
84
+ return $stock->getIsQtyDecimal() ? (float)$quantity : (int)$quantity;
85
+ }
86
+ return null;
87
+ }
88
+ }
89
+
90
+ abstract class Chronopost_Chronorelais_Model_Carrier_AbstractChronorelaisShipping
91
+ extends Mage_Shipping_Model_Carrier_Abstract
92
+ {
93
+ protected $_translate_inline;
94
+ protected $_result;
95
+ protected $_config;
96
+ protected $_countries;
97
+ protected $_helper;
98
+ protected $_messages;
99
+
100
+ /**
101
+ * Collect rates for this shipping method based on information in $request
102
+ *
103
+ * @param Mage_Shipping_Model_Rate_Request $data
104
+ * @return Mage_Shipping_Model_Rate_Result
105
+ */
106
+ public function collectRates(Mage_Shipping_Model_Rate_Request $request) {
107
+ // skip if not enabled
108
+ if (!$this->__getConfigData('active')) return false;
109
+
110
+ /*foreach ($request->_data as $key => $data) {
111
+ echo $key.' => '.$data.'<br/>';
112
+ }*/
113
+
114
+ $process = array(
115
+ 'request' => $request,
116
+ 'result' => Mage::getModel('shipping/rate_result'),
117
+ 'cart.items' => array(),
118
+ 'products' => array(),
119
+ 'data' => array(
120
+ 'module.version' => null,
121
+ 'carrier.code' => $this->_code,
122
+ 'cart.price_excluding_tax' => $request->_data['package_value_with_discount'],
123
+ 'cart.price_including_tax' => null,
124
+ 'cart.weight' => $request->_data['package_weight'],
125
+ 'cart.weight.unit' => null,
126
+ 'cart.quantity' => $request->_data['package_qty'],
127
+ 'destination.country.code' => $request->_data['dest_country_id'],
128
+ 'destination.country.name' => null,
129
+ 'destination.region.code' => $request->_data['dest_region_code'],
130
+ 'destination.postcode' => $request->_data['dest_postcode'],
131
+ 'origin.country.code' => $request->_data['country_id'],
132
+ 'origin.country.name' => null,
133
+ 'origin.region.code' => $request->_data['region_id'],
134
+ 'origin.postcode' => $request->_data['postcode'],
135
+ 'customer.group.id' => null,
136
+ 'customer.group.code' => null,
137
+ 'free_shipping' => $request->getFreeShipping(),
138
+ 'store.id' => $request->_data['store_id'],
139
+ 'store.code' => null,
140
+ 'store.name' => null,
141
+ 'store.address' => null,
142
+ 'store.phone' => null,
143
+ 'date.timestamp' => null,
144
+ 'date.year' => null,
145
+ 'date.month' => null,
146
+ 'date.day' => null,
147
+ 'date.hour' => null,
148
+ 'date.minute' => null,
149
+ 'date.second' => null,
150
+ ),
151
+ 'stop_to_first_match' => null,
152
+ 'config' => null,
153
+ );
154
+
155
+ $items = $request->getAllItems();
156
+ for ($i=0, $n=count($items); $i<$n; $i++) {
157
+ $item = $items[$i];
158
+ if ($item->getProduct() instanceof Mage_Catalog_Model_Product) $process['cart.items'][$item->getId()] = $item;
159
+ }
160
+
161
+ $process_result = $this->_process($process);
162
+
163
+ return $process['result'];
164
+ }
165
+
166
+
167
+ public function getAllowedMethods() {
168
+ $process = array();
169
+ $config = $this->_getConfig();
170
+ $allowed_methods = array();
171
+ if (count($config)>0) {
172
+ foreach ($config as $row) $allowed_methods[$row['*code']] = isset($row['label']) ? $row['label']['value'] : 'No label';
173
+ }
174
+ return $allowed_methods;
175
+ }
176
+
177
+ public function isTrackingAvailable() {
178
+ return true;
179
+ }
180
+
181
+ public function getTrackingInfo($tracking_number) {
182
+ $tracking_url = Mage::helper('chronorelais')->getConfigurationTrackingViewUrl();
183
+ $parts = explode(':',$tracking_number);
184
+ if (count($parts)>=2) {
185
+ $tracking_number = $parts[1];
186
+
187
+ $process = array();
188
+ $config = $this->_getConfig();
189
+
190
+ if (isset($config[$parts[0]]['tracking_url'])) {
191
+ $row = $config[$parts[0]];
192
+ $tmp_tracking_url = $this->_helper->getRowProperty($row,'tracking_url');
193
+ if (isset($tmp_tracking_url)) $tracking_url = $tmp_tracking_url;
194
+ }
195
+ }
196
+
197
+ $tracking_status = Mage::getModel('shipping/tracking_result_status')
198
+ ->setCarrier($this->_code)
199
+ ->setCarrierTitle($this->__getConfigData('title'))
200
+ ->setTracking($tracking_number)
201
+ ->addData(
202
+ array(
203
+ 'status'=>'<a target="_blank" href="'.str_replace('{tracking_number}',$tracking_number,$tracking_url).'">'.__('track the package').'</a>'
204
+ )
205
+ )
206
+ ;
207
+ $tracking_result = Mage::getModel('shipping/tracking_result')
208
+ ->append($tracking_status)
209
+ ;
210
+
211
+ if ($trackings = $tracking_result->getAllTrackings()) return $trackings[0];
212
+ return false;
213
+ }
214
+
215
+
216
+ /***************************************************************************************************************************/
217
+
218
+ protected function _process(&$process) {
219
+ $store = Mage::app()->getStore($process['data']['store.id']);
220
+ $mage_config = Mage::getConfig();
221
+ $timestamp = time();
222
+ $customer_group_id = Mage::getSingleton('customer/session')->getCustomerGroupId();
223
+ // Pour les commandes depuis Adminhtml
224
+ if ($customer_group_id==0) {
225
+ $customer_group_id2 = Mage::getSingleton('adminhtml/session_quote')->getQuote()->getCustomerGroupId();
226
+ if (isset($customer_group_id2)) $customer_group_id = $customer_group_id2;
227
+ }
228
+
229
+ $customer_group_code = Mage::getSingleton('customer/group')->load($customer_group_id)->getData('customer_group_code');
230
+ $process['data'] = array_merge($process['data'],array(
231
+ 'customer.group.id' => $customer_group_id,
232
+ 'customer.group.code' => $customer_group_code,
233
+ 'destination.country.name' => $this->__getCountryName($process['data']['destination.country.code']),
234
+ 'origin.country.name' => $this->__getCountryName($process['data']['origin.country.code']),
235
+ 'cart.weight.unit' => Mage::getStoreConfig('chronorelais/shipping/weight_unit'),
236
+ 'store.code' => $store->getCode(),
237
+ 'store.name' => $store->getConfig('general/store_information/name'),
238
+ 'store.address' => $store->getConfig('general/store_information/address'),
239
+ 'store.phone' => $store->getConfig('general/store_information/phone'),
240
+ 'date.timestamp' => $timestamp,
241
+ 'date.year' => (int)date('Y',$timestamp),
242
+ 'date.month' => (int)date('m',$timestamp),
243
+ 'date.day' => (int)date('d',$timestamp),
244
+ 'date.hour' => (int)date('H',$timestamp),
245
+ 'date.minute' => (int)date('i',$timestamp),
246
+ 'date.second' => (int)date('s',$timestamp),
247
+ 'module.version' => (string)$mage_config->getNode('modules/Chronopost_Chronorelais/version'),
248
+ ));
249
+
250
+ foreach ($process['cart.items'] as $id => $item) {
251
+ if ($item->getProduct()->getTypeId()!='configurable') {
252
+ $parent_item_id = $item->getParentItemId();
253
+ $process['products'][] = new OCS_Magento_Product($item, isset($process['cart.items'][$parent_item_id]) ? $process['cart.items'][$parent_item_id] : null);
254
+ }
255
+ }
256
+
257
+ if (!$process['data']['free_shipping']) {
258
+ foreach ($process['cart.items'] as $item) {
259
+ if ($item->getProduct() instanceof Mage_Catalog_Model_Product) {
260
+ if ($item->getFreeShipping()) $process['data']['free_shipping'] = true;
261
+ else {
262
+ $process['data']['free_shipping'] = false;
263
+ break;
264
+ }
265
+ }
266
+ }
267
+ }
268
+
269
+ $process['data']['cart.price_including_tax'] = $this->__getCartTaxAmount($process)+$process['data']['cart.price_excluding_tax'];
270
+ $process['stop_to_first_match'] = $this->__getConfigData('stop_to_first_match');
271
+ $process['config'] = $this->_getConfig();
272
+ $compression = $this->__getConfigData('auto_compression');
273
+ if ($compression=='compress') {
274
+ Mage::getConfig()->saveConfig('carriers/'.$this->_code.'/config',$this->_helper->formatConfig(true));
275
+ } else if ($compression=='uncompress') {
276
+ Mage::getConfig()->saveConfig('carriers/'.$this->_code.'/config',$this->_helper->formatConfig(false));
277
+ }
278
+
279
+ $this->_helper->debug = (int)(isset($_GET['debug']) ? $_GET['debug'] : $this->__getConfigData('debug'));
280
+ $http_request = Mage::app()->getFrontController()->getRequest();
281
+ $this->_helper->debug = $this->_helper->debug && $http_request->getRouteName()=='checkout' && $http_request->getControllerName()=='cart';
282
+ if ($this->_helper->debug) $this->_helper->setDebugHeader($process);
283
+
284
+ $value_found = false;
285
+ $process_continue = true;
286
+
287
+ //Set error messages if not any matching
288
+ $errorMsg = '';
289
+ $defaultErrorMsg = Mage::helper('shipping')->__('The shipping module is not available.');
290
+ $configErrorMsg = $this->__getConfigData('specificerrmsg');
291
+ $configErrorMsg = ($configErrorMsg ? $configErrorMsg : $defaultErrorMsg);
292
+ $freeShippingEnable = $this->__getConfigData('free_shipping_enable');
293
+ $freeShippingSubtotal = $this->__getConfigData('free_shipping_subtotal');
294
+ $applicationFee = $this->__getConfigData('application_fee');
295
+ $handlingFee = $this->__getConfigData('handling_fee');
296
+
297
+ /* Check weight limit with cart weight*/
298
+ $weight_limit = $this->__getConfigData('weight_limit');
299
+ if($process['data']['cart.weight']>$weight_limit) {
300
+ $value_found = false;
301
+ $process_continue = false;
302
+ }
303
+
304
+ if($process_continue) {
305
+ foreach ($process['config'] as $row) {
306
+ $result = $this->_helper->processRow($process,$row);
307
+ $this->_addMessages($this->_helper->getMessages());
308
+ if ($result->success) {
309
+ $value_found = true;
310
+ $fees = $result->result;
311
+ if($applicationFee) { $fees += $applicationFee; }
312
+ if($handlingFee) { $fees += $handlingFee; }
313
+ if($freeShippingEnable && ($freeShippingSubtotal<=$process['data']['cart.price_excluding_tax'])) {
314
+ $fees = 0;
315
+ }
316
+ $this->__appendMethod($process,$row,$fees);
317
+ if ($process['stop_to_first_match']) break;
318
+ }
319
+ }
320
+ }
321
+ $this->_helper->printDebug();
322
+
323
+ $this->_appendErrors($process,$this->_messages);
324
+ if (!$value_found) $this->__appendError($process,$this->__($configErrorMsg));
325
+ }
326
+
327
+ protected function _getConfig() {
328
+ if (!isset($this->_config)) {
329
+ $this->_helper = new ChronorelaisShippingHelper($this->__getConfigData('config'));
330
+ $this->_config = $this->_helper->getConfig();
331
+ $this->_addMessages($this->_helper->getMessages());
332
+ }
333
+ return $this->_config;
334
+ }
335
+
336
+ protected function _getMethodText($process, $row, $property) {
337
+ if (!isset($row[$property])) return '';
338
+
339
+ $output = '';
340
+ /*$i = 0;
341
+ foreach ($process['request']->_data as $key => $data) {
342
+ if ($i>12) $output .= $key.' => '.$data.'<br/>';
343
+ $i++;
344
+ }*/
345
+
346
+ return $output . ' '.$this->_helper->evalInput($process,$row,$property,str_replace(
347
+ array('{cart.weight}','{cart.price_including_tax}','{cart.price_excluding_tax}'),
348
+ array(
349
+ $process['data']['cart.weight'].$process['data']['cart.weight.unit'],
350
+ $this->__formatPrice($process['data']['cart.price_including_tax']),
351
+ $this->__formatPrice($process['data']['cart.price_excluding_tax'])
352
+ ),
353
+ $this->_helper->getRowProperty($row,$property)
354
+ ));
355
+ }
356
+
357
+ protected function _addMessages($messages) {
358
+ if (!is_array($messages)) $messages = array($messages);
359
+ if (!is_array($this->_messages)) $this->_messages = $messages;
360
+ else $this->_messages = array_merge($this->_messages,$messages);
361
+ }
362
+
363
+ protected function _appendErrors(&$process, $messages) {
364
+ if (is_array($messages)) {
365
+ foreach ($messages as $message) {
366
+ $this->__appendError($process,$this->__($message));
367
+ }
368
+ }
369
+ }
370
+
371
+ /***************************************************************************************************************************/
372
+
373
+ protected function __getConfigData($key) {
374
+ return $this->getConfigData($key);
375
+ }
376
+
377
+ protected function __appendMethod(&$process, $row, $fees) {
378
+ $method = Mage::getModel('shipping/rate_result_method')
379
+ ->setCarrier($this->_code)
380
+ ->setCarrierTitle($this->__getConfigData('title'))
381
+ ->setMethod($row['*code'])
382
+ ->setMethodTitle($this->_getMethodText($process,$row,'label'))
383
+ ->setMethodDescription($this->_getMethodText($process,$row,'description'))
384
+ ->setMethodLogo($this->__getConfigData('logo_url'))
385
+ ->setPrice($fees)
386
+ ->setCost($fees)
387
+ ;
388
+ $process['result']->append($method);
389
+ }
390
+
391
+ protected function __appendError(&$process, $message) {
392
+ if (isset($process['result'])) {
393
+ $error = Mage::getModel('shipping/rate_result_error')
394
+ ->setCarrier($this->_code)
395
+ ->setCarrierTitle($this->__getConfigData('title'))
396
+ ->setErrorMessage($message)
397
+ ;
398
+ $process['result']->append($error);
399
+ }
400
+ }
401
+
402
+ protected function __formatPrice($price) {
403
+ if (!isset($this->_core_helper)) $this->_core_helper = Mage::helper('core');
404
+ return $this->_core_helper->currency($price);
405
+ }
406
+
407
+ protected function __($message) {
408
+ $args = func_get_args();
409
+ $message = array_shift($args);
410
+ if ($message instanceof OCS_Message) {
411
+ $args = $message->args;
412
+ $message = $message->message;
413
+ }
414
+
415
+ $output = Mage::helper('shipping')->__($message);
416
+ if (count($args)==0) return $output;
417
+
418
+ if (!isset($this->_translate_inline)) $this->_translate_inline = Mage::getSingleton('core/translate')->getTranslateInline();
419
+ if ($this->_translate_inline) {
420
+ $parts = explode('}}{{',$output);
421
+ $parts[0] = vsprintf($parts[0],$args);
422
+ return implode('}}{{',$parts);
423
+ }
424
+ else return vsprintf($output,$args);
425
+ }
426
+
427
+ protected function __getCountryName($country_code) {
428
+ return Mage::getModel('directory/country')->load($country_code)->getName();
429
+ //return Mage::app()->getLocale()->getCountryTranslation($country_code);
430
+ /*if (!isset($this->_countries)) {
431
+ // deprecated
432
+ //$this->_countries = Mage::getModel('core/locale')->getLocale()->getCountryTranslationList();
433
+ $this->_countries = Mage::getModel('core/locale')->getLocale()->getTranslationList('territory',null,2);
434
+ }
435
+ return isset($this->_countries[$country_code]) ? $this->_countries[$country_code] : $country_code;*/
436
+ }
437
+
438
+ /*
439
+ protected function __getCartTaxAmount($process) {
440
+ $tax_amount = 0;
441
+
442
+ foreach ($process['cart.items'] as $item) {
443
+ $tax_class_id = $item->getProduct()->getTaxClassId();
444
+ $request = Mage::getSingleton('tax/calculation')->getRateRequest();
445
+ $request->setProductClassId($tax_class_id);
446
+ $vat_rate = Mage::getSingleton('tax/calculation')->getRate($request);
447
+ $vat_rate = isset($rates[$tax_class_id]) ? $rates[$tax_class_id] : 0;
448
+
449
+ if ($vat_rate > 0) $vat_to_add = $item->getData('row_total_with_discount')*$vat_rate/100;
450
+ else $vat_to_add = $item->getData('tax_amount');
451
+ //echo $item->getProduct()->getName().', '.$item->getData('row_total_with_discount').', '.$vat_rate.', '.$vat_to_add.'<br />';
452
+ $tax_amount += $vat_to_add;
453
+ }
454
+ //echo 'tax:'.$tax_amount.'<br />';
455
+ return $tax_amount;
456
+ }
457
+ */
458
+
459
+ protected function __getCartTaxAmount($process) {
460
+ $tax_amount = 0;
461
+ foreach ($process['cart.items'] as $item) {
462
+ $tax_amount += $item->getData('tax_amount');
463
+ }
464
+ return $tax_amount;
465
+ }
466
+ }
467
+
468
+ ?>
app/code/community/Chronopost/Chronorelais/Model/Carrier/Chronoexpress.php ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
1
+ <?php
2
+ class Chronopost_Chronorelais_Model_Carrier_Chronoexpress extends Chronopost_Chronorelais_Model_Carrier_AbstractChronorelaisShipping
3
+ {
4
+ protected $_code = 'chronoexpress';
5
+
6
+ }
app/code/community/Chronopost/Chronorelais/Model/Carrier/Chronopost.php ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
1
+ <?php
2
+ class Chronopost_Chronorelais_Model_Carrier_Chronopost extends Chronopost_Chronorelais_Model_Carrier_AbstractChronorelaisShipping
3
+ {
4
+ protected $_code = 'chronopost';
5
+
6
+ }
app/code/community/Chronopost/Chronorelais/Model/Carrier/Chronorelais.php ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
1
+ <?php
2
+ class Chronopost_Chronorelais_Model_Carrier_Chronorelais extends Chronopost_Chronorelais_Model_Carrier_AbstractChronorelaisShipping
3
+ {
4
+ protected $_code = 'chronorelais';
5
+
6
+ }
app/code/community/Chronopost/Chronorelais/Model/Config/Source/Civility.php ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class Chronopost_Chronorelais_Model_Config_Source_Civility
3
+ {
4
+ public function toOptionArray()
5
+ {
6
+ return array(
7
+ array('value'=>'E', 'label'=>Mage::helper('chronorelais')->__('Madame')),
8
+ array('value'=>'L', 'label'=>Mage::helper('chronorelais')->__('Mademoiselle')),
9
+ array('value'=>'M', 'label'=>Mage::helper('chronorelais')->__('Monsieur'))
10
+ );
11
+ }
12
+ }
app/code/community/Chronopost/Chronorelais/Model/Config/Source/EndOfLineCharacter.php ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class Chronopost_Chronorelais_Model_Config_Source_EndOfLineCharacter
3
+ {
4
+ public function toOptionArray()
5
+ {
6
+ return array(
7
+ array('value'=>'lf', 'label'=>Mage::helper('chronorelais')->__('LF')),
8
+ array('value'=>'cr', 'label'=>Mage::helper('chronorelais')->__('CR')),
9
+ array('value'=>'crlf', 'label'=>Mage::helper('chronorelais')->__('CR+LF'))
10
+ );
11
+ }
12
+ }
app/code/community/Chronopost/Chronorelais/Model/Config/Source/FieldDelimiter.php ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class Chronopost_Chronorelais_Model_Config_Source_FieldDelimiter
3
+ {
4
+ public function toOptionArray()
5
+ {
6
+ return array(
7
+ array('value'=>'none', 'label'=>Mage::helper('chronorelais')->__('None')),
8
+ array('value'=>'simple_quote', 'label'=>Mage::helper('chronorelais')->__('Simple Quote')),
9
+ array('value'=>'double_quotes', 'label'=>Mage::helper('chronorelais')->__('Double Quotes'))
10
+ );
11
+ }
12
+ }
app/code/community/Chronopost/Chronorelais/Model/Config/Source/FieldSeparator.php ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class Chronopost_Chronorelais_Model_Config_Source_FieldSeparator
3
+ {
4
+ public function toOptionArray()
5
+ {
6
+ return array(
7
+ array('value'=>';', 'label'=>Mage::helper('chronorelais')->__('Semicolon')),
8
+ array('value'=>',', 'label'=>Mage::helper('chronorelais')->__('Comma'))
9
+ );
10
+ }
11
+ }
app/code/community/Chronopost/Chronorelais/Model/Config/Source/FileCharset.php ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class Chronopost_Chronorelais_Model_Config_Source_FileCharset
3
+ {
4
+ public function toOptionArray()
5
+ {
6
+ return array(
7
+ array('value'=>'ISO-8859-1', 'label'=>Mage::helper('chronorelais')->__('ISO-8859-1')),
8
+ array('value'=>'UTF-8', 'label'=>Mage::helper('chronorelais')->__('UTF-8')),
9
+ array('value'=>'ASCII-7', 'label'=>Mage::helper('chronorelais')->__('ASCII-7 Bits'))
10
+ );
11
+ }
12
+ }
app/code/community/Chronopost/Chronorelais/Model/Config/Source/FileExtension.php ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class Chronopost_Chronorelais_Model_Config_Source_FileExtension
3
+ {
4
+ public function toOptionArray()
5
+ {
6
+ return array(
7
+ array('value'=>'.txt', 'label'=>Mage::helper('chronorelais')->__('.txt')),
8
+ array('value'=>'.csv', 'label'=>Mage::helper('chronorelais')->__('.csv')),
9
+ array('value'=>'.chr', 'label'=>Mage::helper('chronorelais')->__('.chr'))
10
+ );
11
+ }
12
+ }
app/code/community/Chronopost/Chronorelais/Model/Config/Source/PrintMode.php ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class Chronopost_Chronorelais_Model_Config_Source_PrintMode
3
+ {
4
+ public function toOptionArray()
5
+ {
6
+ return array(
7
+ array('value'=>'PDF', 'label'=>Mage::helper('chronorelais')->__('Print PDF Laser with proof')),
8
+ array('value'=>'SPD', 'label'=>Mage::helper('chronorelais')->__('Print PDF laser without proof')),
9
+ array('value'=>'THE', 'label'=>Mage::helper('chronorelais')->__('Print PDF thermal'))
10
+ );
11
+ }
12
+ }
app/code/community/Chronopost/Chronorelais/Model/Sales/Quote/Address/Total/Shipping.php ADDED
@@ -0,0 +1,207 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Magento
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Open Software License (OSL 3.0)
8
+ * that is bundled with this package in the file LICENSE.txt.
9
+ * It is also available through the world-wide-web at this URL:
10
+ * http://opensource.org/licenses/osl-3.0.php
11
+ * If you did not receive a copy of the license and are unable to
12
+ * obtain it through the world-wide-web, please send an email
13
+ * to license@magentocommerce.com so we can send you a copy immediately.
14
+ *
15
+ * DISCLAIMER
16
+ *
17
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
18
+ * versions in the future. If you wish to customize Magento for your
19
+ * needs please refer to http://www.magentocommerce.com for more information.
20
+ *
21
+ * @category Mage
22
+ * @package Mage_Sales
23
+ * @copyright Copyright (c) 2010 Magento Inc. (http://www.magentocommerce.com)
24
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
25
+ */
26
+
27
+
28
+ class Chronopost_Chronorelais_Model_Sales_Quote_Address_Total_Shipping extends Mage_Sales_Model_Quote_Address_Total_Abstract
29
+ {
30
+ public function __construct()
31
+ {
32
+ $this->setCode('shipping');
33
+ }
34
+
35
+ /**
36
+ * Collect totals information about shipping
37
+ *
38
+ * @param Mage_Sales_Model_Quote_Address $address
39
+ * @return Mage_Sales_Model_Quote_Address_Total_Shipping
40
+ */
41
+ public function collect(Mage_Sales_Model_Quote_Address $address)
42
+ {
43
+ parent::collect($address);
44
+
45
+ $oldWeight = $address->getWeight();
46
+ $address->setWeight(0);
47
+ $address->setFreeMethodWeight(0);
48
+ $this->_setAmount(0)
49
+ ->_setBaseAmount(0);
50
+
51
+ $items = $this->_getAddressItems($address);
52
+ if (!count($items)) {
53
+ return $this;
54
+ }
55
+
56
+ $method = $address->getShippingMethod();
57
+ $freeAddress= $address->getFreeShipping();
58
+
59
+ $addressWeight = $address->getWeight();
60
+ $freeMethodWeight = $address->getFreeMethodWeight();
61
+
62
+ $addressQty = 0;
63
+
64
+ foreach ($items as $item) {
65
+ /**
66
+ * Skip if this item is virtual
67
+ */
68
+ if ($item->getProduct()->isVirtual()) {
69
+ continue;
70
+ }
71
+
72
+ /**
73
+ * Children weight we calculate for parent
74
+ */
75
+ if ($item->getParentItem()) {
76
+ continue;
77
+ }
78
+
79
+ if ($item->getHasChildren() && $item->isShipSeparately()) {
80
+ foreach ($item->getChildren() as $child) {
81
+ if ($child->getProduct()->isVirtual()) {
82
+ continue;
83
+ }
84
+ $addressQty += $child->getTotalQty();
85
+
86
+ if (!$item->getProduct()->getWeightType()) {
87
+ $itemWeight = $child->getWeight();
88
+ $itemQty = $child->getTotalQty();
89
+ $rowWeight = $itemWeight*$itemQty;
90
+ $addressWeight += $rowWeight;
91
+ if ($freeAddress || $child->getFreeShipping()===true) {
92
+ $rowWeight = 0;
93
+ } elseif (is_numeric($child->getFreeShipping())) {
94
+ $freeQty = $child->getFreeShipping();
95
+ if ($itemQty>$freeQty) {
96
+ $rowWeight = $itemWeight*($itemQty-$freeQty);
97
+ }
98
+ else {
99
+ $rowWeight = 0;
100
+ }
101
+ }
102
+ $freeMethodWeight += $rowWeight;
103
+ $item->setRowWeight($rowWeight);
104
+ }
105
+ }
106
+ if ($item->getProduct()->getWeightType()) {
107
+ $itemWeight = $item->getWeight();
108
+ $rowWeight = $itemWeight*$item->getQty();
109
+ $addressWeight+= $rowWeight;
110
+ if ($freeAddress || $item->getFreeShipping()===true) {
111
+ $rowWeight = 0;
112
+ } elseif (is_numeric($item->getFreeShipping())) {
113
+ $freeQty = $item->getFreeShipping();
114
+ if ($item->getQty()>$freeQty) {
115
+ $rowWeight = $itemWeight*($item->getQty()-$freeQty);
116
+ }
117
+ else {
118
+ $rowWeight = 0;
119
+ }
120
+ }
121
+ $freeMethodWeight+= $rowWeight;
122
+ $item->setRowWeight($rowWeight);
123
+ }
124
+ }
125
+ else {
126
+ if (!$item->getProduct()->isVirtual()) {
127
+ $addressQty += $item->getQty();
128
+ }
129
+ $itemWeight = $item->getWeight();
130
+ $rowWeight = $itemWeight*$item->getQty();
131
+ $addressWeight+= $rowWeight;
132
+ if ($freeAddress || $item->getFreeShipping()===true) {
133
+ $rowWeight = 0;
134
+ } elseif (is_numeric($item->getFreeShipping())) {
135
+ $freeQty = $item->getFreeShipping();
136
+ if ($item->getQty()>$freeQty) {
137
+ $rowWeight = $itemWeight*($item->getQty()-$freeQty);
138
+ }
139
+ else {
140
+ $rowWeight = 0;
141
+ }
142
+ }
143
+ $freeMethodWeight+= $rowWeight;
144
+ $item->setRowWeight($rowWeight);
145
+ }
146
+ }
147
+
148
+ if (isset($addressQty)) {
149
+ $address->setItemQty($addressQty);
150
+ }
151
+
152
+ $address->setWeight($addressWeight);
153
+ $address->setFreeMethodWeight($freeMethodWeight);
154
+
155
+ $address->collectShippingRates();
156
+
157
+ $this->_setAmount(0)
158
+ ->_setBaseAmount(0);
159
+
160
+ $method = $address->getShippingMethod();
161
+
162
+ if ($method) {
163
+ foreach ($address->getAllShippingRates() as $rate) {
164
+ if ($rate->getCode()==$method) {
165
+ $amountPrice = $address->getQuote()->getStore()->convertPrice($rate->getPrice(), false);
166
+ $this->_setAmount($amountPrice);
167
+ $this->_setBaseAmount($rate->getPrice());
168
+ if(!$address->getShippingDescription()) {
169
+ $address->setShippingDescription($rate->getCarrierTitle().' - '.$rate->getMethodTitle());
170
+ }
171
+ break;
172
+ }
173
+ }
174
+ }
175
+
176
+ return $this;
177
+ }
178
+
179
+ /**
180
+ * Add shipping totals information to address object
181
+ *
182
+ * @param Mage_Sales_Model_Quote_Address $address
183
+ * @return Mage_Sales_Model_Quote_Address_Total_Shipping
184
+ */
185
+ public function fetch(Mage_Sales_Model_Quote_Address $address)
186
+ {
187
+ $amount = $address->getShippingAmount();
188
+ if ($amount!=0 || $address->getShippingDescription()) {
189
+ $address->addTotal(array(
190
+ 'code'=>$this->getCode(),
191
+ 'title'=>Mage::helper('sales')->__('Shipping & Handling').' ('.$address->getShippingDescription().')',
192
+ 'value'=>$address->getShippingAmount()
193
+ ));
194
+ }
195
+ return $this;
196
+ }
197
+
198
+ /**
199
+ * Get Shipping label
200
+ *
201
+ * @return string
202
+ */
203
+ public function getLabel()
204
+ {
205
+ return Mage::helper('sales')->__('Shipping');
206
+ }
207
+ }
app/code/community/Chronopost/Chronorelais/controllers/AjaxController.php ADDED
@@ -0,0 +1,409 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Magento Chronopost Chronorelais 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 Chronopost
17
+ * @package Chronopost_Chronorelais
18
+ * @copyright Copyright (c) 2008-10
19
+ * @author Sundar
20
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
21
+ */
22
+
23
+ class Chronopost_Chronorelais_AjaxController extends Chronopost_Chronorelais_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',"ocseditor.insertAtCaret(this,'{destination.country.name}');")
44
+ .$this->button('Cart weight',"ocseditor.insertAtCaret(this,'{cart.weight}');")
45
+ .$this->button('Cart quantity',"ocseditor.insertAtCaret(this,'{cart.quantity}');")
46
+ .$this->button('Price including tax',"ocseditor.insertAtCaret(this,'{cart.price_including_tax}');")
47
+ .$this->button('Price excluding tax',"ocseditor.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',"ocseditor.insertAtCaret(this,'{cart.weight}');")
56
+ .$this->button('Products quantity',"ocseditor.insertAtCaret(this,'{cart.quantity}');")
57
+ .$this->button('Price including tax',"ocseditor.insertAtCaret(this,'{cart.price_including_tax}');")
58
+ .$this->button('Price excluding tax',"ocseditor.insertAtCaret(this,'{cart.price_excluding_tax}');")
59
+ ."</p>"
60
+ ."<p><span class=\"buttons-set-label\">".$this->__('Selection')."</span>"
61
+ .$this->button('Weight',"ocseditor.insertAtCaret(this,'{selection.weight}');")
62
+ .$this->button('Products quantity',"ocseditor.insertAtCaret(this,'{selection.quantity}');")
63
+ ."</p>"
64
+ ."<p><span class=\"buttons-set-label\">".$this->__('Product')."</span>"
65
+ .$this->button('Weight',"ocseditor.insertAtCaret(this,'{product.weight}');")
66
+ .$this->button('Quantity',"ocseditor.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',"ocseditor.insertAtCaret(this,'{cart.weight}');")
75
+ .$this->button('Products quantity',"ocseditor.insertAtCaret(this,'{cart.quantity}');")
76
+ .$this->button('Price including tax',"ocseditor.insertAtCaret(this,'{cart.price_including_tax}');")
77
+ .$this->button('Price excluding tax',"ocseditor.insertAtCaret(this,'{cart.price_excluding_tax}');")
78
+ ."</p>"
79
+ ."</fieldset>";
80
+ break;
81
+ case 'customer_groups':
82
+ return "<textarea id=\"".$prefix."\" class=\"field\">".$value."</textarea>"
83
+ ."<fieldset class=\"buttons-set\"><legend>".$this->__('Insert')."</legend>"
84
+ ."<p>"
85
+ .$this->button('Not logged in',"ocseditor.insertAtCaret(this,'NOT LOGGED IN');")
86
+ ."</p>"
87
+ ."</fieldset>";
88
+ break;
89
+ case 'tracking_url':
90
+ return "<textarea id=\"".$prefix."\" class=\"field\">".$value."</textarea>"
91
+ ."<fieldset class=\"buttons-set\"><legend>".$this->__('Insert')."</legend>"
92
+ ."<p>"
93
+ .$this->button('Tracking number',"ocseditor.insertAtCaret(this,'{tracking_number}');")
94
+ ."</p>"
95
+ ."</fieldset>";
96
+ break;
97
+ case 'destination':
98
+ case 'origin':
99
+ $parsed_value = $this->parseAddressFilter($value);
100
+ $excluding = $parsed_value['excluding'];
101
+ return "<div class=\"address-filters-property\"><p>"
102
+ ."<input type=\"radio\" class=\"excluding\" id=\"".$prefix."-exluding-0\" name=\"".$prefix."-exluding\""
103
+ ." value=\"0\"".(!$excluding ? " checked=\"checked\"" : '')." onclick=\"ocseditor.updateCountries(this);\"/>"
104
+ ."<label for=\"".$prefix."-exluding-0\"> ".$this->__('Limit to')."</label> &nbsp; "
105
+ ."<input type=\"radio\" class=\"excluding\" id=\"".$prefix."-exluding-1\" name=\"".$prefix."-exluding\""
106
+ ." value=\"1\"".($excluding ? " checked=\"checked\"" : '')." onclick=\"ocseditor.updateCountries(this);\"/>"
107
+ ."<label for=\"".$prefix."-exluding-1\"> ".$this->__('Exclude')."</label></p>"
108
+ ."<textarea id=\"".$prefix."\" class=\"field\">".$value."</textarea>"
109
+ ."<fieldset class=\"buttons-set\"><legend>".$this->__('Display')."</legend>"
110
+ ."<p>"
111
+ .$this->button('Display original input',"ocseditor.displayCountry('original-value',this,false);")
112
+ .$this->button('Display corrected names',"ocseditor.displayCountry('full-value',this,false);")
113
+ .$this->button('Display codes',"ocseditor.displayCountry('compact-value',this,true);")
114
+ ."</p>"
115
+ ."</fieldset>"
116
+ ."<fieldset class=\"buttons-set\"><legend>".$this->__('Preview')."</legend>"
117
+ ."<div class=\"address-filter-list\">".$this->getAddressFilters($parsed_value)."</div>"
118
+ ."</fieldset>"
119
+ ."</div>"
120
+ ;
121
+ break;
122
+ case '*comment' :
123
+ $lines = explode("\n",trim($value));
124
+ for ($i=0; $i<count($lines); $i++) {
125
+ $lines[$i] = preg_replace('/^# ?/','',$lines[$i]);
126
+ }
127
+ $value = implode("\n",$lines);
128
+ return "<textarea id=\"".$prefix."\" class=\"field\">".$value."</textarea>";
129
+ default :
130
+ return "<textarea id=\"".$prefix."\" class=\"field\">".$value."</textarea>";
131
+ }
132
+ }
133
+
134
+ private function getAddressFilters($data) {
135
+ $address_filters = array();
136
+ foreach ($data['countries'] as $country) {
137
+ $address_filters[] = new AddressFilter($country);
138
+ }
139
+ return implode('',$address_filters);
140
+ }
141
+
142
+ private function parseAddressFilter($address_filter) {
143
+ $output = array(
144
+ 'excluding' => false,
145
+ 'countries' => array(),
146
+ 'original' => $address_filter,
147
+ );
148
+
149
+ $address_filter = str_replace(array("\r\n","\r","\n"),array(',',',',','),$address_filter);
150
+
151
+ if (preg_match('# *\* *- *\((.*)\) *#s',$address_filter,$result)) {
152
+ $address_filter = $result[1];
153
+ $output['excluding'] = true;
154
+ }
155
+
156
+ $tmp_address_filter_array = explode(',',trim($address_filter));
157
+
158
+ $concat = false;
159
+ $concatened = '';
160
+ $address_filter_array = array();
161
+ $i = 0;
162
+
163
+ foreach ($tmp_address_filter_array as $address_filter) {
164
+ if ($concat) $concatened .= ','.$address_filter;
165
+ else {
166
+ if ($i<count($tmp_address_filter_array)-1 && preg_match('#\(#',$address_filter)) {
167
+ $concat = true;
168
+ $concatened .= $address_filter;
169
+ } else $address_filter_array[] = $address_filter;
170
+ }
171
+ if (preg_match('#\)#',$address_filter)) {
172
+ $address_filter_array[] = $concatened;
173
+ $concatened = '';
174
+ $concat = false;
175
+ }
176
+ $i++;
177
+ }
178
+
179
+ foreach ($address_filter_array as $address_filter) {
180
+ $address_filter = trim($address_filter);
181
+ if (trim($address_filter)!='') {
182
+ if (preg_match('# *([^,(]+) *(-)? *(?:\( *(-)? *(.*)\))? *#s',$address_filter,$result)) {
183
+ $country_code = $result[1];
184
+
185
+ $region_codes = explode(',',$result[4]);
186
+ $in_array = false;
187
+ for ($i=count($region_codes); --$i>=0;) {
188
+ $code = trim($region_codes[$i]);
189
+ $region_codes[$i] = $code;
190
+ }
191
+ /*$in_array = in_array($address['region_code'],$region_codes,true) || in_array($address['postcode'],$region_codes,true);*/
192
+ $excluding_region = $result[2]=='-' || $result[3]=='-';
193
+ $output['countries'][] = array(
194
+ 'excluding' => $excluding_region,
195
+ 'country_code' => $country_code,
196
+ 'region_codes' => implode(',',$region_codes),
197
+ 'original' => $address_filter,
198
+ );
199
+ } else {
200
+ $output['countries'][] = array(
201
+ 'excluding' => null,
202
+ 'country_code' => $address_filter,
203
+ 'region_codes' => null,
204
+ 'original' => $address_filter,
205
+ );
206
+ }
207
+ }
208
+ }
209
+ return $output;
210
+ }
211
+
212
+ private function getRowUI($row, $selected) {
213
+ $row['_ID_']['value'] = isset($row['_ID_']['value']) ? $row['_ID_']['value'] : uniqid('c');
214
+ $row_id = $row['_ID_']['value'];
215
+
216
+ if (isset($row['lines'])) {
217
+ $output = "<div id=\"r-".$row_id."-container\" class=\"row-container has-error ignored-lines".($selected ? ' selected' : '')."\">"
218
+ ."<div class=\"row-header\" onclick=\"ocseditor.selectRow('".$row_id."');\">"
219
+ ."<div class=\"row-actions\">"
220
+ .$this->button('Apply changes',"ocseditor.applyChanges();")
221
+ .$this->button('Delete',"ocseditor.removeRow(this);",'delete')
222
+ ."</div>"
223
+ ."<div class=\"row-title\">".$this->__('Ignored lines')."</div></div>"
224
+ ."<div class=\"properties-container\"><textarea class=\"field\">".$row['lines']."</textarea></div></div>";
225
+ return $output;
226
+ }
227
+
228
+ if (!isset($row['label'])) {
229
+ $row['label']['value'] = $this->__('New shipping method');
230
+ }
231
+
232
+ $properties = array(
233
+ 'enabled' => 'Enabled',
234
+ 'code' => 'Code',
235
+ 'label' => 'Label',
236
+ 'description' => 'Description',
237
+ 'destination' => 'Destination',
238
+ 'origin' => 'Origin',
239
+ 'conditions' => 'Conditions',
240
+ 'fees' => 'Fees',
241
+ 'customer_groups' => 'Customer groups',
242
+ 'tracking_url' => 'Tracking url',
243
+ '*comment' => 'Comment',
244
+ );
245
+
246
+ $label = $row['label']['value'];
247
+ $output = "<div id=\"r-".$row_id."-container\" class=\"row-container".($selected ? ' selected' : '')."\">"
248
+ ."<div class=\"row-header\" onclick=\"ocseditor.selectRow('".$row_id."');\">"
249
+ ."<div class=\"row-actions\">".$this->button('Delete',"ocseditor.removeRow(this);",'delete')."</div><div class=\"row-title\">".$label."</div></div>"
250
+ ."<div class=\"properties-container\">";
251
+ $list = "<ul class=\"properties-list\">";
252
+ $j = 0;
253
+ foreach ($properties as $property_key => $label) {
254
+ $cleaned_property = $this->cleanKey($property_key);
255
+ $value = isset($row[$property_key]) ? trim($row[$property_key]['value']) : '';
256
+ $list .= "<li id=\"r-".$row_id."-p-".$cleaned_property."-item\" class=\"property-item".($j==0 ? ' selected' : '')
257
+ .(empty($value) ? ' empty' : '')
258
+ ."\" onclick=\"ocseditor.selectProperty('".$row_id."','".$cleaned_property."');\">".$this->__($label)."</li>";
259
+ $output .= "<div id=\"r-".$row_id."-p-".$cleaned_property."-container\" class=\"property-container"
260
+ .($j==0 ? ' selected' : '')."\" property-name=\"".$property_key."\">"
261
+ ."<div class=\"buttons-set\" style=\"text-align:right;\">".$this->button('Help',"ocseditor.help('property.".$property_key."');",'help')."</div>"
262
+ .$this->getPropertyHelper($row_id,$property_key,$row[$property_key])."</div>";
263
+ $j++;
264
+ }
265
+ foreach ($row as $property_key => $property) {
266
+ if (!isset($properties[$property_key]) && substr($property_key,0,1)!='*') {
267
+ $label = $property_key;
268
+ $cleaned_property = $this->cleanKey($property_key);
269
+ $value = isset($row[$property_key]) ? trim($row[$property_key]['value']) : '';
270
+ $list .= "<li id=\"r-".$row_id."-p-".$cleaned_property."-item\" class=\"property-item".($j==0 ? ' selected' : '')
271
+ .(empty($value) ? ' empty' : '').($cleaned_property=='_ID_' ? ' hide' : '')
272
+ ."\" onclick=\"ocseditor.selectProperty('".$row_id."','".$cleaned_property."');\">".$this->__($label)."</li>";
273
+ $output .= "<div id=\"r-".$row_id."-p-".$cleaned_property."-container\" class=\"property-container"
274
+ .($j==0 ? ' selected' : '')."\" property-name=\"".$property_key."\">"
275
+ ."<div class=\"buttons-set\" style=\"text-align:right;\">".$this->button('Help',"ocseditor.help('property.".$property_key."');",'help')."</div>"
276
+ .$this->getPropertyHelper($row_id,$property_key,$property)."</div>";
277
+ $j++;
278
+ }
279
+ }
280
+ $output .= $list."</div></div>";
281
+ return $output;
282
+ }
283
+
284
+ private function getConfigErrors($config) {
285
+ $script = "ocseditor.resetErrors();";
286
+ foreach ($config as $row_code => $row) {
287
+ if (isset($row['*messages'])) {
288
+ $error = '';
289
+ foreach ($row['*messages'] as $message) {
290
+ $error .= "<p>".$this->__($message)."</p>";
291
+ }
292
+ if ($error!='') $script .= "ocseditor.setError('".$row['_ID_']['value']."','','".$this->jsEscape($error)."');";
293
+ }
294
+ foreach ($row as $property_key => $property) {
295
+ if (isset($property['messages'])) {
296
+ $error = '';
297
+ foreach ($property['messages'] as $message) {
298
+ $error .= "<p>".$this->__($message)."</p>";
299
+ }
300
+ if ($error!='') {
301
+ $script .= "ocseditor.setError('".$row['_ID_']['value']."','".$property_key."','"
302
+ .$this->jsEscape($error
303
+ .($property['value']!=$property['original_value'] ?
304
+ "<p>"
305
+ .$this->button('Correct',"ocseditor.correct('".$row['_ID_']['value']."','".$property_key."','".$this->jsEscape($property['value'])."');")
306
+ ."</p>" : '')
307
+ )."');";
308
+ }
309
+ }
310
+ }
311
+ }
312
+ //$script .= "alert('".str_replace(array("\r\n","\n","\'","'"),array(" "," ","\\\'","\'"),$script)."');";
313
+ return $script;
314
+ }
315
+
316
+ private function loadConfig($input) {
317
+ include_once $this->getIncludingPath('ChronorelaisShippingHelper.php');
318
+
319
+ $helper = new ChronorelaisShippingHelper($input);
320
+ $helper->checkConfig();
321
+ $config = $helper->getConfig();
322
+ //print_r($config);
323
+
324
+ $output = "<div class=\"buttons-set\">"
325
+ .$this->button('Add a shipping method',"ocseditor.addRow();",'add')
326
+ ."</div><div class=\"config-container\">";
327
+ $i = 0;
328
+ foreach ($config as &$row) {
329
+ $output .= $this->getRowUI($row,$i==0);
330
+ $i++;
331
+ }
332
+ $output .= "</div><script type=\"text/javascript\">".$this->getConfigErrors($config)."</script>";
333
+ return $output;
334
+ }
335
+
336
+ public function indexAction() {
337
+ header('Content-Type: text/html; charset=UTF-8');
338
+
339
+ include_once $this->getIncludingPath('countries.inc.php');
340
+
341
+ switch ($_POST['what']) {
342
+ case 'open':
343
+ $output = ""
344
+ // Donate page
345
+ //.$this->page('donate',"Support the development of Chronorelais Shipping extension",$this->__('{ocseditor.donate-page.content}'))
346
+ // Help page
347
+ .$this->page('help',"Chronorelais Shipping extension help",'')
348
+ // Main page
349
+ .$this->pageHeader("Chronorelais Shipping configuration editor",
350
+ $this->button('Save',"ocseditor.save();",'save')
351
+ .$this->button('Export',"ocseditor.saveToFile();",'')
352
+ .$this->button('Load',"ocseditor.showConfigLoader();",'')
353
+ .$this->button('Close',"ocseditor.close();",'cancel')
354
+ )
355
+ ."<div id=\"ocs-editor-config-loader\">"
356
+ ."<textarea></textarea>"
357
+ ."<div class=\"buttons-set\">"
358
+ .$this->button('Load',"ocseditor.loadConfig();",'')
359
+ .$this->button('Cancel',"ocseditor.hideConfigLoader();",'cancel')
360
+ ."</div>"
361
+ ."</div>"
362
+ ."<div id=\"ocs-editor-config-container\">".$this->loadConfig($_POST['input'])."</div>"
363
+ /*."<div class=\"donate-container\">"
364
+ ."<table cellspacing=\"0\"><tr>"
365
+ ."<td>".$this->__('You appreciate this extension and would like to help?')."</td>"
366
+ ."<td class=\"form-buttons\">"
367
+ .$this->button('Donate',"ocseditor.openPage('donate');",'donate')
368
+ ."</td>"
369
+ ."</tr></table>"
370
+ ."</div>"*/
371
+ ;
372
+ echo $output;
373
+ exit;
374
+ case 'help':
375
+ echo $this->__('{ocseditor.help.'.$_POST['input'].'}');
376
+ exit;
377
+ case 'add-row':
378
+ echo $this->getRowUI(array(),true);
379
+ exit;
380
+ case 'load-config':
381
+ echo $this->loadConfig($_POST['config']);
382
+ exit;
383
+ case 'check-config':
384
+ include_once $this->getIncludingPath('ChronorelaisShippingHelper.php');
385
+
386
+ $helper = new ChronorelaisShippingHelper(urldecode($_POST['config']));
387
+ $helper->checkConfig();
388
+ print_r($helper->getConfig(),$out);
389
+ //$script = "alert('".$this->jsEscape(urldecode($_POST['config']))."');";
390
+ $script = $this->getConfigErrors($helper->getConfig());
391
+ //$script = "alert('".$this->jsEscape($this->getConfigErrors($helper->getConfig()))."');";
392
+ break;
393
+ case 'save-to-file':
394
+ include_once $this->getIncludingPath('ChronorelaisShippingHelper.php');
395
+
396
+ $helper = new ChronorelaisShippingHelper(urldecode($_POST['config']));
397
+ $formatted_config = $helper->formatConfig(false);
398
+ $this->forceDownload('chronorelais-shipping-config.txt',$formatted_config);
399
+ exit;
400
+ case 'get-address-filters':
401
+ $result = $this->parseAddressFilter($_POST['input']);
402
+ echo $this->getAddressFilters($result);
403
+ exit;
404
+ }
405
+
406
+ echo "<script type=\"text/javascript\">".$script."</script>";
407
+ exit;
408
+ }
409
+ }
app/code/community/Chronopost/Chronorelais/controllers/Checkout/OnepageController.php ADDED
@@ -0,0 +1,657 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ require_once 'Mage/Checkout/controllers/OnepageController.php';
4
+ class Chronopost_Chronorelais_Checkout_OnepageController extends Mage_Checkout_OnepageController
5
+ {
6
+ protected $_sectionUpdateFunctions = array(
7
+ 'payment-method' => '_getPaymentMethodsHtml',
8
+ 'shipping-method' => '_getShippingMethodsHtml',
9
+ 'review' => '_getReviewHtml',
10
+ 'shipping-method-chronorelais' => '_getReviewHtml',
11
+ );
12
+
13
+ /**
14
+ * @return Mage_Checkout_OnepageController
15
+ */
16
+ public function preDispatch()
17
+ {
18
+ parent::preDispatch();
19
+ $this->_preDispatchValidateCustomer();
20
+ return $this;
21
+ }
22
+
23
+ protected function _ajaxRedirectResponse()
24
+ {
25
+ $this->getResponse()
26
+ ->setHeader('HTTP/1.1', '403 Session Expired')
27
+ ->setHeader('Login-Required', 'true')
28
+ ->sendResponse();
29
+ return $this;
30
+ }
31
+
32
+ /**
33
+ * Validate ajax request and redirect on failure
34
+ *
35
+ * @return bool
36
+ */
37
+ protected function _expireAjax()
38
+ {
39
+ if (!$this->getOnepage()->getQuote()->hasItems()
40
+ || $this->getOnepage()->getQuote()->getHasError()
41
+ || $this->getOnepage()->getQuote()->getIsMultiShipping()) {
42
+ $this->_ajaxRedirectResponse();
43
+ return true;
44
+ }
45
+ $action = $this->getRequest()->getActionName();
46
+ if (Mage::getSingleton('checkout/session')->getCartWasUpdated(true)
47
+ && !in_array($action, array('index', 'progress'))) {
48
+ $this->_ajaxRedirectResponse();
49
+ return true;
50
+ }
51
+
52
+ return false;
53
+ }
54
+
55
+ /**
56
+ * Get shipping method step html
57
+ *
58
+ * @return string
59
+ */
60
+ protected function _getShippingMethodsHtml()
61
+ {
62
+ $layout = $this->getLayout();
63
+ $update = $layout->getUpdate();
64
+ $update->load('checkout_onepage_shippingmethod');
65
+ $layout->generateXml();
66
+ $layout->generateBlocks();
67
+ $output = $layout->getOutput();
68
+ return $output;
69
+ }
70
+
71
+ /**
72
+ * Get payment method step html
73
+ *
74
+ * @return string
75
+ */
76
+ protected function _getPaymentMethodsHtml()
77
+ {
78
+ $layout = $this->getLayout();
79
+ $update = $layout->getUpdate();
80
+ $update->load('checkout_onepage_paymentmethod');
81
+ $layout->generateXml();
82
+ $layout->generateBlocks();
83
+ $output = $layout->getOutput();
84
+ return $output;
85
+ }
86
+
87
+ protected function _getAdditionalHtml()
88
+ {
89
+ $layout = $this->getLayout();
90
+ $update = $layout->getUpdate();
91
+ $update->load('checkout_onepage_additional');
92
+ $layout->generateXml();
93
+ $layout->generateBlocks();
94
+ $output = $layout->getOutput();
95
+ return $output;
96
+ }
97
+
98
+ /**
99
+ * Get order review step html
100
+ *
101
+ * @return string
102
+ */
103
+ protected function _getReviewHtml()
104
+ {
105
+ return $this->getLayout()->getBlock('root')->toHtml();
106
+ }
107
+
108
+ /**
109
+ * Get payment method step html
110
+ *
111
+ * @return string
112
+ */
113
+ protected function _getChronoRelaisHtml()
114
+ {
115
+ return $this->getLayout()->getBlock('root')->toHtml();
116
+ }
117
+
118
+ /**
119
+ * Get one page checkout model
120
+ *
121
+ * @return Mage_Checkout_Model_Type_Onepage
122
+ */
123
+ public function getOnepage()
124
+ {
125
+ return Mage::getSingleton('checkout/type_onepage');
126
+ }
127
+
128
+ /**
129
+ * Checkout page
130
+ */
131
+ public function indexAction()
132
+ {
133
+ if (!extension_loaded('soap')) {
134
+ if(Mage::helper('chronorelais')->getConfigData('carriers/chronopost/active') || Mage::helper('chronorelais')->getConfigData('carriers/chronorelais/active') || Mage::helper('chronorelais')->getConfigData('carriers/chronoexpress/active')) {
135
+ Mage::getSingleton('checkout/session')->addError($this->__('The SOAP extension is not installed in the server. Please contact the site administrator. Sorry for inconvenience.'));
136
+ $this->_redirect('checkout/cart');
137
+ return;
138
+ }
139
+ }
140
+ if (!Mage::helper('checkout')->canOnepageCheckout()) {
141
+ Mage::getSingleton('checkout/session')->addError($this->__('The onepage checkout is disabled.'));
142
+ $this->_redirect('checkout/cart');
143
+ return;
144
+ }
145
+ $quote = $this->getOnepage()->getQuote();
146
+ if (!$quote->hasItems() || $quote->getHasError()) {
147
+ $this->_redirect('checkout/cart');
148
+ return;
149
+ }
150
+ if (!$quote->validateMinimumAmount()) {
151
+ $error = Mage::getStoreConfig('sales/minimum_order/error_message');
152
+ Mage::getSingleton('checkout/session')->addError($error);
153
+ $this->_redirect('checkout/cart');
154
+ return;
155
+ }
156
+ Mage::getSingleton('checkout/session')->setCartWasUpdated(false);
157
+ Mage::getSingleton('customer/session')->setBeforeAuthUrl(Mage::getUrl('*/*/*', array('_secure'=>true)));
158
+ $this->getOnepage()->initCheckout();
159
+ $this->loadLayout();
160
+ $this->_initLayoutMessages('customer/session');
161
+ $this->getLayout()->getBlock('head')->setTitle($this->__('Checkout'));
162
+ $this->renderLayout();
163
+ }
164
+
165
+ /**
166
+ * Checkout status block
167
+ */
168
+ public function progressAction()
169
+ {
170
+ if ($this->_expireAjax()) {
171
+ return;
172
+ }
173
+ $this->loadLayout(false);
174
+ $this->renderLayout();
175
+ }
176
+
177
+ public function shippingMethodAction()
178
+ {
179
+ if ($this->_expireAjax()) {
180
+ return;
181
+ }
182
+ $this->loadLayout(false);
183
+ $this->renderLayout();
184
+ }
185
+
186
+ public function reviewAction()
187
+ {
188
+ if ($this->_expireAjax()) {
189
+ return;
190
+ }
191
+ $this->loadLayout(false);
192
+ $this->renderLayout();
193
+ }
194
+
195
+ /**
196
+ * Order success action
197
+ */
198
+ public function successAction()
199
+ {
200
+ $session = $this->getOnepage()->getCheckout();
201
+ if (!$session->getLastSuccessQuoteId()) {
202
+ $this->_redirect('checkout/cart');
203
+ return;
204
+ }
205
+
206
+ $lastQuoteId = $session->getLastQuoteId();
207
+ $lastOrderId = $session->getLastOrderId();
208
+ $lastRecurringProfiles = $session->getLastRecurringProfileIds();
209
+ if (!$lastQuoteId || (!$lastOrderId && empty($lastRecurringProfiles))) {
210
+ $this->_redirect('checkout/cart');
211
+ return;
212
+ }
213
+
214
+ $session->clear();
215
+ $this->loadLayout();
216
+ $this->_initLayoutMessages('checkout/session');
217
+ Mage::dispatchEvent('checkout_onepage_controller_success_action');
218
+ $this->renderLayout();
219
+ }
220
+
221
+ public function failureAction()
222
+ {
223
+ $lastQuoteId = $this->getOnepage()->getCheckout()->getLastQuoteId();
224
+ $lastOrderId = $this->getOnepage()->getCheckout()->getLastOrderId();
225
+
226
+ if (!$lastQuoteId || !$lastOrderId) {
227
+ $this->_redirect('checkout/cart');
228
+ return;
229
+ }
230
+
231
+ $this->loadLayout();
232
+ $this->renderLayout();
233
+ }
234
+
235
+
236
+ public function getAdditionalAction()
237
+ {
238
+ $this->getResponse()->setBody($this->_getAdditionalHtml());
239
+ }
240
+
241
+ /**
242
+ * Address JSON
243
+ */
244
+ public function getAddressAction()
245
+ {
246
+ if ($this->_expireAjax()) {
247
+ return;
248
+ }
249
+ $addressId = $this->getRequest()->getParam('address', false);
250
+ if ($addressId) {
251
+ $address = $this->getOnepage()->getAddress($addressId);
252
+
253
+ if (Mage::getSingleton('customer/session')->getCustomer()->getId() == $address->getCustomerId()) {
254
+ $this->getResponse()->setHeader('Content-type', 'application/x-json');
255
+ $this->getResponse()->setBody($address->toJson());
256
+ } else {
257
+ $this->getResponse()->setHeader('HTTP/1.1','403 Forbidden');
258
+ }
259
+ }
260
+ }
261
+
262
+ /**
263
+ * Save checkout method
264
+ */
265
+ public function saveMethodAction()
266
+ {
267
+ if ($this->_expireAjax()) {
268
+ return;
269
+ }
270
+ if ($this->getRequest()->isPost()) {
271
+ $method = $this->getRequest()->getPost('method');
272
+ $result = $this->getOnepage()->saveCheckoutMethod($method);
273
+ $this->getResponse()->setBody(Mage::helper('core')->jsonEncode($result));
274
+ }
275
+ }
276
+
277
+ /**
278
+ * save checkout billing address
279
+ */
280
+ public function saveBillingAction()
281
+ {
282
+ if ($this->_expireAjax()) {
283
+ return;
284
+ }
285
+ if ($this->getRequest()->isPost()) {
286
+ $postData = $this->getRequest()->getPost('billing', array());
287
+ $data = $this->_filterPostData($postData);
288
+ $customerAddressId = $this->getRequest()->getPost('billing_address_id', false);
289
+
290
+ if (isset($data['email'])) {
291
+ $data['email'] = trim($data['email']);
292
+ }
293
+ $result = $this->getOnepage()->saveBilling($data, $customerAddressId);
294
+
295
+ if (!isset($result['error'])) {
296
+ /* check quote for virtual */
297
+ if ($this->getOnepage()->getQuote()->isVirtual()) {
298
+ $result['goto_section'] = 'payment';
299
+ $result['update_section'] = array(
300
+ 'name' => 'payment-method',
301
+ 'html' => $this->_getPaymentMethodsHtml()
302
+ );
303
+ } elseif (isset($data['use_for_shipping']) && $data['use_for_shipping'] == 1) {
304
+ $result['goto_section'] = 'shipping_method';
305
+ $result['update_section'] = array(
306
+ 'name' => 'shipping-method',
307
+ 'html' => $this->_getShippingMethodsHtml()
308
+ );
309
+
310
+ $result['allow_sections'] = array('shipping');
311
+ $result['duplicateBillingInfo'] = 'true';
312
+
313
+ //WEC chronorelais
314
+ if( isset( $_SESSION["customer_shipping_address_reference"] ) ){
315
+ unset( $_SESSION["customer_shipping_address_reference"] );
316
+ }
317
+
318
+ if(!array_key_exists("compagny",$data)){ $data["compagny"]=""; }
319
+
320
+ $_SESSION["customer_shipping_address_reference"]["data"] = $data;
321
+ $_SESSION["customer_shipping_address_reference"]["customerAddressId"] = $customerAddressId;
322
+ $_SESSION["customer_shipping_address_reference"]["available"] = false;
323
+ //ENDWEC
324
+
325
+ } else {
326
+ $result['goto_section'] = 'shipping';
327
+ }
328
+ }
329
+ $this->getResponse()->setBody(Mage::helper('core')->jsonEncode($result));
330
+ }
331
+ }
332
+
333
+ /**
334
+ * Shipping address save action
335
+ */
336
+ public function saveShippingAction()
337
+ {
338
+ if ($this->_expireAjax()) {
339
+ return;
340
+ }
341
+ if ($this->getRequest()->isPost()) {
342
+ $data = $this->getRequest()->getPost('shipping', array());
343
+ $customerAddressId = $this->getRequest()->getPost('shipping_address_id', false);
344
+
345
+
346
+
347
+ $result = $this->getOnepage()->saveShipping($data, $customerAddressId);
348
+
349
+ if (!isset($result['error'])) {
350
+ $result['goto_section'] = 'shipping_method';
351
+ $result['update_section'] = array(
352
+ 'name' => 'shipping-method',
353
+ 'html' => $this->_getShippingMethodsHtml()
354
+ );
355
+ }
356
+ $this->getResponse()->setBody(Mage::helper('core')->jsonEncode($result));
357
+ }
358
+
359
+ //WEC chronorelais
360
+ if( isset( $_SESSION["customer_shipping_address_reference"] ) ){
361
+ unset( $_SESSION["customer_shipping_address_reference"] );
362
+ }
363
+ if(!array_key_exists("compagny",$data)){ $data["compagny"]=""; }
364
+ $_SESSION["customer_shipping_address_reference"]["data"] = $data;
365
+ $_SESSION["customer_shipping_address_reference"]["customerAddressId"] = $customerAddressId;
366
+ $_SESSION["customer_shipping_address_reference"]["available"] = false;
367
+
368
+ //ENDWEC
369
+ }
370
+
371
+ /**
372
+ * Shipping method save action
373
+ */
374
+ public function saveShippingMethodAction()
375
+ {
376
+ if ($this->_expireAjax()) {
377
+ return;
378
+ }
379
+
380
+ if ($this->getRequest()->isPost()) {
381
+
382
+ //WEC chronorelais
383
+ if( $_SESSION["customer_shipping_address_reference"]["available"] ){
384
+ $data = $_SESSION["customer_shipping_address_reference"]["data"];
385
+ $customerAddressId = $_SESSION["customer_shipping_address_reference"]["customerAddressId"];
386
+ $_SESSION["customer_shipping_address_reference"]["available"] = false;
387
+
388
+ $result = $this->getOnepage()->saveShipping($data, $customerAddressId);
389
+ $this->getResponse()->setBody(Mage::helper('core')->jsonEncode($result));
390
+ }
391
+
392
+ $method = $this->getRequest()->getParam('shipping_method');
393
+ $quote = Mage::getSingleton('checkout/cart')->init()->getQuote();
394
+ $address = $quote->getShippingAddress();
395
+
396
+ //if( substr($this->getRequest()->getParam('shipping_method'),0,25) == "chronorelais_chronorelais" ){
397
+ if( substr($this->getRequest()->getParam('shipping_method'),0,12) == "chronorelais" ){
398
+
399
+ $relaisId = $this->getRequest()->getParam('shipping_method_chronorelais');
400
+ if($relaisId!=""){
401
+
402
+ $client = new SoapClient("http://wsshipping.chronopost.fr/soap.point.relais/services/ServiceRechercheBt?wsdl");
403
+ $webservbt = $client->__call("rechercheBtParIdChronopostA2Pas",array($relaisId));
404
+ $relais = $webservbt[0] ;
405
+
406
+ if($relais) {
407
+ $address->setCity($relais->localite)
408
+ ->setPostcode($relais->codePostal)
409
+ ->setStreet ( trim( $relais->adresse1." ".$relais->adresse2." ".$relais->adresse3 ) )
410
+ ->setCompany ( $relais->nomEnseigne )
411
+ ->setWRelayPointCode( $relais->identifiantChronopostPointA2PAS )
412
+ ->save()
413
+ ->setCollectShippingRates(true);
414
+
415
+ $_SESSION["customer_shipping_address_reference"]["available"] = true;
416
+ }
417
+ }
418
+ }
419
+
420
+ $methodTitle = "";
421
+ if(isset($relais->localite)) {
422
+ $methodTitle = ' - '.$relais->nomEnseigne.' - '.trim( $relais->adresse1." ".$relais->adresse2." ".$relais->adresse3 ).' - '.$relais->codePostal.' - '.$relais->localite;
423
+ }
424
+ if ($method) {
425
+ foreach ($address->getAllShippingRates() as $rate) {
426
+ if ($rate->getCode()==$method) {
427
+ $address->setShippingDescription($rate->getCarrierTitle().' - '.$rate->getMethodTitle().$methodTitle);
428
+ break;
429
+ }
430
+ }
431
+ }
432
+
433
+ //ENDWEC chronorelais
434
+
435
+ $data = $this->getRequest()->getPost('shipping_method', '');
436
+
437
+ $result = $this->getOnepage()->saveShippingMethod($data);
438
+
439
+ /*
440
+ $result will have erro data if shipping method is empty
441
+ */
442
+ if(!$result) {
443
+ Mage::dispatchEvent('checkout_controller_onepage_save_shipping_method', array('request'=>$this->getRequest(), 'quote'=>$this->getOnepage()->getQuote()));
444
+ // $this->getResponse()->setBody(Mage::helper('core')->jsonEncode($result));
445
+
446
+ $result['goto_section'] = 'payment';
447
+ $result['update_section'] = array(
448
+ 'name' => 'payment-method',
449
+ 'html' => $this->_getPaymentMethodsHtml()
450
+ );
451
+ }
452
+ $this->getResponse()->setBody(Mage::helper('core')->jsonEncode($result));
453
+ }
454
+ }
455
+
456
+ /**
457
+ * Save payment ajax action
458
+ *
459
+ * Sets either redirect or a JSON response
460
+ */
461
+ public function savePaymentAction()
462
+ {
463
+ if ($this->_expireAjax()) {
464
+ return;
465
+ }
466
+ try {
467
+ if (!$this->getRequest()->isPost()) {
468
+ $this->_ajaxRedirectResponse();
469
+ return;
470
+ }
471
+
472
+ // set payment to quote
473
+ $result = array();
474
+ $data = $this->getRequest()->getPost('payment', array());
475
+ $result = $this->getOnepage()->savePayment($data);
476
+
477
+ // get section and redirect data
478
+ $redirectUrl = $this->getOnepage()->getQuote()->getPayment()->getCheckoutRedirectUrl();
479
+ if (empty($result['error']) && !$redirectUrl) {
480
+ $this->loadLayout('checkout_onepage_review');
481
+ $result['goto_section'] = 'review';
482
+ $result['update_section'] = array(
483
+ 'name' => 'review',
484
+ 'html' => $this->_getReviewHtml()
485
+ );
486
+ }
487
+ if ($redirectUrl) {
488
+ $result['redirect'] = $redirectUrl;
489
+ }
490
+ } catch (Mage_Payment_Exception $e) {
491
+ if ($e->getFields()) {
492
+ $result['fields'] = $e->getFields();
493
+ }
494
+ $result['error'] = $e->getMessage();
495
+ } catch (Mage_Core_Exception $e) {
496
+ $result['error'] = $e->getMessage();
497
+ } catch (Exception $e) {
498
+ Mage::logException($e);
499
+ $result['error'] = $this->__('Unable to set Payment Method.');
500
+ }
501
+ $this->getResponse()->setBody(Mage::helper('core')->jsonEncode($result));
502
+ }
503
+
504
+ /**
505
+ * Create order action
506
+ */
507
+ public function saveOrderAction()
508
+ {
509
+ if ($this->_expireAjax()) {
510
+ return;
511
+ }
512
+
513
+ $result = array();
514
+ try {
515
+ if ($requiredAgreements = Mage::helper('checkout')->getRequiredAgreementIds()) {
516
+ $postedAgreements = array_keys($this->getRequest()->getPost('agreement', array()));
517
+ if ($diff = array_diff($requiredAgreements, $postedAgreements)) {
518
+ $result['success'] = false;
519
+ $result['error'] = true;
520
+ $result['error_messages'] = $this->__('Please agree to all the terms and conditions before placing the order.');
521
+ $this->getResponse()->setBody(Mage::helper('core')->jsonEncode($result));
522
+ return;
523
+ }
524
+ }
525
+ if ($data = $this->getRequest()->getPost('payment', false)) {
526
+ $this->getOnepage()->getQuote()->getPayment()->importData($data);
527
+ }
528
+ $this->getOnepage()->saveOrder();
529
+ $redirectUrl = $this->getOnepage()->getCheckout()->getRedirectUrl();
530
+ $result['success'] = true;
531
+ $result['error'] = false;
532
+ } catch (Mage_Core_Exception $e) {
533
+ Mage::logException($e);
534
+ Mage::helper('checkout')->sendPaymentFailedEmail($this->getOnepage()->getQuote(), $e->getMessage());
535
+ $result['success'] = false;
536
+ $result['error'] = true;
537
+ $result['error_messages'] = $e->getMessage();
538
+
539
+ if ($gotoSection = $this->getOnepage()->getCheckout()->getGotoSection()) {
540
+ $result['goto_section'] = $gotoSection;
541
+ $this->getOnepage()->getCheckout()->setGotoSection(null);
542
+ }
543
+
544
+ if ($updateSection = $this->getOnepage()->getCheckout()->getUpdateSection()) {
545
+ if (isset($this->_sectionUpdateFunctions[$updateSection])) {
546
+ $updateSectionFunction = $this->_sectionUpdateFunctions[$updateSection];
547
+ $result['update_section'] = array(
548
+ 'name' => $updateSection,
549
+ 'html' => $this->$updateSectionFunction()
550
+ );
551
+ }
552
+ $this->getOnepage()->getCheckout()->setUpdateSection(null);
553
+ }
554
+ } catch (Exception $e) {
555
+ Mage::logException($e);
556
+ Mage::helper('checkout')->sendPaymentFailedEmail($this->getOnepage()->getQuote(), $e->getMessage());
557
+ $result['success'] = false;
558
+ $result['error'] = true;
559
+ $result['error_messages'] = $this->__('There was an error processing your order. Please contact us or try again later.');
560
+ }
561
+ $this->getOnepage()->getQuote()->save();
562
+ /**
563
+ * when there is redirect to third party, we don't want to save order yet.
564
+ * we will save the order in return action.
565
+ */
566
+ if (isset($redirectUrl)) {
567
+ $result['redirect'] = $redirectUrl;
568
+ }
569
+
570
+ $this->getResponse()->setBody(Mage::helper('core')->jsonEncode($result));
571
+ }
572
+
573
+ /**
574
+ * Filtering posted data. Converting localized data if needed
575
+ *
576
+ * @param array
577
+ * @return array
578
+ */
579
+ protected function _filterPostData($data)
580
+ {
581
+ $data = $this->_filterDates($data, array('dob'));
582
+ return $data;
583
+ }
584
+
585
+ /**
586
+ * Get relais
587
+ */
588
+ public function getRelaisAction()
589
+ {
590
+ if ($this->_expireAjax()) {
591
+ return;
592
+ }
593
+ $result = array();
594
+ $quote = Mage::getSingleton('checkout/cart')->init()->getQuote();
595
+ $address = $quote->getShippingAddress();
596
+ $postcode = $address->getPostcode();
597
+
598
+ if (extension_loaded('soap')) {
599
+ $client = new SoapClient("http://wsshipping.chronopost.fr/soap.point.relais/services/ServiceRechercheBt?wsdl",array('trace'=> 0,'connection_timeout'=>10));
600
+ $webservbt = $client->__call("rechercheBtParCodeproduitEtCodepostalEtDate",array(0,$postcode,0));
601
+
602
+ if ($webservbt) {
603
+ $this->loadLayout('checkout_onepage_shippingchronorelais');
604
+ $result['goto_section'] = 'shipping-method';
605
+ $result['update_section'] = array(
606
+ 'name' => 'shipping-method-chronorelais',
607
+ 'html' => $this->_getChronoRelaisHtml()
608
+ );
609
+ $result['relaypoints'] = $webservbt;
610
+ } else {
611
+ $result['error'] = true;
612
+ $result['message'] = $this->__('No point relay is associated with this postcode');
613
+ }
614
+ } else {
615
+ $result['error'] = true;
616
+ $result['message'] = $this->__('Sorry for inconvenience, The SOAP extension is not installed in the server. Please contact the site administrator.');
617
+ }
618
+ $this->getResponse()->setBody(Mage::helper('core')->jsonEncode($result));
619
+ }
620
+
621
+ /**
622
+ * Change shipping postal code
623
+ */
624
+ public function changePostalCodeAction()
625
+ {
626
+ if ($this->_expireAjax()) {
627
+ return;
628
+ }
629
+ $result = array();
630
+ $webservbt = array();
631
+ $postcode = $this->getRequest()->getPost('mappostalcode');
632
+ if($postcode) {
633
+ $quote = Mage::getSingleton('checkout/cart')->init()->getQuote();
634
+ $address = $quote->getShippingAddress();
635
+ $address->setPostcode($postcode)
636
+ ->save()
637
+ ->setCollectShippingRates(true);
638
+
639
+ $client = new SoapClient("http://wsshipping.chronopost.fr/soap.point.relais/services/ServiceRechercheBt?wsdl",array('trace'=> 0,'connection_timeout'=>10));
640
+ $webservbt = $client->__call("rechercheBtParCodeproduitEtCodepostalEtDate",array(0,$postcode,0));
641
+ }
642
+ if ($webservbt) {
643
+ $this->loadLayout('checkout_onepage_shippingchronorelais');
644
+ $result['goto_section'] = 'shipping-method';
645
+ $result['update_section'] = array(
646
+ 'name' => 'shipping-method-chronorelais',
647
+ 'html' => $this->_getChronoRelaisHtml()
648
+ );
649
+ $result['relaypoints'] = $webservbt;
650
+ } else {
651
+ $result['error'] = true;
652
+ $result['message'] = $this->__('No point relay is associated with this postcode');
653
+ }
654
+ $this->getResponse()->setBody(Mage::helper('core')->jsonEncode($result));
655
+ }
656
+
657
+ }
app/code/community/Chronopost/Chronorelais/controllers/ExportController.php ADDED
@@ -0,0 +1,446 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class Chronopost_Chronorelais_ExportController extends Mage_Adminhtml_Controller_Action
3
+ {
4
+
5
+ /**
6
+ * Constructor
7
+ */
8
+ protected function _construct()
9
+ {
10
+ $this->setUsedModuleName('Chronopost_Chronorelais');
11
+ }
12
+
13
+ /**
14
+ * Main action : show orders list
15
+ */
16
+ public function indexAction()
17
+ {
18
+ $this->loadLayout()
19
+ ->_setActiveMenu('sales/chronorelais/export')
20
+ ->_addContent($this->getLayout()->createBlock('chronorelais/export_orders'))
21
+ ->renderLayout();
22
+ }
23
+
24
+ public function getValue($value)
25
+ {
26
+ return ($value!='' ? $value : '');
27
+ }
28
+
29
+ public function removeSpclChars($text)
30
+ {
31
+ return ereg_replace("[^0-9a-zA-Z]", "", $text);
32
+ }
33
+
34
+ public function massLivraisonSamediStatusAction()
35
+ {
36
+ if($this->getRequest()->getPost('status')) {
37
+ $this->saveLivraisonSamediStatusAction();
38
+ }
39
+ }
40
+
41
+ public function massExportAction()
42
+ {
43
+ if($this->getRequest()->getPost('format')=='css') {
44
+ $this->exportcssAction();
45
+ } elseif($this->getRequest()->getPost('format')=='cso') {
46
+ $this->exportcsoAction();
47
+ }
48
+ }
49
+
50
+ /**
51
+ * Export CSS Action
52
+ * Generates a CSV file to download (CSS format)
53
+ */
54
+ public function exportcssAction()
55
+ {
56
+ /* get the orders */
57
+ $orderIds = $this->getRequest()->getPost('order_ids');
58
+
59
+ /**
60
+ * Get configuration
61
+ */
62
+ $separator = Mage::helper('chronorelais')->getConfigurationFieldSeparator('css');
63
+ $delimiter = Mage::helper('chronorelais')->getConfigurationFieldDelimiter('css');
64
+
65
+ if ($delimiter == 'simple_quote') {
66
+ $delimiter = "'";
67
+ } else if ($delimiter == 'double_quotes') {
68
+ $delimiter = '"';
69
+ } else {
70
+ $delimiter = '';
71
+ }
72
+ $lineBreak = Mage::helper('chronorelais')->getConfigurationEndOfLineCharacter('css');
73
+ if ($lineBreak == 'lf') {
74
+ $lineBreak = "\n";
75
+ } else if ($lineBreak == 'cr') {
76
+ $lineBreak = "\r";
77
+ } else if ($lineBreak == 'crlf') {
78
+ $lineBreak = "\r\n";
79
+ }
80
+ $fileExtension = Mage::helper('chronorelais')->getConfigurationFileExtension('css');
81
+ $fileCharset = Mage::helper('chronorelais')->getConfigurationFileCharset('css');
82
+
83
+ /* set the filename */
84
+ $filename = 'orders_exportcss_'.Mage::getSingleton('core/date')->date('Ymd_His').$fileExtension;
85
+
86
+ /* initialize the content variable */
87
+ $content = '';
88
+
89
+ if (!empty($orderIds)) {
90
+ foreach ($orderIds as $orderId) {
91
+
92
+ /* get the order */
93
+ $order = Mage::getModel('sales/order')->load($orderId);
94
+ $address = $order->getShippingAddress();
95
+ $billingAddress = $order->getBillingAddress();
96
+
97
+ $_shippingMethod = explode('_',$order->getShippingMethod());
98
+
99
+ /* customer id */
100
+ $content = $this->_addFieldToCsv($content, $delimiter, ($order->getCustomerId() ? $order->getCustomerId() : $address->getLastname()));
101
+ $content .= $separator;
102
+ /* customer company */
103
+ //$content = $this->_addFieldToCsv($content, $delimiter, $address->getCompany() ? $address->getCompany() : ($address->getName() ? $address->getName() : $billingAddress->getName()));
104
+ $content = $this->_addFieldToCsv($content, $delimiter, ($address->getName() ? $address->getName() : $billingAddress->getName()));
105
+ $content .= $separator;
106
+ /* customer name */
107
+ $cust_name = ($_shippingMethod[0] == "chronorelais" ? $this->getValue($address->getName()) : '');
108
+ $content = $this->_addFieldToCsv($content, $delimiter, $cust_name);
109
+ $content .= $separator;
110
+ /* street address */
111
+ $content = $this->_addFieldToCsv($content, $delimiter, $this->getValue($address->getStreet(1)));
112
+ $content .= $separator;
113
+ $content = $this->_addFieldToCsv($content, $delimiter, $this->getValue($address->getStreet(2)));
114
+ $content .= $separator;
115
+ /* postal code */
116
+ $content = $this->_addFieldToCsv($content, $delimiter, $this->getValue($address->getPostcode()));
117
+ $content .= $separator;
118
+ /* city */
119
+ $content = $this->_addFieldToCsv($content, $delimiter, $this->getValue($address->getCity()));
120
+ $content .= $separator;
121
+ /* country code */
122
+ $content = $this->_addFieldToCsv($content, $delimiter, $this->getValue($address->getCountry()));
123
+ $content .= $separator;
124
+ /* telephone */
125
+ $telephone = trim(ereg_replace("[^0-9.-]", " ", $address->getTelephone()));
126
+ $telephone = (strlen($telephone)>=10 ? $telephone : '');
127
+ $content = $this->_addFieldToCsv($content, $delimiter, $telephone);
128
+ $content .= $separator;
129
+ /* email */
130
+ $customer_email = ($address->getEmail()) ? $address->getEmail() : ($billingAddress->getEmail() ? $billingAddress->getEmail() : $order->getCustomerEmail());
131
+ $content = $this->_addFieldToCsv($content, $delimiter, $this->getValue($customer_email));
132
+ $content .= $separator;
133
+ /* chronorelay point */
134
+ $content = $this->_addFieldToCsv($content, $delimiter, $this->getValue($address->getWRelayPointCode()));
135
+ $content .= $separator;
136
+ /* real order id */
137
+ $content = $this->_addFieldToCsv($content, $delimiter, $this->getValue($order->getRealOrderId()));
138
+ $content .= $separator;
139
+ /* total weight */
140
+ $order_weight = number_format($order->getWeight(), 2 , '.' , '');
141
+ //$order_weight = $order_weight * 1000;
142
+ $content = $this->_addFieldToCsv($content, $delimiter, $order_weight);
143
+ $content .= $separator;
144
+
145
+ /* productCode*/
146
+ $productCode = ''; //Default code for chronorelais
147
+ $productCode = Mage::helper('chronorelais')->getChronoProductCodeString($_shippingMethod[0]);
148
+ $content = $this->_addFieldToCsv($content, $delimiter, $productCode);
149
+ $content .= $separator;
150
+
151
+ /* Livraison Samedi*/
152
+ $SaturdayShipping = 'L'; //default value for the saturday shipping
153
+ $send_day = strtolower(date('l'));
154
+ if($_shippingMethod[0] == "chronopost" || $_shippingMethod[0] == "chronorelais") {
155
+ if(!$_deliver_on_saturday = Mage::helper('chronorelais')->getLivraisonSamediStatus($orderId)) {
156
+ $_deliver_on_saturday = Mage::helper('chronorelais')->getConfigData('carriers/'.$_shippingMethod[0].'/deliver_on_saturday');
157
+ } else {
158
+ if($_deliver_on_saturday=='Yes') {
159
+ $_deliver_on_saturday = 1;
160
+ } else {
161
+ $_deliver_on_saturday = 0;
162
+ }
163
+ }
164
+ $is_sending_day = Mage::helper('chronorelais')->isSendingDay();
165
+ if($_deliver_on_saturday && $is_sending_day==true) {
166
+ $SaturdayShipping = 'S';
167
+ } elseif(!$_deliver_on_saturday && $is_sending_day==true) {
168
+ $SaturdayShipping = 'L';
169
+ }
170
+ }
171
+ $content = $this->_addFieldToCsv($content, $delimiter, $SaturdayShipping);
172
+ $content .= $separator;
173
+
174
+ /* empty fields */
175
+ $content = $this->_addFieldToCsv($content, $delimiter, 0);
176
+ $content .= $separator;
177
+ $content = $this->_addFieldToCsv($content, $delimiter, 0);
178
+ $content .= $lineBreak;
179
+ }
180
+
181
+ /* decode the content, depending on the charset */
182
+ if ($fileCharset == 'ISO-8859-1') {
183
+ $content = utf8_decode($content);
184
+ }
185
+
186
+ /* pick file mime type, depending on the extension */
187
+ if ($fileExtension == '.txt') {
188
+ $fileMimeType = 'text/plain';
189
+ } else if ($fileExtension == '.csv') {
190
+ $fileMimeType = 'application/csv';
191
+ } else if ($fileExtension == '.chr') {
192
+ $fileMimeType = 'application/chr';
193
+ } else {
194
+ // default
195
+ $fileMimeType = 'text/plain';
196
+ }
197
+
198
+ /* download the file */
199
+ return $this->_prepareDownloadResponse($filename, $content, $fileMimeType .'; charset="'. $fileCharset .'"');
200
+ }
201
+ else {
202
+ $this->_getSession()->addError($this->__('No Order has been selected'));
203
+ }
204
+ }
205
+
206
+ /**
207
+ * Export CSO Action
208
+ * Generates a CSV file to download (CSO format)
209
+ */
210
+ public function exportcsoAction()
211
+ {
212
+ /* get the orders */
213
+ $orderIds = $this->getRequest()->getPost('order_ids');
214
+
215
+ /**
216
+ * Get configuration
217
+ */
218
+ $separator = Mage::helper('chronorelais')->getConfigurationFieldSeparator('cso');
219
+ $delimiter = Mage::helper('chronorelais')->getConfigurationFieldDelimiter('cso');
220
+ if ($delimiter == 'simple_quote') {
221
+ $delimiter = "'";
222
+ } else if ($delimiter == 'double_quotes') {
223
+ $delimiter = '"';
224
+ } else {
225
+ $delimiter = '';
226
+ }
227
+ $lineBreak = Mage::helper('chronorelais')->getConfigurationEndOfLineCharacter('cso');
228
+ if ($lineBreak == 'lf') {
229
+ $lineBreak = "\n";
230
+ } else if ($lineBreak == 'cr') {
231
+ $lineBreak = "\r";
232
+ } else if ($lineBreak == 'crlf') {
233
+ $lineBreak = "\r\n";
234
+ }
235
+ $fileExtension = Mage::helper('chronorelais')->getConfigurationFileExtension('cso');
236
+ $fileCharset = Mage::helper('chronorelais')->getConfigurationFileCharset('cso');
237
+
238
+ /* set the filename */
239
+ $filename = 'orders_exportcso_'.Mage::getSingleton('core/date')->date('Ymd_His').$fileExtension;
240
+
241
+ /* initialize the content variable */
242
+ $content = '';
243
+
244
+ if (!empty($orderIds)) {
245
+ foreach ($orderIds as $orderId) {
246
+
247
+ /* get the order */
248
+ $order = Mage::getModel('sales/order')->load($orderId);
249
+ $address = $order->getShippingAddress();
250
+ $billingAddress = $order->getBillingAddress();
251
+
252
+ /* customer id */
253
+ $content = $this->_addFieldToCsv($content, $delimiter, ($order->getCustomerId() ? $order->getCustomerId() : $address->getLastname()));
254
+ $content .= $separator;
255
+ /* customer company or name*/
256
+ //$content = $this->_addFieldToCsv($content, $delimiter, $address->getCompany() ? $address->getCompany() : ($address->getName() ? $address->getName() : $billingAddress->getName()));
257
+ $content = $this->_addFieldToCsv($content, $delimiter, $address->getCompany());
258
+ $content .= $separator;
259
+ /* empty */
260
+ $content = $this->_addFieldToCsv($content, $delimiter, $this->getValue(""));
261
+ $content .= $separator;
262
+ /* street address */
263
+ $content = $this->_addFieldToCsv($content, $delimiter, $this->getValue($address->getStreet(1)));
264
+ $content .= $separator;
265
+ $content = $this->_addFieldToCsv($content, $delimiter, $this->getValue($address->getStreet(2)));
266
+ $content .= $separator;
267
+ /* Code Porte */
268
+ $content = $this->_addFieldToCsv($content, $delimiter, $this->getValue(""));
269
+ $content .= $separator;
270
+ /* country code */
271
+ $content = $this->_addFieldToCsv($content, $delimiter, $this->getValue($address->getCountry()));
272
+ $content .= $separator;
273
+ /* postal code */
274
+ $content = $this->_addFieldToCsv($content, $delimiter, $this->removeSpclChars($this->getValue($address->getPostcode())));
275
+ $content .= $separator;
276
+ /* city */
277
+ $content = $this->_addFieldToCsv($content, $delimiter, $this->getValue(strtoupper($address->getCity())));
278
+ $content .= $separator;
279
+ /* lastname */
280
+ $content = $this->_addFieldToCsv($content, $delimiter, $this->getValue($address->getLastname()));
281
+ $content .= $separator;
282
+ /* firstname */
283
+ $content = $this->_addFieldToCsv($content, $delimiter, $this->getValue($address->getFirstname()));
284
+ $content .= $separator;
285
+ /* telephone */
286
+ $telephone = trim(ereg_replace("[^0-9.-]", " ", $address->getTelephone()));
287
+ $telephone = (strlen($telephone)>=10 ? $telephone : '');
288
+ $content = $this->_addFieldToCsv($content, $delimiter, $telephone);
289
+ $content .= $separator;
290
+ /* email */
291
+ $customer_email = ($address->getEmail()) ? $address->getEmail() : ($billingAddress->getEmail() ? $billingAddress->getEmail() : $order->getCustomerEmail());
292
+ $content = $this->_addFieldToCsv($content, $delimiter, $this->getValue($customer_email));
293
+ $content .= $separator;
294
+ /* VAT number*/
295
+ $content = $this->_addFieldToCsv($content, $delimiter, $this->getValue(""));
296
+ $content .= $separator;
297
+ /* productCode*/
298
+ $productCode = ''; //Default code for chronorelais
299
+ $_shippingMethod = explode('_',$order->getShippingMethod());
300
+ if($_shippingMethod[0] == "chronopost") { // Conditions for chronorelais code
301
+ $productCode = 1;
302
+ } elseif($_shippingMethod[0] == "chronorelais") {
303
+ //$productCode = 6; //for chronorelais
304
+ } else {
305
+ $productCode = 4; //for chronoexpress
306
+ }
307
+ $content = $this->_addFieldToCsv($content, $delimiter, $productCode);
308
+ $content .= $separator;
309
+ /* real order id */
310
+ $content = $this->_addFieldToCsv($content, $delimiter, $this->getValue($order->getRealOrderId()));
311
+ $content .= $separator;
312
+ /* total weight */
313
+ $order_weight = number_format($order->getWeight(), 2 , '.' , '');
314
+ $order_weight = $order_weight * 1000;
315
+ $content = $this->_addFieldToCsv($content, $delimiter, $order_weight);
316
+ $content .= $separator;
317
+ /* Valeur Assur�e field*/
318
+ $content = $this->_addFieldToCsv($content, $delimiter, 0);
319
+ $content .= $separator;
320
+ /* Inform the recipient by e-mail field*/
321
+ $content = $this->_addFieldToCsv($content, $delimiter, $this->getValue("N"));
322
+ $content .= $separator;
323
+ /* Print Waybill field*/
324
+ $content = $this->_addFieldToCsv($content, $delimiter, $this->getValue("O"));
325
+ $content .= $separator;
326
+ /* sub-account field*/
327
+ $sub_account = Mage::helper('chronorelais')->getConfigurationSubAccountNumber();
328
+ $content = $this->_addFieldToCsv($content, $delimiter, (strlen($sub_account)==3 ? $sub_account : ""));
329
+ $content .= $separator;
330
+ /* Nature of item field*/
331
+ $content = $this->_addFieldToCsv($content, $delimiter, 2);
332
+ $content .= $separator;
333
+ /* Description of Consignment field*/
334
+ $content = $this->_addFieldToCsv($content, $delimiter, $this->getValue(""));
335
+ $content .= $separator;
336
+ /* Print pro-forma (customs) field*/
337
+ $content = $this->_addFieldToCsv($content, $delimiter, $this->getValue("N"));
338
+ $content .= $separator;
339
+ /* Declared value (customs) field*/
340
+ $content = $this->_addFieldToCsv($content, $delimiter, 0);
341
+ $content .= $separator;
342
+ /* Livraison Samedi (Delivery Saturday) field*/
343
+ $SaturdayShipping = 0; //default value for the saturday shipping
344
+ $send_day = strtolower(date('l'));
345
+ if($_shippingMethod[0] == "chronopost" || $_shippingMethod[0] == "chronorelais") {
346
+ if(!$_deliver_on_saturday = Mage::helper('chronorelais')->getLivraisonSamediStatus($orderId)) {
347
+ $_deliver_on_saturday = Mage::helper('chronorelais')->getConfigData('carriers/'.$_shippingMethod[0].'/deliver_on_saturday');
348
+ } else {
349
+ if($_deliver_on_saturday=='Yes') {
350
+ $_deliver_on_saturday = 1;
351
+ } else {
352
+ $_deliver_on_saturday = 0;
353
+ }
354
+ }
355
+ $is_sending_day = Mage::helper('chronorelais')->isSendingDay();
356
+ if($_deliver_on_saturday && $is_sending_day) {
357
+ $SaturdayShipping = 1;
358
+ } elseif(!$_deliver_on_saturday && $is_sending_day) {
359
+ $SaturdayShipping = 2;
360
+ }
361
+ }
362
+ $content = $this->_addFieldToCsv($content, $delimiter, $SaturdayShipping);
363
+ $content .= $lineBreak;
364
+ }
365
+
366
+ /* decode the content, depending on the charset */
367
+ if ($fileCharset == 'ISO-8859-1') {
368
+ $content = utf8_decode($content);
369
+ }
370
+
371
+ /* pick file mime type, depending on the extension */
372
+ if ($fileExtension == '.txt') {
373
+ $fileMimeType = 'text/plain';
374
+ } else if ($fileExtension == '.csv') {
375
+ $fileMimeType = 'application/csv';
376
+ } else if ($fileExtension == '.chr') {
377
+ $fileMimeType = 'application/chr';
378
+ } else {
379
+ // default
380
+ $fileMimeType = 'text/plain';
381
+ }
382
+
383
+ /* download the file */
384
+ return $this->_prepareDownloadResponse($filename, $content, $fileMimeType .'; charset="'. $fileCharset .'"');
385
+ }
386
+ else {
387
+ $this->_getSession()->addError($this->__('No Order has been selected'));
388
+ }
389
+ }
390
+
391
+ /* Save the Livraison le Samedi status to orders */
392
+ public function saveLivraisonSamediStatusAction()
393
+ {
394
+ /* get the orders */
395
+ $orderIds = $this->getRequest()->getPost('order_ids');
396
+ $status = $this->getRequest()->getPost('status');
397
+ $_connection = Mage::getSingleton('core/resource')->getConnection('core_write');
398
+ $_table = Mage::getSingleton('core/resource')->getTableName('sales_chronopost_order_export_status');
399
+ $exceptions = array();
400
+
401
+ foreach($orderIds as $orderId) {
402
+ $order_details = Mage::getModel('sales/order')->load($orderId);
403
+ $shipping_method = '';
404
+ $livraison_le_samedi = $status;
405
+ if($shipping_method = $order_details->getShippingMethod()) {
406
+ $shipping_method = explode('_',$shipping_method);
407
+ if($shipping_method[0]=='chronoexpress') {
408
+ $livraison_le_samedi = '--';
409
+ }
410
+ }
411
+ $condition = array(
412
+ $_connection->quoteInto('order_id = ?', $orderId),
413
+ );
414
+ $_connection->delete($_table, $condition);
415
+
416
+ $dataLine = array(
417
+ 'order_id' => $orderId,
418
+ 'livraison_le_samedi' => $livraison_le_samedi
419
+ );
420
+ try {
421
+ $_connection->insert($_table, $dataLine);
422
+ }
423
+ catch (Exception $e) {
424
+ $exceptions[] = Mage::helper('chronorelais')->__('Order assigning error: ' . $e->getMessage());
425
+ }
426
+ }
427
+ if($exceptions) {
428
+ $this->_getSession()->addError($exceptions);
429
+ } else {
430
+ $this->_getSession()->addSuccess($this->__('Livraison le Samedi statut a &eacute;t&eacute; ajout&eacute;'));
431
+ }
432
+ $this->_redirect('*/*/index');
433
+ }
434
+
435
+ /**
436
+ * Add a new field to the csv file
437
+ * @param csvContent : the current csv content
438
+ * @param fieldDelimiter : the delimiter character
439
+ * @param fieldContent : the content to add
440
+ * @return : the concatenation of current content and content to add
441
+ */
442
+ private function _addFieldToCsv($csvContent, $fieldDelimiter, $fieldContent) {
443
+ return $csvContent . $fieldDelimiter . $fieldContent . $fieldDelimiter;
444
+ }
445
+
446
+ }
app/code/community/Chronopost/Chronorelais/controllers/ImportController.php ADDED
@@ -0,0 +1,249 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class Chronopost_Chronorelais_ImportController extends Mage_Adminhtml_Controller_Action
3
+ {
4
+
5
+ /**
6
+ * Constructor
7
+ */
8
+ protected function _construct()
9
+ {
10
+ $this->setUsedModuleName('Chronopost_Chronorelais');
11
+ }
12
+
13
+ /**
14
+ * Main action : show import form
15
+ */
16
+ public function indexAction()
17
+ {
18
+ $this->loadLayout()
19
+ ->_setActiveMenu('sales/chronorelais/import')
20
+ ->_addContent($this->getLayout()->createBlock('chronorelais/import_form'))
21
+ ->renderLayout();
22
+ }
23
+
24
+ /**
25
+ * Import Action
26
+ */
27
+ public function importAction()
28
+ {
29
+ if ($this->getRequest()->isPost() && !empty($_FILES['import_chronorelais_file']['tmp_name'])) {
30
+ try {
31
+ $trackingTitle = $_POST['import_chronorelais_tracking_title'];
32
+ $this->_importChronorelaisFile($_FILES['import_chronorelais_file']['tmp_name'], $trackingTitle);
33
+ }
34
+ catch (Mage_Core_Exception $e) {
35
+ $this->_getSession()->addError($e->getMessage());
36
+ }
37
+ catch (Exception $e) {
38
+ $this->_getSession()->addError($e->getMessage());
39
+ $this->_getSession()->addError($this->__('Invalid file upload attempt'));
40
+ }
41
+ }
42
+ else {
43
+ $this->_getSession()->addError($this->__('Invalid file upload attempt'));
44
+ }
45
+ $this->_redirect('*/*/index');
46
+ }
47
+
48
+ /**
49
+ * Importation logic
50
+ * @param string $fileName
51
+ * @param string $trackingTitle
52
+ */
53
+ protected function _importChronorelaisFile($fileName, $trackingTitle)
54
+ {
55
+ /**
56
+ * File handling
57
+ **/
58
+ ini_set('auto_detect_line_endings', true);
59
+ $csvObject = new Varien_File_Csv();
60
+ $csvData = $csvObject->getData($fileName);
61
+
62
+ /**
63
+ * File expected fields
64
+ */
65
+ $expectedCsvFields = array(
66
+ 0 => $this->__('Order Id'),
67
+ 1 => $this->__('Tracking Number')
68
+ );
69
+
70
+ /**
71
+ * Get configuration
72
+ */
73
+ $sendEmail = Mage::helper('chronorelais')->getConfigurationSendEmail();
74
+ $comment = Mage::helper('chronorelais')->getConfigurationShippingComment();
75
+ $includeComment = Mage::helper('chronorelais')->getConfigurationIncludeComment();
76
+
77
+ /* debug */
78
+ //$this->_getSession()->addSuccess($this->__('%s - %s - %s - %s', $sendEmail, $comment, $includeComment, $trackingTitle));
79
+
80
+ /**
81
+ * $k is line number
82
+ * $v is line content array
83
+ */
84
+ foreach ($csvData as $k => $v) {
85
+
86
+ /**
87
+ * End of file has more than one empty lines
88
+ */
89
+ if (count($v) <= 1 && !strlen($v[0])) {
90
+ continue;
91
+ }
92
+
93
+ /**
94
+ * Check that the number of fields is not lower than expected
95
+ */
96
+ if (count($v) < count($expectedCsvFields)) {
97
+ $this->_getSession()->addError($this->__('Line %s format is invalid and has been ignored', $k));
98
+ continue;
99
+ }
100
+
101
+ /**
102
+ * Get fields content
103
+ */
104
+ $orderId = $v[0];
105
+ $trackingNumber = $v[1];
106
+
107
+ /* for debug */
108
+ //$this->_getSession()->addSuccess($this->__('Lecture ligne %s: %s - %s', $k, $orderId, $trackingNumber));
109
+
110
+ /**
111
+ * Try to load the order
112
+ */
113
+ $order = Mage::getModel('sales/order')->loadByIncrementId($orderId);
114
+ if (!$order->getId()) {
115
+ $this->_getSession()->addError($this->__('Order %s does not exist', $orderId));
116
+ continue;
117
+ }
118
+
119
+ /**
120
+ * Try to create a shipment
121
+ */
122
+ $shipmentId = $this->_createShipment($order, $trackingNumber, $trackingTitle, $sendEmail, $comment, $includeComment);
123
+
124
+ if ($shipmentId != 0) {
125
+ $this->_getSession()->addSuccess($this->__('Shipment %s created for order %s, with tracking number %s', $shipmentId, $orderId, $trackingNumber));
126
+ }
127
+
128
+ }//foreach
129
+
130
+ }
131
+
132
+ /**
133
+ * Create new shipment for order
134
+ * Inspired by Mage_Sales_Model_Order_Shipment_Api methods
135
+ *
136
+ * @param Mage_Sales_Model_Order $order (it should exist, no control is done into the method)
137
+ * @param string $trackingNumber
138
+ * @param string $trackingTitle
139
+ * @param booleam $email
140
+ * @param string $comment
141
+ * @param boolean $includeComment
142
+ * @return int : shipment real id if creation was ok, else 0
143
+ */
144
+ public function _createShipment($order, $trackingNumber, $trackingTitle, $email, $comment, $includeComment)
145
+ {
146
+ /**
147
+ * Check shipment creation availability
148
+ */
149
+ if (!$order->canShip()) {
150
+ $this->_getSession()->addError($this->__('Order %s can not be shipped or has already been shipped', $order->getRealOrderId()));
151
+ return 0;
152
+ }
153
+
154
+ /**
155
+ * Initialize the Mage_Sales_Model_Order_Shipment object
156
+ */
157
+ $convertor = Mage::getModel('sales/convert_order');
158
+ $shipment = $convertor->toShipment($order);
159
+
160
+ /**
161
+ * Add the items to send
162
+ */
163
+ foreach ($order->getAllItems() as $orderItem) {
164
+ if (!$orderItem->getQtyToShip()) {
165
+ continue;
166
+ }
167
+ if ($orderItem->getIsVirtual()) {
168
+ continue;
169
+ }
170
+
171
+ $item = $convertor->itemToShipmentItem($orderItem);
172
+ $qty = $orderItem->getQtyToShip();
173
+ $item->setQty($qty);
174
+
175
+ $shipment->addItem($item);
176
+ }//foreach
177
+
178
+ $shipment->register();
179
+
180
+ /**
181
+ * Tracking number instanciation
182
+ */
183
+
184
+ $_shippingMethod = explode("_",$order->getShippingMethod());
185
+ switch($_shippingMethod[0]) {
186
+ case "chronopost":
187
+ case "chronorelais":
188
+ case "chronoexpress":
189
+ $carrier_code = $_shippingMethod[0];
190
+ $popup = 1;
191
+ /*$hash = Mage::helper('core')->urlEncode("order_id:{$order->getId()}:{$order->getProtectCode()}");
192
+ $tracking_url = Mage::getBaseUrl().'chronorelais/relais/tracking/hash/'.$hash.'/';*/
193
+ $tracking_url = str_replace('{tracking_number}', $trackingNumber, Mage::helper('chronorelais')->getConfigurationTrackingViewUrl());
194
+ $tracking_title = $this->__('Track Your Order');
195
+ $tracking_order = '<p><a title="'.$tracking_title.'" href="'.$tracking_url.'"><b>'.$tracking_title.'</b></a></p>';
196
+ break;
197
+ default:
198
+ $carrier_code = 'custom';
199
+ $popup = 0;
200
+ $tracking_order = '';
201
+ break;
202
+ }
203
+
204
+ $track = Mage::getModel('sales/order_shipment_track')
205
+ ->setNumber($trackingNumber)
206
+ ->setCarrierCode($carrier_code)
207
+ ->setTitle($trackingTitle)
208
+ ->setPopup($popup);
209
+ $shipment->addTrack($track);
210
+
211
+ /**
212
+ * Comment handling
213
+ */
214
+ $shipment->addComment($comment, $email && $includeComment);
215
+
216
+ /**
217
+ * Change order status to Processing
218
+ */
219
+ $shipment->getOrder()->setIsInProcess(true);
220
+
221
+ /**
222
+ * If e-mail, set as sent (must be done before shipment object saving)
223
+ */
224
+ if ($email) {
225
+ $shipment->setEmailSent(true);
226
+ }
227
+
228
+ try {
229
+ /**
230
+ * Save the created shipment and the updated order
231
+ */
232
+ $shipment->save();
233
+ $shipment->getOrder()->save();
234
+
235
+ /**
236
+ * Email sending
237
+ */
238
+ $shipment->sendEmail($email, ($includeComment ? $tracking_order.$comment : $tracking_order));
239
+ } catch (Mage_Core_Exception $e) {
240
+ $this->_getSession()->addError($this->__('Shipment creation error for Order %s : %s', $orderId, $e->getMessage()));
241
+ return 0;
242
+ }
243
+
244
+ /**
245
+ * Everything was ok : return Shipment real id
246
+ */
247
+ return $shipment->getIncrementId();
248
+ }
249
+ }
app/code/community/Chronopost/Chronorelais/controllers/RelaisController.php ADDED
@@ -0,0 +1,32 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class Chronopost_Chronorelais_RelaisController extends Mage_Core_Controller_Front_Action {
3
+
4
+ public function filterAction() {
5
+ $this->loadLayout();
6
+ $this->renderLayout();
7
+ }
8
+
9
+ public function detailAction() {
10
+ $this->loadLayout();
11
+ $this->renderLayout();
12
+ }
13
+
14
+ /**
15
+ * Go to the tacking page
16
+ * external function for mail link "Track Your Order" in shipment mail
17
+ */
18
+ public function trackingAction()
19
+ {
20
+ if($this->getRequest()->isGet()) {
21
+ if($hash = $this->getRequest()->getParam('hash')) {
22
+ $req_values = Mage::helper('shipping')->decodeTrackingHash($hash);
23
+ if($req_values) {
24
+ $order = Mage::getModel('sales/order')->load($req_values['id']);
25
+ $popup_url = Mage::helper('shipping')->getTrackingPopupUrlBySalesModel($order);
26
+ header('location: '.$popup_url); exit();
27
+ }
28
+ }
29
+ }
30
+ }
31
+
32
+ }
app/code/community/Chronopost/Chronorelais/controllers/Sales/ImpressionController.php ADDED
@@ -0,0 +1,556 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ require_once 'Mage/Adminhtml/controllers/Sales/Order/ShipmentController.php';
3
+ class Chronopost_Chronorelais_Sales_ImpressionController extends Mage_Adminhtml_Sales_Order_ShipmentController
4
+ {
5
+ protected $_trackingNumbers = '';
6
+
7
+ /**
8
+ * Additional initialization
9
+ *
10
+ */
11
+ protected function _construct()
12
+ {
13
+ $this->setUsedModuleName('Chronopost_Chronorelais');
14
+ }
15
+
16
+ /**
17
+ * Shipping grid
18
+ */
19
+ public function indexAction()
20
+ {
21
+ if (!extension_loaded('soap')) {
22
+ $this->_getSession()->addError($this->__('The SOAP extension is not installed in the server. Please contact the site administrator. Sorry for inconvenience.'));
23
+ return $this->_redirectReferer();
24
+ }
25
+ $this->loadLayout()
26
+ ->_setActiveMenu('sales/chronorelais')
27
+ ->_addContent($this->getLayout()->createBlock('chronorelais/sales_impression'))
28
+ ->renderLayout();
29
+ }
30
+
31
+ /**
32
+ * Save shipment and order in one transaction
33
+ * @param Mage_Sales_Model_Order_Shipment $shipment
34
+ */
35
+ protected function _saveShipment($shipment)
36
+ {
37
+ $shipment->getOrder()->setIsInProcess(true);
38
+ $transactionSave = Mage::getModel('core/resource_transaction')
39
+ ->addObject($shipment)
40
+ ->addObject($shipment->getOrder())
41
+ ->save();
42
+
43
+ return $this;
44
+ }
45
+
46
+ protected function _processDownload($resource, $resourceType)
47
+ {
48
+ $helper = Mage::helper('downloadable/download');
49
+ /* @var $helper Mage_Downloadable_Helper_Download */
50
+
51
+ $helper->setResource($resource, $resourceType);
52
+
53
+ $fileName = $helper->getFilename();
54
+ $contentType = $helper->getContentType();
55
+
56
+ $this->getResponse()
57
+ ->setHttpResponseCode(200)
58
+ ->setHeader('Pragma', 'public', true)
59
+ ->setHeader('Cache-Control', 'must-revalidate, post-check=0, pre-check=0', true)
60
+ ->setHeader('Content-type', $contentType, true);
61
+
62
+ if ($fileSize = $helper->getFilesize()) {
63
+ $this->getResponse()
64
+ ->setHeader('Content-Length', $fileSize);
65
+ }
66
+
67
+ if ($contentDisposition = $helper->getContentDisposition()) {
68
+ $this->getResponse()
69
+ ->setHeader('Content-Disposition', $contentDisposition . '; filename='.$fileName);
70
+ }
71
+
72
+ $this->getResponse()
73
+ ->clearBody();
74
+ $this->getResponse()
75
+ ->sendHeaders();
76
+
77
+ $helper->output();
78
+ }
79
+
80
+ protected function getTrackingNumber($shipmentId)
81
+ {
82
+ $shipment = Mage::getModel('sales/order_shipment')->load($shipmentId);
83
+
84
+ //On récupère le numéro de tracking
85
+ $tracks = $shipment->getTracksCollection();
86
+ foreach ($tracks as $track) {
87
+ if ( $track->getParentId() == $shipmentId)
88
+ {
89
+ $this->_trackingNumbers .= $track->getnumber();
90
+ }
91
+ }
92
+
93
+ return $this->_trackingNumbers;
94
+ }
95
+
96
+ protected function getFilledValue($value)
97
+ {
98
+ if($value) {
99
+ return $this->removeaccents(trim($value));
100
+ } else {
101
+ return '';
102
+ }
103
+ }
104
+
105
+ protected function checkMobileNumber($value)
106
+ {
107
+ if($reqvalue = trim($value)) {
108
+ $_number = substr($reqvalue, 0, 2);
109
+ $fixed_array = array('01','02','03','04','05','06','06');
110
+ if(in_array($_number, $fixed_array)) {
111
+ return $reqvalue;
112
+ } else {
113
+ return '';
114
+ }
115
+ }
116
+ }
117
+
118
+ protected function getExpeditionParams($_order, $_shippingMethod)
119
+ {
120
+ $_shippingAddress = $_order->getShippingAddress();
121
+ $_billingAddress = $_order->getBillingAddress();
122
+ $_helper = Mage::helper('chronorelais');
123
+
124
+ if ($_shippingMethod[0] == 'chronorelais' || $_shippingMethod[0] == 'chronopost' || $_shippingMethod[0] == 'chronoexpress') {
125
+ $esdParams = $header = $shipper = $customer = $recipient = $ref = $skybill = $skybillParams = $password = array();
126
+
127
+ //esdParams parameters
128
+ $esdParams = array(
129
+ 'height' => '',
130
+ 'width' => '',
131
+ 'length' => ''
132
+ );
133
+
134
+ //header parameters
135
+ $header = array(
136
+ 'idEmit' => 'CHRFR',
137
+ 'accountNumber' => $_helper->getConfigurationAccountNumber(),
138
+ 'subAccount' => $_helper->getConfigurationSubAccountNumber()
139
+ );
140
+
141
+ //shipper parameters
142
+ $shipperMobilePhone = $this->checkMobileNumber($_helper->getConfigurationShipperInfo('mobilephone'));
143
+ $shipper = array(
144
+ 'shipperAdress1' => $_helper->getConfigurationShipperInfo('address1'),
145
+ 'shipperAdress2' => $_helper->getConfigurationShipperInfo('address2'),
146
+ 'shipperCity' => $_helper->getConfigurationShipperInfo('city'),
147
+ 'shipperCivility' => $_helper->getConfigurationShipperInfo('civility'),
148
+ 'shipperContactName'=> $_helper->getConfigurationShipperInfo('contactname'),
149
+ 'shipperCountry' => $_helper->getConfigurationShipperInfo('country'),
150
+ 'shipperEmail' => $_helper->getConfigurationShipperInfo('email'),
151
+ 'shipperMobilePhone'=> $shipperMobilePhone,
152
+ 'shipperName' => $_helper->getConfigurationShipperInfo('name'),
153
+ 'shipperName2' => $_helper->getConfigurationShipperInfo('name2'),
154
+ 'shipperPhone' => $_helper->getConfigurationShipperInfo('phone'),
155
+ 'shipperPreAlert' => '',
156
+ 'shipperZipCode' => $_helper->getConfigurationShipperInfo('zipcode')
157
+ );
158
+
159
+ //customer parameters
160
+ $customerMobilePhone = $this->checkMobileNumber($_helper->getConfigurationCustomerInfo('mobilephone'));
161
+ $customer = array(
162
+ 'customerAdress1' => $_helper->getConfigurationCustomerInfo('address1'),
163
+ 'customerAdress2' => $_helper->getConfigurationCustomerInfo('address2'),
164
+ 'customerCity' => $_helper->getConfigurationCustomerInfo('city'),
165
+ 'customerCivility' => $_helper->getConfigurationCustomerInfo('civility'),
166
+ 'customerContactName'=> $_helper->getConfigurationCustomerInfo('contactname'),
167
+ 'customerCountry' => $_helper->getConfigurationCustomerInfo('country'),
168
+ 'customerEmail' => $_helper->getConfigurationCustomerInfo('email'),
169
+ 'customerMobilePhone'=> $customerMobilePhone,
170
+ 'customerName' => $_helper->getConfigurationCustomerInfo('name'),
171
+ 'customerName2' => $_helper->getConfigurationCustomerInfo('name2'),
172
+ 'customerPhone' => $_helper->getConfigurationCustomerInfo('phone'),
173
+ 'customerPreAlert' => '',
174
+ 'customerZipCode' => $_helper->getConfigurationCustomerInfo('zipcode')
175
+ );
176
+
177
+ //recipient parameters
178
+ $recipient_address = $_shippingAddress->getStreet();
179
+ if (!isset($recipient_address[1])) {
180
+ $recipient_address[1] = '';
181
+ }
182
+ $customer_email = ($_shippingAddress->getEmail()) ? $_shippingAddress->getEmail() : ($_billingAddress->getEmail() ? $_billingAddress->getEmail() : $_order->getCustomerEmail());
183
+ $recipientMobilePhone = $this->checkMobileNumber($_shippingAddress->getTelephone());
184
+ $recipientName = $this->getFilledValue($_shippingAddress->getCompany()); //RelayPoint Name if chronorelais or Companyname if chronopost and
185
+ $recipientName2 = $this->getFilledValue($_shippingAddress->getFirstname() . ' ' . $_shippingAddress->getLastname());
186
+ //remove any alphabets in phone number
187
+ $recipientPhone = trim(ereg_replace("[^0-9.-]", " ", $_shippingAddress->getTelephone()));
188
+
189
+ $recipient = array(
190
+ 'recipientAdress1' => $this->getFilledValue($recipient_address[0]),
191
+ 'recipientAdress2' => $this->getFilledValue($recipient_address[1]),
192
+ 'recipientCity' => $this->getFilledValue($_shippingAddress->getCity()),
193
+ 'recipientContactName' => $recipientName2,
194
+ 'recipientCountry' => $this->getFilledValue($_shippingAddress->getCountryId()),
195
+ 'recipientEmail' => $customer_email,
196
+ 'recipientMobilePhone' => $recipientMobilePhone,
197
+ 'recipientName' => $recipientName,
198
+ 'recipientName2' => $recipientName2,
199
+ 'recipientPhone' => $recipientPhone,
200
+ 'recipientPreAlert' => '',
201
+ 'recipientZipCode' => $this->getFilledValue($_shippingAddress->getPostcode()),
202
+ );
203
+
204
+ //ref parameters
205
+ $recipientRef = $this->getFilledValue($_shippingAddress->getWRelayPointCode());
206
+ if(!$recipientRef) {
207
+ $recipientRef = $_order->getCustomerId();
208
+ }
209
+ $shipperRef = $_order->getRealOrderId();
210
+
211
+ $ref = array(
212
+ 'recipientRef' => $recipientRef,
213
+ 'shipperRef' => $shipperRef
214
+ );
215
+
216
+ //skybill parameters
217
+ /* Livraison Samedi (Delivery Saturday) field*/
218
+ $SaturdayShipping = 0; //default value for the saturday shipping
219
+ $send_day = strtolower(date('l'));
220
+ if($_shippingMethod[0] == "chronopost" || $_shippingMethod[0] == "chronorelais") {
221
+ if(!$_deliver_on_saturday = Mage::helper('chronorelais')->getLivraisonSamediStatus($_order->getEntityId())) {
222
+ $_deliver_on_saturday = Mage::helper('chronorelais')->getConfigData('carriers/'.$_shippingMethod[0].'/deliver_on_saturday');
223
+ } else {
224
+ if($_deliver_on_saturday=='Yes') {
225
+ $_deliver_on_saturday = 1;
226
+ } else {
227
+ $_deliver_on_saturday = 0;
228
+ }
229
+ }
230
+ $is_sending_day = Mage::helper('chronorelais')->isSendingDay();
231
+ if($_deliver_on_saturday && $is_sending_day) {
232
+ $SaturdayShipping = 6;
233
+ } elseif(!$_deliver_on_saturday && $is_sending_day) {
234
+ $SaturdayShipping = 1;
235
+ }
236
+ }
237
+
238
+ $skybill = array(
239
+ 'codCurrency' => 'EUR',
240
+ 'codValue' => '',
241
+ 'content1' => '',
242
+ 'content2' => '',
243
+ 'content3' => '',
244
+ 'content4' => '',
245
+ 'content5' => '',
246
+ 'customsCurrency' => 'EUR',
247
+ 'customsValue' => '',
248
+ 'evtCode' => 'DC',
249
+ 'insuredCurrency' => 'EUR',
250
+ 'insuredValue' => '',
251
+ 'objectType' => 'MAR',
252
+ 'productCode' => $_helper->getChronoProductCode($_shippingAddress->getCountryId(),$_shippingMethod[0]),
253
+ 'service' => $SaturdayShipping,
254
+ 'shipDate' => date('c'),
255
+ 'shipHour' => date('H'),
256
+ 'weight' => $_order->getWeight(),
257
+ 'weightUnit' => 'KGM'
258
+ );
259
+
260
+ $skybillParams = array(
261
+ 'mode' => $_helper->getConfigurationSkybillParam()
262
+ );
263
+
264
+ $expeditionArray = array(
265
+ 'esdParams' => $esdParams,
266
+ 'header' => $header,
267
+ 'shipper' => $shipper,
268
+ 'customer' => $customer,
269
+ 'recipient' => $recipient,
270
+ 'ref' => $ref,
271
+ 'skybill' => $skybill,
272
+ 'skybillParams' => $skybillParams,
273
+ 'password' => $_helper->getConfigurationAccountPass(),
274
+ 'option' => '0'
275
+ );
276
+ //printArray($expeditionArray); exit;
277
+ return $expeditionArray;
278
+ }
279
+ }
280
+
281
+ protected function getEtiquetteUrl($shipmentId)
282
+ {
283
+ //On récupère les infos d'expédition
284
+ $reservationNumber = '';
285
+ $_helper = Mage::helper('chronorelais');
286
+
287
+ $shipment = Mage::getModel('sales/order_shipment')->load($shipmentId);
288
+ if($_shipTracks = $shipment->getAllTracks()) {
289
+ foreach($_shipTracks as $_shipTrack) {
290
+ if($_shipTrack->getNumber() && $_shipTrack->getChronoReservationNumber()) {
291
+ $reservationNumber = $_shipTrack->getChronoReservationNumber();
292
+ break;
293
+ }
294
+ }
295
+ if($reservationNumber) {
296
+ return $reservationNumber;
297
+ }
298
+ }
299
+
300
+ $_order = $shipment->getOrder();
301
+ $_shippingMethod = explode("_",$_order->getShippingMethod());
302
+
303
+ $expeditionArray = $this->getExpeditionParams($_order, $_shippingMethod);
304
+ $tracking_number = '';
305
+ if($expeditionArray) {
306
+ $client = new SoapClient("http://wsshipping.chronopost.fr/shipping/services/services/ServiceEProcurement?wsdl", array('trace' => true));
307
+ try
308
+ {
309
+ $webservbt = $client->__call("reservationExpeditionV2",$expeditionArray);
310
+ if(!$webservbt->errorCode && $webservbt->reservationNumber) {
311
+ $tracking_number = $webservbt->skybillNumber;
312
+ // Add tracking number for the shipment if not already exists.
313
+ if(!$this->_trackingNumbers && $webservbt->skybillNumber) {
314
+ $track = Mage::getModel('sales/order_shipment_track')
315
+ ->setNumber($webservbt->skybillNumber)
316
+ ->setCarrier(ucwords($_shippingMethod[0]))
317
+ ->setCarrierCode($_shippingMethod[0])
318
+ ->setTitle(ucwords($_shippingMethod[0]))
319
+ ->setChronoReservationNumber($webservbt->reservationNumber)
320
+ ->setPopup(1);
321
+ $shipment->addTrack($track);
322
+
323
+ $tracking_url = str_replace('{tracking_number}', $tracking_number, Mage::helper('chronorelais')->getConfigurationTrackingViewUrl());
324
+ $tracking_title = $this->__('Track Your Order');
325
+ $tracking_order = '<p><a title="'.$tracking_title.'" href="'.$tracking_url.'"><b>'.$tracking_title.'</b></a></p>';
326
+
327
+ //$shipment->register();
328
+ $comment = '';
329
+ $shipment->setEmailSent(true);
330
+ $this->_saveShipment($shipment);
331
+ $shipment->sendEmail(1, $tracking_order.$comment);
332
+ }
333
+ return $webservbt->reservationNumber;
334
+ } else {
335
+ $this->_getSession()->addError($_helper->__($webservbt->errorMessage));
336
+ }
337
+ }
338
+ catch(SoapFault $fault)
339
+ {
340
+ $this->_getSession()->addError($_helper->__($fault->faultstring));
341
+ }
342
+ }
343
+ }
344
+
345
+ public function getShipmentByOrderId($orderId) {
346
+ $_shipment = Mage::getResourceModel('sales/order_shipment_grid_collection')
347
+ ->addAttributeToFilter('order_id', $orderId)
348
+ ->getAllIds();
349
+ return $_shipment;
350
+ }
351
+
352
+ public function initShipment($orderId)
353
+ {
354
+ $order = Mage::getModel('sales/order')->load($orderId);
355
+
356
+ /**
357
+ * Check order existing
358
+ */
359
+ if (!$order->getId()) {
360
+ $this->_getSession()->addError($this->__('The order no longer exists.'));
361
+ return false;
362
+ }
363
+ /**
364
+ * Check shipment is available to create separate from invoice
365
+ */
366
+
367
+ if ($order->getForcedDoShipmentWithInvoice()) {
368
+ $this->_getSession()->addError($this->__('Cannot do shipment for the order separately from invoice.'));
369
+ return false;
370
+ }
371
+ /**
372
+ * Check shipment create availability
373
+ */
374
+ /*if (!$order->canShip()) {
375
+ $this->_getSession()->addError($this->__('Cannot do shipment for the order.'));
376
+ return false;
377
+ }*/
378
+ $savedQtys = $this->_getItemQtys();
379
+ $shipment = Mage::getModel('sales/service_order', $order)->prepareShipment($savedQtys);
380
+
381
+ Mage::register('current_shipment', $shipment);
382
+ return $shipment;
383
+ }
384
+
385
+ public function createNewShipment($orderId) {
386
+ $_helper = Mage::helper('chronorelais');
387
+ $reservationNumber = '';
388
+ try {
389
+ if ($shipment = $this->initShipment($orderId)) {
390
+ $shipment->register();
391
+
392
+ $_order = $shipment->getOrder();
393
+ $_shippingMethod = explode("_",$_order->getShippingMethod());
394
+
395
+ $expeditionArray = $this->getExpeditionParams($_order, $_shippingMethod);
396
+ $tracking_number = '';
397
+ if($expeditionArray) {
398
+
399
+ $client = new SoapClient("http://wsshipping.chronopost.fr/shipping/services/services/ServiceEProcurement?wsdl", array('trace' => true));
400
+ try
401
+ {
402
+ $expedition = $client->__call("reservationExpeditionV2",$expeditionArray);
403
+ if(!$expedition->errorCode && $expedition->skybillNumber) {
404
+ $tracking_number = $expedition->skybillNumber;
405
+ $track = Mage::getModel('sales/order_shipment_track')
406
+ ->setNumber($expedition->skybillNumber)
407
+ ->setCarrier(ucwords($_shippingMethod[0]))
408
+ ->setCarrierCode($_shippingMethod[0])
409
+ ->setTitle(ucwords($_shippingMethod[0]))
410
+ ->setChronoReservationNumber($expedition->reservationNumber)
411
+ ->setPopup(1);
412
+ $shipment->addTrack($track);
413
+ $reservationNumber = $expedition->reservationNumber;
414
+ } else {
415
+ $this->_getSession()->addError($_helper->__($expedition->errorMessage));
416
+ return;
417
+ }
418
+ }
419
+ catch(SoapFault $fault)
420
+ {
421
+ $this->_getSession()->addError($_helper->__($fault->faultstring));
422
+ return;
423
+ }
424
+ }
425
+
426
+ $tracking_url = str_replace('{tracking_number}', $tracking_number, Mage::helper('chronorelais')->getConfigurationTrackingViewUrl());
427
+ $tracking_title = $this->__('Track Your Order');
428
+ $tracking_order = '<p><a title="'.$tracking_title.'" href="'.$tracking_url.'"><b>'.$tracking_title.'</b></a></p>';
429
+
430
+ $comment = '';
431
+ $shipment->setEmailSent(true);
432
+ $this->_saveShipment($shipment);
433
+ $shipment->sendEmail(1, $tracking_order.$comment);
434
+ $this->_getSession()->addSuccess($this->__('Shipment was successfully created.'));
435
+ return $reservationNumber;
436
+
437
+ }else {
438
+ $this->_forward('noRoute');
439
+ return;
440
+ }
441
+ }
442
+ catch (Mage_Core_Exception $e) {
443
+ $this->_getSession()->addError($e->getMessage());
444
+ return;
445
+ }
446
+ catch (Exception $e) {
447
+ $this->_getSession()->addError($this->__('Can not save shipment: '.$e->getMessage()));
448
+ return;
449
+ }
450
+ }
451
+
452
+ public function printMassAction()
453
+ {
454
+ $shipmentsIds = $this->getRequest()->getPost('shipment_ids');
455
+ try {
456
+ $trackingNumber = $this->getEtiquetteUrl($shipmentsIds);
457
+ if($trackingNumber) {
458
+ $tracking_url = str_replace('{trackingNumber}', $trackingNumber, Mage::helper('chronorelais')->getConfigurationTrackingUrl());
459
+ $this->_processDownload($tracking_url, 'url');
460
+ exit(0);
461
+ }
462
+ } catch (Mage_Core_Exception $e) {
463
+ $this->_getSession()->addError(Mage::helper('chronorelais')->__('Désolé, une erreure est survenu lors de la récupération de l\'étiquetes. Merci de contacter Chronopost ou de réessayer plus tard'));
464
+ }
465
+ return $this->_redirectReferer();
466
+
467
+ }
468
+
469
+ public function printAction()
470
+ {
471
+ $orderId = $this->getRequest()->getParam('order_id');
472
+
473
+ if($_shipments = $this->getShipmentByOrderId($orderId)) {
474
+ $shipmentId = $_shipments[0];
475
+ $trackingNumber = $this->getEtiquetteUrl($shipmentId);
476
+ } else {
477
+ $trackingNumber = $this->createNewShipment($orderId);
478
+ }
479
+
480
+ if($trackingNumber) {
481
+ try {
482
+ $tracking_url = str_replace('{trackingNumber}', $trackingNumber, Mage::helper('chronorelais')->getConfigurationTrackingUrl());
483
+ $this->_processDownload($tracking_url, 'url');
484
+ exit(0);
485
+ } catch (Mage_Core_Exception $e) {
486
+ $this->_getSession()->addError(Mage::helper('chronorelais')->__('Désolé, une erreure est survenu lors de la récupération de l\'étiquetes. Merci de contacter Chronopost ou de réessayer plus tard'));
487
+ }
488
+ }
489
+ return $this->_redirectReferer();
490
+ }
491
+
492
+ public function massLivraisonSamediStatusAction()
493
+ {
494
+ if($this->getRequest()->getPost('status')) {
495
+ $this->saveLivraisonSamediStatusAction();
496
+ }
497
+ }
498
+
499
+ /* Save the Livraison le Samedi status to orders */
500
+ public function saveLivraisonSamediStatusAction()
501
+ {
502
+ /* get the orders */
503
+ $orderIds = $this->getRequest()->getPost('order_ids');
504
+ $status = $this->getRequest()->getPost('status');
505
+ $_connection = Mage::getSingleton('core/resource')->getConnection('core_write');
506
+ $_table = Mage::getSingleton('core/resource')->getTableName('sales_chronopost_order_export_status');
507
+ $exceptions = array();
508
+
509
+ foreach($orderIds as $orderId) {
510
+ $order_details = Mage::getModel('sales/order')->load($orderId);
511
+ $shipping_method = '';
512
+ $livraison_le_samedi = $status;
513
+ if($shipping_method = $order_details->getShippingMethod()) {
514
+ $shipping_method = explode('_',$shipping_method);
515
+ if($shipping_method[0]=='chronoexpress') {
516
+ $livraison_le_samedi = '--';
517
+ }
518
+ }
519
+ $condition = array(
520
+ $_connection->quoteInto('order_id = ?', $orderId),
521
+ );
522
+ $_connection->delete($_table, $condition);
523
+
524
+ $dataLine = array(
525
+ 'order_id' => $orderId,
526
+ 'livraison_le_samedi' => $livraison_le_samedi
527
+ );
528
+ try {
529
+ $_connection->insert($_table, $dataLine);
530
+ }
531
+ catch (Exception $e) {
532
+ $exceptions[] = Mage::helper('chronorelais')->__('Order assigning error: ' . $e->getMessage());
533
+ }
534
+ }
535
+ if($exceptions) {
536
+ $this->_getSession()->addError($exceptions);
537
+ } else {
538
+ $this->_getSession()->addSuccess($this->__('Livraison le Samedi statut a &eacute;t&eacute; ajout&eacute;'));
539
+ }
540
+ $this->_redirect('*/*/index');
541
+ }
542
+
543
+ /* Remove accents characters */
544
+ public function removeaccents($string){
545
+ $stringToReturn = str_replace(
546
+ array('à','á','â','ã','ä', 'ç', 'è','é','ê','ë', 'ì','í','î','ï', 'ñ', 'ò','ó','ô','õ','ö', 'ù','ú','û','ü', 'ý','ÿ', 'À','Á','Â','Ã','Ä', 'Ç', 'È','É','Ê','Ë', 'Ì','Í','Î','Ï', 'Ñ', 'Ò','Ó','Ô','Õ','Ö', 'Ù','Ú','Û','Ü', 'Ý','/','\xa8'),
547
+ array('a','a','a','a','a', 'c', 'e','e','e','e', 'i','i','i','i', 'n', 'o','o','o','o','o', 'u','u','u','u', 'y','y', 'A','A','A','A','A', 'C', 'E','E','E','E', 'I','I','I','I', 'N', 'O','O','O','O','O', 'U','U','U','U', 'Y',' ','e'), $string);
548
+ // Remove all remaining other unknown characters
549
+ $stringToReturn = preg_replace('/[^a-zA-Z0-9\-]/', ' ', $stringToReturn);
550
+ $stringToReturn = preg_replace('/^[\-]+/', '', $stringToReturn);
551
+ $stringToReturn = preg_replace('/[\-]+$/', '', $stringToReturn);
552
+ $stringToReturn = preg_replace('/[\-]{2,}/', ' ', $stringToReturn);
553
+ return $stringToReturn;
554
+ }
555
+
556
+ }
app/code/community/Chronopost/Chronorelais/controllers/Sales/Order/ShipmentController.php ADDED
@@ -0,0 +1,268 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ require_once 'Mage/Adminhtml/controllers/Sales/Order/ShipmentController.php';
3
+ class Chronopost_Chronorelais_Sales_Order_ShipmentController extends Mage_Adminhtml_Sales_Order_ShipmentController
4
+ {
5
+
6
+ /**
7
+ * Save shipment
8
+ * We can save only new shipment. Existing shipments are not editable
9
+ */
10
+
11
+ public function getFilledValue($value)
12
+ {
13
+ if($value) {
14
+ return $this->removeaccents(trim($value));
15
+ } else {
16
+ return '';
17
+ }
18
+ }
19
+
20
+ public function checkMobileNumber($value)
21
+ {
22
+ if($reqvalue = trim($value)) {
23
+ $_number = substr($reqvalue, 0, 2);
24
+ $fixed_array = array('01','02','03','04','05','06','06');
25
+ if(in_array($_number, $fixed_array)) {
26
+ return $reqvalue;
27
+ } else {
28
+ return '';
29
+ }
30
+ }
31
+ }
32
+
33
+ public function saveAction()
34
+ {
35
+ $data = $this->getRequest()->getPost('shipment');
36
+
37
+ try {
38
+ if ($shipment = $this->_initShipment()) {
39
+ $shipment->register();
40
+
41
+ //Si l'expedition est réalisé par Mondial Relay, on créé le tracking automatiquement.
42
+
43
+ $_order = $shipment->getOrder();
44
+ $_shippingMethod = explode("_",$_order->getShippingMethod());
45
+
46
+ $_shippingAddress = $_order->getShippingAddress();
47
+ $_billingAddress = $_order->getBillingAddress();
48
+ $_helper = Mage::helper('chronorelais');
49
+
50
+ if ($_shippingMethod[0] == 'chronorelais' || $_shippingMethod[0] == 'chronopost' || $_shippingMethod[0] == 'chronoexpress') {
51
+
52
+ $esdParams = $header = $shipper = $customer = $recipient = $ref = $skybill = $skybillParams = $password = array();
53
+
54
+ //esdParams parameters
55
+ $esdParams = array(
56
+ 'height' => '',
57
+ 'width' => '',
58
+ 'length' => ''
59
+ );
60
+
61
+ //header parameters
62
+ $header = array(
63
+ 'idEmit' => 'CHRFR',
64
+ 'accountNumber' => $_helper->getConfigurationAccountNumber(),
65
+ 'subAccount' => $_helper->getConfigurationSubAccountNumber()
66
+ );
67
+
68
+ //shipper parameters
69
+ $shipperMobilePhone = $this->checkMobileNumber($_helper->getConfigurationShipperInfo('mobilephone'));
70
+ $shipper = array(
71
+ 'shipperAdress1' => $_helper->getConfigurationShipperInfo('address1'),
72
+ 'shipperAdress2' => $_helper->getConfigurationShipperInfo('address2'),
73
+ 'shipperCity' => $_helper->getConfigurationShipperInfo('city'),
74
+ 'shipperCivility' => $_helper->getConfigurationShipperInfo('civility'),
75
+ 'shipperContactName'=> $_helper->getConfigurationShipperInfo('contactname'),
76
+ 'shipperCountry' => $_helper->getConfigurationShipperInfo('country'),
77
+ 'shipperEmail' => $_helper->getConfigurationShipperInfo('email'),
78
+ 'shipperMobilePhone'=> $shipperMobilePhone,
79
+ 'shipperName' => $_helper->getConfigurationShipperInfo('name'),
80
+ 'shipperName2' => $_helper->getConfigurationShipperInfo('name2'),
81
+ 'shipperPhone' => $_helper->getConfigurationShipperInfo('phone'),
82
+ 'shipperPreAlert' => '',
83
+ 'shipperZipCode' => $_helper->getConfigurationShipperInfo('zipcode')
84
+ );
85
+
86
+ //customer parameters
87
+ $customerMobilePhone = $this->checkMobileNumber($_helper->getConfigurationCustomerInfo('mobilephone'));
88
+ $customer = array(
89
+ 'customerAdress1' => $_helper->getConfigurationCustomerInfo('address1'),
90
+ 'customerAdress2' => $_helper->getConfigurationCustomerInfo('address2'),
91
+ 'customerCity' => $_helper->getConfigurationCustomerInfo('city'),
92
+ 'customerCivility' => $_helper->getConfigurationCustomerInfo('civility'),
93
+ 'customerContactName'=> $_helper->getConfigurationCustomerInfo('contactname'),
94
+ 'customerCountry' => $_helper->getConfigurationCustomerInfo('country'),
95
+ 'customerEmail' => $_helper->getConfigurationCustomerInfo('email'),
96
+ 'customerMobilePhone'=> $customerMobilePhone,
97
+ 'customerName' => $_helper->getConfigurationCustomerInfo('name'),
98
+ 'customerName2' => $_helper->getConfigurationCustomerInfo('name2'),
99
+ 'customerPhone' => $_helper->getConfigurationCustomerInfo('phone'),
100
+ 'customerPreAlert' => '',
101
+ 'customerZipCode' => $_helper->getConfigurationCustomerInfo('zipcode')
102
+ );
103
+
104
+ //recipient parameters
105
+ $recipient_address = $_shippingAddress->getStreet();
106
+ if (!isset($recipient_address[1])) {
107
+ $recipient_address[1] = '';
108
+ }
109
+ $customer_email = ($_shippingAddress->getEmail()) ? $_shippingAddress->getEmail() : ($_billingAddress->getEmail() ? $_billingAddress->getEmail() : $_order->getCustomerEmail());
110
+ $recipientMobilePhone = $this->checkMobileNumber($_shippingAddress->getTelephone());
111
+ $recipientName = $this->getFilledValue($_shippingAddress->getCompany()); //RelayPoint Name if chronorelais or Companyname if chronopost and
112
+ $recipientName2 = $this->getFilledValue($_shippingAddress->getFirstname() . ' ' . $_shippingAddress->getLastname());
113
+ //remove any alphabets in phone number
114
+ $recipientPhone = trim(ereg_replace("[^0-9.-]", " ", $_shippingAddress->getTelephone()));
115
+
116
+ $recipient = array(
117
+ 'recipientAdress1' => $this->getFilledValue($recipient_address[0]),
118
+ 'recipientAdress2' => $this->getFilledValue($recipient_address[1]),
119
+ 'recipientCity' => $this->getFilledValue($_shippingAddress->getCity()),
120
+ 'recipientContactName' => $recipientName2,
121
+ 'recipientCountry' => $this->getFilledValue($_shippingAddress->getCountryId()),
122
+ 'recipientEmail' => $customer_email,
123
+ 'recipientMobilePhone' => $recipientMobilePhone,
124
+ 'recipientName' => $recipientName,
125
+ 'recipientName2' => $recipientName2,
126
+ 'recipientPhone' => $recipientPhone,
127
+ 'recipientPreAlert' => '',
128
+ 'recipientZipCode' => $this->getFilledValue($_shippingAddress->getPostcode()),
129
+ );
130
+
131
+ //ref parameters
132
+ $recipientRef = $this->getFilledValue($_shippingAddress->getWRelayPointCode());
133
+ if(!$recipientRef) {
134
+ $recipientRef = $_order->getCustomerId();
135
+ }
136
+ $shipperRef = $_order->getRealOrderId();
137
+
138
+ $ref = array(
139
+ 'recipientRef' => $recipientRef,
140
+ 'shipperRef' => $shipperRef
141
+ );
142
+
143
+ //skybill parameters
144
+ /* Livraison Samedi (Delivery Saturday) field*/
145
+ $SaturdayShipping = 0; //default value for the saturday shipping
146
+ $send_day = strtolower(date('l'));
147
+ if($_shippingMethod[0] == "chronopost" || $_shippingMethod[0] == "chronorelais") {
148
+ if(!$_deliver_on_saturday = Mage::helper('chronorelais')->getLivraisonSamediStatus($_order->getEntityId())) {
149
+ $_deliver_on_saturday = Mage::helper('chronorelais')->getConfigData('carriers/'.$_shippingMethod[0].'/deliver_on_saturday');
150
+ } else {
151
+ if($_deliver_on_saturday=='Yes') {
152
+ $_deliver_on_saturday = 1;
153
+ } else {
154
+ $_deliver_on_saturday = 0;
155
+ }
156
+ }
157
+ $is_sending_day = Mage::helper('chronorelais')->isSendingDay();
158
+ if($_deliver_on_saturday && $is_sending_day) {
159
+ $SaturdayShipping = 1;
160
+ } elseif(!$_deliver_on_saturday && $is_sending_day) {
161
+ $SaturdayShipping = 6;
162
+ }
163
+ }
164
+ $skybill = array(
165
+ 'codCurrency' => 'EUR',
166
+ 'codValue' => '',
167
+ 'content1' => '',
168
+ 'content2' => '',
169
+ 'content3' => '',
170
+ 'content4' => '',
171
+ 'content5' => '',
172
+ 'customsCurrency' => 'EUR',
173
+ 'customsValue' => '',
174
+ 'evtCode' => 'DC',
175
+ 'insuredCurrency' => 'EUR',
176
+ 'insuredValue' => '',
177
+ 'objectType' => 'MAR',
178
+ 'productCode' => $_helper->getChronoProductCode($_shippingAddress->getCountryId(),$_shippingMethod[0]),
179
+ 'service' => $SaturdayShipping,
180
+ 'shipDate' => date('c'),
181
+ 'shipHour' => date('H'),
182
+ 'weight' => $_order->getWeight(),
183
+ 'weightUnit' => 'KGM'
184
+ );
185
+
186
+ $expeditionArray = array(
187
+ 'esdParams' => $esdParams,
188
+ 'header' => $header,
189
+ 'shipper' => $shipper,
190
+ 'customer' => $customer,
191
+ 'recipient' => $recipient,
192
+ 'ref' => $ref,
193
+ 'skybill' => $skybill,
194
+ 'skybillParams' => $_helper->getConfigurationSkybillParam(),
195
+ 'password' => $_helper->getConfigurationAccountPass(),
196
+ 'option' => '0'
197
+ );
198
+
199
+ $client = new SoapClient("http://wsshipping.chronopost.fr/shipping/services/services/ServiceEProcurement?wsdl", array('trace' => true));
200
+ try
201
+ {
202
+ $expedition = $client->__call("reservationExpeditionV2",$expeditionArray);
203
+ if(!$expedition->errorCode && $expedition->skybillNumber) {
204
+ $track = Mage::getModel('sales/order_shipment_track')
205
+ ->setNumber($expedition->skybillNumber)
206
+ ->setCarrier(ucwords($_shippingMethod[0]))
207
+ ->setCarrierCode($_shippingMethod[0])
208
+ ->setTitle(ucwords($_shippingMethod[0]))
209
+ ->setChronoReservationNumber($expedition->reservationNumber)
210
+ ->setPopup(1);
211
+ $shipment->addTrack($track);
212
+ } else {
213
+ $this->_getSession()->addError($_helper->__($expedition->errorMessage));
214
+ $this->_redirect('*/*/new', array('order_id' => $this->getRequest()->getParam('order_id')));
215
+ return;
216
+ }
217
+ }
218
+ catch(SoapFault $fault)
219
+ {
220
+ $this->_getSession()->addError($_helper->__($fault->faultstring));
221
+ $this->_redirect('*/*/new', array('order_id' => $this->getRequest()->getParam('order_id')));
222
+ return;
223
+ }
224
+ }
225
+
226
+ $comment = '';
227
+ if (!empty($data['comment_text'])) {
228
+ $shipment->addComment($data['comment_text'], isset($data['comment_customer_notify']));
229
+ $comment = $data['comment_text'];
230
+ }
231
+
232
+ if (!empty($data['send_email'])) {
233
+ $shipment->setEmailSent(true);
234
+ }
235
+
236
+ $this->_saveShipment($shipment);
237
+ $shipment->sendEmail(!empty($data['send_email']), $comment);
238
+ $this->_getSession()->addSuccess($this->__('Shipment was successfully created.'));
239
+ $this->_redirect('adminhtml/sales_order/view', array('order_id' => $shipment->getOrderId()));
240
+ return;
241
+
242
+ }else {
243
+ $this->_forward('noRoute');
244
+ return;
245
+ }
246
+ }
247
+ catch (Mage_Core_Exception $e) {
248
+ $this->_getSession()->addError($e->getMessage());
249
+ }
250
+ catch (Exception $e) {
251
+ $this->_getSession()->addError($this->__('Can not save shipment: '.$e->getMessage()));
252
+ }
253
+ $this->_redirect('*/*/new', array('order_id' => $this->getRequest()->getParam('order_id')));
254
+ }
255
+
256
+ public function removeaccents($string){
257
+ $stringToReturn = str_replace(
258
+ array('�','�','�','�','�', '�', '�','�','�','�', '�','�','�','�', '�', '�','�','�','�','�', '�','�','�','�', '�','�', '�','�','�','�','�', '�', '�','�','�','�', '�','�','�','�', '�', '�','�','�','�','�', '�','�','�','�', '�','/','\xa8'),
259
+ array('a','a','a','a','a', 'c', 'e','e','e','e', 'i','i','i','i', 'n', 'o','o','o','o','o', 'u','u','u','u', 'y','y', 'A','A','A','A','A', 'C', 'E','E','E','E', 'I','I','I','I', 'N', 'O','O','O','O','O', 'U','U','U','U', 'Y',' ','e'), $string);
260
+ // Remove all remaining other unknown characters
261
+ $stringToReturn = preg_replace('/[^a-zA-Z0-9\-]/', ' ', $stringToReturn);
262
+ $stringToReturn = preg_replace('/^[\-]+/', '', $stringToReturn);
263
+ $stringToReturn = preg_replace('/[\-]+$/', '', $stringToReturn);
264
+ $stringToReturn = preg_replace('/[\-]{2,}/', ' ', $stringToReturn);
265
+ return $stringToReturn;
266
+ }
267
+
268
+ }
app/code/community/Chronopost/Chronorelais/etc/config.xml ADDED
@@ -0,0 +1,340 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <config>
3
+ <modules>
4
+ <Chronopost_Chronorelais>
5
+ <version>0.1.4</version>
6
+ <depends>
7
+ <Mage_Shipping />
8
+ <Mage_Sales />
9
+ <Mage_Adminhtml />
10
+ </depends>
11
+ </Chronopost_Chronorelais>
12
+ </modules>
13
+
14
+ <global>
15
+ <models>
16
+ <chronorelais>
17
+ <class>Chronopost_Chronorelais_Model</class>
18
+ </chronorelais>
19
+ <sales>
20
+ <rewrite>
21
+ <quote_address_total_shipping>Chronopost_Chronorelais_Model_Sales_Quote_Address_Total_Shipping</quote_address_total_shipping>
22
+ </rewrite>
23
+ </sales>
24
+ </models>
25
+ <blocks>
26
+ <chronorelais>
27
+ <class>Chronopost_Chronorelais_Block</class>
28
+ </chronorelais>
29
+ <adminhtml>
30
+ <rewrite>
31
+ <sales_order_shipment_view>Chronopost_Chronorelais_Block_Sales_Order_Shipment_View</sales_order_shipment_view>
32
+ </rewrite>
33
+ </adminhtml>
34
+ </blocks>
35
+ <helpers>
36
+ <chronorelais>
37
+ <class>Chronopost_Chronorelais_Helper</class>
38
+ </chronorelais>
39
+ </helpers>
40
+
41
+ <resources>
42
+ <sales>
43
+ <shipping>
44
+ <carriers>
45
+ <chronorelais>
46
+ <class>Chronopost_Chronorelais_Model_Carrier_Chronorelais</class>
47
+ </chronorelais>
48
+ <chronopost>
49
+ <class>Chronopost_Chronorelais_Model_Carrier_Chronopost</class>
50
+ </chronopost>
51
+ <chronoexpress>
52
+ <class>Chronopost_Chronorelais_Model_Carrier_Chronoexpress</class>
53
+ </chronoexpress>
54
+ </carriers>
55
+ </shipping>
56
+ </sales>
57
+ <chronorelais_setup>
58
+ <setup>
59
+ <module>Chronopost_Chronorelais</module>
60
+ <class>Mage_Catalog_Model_Resource_Eav_Mysql4_Setup</class>
61
+ </setup>
62
+ <connection>
63
+ <use>core_setup</use>
64
+ </connection>
65
+ </chronorelais_setup>
66
+ <chronorelais_write>
67
+ <connection>
68
+ <use>core_write</use>
69
+ </connection>
70
+ </chronorelais_write>
71
+
72
+ <chronorelais_read>
73
+ <connection>
74
+ <use>core_read</use>
75
+ </connection>
76
+ </chronorelais_read>
77
+ </resources>
78
+
79
+ <rewrite>
80
+ <chronopost_chronorelais_checkout_onepage>
81
+ <from><![CDATA[#^/checkout/onepage/#]]></from>
82
+ <to>/chronorelais/checkout_onepage/</to>
83
+ </chronopost_chronorelais_checkout_onepage>
84
+ <chronopost_chronorelais_sales_order_shipment>
85
+ <from><![CDATA[#^/.*sales_order_shipment/save/#]]></from>
86
+ <to>/chronorelais/sales_order_shipment/save/</to>
87
+ </chronopost_chronorelais_sales_order_shipment>
88
+ </rewrite>
89
+
90
+ <fieldsets>
91
+ <sales_copy_order_billing_address>
92
+ <w_relay_point_code><to_order>*</to_order></w_relay_point_code>
93
+ </sales_copy_order_billing_address>
94
+ <sales_copy_order_shipping_address>
95
+ <w_relay_point_code><to_order>*</to_order></w_relay_point_code>
96
+ </sales_copy_order_shipping_address>
97
+ <sales_convert_quote_address>
98
+ <w_relay_point_code><to_order_address>*</to_order_address><to_customer_address>*</to_customer_address></w_relay_point_code>
99
+ </sales_convert_quote_address>
100
+ <sales_convert_order_address>
101
+ <w_relay_point_code><to_quote_address>*</to_quote_address></w_relay_point_code>
102
+ </sales_convert_order_address>
103
+ <customer_address>
104
+ <w_relay_point_code><to_quote_address>*</to_quote_address></w_relay_point_code>
105
+ </customer_address>
106
+ </fieldsets>
107
+
108
+ </global>
109
+
110
+ <frontend>
111
+ <routers>
112
+ <chronorelais>
113
+ <use>standard</use>
114
+ <args>
115
+ <module>Chronopost_Chronorelais</module>
116
+ <frontName>chronorelais</frontName>
117
+ </args>
118
+ </chronorelais>
119
+ </routers>
120
+
121
+ <layout>
122
+ <updates>
123
+ <chronorelais>
124
+ <file>chronorelais.xml</file>
125
+ </chronorelais>
126
+ </updates>
127
+ </layout>
128
+ <translate>
129
+ <modules>
130
+ <Chronopost_Chronorelais>
131
+ <files>
132
+ <default>Chronopost_Chronorelais.csv</default>
133
+ </files>
134
+ </Chronopost_Chronorelais>
135
+ </modules>
136
+ </translate>
137
+ </frontend>
138
+
139
+ <admin>
140
+ <routers>
141
+ <chronorelais>
142
+ <use>admin</use>
143
+ <args>
144
+ <module>Chronopost_Chronorelais</module>
145
+ <frontName>chronorelais</frontName>
146
+ </args>
147
+ </chronorelais>
148
+ </routers>
149
+ </admin>
150
+
151
+ <adminhtml>
152
+ <menu>
153
+ <sales>
154
+ <children>
155
+ <chronorelais translate="title"> <!-- TODO faire marcher : module="chronorelais" (aussi dans les children) -->
156
+ <title>Chronopost</title>
157
+ <sort_order>15</sort_order>
158
+ <children>
159
+ <export translate="title">
160
+ <title>Export</title>
161
+ <action>chronorelais/export</action>
162
+ <sort_order>10</sort_order>
163
+ </export>
164
+ <import translate="title">
165
+ <title>Import</title>
166
+ <action>chronorelais/import</action>
167
+ <sort_order>20</sort_order>
168
+ </import>
169
+ <impression translate="title" module="sales">
170
+ <title>Impression des étiquettes</title>
171
+ <action>chronorelais/sales_impression</action>
172
+ <sort_order>30</sort_order>
173
+ </impression>
174
+ </children>
175
+ </chronorelais>
176
+ </children>
177
+ </sales>
178
+ </menu>
179
+ <acl>
180
+ <resources>
181
+ <admin>
182
+ <children>
183
+ <sales>
184
+ <children>
185
+ <chronorelais translate="title">
186
+ <title>Chronopost</title>
187
+ <sort_order>15</sort_order>
188
+ <children>
189
+ <export translate="title">
190
+ <title>Export</title>
191
+ <sort_order>10</sort_order>
192
+ </export>
193
+ <import translate="title">
194
+ <title>Import</title>
195
+ <sort_order>20</sort_order>
196
+ </import>
197
+ <impression translate="title" module="sales">
198
+ <title>Impression des étiquettes</title>
199
+ <sort_order>30</sort_order>
200
+ </impression>
201
+ </children>
202
+ </chronorelais>
203
+ </children>
204
+ </sales>
205
+ <system>
206
+ <children>
207
+ <config>
208
+ <children>
209
+ <chronorelais translate="title" module="chronorelais">
210
+ <title>Chronopost</title>
211
+ <sort_order>100</sort_order>
212
+ </chronorelais>
213
+ </children>
214
+ </config>
215
+ </children>
216
+ </system>
217
+ </children>
218
+ </admin>
219
+ </resources>
220
+ </acl>
221
+
222
+ <translate>
223
+ <modules>
224
+ <Chronopost_Chronorelais>
225
+ <files>
226
+ <default>Chronopost_Chronorelais.csv</default>
227
+ </files>
228
+ </Chronopost_Chronorelais>
229
+ </modules>
230
+ </translate>
231
+ </adminhtml>
232
+
233
+ <default>
234
+ <chronorelais>
235
+ <shipping>
236
+ <google_map_api>ABQIAAAAZvdukOwsytNocL5anZKqZxS51Nc8ngbKeRYi0kVLSLeRaqOKHRSLs6O150txpwWCDcct2mH4X-G6OA</google_map_api>
237
+ <tracking_view_url><![CDATA[http://suivi.chronopost.fr/servletSuivi?langue=fr_FR&noLTList={tracking_number}]]></tracking_view_url>
238
+ </shipping>
239
+ <export_css>
240
+ <file_extension>.chr</file_extension>
241
+ <file_charset>ASCII-7</file_charset>
242
+ <endofline_character>crlf</endofline_character>
243
+ <field_delimiter>none</field_delimiter>
244
+ <field_separator>;</field_separator>
245
+ </export_css>
246
+ <export_cso>
247
+ <file_extension>.txt</file_extension>
248
+ <file_charset>ISO-8859-1</file_charset>
249
+ <endofline_character>crlf</endofline_character>
250
+ <field_delimiter>none</field_delimiter>
251
+ <field_separator>;</field_separator>
252
+ </export_cso>
253
+ <import>
254
+ <default_tracking_title>Chronopost - Chronopost livraison express à domicile</default_tracking_title>
255
+ <send_email>1</send_email>
256
+ <shipping_comment></shipping_comment>
257
+ <include_comment>0</include_comment>
258
+ </import>
259
+ </chronorelais>
260
+ <carriers>
261
+ <chronopost>
262
+ <active>0</active>
263
+ <title>Chronopost</title>
264
+ <model>Chronopost_Chronorelais_Model_Carrier_Chronopost</model>
265
+ <tracking_view_url></tracking_view_url>
266
+ <config>
267
+ # Chronopost
268
+ {
269
+ label: "Chronopost livraison express à domicile",
270
+ code: "chronopost",
271
+ description: "Colis livré le lendemain avant 13h, à l’adresse de votre choix.
272
+ Délai à compter de la prise en charge du colis par Chronopost, pour une livraison en France métropolitaine.
273
+ En cas d’absence, le colis est mis en instance dans le bureau de Poste le plus proche.",
274
+ tracking_url: "http://www.fr.chronopost.com/fr/tracking/result?listeNumeros={tracking_number}",
275
+ destination: "FR,MC",
276
+ fees: "{table {cart.weight} in 2.00:17.56, 3.00:18.40, 4.00:19.24, 5.00:20.08, 6.00:20.92, 7.00:21.76, 8.00:22.60, 9.00:23.44, 10.00:24.28, 15.00:28.48, 20.00:32.68, 25.00:36.88, 30.00:41.08}",
277
+ }
278
+ </config>
279
+ <weight_limit>30</weight_limit>
280
+ <quickcost_url>http://wsshipping.chronopost.fr/wsQuickcost/services/ServiceQuickCost?wsdl</quickcost_url>
281
+ <logo_url>chronopost.png</logo_url>
282
+ <debug>0</debug>
283
+ <stop_to_first_match>0</stop_to_first_match>
284
+ <!--<specificerrmsg>This shipping method is currently unavailable.</specificerrmsg>-->
285
+ <sort_order>1</sort_order>
286
+ </chronopost>
287
+ <chronoexpress>
288
+ <active>0</active>
289
+ <title>Chronopost</title>
290
+ <model>Chronopost_Chronorelais_Model_Carrier_Chronoexpress</model>
291
+ <tracking_view_url></tracking_view_url>
292
+ <config>
293
+ # Chronoexpress
294
+ {
295
+ label: "Chronopost livraison express partout dans le monde",
296
+ code: "chronoexpress",
297
+ description: "L'Europe livrée en 1 à 3 jours et le reste du monde en 2 à 5 jours.
298
+ Délai à compter de la prise en charge du colis par Chronopost.",
299
+ tracking_url: "http://www.fr.chronopost.com/fr/tracking/result?listeNumeros={tracking_number}",
300
+ destination: "DE,BE,BG,CY,DK,ES,EE,FI,GR,IE,IT,LV,LT,MT,NL,PL,PT,CZ,RO,SK,AT,HU,LU,GB,SI,SE,GF,YT,GP,MQ,RE",
301
+ fees: "{table {cart.weight} in 0.50:30.94, 1.00:45.07, 1.50:55.26, 2.00:65.45, 2.50:75.64, 3.00:85.83, 3.50:88.72, 4.00:91.61, 4.50:94.50, 5.00:97.39, 30.00:97.39}",
302
+ }
303
+ </config>
304
+ <weight_limit>30</weight_limit>
305
+ <quickcost_url>http://wsshipping.chronopost.fr/wsQuickcost/services/ServiceQuickCost?wsdl</quickcost_url>
306
+ <logo_url>chronopost.png</logo_url>
307
+ <debug>0</debug>
308
+ <stop_to_first_match>0</stop_to_first_match>
309
+ <!--<specificerrmsg>This shipping method is currently unavailable.</specificerrmsg>-->
310
+ <sort_order>1</sort_order>
311
+ </chronoexpress>
312
+ <chronorelais>
313
+ <active>0</active>
314
+ <title>Chrono Relais</title>
315
+ <model>Chronopost_Chronorelais_Model_Carrier_Chronorelais</model>
316
+ <tracking_view_url></tracking_view_url>
317
+ <config>
318
+ # Chronorelais
319
+ {
320
+ label: "Chronopost : livraison express en point Chrono Relais",
321
+ code: "chronorelais",
322
+ description: "Colis disponible le lendemain à partir de 13h dans le point Chrono Relais de votre choix.
323
+ Délai à compter de la prise en charge du colis par Chronopost.",
324
+ tracking_url: "http://www.fr.chronopost.com/fr/tracking/result?listeNumeros={tracking_number}",
325
+ destination: "FR",
326
+ fees: "{table {cart.weight} in 2.00:17.56, 3.00:18.40, 4.00:19.24, 5.00:20.08, 6.00:20.92, 7.00:21.76, 8.00:22.60, 9.00:23.44, 10.00:24.28, 15.00:28.48, 20.00:32.68, 25.00:36.88, 30.00:41.08}",
327
+ }
328
+ </config>
329
+ <weight_limit>20</weight_limit>
330
+ <quickcost_url>http://wsshipping.chronopost.fr/wsQuickcost/services/ServiceQuickCost?wsdl</quickcost_url>
331
+ <logo_url>chronorelais.png</logo_url>
332
+ <debug>0</debug>
333
+ <stop_to_first_match>0</stop_to_first_match>
334
+ <!--<specificerrmsg>This shipping method is currently unavailable.</specificerrmsg>-->
335
+ <sort_order>2</sort_order>
336
+ </chronorelais>
337
+ </carriers>
338
+ </default>
339
+
340
+ </config>
app/code/community/Chronopost/Chronorelais/etc/system.xml ADDED
@@ -0,0 +1,965 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <config>
3
+ <tabs>
4
+ <chronopost translate="label" module="chronorelais">
5
+ <label>Chronopost</label>
6
+ <sort_order>200</sort_order>
7
+ </chronopost>
8
+ </tabs>
9
+ <sections>
10
+ <carriers>
11
+ <groups>
12
+ <chronopost translate="label">
13
+ <label>Chronopost</label>
14
+ <frontend_type>text</frontend_type>
15
+ <sort_order>20</sort_order>
16
+ <show_in_default>1</show_in_default>
17
+ <show_in_website>1</show_in_website>
18
+ <show_in_store>1</show_in_store>
19
+ <fields>
20
+ <active translate="label">
21
+ <label>Enabled</label>
22
+ <frontend_type>select</frontend_type>
23
+ <source_model>adminhtml/system_config_source_yesno</source_model>
24
+ <sort_order>1</sort_order>
25
+ <show_in_default>1</show_in_default>
26
+ <show_in_website>1</show_in_website>
27
+ <show_in_store>1</show_in_store>
28
+ </active>
29
+ <title translate="label">
30
+ <label>Title</label>
31
+ <frontend_type>text</frontend_type>
32
+ <sort_order>2</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
+ </title>
37
+ <config translate="label">
38
+ <label>Configuration</label>
39
+ <frontend_model>chronorelais/adminhtml_system_config_form_field_config</frontend_model>
40
+ <comment>{configuration_syntax_help}</comment>
41
+ <frontend_type>textarea</frontend_type>
42
+ <sort_order>3</sort_order>
43
+ <show_in_default>1</show_in_default>
44
+ <show_in_website>1</show_in_website>
45
+ <show_in_store>1</show_in_store>
46
+ </config>
47
+ <weight_limit translate="label">
48
+ <label>Weight Limit</label>
49
+ <frontend_type>text</frontend_type>
50
+ <comment>in Kg</comment>
51
+ <sort_order>7</sort_order>
52
+ <show_in_default>1</show_in_default>
53
+ <show_in_website>1</show_in_website>
54
+ <show_in_store>1</show_in_store>
55
+ </weight_limit>
56
+ <quickcost translate="label">
57
+ <label>Quickcost</label>
58
+ <frontend_type>select</frontend_type>
59
+ <comment>To obtain the price from your rate grid</comment>
60
+ <source_model>adminhtml/system_config_source_yesno</source_model>
61
+ <sort_order>10</sort_order>
62
+ <show_in_default>1</show_in_default>
63
+ <show_in_website>1</show_in_website>
64
+ <show_in_store>0</show_in_store>
65
+ </quickcost>
66
+ <quickcost_url>
67
+ <label>Quickcost Url</label>
68
+ <frontend_type>text</frontend_type>
69
+ <sort_order>11</sort_order>
70
+ <show_in_default>1</show_in_default>
71
+ <show_in_website>1</show_in_website>
72
+ <show_in_store>0</show_in_store>
73
+ </quickcost_url>
74
+ <free_shipping_enable translate="label">
75
+ <label>Free Shipping on the Amount</label>
76
+ <frontend_type>select</frontend_type>
77
+ <source_model>adminhtml/system_config_source_enabledisable</source_model>
78
+ <sort_order>12</sort_order>
79
+ <show_in_default>1</show_in_default>
80
+ <show_in_website>1</show_in_website>
81
+ <show_in_store>1</show_in_store>
82
+ </free_shipping_enable>
83
+ <free_shipping_subtotal translate="label">
84
+ <label>Minimum Amount for Free Shipping</label>
85
+ <frontend_type>text</frontend_type>
86
+ <sort_order>13</sort_order>
87
+ <show_in_default>1</show_in_default>
88
+ <show_in_website>1</show_in_website>
89
+ <show_in_store>0</show_in_store>
90
+ </free_shipping_subtotal>
91
+ <application_fee translate="label">
92
+ <label>Application Fee</label>
93
+ <frontend_type>text</frontend_type>
94
+ <sort_order>14</sort_order>
95
+ <show_in_default>1</show_in_default>
96
+ <show_in_website>1</show_in_website>
97
+ <show_in_store>1</show_in_store>
98
+ </application_fee>
99
+ <handling_fee translate="label">
100
+ <label>Handling Fee</label>
101
+ <frontend_type>text</frontend_type>
102
+ <sort_order>15</sort_order>
103
+ <show_in_default>1</show_in_default>
104
+ <show_in_website>1</show_in_website>
105
+ <show_in_store>1</show_in_store>
106
+ </handling_fee>
107
+ <logo_url>
108
+ <label>Logo Url</label>
109
+ <frontend_type>text</frontend_type>
110
+ <comment>{logo_ulr_help}</comment>
111
+ <sort_order>18</sort_order>
112
+ <show_in_default>1</show_in_default>
113
+ <show_in_website>1</show_in_website>
114
+ <show_in_store>1</show_in_store>
115
+ </logo_url>
116
+ <debug>
117
+ <label>Debug</label>
118
+ <comment>{debug_help}</comment>
119
+ <frontend_type>text</frontend_type>
120
+ <sort_order>20</sort_order>
121
+ <show_in_default>1</show_in_default>
122
+ <show_in_website>1</show_in_website>
123
+ <show_in_store>1</show_in_store>
124
+ </debug>
125
+ <!--<stop_to_first_match translate="label">
126
+ <label>Stop to first match</label>
127
+ <frontend_type>select</frontend_type>
128
+ <source_model>adminhtml/system_config_source_yesno</source_model>
129
+ <sort_order>22</sort_order>
130
+ <show_in_default>1</show_in_default>
131
+ <show_in_website>1</show_in_website>
132
+ <show_in_store>1</show_in_store>
133
+ </stop_to_first_match>-->
134
+ <deliver_on_saturday translate="label comment">
135
+ <label>Livraison le Samedi</label>
136
+ <comment>If yes has been selected, the option will be available every Thursdays from 6pm to Fridays at 3pm.</comment>
137
+ <frontend_type>select</frontend_type>
138
+ <source_model>adminhtml/system_config_source_yesno</source_model>
139
+ <sort_order>23</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
+ </deliver_on_saturday>
144
+ <!--<showmethod translate="label">
145
+ <label>Show Method if Not Applicable</label>
146
+ <frontend_type>select</frontend_type>
147
+ <sort_order>30</sort_order>
148
+ <frontend_class>shipping-skip-hide</frontend_class>
149
+ <source_model>adminhtml/system_config_source_yesno</source_model>
150
+ <show_in_default>1</show_in_default>
151
+ <show_in_website>1</show_in_website>
152
+ <show_in_store>0</show_in_store>
153
+ </showmethod>
154
+ <specificerrmsg translate="label">
155
+ <label>Displayed Error Message</label>
156
+ <frontend_type>textarea</frontend_type>
157
+ <sort_order>31</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
+ </specificerrmsg>-->
162
+ <sort_order translate="label">
163
+ <label>Sort order</label>
164
+ <frontend_type>text</frontend_type>
165
+ <sort_order>100</sort_order>
166
+ <show_in_default>1</show_in_default>
167
+ <show_in_website>1</show_in_website>
168
+ <show_in_store>1</show_in_store>
169
+ </sort_order>
170
+ </fields>
171
+ </chronopost>
172
+
173
+ <chronoexpress translate="label">
174
+ <label>Chrono Express</label>
175
+ <frontend_type>text</frontend_type>
176
+ <sort_order>21</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
+ <fields>
181
+ <active translate="label">
182
+ <label>Enabled</label>
183
+ <frontend_type>select</frontend_type>
184
+ <source_model>adminhtml/system_config_source_yesno</source_model>
185
+ <sort_order>1</sort_order>
186
+ <show_in_default>1</show_in_default>
187
+ <show_in_website>1</show_in_website>
188
+ <show_in_store>1</show_in_store>
189
+ </active>
190
+ <title translate="label">
191
+ <label>Title</label>
192
+ <frontend_type>text</frontend_type>
193
+ <sort_order>2</sort_order>
194
+ <show_in_default>1</show_in_default>
195
+ <show_in_website>1</show_in_website>
196
+ <show_in_store>1</show_in_store>
197
+ </title>
198
+ <config translate="label">
199
+ <label>Configuration</label>
200
+ <frontend_model>chronorelais/adminhtml_system_config_form_field_config</frontend_model>
201
+ <comment>{configuration_syntax_help}</comment>
202
+ <frontend_type>textarea</frontend_type>
203
+ <sort_order>3</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
+ </config>
208
+ <weight_limit translate="label">
209
+ <label>Weight Limit</label>
210
+ <frontend_type>text</frontend_type>
211
+ <comment>in Kg</comment>
212
+ <sort_order>7</sort_order>
213
+ <show_in_default>1</show_in_default>
214
+ <show_in_website>1</show_in_website>
215
+ <show_in_store>1</show_in_store>
216
+ </weight_limit>
217
+ <quickcost translate="label">
218
+ <label>Quickcost</label>
219
+ <frontend_type>select</frontend_type>
220
+ <comment>To obtain the price from your rate grid</comment>
221
+ <source_model>adminhtml/system_config_source_yesno</source_model>
222
+ <sort_order>10</sort_order>
223
+ <show_in_default>1</show_in_default>
224
+ <show_in_website>1</show_in_website>
225
+ <show_in_store>0</show_in_store>
226
+ </quickcost>
227
+ <quickcost_url>
228
+ <label>Quickcost Url</label>
229
+ <frontend_type>text</frontend_type>
230
+ <sort_order>11</sort_order>
231
+ <show_in_default>1</show_in_default>
232
+ <show_in_website>1</show_in_website>
233
+ <show_in_store>0</show_in_store>
234
+ </quickcost_url>
235
+ <free_shipping_enable translate="label">
236
+ <label>Free Shipping on the Amount</label>
237
+ <frontend_type>select</frontend_type>
238
+ <source_model>adminhtml/system_config_source_enabledisable</source_model>
239
+ <sort_order>12</sort_order>
240
+ <show_in_default>1</show_in_default>
241
+ <show_in_website>1</show_in_website>
242
+ <show_in_store>1</show_in_store>
243
+ </free_shipping_enable>
244
+ <free_shipping_subtotal translate="label">
245
+ <label>Minimum Amount for Free Shipping</label>
246
+ <frontend_type>text</frontend_type>
247
+ <sort_order>13</sort_order>
248
+ <show_in_default>1</show_in_default>
249
+ <show_in_website>1</show_in_website>
250
+ <show_in_store>0</show_in_store>
251
+ </free_shipping_subtotal>
252
+ <application_fee translate="label">
253
+ <label>Application Fee</label>
254
+ <frontend_type>text</frontend_type>
255
+ <sort_order>14</sort_order>
256
+ <show_in_default>1</show_in_default>
257
+ <show_in_website>1</show_in_website>
258
+ <show_in_store>1</show_in_store>
259
+ </application_fee>
260
+ <handling_fee translate="label">
261
+ <label>Handling Fee</label>
262
+ <frontend_type>text</frontend_type>
263
+ <sort_order>15</sort_order>
264
+ <show_in_default>1</show_in_default>
265
+ <show_in_website>1</show_in_website>
266
+ <show_in_store>1</show_in_store>
267
+ </handling_fee>
268
+ <logo_url>
269
+ <label>Logo Url</label>
270
+ <frontend_type>text</frontend_type>
271
+ <comment>{logo_ulr_help}</comment>
272
+ <sort_order>18</sort_order>
273
+ <show_in_default>1</show_in_default>
274
+ <show_in_website>1</show_in_website>
275
+ <show_in_store>1</show_in_store>
276
+ </logo_url>
277
+ <debug>
278
+ <label>Debug</label>
279
+ <comment>{debug_help}</comment>
280
+ <frontend_type>text</frontend_type>
281
+ <sort_order>20</sort_order>
282
+ <show_in_default>1</show_in_default>
283
+ <show_in_website>1</show_in_website>
284
+ <show_in_store>1</show_in_store>
285
+ </debug>
286
+ <!--<stop_to_first_match translate="label">
287
+ <label>Stop to first match</label>
288
+ <frontend_type>select</frontend_type>
289
+ <source_model>adminhtml/system_config_source_yesno</source_model>
290
+ <sort_order>22</sort_order>
291
+ <show_in_default>1</show_in_default>
292
+ <show_in_website>1</show_in_website>
293
+ <show_in_store>1</show_in_store>
294
+ </stop_to_first_match>-->
295
+ <!-- deliver_on_saturday not included in chronoexpress only -->
296
+ <!--<showmethod translate="label">
297
+ <label>Show Method if Not Applicable</label>
298
+ <frontend_type>select</frontend_type>
299
+ <sort_order>30</sort_order>
300
+ <frontend_class>shipping-skip-hide</frontend_class>
301
+ <source_model>adminhtml/system_config_source_yesno</source_model>
302
+ <show_in_default>1</show_in_default>
303
+ <show_in_website>1</show_in_website>
304
+ <show_in_store>0</show_in_store>
305
+ </showmethod>
306
+ <specificerrmsg translate="label">
307
+ <label>Displayed Error Message</label>
308
+ <frontend_type>textarea</frontend_type>
309
+ <sort_order>31</sort_order>
310
+ <show_in_default>1</show_in_default>
311
+ <show_in_website>1</show_in_website>
312
+ <show_in_store>1</show_in_store>
313
+ </specificerrmsg>-->
314
+ <sort_order translate="label">
315
+ <label>Sort order</label>
316
+ <frontend_type>text</frontend_type>
317
+ <sort_order>100</sort_order>
318
+ <show_in_default>1</show_in_default>
319
+ <show_in_website>1</show_in_website>
320
+ <show_in_store>1</show_in_store>
321
+ </sort_order>
322
+ </fields>
323
+ </chronoexpress>
324
+
325
+ <chronorelais translate="label">
326
+ <label>Chrono Relais</label>
327
+ <frontend_type>text</frontend_type>
328
+ <sort_order>22</sort_order>
329
+ <show_in_default>1</show_in_default>
330
+ <show_in_website>1</show_in_website>
331
+ <show_in_store>1</show_in_store>
332
+ <fields>
333
+ <active translate="label">
334
+ <label>Enabled</label>
335
+ <frontend_type>select</frontend_type>
336
+ <source_model>adminhtml/system_config_source_yesno</source_model>
337
+ <sort_order>1</sort_order>
338
+ <show_in_default>1</show_in_default>
339
+ <show_in_website>1</show_in_website>
340
+ <show_in_store>1</show_in_store>
341
+ </active>
342
+ <title translate="label">
343
+ <label>Title</label>
344
+ <frontend_type>text</frontend_type>
345
+ <sort_order>2</sort_order>
346
+ <show_in_default>1</show_in_default>
347
+ <show_in_website>1</show_in_website>
348
+ <show_in_store>1</show_in_store>
349
+ </title>
350
+ <config translate="label">
351
+ <label>Configuration</label>
352
+ <frontend_model>chronorelais/adminhtml_system_config_form_field_config</frontend_model>
353
+ <comment>{configuration_syntax_help}</comment>
354
+ <frontend_type>textarea</frontend_type>
355
+ <sort_order>3</sort_order>
356
+ <show_in_default>1</show_in_default>
357
+ <show_in_website>1</show_in_website>
358
+ <show_in_store>1</show_in_store>
359
+ </config>
360
+ <weight_limit translate="label">
361
+ <label>Weight Limit</label>
362
+ <frontend_type>text</frontend_type>
363
+ <comment>in Kg</comment>
364
+ <sort_order>7</sort_order>
365
+ <show_in_default>1</show_in_default>
366
+ <show_in_website>1</show_in_website>
367
+ <show_in_store>1</show_in_store>
368
+ </weight_limit>
369
+ <quickcost translate="label">
370
+ <label>Quickcost</label>
371
+ <frontend_type>select</frontend_type>
372
+ <comment>To obtain the price from your rate grid</comment>
373
+ <source_model>adminhtml/system_config_source_yesno</source_model>
374
+ <sort_order>10</sort_order>
375
+ <show_in_default>1</show_in_default>
376
+ <show_in_website>1</show_in_website>
377
+ <show_in_store>0</show_in_store>
378
+ </quickcost>
379
+ <quickcost_url>
380
+ <label>Quickcost Url</label>
381
+ <frontend_type>text</frontend_type>
382
+ <sort_order>11</sort_order>
383
+ <show_in_default>1</show_in_default>
384
+ <show_in_website>1</show_in_website>
385
+ <show_in_store>0</show_in_store>
386
+ </quickcost_url>
387
+ <free_shipping_enable translate="label">
388
+ <label>Free Shipping with Minimum Order Amount</label>
389
+ <frontend_type>select</frontend_type>
390
+ <source_model>adminhtml/system_config_source_enabledisable</source_model>
391
+ <sort_order>12</sort_order>
392
+ <show_in_default>1</show_in_default>
393
+ <show_in_website>1</show_in_website>
394
+ <show_in_store>1</show_in_store>
395
+ </free_shipping_enable>
396
+ <free_shipping_subtotal translate="label">
397
+ <label>Minimum Order Amount for Free Shipping</label>
398
+ <frontend_type>text</frontend_type>
399
+ <sort_order>13</sort_order>
400
+ <show_in_default>1</show_in_default>
401
+ <show_in_website>1</show_in_website>
402
+ <show_in_store>1</show_in_store>
403
+ </free_shipping_subtotal>
404
+ <application_fee translate="label">
405
+ <label>Application Fee</label>
406
+ <frontend_type>text</frontend_type>
407
+ <sort_order>14</sort_order>
408
+ <show_in_default>1</show_in_default>
409
+ <show_in_website>1</show_in_website>
410
+ <show_in_store>1</show_in_store>
411
+ </application_fee>
412
+ <handling_fee translate="label">
413
+ <label>Handling Fee</label>
414
+ <frontend_type>text</frontend_type>
415
+ <sort_order>15</sort_order>
416
+ <show_in_default>1</show_in_default>
417
+ <show_in_website>1</show_in_website>
418
+ <show_in_store>1</show_in_store>
419
+ </handling_fee>
420
+ <logo_url>
421
+ <label>Logo Url</label>
422
+ <frontend_type>text</frontend_type>
423
+ <comment>{logo_ulr_help}</comment>
424
+ <sort_order>18</sort_order>
425
+ <show_in_default>1</show_in_default>
426
+ <show_in_website>1</show_in_website>
427
+ <show_in_store>1</show_in_store>
428
+ </logo_url>
429
+ <debug>
430
+ <label>Debug</label>
431
+ <comment>{debug_help}</comment>
432
+ <frontend_type>text</frontend_type>
433
+ <sort_order>20</sort_order>
434
+ <show_in_default>1</show_in_default>
435
+ <show_in_website>1</show_in_website>
436
+ <show_in_store>1</show_in_store>
437
+ </debug>
438
+ <!--<stop_to_first_match translate="label">
439
+ <label>Stop to first match</label>
440
+ <frontend_type>select</frontend_type>
441
+ <source_model>adminhtml/system_config_source_yesno</source_model>
442
+ <sort_order>22</sort_order>
443
+ <show_in_default>1</show_in_default>
444
+ <show_in_website>1</show_in_website>
445
+ <show_in_store>1</show_in_store>
446
+ </stop_to_first_match>-->
447
+ <deliver_on_saturday translate="label comment">
448
+ <label>Livraison le Samedi</label>
449
+ <comment>If yes has been selected, the option will be available every Thursdays from 6pm to Fridays at 3pm.</comment>
450
+ <frontend_type>select</frontend_type>
451
+ <source_model>adminhtml/system_config_source_yesno</source_model>
452
+ <sort_order>23</sort_order>
453
+ <show_in_default>1</show_in_default>
454
+ <show_in_website>1</show_in_website>
455
+ <show_in_store>1</show_in_store>
456
+ </deliver_on_saturday>
457
+ <!--<showmethod translate="label">
458
+ <label>Show Method if Not Applicable</label>
459
+ <frontend_type>select</frontend_type>
460
+ <sort_order>30</sort_order>
461
+ <frontend_class>shipping-skip-hide</frontend_class>
462
+ <source_model>adminhtml/system_config_source_yesno</source_model>
463
+ <show_in_default>1</show_in_default>
464
+ <show_in_website>1</show_in_website>
465
+ <show_in_store>0</show_in_store>
466
+ </showmethod>
467
+ <specificerrmsg translate="label">
468
+ <label>Displayed Error Message</label>
469
+ <frontend_type>textarea</frontend_type>
470
+ <sort_order>31</sort_order>
471
+ <show_in_default>1</show_in_default>
472
+ <show_in_website>1</show_in_website>
473
+ <show_in_store>1</show_in_store>
474
+ </specificerrmsg>-->
475
+ <sort_order translate="label">
476
+ <label>Sort order</label>
477
+ <frontend_type>text</frontend_type>
478
+ <sort_order>100</sort_order>
479
+ <show_in_default>1</show_in_default>
480
+ <show_in_website>1</show_in_website>
481
+ <show_in_store>1</show_in_store>
482
+ </sort_order>
483
+ </fields>
484
+ </chronorelais>
485
+ </groups>
486
+ </carriers>
487
+ </sections>
488
+
489
+ <sections>
490
+ <chronorelais>
491
+ <label>Chronopost Settings</label>
492
+ <tab>chronopost</tab>
493
+ <frontend_type>text</frontend_type>
494
+ <sort_order>2000</sort_order>
495
+ <show_in_default>1</show_in_default>
496
+ <show_in_website>1</show_in_website>
497
+ <show_in_store>1</show_in_store>
498
+ <groups>
499
+ <shipping translate="label">
500
+ <label>General</label>
501
+ <frontend_type>text</frontend_type>
502
+ <sort_order>10</sort_order>
503
+ <show_in_default>1</show_in_default>
504
+ <show_in_website>1</show_in_website>
505
+ <show_in_store>1</show_in_store>
506
+ <fields>
507
+ <account_number translate="label">
508
+ <label>N° de compte Chronopost</label>
509
+ <frontend_type>text</frontend_type>
510
+ <sort_order>7</sort_order>
511
+ <show_in_default>1</show_in_default>
512
+ <show_in_website>1</show_in_website>
513
+ <show_in_store>1</show_in_store>
514
+ </account_number>
515
+ <sub_account_number translate="label">
516
+ <label>Sous-compte</label>
517
+ <comment>must be 3 digits or empty</comment>
518
+ <frontend_type>text</frontend_type>
519
+ <sort_order>8</sort_order>
520
+ <show_in_default>1</show_in_default>
521
+ <show_in_website>1</show_in_website>
522
+ <show_in_store>1</show_in_store>
523
+ </sub_account_number>
524
+ <account_pass translate="label">
525
+ <label>Mot de passe Chronopost</label>
526
+ <frontend_type>text</frontend_type>
527
+ <sort_order>9</sort_order>
528
+ <show_in_default>1</show_in_default>
529
+ <show_in_website>1</show_in_website>
530
+ <show_in_store>1</show_in_store>
531
+ </account_pass>
532
+ <google_map_api translate="label">
533
+ <label>Google Map API Key</label>
534
+ <frontend_type>text</frontend_type>
535
+ <sort_order>10</sort_order>
536
+ <show_in_default>1</show_in_default>
537
+ <show_in_website>1</show_in_website>
538
+ <show_in_store>1</show_in_store>
539
+ </google_map_api>
540
+ <tracking_view_url translate="label">
541
+ <label>Tracking URL</label>
542
+ <comment>For English language, replace fr_FR with en_GB in the above url</comment>
543
+ <frontend_type>text</frontend_type>
544
+ <sort_order>20</sort_order>
545
+ <show_in_default>1</show_in_default>
546
+ <show_in_website>1</show_in_website>
547
+ <show_in_store>1</show_in_store>
548
+ </tracking_view_url>
549
+
550
+ </fields>
551
+ </shipping>
552
+ <export_css translate="label">
553
+ <label>Export Configuration CSS</label>
554
+ <frontend_type>text</frontend_type>
555
+ <sort_order>20</sort_order>
556
+ <show_in_default>1</show_in_default>
557
+ <show_in_website>1</show_in_website>
558
+ <show_in_store>1</show_in_store>
559
+ <fields>
560
+ <file_extension translate="label">
561
+ <label>File Extension</label>
562
+ <frontend_type>select</frontend_type>
563
+ <source_model>chronorelais/config_source_fileExtension</source_model>
564
+ <sort_order>10</sort_order>
565
+ <show_in_default>1</show_in_default>
566
+ <show_in_website>1</show_in_website>
567
+ <show_in_store>1</show_in_store>
568
+ </file_extension>
569
+ <file_charset translate="label">
570
+ <label>File Charset</label>
571
+ <frontend_type>select</frontend_type>
572
+ <source_model>chronorelais/config_source_fileCharset</source_model>
573
+ <sort_order>20</sort_order>
574
+ <show_in_default>1</show_in_default>
575
+ <show_in_website>1</show_in_website>
576
+ <show_in_store>1</show_in_store>
577
+ </file_charset>
578
+ <endofline_character translate="label">
579
+ <label>End Of Line Character</label>
580
+ <frontend_type>select</frontend_type>
581
+ <source_model>chronorelais/config_source_endOfLineCharacter</source_model>
582
+ <sort_order>30</sort_order>
583
+ <show_in_default>1</show_in_default>
584
+ <show_in_website>1</show_in_website>
585
+ <show_in_store>1</show_in_store>
586
+ </endofline_character>
587
+ <field_delimiter translate="label">
588
+ <label>Field Delimiter</label>
589
+ <frontend_type>select</frontend_type>
590
+ <source_model>chronorelais/config_source_fieldDelimiter</source_model>
591
+ <sort_order>40</sort_order>
592
+ <show_in_default>1</show_in_default>
593
+ <show_in_website>1</show_in_website>
594
+ <show_in_store>1</show_in_store>
595
+ </field_delimiter>
596
+ <field_separator translate="label">
597
+ <label>Field Separator</label>
598
+ <frontend_type>select</frontend_type>
599
+ <source_model>chronorelais/config_source_fieldSeparator</source_model>
600
+ <sort_order>50</sort_order>
601
+ <show_in_default>1</show_in_default>
602
+ <show_in_website>1</show_in_website>
603
+ <show_in_store>1</show_in_store>
604
+ </field_separator>
605
+ </fields>
606
+ </export_css>
607
+ <export_cso translate="label">
608
+ <label>Export Configuration CSO</label>
609
+ <frontend_type>text</frontend_type>
610
+ <sort_order>21</sort_order>
611
+ <show_in_default>1</show_in_default>
612
+ <show_in_website>1</show_in_website>
613
+ <show_in_store>1</show_in_store>
614
+ <fields>
615
+ <file_extension translate="label">
616
+ <label>File Extension</label>
617
+ <frontend_type>select</frontend_type>
618
+ <source_model>chronorelais/config_source_fileExtension</source_model>
619
+ <sort_order>10</sort_order>
620
+ <show_in_default>1</show_in_default>
621
+ <show_in_website>1</show_in_website>
622
+ <show_in_store>1</show_in_store>
623
+ </file_extension>
624
+ <file_charset translate="label">
625
+ <label>File Charset</label>
626
+ <frontend_type>select</frontend_type>
627
+ <source_model>chronorelais/config_source_fileCharset</source_model>
628
+ <sort_order>20</sort_order>
629
+ <show_in_default>1</show_in_default>
630
+ <show_in_website>1</show_in_website>
631
+ <show_in_store>1</show_in_store>
632
+ </file_charset>
633
+ <endofline_character translate="label">
634
+ <label>End Of Line Character</label>
635
+ <frontend_type>select</frontend_type>
636
+ <source_model>chronorelais/config_source_endOfLineCharacter</source_model>
637
+ <sort_order>30</sort_order>
638
+ <show_in_default>1</show_in_default>
639
+ <show_in_website>1</show_in_website>
640
+ <show_in_store>1</show_in_store>
641
+ </endofline_character>
642
+ <field_delimiter translate="label">
643
+ <label>Field Delimiter</label>
644
+ <frontend_type>select</frontend_type>
645
+ <source_model>chronorelais/config_source_fieldDelimiter</source_model>
646
+ <sort_order>40</sort_order>
647
+ <show_in_default>1</show_in_default>
648
+ <show_in_website>1</show_in_website>
649
+ <show_in_store>1</show_in_store>
650
+ </field_delimiter>
651
+ <field_separator translate="label">
652
+ <label>Field Separator</label>
653
+ <frontend_type>select</frontend_type>
654
+ <source_model>chronorelais/config_source_fieldSeparator</source_model>
655
+ <sort_order>50</sort_order>
656
+ <show_in_default>1</show_in_default>
657
+ <show_in_website>1</show_in_website>
658
+ <show_in_store>1</show_in_store>
659
+ </field_separator>
660
+ </fields>
661
+ </export_cso>
662
+ <import translate="label">
663
+ <label>Import Configuration</label>
664
+ <frontend_type>text</frontend_type>
665
+ <sort_order>30</sort_order>
666
+ <show_in_default>1</show_in_default>
667
+ <show_in_website>1</show_in_website>
668
+ <show_in_store>1</show_in_store>
669
+ <fields>
670
+ <default_tracking_title translate="label comment">
671
+ <label>Default Tracking Title</label>
672
+ <frontend_type>text</frontend_type>
673
+ <sort_order>10</sort_order>
674
+ <show_in_default>1</show_in_default>
675
+ <show_in_website>1</show_in_website>
676
+ <show_in_store>1</show_in_store>
677
+ <comment>This value can be changed in the import form</comment>
678
+ </default_tracking_title>
679
+ <send_email translate="label comment">
680
+ <label>Send an e-mail</label>
681
+ <frontend_type>select</frontend_type>
682
+ <source_model>adminhtml/system_config_source_yesno</source_model>
683
+ <sort_order>20</sort_order>
684
+ <show_in_default>1</show_in_default>
685
+ <show_in_website>1</show_in_website>
686
+ <show_in_store>1</show_in_store>
687
+ <comment>Send shipping confirmation to the customer</comment>
688
+ </send_email>
689
+ <shipping_comment translate="label comment">
690
+ <label>Shipping Comment</label>
691
+ <frontend_type>text</frontend_type>
692
+ <sort_order>30</sort_order>
693
+ <show_in_default>1</show_in_default>
694
+ <show_in_website>1</show_in_website>
695
+ <show_in_store>1</show_in_store>
696
+ <comment>Internal comment, can be left empty</comment>
697
+ </shipping_comment>
698
+ <include_comment translate="label comment">
699
+ <label>Include comment into e-mail</label>
700
+ <frontend_type>select</frontend_type>
701
+ <source_model>adminhtml/system_config_source_yesno</source_model>
702
+ <sort_order>40</sort_order>
703
+ <show_in_default>1</show_in_default>
704
+ <show_in_website>1</show_in_website>
705
+ <show_in_store>1</show_in_store>
706
+ <comment>Only applies if the shipping comment is set</comment>
707
+ </include_comment>
708
+ </fields>
709
+ </import>
710
+
711
+ <shipperinformation translate="label">
712
+ <label>Shipper Information for Labels printing</label>
713
+ <frontend_type>text</frontend_type>
714
+ <sort_order>40</sort_order>
715
+ <show_in_default>1</show_in_default>
716
+ <show_in_website>1</show_in_website>
717
+ <show_in_store>1</show_in_store>
718
+ <fields>
719
+ <civility translate="label">
720
+ <label>Shipper Civility</label>
721
+ <frontend_type>select</frontend_type>
722
+ <source_model>chronorelais/config_source_civility</source_model>
723
+ <sort_order>10</sort_order>
724
+ <show_in_default>1</show_in_default>
725
+ <show_in_website>1</show_in_website>
726
+ <show_in_store>1</show_in_store>
727
+ </civility>
728
+ <name translate="label comment">
729
+ <label>Shipper Name</label>
730
+ <frontend_type>text</frontend_type>
731
+ <sort_order>20</sort_order>
732
+ <show_in_default>1</show_in_default>
733
+ <show_in_website>1</show_in_website>
734
+ <show_in_store>1</show_in_store>
735
+ <comment>Company name</comment>
736
+ </name>
737
+ <name2 translate="label comment">
738
+ <label>Shipper Name2</label>
739
+ <frontend_type>text</frontend_type>
740
+ <sort_order>30</sort_order>
741
+ <show_in_default>1</show_in_default>
742
+ <show_in_website>1</show_in_website>
743
+ <show_in_store>1</show_in_store>
744
+ <comment>[Optional]</comment>
745
+ </name2>
746
+ <address1 translate="label">
747
+ <label>Shipper Address1</label>
748
+ <frontend_type>text</frontend_type>
749
+ <sort_order>40</sort_order>
750
+ <show_in_default>1</show_in_default>
751
+ <show_in_website>1</show_in_website>
752
+ <show_in_store>1</show_in_store>
753
+ </address1>
754
+ <address2 translate="label comment">
755
+ <label>Shipper Address2</label>
756
+ <frontend_type>text</frontend_type>
757
+ <sort_order>50</sort_order>
758
+ <show_in_default>1</show_in_default>
759
+ <show_in_website>1</show_in_website>
760
+ <show_in_store>1</show_in_store>
761
+ <comment>[Optional]</comment>
762
+ </address2>
763
+ <zipcode translate="label">
764
+ <label>Shipper Zipcode</label>
765
+ <frontend_type>text</frontend_type>
766
+ <sort_order>60</sort_order>
767
+ <show_in_default>1</show_in_default>
768
+ <show_in_website>1</show_in_website>
769
+ <show_in_store>1</show_in_store>
770
+ </zipcode>
771
+ <city translate="label">
772
+ <label>Shipper City</label>
773
+ <frontend_type>text</frontend_type>
774
+ <sort_order>70</sort_order>
775
+ <show_in_default>1</show_in_default>
776
+ <show_in_website>1</show_in_website>
777
+ <show_in_store>1</show_in_store>
778
+ </city>
779
+ <country translate="label">
780
+ <label>Shipper Country</label>
781
+ <frontend_type>select</frontend_type>
782
+ <sort_order>80</sort_order>
783
+ <source_model>adminhtml/system_config_source_country</source_model>
784
+ <show_in_default>1</show_in_default>
785
+ <show_in_website>1</show_in_website>
786
+ <show_in_store>1</show_in_store>
787
+ </country>
788
+ <contactname translate="label">
789
+ <label>Shipper Contact Name</label>
790
+ <frontend_type>text</frontend_type>
791
+ <sort_order>90</sort_order>
792
+ <show_in_default>1</show_in_default>
793
+ <show_in_website>1</show_in_website>
794
+ <show_in_store>1</show_in_store>
795
+ </contactname>
796
+ <email translate="label">
797
+ <label>Shipper Email</label>
798
+ <frontend_type>text</frontend_type>
799
+ <sort_order>100</sort_order>
800
+ <show_in_default>1</show_in_default>
801
+ <show_in_website>1</show_in_website>
802
+ <show_in_store>1</show_in_store>
803
+ <comment>[Optional]</comment>
804
+ </email>
805
+ <phone translate="label comment">
806
+ <label>Shipper Telephone</label>
807
+ <frontend_type>text</frontend_type>
808
+ <sort_order>110</sort_order>
809
+ <show_in_default>1</show_in_default>
810
+ <show_in_website>1</show_in_website>
811
+ <show_in_store>1</show_in_store>
812
+ <comment>[Optional]</comment>
813
+ </phone>
814
+ <mobilephone translate="label comment">
815
+ <label>Shipper Mobile</label>
816
+ <frontend_type>text</frontend_type>
817
+ <sort_order>120</sort_order>
818
+ <show_in_default>1</show_in_default>
819
+ <show_in_website>1</show_in_website>
820
+ <show_in_store>1</show_in_store>
821
+ <comment>[Optional]</comment>
822
+ </mobilephone>
823
+ </fields>
824
+ </shipperinformation>
825
+
826
+ <customerinformation translate="label">
827
+ <label>Chronopost Customer Account Information for Labels printing</label>
828
+ <frontend_type>text</frontend_type>
829
+ <sort_order>50</sort_order>
830
+ <show_in_default>1</show_in_default>
831
+ <show_in_website>1</show_in_website>
832
+ <show_in_store>1</show_in_store>
833
+ <fields>
834
+ <civility translate="label">
835
+ <label>Customer Civility</label>
836
+ <frontend_type>select</frontend_type>
837
+ <source_model>chronorelais/config_source_civility</source_model>
838
+ <sort_order>10</sort_order>
839
+ <show_in_default>1</show_in_default>
840
+ <show_in_website>1</show_in_website>
841
+ <show_in_store>1</show_in_store>
842
+ </civility>
843
+ <name translate="label comment">
844
+ <label>Customer Name </label>
845
+ <frontend_type>text</frontend_type>
846
+ <sort_order>20</sort_order>
847
+ <show_in_default>1</show_in_default>
848
+ <show_in_website>1</show_in_website>
849
+ <show_in_store>1</show_in_store>
850
+ <comment>Company name</comment>
851
+ </name>
852
+ <name2 translate="label comment">
853
+ <label>Customer Name2</label>
854
+ <frontend_type>text</frontend_type>
855
+ <sort_order>30</sort_order>
856
+ <show_in_default>1</show_in_default>
857
+ <show_in_website>1</show_in_website>
858
+ <show_in_store>1</show_in_store>
859
+ <comment>[Optional]</comment>
860
+ </name2>
861
+ <address1 translate="label">
862
+ <label>Customer Address1</label>
863
+ <frontend_type>text</frontend_type>
864
+ <sort_order>40</sort_order>
865
+ <show_in_default>1</show_in_default>
866
+ <show_in_website>1</show_in_website>
867
+ <show_in_store>1</show_in_store>
868
+ </address1>
869
+ <address2 translate="label comment">
870
+ <label>Customer Address2</label>
871
+ <frontend_type>text</frontend_type>
872
+ <sort_order>50</sort_order>
873
+ <show_in_default>1</show_in_default>
874
+ <show_in_website>1</show_in_website>
875
+ <show_in_store>1</show_in_store>
876
+ <comment>[Optional]</comment>
877
+ </address2>
878
+ <zipcode translate="label">
879
+ <label>Customer Zipcode</label>
880
+ <frontend_type>text</frontend_type>
881
+ <sort_order>60</sort_order>
882
+ <show_in_default>1</show_in_default>
883
+ <show_in_website>1</show_in_website>
884
+ <show_in_store>1</show_in_store>
885
+ </zipcode>
886
+ <city translate="label">
887
+ <label>Customer City</label>
888
+ <frontend_type>text</frontend_type>
889
+ <sort_order>70</sort_order>
890
+ <show_in_default>1</show_in_default>
891
+ <show_in_website>1</show_in_website>
892
+ <show_in_store>1</show_in_store>
893
+ </city>
894
+ <country translate="label">
895
+ <label>Customer Country</label>
896
+ <frontend_type>select</frontend_type>
897
+ <sort_order>80</sort_order>
898
+ <source_model>adminhtml/system_config_source_country</source_model>
899
+ <show_in_default>1</show_in_default>
900
+ <show_in_website>1</show_in_website>
901
+ <show_in_store>1</show_in_store>
902
+ </country>
903
+ <contactname translate="label">
904
+ <label>Customer Contact Name</label>
905
+ <frontend_type>text</frontend_type>
906
+ <sort_order>90</sort_order>
907
+ <show_in_default>1</show_in_default>
908
+ <show_in_website>1</show_in_website>
909
+ <show_in_store>1</show_in_store>
910
+ </contactname>
911
+ <email translate="label">
912
+ <label>Customer Email</label>
913
+ <frontend_type>text</frontend_type>
914
+ <sort_order>100</sort_order>
915
+ <show_in_default>1</show_in_default>
916
+ <show_in_website>1</show_in_website>
917
+ <show_in_store>1</show_in_store>
918
+ <comment>[Optional]</comment>
919
+ </email>
920
+ <phone translate="label comment">
921
+ <label>Customer Telephone</label>
922
+ <frontend_type>text</frontend_type>
923
+ <sort_order>110</sort_order>
924
+ <show_in_default>1</show_in_default>
925
+ <show_in_website>1</show_in_website>
926
+ <show_in_store>1</show_in_store>
927
+ <comment>[Optional]</comment>
928
+ </phone>
929
+ <mobilephone translate="label comment">
930
+ <label>Customer Mobile</label>
931
+ <frontend_type>text</frontend_type>
932
+ <sort_order>120</sort_order>
933
+ <show_in_default>1</show_in_default>
934
+ <show_in_website>1</show_in_website>
935
+ <show_in_store>1</show_in_store>
936
+ <comment>[Optional]</comment>
937
+ </mobilephone>
938
+ </fields>
939
+ </customerinformation>
940
+
941
+ <skybillparam translate="label">
942
+ <label>Skybill Parameters for Labels printing</label>
943
+ <frontend_type>text</frontend_type>
944
+ <sort_order>60</sort_order>
945
+ <show_in_default>1</show_in_default>
946
+ <show_in_website>1</show_in_website>
947
+ <show_in_store>1</show_in_store>
948
+ <fields>
949
+ <mode translate="label">
950
+ <label>Print Mode</label>
951
+ <frontend_type>select</frontend_type>
952
+ <source_model>chronorelais/config_source_printMode</source_model>
953
+ <sort_order>10</sort_order>
954
+ <show_in_default>1</show_in_default>
955
+ <show_in_website>1</show_in_website>
956
+ <show_in_store>1</show_in_store>
957
+ <required>1</required>
958
+ </mode>
959
+ </fields>
960
+ </skybillparam>
961
+ </groups>
962
+ </chronorelais>
963
+ </sections>
964
+
965
+ </config>
app/code/community/Chronopost/Chronorelais/includes/ChronorelaisShippingHelper.php ADDED
@@ -0,0 +1,1245 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class ChronorelaisShippingHelper
3
+ {
4
+ public static $DEBUG_INDEX_COUNTER = 0;
5
+ public static $FLOAT_REGEX = '[-]?\d+(?:[.]\d+)?';
6
+ public static $POSITIVE_FLOAT_REGEX = '\d+(?:[.]\d+)?';
7
+ //public static $COUPLE_REGEX = '(?:[0-9.]+|\*)(?:\[|\])?\:[0-9.]+(?:\:[0-9.]+%?)*';
8
+ public static $COUPLE_REGEX = '(?:[0-9.]+|\*) *(?:\[|\])? *\: *[0-9.]+';
9
+ public static $UNCOMPRESSED_STRINGS = array(
10
+ ' product.attribute.',
11
+ ' product.option.',
12
+ ' product.stock.',
13
+ '{product.attribute.',
14
+ '{product.option.',
15
+ '{product.stock.',
16
+ '{product.weight}',
17
+ '{product.quantity}',
18
+ '{cart.weight}',
19
+ '{cart.quantity}',
20
+ '{cart.price_including_tax}',
21
+ '{cart.price_excluding_tax}',
22
+ '{cart.',
23
+ '{customvar.',
24
+ '{selection.weight}',
25
+ '{selection.quantity}',
26
+ '{selection.',
27
+ '{destination.country.',
28
+ '{foreach ',
29
+ '{/foreach}',
30
+ );
31
+ public static $COMPRESSED_STRINGS = array(
32
+ ' p.a.',
33
+ ' p.o.',
34
+ ' p.s.',
35
+ '{p.a.',
36
+ '{p.o.',
37
+ '{p.s.',
38
+ '{p.w}',
39
+ '{p.qty}',
40
+ '{c.w}',
41
+ '{c.qty}',
42
+ '{c.pit}',
43
+ '{c.pet}',
44
+ '{c.',
45
+ '{v.',
46
+ '{s.w}',
47
+ '{s.qty}',
48
+ '{s.',
49
+ '{dest.ctry.',
50
+ '{each ',
51
+ '{/each}',
52
+ );
53
+
54
+ protected $_input;
55
+ protected $_config;
56
+ protected $_messages;
57
+ protected $_formula_cache;
58
+ protected $_expression_cache;
59
+ public $debug = 0;
60
+ public $debug_output = '';
61
+ public $debug_header = null;
62
+
63
+ public function ChronorelaisShippingHelper($input) {
64
+ $this->_formula_cache = array();
65
+ $this->_messages = array();
66
+ $this->_input = $input;
67
+ $this->_config = array();
68
+ $this->_parseInput();
69
+ }
70
+
71
+ private function debug($text, $level=10) {
72
+ if ($this->debug>=$level) $this->debug_output .= "<p>".$text."</p>";
73
+ }
74
+
75
+ public function printDebug() {
76
+ if ($this->debug>0) {
77
+ $index = self::$DEBUG_INDEX_COUNTER++;
78
+ echo "<style rel=\"stylesheet\" type=\"text/css\">"
79
+ .".osh-formula{color:#f90;} .osh-key{color:#0099f7;}"
80
+ .".osh-error{color:#f00;} .osh-warning{color:#ff0;} .osh-info{color:#7bf700;}"
81
+ .".osh-debug{background:#000;color:#bbb;position:absolute;top:0;left:0;width:100%;z-index:100;-moz-opacity:0.9;opacity:0.9;text-align:left;white-space:pre-wrap;}"
82
+ .".osh-debug-content{padding:10px;}"
83
+ .".osh-replacement{color:#ff3000;}"
84
+ ."</style>"
85
+ ."<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>"
86
+ ."<p>".$this->debug_header."</p>".$this->debug_output."</pre></div>";
87
+ }
88
+ }
89
+
90
+ public function setDebugHeader($process) {
91
+ $header = 'DEBUG app/code/community/Chronopost/Chronorelais/Model/Carrier/ChronorelaisShippingHelper.php<br/>';
92
+ foreach ($process['data'] as $key => $data) {
93
+ $header .= ' <span class="osh-key">'.$key.'</span> = <span class="osh-formula">'.$this->_toString($data).'</span><br/>';
94
+ }
95
+ $this->debug_header = $header;
96
+ }
97
+
98
+ public function getConfig() {
99
+ return $this->_config;
100
+ }
101
+
102
+ public function getMessages() {
103
+ $messages = $this->_messages;
104
+ $this->_messages = array();
105
+ return $messages;
106
+ }
107
+
108
+ public function formatConfig($compress) {
109
+ $output = '';
110
+ foreach ($this->_config as $code => $row) {
111
+ if (!isset($row['lines'])) {
112
+ if (isset($row['*comment']['value'])) {
113
+ $output .= trim($row['*comment']['value'])."\n";
114
+ }
115
+ $output .= '{'.($compress ? '' : "\n");
116
+ foreach ($row as $key => $property) {
117
+ if (substr($key,0,1)!='*') {
118
+ $value = $property['value'];
119
+ if (isset($property['comment'])) $output .= ($compress ? '' : "\t").'/* '.$property['comment'].' */'.($compress ? '' : "\n");
120
+ $output .= ($compress ? '' : "\t").$key.':'.($compress ? '' : ' ');
121
+ if (is_bool($value)) $output .= $value ? 'true' : 'false';
122
+ else if (is_int($value)) $output .= $value;
123
+ else if ((string)((float)$value)==$value) $output .= $value;
124
+ else $output .= '"'.str_replace('"','\\"',$value).'"';
125
+ $output .= ','.($compress ? '' : "\n");
126
+ }
127
+ }
128
+ if ($compress) $output = preg_replace('/,$/','',$output);
129
+ $output .= "}\n".($compress ? '' : "\n");
130
+ } else {
131
+ $output .= $row['lines']."\n";
132
+ }
133
+ }
134
+ return $compress ? $this->compress($output) : $this->uncompress($output);
135
+ }
136
+
137
+ public function checkConfig() {
138
+ $process = array(
139
+ 'result' => null,
140
+ 'data' => array(
141
+ 'cart.price_excluding_tax' => 0,
142
+ 'cart.price_including_tax' => 0,
143
+ 'destination.country.code' => '',
144
+ 'destination.country.name' => '',
145
+ 'destination.region.code' => '',
146
+ 'destination.postcode' => '',
147
+ 'origin.country.code' => '',
148
+ 'origin.country.name' => '',
149
+ 'origin.region.code' => '',
150
+ 'origin.postcode' => '',
151
+ 'free_shipping' => false,
152
+ 'customer.group.id' => '',
153
+ 'customer.group.code' => '',
154
+ 'cart.weight' => 0,
155
+ 'cart.weight.unit' => 'kg',
156
+ 'cart.quantity' => 0,
157
+ ),
158
+ 'cart.items' => array(),
159
+ 'products' => array(),
160
+ 'config' => $this->_config,
161
+ );
162
+ foreach ($this->_config as $code => &$row) {
163
+ $this->processRow($process,$row,$check_all_conditions=true);
164
+ foreach ($row as $property_key => $property_value) {
165
+ if (substr($property_key,0,1)!='*') $this->getRowProperty($row,$property_key);
166
+ }
167
+ }
168
+ }
169
+
170
+ public function processRow($process, &$row, $is_checking=false) {
171
+ if (!isset($row['*code'])) return;
172
+
173
+ self::debug('process row <span class="osh-key">'.$row['*code'].'</span>',1);
174
+ if (!isset($row['label']['value'])) $row['label']['value'] = '***';
175
+
176
+ $enabled = $this->getRowProperty($row,'enabled');
177
+ if (isset($enabled)) {
178
+ if (!$is_checking && !$enabled) {
179
+ $this->addMessage('info',$row,'enabled','Configuration disabled');
180
+ return new OCS_Result(false);
181
+ }
182
+ }
183
+
184
+ $conditions = $this->getRowProperty($row,'conditions');
185
+ if (isset($conditions)) {
186
+ $result = $this->_processFormula($process,$row,'conditions',$conditions,$is_checking);
187
+ if (!$is_checking) {
188
+ if (!$result->success) return $result;
189
+ if (!$result->result) {
190
+ $this->addMessage('info',$row,'conditions',"The cart doesn't match conditions");
191
+ return new OCS_Result(false);
192
+ }
193
+ }
194
+ }
195
+
196
+ $destination = $this->getRowProperty($row,'destination');
197
+ if (isset($destination)) {
198
+ $destination_match = $this->_addressMatch($destination,array(
199
+ 'country_code' => $process['data']['destination.country.code'],
200
+ 'region_code' => $process['data']['destination.region.code'],
201
+ 'postcode' => $process['data']['destination.postcode']
202
+ ));
203
+ if (!$is_checking && !$destination_match) {
204
+ $this->addMessage('info',$row,'destination',"The shipping method doesn't cover the zone");
205
+ return new OCS_Result(false);
206
+ }
207
+ }
208
+
209
+ $origin = $this->getRowProperty($row,'origin');
210
+ if (isset($origin)) {
211
+ $origin_match = $this->_addressMatch($origin,array(
212
+ 'country_code' => $process['data']['origin.country.code'],
213
+ 'region_code' => $process['data']['origin.region.code'],
214
+ 'postcode' => $process['data']['origin.postcode']
215
+ ));
216
+ if (!$is_checking && !$origin_match) {
217
+ $this->addMessage('info',$row,'origin',"The shipping method doesn't match to shipping origin");
218
+ return new OCS_Result(false);
219
+ }
220
+ }
221
+
222
+ $customer_groups = $this->getRowProperty($row,'customer_groups');
223
+ if (isset($customer_groups)) {
224
+ $groups = explode(',',$customer_groups);
225
+ $group_match = false;
226
+ //self::debug('code:'.$process['data']['customer.group.code'].', id:'.$process['data']['customer.group.id']);
227
+ foreach ($groups as $group) {
228
+ $group = trim($group);
229
+ if ($group==$process['data']['customer.group.code'] || is_int($group) && $group==$process['data']['customer.group.id'] || $group=='*') {
230
+ $group_match = true;
231
+ break;
232
+ }
233
+ }
234
+ if (!$is_checking && !$group_match) {
235
+ $this->addMessage('info',$row,'customer_groups',"The shipping method doesn't match to customer group (%s)",$process['data']['customer.group.code']);
236
+ return new OCS_Result(false);
237
+ }
238
+ }
239
+
240
+ //Chronopost quickcost method for dynamic price if it is set enabled
241
+ $quickcost = Mage::getStoreConfig('carriers/'.$process['data']['carrier.code'].'/quickcost');
242
+ if($quickcost) {
243
+ if($quickCostValues = $this->getQuickCostValue($process['data'])) {
244
+ if($quickCostValues->errorCode==0) {
245
+ return new OCS_Result(true,(float)$quickCostValues->amountTTC);
246
+ } else {
247
+ $this->addMessage('error',$row,'chronopost',$quickCostValues->errorMessage);
248
+ return new OCS_Result(false);
249
+ }
250
+ } else {
251
+ return new OCS_Result(false);
252
+ }
253
+ }
254
+
255
+ $fees = $this->getRowProperty($row,'fees');
256
+ if (isset($fees)) {
257
+ $result = $this->_processFormula($process,$row,'fees',$fees,$is_checking);
258
+ if (!$result->success) return $result;
259
+ self::debug(' => <span class="osh-info">result = <span class="osh-formula">'.$this->_toString($result->result).'</span>',1);
260
+ return new OCS_Result(true,(float)$result->result);
261
+ }
262
+
263
+ return new OCS_Result(false);
264
+ }
265
+
266
+ public function getQuickCostValue($processData) {
267
+ $quickCost = array();
268
+ $_helper = Mage::helper('chronorelais');
269
+ $account_number = $_helper->getConfigurationAccountNumber();
270
+ $password = $_helper->getConfigurationAccountPass();
271
+ $productCode = $_helper->getChronoProductCode($processData['destination.country.code'], $processData['carrier.code']);
272
+ $origin_postcode = $_helper->getConfigurationShipperInfo('zipcode');
273
+
274
+ //to get arrival code
275
+ $arrCode = $processData['destination.postcode'];
276
+ if($processData['carrier.code']=='chronoexpress') {
277
+ $arrCode = $processData['destination.country.code'];
278
+ }
279
+
280
+ $quickCost = array(
281
+ 'contratNumber' => $account_number,
282
+ 'depCode' => $origin_postcode,
283
+ 'arrCode' => $arrCode,
284
+ 'weight' => $processData['cart.weight'],
285
+ 'productCode' => $productCode,
286
+ 'type' => 'M',
287
+ 'password' => $password
288
+ );
289
+
290
+ try {
291
+ $quickcost_url = Mage::helper('chronorelais')->getConfigData('carriers/'.$process['data']['carrier.code'].'/quickcost_url');
292
+ if(!$quickcost_url) { $quickcost_url = "http://wsshipping.chronopost.fr/wsQuickcost/services/ServiceQuickCost?wsdl"; }
293
+ $client = new SoapClient($quickcost_url);
294
+ $webservbt = $client->__call("quickCost",$quickCost);
295
+ return $webservbt;
296
+ } catch(SoapFault $fault) {
297
+ $this->addMessage('info',$row,'chronopost',$fault->faultstring);
298
+ return false;
299
+ }
300
+ }
301
+
302
+ public function getRowProperty(&$row, $key, $original_row=null, $original_key=null) {
303
+ $property = null;
304
+ $output = null;
305
+ if (isset($original_row) && isset($original_key) && $original_row['*code']==$row['*code'] && $original_key==$key) {
306
+ $this->addMessage('error',$row,$key,'Infinite loop %s',"<span class=\"code\">{".$row['*code'].'.'.$key."}</span>");
307
+ return array('error' => 'Infinite loop');
308
+ }
309
+ if (isset($row[$key]['value'])) {
310
+ $property = $row[$key]['value'];
311
+ $output = $property;
312
+ self::debug(' get <span class="osh-key">'.$row['*code'].'</span>.<span class="osh-key">'.$key.'</span> = <span class="osh-formula">'.$this->_toString($property).'</span>',5);
313
+ preg_match_all('/{([a-z0-9_]+)\.([a-z0-9_]+)}/i',$output,$result_set,PREG_SET_ORDER);
314
+ foreach ($result_set as $result) {
315
+ list($original,$ref_code,$ref_key) = $result;
316
+ if (!in_array($ref_code,array('module','date','store','cart','product','selection','customvar'))) {
317
+ if ($ref_code==$row['code']['value'] && $ref_key==$key) {
318
+ $this->addMessage('error',$row,$key,'Infinite loop %s',"<span class=\"code\">".$original."</span>");
319
+ return null;
320
+ }
321
+ if (isset($this->_config[$ref_code][$ref_key]['value'])) {
322
+ $replacement = $this->getRowProperty($this->_config[$ref_code],$ref_key,
323
+ isset($original_row) ? $original_row : $row,isset($original_key) ? $original_key : $key);
324
+ if (is_array($replacement) && isset($replacement['error'])) {
325
+ return isset($original_row) ? $replacement : 'false';
326
+ }
327
+ } else {
328
+ $this->addMessage('error',$row,$key,'Non-existent property %s',"<span class=\"code\">".$original."</span>");
329
+ $replacement = 'null';
330
+ }
331
+ $output = $this->replace($original,$replacement,$output);
332
+ }
333
+ }
334
+ } else {
335
+ self::debug(' get <span class="osh-key">'.$row['*code'].'</span>.<span class="osh-key">'.$key.'</span> = <span class="osh-formula">null</span>',5);
336
+ }
337
+ return $output;
338
+ }
339
+
340
+ protected function _toString($value) {
341
+ if (!isset($value)) return 'null';
342
+ else if (is_bool($value)) return $value ? 'true' : 'false';
343
+ else return $value;
344
+ }
345
+
346
+ protected function replace($from, $to, $input) {
347
+ if ($from===$to) return $input;
348
+ if (strpos($input,$from)===false) return $input;
349
+ $to = $this->_toString($to);
350
+ self::debug(' replace <span class="osh-replacement">'.$this->_toString($from).'</span> by <span class="osh-replacement">'.$to.'</span> =&gt; <span class="osh-formula">'.str_replace($from,'<span class="osh-replacement">'.$to.'</span>',$input).'</span>',5);
351
+ return str_replace($from,$to,$input);
352
+ }
353
+
354
+ protected function _min() {
355
+ $args = func_get_args();
356
+ $min = null;
357
+ foreach ($args as $arg) {
358
+ if (isset($arg) && (!isset($min) || $min>$arg)) $min = $arg;
359
+ }
360
+ return $min;
361
+ }
362
+
363
+ protected function _max() {
364
+ $args = func_get_args();
365
+ $max = null;
366
+ foreach ($args as $arg) {
367
+ if (isset($arg) && (!isset($max) || $max<$arg)) $max = $arg;
368
+ }
369
+ return $max;
370
+ }
371
+
372
+ protected function _processFormula($process, &$row, $property_key, $formula_string, $is_checking, $use_cache=true)
373
+ {
374
+ $result = $this->_prepareFormula($process,$row,$property_key,$formula_string,$is_checking,$use_cache);
375
+ if (!$result->success) return $result;
376
+
377
+ $eval_result = $this->_evalFormula($result->result);
378
+ if (!isset($eval_result)) {
379
+ $this->addMessage('error',$row,$property_key,'Invalid formula');
380
+ $result = new OCS_Result(false);
381
+ if ($use_cache) $this->setCache($formula_string,$result);
382
+ return $result;
383
+ }
384
+ self::debug(' formula evaluation = <span class="osh-formula">'.$this->_toString($eval_result).'</span>',10);
385
+ $result = new OCS_Result(true,$eval_result);
386
+ if ($use_cache) $this->setCache($formula_string,$result);
387
+ return $result;
388
+ }
389
+
390
+ public function evalInput($process, $row, $property_key, $input) {
391
+ $result = $this->_prepareFormula($process,$row,$property_key,$input,$is_checking=false,$use_cache=true);
392
+ return $result->success ? $result->result : $input;
393
+ }
394
+
395
+ protected function setCache($expression, $value) {
396
+ if ($value instanceof OCS_Result) {
397
+ $this->_formula_cache[$expression] = $value;
398
+ self::debug(' cache <span class="osh-replacement">'.$expression.'</span> = <span class="osh-formula">'.$this->_toString($this->_formula_cache[$expression]).'</span>',10);
399
+ } else {
400
+ $value = $this->_toString($value);
401
+ $this->_expression_cache[$expression] = $value;
402
+ self::debug(' cache <span class="osh-replacement">'.$expression.'</span> = <span class="osh-formula">'.$value.'</span>',10);
403
+ }
404
+ }
405
+
406
+ protected function _prepareFormula($process, $row, $property_key, $formula_string, $is_checking, $use_cache=true)
407
+ {
408
+ if ($use_cache && isset($this->_formula_cache[$formula_string])) {
409
+ $result = $this->_formula_cache[$formula_string];
410
+ self::debug(' get cached formula <span class="osh-replacement">'.$formula_string.'</span> = <span class="osh-formula">'.$this->_toString($result->result).'</span>',10);
411
+ return $result;
412
+ }
413
+
414
+ $formula = $formula_string;
415
+ //self::debug(' formula = <span class="osh-formula">'.$formula.'</span>',10);
416
+
417
+ while (preg_match("#{foreach product\.((?:attribute|option)\.(?:[a-z0-9_]+))}(.*){/foreach}#i",$formula,$result)) {
418
+ $original = $result[0];
419
+ if ($use_cache && isset($this->_expression_cache[$original])) {
420
+ $replacement = $this->_expression_cache[$original];
421
+ self::debug(' get cached expression <span class="osh-replacement">'.$original.'</span> = <span class="osh-formula">'.$replacement.'</span>',10);
422
+ }
423
+ else {
424
+ $replacement = 0;
425
+ list($filter_property_type,$filter_property_name) = explode('.',$result[1]);
426
+ $selections = array();
427
+ self::debug(' :: foreach <span class="osh-key">'.$filter_property_type.'</span>.<span class="osh-key">'.$filter_property_name.'</span>',10);
428
+ foreach ($process['products'] as $product) {
429
+ $tmp_value = $this->_getProductProperty($product,$filter_property_type,$filter_property_name,$get_by_id=false);
430
+ self::debug(' products[<span class="osh-formula">'.$product->getName().'</span>].<span class="osh-key">'.$filter_property_type.'</span>.<span class="osh-key">'.$filter_property_name.'</span> = <span class="osh-formula">'.$this->_toString($tmp_value).'</span>',10);
431
+ $key = 'val_'.$tmp_value;
432
+ $sel = isset($selections[$key]) ? $selections[$key] : null;
433
+ $selections[$key]['products'][] = $product;
434
+ $selections[$key]['weight'] = (isset($sel['weight']) ? $sel['weight'] : 0)+$product->getAttribute('weight')*$product->getQuantity();
435
+ $selections[$key]['quantity'] = (isset($sel['quantity']) ? $sel['quantity'] : 0)+$product->getQuantity();
436
+ }
437
+ self::debug(' :: start foreach',10);
438
+ foreach ($selections as $selection) {
439
+ $process2 = $process;
440
+ $process2['products'] = $selection['products'];
441
+ $process2['data']['selection.quantity'] = $selection['quantity'];
442
+ $process2['data']['selection.weight'] = $selection['weight'];
443
+ $process_result = $this->_processFormula($process2,$row,$property_key,$result[2],$is_checking,$tmp_use_cache=false);
444
+ $replacement += $process_result->result;
445
+ }
446
+ self::debug(' :: end foreach <span class="osh-key">'.$filter_property_type.'</span>.<span class="osh-key">'.$filter_property_name.'</span>',10);
447
+ if ($use_cache) $this->setCache($original,$replacement);
448
+ }
449
+ $formula = $this->replace($original,$replacement,$formula);
450
+ }
451
+
452
+ $formula = str_replace(array("\n","\t"),array('',''),$formula);
453
+
454
+ while (preg_match("#{customvar\.([a-z0-9_]+)}#i",$formula,$result)) {
455
+ $original = $result[0];
456
+ $replacement = Mage::getModel('core/variable')->loadByCode($result[1])->getValue('plain');
457
+ $formula = $this->replace($original,$replacement,$formula);
458
+ }
459
+
460
+ $first_product = isset($process['products'][0]) ? $process['products'][0] : null;
461
+ if (!isset($process['data']['selection.weight'])) $process['data']['selection.weight'] = $process['data']['cart.weight'];
462
+ if (!isset($process['data']['selection.quantity'])) $process['data']['selection.quantity'] = $process['data']['cart.quantity'];
463
+ $process['data']['product.weight'] = isset($first_product) ? $first_product->getAttribute('weight') : 0;
464
+ $process['data']['product.quantity'] = isset($first_product) ? $first_product->getQuantity() : 0;
465
+
466
+ foreach ($process['data'] as $original => $replacement) {
467
+ $formula = $this->replace('{'.$original.'}',$replacement,$formula);
468
+ }
469
+
470
+ if (isset($first_product)) {
471
+ while (preg_match("#{product\.(attribute|option|stock)\.([a-z0-9_]+)}#i",$formula,$result)) {
472
+ $original = $result[0];
473
+ switch ($result[1]) {
474
+ case 'attribute': $replacement = $first_product->getAttribute($result[2]); break;
475
+ case 'option': $replacement = $first_product->getOption($result[2]); break;
476
+ case 'stock': $replacement = $first_product->getStockData($result[2]); break;
477
+ }
478
+ $formula = $this->replace($original,$replacement,$formula);
479
+ }
480
+ }
481
+
482
+ //while (preg_match("/{(count|all|any) (attribute|option) '([^'\)]+)' ?(==|<=|>=|<|>|!=) ?(".self::$FLOAT_REGEX."|true|false|'[^'\)]*')}/",$formula,$result)
483
+ // || preg_match("/{(sum|count distinct) (attribute|option) '([^'\)]+)'}/",$formula,$result))
484
+ while (preg_match("/{(count) products(?: where ([^}]+))?}/i",$formula,$result)
485
+ || preg_match("/{(sum|count distinct) product\.(attribute|option)\.([a-z0-9_]+)(?: where ([^}]+))?}/i",$formula,$result)) {
486
+ $original = $result[0];
487
+ if ($use_cache && isset($this->_expression_cache[$original])) {
488
+ $replacement = $this->_expression_cache[$original];
489
+ self::debug(' get cached expression <span class="osh-replacement">'.$original.'</span> = <span class="osh-formula">'.$replacement.'</span>',10);
490
+ }
491
+ else {
492
+ $replacement = $this->_processProductProperty($process['products'],$result);
493
+ if ($use_cache) $this->setCache($result[0],$replacement);
494
+ }
495
+ $formula = $this->replace($original,$replacement,$formula);
496
+ }
497
+
498
+ //while (preg_match("/{table '([^']+)' ([^}]+)}/",$formula,$result))
499
+ while (preg_match("/{table ([^}]+) in ([0-9\.:,\*\[\] ]+)}/i",$formula,$result)) {
500
+ $original = $result[0];
501
+ if ($use_cache && isset($this->_expression_cache[$original])) {
502
+ $replacement = $this->_expression_cache[$original];
503
+ self::debug(' get cached expression <span class="osh-replacement">'.$original.'</span> = <span class="osh-formula">'.$replacement.'</span>',10);
504
+ } else {
505
+ $reference_value = $this->_evalFormula($result[1]);
506
+ if (isset($reference_value)) {
507
+ $fees_table_string = $result[2];
508
+
509
+ if (!preg_match('#^'.self::$COUPLE_REGEX.'(?:, *'.self::$COUPLE_REGEX.')*$#',$fees_table_string)) {
510
+ $this->addMessage('error',$row,$property_key,'Error in table %s','<span class="osh-formula">'.htmlentities($result[0]).'</span>');
511
+ $result = new OCS_Result(false);
512
+ if ($use_cache) $this->setCache($formula_string,$result);
513
+ return $result;
514
+ }
515
+ $fees_table = explode(',',$fees_table_string);
516
+
517
+ $replacement = null;
518
+ foreach ($fees_table as $item) {
519
+ $fee_data = explode(':',$item);
520
+
521
+ $fee = trim($fee_data[1]);
522
+ $max_value = trim($fee_data[0]);
523
+
524
+ $last_char = $max_value{strlen($max_value)-1};
525
+ if ($last_char=='[') $including_max_value = false;
526
+ else if ($last_char==']') $including_max_value = true;
527
+ else $including_max_value = true;
528
+
529
+ $max_value = str_replace(array('[',']'),'',$max_value);
530
+
531
+ if ($max_value=='*' || $including_max_value && $reference_value<=$max_value || !$including_max_value && $reference_value<$max_value) {
532
+ $replacement = $fee;//$this->_calculateFee($process,$fee,$var);
533
+ break;
534
+ }
535
+ }
536
+ }
537
+ $replacement = $this->_toString($replacement);
538
+ if ($use_cache) $this->setCache($original,$replacement);
539
+ }
540
+ $formula = $this->replace($original,$replacement,$formula);
541
+ }
542
+ $result = new OCS_Result(true,$formula);
543
+ return $result;
544
+ }
545
+
546
+ protected function _evalFormula($formula) {
547
+ if (is_bool($formula)) return $formula;
548
+ 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'
549
+ .'|in_array\(\'(?:[^\']*)\', *array\( *(?:\'(?:[^\']+)\') *(?: *, *\'(?:[^\']+)\')* *\) *\)'
550
+ .'|\'[^\']*\'|[0-9,\'\.\-\(\)\*\/\?\:\+\<\>\=\&\|%! ])*$/',$formula)) {
551
+ $errors = array(
552
+ PREG_NO_ERROR => 'PREG_NO_ERROR',
553
+ PREG_INTERNAL_ERROR => 'PREG_INTERNAL_ERROR',
554
+ PREG_BACKTRACK_LIMIT_ERROR => 'PREG_BACKTRACK_LIMIT_ERROR',
555
+ PREG_RECURSION_LIMIT_ERROR => 'PREG_RECURSION_LIMIT_ERROR',
556
+ PREG_BAD_UTF8_ERROR => 'PREG_BAD_UTF8_ERROR',
557
+ PREG_BAD_UTF8_OFFSET_ERROR => 'PREG_BAD_UTF8_OFFSET_ERROR',
558
+ );
559
+ $error = preg_last_error();
560
+ if (isset($errors[$error])) $error = $errors[$error];
561
+ self::debug(' doesn\'t match ('.$error.')',10);
562
+ return null;
563
+ }
564
+ $formula = str_replace(
565
+ array('min','max'),
566
+ array('$this->_min','$this->_max'),
567
+ $formula
568
+ );
569
+ $eval_result = null;
570
+ @eval('$eval_result = ('.$formula.');');
571
+ return $eval_result;
572
+ }
573
+
574
+ protected function _getOptionsAndData($string) {
575
+ if (preg_match('/^(\\s*\(\\s*([^\] ]*)\\s*\)\\s*)/',$string,$result)) {
576
+ $options = $result[2];
577
+ $data = str_replace($result[1],'',$string);
578
+ } else {
579
+ $options = '';
580
+ $data = $string;
581
+ }
582
+ return array(
583
+ 'options' => $options,
584
+ 'data' => $data,
585
+ );
586
+ }
587
+
588
+ public function compress($input) {
589
+ if (preg_match_all("/{table (.*) in (".self::$COUPLE_REGEX."(?:, *".self::$COUPLE_REGEX.")*)}/imsU",$input,$result,PREG_SET_ORDER)) {
590
+ foreach ($result as $result_i) {
591
+ $fees_table = explode(',',$result_i[2]);
592
+ $value = null;
593
+ foreach ($fees_table as $index => $item) {
594
+ list($max_value,$fee) = explode(':',$item);
595
+ $last_char = $max_value{strlen($max_value)-1};
596
+ if (in_array($last_char,array('[',']'))) {
597
+ $including_char = $last_char;
598
+ $max_value = str_replace(array('[',']'),'',$max_value);
599
+ } else $including_char = '';
600
+ $fees_table[$index] = ((float)$max_value).$including_char.':'.((float)$fee);
601
+ }
602
+ $input = str_replace($result_i[2],implode(',',$fees_table),$input);
603
+ $input = str_replace($result_i[1],trim($result_i[1]),$input);
604
+ }
605
+ }
606
+ if (preg_match_all("#{foreach ([^}]*)}(.*){/foreach}#imsU",$input,$result,PREG_SET_ORDER)) {
607
+ foreach ($result as $result_i) {
608
+ $input = str_replace($result_i[1],trim($result_i[1]),$input);
609
+ $input = str_replace($result_i[2],trim($result_i[2]),$input);
610
+ }
611
+ }
612
+ return '$$'.str_replace(
613
+ self::$UNCOMPRESSED_STRINGS,
614
+ self::$COMPRESSED_STRINGS,
615
+ $input
616
+ );
617
+ }
618
+
619
+ public function uncompress($input) {
620
+ if (preg_match_all("/{table (.*) in (".self::$COUPLE_REGEX."(?:, *".self::$COUPLE_REGEX.")*)}/iU",$input,$result,PREG_SET_ORDER)) {
621
+ foreach ($result as $result_i) {
622
+ $fees_table = explode(',',$result_i[2]);
623
+ $value = null;
624
+ foreach ($fees_table as $index => $item) {
625
+ list($max_value,$fee) = explode(':',$item);
626
+ $last_char = $max_value{strlen($max_value)-1};
627
+ if (in_array($last_char,array('[',']'))) {
628
+ $including_char = $last_char;
629
+ $max_value = str_replace(array('[',']'),'',$max_value);
630
+ } else $including_char = '';
631
+ $max_value = (float)$max_value;
632
+ $fee = (float)$fee;
633
+ $new_max_value = number_format($max_value,2,'.','');
634
+ $new_fee = number_format($fee,2,'.','');
635
+ $fees_table[$index] = (((float)$new_max_value)==$max_value ? $new_max_value : $max_value).$including_char.':'
636
+ .(((float)$new_fee)==$fee ? $new_fee : $fee);
637
+ }
638
+ $input = str_replace($result_i[2],implode(', ',$fees_table),$input);
639
+ $input = str_replace($result_i[1],trim($result_i[1]),$input);
640
+ }
641
+ }
642
+ if (preg_match_all("#{foreach ([^}]*)}(.*){/foreach}#iU",$input,$result,PREG_SET_ORDER)) {
643
+ foreach ($result as $result_i) {
644
+ $input = str_replace($result_i[1],trim($result_i[1]),$input);
645
+ $input = str_replace($result_i[2],trim($result_i[2]),$input);
646
+ }
647
+ }
648
+ return str_replace(
649
+ self::$COMPRESSED_STRINGS,
650
+ self::$UNCOMPRESSED_STRINGS,
651
+ $input
652
+ );
653
+ }
654
+
655
+ public function parseProperty($input) {
656
+ $value = $input==='false' || $input==='true' ? $input=='true' : str_replace('\"','"',preg_replace('/^(?:"|\')(.*)(?:"|\')$/s','$1',$input));
657
+ return $value==='' ? null : $value;
658
+ }
659
+
660
+ public function cleanProperty(&$row, $key) {
661
+ $input = $row[$key]['value'];
662
+ if (is_string($input)) {
663
+ $input = str_replace(array("\n"),array(''),$input);
664
+ while (preg_match('/({TABLE |{SUM |{COUNT | DISTINCT | IN )/',$input,$resi)) {
665
+ $input = str_replace($resi[0],strtolower($resi[0]),$input);
666
+ }
667
+
668
+ while (preg_match('/{{customVar code=([a-zA-Z0-9_-]+)}}/',$input,$resi)) {
669
+ $input = str_replace($resi[0],'{customvar.'.$resi[1].'}',$input);
670
+ }
671
+
672
+ $regex = "{(weight|products_quantity|price_including_tax|price_excluding_tax|country)}";
673
+ if (preg_match('/'.$regex.'/',$input,$resi)) {
674
+ $this->addMessage('warning',$row,$key,'Usage of deprecated syntax %s','<span class="osh-formula">'.$resi[0].'</span>');
675
+ while (preg_match('/'.$regex.'/',$input,$resi)) {
676
+ switch ($resi[1]) {
677
+ case 'price_including_tax':
678
+ case 'price_excluding_tax':
679
+ case 'weight':
680
+ $input = str_replace($resi[0],"{cart.".$resi[1]."}",$input);
681
+ break;
682
+ case 'products_quantity': $input = str_replace($resi[0],"{cart.quantity}",$input); break;
683
+ case 'country': $input = str_replace($resi[0],"{destination.country.name}",$input); break;
684
+ }
685
+ }
686
+ }
687
+
688
+ $regex1 = "{copy '([a-zA-Z0-9_]+)'\.'([a-zA-Z0-9_]+)'}";
689
+ if (preg_match('/'.$regex1.'/',$input,$resi)) {
690
+ $this->addMessage('warning',$row,$key,'Usage of deprecated syntax %s','<span class="osh-formula">'.$resi[0].'</span>');
691
+ while (preg_match('/'.$regex1.'/',$input,$resi)) $input = str_replace($resi[0],'{'.$resi[1].'.'.$resi[2].'}',$input);
692
+ }
693
+
694
+ $regex1 = "{(count|all|any) (attribute|option) '([^'\)]+)' ?((?:==|<=|>=|<|>|!=) ?(?:".self::$FLOAT_REGEX."|true|false|'[^'\)]*'))}";
695
+ $regex2 = "{(sum) (attribute|option) '([^'\)]+)'}";
696
+ if (preg_match('/'.$regex1.'/',$input,$resi) || preg_match('/'.$regex2.'/',$input,$resi)) {
697
+ $this->addMessage('warning',$row,$key,'Usage of deprecated syntax %s','<span class="osh-formula">'.$resi[0].'</span>');
698
+ while (preg_match('/'.$regex1.'/',$input,$resi) || preg_match('/'.$regex2.'/',$input,$resi)) {
699
+ switch ($resi[1]) {
700
+ case 'count': $input = str_replace($resi[0],"{count products where product.".$resi[2]."s.".$resi[3].$resi[4]."}",$input); break;
701
+ case 'all': $input = str_replace($resi[0],"{count products where product.".$resi[2]."s.".$resi[3].$resi[4]."}=={products_quantity}",$input); break;
702
+ case 'any': $input = str_replace($resi[0],"{count products where product.".$resi[2]."s.".$resi[3].$resi[4]."}>0",$input); break;
703
+ case 'sum': $input = str_replace($resi[0],"{sum product.".$resi[2].".".$resi[3]."}",$input); break;
704
+ }
705
+ }
706
+ }
707
+
708
+ $regex = "((?:{| )product.(?:attribute|option))s.";
709
+ if (preg_match('/'.$regex.'/',$input,$resi)) {
710
+ $this->addMessage('warning',$row,$key,'Usage of deprecated syntax %s','<span class="osh-formula">'.$resi[0].'</span>');
711
+ while (preg_match('/'.$regex.'/',$input,$resi)) {
712
+ $input = str_replace($resi[0],$resi[1].'.',$input);
713
+ }
714
+ }
715
+
716
+ $regex = "{table '([^']+)' (".self::$COUPLE_REGEX."(?:, *".self::$COUPLE_REGEX.")*)}";
717
+ if (preg_match('/'.$regex.'/',$input,$resi)) {
718
+ $this->addMessage('warning',$row,$key,'Usage of deprecated syntax %s','<span class="osh-formula">'.$resi[0].'</span>');
719
+ while (preg_match('/'.$regex.'/',$input,$resi)) {
720
+ switch ($resi[1]) {
721
+ case 'products_quantity':
722
+ $input = str_replace($resi[0],"{table {cart.weight} in ".$resi[2]."}*{cart.quantity}",$input);
723
+ break;
724
+ default:
725
+ $input = str_replace($resi[0],"{table {cart.".$resi[1]."} in ".$resi[2]."}",$input);
726
+ break;
727
+ }
728
+ }
729
+ }
730
+ }
731
+ $row[$key]['value'] = $input;
732
+ }
733
+
734
+ protected function _parseInput() {
735
+ $config_string = str_replace(
736
+ array('&gt;','&lt;','“','”',utf8_encode(chr(147)),utf8_encode(chr(148)),'&laquo;','&raquo;',"\r\n","\t"),
737
+ array('>','<','"','"','"','"','"','"',"\n",' '),
738
+ $this->_input
739
+ );
740
+
741
+ if (substr($config_string,0,2)=='$$') $config_string = $this->uncompress(substr($config_string,2,strlen($config_string)));
742
+
743
+ //echo ini_get('pcre.backtrack_limit');
744
+ //exit;
745
+
746
+ $row_regex = ' *([a-z0-9_]+)\\s*:\\s*("(?:(?:[^"]|\\\\")*[^\\\\])?"|'.self::$FLOAT_REGEX.'|false|true)\\s*(,)? *(?:\\n)?';
747
+ if (!preg_match_all('/((?:#+[^{\\n]*\\s+)*)\\s*(#)?{\\s*('.$row_regex.')+\\s*}/i',$config_string,$result,PREG_SET_ORDER)) {
748
+ $errors = array(
749
+ PREG_NO_ERROR => 'PREG_NO_ERROR',
750
+ PREG_INTERNAL_ERROR => 'PREG_INTERNAL_ERROR',
751
+ PREG_BACKTRACK_LIMIT_ERROR => 'PREG_BACKTRACK_LIMIT_ERROR',
752
+ PREG_RECURSION_LIMIT_ERROR => 'PREG_RECURSION_LIMIT_ERROR',
753
+ PREG_BAD_UTF8_ERROR => 'PREG_BAD_UTF8_ERROR',
754
+ PREG_BAD_UTF8_OFFSET_ERROR => 'PREG_BAD_UTF8_OFFSET_ERROR',
755
+ );
756
+ $error = preg_last_error();
757
+ if (isset($errors[$error])) $error = $errors[$error];
758
+ self::debug(' preg_match_all error ('.$error.')',10);
759
+ }
760
+
761
+ $this->_config = array();
762
+ $available_keys = array(
763
+ 'code','label','enabled','description','fees','conditions','destination','origin','customer_groups','tracking_url',
764
+ 'fees_table','fees_formula','fixed_fees','reference_value',
765
+ 'prices_range','weights_range','product_properties',
766
+ 'free_shipping__fees_table','free_shipping__fees_formula','free_shipping__fixed_fees','free_shipping__label',
767
+ );
768
+
769
+ foreach ($result as $block) {
770
+ $deprecated_properties = array();
771
+ $unknown_properties = array();
772
+ $missing_semicolon = array();
773
+ $obsolete_disabling_method = array();
774
+
775
+ //$before = strstr($config_string,$block[0],true); // Seulement compatible avec PHP 5.3.0
776
+ list($before) = explode($block[0],$config_string,2);
777
+ if ($before!==false && trim($before)!='') {
778
+ $config_string = substr($config_string,strlen($before));
779
+ $this->_addIgnoredLines(trim($before));
780
+ $this->addMessage('info',$row=null,null,'Ignored lines %s','<div class="code">'.trim($before).'</div>');
781
+ }
782
+
783
+ $config_string = str_replace($block[0], '', $config_string);
784
+ preg_match_all('/'.$row_regex.'/i',$block[0],$result2,PREG_SET_ORDER);
785
+ $block_string = $block[0];
786
+
787
+ $row = array();
788
+ $i = 1;
789
+ foreach ($result2 as $data) {
790
+ $key = $data[1];
791
+ if (in_array($key,$available_keys) || substr($key,0,1)=='_') {
792
+ $property = $this->parseProperty($data[2]);
793
+ if (isset($property)) {
794
+ $row[$key] = array('value' => $property, 'original_value' => $property);
795
+ $this->cleanProperty($row,$key);
796
+ }
797
+ if ($i>2) {
798
+ $block_string = str_replace($data[0],$i==3 ? "...\n" : '',$block_string);
799
+ }
800
+ if ($i!=count($result2) && !isset($data[3]) || isset($data[3]) && $data[3]!=',') {
801
+ if (preg_match('/^("|\')(.{40})(.*)("|\')$/s',$data[2],$resultx))
802
+ $missing_semicolon[] = trim(str_replace($data[2],$resultx[1].$resultx[2].' ...'.$resultx[4],$data[0]));
803
+ else $missing_semicolon[] = trim($data[0]);
804
+ }
805
+ } else {
806
+ if (!in_array($key,$unknown_properties)) $unknown_properties[] = $key;
807
+ }
808
+ $i++;
809
+ }
810
+ if ($block[1]!='') $row['*comment']['value'] = $block[1];
811
+ if ($block[2]=='#' && !isset($row['enabled'])) {
812
+ $row['enabled'] = array('value' => false);
813
+ $obsolete_disabling_method[] = $block_string;
814
+ }
815
+
816
+ $formula_fields_to_check = array();
817
+ if (isset($row['conditions'])) $formula_fields_to_check[] = 'conditions';
818
+ if (isset($row['fees'])) $formula_fields_to_check[] = 'fees';
819
+
820
+ if (count($formula_fields_to_check)>0) {
821
+ foreach ($formula_fields_to_check as $property) {
822
+ $property_value = $row[$property]['value'];
823
+ if (preg_match('/{ +/',$property_value)) {
824
+ $this->addMessage('warning',$row,$property,'There are unwanted spaces after char `%s`','{');
825
+ $property_value = preg_replace('/{ +/','{',$property_value);
826
+ }
827
+ if (preg_match('/ +}/',$property_value)) {
828
+ $this->addMessage('warning',$row,$property,'There are unwanted spaces before char `%s`','}');
829
+ $property_value = preg_replace('/ +}/','}',$property_value);
830
+ }
831
+ if (preg_match('/ +/',$property_value)) {
832
+ $this->addMessage('warning',$row,$property,'There are unwanted multiples spaces `%s`',preg_replace('/( +)/','<span class="osh-formula">*$1*</span>',$property_value));
833
+ $property_value = preg_replace('/ +/',' ',$property_value);
834
+ }
835
+ $row[$property]['value'] = trim($property_value);
836
+ }
837
+ }
838
+
839
+ $float_value_regex = '\\s*('.self::$POSITIVE_FLOAT_REGEX.'|\*)\\s*';
840
+ $conditions = array();
841
+ if (isset($row['prices_range'])) {
842
+ if (!in_array('prices_range',$deprecated_properties)) $deprecated_properties[] = 'prices_range';
843
+
844
+ $result = $this->_getOptionsAndData($row['prices_range']['value']);
845
+ $options = $result['options'];
846
+ $prices_range = $result['data'];
847
+
848
+ if (($options=='' || in_array($options,array('incl.tax','ttc')))
849
+ && preg_match('/^\\s*(\[|\])?'.$float_value_regex.'=>'.$float_value_regex.'(\[|\])?\\s*$/',$prices_range,$result)) {
850
+ $min_price_included = $result[1]=='[';
851
+ $min_price = $result[2]=='*' ? -1 : (float)$result[2];
852
+ $max_price = $result[3]=='*' ? -1 : (float)$result[3];
853
+ $max_price_included = !isset($result[4]) || $result[4]==']' || $result[4]=='';
854
+
855
+ $tax_included = $options!='' && in_array($options,array('incl.tax','ttc')) || isset($row['reference_value']) && $row['reference_value']['value']=='price_including_tax';
856
+ $price = $tax_included ? '{cart.price_including_tax}' : '{cart.price_excluding_tax}';
857
+
858
+ if ($min_price!=-1) $conditions[] = $price.'>'.($min_price_included ? '=' : '').$min_price;
859
+ if ($max_price!=-1) $conditions[] = $price.'<'.($max_price_included ? '=' : '').$max_price;
860
+ }
861
+ 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>');
862
+ unset($row['prices_range']);
863
+ }
864
+ if (isset($row['weights_range'])) {
865
+ if (!in_array('weights_range',$deprecated_properties)) $deprecated_properties[] = 'weights_range';
866
+ if (preg_match('/^\\s*(\[|\])?'.$float_value_regex.'=>'.$float_value_regex.'(\[|\])?\\s*$/',$row['weights_range']['value'],$result)) {
867
+ $min_weight_included = $result[1]=='[';
868
+ $min_weight = $result[2]=='*' ? -1 : (float)$result[2];
869
+ $max_weight = $result[3]=='*' ? -1 : (float)$result[3];
870
+ $max_weight_included = !isset($result[4]) || $result[4]==']' || $result[4]=='';
871
+
872
+ if ($min_weight!=-1) $conditions[] = '{cart.weight}>'.($min_weight_included ? '=' : '').$min_weight;
873
+ if ($max_weight!=-1) $conditions[] = '{cart.weight}<'.($max_weight_included ? '=' : '').$max_weight;
874
+ }
875
+ 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>');
876
+ unset($row['weights_range']);
877
+ }
878
+ if (isset($row['product_properties'])) {
879
+ if (!in_array('product_properties',$deprecated_properties)) $deprecated_properties[] = 'product_properties';
880
+ $product_property_regex = "\\s*(and|or)? *\((?:(all|any|sum) )?(attribute|option) '([^'\)]+)' ?(==|=|<=|>=|<|>|!=) ?(".self::$FLOAT_REGEX."|true|false|'[^'\)]*')\)\\s*";
881
+ if (preg_match('/^('.$product_property_regex.')+$/',$row['product_properties']['value'],$result)) {
882
+ preg_match_all('/'.$product_property_regex.'/',$row['product_properties']['value'],$results,PREG_SET_ORDER);
883
+ $product_properties_condition = '';
884
+ foreach ($results as $result) {
885
+ $and_or = $result[1];
886
+ if ($and_or=='') $and_or = 'and';
887
+ $any_all_sum = $result[2];
888
+ if ($any_all_sum=='') $any_all_sum = 'any';
889
+ $property_type = $result[3];
890
+ $property_name = $result[4];
891
+ $cmp_symbol = $result[5];
892
+ if ($cmp_symbol=='=') $cmp_symbol = '==';
893
+ $cmp_value = $result[6];
894
+
895
+ $product_properties_condition .= $product_properties_condition=='' ? '' : ' '.$and_or.' ';
896
+ switch ($any_all_sum) {
897
+ case 'sum':
898
+ $product_properties_condition .= "{sum product.".$property_type.".".$property_name."}".$cmp_symbol.$cmp_value;
899
+ break;
900
+ case 'all':
901
+ $product_properties_condition .= "{count products where product.".$property_type.".".$property_name.$cmp_symbol.$cmp_value."}=={products_quantity}";
902
+ break;
903
+ case 'any':
904
+ $product_properties_condition .= "{count products where product.".$property_type.".".$property_name.$cmp_symbol.$cmp_value."}>0";
905
+ break;
906
+ }
907
+ }
908
+ if ($product_properties_condition!='') $conditions[] = $product_properties_condition;
909
+ }
910
+ 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>');
911
+ unset($row['product_properties']);
912
+ }
913
+ if (count($conditions)>0) $row['conditions'] = array('value' => count($conditions)==1 ? $conditions[0] : '('.implode(') && (',$conditions).')');
914
+
915
+ $fees = array();
916
+ if (isset($row['fees_table'])) {
917
+ if (!in_array('fees_table',$deprecated_properties)) $deprecated_properties[] = 'fees_table';
918
+ $options_and_data = $this->_getOptionsAndData($row['fees_table']['value']);
919
+ $options = $options_and_data['options'];
920
+ $fees_table_string = $options_and_data['data'];
921
+
922
+ $var = null;
923
+ if ($options=='') $var = (isset($row['reference_value']) ? $row['reference_value']['value'] : 'weight');
924
+ else if (in_array($options,array('incl.tax','ttc'))) $var = 'price_including_tax';
925
+ else if (in_array($options,array('excl.tax','ht'))) $var = 'price_excluding_tax';
926
+
927
+ if (isset($var)) {
928
+ if ($var=='price') $var = 'price_excluding_tax';
929
+ if ($var=='products_quantity') $var = 'quantity';
930
+ if (preg_match('/^[[:space:]]*\*[[:space:]]*:[[:space:]]*('.$float_value_regex.')[[:space:]]*$/s',$fees_table_string,$result)) $fees[] = $result[1];
931
+ else $fees[] = "{table {cart.".$var."} in ".str_replace(' ','',$fees_table_string)."}".($var=='quantity' ? '*{cart.quantity}' : '');
932
+ }
933
+ 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>');
934
+ unset($row['fees_table']);
935
+ }
936
+ if (isset($row['fees_formula'])) {
937
+ if (!in_array('fees_formula',$deprecated_properties)) $deprecated_properties[] = 'fees_formula';
938
+ $fees[] = str_replace(' ','',$row['fees_formula']['value']);
939
+ unset($row['fees_formula']);
940
+ }
941
+ if (isset($row['fixed_fees'])) {
942
+ if (!in_array('fixed_fees',$deprecated_properties)) $deprecated_properties[] = 'fixed_fees';
943
+ if ($row['fixed_fees']['value']!=0 || count($fees)==0) $fees[] = str_replace(' ','',$row['fixed_fees']['value']);
944
+ unset($row['fixed_fees']);
945
+ }
946
+ if (!isset($row['fees']) && count($fees)>0) $row['fees'] = array('value' => implode('+',$fees));
947
+
948
+ $fs_fees = array();
949
+ if (isset($row['free_shipping__fees_table'])) {
950
+ if (!in_array('free_shipping__fees_table',$deprecated_properties)) $deprecated_properties[] = 'free_shipping__fees_table';
951
+ $options_and_data = $this->_getOptionsAndData($row['free_shipping__fees_table']['value']);
952
+ $options = $options_and_data['options'];
953
+ $fees_table_string = $options_and_data['data'];
954
+
955
+ $var = null;
956
+ if ($options=='') $var = isset($row['reference_value']) ? $row['reference_value']['value'] : 'weight';
957
+ else if (in_array($options,array('incl.tax','ttc'))) $var = 'price_including_tax';
958
+ else if (in_array($options,array('excl.tax','ht'))) $var = 'price_excluding_tax';
959
+ if ($var=='price') $var = 'price_excluding_tax';
960
+
961
+ if (isset($var)) {
962
+ if ($var=='price') $var = 'price_excluding_tax';
963
+ if ($var=='products_quantity') $var = 'quantity';
964
+ if (preg_match('/^[[:space:]]*\*[[:space:]]*:[[:space:]]*('.$float_value_regex.')[[:space:]]*$/s',$fees_table_string,$result)) $fs_fees[] = $result[1];
965
+ else $fs_fees[] = "{table {cart.".$var."} in ".str_replace(' ','',$fees_table_string)."}".($var=='quantity' ? '*{cart.quantity}' : '');
966
+ }
967
+ 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>');
968
+ unset($row['free_shipping__fees_table']);
969
+ }
970
+ if (isset($row['free_shipping__fees_formula'])) {
971
+ if (!in_array('free_shipping__fees_formula',$deprecated_properties)) $deprecated_properties[] = 'free_shipping__fees_formula';
972
+ $fs_fees[] = str_replace(' ','',$row['free_shipping__fees_formula']['value']);
973
+ unset($row['free_shipping__fees_formula']);
974
+ }
975
+ if (isset($row['free_shipping__fixed_fees'])) {
976
+ if (!in_array('free_shipping__fixed_fees',$deprecated_properties)) $deprecated_properties[] = 'free_shipping__fixed_fees';
977
+ if ($row['free_shipping__fixed_fees']['value']!=0 || count($fees)==0) $fs_fees[] = str_replace(' ','',$row['free_shipping__fixed_fees']['value']);
978
+ unset($row['free_shipping__fixed_fees']);
979
+ }
980
+
981
+ if (isset($row['reference_value'])) {
982
+ if (!in_array('reference_value',$deprecated_properties)) $deprecated_properties[] = 'reference_value';
983
+ unset($row['reference_value']);
984
+ }
985
+
986
+ if (count($fs_fees)>0) {
987
+ $row2 = $row;
988
+ if (isset($row['code'])) $row2['code']['value'] = $row['code']['value'].'__free_shipping';
989
+ $row2['fees']['value'] = implode('+',$fs_fees);
990
+ $row2['conditions']['value'] = isset($row2['conditions']) ? '('.$row2['conditions']+') and {free_shipping}' : '{free_shipping}';
991
+ $row['conditions']['value'] = isset($row['conditions']) ? '('.$row['conditions']+') and !{free_shipping}' : '!{free_shipping}';
992
+ if (isset($row['free_shipping__label'])) {
993
+ if (!in_array('free_shipping__label',$deprecated_properties)) $deprecated_properties[] = 'free_shipping__label';
994
+ $row2['label']['value'] = $row['free_shipping__label']['value'];
995
+ unset($row['free_shipping__label']);
996
+ unset($row2['free_shipping__label']);
997
+ }
998
+ $this->_addRow($row2);
999
+ }
1000
+ 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>');
1001
+ 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>');
1002
+ 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>');
1003
+ 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>');
1004
+ $this->_addRow($row);
1005
+ }
1006
+ if (trim($config_string)!='') {
1007
+ $this->_addIgnoredLines(trim($config_string));
1008
+ $this->addMessage('info',$row=null,null,'Ignored lines %s','<div class="code">'.trim($config_string).'</div>');
1009
+ }
1010
+ }
1011
+
1012
+ public function addMessage($type, &$row, $property) {
1013
+ $args = func_get_args();
1014
+ array_shift($args);
1015
+ array_shift($args);
1016
+ array_shift($args);
1017
+ $message = new OCS_Message($type,$args);
1018
+ if (isset($row)) {
1019
+ if (isset($property)) {
1020
+ $row[$property]['messages'][] = $message;
1021
+ } else {
1022
+ $row['*messages'][] = $message;
1023
+ }
1024
+ }
1025
+ $this->_messages[] = $message;
1026
+ self::debug(' => <span class="osh-'.$message->type.'">'.$message->toString().'</span>',1);
1027
+ }
1028
+
1029
+ protected function _addRow(&$row) {
1030
+ if (isset($row['code'])) {
1031
+ $key = $row['code']['value'];
1032
+ if (isset($this->_config[$key])) $this->addMessage('error',$row,'code','The property `code` must be unique, `%s` has been found twice',$key);
1033
+ while (isset($this->_config[$key])) $key .= rand(0,9);
1034
+ //$row['code'] = $key;
1035
+ } else {
1036
+ $i = 1;
1037
+ do {
1038
+ $key = 'code_auto'.sprintf('%03d',$i);
1039
+ $i++;
1040
+ } while (isset($this->_config[$key]));
1041
+ }
1042
+ $row['*code'] = $key;
1043
+ $this->_config[$key] = $row;
1044
+ }
1045
+
1046
+ protected function _addIgnoredLines($lines) {
1047
+ $this->_config[] = array('lines' => $lines);
1048
+ }
1049
+
1050
+ protected function _addressMatch($address_filter, $address) {
1051
+ $excluding = false;
1052
+ if (preg_match('# *\* *- *\((.*)\) *#s',$address_filter,$result)) {
1053
+ $address_filter = $result[1];
1054
+ $excluding = true;
1055
+ }
1056
+
1057
+ $tmp_address_filter_array = explode(',',trim($address_filter));
1058
+
1059
+ $concat = false;
1060
+ $concatened = '';
1061
+ $address_filter_array = array();
1062
+ $i = 0;
1063
+
1064
+ foreach ($tmp_address_filter_array as $address_filter) {
1065
+ if ($concat) $concatened .= ','.$address_filter;
1066
+ else {
1067
+ if ($i<count($tmp_address_filter_array)-1 && preg_match('#\(#',$address_filter)) {
1068
+ $concat = true;
1069
+ $concatened .= $address_filter;
1070
+ } else $address_filter_array[] = $address_filter;
1071
+ }
1072
+ if (preg_match('#\)#',$address_filter)) {
1073
+ $address_filter_array[] = $concatened;
1074
+ $concatened = '';
1075
+ $concat = false;
1076
+ }
1077
+ $i++;
1078
+ }
1079
+
1080
+ foreach ($address_filter_array as $address_filter) {
1081
+ if (preg_match('# *([A-Z]{2}) *(-)? *(?:\( *(-)? *(.*)\))? *#s',$address_filter,$result)) {
1082
+ $country_code = $result[1];
1083
+ if ($address['country_code']==$country_code) {
1084
+ self::debug(' country code <span class="osh-replacement">'.$address['country_code'].'</span> matches',5);
1085
+ if (!isset($result[4]) || $result[4]=='') return !$excluding;
1086
+ else {
1087
+ $region_codes = explode(',',$result[4]);
1088
+ $in_array = false;
1089
+ for ($i=count($region_codes); --$i>=0;) {
1090
+ $code = trim($region_codes[$i]);
1091
+ $region_codes[$i] = $code;
1092
+ if ($address['region_code']===$code) {
1093
+ self::debug(' region code <span class="osh-replacement">'.$address['region_code'].'</span> matches',5);
1094
+ $in_array = true;
1095
+ } else if ($address['postcode']===$code) {
1096
+ self::debug(' postcode <span class="osh-replacement">'.$address['postcode'].'</span> matches',5);
1097
+ $in_array = true;
1098
+ } else if (strpos($code,'*')!==false && preg_match('/^'.str_replace('*','(?:.*)',$code).'$/',$address['postcode'])) {
1099
+ self::debug(' postcode <span class="osh-replacement">'.$address['postcode'].'</span> matches <span class="osh-formula">'.$code.'</span>',5);
1100
+ $in_array = true;
1101
+ }
1102
+ if ($in_array) break;
1103
+ }
1104
+ if (!$in_array) {
1105
+ self::debug(' region code <span class="osh-replacement">'.$address['region_code'].'</span> and postcode <span class="osh-replacement">'.$address['postcode'].'</span> don\'t match',5);
1106
+ }
1107
+ // Vérification stricte
1108
+ /*$in_array = in_array($address['region_code'],$region_codes,true) || in_array($address['postcode'],$region_codes,true);*/
1109
+ $excluding_region = $result[2]=='-' || $result[3]=='-';
1110
+ if ($excluding_region && !$in_array || !$excluding_region && $in_array) return !$excluding;
1111
+ }
1112
+ }
1113
+ }
1114
+ }
1115
+ return $excluding;
1116
+ }
1117
+
1118
+ protected function _getProductProperty($product, $property_type, $property_name, $get_by_id=false) {
1119
+ switch ($property_type) {
1120
+ case 'attribute':
1121
+ case 'attributes': return $product->getAttribute($property_name,$get_by_id);
1122
+ case 'option':
1123
+ case 'options': return $product->getOption($property_name,$get_by_id);
1124
+ case 'stock': return $product->getStockData($property_name);
1125
+ }
1126
+ return null;
1127
+ }
1128
+
1129
+ protected function _processProductProperty($products, $regex_result) {
1130
+ // COUNT, SUM or COUNT DISTINCT
1131
+ $operation = strtolower($regex_result[1]);
1132
+ switch ($operation) {
1133
+ case 'sum':
1134
+ case 'count distinct':
1135
+ $property_type = $regex_result[2];
1136
+ $property_name = $regex_result[3];
1137
+ $conditions = isset($regex_result[4]) ? $regex_result[4] : null;
1138
+ break;
1139
+ case 'count':
1140
+ $conditions = isset($regex_result[2]) ? $regex_result[2] : null;
1141
+ break;
1142
+ }
1143
+
1144
+ self::debug(' :: start <span class="osh-replacement">'.$regex_result[0].'</span>',10);
1145
+
1146
+ $return_value = 0;
1147
+
1148
+ preg_match_all('/product\.(attribute(?:s)?|option(?:s)?|stock)\.([a-z0-9_]+)(?:\.(id))?/i',$conditions,$properties_regex_result,PREG_SET_ORDER);
1149
+ $properties = array();
1150
+ foreach ($properties_regex_result as $property_regex_result) {
1151
+ $key = $property_regex_result[0];
1152
+ if (!isset($properties[$key])) $properties[$key] = $property_regex_result;
1153
+ }
1154
+
1155
+ foreach ($products as $product) {
1156
+ if (isset($conditions) && $conditions!='') {
1157
+ $formula = $conditions;
1158
+ foreach ($properties as $property) {
1159
+ $value = $this->_getProductProperty(
1160
+ $product,
1161
+ $tmp_property_type = $property[1],
1162
+ $tmp_property_name = $property[2],
1163
+ $get_by_id = isset($property[3]) && $property[3]=='id'
1164
+ );
1165
+ //$formula = $this->replace($property[0],$value,$formula);
1166
+ $from = $property[0];
1167
+ $to = is_string($value) || empty($value) ? "'".$value."'" : $value;
1168
+ $formula = str_replace($from,$to,$formula);
1169
+ self::debug(' replace <span class="osh-replacement">'.$from.'</span> by <span class="osh-replacement">'.$to.'</span> =&gt; <span class="osh-formula">'.str_replace($from,'<span class="osh-replacement">'.$to.'</span>',$formula).'</span>',5);
1170
+ }
1171
+ $eval_result = $this->_evalFormula($formula);
1172
+ if (!isset($eval_result)) return 'null';
1173
+ }
1174
+ else $eval_result = true;
1175
+
1176
+ if ($eval_result==true) {
1177
+ switch ($operation) {
1178
+ case 'sum':
1179
+ $value = $this->_getProductProperty($product,$property_type,$property_name);
1180
+ //self::debug($product->getSku().'.'.$property_type.'.'.$property_name.' = "'.$value.'" x '.$product->getQuantity(),10);
1181
+ $return_value += $value*$product->getQuantity();
1182
+ break;
1183
+ case 'count distinct':
1184
+ if (!isset($distinct_values)) $distinct_values = array();
1185
+ $value = $this->_getProductProperty($product,$property_type,$property_name);
1186
+ if (!in_array($value,$distinct_values)) {
1187
+ $distinct_values[] = $value;
1188
+ $return_value++;
1189
+ }
1190
+ break;
1191
+ case 'count':
1192
+ $return_value += $product->getQuantity();
1193
+ break;
1194
+ }
1195
+ }
1196
+ }
1197
+
1198
+ self::debug(' :: end <span class="osh-replacement">'.$regex_result[0].'</span>',10);
1199
+
1200
+ return $return_value;
1201
+ }
1202
+
1203
+ }
1204
+
1205
+ interface OCS_Product {
1206
+ public function getOption($option);
1207
+ public function getAttribute($attribute);
1208
+ public function getName();
1209
+ public function getSku();
1210
+ public function getQuantity();
1211
+ public function getStockData($key);
1212
+ }
1213
+
1214
+ class OCS_Message {
1215
+ public $type;
1216
+ public $message;
1217
+ public $args;
1218
+
1219
+ public function OCS_Message($type, $args) {
1220
+ $this->type = $type;
1221
+ $this->message = array_shift($args);
1222
+ $this->args = $args;
1223
+ }
1224
+
1225
+ public function toString() {
1226
+ return vsprintf($this->message,$this->args);
1227
+ }
1228
+ }
1229
+
1230
+ class OCS_Result {
1231
+ public $success;
1232
+ public $result;
1233
+
1234
+ public function OCS_Result($success, $result=null) {
1235
+ $this->success = $success;
1236
+ $this->result = $result;
1237
+ }
1238
+
1239
+ public function __toString() {
1240
+ return is_bool($this->result) ? ($this->result ? 'true' : 'false') : (string)$this->result;
1241
+ }
1242
+ }
1243
+
1244
+
1245
+ ?>
app/code/community/Chronopost/Chronorelais/includes/countries.inc.php ADDED
@@ -0,0 +1,523 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
+ $input = trim($input);
369
+ $this->data = $data;
370
+ $this->classes = array();
371
+ $this->address_filters_list = null;
372
+ $this->parse();
373
+ }
374
+
375
+ public function parse($recursive=true) {
376
+ if (strlen($this->data['country_code'])==2) {
377
+ $code = strtoupper($this->data['country_code']);
378
+ $name = Country::getCountryNameByCode($code);
379
+
380
+ if (isset($name)) {
381
+ $this->code = $code;
382
+ $this->name = $name;
383
+ $this->classes[] = 'known';
384
+ }
385
+ }
386
+ if (!isset($this->name)) {
387
+ $code = Country::getCountryCodeByName($this->data['country_code']);
388
+ if (!isset($code)) {
389
+ $this->classes[] = 'soft-cleaned';
390
+ $cleaned_name = Country::softClean($this->data['country_code']);
391
+ $code = Country::getCountryCodeByName($cleaned_name,'soft-cleaned');
392
+ }
393
+ if (!isset($code)) {
394
+ $this->classes[] = 'replaced';
395
+ $code = Country::getCountryCodeByReplacedName($cleaned_name);
396
+ }
397
+ if (!isset($code)) {
398
+ $this->classes[] = 'hard-cleaned';
399
+ $cleaned_name = Country::hardClean($cleaned_name);
400
+ $code = Country::getCountryCodeByName($cleaned_name,'hard-cleaned');
401
+ }
402
+ if (!isset($code)) {
403
+ $this->classes[] = 'replaced';
404
+ $code = Country::getCountryCodeByReplacedName($cleaned_name);
405
+ }
406
+ if (isset($code)) {
407
+ $this->code = $code;
408
+ $this->name = Country::getCountryNameByCode($code);
409
+ $this->classes[] = 'known';
410
+ } else {
411
+ $this->classes[] = 'unknown';
412
+ }
413
+ }
414
+
415
+ if ($recursive && $this->hasClass('unknown')) {
416
+ if (!isset($cleaned_name)) $cleaned_name = Country::hardClean(Country::softClean($this->data['original']));
417
+ switch ($cleaned_name) {
418
+ case 'corse':
419
+ $this->data = array(
420
+ 'exclusion' => false,
421
+ 'country_code' => 'FR',
422
+ 'region_codes' => '2A,2B',
423
+ 'original' => $this->data['original'],
424
+ );
425
+ $this->classes = array('replaced');
426
+ $this->parse(false);
427
+ break;
428
+ case 'uk':
429
+ $this->data = array(
430
+ 'exclusion' => false,
431
+ 'country_code' => 'GB',
432
+ 'region_codes' => '',
433
+ 'original' => $this->data['original'],
434
+ );
435
+ $this->classes = array('replaced');
436
+ $this->parse(false);
437
+ break;
438
+ case 'union-europeenne':
439
+ case 'ue':
440
+ $this->createAddressFilterGroup(
441
+ 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'),
442
+ $code = 'UE',
443
+ $name = 'Union européenne'
444
+ );
445
+ break;
446
+ case 'dom':
447
+ $this->createAddressFilterGroup(
448
+ array('GP','MQ','GF','RE'),
449
+ $code = 'DOM',
450
+ $name = "Département d'Outre-Mer"
451
+ );
452
+ break;
453
+ case 'com':
454
+ $this->createAddressFilterGroup(
455
+ array('PF','PM','WF','YT','MF','BL'),
456
+ $code = 'COM',
457
+ $name = "Collectivités d'Outre-Mer"
458
+ );
459
+ break;
460
+ case 'outre-mer':
461
+ $this->createAddressFilterGroup(
462
+ array('DOM','COM','NC','TF'),
463
+ $code = "Outre-Mer",
464
+ $name = "Outre-Mer"
465
+ );
466
+ break;
467
+ }
468
+ }
469
+
470
+ if ($this->hasClass('known')) {
471
+ if ($this->hasClass('replaced') || $this->hasClass('hard-cleaned')) $this->label = '<span class="bad">'.$this->data['original'].'</span> '.$this->name;
472
+ else $this->label = $this->name;
473
+ if (isset($this->data['region_codes']) && $this->data['region_codes']!='') {
474
+ $this->label .= ' ('.$this->data['region_codes'].')';
475
+ }
476
+ } else {
477
+ $this->label = $this->data['original'];
478
+ }
479
+ }
480
+
481
+ public function createAddressFilterGroup($countries, $code, $name) {
482
+ $this->address_filters_list = array();
483
+ foreach ($countries as $country_code) {
484
+ $this->address_filters_list[] = new AddressFilter(array('country_code' => $country_code, 'original' => $country_code));
485
+ }
486
+ $this->classes = array('known');
487
+ $this->code = $code;
488
+ $this->name = $name;
489
+ }
490
+
491
+ public function hasClass($class) {
492
+ return in_array($class,$this->classes);
493
+ }
494
+
495
+ public function __toString() {
496
+ $output = '';
497
+ if (isset($this->address_filters_list)) {
498
+ $compact_value = $this->code;
499
+ $full_value = $this->name;
500
+ $output .= '<span class="address-filter address-filter-group"'
501
+ .' full-value="'.$full_value.'" compact-value="'.$compact_value.'" original-value="'.$this->data['original'].'"><span class="address-filter-group-label">'.$this->label.'</span>';
502
+ foreach ($this->address_filters_list as $address_filter) {
503
+ $output .= $address_filter;
504
+ }
505
+ $output .= '</span>';
506
+ } else {
507
+ if (isset($this->code)) {
508
+ $compact_value = $this->code.(isset($this->data['region_codes']) && $this->data['region_codes']!='' ? '('.$this->data['region_codes'].')' : '');
509
+ $full_value = $this->name.(isset($this->data['region_codes']) && $this->data['region_codes']!='' ? ' ('.$this->data['region_codes'].')' : '');
510
+ } else {
511
+ $compact_value = $this->data['original'];
512
+ $full_value = $this->data['original'];
513
+ }
514
+ $output .= '<span class="address-filter country-'.$this->code.' '.implode(' ',$this->classes)
515
+ .'" country-code="'.$this->code.'" full-value="'.$full_value.'" compact-value="'.$compact_value.'" original-value="'.$this->data['original'].'">'
516
+ .$this->label.'</span>';
517
+ }
518
+ return $output;
519
+ }
520
+ }
521
+
522
+
523
+ ?>
app/code/community/Chronopost/Chronorelais/sql/chronorelais_setup/mysql4-install-0.1.0.php ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ $installer = $this;
4
+
5
+ $installer->startSetup();
6
+
7
+ $installer->addAttribute('order', 'w_relay_point_code', array(
8
+ 'type' => 'varchar',
9
+ 'input' => 'text',
10
+ 'default' => 0,
11
+ 'label' => 'Relay point',
12
+ 'required' => 0
13
+ ));
14
+
15
+ $installer->endSetup();
app/code/community/Chronopost/Chronorelais/sql/chronorelais_setup/mysql4-upgrade-0.1.0-0.1.1.php ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
1
+ <?php
2
+ $installer = $this;
3
+ $installer->startSetup();
4
+
5
+ $this->run("
6
+ ALTER TABLE {$this->getTable('sales_flat_quote_address')} ADD `w_relay_point_code` varchar(255);
7
+ ");
8
+ $this->endSetup();
app/code/community/Chronopost/Chronorelais/sql/chronorelais_setup/mysql4-upgrade-0.1.1-0.1.2.php ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
1
+ <?php
2
+ $installer = $this;
3
+ $installer->startSetup();
4
+
5
+ $this->run("
6
+ ALTER TABLE {$this->getTable('sales_flat_order_address')} ADD `w_relay_point_code` varchar(255);
7
+ ");
8
+ $this->endSetup();
app/code/community/Chronopost/Chronorelais/sql/chronorelais_setup/mysql4-upgrade-0.1.2-0.1.3.php ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
1
+ <?php
2
+ $installer = $this;
3
+ $installer->startSetup();
4
+
5
+ $this->run("
6
+ ALTER TABLE {$this->getTable('sales_flat_shipment_track')} ADD `chrono_reservation_number` varchar(255);
7
+ ");
8
+ $this->endSetup();
app/code/community/Chronopost/Chronorelais/sql/chronorelais_setup/mysql4-upgrade-0.1.3-0.1.4.php ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ $installer = $this;
3
+ $installer->startSetup();
4
+
5
+ $installer->run("
6
+ -- DROP TABLE IF EXISTS {$this->getTable('sales_chronopost_order_export_status')};
7
+ CREATE TABLE {$this->getTable('sales_chronopost_order_export_status')} (
8
+ `order_id` int(10) unsigned NOT NULL,
9
+ `livraison_le_samedi` varchar(10) NOT NULL DEFAULT 'Yes',
10
+ UNIQUE KEY `order_id` (`order_id`)
11
+ ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
12
+ ");
13
+
14
+ $installer->endSetup();
app/design/adminhtml/default/default/template/chronorelais/import/form.phtml ADDED
@@ -0,0 +1,65 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <div class="content-header">
2
+ <table cellspacing="0">
3
+ <tr>
4
+ <td><h3 class="icon-head head-tax-rate-importExport"><?php echo Mage::helper('chronorelais')->__('Importer une liste de num&eacute;ros de colis') ?></h3></td>
5
+ </tr>
6
+ </table>
7
+ </div>
8
+ <div class="entry-edit">
9
+ <div class="box-left">
10
+ <form id="import_form" action="<?php echo $this->getUrl('*/*/import') ?>" method="post" enctype="multipart/form-data">
11
+ <?php echo $this->getBlockHtml('formkey')?>
12
+ <div class="entry-edit-head">
13
+ <h4 class="icon-head head-edit-form fieldset-legend"><?php echo Mage::helper('chronorelais')->__('Importer une liste de num&eacute;ros de colis') ?></h4>
14
+ </div>
15
+
16
+ <fieldset>
17
+ <table class="form-list" cellspacing="0">
18
+ <colgroup class="label"/>
19
+ <colgroup class="value"/>
20
+ <tbody>
21
+ <tr>
22
+ <td class="label">
23
+ <label><?php echo Mage::helper('chronorelais')->__('Tracking Title') ?></label>
24
+ </td>
25
+ <td class="value">
26
+ <input type="text" name="import_chronorelais_tracking_title" class="input-file" value="<?php echo Mage::helper('chronorelais')->getConfigurationDefaultTrackingTitle() ?>"/>
27
+ </td>
28
+ </tr>
29
+ <tr>
30
+ <td class="label">
31
+ <label><?php echo Mage::helper('chronorelais')->__('Import File') ?></label>
32
+ </td>
33
+ <td class="value">
34
+ <input type="file" name="import_chronorelais_file" class="input-file required-entry"/>
35
+ <p class="nm">
36
+ <small><?php echo Mage::helper('chronorelais')->__('Line format:'). ' "'.Mage::helper('chronorelais')->__('order id').'","'.Mage::helper('chronorelais')->__('tracking number').'"'; ?></small>
37
+ </p>
38
+ </td>
39
+ </tr>
40
+ <tr>
41
+ <td>&nbsp;</td>
42
+ <td class="value">
43
+ <?php $button_label = Mage::helper('chronorelais')->__('Import'); ?>
44
+ <?php echo $this->getButtonHtml($button_label, "this.form.submit();displayLoadingMask();") ?>
45
+ </td>
46
+ </tr>
47
+ </tbody>
48
+ </table>
49
+ </fieldset>
50
+
51
+ </form>
52
+ <script type="text/javascript">
53
+ var importForm = new varienForm('import_form');
54
+
55
+ function displayLoadingMask()
56
+ {
57
+ var loaderArea = $$('#html-body .wrapper')[0]; // Blocks all page
58
+ Position.clone($(loaderArea), $('loading-mask'), {offsetLeft:-2});
59
+ toggleSelectsUnderBlock($('loading-mask'), false);
60
+ Element.show('loading-mask');
61
+ }
62
+ </script>
63
+ </div>
64
+ <div class="clear"></div>
65
+ </div>
app/design/frontend/default/default/layout/chronorelais.xml ADDED
@@ -0,0 +1,44 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <layout version="0.1.0">
3
+ <default>
4
+ <reference name="head">
5
+ <action method="addItem"><type>skin_css</type><name>chronorelais/chronorelais.css</name></action>
6
+ </reference>
7
+ </default>
8
+
9
+ <checkout_onepage_index>
10
+ <reference name="checkout.onepage.shipping_method">
11
+ <action method="setTemplate"><template>chronorelais/checkout/onepage/shipping_method.phtml</template></action>
12
+ <block type="checkout/onepage_shipping_method_available" name="checkout.onepage.shipping_method.available" as="available" template="chronorelais/checkout/onepage/shipping_method/available.phtml">
13
+ <block type="chronorelais/checkout_onepage_shipping_method_chronorelais" name="checkout.onepage.shipping_method.chronorelais" as="relaislist" template="chronorelais/checkout/onepage/shipping_method/chronorelais.phtml"/>
14
+ </block>
15
+ </reference>
16
+ </checkout_onepage_index>
17
+
18
+ <checkout_onepage_shippingmethod>
19
+ <remove name="right"/>
20
+ <remove name="left"/>
21
+ <block type="checkout/onepage_shipping_method_available" name="root" output="toHtml" template="chronorelais/checkout/onepage/shipping_method/available.phtml">
22
+ <!--<block type="checkout/onepage_shipping_method_chronorelais" name="checkout.onepage.shipping_method.chronorelais" as="relaislist" template="chronorelais/checkout/onepage/shipping_method/chronorelais.phtml"/>-->
23
+ </block>
24
+ </checkout_onepage_shippingmethod>
25
+
26
+ <checkout_onepage_shippingchronorelais>
27
+ <remove name="right"/>
28
+ <remove name="left"/>
29
+ <block type="chronorelais/checkout_onepage_shipping_method_chronorelais" name="root" output="toHtml" template="chronorelais/checkout/onepage/shipping_method/chronorelais.phtml"/>
30
+ </checkout_onepage_shippingchronorelais>
31
+
32
+ <customer_account_index>
33
+ <reference name="customer_account_dashboard">
34
+ <block type="sales/order_recent" name="customer_account_dashboard_top" as="top" template="chronorelais/sales/order/recent.phtml"/>
35
+ </reference>
36
+ </customer_account_index>
37
+
38
+ <sales_order_history>
39
+ <reference name="sales.order.history">
40
+ <action method="setTemplate"><template>chronorelais/sales/order/history.phtml</template></action>
41
+ </reference>
42
+ </sales_order_history>
43
+
44
+ </layout>
app/design/frontend/default/default/template/chronorelais/checkout/onepage/shipping_method.phtml ADDED
@@ -0,0 +1,93 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Magento
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Academic Free License (AFL 3.0)
8
+ * that is bundled with this package in the file LICENSE_AFL.txt.
9
+ * It is also available through the world-wide-web at this URL:
10
+ * http://opensource.org/licenses/afl-3.0.php
11
+ * If you did not receive a copy of the license and are unable to
12
+ * obtain it through the world-wide-web, please send an email
13
+ * to license@magentocommerce.com so we can send you a copy immediately.
14
+ *
15
+ * DISCLAIMER
16
+ *
17
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
18
+ * versions in the future. If you wish to customize Magento for your
19
+ * needs please refer to http://www.magentocommerce.com for more information.
20
+ *
21
+ * @category design
22
+ * @package base_default
23
+ * @copyright Copyright (c) 2010 Magento Inc. (http://www.magentocommerce.com)
24
+ * @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0)
25
+ */
26
+ ?>
27
+ <?php $isSoColissimoSimplicite = Mage::getConfig()->getModuleConfig('LaPoste_SoColissimoSimplicite')->is('active'); ?>
28
+
29
+ <script src="http://maps.google.com/maps?file=api&amp;v=2&amp;sensor=false&amp;key=<?php echo Mage::helper('chronorelais')->getConfigurationGoogleMapAPIKey()?>" type="text/javascript"></script>
30
+ <script type="text/javascript" src="<?php echo $this->getSkinUrl('chronorelais/chronorelaismap.js') ?>"></script>
31
+ <script type="text/javascript">
32
+ //<![CDATA[
33
+ var Picto_Chrono_Relais = '<?php echo $this->getSkinUrl('chronorelais/Picto_Chrono_Relais.png')?>';
34
+ var Home_Chrono_Icon = '<?php echo $this->getSkinUrl('chronorelais/home.png')?>';
35
+ //]]>
36
+ </script>
37
+ <form id="co-shipping-method-form" action="">
38
+ <div id="checkout-shipping-method-load">
39
+ <?php echo $this->getChildHtml('available') ?>
40
+ </div>
41
+ <?php if(!empty($isSoColissimoSimplicite)) : ?>
42
+ <?php $_helper = Mage::helper('socolissimosimplicite'); ?>
43
+ <script type="text/javascript">
44
+ //<![CDATA[
45
+ // update method save to redirect onSuccess to method which deals with colissimo choice
46
+ ShippingMethod.prototype.saveWithColissimo = function(){
47
+ if (checkout.loadWaiting!=false) return;
48
+ if (this.validate()) {
49
+ checkout.setLoadWaiting('shipping-method');
50
+ var request = new Ajax.Request(
51
+ this.saveUrl,
52
+ {
53
+ method:'post',
54
+ onComplete: this.onComplete,
55
+ onSuccess: this.redirectToColissimo,
56
+ onFailure: checkout.ajaxFailure.bind(checkout),
57
+ parameters: Form.serialize(this.form)
58
+ }
59
+ );
60
+ }
61
+ };
62
+ // check if colissimo is selected, then redirect on form which post data on this platform
63
+ ShippingMethod.prototype.redirectToColissimo = function(transport){
64
+ var rateCodeSoColissimoSimplicite = '<?php echo $_helper->getRateCode()?>';
65
+ var urlFormSoColissimoSimplicite = '<?php echo $_helper->getFormUrl()?>';
66
+ var methods = document.getElementsByName('shipping_method');
67
+ for (var i=0; i<methods.length; i++) {
68
+ if (methods[i].value == rateCodeSoColissimoSimplicite && methods[i].checked) {
69
+ window.location = urlFormSoColissimoSimplicite;
70
+ }
71
+ }
72
+ // pass to next step (= default onSave binding
73
+ ShippingMethod.prototype.nextStep(transport);
74
+ };
75
+ //]]>
76
+ </script>
77
+ <?php endif; ?>
78
+ <script type="text/javascript">
79
+ //<![CDATA[
80
+ var shippingMethod = new ShippingMethod('co-shipping-method-form', "<?php echo $this->getUrl('checkout/onepage/saveShippingMethod') ?>");
81
+ //]]>
82
+ </script>
83
+ <div id="onepage-checkout-shipping-method-additional-load">
84
+ <?php echo $this->getChildHtml('additional') ?>
85
+ </div>
86
+ <div class="buttons-set" id="shipping-method-buttons-container">
87
+ <p class="back-link"><a href="#" onclick="checkout.back(); return false;"><small>&laquo; </small><?php echo $this->__('Back') ?></a></p>
88
+ <button type="button" class="button" onclick=" <?php if(!empty($isSoColissimoSimplicite)) : ?>shippingMethod.saveWithColissimo()<?php else: ?>shippingMethod.save()<?php endif;?>"><span><span><?php echo $this->__('Continue') ?></span></span></button>
89
+ <span id="shipping-method-please-wait" class="please-wait" style="display:none;">
90
+ <img src="<?php echo $this->getSkinUrl('images/opc-ajax-loader.gif') ?>" alt="<?php echo $this->__('Loading next step...') ?>" title="<?php echo $this->__('Loading next step...') ?>" class="v-middle" /> <?php echo $this->__('Loading next step...') ?>
91
+ </span>
92
+ </div>
93
+ </form>
app/design/frontend/default/default/template/chronorelais/checkout/onepage/shipping_method/available.phtml ADDED
@@ -0,0 +1,94 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Magento
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Academic Free License (AFL 3.0)
8
+ * that is bundled with this package in the file LICENSE_AFL.txt.
9
+ * It is also available through the world-wide-web at this URL:
10
+ * http://opensource.org/licenses/afl-3.0.php
11
+ * If you did not receive a copy of the license and are unable to
12
+ * obtain it through the world-wide-web, please send an email
13
+ * to license@magentocommerce.com so we can send you a copy immediately.
14
+ *
15
+ * DISCLAIMER
16
+ *
17
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
18
+ * versions in the future. If you wish to customize Magento for your
19
+ * needs please refer to http://www.magentocommerce.com for more information.
20
+ *
21
+ * @category design
22
+ * @package base_default
23
+ * @copyright Copyright (c) 2010 Magento Inc. (http://www.magentocommerce.com)
24
+ * @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0)
25
+ */
26
+ ?>
27
+ <?php if (!($_shippingRateGroups = $this->getShippingRates())): ?>
28
+ <p><?php echo $this->__('Sorry, no quotes are available for this order at this time.') ?></p>
29
+ <?php else: ?>
30
+ <dl class="sp-methods">
31
+ <?php $_sole = count($_shippingRateGroups) == 1; foreach ($_shippingRateGroups as $code => $_rates): ?>
32
+ <dt><?php echo $this->getCarrierName($code) ?></dt>
33
+ <dd>
34
+ <ul>
35
+ <?php $_sole = $_sole && count($_rates) == 1; foreach ($_rates as $_rate): ?>
36
+ <li>
37
+ <?php if ($_rate->getErrorMessage()): ?>
38
+ <ul class="messages"><li class="error-msg"><ul><li><?php echo $_rate->getErrorMessage() ?></li></ul></li></ul>
39
+ <?php else: ?>
40
+ <table>
41
+ <tr><td class="method-radio">
42
+ <?php /*if ($_sole) : ?>
43
+ <span class="no-display"><input name="shipping_method" type="radio" value="<?php echo $_rate->getCode() ?>" id="s_method_<?php echo $_rate->getCode() ?>" checked="checked" onclick="<?php if($code=="chronorelais"): ?>shippingMethod.getrelais('<?php echo $this->getUrl('checkout/onepage/getRelais')?>')<?php else: ?>shippingMethod.hiderelais()<?php endif; ?>" /></span>
44
+ <?php else:*/ ?>
45
+ <input name="shipping_method" type="radio" value="<?php echo $_rate->getCode() ?>" id="s_method_<?php echo $_rate->getCode() ?>"<?php /*if($_rate->getCode()===$this->getAddressShippingMethod()) echo ' checked="checked"'*/ ?> class="radio" onclick="<?php if($code=="chronorelais"): ?>shippingMethod.getrelais('<?php echo $this->getUrl('checkout/onepage/getRelais')?>')<?php else: ?>shippingMethod.hiderelais()<?php endif; ?>" />
46
+ <?php //endif; ?>
47
+ </td>
48
+ <?php if(Mage::getStoreConfig('carriers/'.$code.'/logo_url')): ?>
49
+ <td class="method-image"><img src="<?php echo $this->getSkinUrl("chronorelais/".Mage::getStoreConfig('carriers/'.$code.'/logo_url')); ?>" alt="" /></td>
50
+ <?php endif; ?>
51
+ <td class="method-contents">
52
+ <label for="s_method_<?php echo $_rate->getCode() ?>"><?php echo $_rate->getMethodTitle() ?>
53
+ <?php $_excl = $this->getShippingPrice($_rate->getPrice(), $this->helper('tax')->displayShippingPriceIncludingTax()); ?>
54
+ <?php $_incl = $this->getShippingPrice($_rate->getPrice(), true); ?>
55
+ <?php echo $_excl; ?>
56
+ <?php if ($this->helper('tax')->displayShippingBothPrices() && $_incl != $_excl): ?>
57
+ (<?php echo $this->__('Incl. Tax'); ?> <?php echo $_incl; ?>)
58
+ <?php endif; ?>
59
+ </label>
60
+ <?php if($_rate->getMethodDescription()): ?>
61
+ <div class="method-description">
62
+ <?php echo $_rate->getMethodDescription()?>
63
+ </div>
64
+ <?php endif;?>
65
+
66
+ <?php // disponibilit� de la plateforme soco ?>
67
+ <?php if(Mage::getConfig()->getModuleConfig('LaPoste_SoColissimoSimplicite')->is('active')) : ?>
68
+ <?php $helper = Mage::helper('socolissimosimplicite'); ?>
69
+ <?php
70
+ $serviceIsAvailable = true;
71
+ if ($helper->getServiceIsAvailable() and $helper->getServiceIsAvailableUrl() != '') {
72
+ $serviceIsAvailable = $helper->checkserviceAvailability();
73
+ }
74
+ ?>
75
+ <?php if ($_rate->getCode() == 'socolissimosimplicite_socolissimosimplicite' and !$serviceIsAvailable): ?>
76
+ <ul class="messages"><li class="error-msg"><ul><li><?php echo $helper->getServiceNotAvailableMessage(); ?></li></ul></li></ul>
77
+ <?php endif ?>
78
+ <?php endif; ?>
79
+ </td>
80
+ </tr>
81
+ </table>
82
+ <?php if($code=="chronorelais"): ?>
83
+ <div id="checkout-shipping-method-chronorelais-load" class="chronorelais-list">
84
+ <?php echo $this->getChildHtml('relaislist') ?>
85
+ </div>
86
+ <?php endif; ?>
87
+ <?php endif ?>
88
+ </li>
89
+ <?php endforeach; ?>
90
+ </ul>
91
+ </dd>
92
+ <?php endforeach; ?>
93
+ </dl>
94
+ <?php endif; ?>
app/design/frontend/default/default/template/chronorelais/checkout/onepage/shipping_method/chronorelais.phtml ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php if(count($this->getChronorelais())>0): ?>
2
+ <?php
3
+ $quote = Mage::getSingleton('checkout/cart')->init()->getQuote();
4
+ $address = $quote->getShippingAddress();
5
+ $postcode = $address->getPostcode();
6
+ ?>
7
+ <div class="chronorelaismap">
8
+ <div class="mappostalcode">
9
+ <input type="text" name="mappostalcode" id="mappostalcode" value="<?php echo $postcode ?>" class="input-text" onkeydown="if (event.keyCode == 13) shippingMethod.changePostalCode('<?php echo $this->getUrl('checkout/onepage/changePostalCode')?>')" />
10
+ <button onclick="shippingMethod.changePostalCode('<?php echo $this->getUrl('checkout/onepage/changePostalCode')?>');" id="mappostalcodebtn" class="button" type="button"><span><span><?php echo $this->__('Changer mon code postal')?></span></span></button>
11
+ <span style="display: none;" class="please-wait" id="postalcode-please-wait"><img class="v-middle" title="<?php echo $this->__('Loading map...')?>" alt="<?php echo $this->__('Loading map...')?>" src="<?php echo $this->getSkinUrl('images/opc-ajax-loader.gif')?>"> <?php echo $this->__('Loading map...')?></span>
12
+ </div>
13
+ <div id="chronomap"></div>
14
+ </div>
15
+ <dl class="sp-methods-chronorelais">
16
+ <dt><?php echo $this->__('Chronorelay points')?></dt>
17
+ <dd>
18
+ <ul>
19
+ <?php foreach($this->getChronorelais() as $key=>$chronorelais): ?>
20
+ <li>
21
+ <input name="shipping_method_chronorelais" type="radio" value="<?php echo $chronorelais->identifiantChronopostPointA2PAS;?>" id="s_method_chronorelais_<?php echo $chronorelais->identifiantChronopostPointA2PAS;?>" class="radio" onclick="loadMyPoint('<?php echo $chronorelais->identifiantChronopostPointA2PAS;//$key?>')" />
22
+ <label for="s_method_chronorelais_<?php echo $chronorelais->identifiantChronopostPointA2PAS;?>"><?php echo $chronorelais->nomEnseigne.' - '.$chronorelais->adresse1.' - '.$chronorelais->codePostal.' - '.$chronorelais->localite;?></label>
23
+ </li>
24
+ <?php endforeach; ?>
25
+ </ul>
26
+ </dd>
27
+ </dl>
28
+
29
+ <?php endif; ?>
app/design/frontend/default/default/template/chronorelais/sales/order/history.phtml ADDED
@@ -0,0 +1,79 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Magento
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Academic Free License (AFL 3.0)
8
+ * that is bundled with this package in the file LICENSE_AFL.txt.
9
+ * It is also available through the world-wide-web at this URL:
10
+ * http://opensource.org/licenses/afl-3.0.php
11
+ * If you did not receive a copy of the license and are unable to
12
+ * obtain it through the world-wide-web, please send an email
13
+ * to license@magentocommerce.com so we can send you a copy immediately.
14
+ *
15
+ * DISCLAIMER
16
+ *
17
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
18
+ * versions in the future. If you wish to customize Magento for your
19
+ * needs please refer to http://www.magentocommerce.com for more information.
20
+ *
21
+ * @category design
22
+ * @package base_default
23
+ * @copyright Copyright (c) 2010 Magento Inc. (http://www.magentocommerce.com)
24
+ * @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0)
25
+ */
26
+ ?>
27
+ <?php echo $this->getMessagesBlock()->getGroupedHtml() ?>
28
+ <?php $_orders = $this->getOrders(); ?>
29
+ <div class="page-title">
30
+ <h1><?php echo $this->__('My Orders') ?></h1>
31
+ </div>
32
+ <?php echo $this->getPagerHtml(); ?>
33
+ <?php if($_orders->getSize()): ?>
34
+ <table class="data-table" id="my-orders-table">
35
+ <col width="1" />
36
+ <col width="1" />
37
+ <col />
38
+ <col width="1" />
39
+ <col width="1" />
40
+ <col width="1" />
41
+ <thead>
42
+ <tr>
43
+ <th><?php echo $this->__('Order #') ?></th>
44
+ <th><?php echo $this->__('Date') ?></th>
45
+ <th><?php echo $this->__('Ship To') ?></th>
46
+ <th><span class="nobr"><?php echo $this->__('Order Total') ?></span></th>
47
+ <th><span class="nobr"><?php echo $this->__('Order Status') ?></span></th>
48
+ <th>&nbsp;</th>
49
+ </tr>
50
+ </thead>
51
+ <tbody>
52
+ <?php $_odd = ''; ?>
53
+ <?php foreach ($_orders as $_order): ?>
54
+ <tr>
55
+ <td><?php echo $_order->getRealOrderId() ?></td>
56
+ <td><span class="nobr"><?php echo $this->formatDate($_order->getCreatedAtStoreDate()) ?></span></td>
57
+ <td><?php echo $_order->getShippingAddress() ? $this->htmlEscape($_order->getShippingAddress()->getName()) : '&nbsp;' ?></td>
58
+ <td><?php echo $_order->formatPrice($_order->getGrandTotal()) ?></td>
59
+ <td><em><?php echo $_order->getStatusLabel() ?></em></td>
60
+ <td class="a-center">
61
+ <span class="nobr"><a href="<?php echo $this->getViewUrl($_order) ?>"><?php echo $this->__('View Order') ?></a>
62
+ <?php /*<span class="separator">|</span><a href="<?php echo $this->getTrackUrl($_order) ?>"><?php echo $this->__('Track Order') ?></a>&nbsp;*/ ?>
63
+ <?php if ($this->helper('sales/reorder')->canReorder($_order)) : ?>
64
+ <span class="separator">|</span> <a href="<?php echo $this->getReorderUrl($_order) ?>" class="link-reorder"><?php echo $this->__('Reorder') ?></a>
65
+ <?php endif ?>
66
+ </span>
67
+ <?php if ($_order->getTracksCollection()->count()) : ?>
68
+ <a href="#" onclick="popWin('<?php echo $this->helper('shipping')->getTrackingPopupUrlBySalesModel($_order) ?>','trackorder','top=50,left=50,width=800,height=600,resizable=yes,scrollbars=yes'); return false;" title="<?php echo $this->__('Track Your Order') ?>"><?php echo $this->__('Track Your Order') ?></a>
69
+ <?php endif; ?>
70
+ </td>
71
+ </tr>
72
+ <?php endforeach; ?>
73
+ </tbody>
74
+ </table>
75
+ <script type="text/javascript">decorateTable('my-orders-table');</script>
76
+ <?php echo $this->getPagerHtml(); ?>
77
+ <?php else: ?>
78
+ <p><?php echo $this->__('You have placed no orders.'); ?></p>
79
+ <?php endif ?>
app/design/frontend/default/default/template/chronorelais/sales/order/recent.phtml ADDED
@@ -0,0 +1,78 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Magento
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Academic Free License (AFL 3.0)
8
+ * that is bundled with this package in the file LICENSE_AFL.txt.
9
+ * It is also available through the world-wide-web at this URL:
10
+ * http://opensource.org/licenses/afl-3.0.php
11
+ * If you did not receive a copy of the license and are unable to
12
+ * obtain it through the world-wide-web, please send an email
13
+ * to license@magentocommerce.com so we can send you a copy immediately.
14
+ *
15
+ * DISCLAIMER
16
+ *
17
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
18
+ * versions in the future. If you wish to customize Magento for your
19
+ * needs please refer to http://www.magentocommerce.com for more information.
20
+ *
21
+ * @category design
22
+ * @package base_default
23
+ * @copyright Copyright (c) 2010 Magento Inc. (http://www.magentocommerce.com)
24
+ * @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0)
25
+ */
26
+ ?>
27
+ <div class="box-account box-recent">
28
+ <?php $_orders = $this->getOrders(); ?>
29
+ <div class="box-head">
30
+ <h2><?php echo $this->__('Recent Orders') ?></h2>
31
+ <?php if( sizeof($_orders->getItems()) > 0 ): ?><a href="<?php echo $this->getUrl('sales/order/history') ?>"><?php echo $this->__('View All') ?></a><?php endif; ?>
32
+ </div>
33
+ <?php if( sizeof($_orders->getItems()) > 0 ): ?>
34
+ <table class="data-table" id="my-orders-table">
35
+ <col width="1" />
36
+ <col width="1" />
37
+ <col />
38
+ <col width="1" />
39
+ <col width="1" />
40
+ <col width="1" />
41
+ <thead>
42
+ <tr>
43
+ <th><?php echo $this->__('Order #') ?></th>
44
+ <th><?php echo $this->__('Date') ?></th>
45
+ <th><?php echo $this->__('Ship To') ?></th>
46
+ <th><span class="nobr"><?php echo $this->__('Order Total') ?></span></th>
47
+ <th><?php echo $this->__('Status') ?></th>
48
+ <th>&nbsp;</th>
49
+ </tr>
50
+ </thead>
51
+ <tbody>
52
+ <?php foreach ($_orders as $_order): ?>
53
+ <tr>
54
+ <td><?php echo $_order->getRealOrderId() ?></td>
55
+ <td><span class="nobr"><?php echo $this->formatDate($_order->getCreatedAtStoreDate()) ?></span></td>
56
+ <td><?php echo $_order->getShippingAddress() ? $this->htmlEscape($_order->getShippingAddress()->getName()) : '&nbsp;' ?></td>
57
+ <td><?php echo $_order->formatPrice($_order->getGrandTotal()) ?></td>
58
+ <td><em><?php echo $_order->getStatusLabel() ?></em></td>
59
+ <td class="a-center">
60
+ <span class="nobr">
61
+ <a href="<?php echo $this->getViewUrl($_order) ?>"><?php echo $this->__('View Order') ?></a>
62
+ <?php if ($this->helper('sales/reorder')->canReorder($_order)) : ?>
63
+ <span class="separator">|</span> <a href="<?php echo $this->getReorderUrl($_order) ?>" class="link-reorder"><?php echo $this->__('Reorder') ?></a>
64
+ <?php endif ?>
65
+ </span>
66
+ <?php if ($_order->getTracksCollection()->count()) : ?>
67
+ <a href="#" onclick="popWin('<?php echo $this->helper('shipping')->getTrackingPopupUrlBySalesModel($_order) ?>','trackorder','top=50,left=50,width=800,height=600,resizable=yes,scrollbars=yes'); return false;" title="<?php echo $this->__('Track Your Order') ?>"><?php echo $this->__('Track Your Order') ?></a>
68
+ <?php endif; ?>
69
+ </td>
70
+ </tr>
71
+ <?php endforeach; ?>
72
+ </tbody>
73
+ </table>
74
+ <script type="text/javascript">decorateTable('my-orders-table')</script>
75
+ <?php else: ?>
76
+ <p><?php echo $this->__('You have placed no orders.'); ?></p>
77
+ <?php endif; ?>
78
+ </div>
app/etc/modules/WSChronopost_Chronorelais.xml ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <!--
3
+ /**
4
+ * Magento Wecom Chronorelais 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 Wecom
17
+ * @package Wecom_Chronorelais
18
+ * @copyright Copyright (c) 2008-2010 Wecom
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
+ <Chronopost_Chronorelais>
26
+ <active>true</active>
27
+ <codePool>community</codePool>
28
+ <version>0.1.2</version>
29
+ </Chronopost_Chronorelais>
30
+ </modules>
31
+ </config>
app/locale/en_US/Chronopost_Chronorelais.csv ADDED
@@ -0,0 +1,1034 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
+ "No point relay is associated with this postcode","No point relay is associated with this postcode"
24
+ "track the package","track the package"
25
+ "Chronorelay points","Chronorelay points"
26
+ "Application Fee","Application Fee"
27
+ "Handling Fee","Handling Fee"
28
+ "Logo Url","Logo Url"
29
+ "Weight Limit","Weight Limit"
30
+ "Free Shipping on the Amount","Free Shipping on the Amount"
31
+ "Minimum Amount for Free Shipping","Minimum Amount for Free Shipping"
32
+ "Semicolon","Semicolon"
33
+ "Comma","Comma"
34
+
35
+ "Configuration","Configuration"
36
+ "{configuration_syntax_help}","<a href='http://www.magentocommerce.com/boards/viewthread/37860/' target='_blank'>Help</a>"
37
+ "{debug_help}","0 = none, 1 = minimum, 10 = full"
38
+ "{logo_ulr_help}","Upload the logo image to the given skin folder. skin/frontend/[your package name]/[your skin name]/chronorelais/"
39
+
40
+ "Tracking URL","Tracking URL"
41
+ "Debug","Debug"
42
+ "Stop to first match","Stop to first match"
43
+ "Chronorelais Shipping module","Chronorelais Shipping module"
44
+ "Weight unit","Weight unit"
45
+ "Auto Price","Auto Price"
46
+
47
+ # OCSEditor
48
+ # Wecom_Chronorelais_Block_Adminhtml_System_Config_Form_Field_Config
49
+ "Open editor","Open editor"
50
+ # Wecom_Chronorelais_AjaxController
51
+ "Chronorelais Shipping configuration editor","Chronorelais Shipping configuration editor"
52
+ "Save","Save"
53
+ "Cancel","Cancel"
54
+ "Close","Close"
55
+ "Load","Load"
56
+ "Export","Export"
57
+ "Add a shipping method","Add a shipping method"
58
+ "New shipping method","New shipping method"
59
+ "Delete","Delete"
60
+ "Weight","Weight"
61
+ "Products quantity","Products quantity"
62
+ "Quantity","Quantity"
63
+ "Price including tax","Price including tax"
64
+ "Price excluding tax","Price excluding tax"
65
+ "Not logged in","Not logged in"
66
+ "Tracking number","Tracking number"
67
+ "Insert","Insert"
68
+ "Cart","Cart"
69
+ "Selection","Selection"
70
+ "Product","Product"
71
+ "Display","Display"
72
+ "Display original input","Display original input"
73
+ "Display corrected names","Display corrected names"
74
+ "Display codes","Display codes"
75
+ "Limit to","Limit to"
76
+ "Exclude","Exclude"
77
+ "Destination country","Destination country"
78
+ "Cart weight","Cart weight"
79
+ "Cart quantity","Cart quantity"
80
+ "Disabled","Disabled"
81
+ "Ignored lines","Ignored lines"
82
+ "Correct","Correct"
83
+ "Apply changes","Apply changes"
84
+ # Fields
85
+ "Enabled","Enabled"
86
+ "Code","Code"
87
+ "Label","Label"
88
+ "Description","Description"
89
+ "Destination","Destination"
90
+ "Origin","Origin"
91
+ "Conditions","Conditions"
92
+ "Fees","Fees"
93
+ "Customer groups","Customer groups"
94
+ "Tracking url","Tracking url"
95
+ "Comment","Comment"
96
+ # JS
97
+ "Dissociate","Dissociate"
98
+ "Remove","Remove"
99
+ "Edit","Edit"
100
+ "Enter the new value:","Enter the new value:"
101
+ "[No label]","[No label]"
102
+ "Loading...","Loading..."
103
+ # Help
104
+ "Chronorelais Shipping extension help","Chronorelais Shipping extension help"
105
+ "{ocseditor.help.summary}","
106
+ <h4>Summary</h4>
107
+ <div class=""table-of-contents"">
108
+ <ul>
109
+ <li><a href=""#"" onclick=""ocseditor.help('introduction');"">Introduction</a></li>
110
+ <li><a href=""#"" onclick=""ocseditor.help('property.label');"">The label : `label`</a></li>
111
+ <li><a href=""#"" onclick=""ocseditor.help('property.fees');"">Shipping fees : `fees`</a>
112
+ <ul>
113
+ <li><a href=""#"" onclick=""ocseditor.help('more.formulas');"">Introduction to formulas</a></li>
114
+ <li><a href=""#"" onclick=""ocseditor.help('more.tables');"">Use of rate tables</a></li>
115
+ <li><a href=""#"" onclick=""ocseditor.help('more.copy');"">Make a copy of a property of another method</a></li>
116
+ <li><a href=""#"" onclick=""ocseditor.help('more.special-functions');"">Special functions in formulas</a></li>
117
+ <li class=""new""><a href=""#"" onclick=""ocseditor.help('more.attributes-options');"">Usage of product's attributes or options</a> (stock data added in version 2.3.2)</li>
118
+ <li class=""new""><a href=""#"" onclick=""ocseditor.help('more.foreach');"">Usage of foreach loops</a> (added in version 2.1.7)</li>
119
+ <li class=""new""><a href=""#"" onclick=""ocseditor.help('more.custom-variables');"">Usage of Magento's custom variables</a> (added in version 2.2.7)</li>
120
+ </ul>
121
+ </li>
122
+ <li><a href=""#"" onclick=""ocseditor.help('property.conditions');"">The conditions : `conditions`</a></li>
123
+ <li><a href=""#"" onclick=""ocseditor.help('property.destination');"">The destination : `destination`</a></li>
124
+ <li><a href=""#"" onclick=""ocseditor.help('property.code');"">The code : `code`</a></li>
125
+ <li><a href=""#"" onclick=""ocseditor.help('property.description');"">The description : `description`</a></li>
126
+ <li><a href=""#"" onclick=""ocseditor.help('property.origin');"">The origin : `origin`</a></li>
127
+ <li><a href=""#"" onclick=""ocseditor.help('property.customer_groups');"">Customer groups : `customer_groups`</a></li>
128
+ <li><a href=""#"" onclick=""ocseditor.help('property.tracking_url');"">Tracking URL : `tracking_url`</a></li>
129
+ <li><a href=""#"" onclick=""ocseditor.help('property.*comment');"">Comments</a></li>
130
+ <li><a href=""#"" onclick=""ocseditor.help('changelog');"">Changelog</a></li>
131
+ </ul>
132
+ </div>
133
+
134
+ "
135
+ "{ocseditor.help.introduction}","
136
+ <div class=""help-header"">
137
+ <p><a href=""#"" onclick=""ocseditor.help('summary');"">Summary</a></p>
138
+ </div>
139
+
140
+ <h4>Introduction</h4>
141
+ <p>
142
+ 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>
143
+ </p>
144
+
145
+ <p>
146
+ The configuration syntax is similar to JSON syntax.
147
+ </p>
148
+ <p>
149
+
150
+ Example :
151
+ </p>
152
+ <div class=""code""><span class=""comment""># National</span><br/>
153
+ {<br/>
154
+ &nbsp;&nbsp;&nbsp;label: <span class=""string"">""National""</span>,<br/>
155
+ &nbsp;&nbsp;&nbsp;destination: <span class=""string"">""AD,FR,MC""</span>,<br/>
156
+ &nbsp;&nbsp;&nbsp;conditions: <span class=""string"">""{cart.price_excluding_tax}&lt;1000.00""</span>,<br/>
157
+
158
+ &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/>
159
+ }</div>
160
+
161
+ <p>
162
+ The character `#` at the beginning of a line indicates a comment.<br/>
163
+ A configuration element begins with the character `{` and ends with `}`.<br/>
164
+ A configuration element contains several properties associated with values.<br/>
165
+
166
+ 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.
167
+ </p>
168
+ <p>
169
+ List of properties:
170
+ </p>
171
+ <ul>
172
+ <li><b>label</b>: name (label)</li>
173
+ <li><b>description</b>: description (only visible if template show it)</li>
174
+ <li><b>code</b>: shipping method's code (optional but if specified it must be unique)</li>
175
+ <li><b>enabled</b>: configuration bloc activated or not (ex: <span class=""value"">true</span> or <span class=""value"">false</span>)</li>
176
+ <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>
177
+ <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>
178
+ <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>
179
+ <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>
180
+ <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>
181
+ </ul>
182
+
183
+ <div class=""help-footer"">
184
+ <p><a href=""#"" onclick=""ocseditor.help('summary');"">Summary</a></p>
185
+ </div>
186
+
187
+ "
188
+ "{ocseditor.help.property.label}","
189
+ <div class=""help-header"">
190
+ <p><a href=""#"" onclick=""ocseditor.help('summary');"">Summary</a></p>
191
+ </div>
192
+
193
+ <h4>The label : `label`</h4>
194
+ <p>This will be the name given to the shipping method.</p>
195
+ <p>Elements such as the weight of goods can be inserted in the label.<br/>
196
+ To do this, use the following variables:</p>
197
+ <ul>
198
+ <li><b>{destination.country.name}</b>: destination country name</li>
199
+ <li><b>{destination.country.code}</b>: destination country code</li>
200
+ <li><b>{destination.region.code}</b>: destination region code</li>
201
+ <li><b>{destination.postcode}</b>: destination postcode</li>
202
+ <li><b>{origin.country.name}</b>: origin country name</li>
203
+ <li><b>{origin.country.code}</b>: origin country code</li>
204
+ <li><b>{origin.region.code}</b>: origin region code</li>
205
+ <li><b>{origin.postcode}</b>: origin postcode</li>
206
+ <li><b>{cart.weight}</b>: weight of goods</li>
207
+ <li><b>{cart.weight.unit}</b>: weight unit</li>
208
+ <li><b>{cart.quantity}</b>: products quantity</li>
209
+ <li><b>{cart.price_including_tax}</b>: price including tax</li>
210
+ <li><b>{cart.price_excluding_tax}</b>: price excluding tax</li>
211
+ <li><b>{store.code}</b>: store code</li>
212
+ <li><b>{store.name}</b>: store name</li>
213
+ <li><b>{store.address}</b>: store address</li>
214
+ <li><b>{store.phone}</b>: store phone</li>
215
+ <li><b>{date.timestamp}</b>: UNIX timestamp of current date</li>
216
+ <li><b>{date.year}</b>: year of current date</li>
217
+ <li><b>{date.month}</b>: month of current date</li>
218
+ <li><b>{date.day}</b>: day of current date</li>
219
+ <li><b>{date.hour}</b>: hour of current date</li>
220
+ <li><b>{date.minute}</b>: minute of current date</li>
221
+ <li><b>{date.second}</b>: second of current date</li>
222
+ </ul>
223
+ <div class=""code"">label: <span class=""string"">""Colissimo ({cart.weight} / {destination.country.name})""</span>,</div>
224
+ <p>This line will display for example ""Colissimo (3.0kg / France)"".</p>
225
+
226
+ <div class=""help-footer"">
227
+ <p><a href=""#"" onclick=""ocseditor.help('summary');"">Summary</a></p>
228
+ </div>
229
+ "
230
+ "{ocseditor.help.property.fees}","
231
+ <div class=""help-header"">
232
+ <p><a href=""#"" onclick=""ocseditor.help('summary');"">Summary</a></p>
233
+ </div>
234
+
235
+ <h4>Shipping fees : `fees`</h4>
236
+ <p>
237
+ The property `fees` is specified as a <a href=""#"" onclick=""ocseditor.help('more.formulas');"">formula (see introduction to formulas)</a>.
238
+ </p>
239
+
240
+ <div class=""code""><span class=""comment""># Fixed fees</span><br/>fees: 10.00,<br/>
241
+ <br/>
242
+ <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/>
243
+ <br/>
244
+ <span class=""comment""># Formula</span><br/>fees: <span class=""string"">""0.1 * {cart.price_excluding_tax} + 10.00""</span>,<br/>
245
+ <br/>
246
+ <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>,
247
+ </div>
248
+
249
+ <div class=""help-footer"">
250
+ <p><a href=""#"" onclick=""ocseditor.help('summary');"">Summary</a></p>
251
+ </div>
252
+ "
253
+ "{ocseditor.help.more.formulas}","
254
+ <div class=""help-header"">
255
+ <p><a href=""#"" onclick=""ocseditor.help('summary');"">Summary</a></p>
256
+ </div>
257
+
258
+ <h4>Introduction to formulas</h4>
259
+ <p>
260
+ Properties `fees` and `conditions` are specified as formulas.
261
+ </p>
262
+ <p>
263
+ Mathematical signs available:
264
+ </p>
265
+ <ul>
266
+ <li>operators: *, /, + et -</li>
267
+ <li>modulo: %</li>
268
+ <li>brackets: ( et )</li>
269
+ <li>boolean operators &amp;&amp;, and, ||, or, ==, &lt;, &gt;, &lt;=, &gt;=</li>
270
+ <li>binary operators &amp; et |</li>
271
+ <li>operators group C ? X : Y (ex: ""{cart.price_exluding_tax}&gt;100 ? 15*{cart.weight} : 20*{cart.weight}"")</li>
272
+ </ul>
273
+ <p>
274
+ Functions available:
275
+ </p>
276
+ <ul>
277
+ <li>rounds: round(x), floor(x), ceil(x)</li>
278
+ <li>absolute value: abs(x)</li>
279
+ <li>maximum: max(x,y)</li>
280
+ <li>minimum: min(x,y)</li>
281
+ <li>random integer: rand(min,max)</li>
282
+ <li>power: pow(x,puissance)</li>
283
+ <li>PI number: pi()</li>
284
+ <li>square root: sqrt(x)</li>
285
+ <li>logarithm: log(x) for the natural logarithm or log(x,base)</li>
286
+ <li>exponential: exp(x)</li>
287
+ </ul>
288
+ <p>
289
+ Ability to use advanced features like: casting to integer (int) casting to floating number (float), comparison with null or boolean values true and false.
290
+ </p>
291
+ <p>
292
+ Variables available:
293
+ </p>
294
+ <ul>
295
+
296
+ <li><b>{cart.weight}</b>: full package weight</li>
297
+ <li><b>{cart.price_including_tax}</b>: price including tax</li>
298
+ <li><b>{cart.price_excluding_tax}</b>: price excluding tax</li>
299
+ <li><b>{cart.quantity}</b>: items count in cart</li>
300
+ <li><b>{date.timestamp}</b>: UNIX timestamp of current date</li>
301
+ <li><b>{date.year}</b>: year of current date</li>
302
+ <li><b>{date.month}</b>: month of current date</li>
303
+ <li><b>{date.day}</b>: day of current date</li>
304
+ <li><b>{date.hour}</b>: hour of current date</li>
305
+ <li><b>{date.minute}</b>: minute of current date</li>
306
+ <li><b>{date.second}</b>: second of current date</li>
307
+ <li><b>{free_shipping}</b>: free shipping (offered by a Magento rule) [true/false]</li>
308
+ </ul>
309
+ <p>
310
+ You can put spaces and line returns in formulas (to air).
311
+ </p>
312
+ <p class=""new"" style=""font-weight: bold;"">
313
+ You can also use advanced features such as rates tables, copy of a property of another method,
314
+ special functions, usage of product's attributes and options or usage of custom variables.
315
+ </p>
316
+
317
+ <div class=""help-footer"">
318
+ <p><a href=""#"" onclick=""ocseditor.help('summary');"">Summary</a></p>
319
+ </div>
320
+ "
321
+ "{ocseditor.help.more.tables}","
322
+ <div class=""help-header"">
323
+ <p><a href=""#"" onclick=""ocseditor.help('summary');"">Summary</a></p>
324
+ </div>
325
+
326
+ <h4>Usage of rates tables</h4>
327
+ <p>
328
+ In a table, you can include or exclude a limit value with characters '[' and ']' :
329
+ </p>
330
+ <div class=""code""><span class=""comment""># Upper limit 1.0 included</span><br/>
331
+ fees: <span class=""string"">""{table {cart.weight} in 1.0]:5.00}""</span>,<br/>
332
+ <br/>
333
+ <span class=""comment""># Upper limit 1.0 excluded</span><br/>
334
+ fees: <span class=""string"">""{table {cart.weight} in 1.0[:5.00}""</span>,</div>
335
+
336
+ <p>
337
+ In a table, you must specify the reference value. For this, we can use one of the available variables.<br/>
338
+ You can also use a formula to define another reference variable.
339
+ </p>
340
+
341
+ <div class=""code""><span class=""comment""># Limit values are compared to the cart's weight</span><br/>
342
+ fees: <span class=""string"">""{table {cart.weight} in 0.5:5.30, 1.0:6.50}""</span>,<br/>
343
+ <br/>
344
+ <span class=""comment""># Limit values are compared to the items count</span><br/>
345
+ fees: <span class=""string"">""{table {cart.quantity} in 10:5.30, 20:6.50}""</span>,<br/>
346
+ <br/>
347
+ <span class=""comment""># Limit values are compared to the prixe including tax</span><br/>
348
+ fees: <span class=""string"">""{table {cart.price_including_tax} in 15.00:5.30, 30.00:6.50}""</span>,<br/>
349
+ <br/>
350
+ <span class=""comment""># Limit values are compared to the prixe excluding tax</span><br/>
351
+ fees: <span class=""string"">""{table {cart.price_excluding_tax} in 15.00:5.30, 30.00:6.50}""</span>,<br/>
352
+ <br/>
353
+ <span class=""comment""># Limit values are compared to an user defined reference value</span><br/>
354
+ fees: <span class=""string"">""{table ceil({cart.weight}/10) in 1:5.30, 2:6.50}""</span>,
355
+ </div>
356
+
357
+ <div class=""help-footer"">
358
+ <p><a href=""#"" onclick=""ocseditor.help('summary');"">Summary</a></p>
359
+ </div>
360
+ "
361
+ "{ocseditor.help.more.copy}","
362
+ <div class=""help-header"">
363
+ <p><a href=""#"" onclick=""ocseditor.help('summary');"">Summary</a></p>
364
+ </div>
365
+
366
+ <h4>Make a copy of a property of another method</h4>
367
+ <p>
368
+ It is possible to make a copy of a property in another using the syntax below.
369
+ </p>
370
+ <p>
371
+ You can use this technique in the properties 'conditions', 'fees',
372
+ 'enabled', 'label', 'description', 'destination', 'origin', 'customer_groups' and 'tracking_url'
373
+ <strong>but not in property 'code'</strong>.
374
+ </p>
375
+
376
+ <div class=""code""><span class=""comment""># Colissimo</span><br/>
377
+ {<br/>
378
+ &nbsp;&nbsp;&nbsp;code: <span class=""string"">""colissimo""</span>,<br/>
379
+ &nbsp;&nbsp;&nbsp;label: <span class=""string"">""Colissimo""</span>,<br/>
380
+ &nbsp;&nbsp;&nbsp;destination: <span class=""string"">""AD,FR,MC""</span>,<br/>
381
+ &nbsp;&nbsp;&nbsp;conditions: <span class=""string"">""{cart.price_excluding_tax}&lt;1000.00""</span>,<br/>
382
+ &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/>
383
+ }<br/>
384
+ ...<br/>
385
+ &nbsp;&nbsp;&nbsp;<span class=""comment""># Copy conditions of another method</span><br/>
386
+ &nbsp;&nbsp;&nbsp;conditions: <span class=""string"">""({colissimo.conditions}) and ({cart.weight}&gt;10.0)""</span>,<br/>
387
+ ...<br/>
388
+ &nbsp;&nbsp;&nbsp;<span class=""comment""># Copy shipping fees of another method</span><br/>
389
+ &nbsp;&nbsp;&nbsp;fees: <span class=""string"">""({colissimo.fees}) + 15.00""</span>,<br/>
390
+ ...
391
+ </div>
392
+
393
+ <div class=""help-footer"">
394
+ <p><a href=""#"" onclick=""ocseditor.help('summary');"">Summary</a></p>
395
+ </div>
396
+ "
397
+ "{ocseditor.help.more.special-functions}","
398
+ <div class=""help-header"">
399
+ <p><a href=""#"" onclick=""ocseditor.help('summary');"">Summary</a></p>
400
+ </div>
401
+
402
+ <h4>Special functions in formulas</h4>
403
+
404
+ <p>
405
+ You can use special functions in formulas.
406
+ </p>
407
+ <p>
408
+ List of special functions :
409
+ </p>
410
+ <ul>
411
+ <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>
412
+ <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>
413
+ </ul>
414
+
415
+ <div class=""code""><span class=""comment""># Example of usage of the min function to propose Free shipping<br/>
416
+ # and supplements for faster shipping methods</span><br/>
417
+ {<br/>
418
+ &nbsp;&nbsp;&nbsp;code: <span class=""string"">""courrier_suivi""</span>,<br/>
419
+ &nbsp;&nbsp;&nbsp;label: <span class=""string"">""Courrier suivi""</span>,<br/>
420
+ &nbsp;&nbsp;&nbsp;destination: <span class=""string"">""FR""</span>,<br/>
421
+ &nbsp;&nbsp;&nbsp;conditions: <span class=""string"">""{cart.price_including_tax}&lt;80""</span>,<br/>
422
+ &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/>
423
+ }<br/>
424
+ <br/>
425
+ {<br/>
426
+ &nbsp;&nbsp;&nbsp;code: <span class=""string"">""courrier_suivi_offert""</span>,<br/>
427
+ &nbsp;&nbsp;&nbsp;label: <span class=""string"">""Free shipping - Courrier suivi""</span>,<br/>
428
+ &nbsp;&nbsp;&nbsp;destination: <span class=""string"">""{courrier_suivi.destination}""</span>,<br/>
429
+ &nbsp;&nbsp;&nbsp;conditions: <span class=""string"">""{cart.price_including_tax}&gt;=80 and {cart.weight}&lt;=0.500""</span>,<br/>
430
+ &nbsp;&nbsp;&nbsp;fees: 0.00,<br/>
431
+ }<br/>
432
+ <br/>
433
+ {<br/>
434
+ &nbsp;&nbsp;&nbsp;code: <span class=""string"">""lettre_recommandee""</span>,<br/>
435
+ &nbsp;&nbsp;&nbsp;label: <span class=""string"">""Lettre Recommandée""</span>,<br/>
436
+ &nbsp;&nbsp;&nbsp;destination: <span class=""string"">""FR""</span>,<br/>
437
+ &nbsp;&nbsp;&nbsp;conditions: <span class=""string"">""{cart.price_including_tax}&lt;80""</span>,<br/>
438
+ &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/>
439
+ }<br/>
440
+ <br/>
441
+ {<br/>
442
+ &nbsp;&nbsp;&nbsp;code: <span class=""string"">""lettre_recommandee_offert""</span>,<br/>
443
+ &nbsp;&nbsp;&nbsp;label: <span class=""string"">""Free shipping - Lettre Recommandée""</span>,<br/>
444
+ &nbsp;&nbsp;&nbsp;destination: <span class=""string"">""{lettre_recommandee.destination}""</span>,<br/>
445
+ &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/>
446
+ &nbsp;&nbsp;&nbsp;fees: 0.00,<br/>
447
+ }<br/>
448
+ <br/>
449
+ {<br/>
450
+ &nbsp;&nbsp;&nbsp;code: <span class=""string"">""supplement_lettre_recommandee""</span>,<br/>
451
+ &nbsp;&nbsp;&nbsp;label: <span class=""string"">""Lettre Recommandée supplement""</span>,<br/>
452
+ &nbsp;&nbsp;&nbsp;destination: <span class=""string"">""{lettre_recommandee.destination}""</span>,<br/>
453
+ &nbsp;&nbsp;&nbsp;conditions: <span class=""string"">""{courrier_suivi_offert.conditions}""</span>,<br/>
454
+ &nbsp;&nbsp;&nbsp;fees: <span class=""string"">""{lettre_recommandee.fees} - {courrier_suivi.fees}""</span>,<br/>
455
+ }<br/>
456
+ <br/>
457
+ {<br/>
458
+ &nbsp;&nbsp;&nbsp;code: <span class=""string"">""colissimo""</span>,<br/>
459
+ &nbsp;&nbsp;&nbsp;label: <span class=""string"">""Colissimo""</span>,<br/>
460
+ &nbsp;&nbsp;&nbsp;destination: <span class=""string"">""FR""</span>,<br/>
461
+ &nbsp;&nbsp;&nbsp;conditions: <span class=""string"">""{cart.price_including_tax}&lt;80""</span>,<br/>
462
+ &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/>
463
+ }<br/>
464
+ <br/>
465
+ {<br/>
466
+ &nbsp;&nbsp;&nbsp;code: <span class=""string"">""colissimo_offert""</span>,<br/>
467
+ &nbsp;&nbsp;&nbsp;label: <span class=""string"">""Free shipping - Colissimo""</span>,<br/>
468
+ &nbsp;&nbsp;&nbsp;destination: <span class=""string"">""{colissimo.destination}""</span>,<br/>
469
+ &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/>
470
+ &nbsp;&nbsp;&nbsp;fees: 0.00,<br/>
471
+ }<br/>
472
+ <br/>
473
+ {<br/>
474
+ &nbsp;&nbsp;&nbsp;code: <span class=""string"">""supplement_colissimo""</span>,<br/>
475
+ &nbsp;&nbsp;&nbsp;label: <span class=""string"">""Colissimo supplement""</span>,<br/>
476
+ &nbsp;&nbsp;&nbsp;destination: <span class=""string"">""{colissimo.destination}""</span>,<br/>
477
+ &nbsp;&nbsp;&nbsp;conditions: <span class=""string"">""{courrier_suivi_offert.conditions} or {lettre_recommandee_offert.conditions}""</span>,<br/>
478
+ &nbsp;&nbsp;&nbsp;fees: <span class=""string"">""{colissimo.fees} - min({courrier_suivi.fees},{lettre_recommandee.fees})""</span>,<br/>
479
+ }<br/>
480
+ <br/>
481
+ {<br/>
482
+ &nbsp;&nbsp;&nbsp;code: <span class=""string"">""chronopost""</span>,<br/>
483
+ &nbsp;&nbsp;&nbsp;label: <span class=""string"">""Chronopost""</span>,<br/>
484
+ &nbsp;&nbsp;&nbsp;destination: <span class=""string"">""FR""</span>,<br/>
485
+ &nbsp;&nbsp;&nbsp;conditions: <span class=""string"">""{cart.price_including_tax}&lt;80""</span>,<br/>
486
+ &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/>
487
+ }<br/>
488
+ <br/>
489
+ {<br/>
490
+ &nbsp;&nbsp;&nbsp;code: <span class=""string"">""chronopost_offert""</span>,<br/>
491
+ &nbsp;&nbsp;&nbsp;label: <span class=""string"">""Free shipping - Chronopost""</span>,<br/>
492
+ &nbsp;&nbsp;&nbsp;destination: <span class=""string"">""FR""</span>,<br/>
493
+ &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/>
494
+ &nbsp;&nbsp;&nbsp;fees: 0.00,<br/>
495
+ }<br/>
496
+ <br/>
497
+ {<br/>
498
+ &nbsp;&nbsp;&nbsp;code: <span class=""string"">""supplement_chronopost""</span>,<br/>
499
+ &nbsp;&nbsp;&nbsp;label: <span class=""string"">""Chronopost supplement""</span>,<br/>
500
+ &nbsp;&nbsp;&nbsp;destination: <span class=""string"">""{chronopost.destination}""</span>,<br/>
501
+ &nbsp;&nbsp;&nbsp;conditions: <span class=""string"">""{courrier_suivi_offert.conditions} or {lettre_recommandee_offert.conditions} or {colissimo_offert.conditions}""</span>,<br/>
502
+ &nbsp;&nbsp;&nbsp;fees: <span class=""string"">""{chronopost.fees} - min({courrier_suivi.fees},{lettre_recommandee.fees},{colissimo.fees})""</span>,<br/>
503
+ }
504
+ </div>
505
+
506
+ <div class=""help-footer"">
507
+ <p><a href=""#"" onclick=""ocseditor.help('summary');"">Summary</a></p>
508
+ </div>
509
+ "
510
+ "{ocseditor.help.more.attributes-options}","
511
+ <div class=""help-header"">
512
+ <p><a href=""#"" onclick=""ocseditor.help('summary');"">Summary</a></p>
513
+ </div>
514
+
515
+ <h4>Usage of product's attributes or options</h4>
516
+
517
+ <p>
518
+ It is possible to use product's attributes or options with the syntax below.
519
+ </p>
520
+ <p>
521
+ You can use this technique in the properties 'conditions' and 'fees'.
522
+ </p>
523
+
524
+ <div class=""code""><span class=""comment""># If at least one product has the attribute 'color' equal to 'Blue'<br/></span>
525
+ conditions: <span class=""string"">""{count products where product.attribute.color=='Bleu'}&gt;0""</span>,<br/>
526
+ ...<br/>
527
+ <span class=""comment""># If all products have the option 'size' greater or equal to '1'<br/></span>
528
+ conditions: <span class=""string"">""{count products where product.option.size&gt;='1'}=={cart.quantity}""</span>,<br/>
529
+ ...<br/>
530
+ <span class=""comment""># Different SKU count<br/></span>
531
+ conditions: <span class=""string"">""{count distinct product.attribute.sku}""</span>,<br/>
532
+ ...<br/>
533
+ <span class=""comment""># The sum of all options 'size' is greater than '1'<br/></span>
534
+ conditions: <span class=""string"">""{sum product.option.size}&gt;30""</span>,<br/>
535
+ ...<br/>
536
+ <span class=""comment""># Count of products in stock<br/></span>
537
+ conditions: <span class=""string"">""{count products where product.stock.is_in_stock==true}""</span>,<br/>
538
+ ...</div>
539
+
540
+ <p>
541
+ Available prefixes list:
542
+ </p>
543
+ <ul>
544
+ <li><b>count:</b> count (always followed by 'products')</li>
545
+ <li><b>count distinct:</b> distinct count (always followed by a property)</li>
546
+ <li><b>sum:</b> sum (always followed by a property)</li>
547
+ </ul>
548
+ <p>
549
+ Available properties list:
550
+ </p>
551
+ <ul>
552
+ <li><b>product.attribute.* :</b> attribute</li>
553
+ <li><b>product.option.* :</b> option</li>
554
+ <li><b>product.stock.is_in_stock :</b> product availability</li>
555
+ <li><b>product.stock.quantity :</b> stock quantity of the product</li>
556
+ </ul>
557
+ <p>
558
+ 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.
559
+ </p>
560
+ <p>
561
+ 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.
562
+ </p>
563
+ <div class=""code""><span class=""comment""># Property Yes/No</span><br/>
564
+ conditions: <span class=""string"">""{count products where product.attribute.colissimo_allowed==1}""</span>,<br/>
565
+ <span class=""comment""># or</span><br/>
566
+ conditions: <span class=""string"">""{count products where product.attribute.colissimo_allowed==true}""</span>,</div>
567
+
568
+ <p>
569
+ 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:
570
+ </p>
571
+
572
+ <div class=""code""><span class=""comment""># Condition validated if the attribute 'color' is equal to the value whose id is 1</span><br/>
573
+ conditions: <span class=""string"">""{count products where product.attribute.color.id==1}""</span>,</div>
574
+
575
+ <div class=""help-footer"">
576
+ <p><a href=""#"" onclick=""ocseditor.help('summary');"">Summary</a></p>
577
+ </div>
578
+ "
579
+ "{ocseditor.help.more.foreach}","
580
+ <div class=""help-header"">
581
+ <p><a href=""#"" onclick=""ocseditor.help('summary');"">Summary</a></p>
582
+ </div>
583
+
584
+ <h4>Usage of foreach loops</h4>
585
+ <p>
586
+ Foreach loops can perform calculations on groups of products rather than consider all the products in the basket.<br/>
587
+ The overall result of a foreach loop is the sum of the results of each pass through the loop.
588
+ </p>
589
+ <p>
590
+ Inside a foreach loop, it is possible to use new variables:
591
+ </p>
592
+ <ul>
593
+ <li><b>{selection.weight}</b>: selection weight</li>
594
+ <li><b>{selection.quantity}</b>: items count in the selection</li>
595
+ </ul>
596
+ <p>
597
+ When the selection is done on the sku, each selection is composed of a single article. We can use other variables:
598
+ </p>
599
+ <ul>
600
+ <li><b>{product.weight}</b>: weight of selected product</li>
601
+ <li><b>{product.quantity}</b>: quantity of selected product</li>
602
+ <li><b>{product.attribute.*}</b>: attribute of the selected product</li>
603
+ <li><b>{product.option.*}</b>: option of the selected product</li>
604
+ </ul>
605
+
606
+ <div class=""code""><span class=""comment""># Grouping products by origin and treat groups seperatly</span><br/>
607
+ 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/>
608
+ <br/>
609
+ <span class=""comment""># Individual calculation of shipping fees</span><br/>
610
+ fees: <span class=""string"">""{foreach product.attribute.sku}{product.attribute.shipping}*{product.quantity}{/foreach}""</span>,<br/>
611
+ </div>
612
+
613
+ <div class=""help-footer"">
614
+ <p><a href=""#"" onclick=""ocseditor.help('summary');"">Summary</a></p>
615
+ </div>
616
+ "
617
+ "{ocseditor.help.more.custom-variables}","
618
+ <div class=""help-header"">
619
+ <p><a href=""#"" onclick=""ocseditor.help('summary');"">Summary</a></p>
620
+ </div>
621
+
622
+ <h4>Usage of Magento's Custom Variables</h4>
623
+ <p>
624
+ Since version 1.4.0.1 of Magento, it is possible to define custom variables.
625
+ </p>
626
+ <p>
627
+ Version 2.2.7 of Chronorelais Shipping allows you to use these custom variables using the following syntax:
628
+ </p>
629
+ <div class=""code""><span class=""comment""># Usage of custom variable my_var<br/></span>
630
+ fees: <span class=""string"">""{customvar.my_var}*5.00""</span>,<br/>
631
+ ...<br/>
632
+ <span class=""comment""># The same using the standard syntax of Magento<br/></span>
633
+ fees: <span class=""string"">""{{customVar code=my_var}}*5.00""</span>,<br/>
634
+ ...</div>
635
+
636
+ <div class=""help-footer"">
637
+ <p><a href=""#"" onclick=""ocseditor.help('summary');"">Summary</a></p>
638
+ </div>
639
+ "
640
+ "{ocseditor.help.property.conditions}","
641
+ <div class=""help-header"">
642
+ <p><a href=""#"" onclick=""ocseditor.help('summary');"">Summary</a></p>
643
+ </div>
644
+
645
+ <h4>The conditions : `conditions`</h4>
646
+ <p>
647
+ The property `conditions` is specified as a <a href=""#"" onclick=""ocseditor.help('more.formulas');"">formula (see introduction to formulas)</a>
648
+ that must return a boolean value (true or false).
649
+ </p>
650
+
651
+ <div class=""code""><span class=""comment""># Prices range</span><br/>
652
+ <br/>
653
+ &nbsp;&nbsp;&nbsp;<span class=""comment""># From 0 to 70 including tax</span><br/>
654
+ &nbsp;&nbsp;&nbsp;conditions: <span class=""string"">""{cart.price_including_tax}&lt;=70""</span>,<br/>
655
+
656
+ <br/>
657
+ &nbsp;&nbsp;&nbsp;<span class=""comment""># From 0 to 70 excluding tax</span><br/>
658
+ &nbsp;&nbsp;&nbsp;conditions: <span class=""string"">""{cart.price_excluding_tax}&lt;=70""</span>,<br/>
659
+ <br/>
660
+ &nbsp;&nbsp;&nbsp;<span class=""comment""># From 20 excluded to 70 included</span><br/>
661
+ &nbsp;&nbsp;&nbsp;conditions: <span class=""string"">""({cart.price_excluding_tax} &gt; 20) and ({cart.price_excluding_tax} &lt;= 70)""</span>,<br/>
662
+ <br/>
663
+ &nbsp;&nbsp;&nbsp;<span class=""comment""># From 10 included to 50 excluded</span><br/>
664
+ &nbsp;&nbsp;&nbsp;conditions: <span class=""string"">""({cart.price_excluding_tax} &gt;= 10) and ({cart.price_excluding_tax} &lt; 50)""</span>,<br/>
665
+
666
+ <br/>
667
+ <br/>
668
+ <span class=""comment""># Weights range</span><br/>
669
+ <br/>
670
+ &nbsp;&nbsp;&nbsp;<span class=""comment""># From 0.5 excluded to 3 included</span><br/>
671
+ &nbsp;&nbsp;&nbsp;conditions: <span class=""string"">""({cart.weight} &gt; 0.5) and ({cart.weight} &lt;= 3.0)""</span>,<br/>
672
+ <br/>
673
+ &nbsp;&nbsp;&nbsp;<span class=""comment""># From 1 included to 5 excluded</span><br/>
674
+ &nbsp;&nbsp;&nbsp;conditions: <span class=""string"">""({cart.weight} &gt;= 1.0) and ({cart.weight} &lt; 5.0)""</span>,<br/>
675
+ <br/>
676
+ <br/>
677
+ <span class=""comment""># Frais de port offerts</span><br/>
678
+
679
+ <br/>
680
+ &nbsp;&nbsp;&nbsp;<span class=""comment""># Uniquement si frais de port offerts</span><br/>
681
+ &nbsp;&nbsp;&nbsp;conditions: <span class=""string"">""{free_shipping}""</span>,<br/>
682
+ <br/>
683
+ &nbsp;&nbsp;&nbsp;<span class=""comment""># Uniquement si frais de port non offerts</span><br/>
684
+ &nbsp;&nbsp;&nbsp;conditions: <span class=""string"">""!{free_shipping}""</span>,<br/>
685
+ <br/>
686
+ <br/>
687
+ <span class=""comment""># Product's attribute or option</span><br/>
688
+ <br/>
689
+ &nbsp;&nbsp;&nbsp;<span class=""comment""># If at least one product has the attribute 'color' equal to 'Blue'</span><br/>
690
+ &nbsp;&nbsp;&nbsp;conditions: <span class=""string"">""{count products where product.attribute.color=='Bleu'}&gt;1""</span>,<br/>
691
+ <br/>
692
+ &nbsp;&nbsp;&nbsp;<span class=""comment""># If all products have the option 'size' greater or equal to '1'</span><br/>
693
+ &nbsp;&nbsp;&nbsp;conditions: <span class=""string"">""{count products where product.option.size&gt;='1'}=={cart.quantity}""</span>,</div>
694
+
695
+ <div class=""help-footer"">
696
+ <p><a href=""#"" onclick=""ocseditor.help('summary');"">Summary</a></p>
697
+ </div>
698
+
699
+ "
700
+ "{ocseditor.help.property.destination}","
701
+ <div class=""help-header"">
702
+ <p><a href=""#"" onclick=""ocseditor.help('summary');"">Summary</a></p>
703
+ </div>
704
+
705
+ <h4>The destination : `destination`</h4>
706
+ <p>
707
+ The country codes used are those of Magento (it seem that they are the same as the codes ISO 3166-1 alpha-2).<br/>
708
+ It is possible to specify region codes <span class=""new"">or postcodes</span> that you want to filter or exclude.
709
+ </p>
710
+
711
+ <div class=""code""><span class=""comment""># France, Germany, Switzerland, Spain, Italy</span><br/>
712
+ destination: <span class=""string"">""FR,DE,CH,ES,IT""</span>,<br/>
713
+ <br/>
714
+ <span class=""comment""># France without Corsica</span><br/>
715
+ destination: <span class=""string"">""FR-(2A,2B)""</span>,<br/>
716
+
717
+ <br/>
718
+ <span class=""comment""># Corsica</span><br/>
719
+ destination: <span class=""string"">""FR(2A,2B)""</span>,<br/>
720
+ <br/>
721
+ <span class=""comment""># World without Germany and Corsica</span><br/>
722
+ destination: <span class=""string"">""* - ( DE, FR(2A,2B) )""</span>,</div>
723
+
724
+ <div class=""tips"">
725
+ <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>
726
+ <ul>
727
+ <li><strong>UE</strong> or <strong>Union Européenne</strong> : adds the European Union countries.</li>
728
+ <li><strong>DOM</strong> : adds French Overseas Departments.</li>
729
+ <li><strong>COM</strong> : adds French Overseas Communities.</li>
730
+ <li><strong>Outre-Mer</strong> : adds the whole French Overseas.</li>
731
+ <li><strong>Corse</strong> : adds Corsica (""FR(2A,2B)"").</li>
732
+ </ul>
733
+ <p>
734
+ 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.
735
+ </p>
736
+ </div>
737
+
738
+ <div class=""help-footer"">
739
+ <p><a href=""#"" onclick=""ocseditor.help('summary');"">Summary</a></p>
740
+ </div>
741
+ "
742
+ "{ocseditor.help.property.enabled}","
743
+ <div class=""help-header"">
744
+ <p><a href=""#"" onclick=""ocseditor.help('summary');"">Summary</a></p>
745
+ </div>
746
+
747
+ <h4>The activation : `enabled`</h4>
748
+ <p>Enable or disable the shipping method.</p>
749
+ <p>The value must be boolean.</p>
750
+
751
+ <div class=""help-footer"">
752
+ <p><a href=""#"" onclick=""ocseditor.help('summary');"">Summary</a></p>
753
+ </div>
754
+ "
755
+ "{ocseditor.help.property.code}","
756
+ <div class=""help-header"">
757
+ <p><a href=""#"" onclick=""ocseditor.help('summary');"">Summary</a></p>
758
+ </div>
759
+
760
+ <h4>The code : `code`</h4>
761
+ <p>This is the identifier of the shipping method.</p>
762
+ <p>It must be unique. If not unique, it will be changed.</p>
763
+
764
+ <div class=""help-footer"">
765
+ <p><a href=""#"" onclick=""ocseditor.help('summary');"">Summary</a></p>
766
+ </div>
767
+ "
768
+ "{ocseditor.help.property.description}","
769
+ <div class=""help-header"">
770
+ <p>See the property <a href=""#"" onclick=""ocseditor.help('property.label');"">label</a>.</p>
771
+ <p><a href=""#"" onclick=""ocseditor.help('summary');"">Summary</a></p>
772
+ </div>
773
+
774
+ <h4>The description : `description`</h4>
775
+ <p>This will be the description given to the shipping method.</p>
776
+ <p>The usage is the same as the property <a href=""#"" onclick=""ocseditor.help('property.label');"">label</a>.</p>
777
+
778
+ <div class=""help-footer"">
779
+ <p>See the property <a href=""#"" onclick=""ocseditor.help('property.label');"">label</a>.</p>
780
+ <p><a href=""#"" onclick=""ocseditor.help('summary');"">Summary</a></p>
781
+ </div>
782
+ "
783
+ "{ocseditor.help.property.origin}","
784
+ <div class=""help-header"">
785
+ <p>See the property <a href=""#"" onclick=""ocseditor.help('property.destination');"">destination</a>.</p>
786
+ <p><a href=""#"" onclick=""ocseditor.help('summary');"">Summary</a></p>
787
+ </div>
788
+
789
+ <h4>The origin : `origin`</h4>
790
+ <p>
791
+ Same than destination but to filter shipping origin.<br/>
792
+ The syntax is the same as for <a href=""#"" onclick=""ocseditor.help('property.destination');"">destination</a> filtering.
793
+ </p>
794
+
795
+ <div class=""help-footer"">
796
+ <p>See the property <a href=""#"" onclick=""ocseditor.help('property.destination');"">destination</a>.</p>
797
+ <p><a href=""#"" onclick=""ocseditor.help('summary');"">Summary</a></p>
798
+ </div>
799
+ "
800
+ "{ocseditor.help.property.customer_groups}","
801
+ <div class=""help-header"">
802
+ <p><a href=""#"" onclick=""ocseditor.help('summary');"">Summary</a></p>
803
+ </div>
804
+
805
+ <h4>Customer groups : `customer_groups`</h4>
806
+ <p>
807
+ You can use the name or the ID of customer groups.
808
+ </p>
809
+
810
+ <div class=""code""><span class=""comment""># Groups NOT LOGGED IN and General</span><br/>
811
+ customer_groups: <span class=""string"">""NOT LOGGED IN,General""</span>,<br/>
812
+
813
+ <br/>
814
+ <span class=""comment""># Groups NOT LOGGED IN and General by ID</span><br/>
815
+ customer_groups: <span class=""string"">""0,1""</span>,<br/>
816
+ <br/>
817
+ <span class=""comment""># Group Retailer</span><br/>
818
+ customer_groups: <span class=""string"">""Retailer""</span>,</div>
819
+
820
+ <div class=""help-footer"">
821
+ <p><a href=""#"" onclick=""ocseditor.help('summary');"">Summary</a></p>
822
+ </div>
823
+ "
824
+ "{ocseditor.help.property.tracking_url}","
825
+ <div class=""help-header"">
826
+ <p><a href=""#"" onclick=""ocseditor.help('summary');"">Summary</a></p>
827
+ </div>
828
+
829
+ <h4>Tracking URL : `tracking_url`</h4>
830
+ <p>
831
+ Documentation is coming.
832
+ </p>
833
+
834
+ <div class=""help-footer"">
835
+ <p><a href=""#"" onclick=""ocseditor.help('summary');"">Summary</a></p>
836
+ </div>
837
+ "
838
+ "{ocseditor.help.property.*comment}","
839
+ <div class=""help-header"">
840
+ <p><a href=""#"" onclick=""ocseditor.help('summary');"">Summary</a></p>
841
+ </div>
842
+
843
+ <h4>Comments</h4>
844
+ <p>
845
+ You can add a comment on the shipping method. It will not be shown anywhere but you can put annotations.
846
+ </p>
847
+
848
+ <div class=""help-footer"">
849
+ <p><a href=""#"" onclick=""ocseditor.help('summary');"">Summary</a></p>
850
+ </div>
851
+ "
852
+ "{ocseditor.help.changelog}","
853
+ <div class=""help-header"">
854
+ <p><a href=""#"" onclick=""ocseditor.help('summary');"">Summary</a></p>
855
+ </div>
856
+
857
+ <h4>Changelog (in french)</h4>
858
+ <div class=""code""><pre>
859
+ [2.3.6 - 23 novembre 2010]
860
+ Ajout d'un fichier app/etc/modules/Wecom_Chronorelais.xml vide pour écraser celui des versions précédentes à la 2.3.0 afin d'éviter une cohabitation de deux versions
861
+ Amélioration du traitement des commentaires avec l'éditeur (gestion des caractères #)
862
+
863
+ [2.3.5 - 08 novembre 2010]
864
+ Correction d'un problème chez les utilisateurs ayant une version de PHP antérieure à 5.3.0
865
+
866
+ [2.3.4 - 06 novembre 2010]
867
+ 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
868
+
869
+ [2.3.3 - 05 novembre 2010]
870
+ Possibilité de faire des copie de propriétés de façon récursive avec contrôle de boucle infinie
871
+
872
+ [2.3.2 - 05 novembre 2010]
873
+ Amélioration de l'éditeur :
874
+ - Ajout de l'aide en langue anglais
875
+ - Ajout d'informations dans l'aide
876
+ - Ajout des messages d'erreur de la configuration, avec possibilité de correction rapide
877
+ - Ajout de champs pour les lignes ignorées : on peut ainsi les modifier et appliquer les modifications
878
+ 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}
879
+ Suppression de l'affichage du message d'erreur ""Correspondance non trouvée""
880
+ Correction d'un bug avec les groupes utilisateur ($id==null retournait true lorsque $id était égal à 0)
881
+ Correction d'une erreur de récupération de l'unité de poids
882
+ Améliorations diverses
883
+
884
+ [2.3.1 - 29 octobre 2010]
885
+ 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
886
+
887
+ [2.3.0 - 28 octobre 2010]
888
+ Correction d'un bug avec le caractère * dans les champs ""destination"" et ""origin"" comme jocker
889
+ Ajout d'un éditeur pour faciliter la modification des configurations Chronorelais Shipping
890
+ L'éditeur contient également une aide
891
+ Déplacement de certains fichiers pour mieux correspondre à la structure de Magento
892
+
893
+ [2.2.8 - 20 octobre 2010]
894
+ Correction d'une erreur dans l'include d'ChronorelaisShippingHelper lorsqu'on utilise le Compiler
895
+ Correction d'un bug de calcul du prix TTC dans certains cas ('row_total_with_discount' est égal à 0)
896
+ 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)
897
+ Ajout d'un bouton pour fermer la console de debug
898
+ Ajout d'informations dans le debug (tests sur la destination et l'origine, liste des variables passées en paramètre)
899
+ Affichage du debug uniquement sur la page panier (pas sur les pages en ajax)
900
+ Récupération du bon customer group lors d'une commande créée depuis le backoffice de Magento
901
+
902
+ [2.2.7 - 27 août 2010]
903
+ 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}}
904
+
905
+ [2.2.6 - 25 août 2010]
906
+ 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
907
+
908
+ [2.2.5 - 22 août 2010]
909
+ Correction d'un bug avec les propriétés de type booléenne spécifiées sans les guillemets (comme la propriété enabled)
910
+ Correction d'un bug avec la propriété customer_groups
911
+
912
+ [2.2.4 - 10 août 2010]
913
+ 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
914
+ 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
915
+ Amélioration de la clarté du debug (utilisation de couleurs et d'indentations)
916
+ Correction de bugs légers
917
+ Mise à jour de la syntaxe de la configuration proposée par défaut
918
+
919
+ [2.2.3 - 29 juillet 2010]
920
+ Correction d'un bug avec le traitement de formules dont le résultat est false
921
+
922
+ [2.2.2 - 29 juillet 2010]
923
+ Amélioration du système de cache des formules
924
+
925
+ [2.2.1 - 27 juillet 2010]
926
+ Correction de petits bugs
927
+
928
+ [2.2.0 - 22 juillet 2010]
929
+ Possibilité de compression/décompression de la configuration
930
+ 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})
931
+ Syntaxe légèrement modifié pour {product.attribute.xxx} et {product.option.xxx} (pas de s)
932
+ Ajout de nouvelles propriétés utilisables dans le foreach : {selection.weight}, {selection.quantity}, {product.weight}, {product.quantity}
933
+ Possibilité d'utiliser {product.attribute.xxx} et {product.option.xxx} dans le foreach
934
+
935
+ [2.1.9 - 20 juillet 2010]
936
+ Évaluation des formules contenues dans les propriétés ""label"" et ""description""
937
+
938
+ [2.1.8 - 20 juillet 2010]
939
+ Correction d'une erreur dans le foreach (l'attribut était toujours ""name"")
940
+
941
+ [2.1.7 - 19 juillet 2010]
942
+ Ajout de la syntaxe foreach product.attribute.xxx
943
+
944
+ [2.1.6 - 28 décembre 2009]
945
+ Correction d'une erreur dans le nom d'une variable qui entrainait un plantage dans certaines situations
946
+
947
+ [2.1.5 - 28 décembre 2009]
948
+ Modification de la syntaxe des tables (pour offrir plus de souplesse)
949
+
950
+ [2.1.4 - 24 décembre 2009]
951
+ Modification de la syntaxe d'utilisation des propriétés des produits (pour offrir beaucoup plus de souplesse)
952
+ Possibilité de filtrer les produits dont on veut utiliser les propriétés.
953
+ Ajout de 'COUNT DISTINCT'
954
+
955
+ [2.1.3 - 17 décembre 2009]
956
+ Correction du calcul du nombre de produits dont les propriétés correspondent ""{count ..."" : prise en compte de la quantité
957
+ Simplification de la syntaxe de copie de propriété
958
+
959
+ [2.1.2 - 27 novembre 2009]
960
+ 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
961
+
962
+ [2.1.1 - 26 novembre 2009]
963
+ Suppression de la propriété 'product_properties' qui doit être utilisée dans la propriété 'conditions'
964
+ Améliorations diverses
965
+
966
+ [2.1.0 - 24 novembre 2009]
967
+ Regroupement des propriétés 'fees_table', 'fees_formula' et 'fixed_fees' dans une unique propriété 'fees'
968
+ Regroupement des propriétés 'prices_range' et 'weights_range' dans une unique propriété 'conditions'
969
+ Suppression de la propriété 'reference_value'
970
+ 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)
971
+ 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'
972
+ Utilisation des valeurs des propriétés obsolètes dans leur nouvel équivalent
973
+ Possibilité de copier une propriété avec la syntaxe ""{copy 'colissimo'.'fees'}""
974
+ 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
975
+ 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
976
+
977
+ [2.0.12 - 19 novembre 2009]
978
+ Amélioration de la transmission des variables entre les méthodes de la classe
979
+
980
+ [2.0.11 - 19 novembre 2009]
981
+ Correction du filtrage en fonction des options et des attributs des produits en présence de produits configurables
982
+
983
+ [2.0.10 - 13 novembre 2009]
984
+ Amélioration du filtrage en fonction des options et des attributs des produits
985
+ Correction du filtrage en fonction des options des produits
986
+
987
+ [2.0.9 - 12 novembre 2009]
988
+ Correction du filtrage en fonction des options des produits
989
+
990
+ [2.0.8 - 12 novembre 2009]
991
+ Possibilité de filtrer en fonction des options des produits
992
+
993
+ [2.0.7 - 04 novembre 2009]
994
+ Possibilité de filtrer en fonction de l'origine de livraison
995
+ Possibilité de filtrer en fonction des attributs de produits
996
+ Possibilité de spécifier un code postal dans le filtrage de la destination
997
+ Compatibilité avec Magento 1.4.* : utilisation de la fonction getTranslationList au lieu de getCountryTranslationList qui est dépréciée
998
+
999
+ [2.0.6 - 02 octobre 2009]
1000
+ Possibilité de spécifier des groupes de clients
1001
+
1002
+ [2.0.5 - 18 août 2009]
1003
+ Ajout de la possibilité de spécifier dans la destination le monde entier sauf certains pays
1004
+ Correction d'un problème de parsing de la destination lorsqu'il n'y avait qu'un seul code région entre parenthèses
1005
+ Possibilité d'avoir des codes région comprenant des espaces
1006
+
1007
+ [2.0.4 - 28 juillet 2009]
1008
+ Suppression des options ""Unité de poids"" et ""Utiliser le montant TTC"" de chaque mode de livraison
1009
+ 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 ']'
1010
+ Possibilité de spécifier dans les champs 'prices_range' et 'fees_table' si on utilise le montant HT ou TTC
1011
+ Ajout du champ 'enabled' et suppression de la possibilité de désactiver un bloc de configuration avec le caractère '#'
1012
+ Modification du message d'erreur par défaut
1013
+ Ajout d'un message d'erreur en cas d'erreur d'interprétation d'une formule de calcul de frais
1014
+
1015
+ [2.0.3 - 27 juillet 2009]
1016
+ Correction d'une erreur dans l'interprétation des formules avec des fonctions à arguments multiples (min, max, rand)
1017
+
1018
+ [2.0.2 - 27 juin 2009]
1019
+ Correction d'une erreur d'expression régulière
1020
+
1021
+ [2.0.1 - 25 juin 2009]
1022
+ 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'
1023
+ Correction d'un problème de Magento qui ne semble pas retourner la bonne valeur lors de l'appel à la méthode $request->getFreeShipping()
1024
+ 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()
1025
+ Corrections de bugs
1026
+
1027
+ [2.0 - 3 avril 2009]
1028
+ Création de la version 2.0 du module Chronorelais Shipping qui n'est plus compatible avec les anciennes versions
1029
+ </pre></div>
1030
+
1031
+ <div class=""help-footer"">
1032
+ <p><a href=""#"" onclick=""ocseditor.help('summary');"">Summary</a></p>
1033
+ </div>
1034
+ "
app/locale/fr_FR/Chronopost_Chronorelais.csv ADDED
@@ -0,0 +1,1034 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
+ "No point relay is associated with this postcode","Aucun point Chrono Relais trouvé"
24
+ "track the package","suivre le colis"
25
+ "Chronorelay points","Les points relais les plus proches"
26
+ "Application Fee","Frais de dossier"
27
+ "Handling Fee","Frais de traitement"
28
+ "Logo Url","Url du logo"
29
+ "Weight Limit","Limite de poids"
30
+ "Free Shipping on the Amount","Livraison gratuite fonction du montant"
31
+ "Minimum Amount for Free Shipping","Montant minimum pour livraison gratuite"
32
+ "Semicolon","Point virgule"
33
+ "Comma","Virgule"
34
+
35
+ "Configuration","Configuration"
36
+ "{configuration_syntax_help}","<a href='http://www.magentocommerce.com/boards/viewthread/37860/' target='_blank'>Aide</a>"
37
+ "{debug_help}","0 = aucun, 1 = minimum, 10 = complet"
38
+ "{logo_ulr_help}","Upload the logo image to the given skin folder. skin/frontend/[your package name]/[your skin name]/chronorelais/"
39
+
40
+ "Tracking URL","URL de suivi"
41
+ "Debug","Debug"
42
+ "Stop to first match","Arrêt à la première correspondance trouvée"
43
+ "Chronorelais Shipping module","Module Chronorelais Shipping"
44
+ "Weight unit","Unité de poids"
45
+ "Auto Price","Prix automatique"
46
+
47
+ # OCSEditor
48
+ # Wecom_Chronorelais_Block_Adminhtml_System_Config_Form_Field_Config
49
+ "Open editor","Ouvrir l'éditeur"
50
+ # Wecom_Chronorelais_AjaxController
51
+ "Chronorelais Shipping configuration editor","Éditeur de configuration Chronorelais Shipping"
52
+ "Save","Sauvegarder"
53
+ "Cancel","Annuler"
54
+ "Close","Fermer"
55
+ "Load","Charger"
56
+ "Export","Exporter"
57
+ "Add a shipping method","Ajouter une méthode de livraison"
58
+ "New shipping method","Nouvelle méthode de livraison"
59
+ "Delete","Supprimer"
60
+ "Weight","Poids"
61
+ "Products quantity","Quantité d'articles"
62
+ "Quantity","Quantité"
63
+ "Price including tax","Prix TTC"
64
+ "Price excluding tax","Prix HT"
65
+ "Not logged in","Non connecté"
66
+ "Tracking number","Numéro de suivi"
67
+ "Insert","Insérer"
68
+ "Cart","Panier"
69
+ "Selection","Sélection"
70
+ "Product","Produit"
71
+ "Display","Affichage"
72
+ "Display original input","Afficher la saisie originale"
73
+ "Display corrected names","Afficher les noms corrigés"
74
+ "Display codes","Afficher les codes"
75
+ "Limit to","Limiter à"
76
+ "Exclude","Exclure"
77
+ "Destination country","Pays de destination"
78
+ "Cart weight","Poids du panier"
79
+ "Cart quantity","Nombre d'articles dans le panier"
80
+ "Disabled","Désactivé"
81
+ "Ignored lines","Lignes ignorées"
82
+ "Correct","Corriger"
83
+ "Apply changes","Appliquer les modifications"
84
+ # Fields
85
+ "Enabled","Activé"
86
+ "Code","Code"
87
+ "Label","Libellé"
88
+ "Description","Description"
89
+ "Destination","Destination"
90
+ "Origin","Origine"
91
+ "Conditions","Conditions"
92
+ "Fees","Coûts"
93
+ "Customer groups","Groupes utilisateur"
94
+ "Tracking url","URL de suivi"
95
+ "Comment","Commentaire"
96
+ # JS
97
+ "Dissociate","Dissocier"
98
+ "Remove","Supprimer"
99
+ "Edit","Modifier"
100
+ "Enter the new value:","Veuillez saisir la nouvelle valeur :"
101
+ "[No label]","[Pas de libellé]"
102
+ "Loading...","En cours de chargement..."
103
+ # Help
104
+ "Chronorelais Shipping extension help","Aide de l'extension Chronorelais Shipping"
105
+ "{ocseditor.help.summary}","
106
+ <h4>Sommaire</h4>
107
+ <div class=""table-of-contents"">
108
+ <ul>
109
+ <li><a href=""#"" onclick=""ocseditor.help('introduction');"">Introduction</a></li>
110
+ <li><a href=""#"" onclick=""ocseditor.help('property.label');"">Le libellé : `label`</a></li>
111
+ <li><a href=""#"" onclick=""ocseditor.help('property.fees');"">Les frais de port : `fees`</a>
112
+ <ul>
113
+ <li><a href=""#"" onclick=""ocseditor.help('more.formulas');"">Initiation aux formules</a></li>
114
+ <li><a href=""#"" onclick=""ocseditor.help('more.tables');"">Utilisation des tables de tarifs</a></li>
115
+ <li><a href=""#"" onclick=""ocseditor.help('more.copy');"">Faire une copie d'une propriété d'une autre méthode</a></li>
116
+ <li><a href=""#"" onclick=""ocseditor.help('more.special-functions');"">Fonctions spéciales dans les formules</a></li>
117
+ <li class=""new""><a href=""#"" onclick=""ocseditor.help('more.attributes-options');"">Utilisation des attributs ou des options des produits</a> (ajout des stocks dans la version 2.3.2)</li>
118
+ <li class=""new""><a href=""#"" onclick=""ocseditor.help('more.foreach');"">Utilisation des boucles foreach</a> (ajouté dans version 2.1.7)</li>
119
+ <li class=""new""><a href=""#"" onclick=""ocseditor.help('more.custom-variables');"">Utilisation des variables personnalisées de Magento (Custom Variables)</a> (ajouté dans version 2.2.7)</li>
120
+ </ul>
121
+ </li>
122
+ <li><a href=""#"" onclick=""ocseditor.help('property.conditions');"">Les conditions : `conditions`</a></li>
123
+ <li><a href=""#"" onclick=""ocseditor.help('property.destination');"">La destination : `destination`</a></li>
124
+ <li><a href=""#"" onclick=""ocseditor.help('property.enabled');"">L'activation : `enabled`</a></li>
125
+ <li><a href=""#"" onclick=""ocseditor.help('property.code');"">Le code : `code`</a></li>
126
+ <li><a href=""#"" onclick=""ocseditor.help('property.description');"">La description : `description`</a></li>
127
+ <li><a href=""#"" onclick=""ocseditor.help('property.origin');"">L'origine : `origin`</a></li>
128
+ <li><a href=""#"" onclick=""ocseditor.help('property.customer_groups');"">Les groupes client : `customer_groups`</a></li>
129
+ <li><a href=""#"" onclick=""ocseditor.help('property.tracking_url');"">L'URL de suivi : `tracking_url`</a></li>
130
+ <li><a href=""#"" onclick=""ocseditor.help('property.*comment');"">Commentaires</a></li>
131
+ <li><a href=""#"" onclick=""ocseditor.help('changelog');"">Changelog</a></li>
132
+ </ul>
133
+ </div>
134
+ "
135
+ "{ocseditor.help.introduction}","
136
+ <div class=""help-header"">
137
+ <p><a href=""#"" onclick=""ocseditor.help('summary');"">Sommaire</a></p>
138
+ </div>
139
+
140
+ <h4>Introduction</h4>
141
+ <p>
142
+ 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>
143
+ </p>
144
+
145
+ <p>
146
+ La syntaxe de configuration est une syntaxe proche de la syntaxe JSON.
147
+ </p>
148
+ <p>
149
+
150
+ Exemple :
151
+ </p>
152
+ <div class=""code""><span class=""comment""># National</span><br/>
153
+ {<br/>
154
+ &nbsp;&nbsp;&nbsp;label: <span class=""string"">""National""</span>,<br/>
155
+ &nbsp;&nbsp;&nbsp;destination: <span class=""string"">""AD,FR,MC""</span>,<br/>
156
+ &nbsp;&nbsp;&nbsp;conditions: <span class=""string"">""{cart.price_excluding_tax}&lt;1000.00""</span>,<br/>
157
+
158
+ &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/>
159
+ }</div>
160
+
161
+ <p>
162
+ Le caractère `#` en début de ligne indique un commentaire.<br/>
163
+ Un élément de configuration débute par le caractère `{` et se termine par `}`.<br/>
164
+ Un élément de configuration contient plusieurs propriétés associées à des valeurs.<br/>
165
+
166
+ 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.
167
+ </p>
168
+ <p>
169
+ Liste des propriétés :
170
+ </p>
171
+ <ul>
172
+ <li><b>label</b>: nom (libellé)</li>
173
+ <li><b>description</b>: description (visible seulement si le template l'affiche)</li>
174
+ <li><b>code</b>: code de la méthode de livraison (facultatif mais s'il est spécifié il doit être unique)</li>
175
+ <li><b>enabled</b>: bloc de configuration activé ou non (ex: <span class=""value"">true</span> ou <span class=""value"">false</span>)</li>
176
+ <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>
177
+ <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>
178
+ <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>
179
+ <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>
180
+ <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>
181
+ </ul>
182
+
183
+ <div class=""help-footer"">
184
+ <p><a href=""#"" onclick=""ocseditor.help('summary');"">Sommaire</a></p>
185
+ </div>
186
+
187
+ "
188
+ "{ocseditor.help.property.label}","
189
+ <div class=""help-header"">
190
+ <p><a href=""#"" onclick=""ocseditor.help('summary');"">Sommaire</a></p>
191
+ </div>
192
+
193
+ <h4>Le libellé : `label`</h4>
194
+ <p>Il s'agit du nom qui sera donné à la méthode de livraison.</p>
195
+ <p>On peut insérer certains éléments comme le poids des marchandises dans le libellé.<br/>
196
+ Pour ce faire, utiliser les variables suivantes :</p>
197
+ <ul>
198
+ <li><b>{destination.country.name}</b>: le pays de destination</li>
199
+ <li><b>{destination.country.code}</b>: le code du pays de destination</li>
200
+ <li><b>{destination.region.code}</b>: le code de la région de destination</li>
201
+ <li><b>{destination.postcode}</b>: le code postal de destination</li>
202
+ <li><b>{origin.country.name}</b>: le pays d'envoi</li>
203
+ <li><b>{origin.country.code}</b>: le code du pays d'envoi</li>
204
+ <li><b>{origin.region.code}</b>: le code de la région d'envoi</li>
205
+ <li><b>{origin.postcode}</b>: le code postal d'envoi</li>
206
+ <li><b>{cart.weight}</b>: poids des marchandises</li>
207
+ <li><b>{cart.weight.unit}</b>: l'unité de poids</li>
208
+ <li><b>{cart.quantity}</b>: la quantité d'articles</li>
209
+ <li><b>{cart.price_including_tax}</b>: prix TTC</li>
210
+ <li><b>{cart.price_excluding_tax}</b>: prix HT</li>
211
+ <li><b>{store.code}</b>: code du magasin</li>
212
+ <li><b>{store.name}</b>: nom du magasin</li>
213
+ <li><b>{store.address}</b>: adresse du magasin</li>
214
+ <li><b>{store.phone}</b>: téléphone du magasin</li>
215
+ <li><b>{date.timestamp}</b>: timestamp UNIX de la date actuelle</li>
216
+ <li><b>{date.year}</b>: année de la date actuelle</li>
217
+ <li><b>{date.month}</b>: mois de la date actuelle</li>
218
+ <li><b>{date.day}</b>: jour de la date actuelle</li>
219
+ <li><b>{date.hour}</b>: heure de la date actuelle</li>
220
+ <li><b>{date.minute}</b>: minute de la date actuelle</li>
221
+ <li><b>{date.second}</b>: seconde de la date actuelle</li>
222
+ </ul>
223
+ <div class=""code"">label: <span class=""string"">""Colissimo ({cart.weight} / {destination.country.name})""</span>,</div>
224
+ <p>La ligne ci-dessus affichera par exemple ""Colissimo (3.0kg / France)"".</p>
225
+
226
+ <div class=""help-footer"">
227
+ <p><a href=""#"" onclick=""ocseditor.help('summary');"">Sommaire</a></p>
228
+ </div>
229
+ "
230
+ "{ocseditor.help.property.fees}","
231
+ <div class=""help-header"">
232
+ <p><a href=""#"" onclick=""ocseditor.help('summary');"">Sommaire</a></p>
233
+ </div>
234
+
235
+ <h4>Les frais de port : `fees`</h4>
236
+ <p>
237
+ La propriété `fees` se spécifie sous la forme d'une <a href=""#"" onclick=""ocseditor.help('more.formulas');"">formule (voir l'initiation aux formules)</a>.
238
+ </p>
239
+ <div class=""code""><span class=""comment""># Frais fixes</span><br/>fees: 10.00,<br/>
240
+ <br/>
241
+ <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/>
242
+ <br/>
243
+ <span class=""comment""># Formule</span><br/>fees: <span class=""string"">""0.1 * {cart.price_excluding_tax} + 10.00""</span>,<br/>
244
+ <br/>
245
+ <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>,
246
+ </div>
247
+
248
+ <div class=""help-footer"">
249
+ <p><a href=""#"" onclick=""ocseditor.help('summary');"">Sommaire</a></p>
250
+ </div>
251
+ "
252
+ "{ocseditor.help.more.formulas}","
253
+ <div class=""help-header"">
254
+ <p><a href=""#"" onclick=""ocseditor.help('summary');"">Sommaire</a></p>
255
+ </div>
256
+
257
+ <h4>Initiation aux formules</h4>
258
+ <p>
259
+ Les propriétés `fees` et `conditions` sont spécifiées sous la forme de formules.
260
+ </p>
261
+ <p>
262
+ Signes mathématiques disponibles :
263
+ </p>
264
+ <ul>
265
+ <li>opérateurs : *, /, + et -</li>
266
+ <li>modulo : %</li>
267
+ <li>parenthèses : ( et )</li>
268
+ <li>les opérateurs booléens &amp;&amp;, and, ||, or, ==, &lt;, &gt;, &lt;=, &gt;=</li>
269
+ <li>les opérateurs binaires &amp; et |</li>
270
+ <li>le groupe d'opérateur C ? X : Y (ex: ""{cart.price_exluding_tax}&gt;100 ? 15*{cart.weight} : 20*{cart.weight}"")</li>
271
+ </ul>
272
+ <p>
273
+ Fonctions disponibles :
274
+ </p>
275
+ <ul>
276
+ <li>arrondis : round(x), floor(x), ceil(x)</li>
277
+ <li>valeur absolue : abs(x)</li>
278
+ <li>maximum : max(x,y)</li>
279
+ <li>minimum : min(x,y)</li>
280
+ <li>entier aléatoire : rand(min,max)</li>
281
+ <li>puissance : pow(x,puissance)</li>
282
+ <li>nombre PI : pi()</li>
283
+ <li>racine carrée : sqrt(x)</li>
284
+ <li>logarithme : log(x) pour le logarithme népérien ou log(x,base)</li>
285
+ <li>exponentiel : exp(x)</li>
286
+ </ul>
287
+ <p>
288
+ Possibilité d'utiliser les fonctionnalités avancées suivantes : casting en entier (int) ou en nombre flottant (float),
289
+ comparaison avec la valeur null ou les valeurs booléennes true et false.
290
+ </p>
291
+ <p>
292
+ Variables disponibles :
293
+ </p>
294
+ <ul>
295
+
296
+ <li><b>{cart.weight}</b>: poids du colis</li>
297
+ <li><b>{cart.price_including_tax}</b>: prix TTC</li>
298
+ <li><b>{cart.price_excluding_tax}</b>: prix HT</li>
299
+ <li><b>{cart.quantity}</b>: nombre d'articles dans le panier</li>
300
+ <li><b>{date.timestamp}</b>: timestamp UNIX de la date actuelle</li>
301
+ <li><b>{date.year}</b>: année de la date actuelle</li>
302
+ <li><b>{date.month}</b>: mois de la date actuelle</li>
303
+ <li><b>{date.day}</b>: jour de la date actuelle</li>
304
+ <li><b>{date.hour}</b>: heure de la date actuelle</li>
305
+ <li><b>{date.minute}</b>: minute de la date actuelle</li>
306
+ <li><b>{date.second}</b>: seconde de la date actuelle</li>
307
+ <li><b>{free_shipping}</b>: frais de port offert (par une règle dans Magento) [true/false]</li>
308
+ </ul>
309
+ <p>
310
+ Vous avez la possibilité de mettre des espaces et des retours à la ligne dans les formules (pour aérer).
311
+ </p>
312
+ <p class=""new"" style=""font-weight: bold;"">
313
+ 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,
314
+ les fonctions spéciales, l'utilisation des attributs et des options des produits ou encore l'utilisation des variables personnalisées.
315
+ </p>
316
+
317
+ <div class=""help-footer"">
318
+ <p><a href=""#"" onclick=""ocseditor.help('summary');"">Sommaire</a></p>
319
+ </div>
320
+ "
321
+ "{ocseditor.help.more.tables}","
322
+ <div class=""help-header"">
323
+ <p><a href=""#"" onclick=""ocseditor.help('summary');"">Sommaire</a></p>
324
+ </div>
325
+
326
+ <h4>Utilisation des tables de tarifs</h4>
327
+ <p>
328
+ Dans une table, on peut inclure ou exclure une valeur limite avec les caractères '[' et ']' :
329
+ </p>
330
+ <div class=""code""><span class=""comment""># Limite supérieure 1.0 incluse</span><br/>
331
+ fees: <span class=""string"">""{table {cart.weight} in 1.0]:5.00}""</span>,<br/>
332
+
333
+ <br/>
334
+ <span class=""comment""># Limite supérieure 1.0 exclue</span><br/>
335
+ fees: <span class=""string"">""{table {cart.weight} in 1.0[:5.00}""</span>,</div>
336
+
337
+ <p>
338
+ Dans une table, on doit spécifier la valeur de référence. Pour cela, on peut utiliser une des variables disponibles.<br/>
339
+ Vous pouvez aussi utiliser une formule afin de définir une autre variable de référence.
340
+ </p>
341
+
342
+ <div class=""code""><span class=""comment""># Les valeurs limites sont comparées au poids du panier</span><br/>
343
+ fees: <span class=""string"">""{table {cart.weight} in 0.5:5.30, 1.0:6.50}""</span>,<br/>
344
+ <br/>
345
+ <span class=""comment""># Les valeurs limites sont comparées à la quantité d'articles</span><br/>
346
+ fees: <span class=""string"">""{table {cart.quantity} in 10:5.30, 20:6.50}""</span>,<br/>
347
+ <br/>
348
+ <span class=""comment""># Les valeurs limites sont comparées au prix TTC</span><br/>
349
+ fees: <span class=""string"">""{table {cart.price_including_tax} in 15.00:5.30, 30.00:6.50}""</span>,<br/>
350
+ <br/>
351
+ <span class=""comment""># Les valeurs limites sont comparées au prix HT</span><br/>
352
+ fees: <span class=""string"">""{table {cart.price_excluding_tax} in 15.00:5.30, 30.00:6.50}""</span>,<br/>
353
+ <br/>
354
+ <span class=""comment""># Les valeurs limites sont comparées à une valeur de référence définie par l'utilisateur</span><br/>
355
+ fees: <span class=""string"">""{table ceil({cart.weight}/10) in 1:5.30, 2:6.50}""</span>,
356
+ </div>
357
+
358
+ <div class=""help-footer"">
359
+ <p><a href=""#"" onclick=""ocseditor.help('summary');"">Sommaire</a></p>
360
+ </div>
361
+ "
362
+ "{ocseditor.help.more.copy}","
363
+ <div class=""help-header"">
364
+ <p><a href=""#"" onclick=""ocseditor.help('summary');"">Sommaire</a></p>
365
+ </div>
366
+
367
+ <h4>Faire une copie d'une propriété d'une autre méthode</h4>
368
+ <p>
369
+ Il est possible de faire une copie d'une propriété dans une autre à l'aide de la syntaxe ci-dessous.
370
+ </p>
371
+ <p>
372
+ Vous pouvez utiliser cette technique dans les propriétés 'conditions', 'fees',
373
+ 'enabled', 'label', 'description', 'destination', 'origin', 'customer_groups' et 'tracking_url'
374
+ <strong>mais pas dans la propriété 'code'</strong>.
375
+ </p>
376
+
377
+ <div class=""code""><span class=""comment""># Colissimo</span><br/>
378
+ {<br/>
379
+ &nbsp;&nbsp;&nbsp;code: <span class=""string"">""colissimo""</span>,<br/>
380
+ &nbsp;&nbsp;&nbsp;label: <span class=""string"">""Colissimo""</span>,<br/>
381
+ &nbsp;&nbsp;&nbsp;destination: <span class=""string"">""AD,FR,MC""</span>,<br/>
382
+ &nbsp;&nbsp;&nbsp;conditions: <span class=""string"">""{cart.price_excluding_tax}&lt;1000.00""</span>,<br/>
383
+ &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/>
384
+ }<br/>
385
+ ...<br/>
386
+ &nbsp;&nbsp;&nbsp;<span class=""comment""># Copie des conditions d'une autre méthode</span><br/>
387
+ &nbsp;&nbsp;&nbsp;conditions: <span class=""string"">""({colissimo.conditions}) and ({cart.weight}&gt;10.0)""</span>,<br/>
388
+ ...<br/>
389
+ &nbsp;&nbsp;&nbsp;<span class=""comment""># Copie des frais de port d'une autre méthode</span><br/>
390
+ &nbsp;&nbsp;&nbsp;fees: <span class=""string"">""({colissimo.fees}) + 15.00""</span>,<br/>
391
+ ...
392
+ </div>
393
+
394
+ <div class=""help-footer"">
395
+ <p><a href=""#"" onclick=""ocseditor.help('summary');"">Sommaire</a></p>
396
+ </div>
397
+ "
398
+ "{ocseditor.help.more.special-functions}","
399
+ <div class=""help-header"">
400
+ <p><a href=""#"" onclick=""ocseditor.help('summary');"">Sommaire</a></p>
401
+ </div>
402
+
403
+ <h4>Fonctions spéciales dans les formules</h4>
404
+
405
+ <p>
406
+ Vous pouvez utiliser dans les formules des fonctions spéciales.
407
+ </p>
408
+ <p>
409
+ Liste des fonctions spéciales :
410
+ </p>
411
+ <ul>
412
+ <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>
413
+ <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>
414
+ </ul>
415
+
416
+ <div class=""code""><span class=""comment""># Exemple d'utilisation de la fonction min pour proposé des frais de port gratuits<br/>
417
+ # et un supplément pour les méthodes de transport plus rapides</span><br/>
418
+ {<br/>
419
+ &nbsp;&nbsp;&nbsp;code: <span class=""string"">""courrier_suivi""</span>,<br/>
420
+ &nbsp;&nbsp;&nbsp;label: <span class=""string"">""Courrier suivi""</span>,<br/>
421
+ &nbsp;&nbsp;&nbsp;destination: <span class=""string"">""FR""</span>,<br/>
422
+ &nbsp;&nbsp;&nbsp;conditions: <span class=""string"">""{cart.price_including_tax}&lt;80""</span>,<br/>
423
+ &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/>
424
+ }<br/>
425
+ <br/>
426
+ {<br/>
427
+ &nbsp;&nbsp;&nbsp;code: <span class=""string"">""courrier_suivi_offert""</span>,<br/>
428
+ &nbsp;&nbsp;&nbsp;label: <span class=""string"">""Frais de port offerts - Courrier suivi""</span>,<br/>
429
+ &nbsp;&nbsp;&nbsp;destination: <span class=""string"">""{courrier_suivi.destination}""</span>,<br/>
430
+ &nbsp;&nbsp;&nbsp;conditions: <span class=""string"">""{cart.price_including_tax}&gt;=80 and {cart.weight}&lt;=0.500""</span>,<br/>
431
+ &nbsp;&nbsp;&nbsp;fees: 0.00,<br/>
432
+ }<br/>
433
+ <br/>
434
+ {<br/>
435
+ &nbsp;&nbsp;&nbsp;code: <span class=""string"">""lettre_recommandee""</span>,<br/>
436
+ &nbsp;&nbsp;&nbsp;label: <span class=""string"">""Lettre Recommandée""</span>,<br/>
437
+ &nbsp;&nbsp;&nbsp;destination: <span class=""string"">""FR""</span>,<br/>
438
+ &nbsp;&nbsp;&nbsp;conditions: <span class=""string"">""{cart.price_including_tax}&lt;80""</span>,<br/>
439
+ &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/>
440
+ }<br/>
441
+ <br/>
442
+ {<br/>
443
+ &nbsp;&nbsp;&nbsp;code: <span class=""string"">""lettre_recommandee_offert""</span>,<br/>
444
+ &nbsp;&nbsp;&nbsp;label: <span class=""string"">""Frais de port offerts - Lettre Recommandée""</span>,<br/>
445
+ &nbsp;&nbsp;&nbsp;destination: <span class=""string"">""{lettre_recommandee.destination}""</span>,<br/>
446
+ &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/>
447
+ &nbsp;&nbsp;&nbsp;fees: 0.00,<br/>
448
+ }<br/>
449
+ <br/>
450
+ {<br/>
451
+ &nbsp;&nbsp;&nbsp;code: <span class=""string"">""supplement_lettre_recommandee""</span>,<br/>
452
+ &nbsp;&nbsp;&nbsp;label: <span class=""string"">""Supplément 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"">""{courrier_suivi_offert.conditions}""</span>,<br/>
455
+ &nbsp;&nbsp;&nbsp;fees: <span class=""string"">""{lettre_recommandee.fees} - {courrier_suivi.fees}""</span>,<br/>
456
+ }<br/>
457
+ <br/>
458
+ {<br/>
459
+ &nbsp;&nbsp;&nbsp;code: <span class=""string"">""colissimo""</span>,<br/>
460
+ &nbsp;&nbsp;&nbsp;label: <span class=""string"">""Colissimo""</span>,<br/>
461
+ &nbsp;&nbsp;&nbsp;destination: <span class=""string"">""FR""</span>,<br/>
462
+ &nbsp;&nbsp;&nbsp;conditions: <span class=""string"">""{cart.price_including_tax}&lt;80""</span>,<br/>
463
+ &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/>
464
+ }<br/>
465
+ <br/>
466
+ {<br/>
467
+ &nbsp;&nbsp;&nbsp;code: <span class=""string"">""colissimo_offert""</span>,<br/>
468
+ &nbsp;&nbsp;&nbsp;label: <span class=""string"">""Frais de port offerts - Colissimo""</span>,<br/>
469
+ &nbsp;&nbsp;&nbsp;destination: <span class=""string"">""{colissimo.destination}""</span>,<br/>
470
+ &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/>
471
+ &nbsp;&nbsp;&nbsp;fees: 0.00,<br/>
472
+ }<br/>
473
+ <br/>
474
+ {<br/>
475
+ &nbsp;&nbsp;&nbsp;code: <span class=""string"">""supplement_colissimo""</span>,<br/>
476
+ &nbsp;&nbsp;&nbsp;label: <span class=""string"">""Supplément Colissimo""</span>,<br/>
477
+ &nbsp;&nbsp;&nbsp;destination: <span class=""string"">""{colissimo.destination}""</span>,<br/>
478
+ &nbsp;&nbsp;&nbsp;conditions: <span class=""string"">""{courrier_suivi_offert.conditions} or {lettre_recommandee_offert.conditions}""</span>,<br/>
479
+ &nbsp;&nbsp;&nbsp;fees: <span class=""string"">""{colissimo.fees} - min({courrier_suivi.fees},{lettre_recommandee.fees})""</span>,<br/>
480
+ }<br/>
481
+ <br/>
482
+ {<br/>
483
+ &nbsp;&nbsp;&nbsp;code: <span class=""string"">""chronopost""</span>,<br/>
484
+ &nbsp;&nbsp;&nbsp;label: <span class=""string"">""Chronopost""</span>,<br/>
485
+ &nbsp;&nbsp;&nbsp;destination: <span class=""string"">""FR""</span>,<br/>
486
+ &nbsp;&nbsp;&nbsp;conditions: <span class=""string"">""{cart.price_including_tax}&lt;80""</span>,<br/>
487
+ &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/>
488
+ }<br/>
489
+ <br/>
490
+ {<br/>
491
+ &nbsp;&nbsp;&nbsp;code: <span class=""string"">""chronopost_offert""</span>,<br/>
492
+ &nbsp;&nbsp;&nbsp;label: <span class=""string"">""Frais de port offerts - 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 and {cart.weight}&gt;29.8 and {cart.weight}&lt;=30""</span>,<br/>
495
+ &nbsp;&nbsp;&nbsp;fees: 0.00,<br/>
496
+ }<br/>
497
+ <br/>
498
+ {<br/>
499
+ &nbsp;&nbsp;&nbsp;code: <span class=""string"">""supplement_chronopost""</span>,<br/>
500
+ &nbsp;&nbsp;&nbsp;label: <span class=""string"">""Supplément Chronopost""</span>,<br/>
501
+ &nbsp;&nbsp;&nbsp;destination: <span class=""string"">""{chronopost.destination}""</span>,<br/>
502
+ &nbsp;&nbsp;&nbsp;conditions: <span class=""string"">""{courrier_suivi_offert.conditions} or {lettre_recommandee_offert.conditions} or {colissimo_offert.conditions}""</span>,<br/>
503
+ &nbsp;&nbsp;&nbsp;fees: <span class=""string"">""{chronopost.fees} - min({courrier_suivi.fees},{lettre_recommandee.fees},{colissimo.fees})""</span>,<br/>
504
+ }
505
+ </div>
506
+
507
+ <div class=""help-footer"">
508
+ <p><a href=""#"" onclick=""ocseditor.help('summary');"">Sommaire</a></p>
509
+ </div>
510
+ "
511
+ "{ocseditor.help.more.attributes-options}","
512
+ <div class=""help-header"">
513
+ <p><a href=""#"" onclick=""ocseditor.help('summary');"">Sommaire</a></p>
514
+ </div>
515
+
516
+ <h4>Utilisation des attributs ou des options des produits</h4>
517
+
518
+ <p>
519
+ Il est possible d'utiliser les attributs ou les options des produits à l'aide de la syntaxe ci-dessous.
520
+ </p>
521
+ <p>
522
+ Vous pouvez utiliser cette technique dans les propriétés 'conditions' et 'fees'.
523
+ </p>
524
+
525
+ <div class=""code""><span class=""comment""># Si au moins un produit possède l'attribut 'color' égal à 'Bleu'<br/></span>
526
+ conditions: <span class=""string"">""{count products where product.attribute.color=='Bleu'}&gt;0""</span>,<br/>
527
+ ...<br/>
528
+ <span class=""comment""># Si tous les produits possèdent l'option 'size' supérieure ou égal à '1'<br/></span>
529
+ conditions: <span class=""string"">""{count products where product.option.size&gt;='1'}=={cart.quantity}""</span>,<br/>
530
+ ...<br/>
531
+ <span class=""comment""># Le nombre de SKU différents<br/></span>
532
+ conditions: <span class=""string"">""{count distinct product.attribute.sku}""</span>,<br/>
533
+ ...<br/>
534
+ <span class=""comment""># La somme de toutes les options 'size' est supérieure à 30<br/></span>
535
+ conditions: <span class=""string"">""{sum product.option.size}&gt;30""</span>,<br/>
536
+ ...<br/>
537
+ <span class=""comment""># Le nombre de produits en stock<br/></span>
538
+ conditions: <span class=""string"">""{count products where product.stock.is_in_stock==true}""</span>,<br/>
539
+ ...
540
+ </div>
541
+
542
+ <p>
543
+ Liste des préfixes possibles :
544
+ </p>
545
+ <ul>
546
+ <li><b>count :</b> nombre (toujours suivi de 'products')</li>
547
+ <li><b>count distinct :</b> nombre distinct (toujours suivi d'une propriété)</li>
548
+ <li><b>sum :</b> somme (toujours suivi d'une propriété)</li>
549
+ </ul>
550
+ <p>
551
+ Liste des propriétés possibles :
552
+ </p>
553
+ <ul>
554
+ <li><b>product.attribute.* :</b> attribut</li>
555
+ <li><b>product.option.* :</b> option</li>
556
+ <li><b>product.stock.is_in_stock :</b> disponibilité du produit</li>
557
+ <li><b>product.stock.quantity :</b> stock du produit</li>
558
+ </ul>
559
+ <p>
560
+ 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.
561
+ </p>
562
+ <p>
563
+ 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.
564
+ </p>
565
+ <div class=""code""><span class=""comment""># Propriété de type Oui/Non</span><br/>
566
+ conditions: <span class=""string"">""{count products where product.attribute.colissimo_allowed==1}""</span>,<br/>
567
+ <span class=""comment""># ou</span><br/>
568
+ conditions: <span class=""string"">""{count products where product.attribute.colissimo_allowed==true}""</span>,</div>
569
+
570
+ <p>
571
+ 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 :
572
+ </p>
573
+
574
+ <div class=""code""><span class=""comment""># Condition validée si l'attribut 'color' est égale à la valeur dont l'id est 1</span><br/>
575
+ conditions: <span class=""string"">""{count products where product.attribute.color.id==1}""</span>,</div>
576
+
577
+ <div class=""help-footer"">
578
+ <p><a href=""#"" onclick=""ocseditor.help('summary');"">Sommaire</a></p>
579
+ </div>
580
+ "
581
+ "{ocseditor.help.more.foreach}","
582
+ <div class=""help-header"">
583
+ <p><a href=""#"" onclick=""ocseditor.help('summary');"">Sommaire</a></p>
584
+ </div>
585
+
586
+ <h4>Utilisation des boucles foreach</h4>
587
+
588
+ <p>
589
+ 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/>
590
+ Le résultat global d'une boucle foreach est la somme des résultats de chaque passage dans la boucle.
591
+ </p>
592
+ <p>
593
+ A l'intérieur d'une boucle foreach, il est possible d'utiliser de nouvelles variables :
594
+ </p>
595
+ <ul>
596
+ <li><b>{selection.weight}</b>: poids de la sélection</li>
597
+ <li><b>{selection.quantity}</b>: nombre d'articles dans la sélection</li>
598
+ </ul>
599
+ <p>
600
+ 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 :
601
+ </p>
602
+ <ul>
603
+ <li><b>{product.weight}</b>: poids de l'article sélectionné</li>
604
+ <li><b>{product.quantity}</b>: quantité de l'article sélectionné</li>
605
+ <li><b>{product.attribute.*}</b>: attribut de l'article sélectionné</li>
606
+ <li><b>{product.option.*}</b>: option de l'article sélectionné</li>
607
+ </ul>
608
+
609
+ <div class=""code""><span class=""comment""># Regroupement des produits par origine puis traitement des groupes séparémment</span><br/>
610
+ 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/>
611
+ <br/>
612
+ <span class=""comment""># Calcul individuel des frais de port</span><br/>
613
+ fees: <span class=""string"">""{foreach product.attribute.sku}{product.attribute.shipping}*{product.quantity}{/foreach}""</span>,<br/>
614
+ </div>
615
+
616
+ <div class=""help-footer"">
617
+ <p><a href=""#"" onclick=""ocseditor.help('summary');"">Sommaire</a></p>
618
+ </div>
619
+ "
620
+ "{ocseditor.help.more.custom-variables}","
621
+ <div class=""help-header"">
622
+ <p><a href=""#"" onclick=""ocseditor.help('summary');"">Sommaire</a></p>
623
+ </div>
624
+
625
+ <h4>Utilisation des variables personnalisées de Magento (Custom Variables)</h4>
626
+ <p>
627
+ Depuis la version 1.4.0.1 de Magento, il est possible de définir des variables personnalisées.
628
+ </p>
629
+ <p>
630
+ La version 2.2.7 d'Chronorelais Shipping vous permet d'utiliser ces variables personnalisées grâce à la syntaxe suivante :
631
+ </p>
632
+ <div class=""code""><span class=""comment""># Utilisation de la variable personnalisée my_var<br/></span>
633
+ fees: <span class=""string"">""{customvar.my_var}*5.00""</span>,<br/>
634
+ ...<br/>
635
+ <span class=""comment""># Idem en utilisant la syntaxe standard de Magento<br/></span>
636
+ fees: <span class=""string"">""{{customVar code=my_var}}*5.00""</span>,<br/>
637
+ ...</div>
638
+
639
+ <div class=""help-footer"">
640
+ <p><a href=""#"" onclick=""ocseditor.help('summary');"">Sommaire</a></p>
641
+ </div>
642
+ "
643
+ "{ocseditor.help.property.conditions}","
644
+ <div class=""help-header"">
645
+ <p><a href=""#"" onclick=""ocseditor.help('summary');"">Sommaire</a></p>
646
+ </div>
647
+
648
+ <h4>Les conditions : `conditions`</h4>
649
+ <p>
650
+ La propriété `conditions` se spécifie sous la forme d'une <a href=""#"" onclick=""ocseditor.help('more.formulas');"">formule (voir l'initiation aux formules)</a>
651
+ qui doit retourner une valeur booléenne (true ou false).
652
+ </p>
653
+
654
+ <div class=""code""><span class=""comment""># Tranches de prix</span><br/>
655
+ <br/>
656
+ &nbsp;&nbsp;&nbsp;<span class=""comment""># De 0 à 70 TTC</span><br/>
657
+ &nbsp;&nbsp;&nbsp;conditions: <span class=""string"">""{cart.price_including_tax}&lt;=70""</span>,<br/>
658
+ <br/>
659
+ &nbsp;&nbsp;&nbsp;<span class=""comment""># De 0 à 70 HT</span><br/>
660
+ &nbsp;&nbsp;&nbsp;conditions: <span class=""string"">""{cart.price_excluding_tax}&lt;=70""</span>,<br/>
661
+ <br/>
662
+ &nbsp;&nbsp;&nbsp;<span class=""comment""># De 20 exclu à 70 inclu</span><br/>
663
+ &nbsp;&nbsp;&nbsp;conditions: <span class=""string"">""({cart.price_excluding_tax} &gt; 20) and ({cart.price_excluding_tax} &lt;= 70)""</span>,<br/>
664
+ <br/>
665
+ &nbsp;&nbsp;&nbsp;<span class=""comment""># De 10 inclu à 50 exclu</span><br/>
666
+ &nbsp;&nbsp;&nbsp;conditions: <span class=""string"">""({cart.price_excluding_tax} &gt;= 10) and ({cart.price_excluding_tax} &lt; 50)""</span>,<br/>
667
+ <br/>
668
+ <br/>
669
+ <span class=""comment""># Tranches de poids</span><br/>
670
+ <br/>
671
+ &nbsp;&nbsp;&nbsp;<span class=""comment""># De 0.5 exclu à 3 inclu</span><br/>
672
+ &nbsp;&nbsp;&nbsp;conditions: <span class=""string"">""({cart.weight} &gt; 0.5) and ({cart.weight} &lt;= 3.0)""</span>,<br/>
673
+ <br/>
674
+ &nbsp;&nbsp;&nbsp;<span class=""comment""># De 1 inclu à 5 exclu</span><br/>
675
+ &nbsp;&nbsp;&nbsp;conditions: <span class=""string"">""({cart.weight} &gt;= 1.0) and ({cart.weight} &lt; 5.0)""</span>,<br/>
676
+ <br/>
677
+ <br/>
678
+ <span class=""comment""># Free shipping</span><br/>
679
+ <br/>
680
+ &nbsp;&nbsp;&nbsp;<span class=""comment""># Only when free shipping</span><br/>
681
+ &nbsp;&nbsp;&nbsp;conditions: <span class=""string"">""{free_shipping}""</span>,<br/>
682
+ <br/>
683
+ &nbsp;&nbsp;&nbsp;<span class=""comment""># Only when no free shipping</span><br/>
684
+ &nbsp;&nbsp;&nbsp;conditions: <span class=""string"">""!{free_shipping}""</span>,<br/>
685
+ <br/>
686
+ <br/>
687
+ <span class=""comment""># Attribut ou option des produits</span><br/>
688
+ <br/>
689
+ &nbsp;&nbsp;&nbsp;<span class=""comment""># Si au moins un produit possède l'attribut 'color' égal à 'Bleu'</span><br/>
690
+ &nbsp;&nbsp;&nbsp;conditions: <span class=""string"">""{count products where product.attribute.color=='Bleu'}&gt;1""</span>,<br/>
691
+ <br/>
692
+ &nbsp;&nbsp;&nbsp;<span class=""comment""># Si tous les produits possèdent l'option 'size' supérieure ou égal à '1'</span><br/>
693
+ &nbsp;&nbsp;&nbsp;conditions: <span class=""string"">""{count products where product.option.size&gt;='1'}=={cart.quantity}""</span>,</div>
694
+
695
+ <div class=""help-footer"">
696
+ <p><a href=""#"" onclick=""ocseditor.help('summary');"">Sommaire</a></p>
697
+ </div>
698
+
699
+ "
700
+ "{ocseditor.help.property.destination}","
701
+ <div class=""help-header"">
702
+ <p><a href=""#"" onclick=""ocseditor.help('summary');"">Sommaire</a></p>
703
+ </div>
704
+
705
+ <h4>La destination : `destination`</h4>
706
+ <p>
707
+ Les codes pays utilisés sont ceux de Magento (à priori ils sont les mêmes que les codes ISO 3166-1 alpha-2).<br/>
708
+ Il est possible de spécifier les codes régions <span class=""new"">ou les codes postaux</span> que l'on veut filtrer ou exclure.<br/>
709
+ </p>
710
+
711
+ <div class=""code""><span class=""comment""># France, Allemagne, Suisse, Espagne, Italie</span><br/>
712
+ destination: <span class=""string"">""FR,DE,CH,ES,IT""</span>,<br/>
713
+ <br/>
714
+ <span class=""comment""># France sauf la Corse</span><br/>
715
+ destination: <span class=""string"">""FR-(2A,2B)""</span>,<br/>
716
+
717
+ <br/>
718
+ <span class=""comment""># Corse</span><br/>
719
+ destination: <span class=""string"">""FR(2A,2B)""</span>,<br/>
720
+ <br/>
721
+ <span class=""comment""># Le monde entier sauf l'Allemagne et la Corse</span><br/>
722
+ destination: <span class=""string"">""* - ( DE, FR(2A,2B) )""</span>,</div>
723
+
724
+ <div class=""tips"">
725
+ <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>
726
+ <ul>
727
+ <li><strong>UE</strong> ou <strong>Union Européenne</strong> : ajoute les pays de l'Union Européenne.</li>
728
+ <li><strong>DOM</strong> : ajoute les Départements d'Outre-Mer Français.</li>
729
+ <li><strong>COM</strong> : ajoute les Collectivités d'Outre-Mer Françaises.</li>
730
+ <li><strong>Outre-Mer</strong> : ajoute tout l'Outre-Mer Français.</li>
731
+ <li><strong>Corse</strong> : ajoute la corse (""FR(2A,2B)"").</li>
732
+ </ul>
733
+ <p>
734
+ 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.
735
+ </p>
736
+ </div>
737
+
738
+ <div class=""help-footer"">
739
+ <p><a href=""#"" onclick=""ocseditor.help('summary');"">Sommaire</a></p>
740
+ </div>
741
+ "
742
+ "{ocseditor.help.property.enabled}","
743
+ <div class=""help-header"">
744
+ <p><a href=""#"" onclick=""ocseditor.help('summary');"">Sommaire</a></p>
745
+ </div>
746
+
747
+ <h4>L'activation : `enabled`</h4>
748
+ <p>Permet d'activer ou de désactiver la méthode de livraison.</p>
749
+ <p>La valeur doit être booléenne.</p>
750
+
751
+ <div class=""help-footer"">
752
+ <p><a href=""#"" onclick=""ocseditor.help('summary');"">Sommaire</a></p>
753
+ </div>
754
+ "
755
+ "{ocseditor.help.property.code}","
756
+ <div class=""help-header"">
757
+ <p><a href=""#"" onclick=""ocseditor.help('summary');"">Sommaire</a></p>
758
+ </div>
759
+
760
+ <h4>Le code : `code`</h4>
761
+ <p>C'est l'identifiant de la méthode de livraison.</p>
762
+ <p>Il doit être unique. S'il n'est pas unique, il sera modifié.</p>
763
+
764
+ <div class=""help-footer"">
765
+ <p><a href=""#"" onclick=""ocseditor.help('summary');"">Sommaire</a></p>
766
+ </div>
767
+ "
768
+ "{ocseditor.help.property.description}","
769
+ <div class=""help-header"">
770
+ <p>Voir également la propriété <a href=""#"" onclick=""ocseditor.help('property.label');"">label</a>.</p>
771
+ <p><a href=""#"" onclick=""ocseditor.help('summary');"">Sommaire</a></p>
772
+ </div>
773
+
774
+ <h4>La description : `description`</h4>
775
+ <p>Il s'agit de la description de la méthode de livraison.</p>
776
+ <p>Le fonctionnement est identique à la propriété <a href=""#"" onclick=""ocseditor.help('property.label');"">label</a>.</p>
777
+
778
+ <div class=""help-footer"">
779
+ <p>Voir également la propriété <a href=""#"" onclick=""ocseditor.help('property.label');"">label</a>.</p>
780
+ <p><a href=""#"" onclick=""ocseditor.help('summary');"">Sommaire</a></p>
781
+ </div>
782
+ "
783
+ "{ocseditor.help.property.origin}","
784
+ <div class=""help-header"">
785
+ <p>Voir également la propriété <a href=""#"" onclick=""ocseditor.help('property.destination');"">destination</a>.</p>
786
+ <p><a href=""#"" onclick=""ocseditor.help('summary');"">Sommaire</a></p>
787
+ </div>
788
+
789
+ <h4>L'origine : `origin`</h4>
790
+ <p>
791
+ Idem que la destination mais pour filtrer l'origine de livraison.<br/>
792
+ La syntaxe est identique au filtrage de la <a href=""#"" onclick=""ocseditor.help('property.destination');"">destination</a>.
793
+ </p>
794
+
795
+ <div class=""help-footer"">
796
+ <p>Voir également la propriété <a href=""#"" onclick=""ocseditor.help('property.destination');"">destination</a>.</p>
797
+ <p><a href=""#"" onclick=""ocseditor.help('summary');"">Sommaire</a></p>
798
+ </div>
799
+ "
800
+ "{ocseditor.help.property.customer_groups}","
801
+ <div class=""help-header"">
802
+ <p><a href=""#"" onclick=""ocseditor.help('summary');"">Sommaire</a></p>
803
+ </div>
804
+
805
+ <h4>Les groupes client : `customer_groups`</h4>
806
+ <p>
807
+ On peut utiliser le nom ou l'ID des groupes client.
808
+ </p>
809
+
810
+ <div class=""code""><span class=""comment""># Groupes NOT LOGGED IN et General</span><br/>
811
+ customer_groups: <span class=""string"">""NOT LOGGED IN,General""</span>,<br/>
812
+
813
+ <br/>
814
+ <span class=""comment""># Groupes NOT LOGGED IN et General par leur ID</span><br/>
815
+ customer_groups: <span class=""string"">""0,1""</span>,<br/>
816
+ <br/>
817
+ <span class=""comment""># Groupe Retailer</span><br/>
818
+ customer_groups: <span class=""string"">""Retailer""</span>,</div>
819
+
820
+ <div class=""help-footer"">
821
+ <p><a href=""#"" onclick=""ocseditor.help('summary');"">Sommaire</a></p>
822
+ </div>
823
+ "
824
+ "{ocseditor.help.property.tracking_url}","
825
+ <div class=""help-header"">
826
+ <p><a href=""#"" onclick=""ocseditor.help('summary');"">Sommaire</a></p>
827
+ </div>
828
+
829
+ <h4>L'URL de suivi : `tracking_url`</h4>
830
+ <p>
831
+ Documentation à venir.
832
+ </p>
833
+
834
+ <div class=""help-footer"">
835
+ <p><a href=""#"" onclick=""ocseditor.help('summary');"">Sommaire</a></p>
836
+ </div>
837
+ "
838
+ "{ocseditor.help.property.*comment}","
839
+ <div class=""help-header"">
840
+ <p><a href=""#"" onclick=""ocseditor.help('summary');"">Sommaire</a></p>
841
+ </div>
842
+
843
+ <h4>Commentaires</h4>
844
+ <p>
845
+ 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.
846
+ </p>
847
+
848
+ <div class=""help-footer"">
849
+ <p><a href=""#"" onclick=""ocseditor.help('summary');"">Sommaire</a></p>
850
+ </div>
851
+ "
852
+ "{ocseditor.help.changelog}","
853
+ <div class=""help-header"">
854
+ <p><a href=""#"" onclick=""ocseditor.help('summary');"">Sommaire</a></p>
855
+ </div>
856
+
857
+ <h4>Changelog</h4>
858
+ <div class=""code""><pre>
859
+ [2.3.6 - 23 novembre 2010]
860
+ Ajout d'un fichier app/etc/modules/Wecom_Chronorelais.xml vide pour écraser celui des versions précédentes à la 2.3.0 afin d'éviter une cohabitation de deux versions
861
+ Amélioration du traitement des commentaires avec l'éditeur (gestion des caractères #)
862
+
863
+ [2.3.5 - 08 novembre 2010]
864
+ Correction d'un problème chez les utilisateurs ayant une version de PHP antérieure à 5.3.0
865
+
866
+ [2.3.4 - 06 novembre 2010]
867
+ 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
868
+
869
+ [2.3.3 - 05 novembre 2010]
870
+ Possibilité de faire des copie de propriétés de façon récursive avec contrôle de boucle infinie
871
+
872
+ [2.3.2 - 05 novembre 2010]
873
+ Amélioration de l'éditeur :
874
+ - Ajout de l'aide en langue anglais
875
+ - Ajout d'informations dans l'aide
876
+ - Ajout des messages d'erreur de la configuration, avec possibilité de correction rapide
877
+ - Ajout de champs pour les lignes ignorées : on peut ainsi les modifier et appliquer les modifications
878
+ 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}
879
+ Suppression de l'affichage du message d'erreur ""Correspondance non trouvée""
880
+ Correction d'un bug avec les groupes utilisateur ($id==null retournait true lorsque $id était égal à 0)
881
+ Correction d'une erreur de récupération de l'unité de poids
882
+ Améliorations diverses
883
+
884
+ [2.3.1 - 29 octobre 2010]
885
+ 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
886
+
887
+ [2.3.0 - 28 octobre 2010]
888
+ Correction d'un bug avec le caractère * dans les champs ""destination"" et ""origin"" comme jocker
889
+ Ajout d'un éditeur pour faciliter la modification des configurations Chronorelais Shipping
890
+ L'éditeur contient également une aide
891
+ Déplacement de certains fichiers pour mieux correspondre à la structure de Magento
892
+
893
+ [2.2.8 - 20 octobre 2010]
894
+ Correction d'une erreur dans l'include d'ChronorelaisShippingHelper lorsqu'on utilise le Compiler
895
+ Correction d'un bug de calcul du prix TTC dans certains cas ('row_total_with_discount' est égal à 0)
896
+ 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)
897
+ Ajout d'un bouton pour fermer la console de debug
898
+ Ajout d'informations dans le debug (tests sur la destination et l'origine, liste des variables passées en paramètre)
899
+ Affichage du debug uniquement sur la page panier (pas sur les pages en ajax)
900
+ Récupération du bon customer group lors d'une commande créée depuis le backoffice de Magento
901
+
902
+ [2.2.7 - 27 août 2010]
903
+ 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}}
904
+
905
+ [2.2.6 - 25 août 2010]
906
+ 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
907
+
908
+ [2.2.5 - 22 août 2010]
909
+ Correction d'un bug avec les propriétés de type booléenne spécifiées sans les guillemets (comme la propriété enabled)
910
+ Correction d'un bug avec la propriété customer_groups
911
+
912
+ [2.2.4 - 10 août 2010]
913
+ 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
914
+ 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
915
+ Amélioration de la clarté du debug (utilisation de couleurs et d'indentations)
916
+ Correction de bugs légers
917
+ Mise à jour de la syntaxe de la configuration proposée par défaut
918
+
919
+ [2.2.3 - 29 juillet 2010]
920
+ Correction d'un bug avec le traitement de formules dont le résultat est false
921
+
922
+ [2.2.2 - 29 juillet 2010]
923
+ Amélioration du système de cache des formules
924
+
925
+ [2.2.1 - 27 juillet 2010]
926
+ Correction de petits bugs
927
+
928
+ [2.2.0 - 22 juillet 2010]
929
+ Possibilité de compression/décompression de la configuration
930
+ 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})
931
+ Syntaxe légèrement modifié pour {product.attribute.xxx} et {product.option.xxx} (pas de s)
932
+ Ajout de nouvelles propriétés utilisables dans le foreach : {selection.weight}, {selection.quantity}, {product.weight}, {product.quantity}
933
+ Possibilité d'utiliser {product.attribute.xxx} et {product.option.xxx} dans le foreach
934
+
935
+ [2.1.9 - 20 juillet 2010]
936
+ Évaluation des formules contenues dans les propriétés ""label"" et ""description""
937
+
938
+ [2.1.8 - 20 juillet 2010]
939
+ Correction d'une erreur dans le foreach (l'attribut était toujours ""name"")
940
+
941
+ [2.1.7 - 19 juillet 2010]
942
+ Ajout de la syntaxe foreach product.attribute.xxx
943
+
944
+ [2.1.6 - 28 décembre 2009]
945
+ Correction d'une erreur dans le nom d'une variable qui entrainait un plantage dans certaines situations
946
+
947
+ [2.1.5 - 28 décembre 2009]
948
+ Modification de la syntaxe des tables (pour offrir plus de souplesse)
949
+
950
+ [2.1.4 - 24 décembre 2009]
951
+ Modification de la syntaxe d'utilisation des propriétés des produits (pour offrir beaucoup plus de souplesse)
952
+ Possibilité de filtrer les produits dont on veut utiliser les propriétés.
953
+ Ajout de 'COUNT DISTINCT'
954
+
955
+ [2.1.3 - 17 décembre 2009]
956
+ Correction du calcul du nombre de produits dont les propriétés correspondent ""{count ..."" : prise en compte de la quantité
957
+ Simplification de la syntaxe de copie de propriété
958
+
959
+ [2.1.2 - 27 novembre 2009]
960
+ 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
961
+
962
+ [2.1.1 - 26 novembre 2009]
963
+ Suppression de la propriété 'product_properties' qui doit être utilisée dans la propriété 'conditions'
964
+ Améliorations diverses
965
+
966
+ [2.1.0 - 24 novembre 2009]
967
+ Regroupement des propriétés 'fees_table', 'fees_formula' et 'fixed_fees' dans une unique propriété 'fees'
968
+ Regroupement des propriétés 'prices_range' et 'weights_range' dans une unique propriété 'conditions'
969
+ Suppression de la propriété 'reference_value'
970
+ 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)
971
+ 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'
972
+ Utilisation des valeurs des propriétés obsolètes dans leur nouvel équivalent
973
+ Possibilité de copier une propriété avec la syntaxe ""{copy 'colissimo'.'fees'}""
974
+ 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
975
+ 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
976
+
977
+ [2.0.12 - 19 novembre 2009]
978
+ Amélioration de la transmission des variables entre les méthodes de la classe
979
+
980
+ [2.0.11 - 19 novembre 2009]
981
+ Correction du filtrage en fonction des options et des attributs des produits en présence de produits configurables
982
+
983
+ [2.0.10 - 13 novembre 2009]
984
+ Amélioration du filtrage en fonction des options et des attributs des produits
985
+ Correction du filtrage en fonction des options des produits
986
+
987
+ [2.0.9 - 12 novembre 2009]
988
+ Correction du filtrage en fonction des options des produits
989
+
990
+ [2.0.8 - 12 novembre 2009]
991
+ Possibilité de filtrer en fonction des options des produits
992
+
993
+ [2.0.7 - 04 novembre 2009]
994
+ Possibilité de filtrer en fonction de l'origine de livraison
995
+ Possibilité de filtrer en fonction des attributs de produits
996
+ Possibilité de spécifier un code postal dans le filtrage de la destination
997
+ Compatibilité avec Magento 1.4.* : utilisation de la fonction getTranslationList au lieu de getCountryTranslationList qui est dépréciée
998
+
999
+ [2.0.6 - 02 octobre 2009]
1000
+ Possibilité de spécifier des groupes de clients
1001
+
1002
+ [2.0.5 - 18 août 2009]
1003
+ Ajout de la possibilité de spécifier dans la destination le monde entier sauf certains pays
1004
+ Correction d'un problème de parsing de la destination lorsqu'il n'y avait qu'un seul code région entre parenthèses
1005
+ Possibilité d'avoir des codes région comprenant des espaces
1006
+
1007
+ [2.0.4 - 28 juillet 2009]
1008
+ Suppression des options ""Unité de poids"" et ""Utiliser le montant TTC"" de chaque mode de livraison
1009
+ 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 ']'
1010
+ Possibilité de spécifier dans les champs 'prices_range' et 'fees_table' si on utilise le montant HT ou TTC
1011
+ Ajout du champ 'enabled' et suppression de la possibilité de désactiver un bloc de configuration avec le caractère '#'
1012
+ Modification du message d'erreur par défaut
1013
+ Ajout d'un message d'erreur en cas d'erreur d'interprétation d'une formule de calcul de frais
1014
+
1015
+ [2.0.3 - 27 juillet 2009]
1016
+ Correction d'une erreur dans l'interprétation des formules avec des fonctions à arguments multiples (min, max, rand)
1017
+
1018
+ [2.0.2 - 27 juin 2009]
1019
+ Correction d'une erreur d'expression régulière
1020
+
1021
+ [2.0.1 - 25 juin 2009]
1022
+ 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'
1023
+ Correction d'un problème de Magento qui ne semble pas retourner la bonne valeur lors de l'appel à la méthode $request->getFreeShipping()
1024
+ 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()
1025
+ Corrections de bugs
1026
+
1027
+ [2.0 - 3 avril 2009]
1028
+ Création de la version 2.0 du module Chronorelais Shipping qui n'est plus compatible avec les anciennes versions
1029
+ </pre></div>
1030
+
1031
+ <div class=""help-footer"">
1032
+ <p><a href=""#"" onclick=""ocseditor.help('summary');"">Sommaire</a></p>
1033
+ </div>
1034
+ "
js/chronopost/chronorelais/ocseditor.css ADDED
@@ -0,0 +1,465 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #ocs-editor #ocs-editor-config-loader {
2
+ padding: 5px;
3
+ border: solid 1px #6f8992;
4
+ background: #e7efef;
5
+ display: none;
6
+ }
7
+
8
+ #ocs-editor #ocs-editor-config-loader textarea {
9
+ height: 100px;
10
+ }
11
+
12
+ #ocs-editor #os-config-helper {
13
+ }
14
+ #ocs-editor .buttons-set-label {
15
+ padding: 2px 10px 2px 0;
16
+ display: inline-block;
17
+ font-weight: bold;
18
+ }
19
+ #ocs-editor div.buttons-set {
20
+ padding: 0;
21
+ margin: 2px 0;
22
+ }
23
+ #ocs-editor fieldset {
24
+ display: block;
25
+ border: solid 1px #6f8992;
26
+ margin: 2px 0;
27
+ padding: 0 8px 2px 8px;
28
+ }
29
+ #ocs-editor fieldset.buttons-set {
30
+ margin: 2px 0;
31
+ }
32
+ #ocs-editor legend {
33
+ display: inline;
34
+ font-weight: bold;
35
+ margin-left: 15px;
36
+ padding: 0 5px;
37
+ }
38
+
39
+ #ocs-editor .config-container {
40
+ border-top: solid 1px #6f8992;
41
+ }
42
+
43
+ #ocs-editor .properties-container {
44
+ position: relative;
45
+ display: none;
46
+ }
47
+
48
+ #ocs-editor .row-container.selected .properties-container {
49
+ display: block;
50
+ background: #d1dedf;
51
+ }
52
+
53
+ #ocs-editor .row-container.has-error .properties-container {
54
+ background: #f3c6c6;
55
+ }
56
+
57
+ #ocs-editor .properties-list {
58
+ position: relative;
59
+ height: 350px;
60
+ list-style: none;
61
+ width: 20%;
62
+ z-index: 2;
63
+ padding: 5px 0;
64
+ -webkit-box-sizing: border-box; /* Safari/Chrome, other WebKit */
65
+ -khtml-box-sizing: border-box;
66
+ -moz-box-sizing: border-box; /* Firefox, other Gecko */
67
+ box-sizing: border-box; /* Opera/IE 8+ */
68
+ }
69
+
70
+ #ocs-editor .properties-list li {
71
+ margin-left: 10px;
72
+ padding: 5px 0;
73
+ cursor: pointer;
74
+ font-weight: bold;
75
+ }
76
+
77
+ #ocs-editor .properties-list li.selected {
78
+ font-weight: bold;
79
+ border-left: solid 1px #6f8992;
80
+ border-top: solid 1px #6f8992;
81
+ border-bottom: solid 1px #6f8992;
82
+ background: #e7efef;
83
+ padding: 7px 10px;
84
+ position: relative;
85
+ left: 1px;
86
+ }
87
+
88
+ #ocs-editor .row-container.has-error .properties-list li.selected {
89
+ border-color: #af2c2c;
90
+ background: #f7e8e8;
91
+ }
92
+
93
+ #ocs-editor .properties-list li.has-error {
94
+ font-weight: bold;
95
+ color: #d40707;
96
+ }
97
+
98
+ #ocs-editor .properties-list li.empty {
99
+ font-weight: normal;
100
+ -webkit-opacity: 0.8;
101
+ -khtml-opacity: 0.8;
102
+ -moz-opacity: 0.8;
103
+ opacity: 0.8;
104
+ }
105
+
106
+ #ocs-editor .properties-list li.hide {
107
+ display: none;
108
+ }
109
+
110
+ #ocs-editor .property-container {
111
+ position: absolute;
112
+ top: 0;
113
+ right: 0;
114
+ height: 350px;
115
+ overflow: auto;
116
+ width: 80%;
117
+ padding: 8px;
118
+ -webkit-box-sizing: border-box; /* Safari/Chrome, other WebKit */
119
+ -khtml-box-sizing: border-box;
120
+ -moz-box-sizing: border-box; /* Firefox, other Gecko */
121
+ box-sizing: border-box; /* Opera/IE 8+ */
122
+ display: none;
123
+ border-left: solid 1px #6f8992;
124
+ background: #e7efef;
125
+ z-index: 1;
126
+ }
127
+
128
+ #ocs-editor .property-container.selected {
129
+ display: block;
130
+ }
131
+
132
+ #ocs-editor .row-container.has-error .property-container {
133
+ border-color: #af2c2c;
134
+ background: #f7e8e8;
135
+ }
136
+
137
+ #ocs-editor .row-header {
138
+ padding: 3px;
139
+ background: #d1dedf;
140
+ color: #6f8992;
141
+ }
142
+
143
+ #ocs-editor .row-header .error {
144
+ padding: 0 10px;
145
+ }
146
+
147
+ #ocs-editor .row-container.selected .row-header .error {
148
+ color: #fff !important;
149
+ }
150
+
151
+ #ocs-editor .row-title {
152
+ padding: 2px 9px;
153
+ cursor: pointer;
154
+ font-weight: bold;
155
+ font-size: 1.3em;
156
+ }
157
+
158
+ #ocs-editor .row-actions {
159
+ float: right;
160
+ opacity: 0.7;
161
+ -moz-opacity: 0.7;
162
+ -webkit-opacity: 0.7;
163
+ -khtml-opacity: 0.7;
164
+ }
165
+ #ocs-editor .row-actions button {
166
+ margin-left: 5px;
167
+ }
168
+
169
+ #ocs-editor .row-container {
170
+ border: solid 1px #6f8992;
171
+ border-top: 0;
172
+ }
173
+
174
+ #ocs-editor .row-container.selected .row-header {
175
+ background: #6f8992;
176
+ color: #fff;
177
+ }
178
+
179
+ #ocs-editor .row-container.selected .row-actions {
180
+ opacity: 1;
181
+ -moz-opacity: 1;
182
+ -webkit-opacity: 1;
183
+ -khtml-opacity: 1;
184
+ }
185
+
186
+ #ocs-editor .row-container.has-error {
187
+ border: solid 1px #af2c2c;
188
+ }
189
+
190
+ #ocs-editor .row-container.has-error .row-header {
191
+ background: #f3c6c6;
192
+ color: #af2c2c;
193
+ }
194
+
195
+ #ocs-editor .row-container.selected.has-error .row-header {
196
+ background: #af2c2c;
197
+ color: #fff;
198
+ }
199
+
200
+ #ocs-editor textarea {
201
+ border: 0;
202
+ background: #fff;
203
+ display: block;
204
+ overflow: visible;
205
+ width: 100%;
206
+ height: auto;
207
+ -webkit-box-sizing: border-box; /* Safari/Chrome, other WebKit */
208
+ -moz-box-sizing: border-box; /* Firefox, other Gecko */
209
+ -khtml-box-sizing: border-box;
210
+ box-sizing: border-box; /* Opera/IE 8+ */
211
+ padding: 2px 0 2px 5px;
212
+ }
213
+
214
+ #ocs-editor .row-container textarea {
215
+ height: 100px;
216
+ }
217
+
218
+ #ocs-editor .field-container{
219
+ background: #666;
220
+ padding: 2px;
221
+ }
222
+
223
+ #ocs-editor .address-filter-list {
224
+ font-size: 0.9em;
225
+ padding: 2px 0 5px 0;
226
+ line-height: normal;
227
+ }
228
+
229
+ #ocs-editor .address-filter {
230
+ display: inline-block;
231
+ padding: 2px 7px;
232
+ margin: 1px;
233
+ cursor: pointer;
234
+ -webkit-border-radius: 5px;
235
+ -khtml-border-radius: 5px;
236
+ -moz-border-radius: 5px;
237
+ border-radius: 5px;
238
+ }
239
+
240
+ #ocs-editor .address-filter-group-label {
241
+ padding: 2px 7px;
242
+ margin: 1px;
243
+ cursor: pointer;
244
+ border: solid 1px #6f8992;
245
+ background: #6f8992;
246
+ display: inline-block;
247
+ }
248
+
249
+ #ocs-editor .address-filter-group {
250
+ padding: 2px;
251
+ color: #fff;
252
+ border: 0;
253
+ background: #6f8992;
254
+ display: block;
255
+ }
256
+
257
+ #ocs-editor .address-filter.known {
258
+ color: #000;
259
+ border: solid 1px #000;
260
+ background: #7f0;
261
+ }
262
+
263
+ #ocs-editor .address-filter.soft-cleaned {
264
+ /*color: #000;
265
+ border: solid 1px #000;
266
+ background: #f90;*/
267
+ }
268
+
269
+ #ocs-editor .address-filter.hard-cleaned {
270
+ color: #000;
271
+ border: solid 1px #000;
272
+ background: #f90;
273
+ }
274
+
275
+ #ocs-editor .address-filter.replaced {
276
+ color: #000;
277
+ border: solid 1px #000;
278
+ background: #f90;
279
+ }
280
+
281
+ #ocs-editor .address-filter.warning {
282
+ color: #000;
283
+ border: solid 1px #000;
284
+ background: #f90;
285
+ }
286
+
287
+ #ocs-editor .address-filter.unknown {
288
+ color: #000;
289
+ border: solid 1px #000;
290
+ background: #f00;
291
+ font-weight: bold;
292
+ }
293
+ #ocs-editor .address-filter.error {
294
+ color: #f00;
295
+ border: solid 1px #f00;
296
+ background: #dcc;
297
+ font-weight: bold;
298
+ }
299
+
300
+ #ocs-editor .bad {
301
+ text-decoration: line-through;
302
+ }
303
+
304
+ #ocs-editor .donate-container {
305
+ position: absolute;
306
+ bottom: 0;
307
+ border-top: solid 4px #dfdfdf;
308
+ padding: 0.25em 0 0 0;
309
+ width: 100%;
310
+ color: #eb5e00;
311
+ font-size: 1.25em;
312
+ font-weight: bold;
313
+ background: #fff;
314
+ }
315
+ #ocs-editor .donate-container table {
316
+ width: 100%;
317
+ }
318
+
319
+ #ocs-editor .donate-container .form-buttons {
320
+ text-align: right;
321
+ margin-bottom: 0;
322
+ white-space: nowrap;
323
+ }
324
+
325
+ #ocs-editor .ocseditor-page {
326
+ position: absolute;
327
+ top: 0;
328
+ left: 0;
329
+ width: 100%;
330
+ height: 100%;
331
+ z-index: 300;
332
+ display: none;
333
+ background: #fff;
334
+ }
335
+
336
+ #ocs-editor .owebia-address {
337
+ padding-left: 50px;
338
+ font-family: monospace;
339
+ }
340
+
341
+ #ocs-contextual-menu {
342
+ -webkit-box-shadow: 2px 2px 5px #000;
343
+ -khtml-box-shadow: 2px 2px 5px #000;
344
+ -moz-box-shadow: 2px 2px 5px #000;
345
+ box-shadow: 2px 2px 5px #000;
346
+ background: #d1dedf;
347
+ list-style: none;
348
+ margin: 0;
349
+ display: none;
350
+ border: solid 1px #6f8992;
351
+ padding-bottom: 1px;
352
+ }
353
+ #ocs-contextual-menu li {
354
+ font-size: 0.9em;
355
+ }
356
+
357
+ #ocs-contextual-menu a {
358
+ padding: 3px 7px;
359
+ display: block;
360
+ color: #000;
361
+ text-decoration: none;
362
+ }
363
+
364
+ #ocs-contextual-menu a:hover {
365
+ background: #6f8992;
366
+ color: #fff;
367
+ }
368
+
369
+ #ocs-contextual-menu span {
370
+ padding: 2px 7px;
371
+ display: block;
372
+ color: #000;
373
+ border-bottom: solid 1px #6f8992;
374
+ font-weight: bold;
375
+ margin-bottom: 1px;
376
+ }
377
+
378
+ #ocs-editor .ocseditor-page .code {
379
+ font-family: monospace;
380
+ word-wrap: break-word;
381
+ }
382
+ #ocs-editor .ocseditor-page div.code {
383
+ background-color: #efe8de;
384
+ border: solid 1px #5c5248;
385
+ border-left: solid 3px #5c5248;
386
+ padding: 10px 5px;
387
+ overflow: auto;
388
+ }
389
+ #ocs-editor .ocseditor-page span.code {
390
+ padding: 0 3px;
391
+ color: #522;
392
+ font-weight: bold;
393
+ }
394
+ #ocs-editor .ocseditor-page .code .comment {
395
+ color: #666;
396
+ }
397
+ #ocs-editor .ocseditor-page .code .string {
398
+ color: #009f00;
399
+ }
400
+ #ocs-editor .ocseditor-page p {
401
+ margin: 7px 0;
402
+ }
403
+
404
+ #ocs-editor .ocseditor-page ul {
405
+ margin: 0 0 15px 20px;
406
+ list-style: disc;
407
+ }
408
+
409
+ #ocs-editor .ocseditor-page h4 {
410
+ padding: 0 0 2px 0;
411
+ margin: 0;
412
+ border-bottom: solid 1px #dfdfdf;
413
+ }
414
+ #ocs-editor .tips {
415
+ background: #ffdb6f;
416
+ padding: 3px 10px;
417
+ margin: 10px 0;
418
+ }
419
+ #ocs-editor .tips p {
420
+ margin: 4px 0;
421
+ }
422
+ #ocs-editor .help-header, #ocs-editor .help-footer {
423
+ background: #d1dedf;
424
+ padding: 3px 10px;
425
+ margin: 0 0 10px 0;
426
+ }
427
+ #ocs-editor .help-footer {
428
+ margin: 10px 0 0 0;
429
+ }
430
+ #ocs-editor .help-header p, #ocs-editor .help-footer p {
431
+ margin: 4px 0;
432
+ }
433
+ #ocs-editor .help-header a, #ocs-editor .help-footer a {
434
+ color: #444;
435
+ }
436
+ #ocs-editor .ocseditor-page .new {
437
+ color: #0221a9;
438
+ }
439
+ #ocs-editor .table-of-contents {
440
+ margin: 15px 0;
441
+ padding: 15px;
442
+ background-color: #d1dedf;
443
+ }
444
+ #ocs-editor .table-of-contents ul {
445
+ padding: 0;
446
+ margin: 0;
447
+ list-style: none;
448
+ }
449
+ #ocs-editor .table-of-contents ul ul {
450
+ margin: 3px 0 5px 15px;
451
+ }
452
+ #ocs-editor .table-of-contents li {
453
+ padding: 2px 0;
454
+ margin: 0;
455
+ }
456
+ #ocs-editor .table-of-contents a {
457
+ color: #444;
458
+ }
459
+ #ocs-editor .table-of-contents li.new a {
460
+ color: #0221a9;
461
+ font-weight: bold;
462
+ }
463
+ #ocs-editor .table-of-contents a.deprecated {
464
+ color: #8f6e47;
465
+ }
js/chronopost/chronorelais/ocseditor.js ADDED
@@ -0,0 +1,674 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * Magento Chronopost Chronorelais 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 Chronopost
15
+ * @package Chronopost_Chronorelais
16
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
17
+ */
18
+
19
+ /**
20
+ * @constructor
21
+ */
22
+ OCSEditor = function (options) {
23
+ this.options = options;
24
+
25
+ this.jwindow = jQuery(window);
26
+ this.jeditor = null;
27
+ this.jeditor_content = null;
28
+ this.jtextarea = null;
29
+ this.jcontextualmenu = null;
30
+ this.mouse_event_owner = null;
31
+ this.dialog_v_padding = 10;
32
+ this.dialog_h_padding = 15;
33
+ }
34
+
35
+ OCSEditor.prototype = {
36
+ /**
37
+ * @private
38
+ */
39
+ _init: function () {
40
+ var jeditor = this._dialog('ocs-editor',"<div style=\"width:100%;height:100%;position:relative;\" id=\"ocs-editor-content\"></div>");
41
+ this.jeditor = jeditor;
42
+ var jdialogbox = jeditor.find('.dialog-box');
43
+ this.jeditor_content = jeditor.find('#ocs-editor-content');
44
+ this.jeditor_content.css({width: jdialogbox.innerWidth()-this.dialog_h_padding*2, height: jdialogbox.innerHeight()-this.dialog_v_padding*2, border: '0'});
45
+
46
+ var self = this;
47
+ jQuery('#ocs-editor .address-filter-list > .address-filter').live('click',function (event) {
48
+ var caller = jQuery(this);
49
+ self._contextualMenu('address-filter',caller);
50
+ jQuery('#ocs-contextual-menu').css({position: 'absolute', 'z-index': 100, left: event.pageX-7, top: event.pageY}).show();
51
+ event.preventDefault();
52
+ event.stopPropagation();
53
+ });
54
+ jQuery('#ocs-editor .property-container .field').live('blur',function (event) {
55
+ self._updateProperty(this);
56
+ event.preventDefault();
57
+ event.stopPropagation();
58
+ });
59
+ /*jQuery('#ocs-editor .property-container textarea').live('change',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="ocs-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('address-filter-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
+ var parent = caller.parents('.property-container');
136
+ jQuery('#remove-link').click(function (event) {
137
+ caller.fadeOut(null,function(){
138
+ caller.remove();
139
+ self.updateCountries(parent);
140
+ });
141
+ event.preventDefault();
142
+ });
143
+ jQuery('#edit-link').click(function (event) {
144
+ var new_value = prompt(this.options.prompt_new_value_label,caller.attr('original-value'));
145
+ self._ajax({
146
+ data: {
147
+ what: 'get-address-filters',
148
+ input: new_value
149
+ },
150
+ success: function (msg) {
151
+ caller.replaceWith(msg);
152
+ self.updateCountries(parent);
153
+ }
154
+ });
155
+ event.preventDefault();
156
+ });
157
+ jQuery('#ungroup-link').click(function (event) {
158
+ self._dissociateAddressFiltersGroup(caller,100);
159
+ event.preventDefault();
160
+ });
161
+ break;
162
+ }
163
+ },
164
+
165
+ /**
166
+ * @private
167
+ */
168
+ _ajax: function (args) {
169
+ args.data.form_key = this.options.form_key;
170
+ jQuery.ajax({
171
+ type: 'POST',
172
+ url: this.options.ajax_url,
173
+ data: args.data,
174
+ success: args.success
175
+ });
176
+ },
177
+
178
+ /**
179
+ * @private
180
+ */
181
+ _download: function (data) {
182
+ data.form_key = this.options.form_key;
183
+ data = jQuery.param(data);
184
+ var inputs = '';
185
+ jQuery.each(data.split('&'),function(){
186
+ var tmp = this.split('=');
187
+ inputs += '<input type="hidden" name="'+tmp[0]+'" value="'+tmp[1]+'"/>';
188
+ });
189
+ jQuery('<form action="'+this.options.ajax_url+'" method="post">'+inputs+'</form>').appendTo('body').submit().remove();
190
+ },
191
+
192
+ /**
193
+ * @private
194
+ */
195
+ _checkCountries: function (parent) {
196
+ var output = '';
197
+ parent.find('.address-filter').each(function () {
198
+ var country_code = jQuery(this).attr('country-code');
199
+ output += country_code+',';
200
+ if (country_code!='') {
201
+ var tmp = parent.find('.country-'+country_code);
202
+ if (tmp.size()>1) {
203
+ tmp.addClass('warning');
204
+ } else {
205
+ tmp.removeClass('warning');
206
+ }
207
+ }
208
+ });
209
+ },
210
+
211
+ /**
212
+ * @private
213
+ */
214
+ _getConfig: function () {
215
+ var self = this;
216
+ var config = '';
217
+ this.jeditor_content.find('.row-container').each(function(){
218
+ var jrowcontainer = jQuery(this);
219
+ if (jrowcontainer.hasClass('ignored-lines')) {
220
+ config += jrowcontainer.find('.field').val()+"\n";
221
+ } else {
222
+ var comment = jrowcontainer.find('.property-container[property-name="*comment"] .field').val();
223
+ if (comment!='') {
224
+ var lines = comment.replace(/(?:\r\n|\n|\r)/,"\n").split("\n");
225
+ for (var i=0; i<lines.length; i++) {
226
+ if (lines[i].substr(0,1)!='#') lines[i] = '# '+lines[i];
227
+ else lines[i] = '#'+lines[i];
228
+ }
229
+ config += lines.join("\n")+"\n";
230
+ }
231
+ config += "{\n";
232
+ jrowcontainer.find('.property-container').each(function(){
233
+ var jpropertycontainer = jQuery(this);
234
+ var property = jpropertycontainer.attr('property-name');
235
+ if (property!='*comment') {
236
+ var value = null;
237
+ if (property=='destination' || property=='origin') {
238
+ value = self._getAddressFilter('compact-value',this,true,true);
239
+ }
240
+ else value = jpropertycontainer.find('.field').val();
241
+ var property = jpropertycontainer.attr('property-name');
242
+
243
+ switch (property) {
244
+ case 'enabled':
245
+ if (value!='1') config += "\t"+property+': false,'+"\n";
246
+ break;
247
+ default:
248
+ if (value!='') config += "\t"+property+': "'+value+'",'+"\n";
249
+ break;
250
+ }
251
+
252
+ }
253
+ });
254
+ config += "}\n";
255
+ }
256
+ });
257
+ return config;
258
+ },
259
+
260
+ /**
261
+ * @private
262
+ */
263
+ _dissociateAddressFiltersGroup: function (caller, delay) {
264
+ var self = this;
265
+ var childs = caller.children('.address-filter');
266
+ if (delay>0) {
267
+ childs.each(function (i) {
268
+ var child = jQuery(this);
269
+ child.delay(i*delay).fadeOut(null,function(){
270
+ child.insertBefore(caller);
271
+ child.fadeIn();
272
+ if (i==childs.size()-1) {
273
+ caller.fadeOut(null,function(){
274
+ caller.remove();
275
+ self.updateCountries(parent);
276
+ });
277
+ }
278
+ });
279
+ });
280
+ } else {
281
+ childs.insertBefore(caller);
282
+ caller.remove();
283
+ self.updateCountries(parent);
284
+ }
285
+ },
286
+
287
+ /**
288
+ * @private
289
+ */
290
+ _updateAddressFilters: function (object) {
291
+ if (!(object instanceof jQuery)) object = jQuery(object);
292
+ if (!object.hasClass('property-container')) object = object.parents('.property-container');
293
+
294
+ var self = this;
295
+ this._ajax({
296
+ data: {
297
+ what: 'get-address-filters',
298
+ input: object.find('textarea').val()
299
+ },
300
+ success: function (msg) {
301
+ object.find('.address-filter-list').html(msg);
302
+ //self._checkCountries(object);
303
+ }
304
+ });
305
+ },
306
+
307
+ /**
308
+ * @private
309
+ */
310
+ _updateProperty: function (object) {
311
+ if (!(object instanceof jQuery)) object = jQuery(object);
312
+
313
+ var property_container = object.parents('.property-container');
314
+ var property_name = property_container.attr('property-name');
315
+ switch (property_name) {
316
+ case 'destination':
317
+ case 'origin':
318
+ this._updateAddressFilters(object);
319
+ break;
320
+ case 'label':
321
+ this._updateRowTitle(object,property_container);
322
+ break;
323
+ }
324
+ this._ajax({
325
+ data: {
326
+ what: 'check-config',
327
+ config: encodeURIComponent(this._getConfig()),
328
+ },
329
+ success: function (msg) {
330
+ jQuery('body').append(msg);
331
+ }
332
+ });
333
+ var id = object.attr('id')+'-item';
334
+ if (object.val().trim()=='') jQuery('#'+id).addClass('empty');
335
+ else jQuery('#'+id).removeClass('empty');
336
+ },
337
+
338
+ /**
339
+ * @private
340
+ */
341
+ _updateRowTitle: function (jtextarea) {
342
+ var title = jtextarea.val().trim();
343
+ if (title=='') title = this.options.default_row_label;
344
+ jtextarea.parents('.row-container').find('.row-title').html(title);
345
+ },
346
+
347
+ /**
348
+ * @private
349
+ */
350
+ _updateRowsUI: function () {
351
+ var jrows = this.jeditor.find('.row-container');
352
+ if (jrows.filter('.selected').size()==0) {
353
+ jrows.eq(0).addClass('selected');
354
+ }
355
+ if (jrows.size()<=1) {
356
+ jrows.find('.row-actions .delete').hide();
357
+ } else {
358
+ jrows.find('.row-actions .delete').show();
359
+ }
360
+ },
361
+
362
+ /**
363
+ * @private
364
+ */
365
+ /*_linearizeAddressFilters: function (object) {
366
+ if (!(object instanceof jQuery)) object = jQuery(object);
367
+ if (!object.hasClass('property-container')) object = object.parents('.property-container');
368
+
369
+ var self = this;
370
+ object.find('.address-filter-list .address-filter-group').each(function () {
371
+ self._dissociateAddressFiltersGroup(jQuery(this),0);
372
+ });
373
+ },*/
374
+
375
+ /**
376
+ * @public
377
+ */
378
+ insertAtCaret: function (object, text_to_insert) {
379
+ if (!(object instanceof jQuery)) {
380
+ object = jQuery(object);
381
+ if (object[0].nodeName!='textarea') object = object.parents('.property-container');
382
+ }
383
+ if (object.hasClass('property-container')) object = object.find('textarea');
384
+
385
+ object.each(function (i) {
386
+ if (document.selection) {
387
+ this.focus();
388
+ var sel = document.selection.createRange();
389
+ sel.text = text_to_insert;
390
+ this.focus();
391
+ } else if (this.selectionStart || this.selectionStart=='0') {
392
+ var start_index = this.selectionStart;
393
+ var end_index = this.selectionEnd;
394
+ var scroll_top = this.scrollTop;
395
+ this.value = this.value.substring(0,start_index)+text_to_insert+this.value.substring(end_index,this.value.length);
396
+ this.focus();
397
+ this.selectionStart = start_index + text_to_insert.length;
398
+ this.selectionEnd = start_index + text_to_insert.length;
399
+ this.scrollTop = scroll_top;
400
+ } else {
401
+ this.value += text_to_insert;
402
+ this.focus();
403
+ }
404
+ });
405
+ },
406
+
407
+ /**
408
+ * @public
409
+ */
410
+ updateCountries: function (object) {
411
+ if (!(object instanceof jQuery)) object = jQuery(object);
412
+ if (!object.hasClass('property-container')) object = object.parents('.property-container');
413
+
414
+ var list = object.find('.address-filter-list');
415
+ var displayed_field = list.attr('displayed-field');
416
+ if (displayed_field==null) displayed_field = 'original-value';
417
+ var compact = list.attr('compact');
418
+ if (compact==null) compact = false;
419
+ else compact = compact=='1';
420
+ this.displayCountry(displayed_field,object,compact);
421
+ this._checkCountries(object);
422
+ },
423
+
424
+ /**
425
+ * @private
426
+ */
427
+ _getAddressFilter: function (field, object, compact, linearize_groups) {
428
+ if (!(object instanceof jQuery)) object = jQuery(object);
429
+ if (!object.hasClass('property-container')) object = object.parents('.property-container');
430
+
431
+ var values = [];
432
+ object.find('.address-filter-list').attr('displayed-field',field).attr('compact',compact?'1':'0');
433
+
434
+ if (linearize_groups) {
435
+ object.find('.address-filter-list .address-filter').each(function () {
436
+ var jfilter = jQuery(this);
437
+ if (!jfilter.hasClass('address-filter-group')) values.push(jfilter.attr(field));
438
+ });
439
+ } else {
440
+ object.find('.address-filter-list > .address-filter').each(function () {
441
+ values.push(jQuery(this).attr(field));
442
+ });
443
+ }
444
+ var excluding = object.find('.excluding:checked').val()=='1';
445
+ return (excluding ? '* - (' : '')+values.join(','+(compact ? '' : ' '))+(excluding ? ')' : '');
446
+ },
447
+
448
+ /**
449
+ * @public
450
+ */
451
+ displayCountry: function (field, object, compact) {
452
+ if (!(object instanceof jQuery)) object = jQuery(object);
453
+ if (!object.hasClass('property-container')) object = object.parents('.property-container');
454
+
455
+ object.find('.field').val(this._getAddressFilter(field,object,compact,false));
456
+ this._checkCountries(object);
457
+ },
458
+
459
+ /**
460
+ * @public
461
+ */
462
+ selectProperty: function (code, property) {
463
+ jQuery('#r-'+code+'-container .property-item, #r-'+code+'-container .property-container').removeClass('selected');
464
+ jQuery('#r-'+code+'-p-'+property+'-item, #r-'+code+'-p-'+property+'-container').addClass('selected');
465
+ },
466
+
467
+ /**
468
+ * @public
469
+ */
470
+ selectRow: function (code) {
471
+ jQuery('#ocs-editor .row-container').removeClass('selected');
472
+ jQuery('#r-'+code+'-container').addClass('selected');
473
+ },
474
+
475
+ /**
476
+ * @public
477
+ */
478
+ resetErrors: function (code, property, error) {
479
+ this.jeditor.find('.has-error').not('.ignored-lines').removeClass('has-error');
480
+ this.jeditor.find('div.error').remove();
481
+ },
482
+
483
+ /**
484
+ * @public
485
+ */
486
+ setError: function (code, property, error) {
487
+ if (property=='') {
488
+ jQuery('#r-'+code+'-container .row-header').append("<div class=\"error\">"+error+"</div>");
489
+ } else {
490
+ jQuery('#r-'+code+'-container').addClass('has-error');
491
+ jQuery('#r-'+code+'-p-'+property+'-item').addClass('has-error');
492
+ jQuery('#r-'+code+'-p-'+property+'-container').prepend("<div class=\"error\">"+error+"</div>");
493
+ }
494
+ },
495
+
496
+ /**
497
+ * @public
498
+ */
499
+ correct: function (code, property, value) {
500
+ var jfield = jQuery('#r-'+code+'-p-'+property);
501
+ jfield.val(value);
502
+ this._updateProperty(jfield);
503
+ },
504
+
505
+ /**
506
+ * @public
507
+ */
508
+ removeRow: function (object) {
509
+ var self = this;
510
+ var jrow = jQuery(object).parents('.row-container');
511
+ jrow.fadeOut(null,function(){
512
+ jrow.remove();
513
+ self._updateRowsUI();
514
+ });
515
+ },
516
+
517
+ /**
518
+ * @public
519
+ */
520
+ addRow: function () {
521
+ var self = this;
522
+ this._ajax({
523
+ data: {
524
+ what: 'add-row'
525
+ },
526
+ success: function (msg) {
527
+ var jcontainer = self.jeditor.find('.config-container');
528
+ jcontainer.find('.row-container.selected').removeClass('selected');
529
+ jcontainer.append(msg);
530
+ self._updateRowsUI();
531
+ }
532
+ });
533
+ },
534
+
535
+ /**
536
+ * @public
537
+ */
538
+ saveToFile: function () {
539
+ this._download({
540
+ what: 'save-to-file',
541
+ config: this._getConfig(),
542
+ });
543
+ },
544
+
545
+ /**
546
+ * @public
547
+ */
548
+ save: function () {
549
+ this.jtextarea.val(this._getConfig());
550
+ this.close();
551
+ },
552
+
553
+ /**
554
+ * @public
555
+ */
556
+ applyChanges: function () {
557
+ this.loadConfig(this._getConfig());
558
+ },
559
+
560
+ /**
561
+ * @public
562
+ */
563
+ loadConfig: function (config) {
564
+ if (typeof config=='undefined') {
565
+ config = jQuery('#ocs-editor-config-loader textarea').val()
566
+ }
567
+ var self = this;
568
+ this._ajax({
569
+ data: {
570
+ what: 'load-config',
571
+ config: config
572
+ },
573
+ success: function (msg) {
574
+ jQuery('#ocs-editor-config-container').html(msg);
575
+ self.jeditor.find('.address-filter-list').each(function(){
576
+ self._checkCountries(jQuery(this));
577
+ });
578
+ self._updateRowsUI();
579
+ jQuery('#ocs-editor-config-loader').slideUp().find('textarea').val('');
580
+ }
581
+ });
582
+ },
583
+
584
+ /**
585
+ * @public
586
+ */
587
+ showConfigLoader: function () {
588
+ jQuery('#ocs-editor-config-loader').slideDown();
589
+ },
590
+
591
+ /**
592
+ * @public
593
+ */
594
+ hideConfigLoader: function () {
595
+ jQuery('#ocs-editor-config-loader').slideUp().find('textarea').val('');
596
+ },
597
+
598
+ /**
599
+ * @public
600
+ */
601
+ open: function (object) {
602
+ if (this.jeditor==null) this._init();
603
+
604
+ var jcell = jQuery(object).parents('td.value');
605
+ this.jtextarea = jcell.find('textarea');
606
+
607
+ this.jeditor_content.html('<div class=\"loading rule-param-wait\">'+this.options.loading_label+'</div>');
608
+ this.jeditor.fadeIn();
609
+
610
+ var self = this;
611
+ this._ajax({
612
+ data: {
613
+ what: 'open',
614
+ input: this.jtextarea.val()
615
+ },
616
+ success: function (msg) {
617
+ self.jeditor_content.html(msg);
618
+ var jconfig_container = self.jeditor.find('#ocs-editor-config-container');
619
+ var height = self.jeditor_content.height() - jconfig_container.position().top - self.jeditor.find('.donate-container').height() - 15;
620
+ jconfig_container.css({
621
+ overflow: 'auto',
622
+ height: height
623
+ });
624
+ self._updateRowsUI();
625
+ }
626
+ });
627
+ },
628
+
629
+ /**
630
+ * @public
631
+ */
632
+ close: function () {
633
+ this.jeditor.fadeOut();
634
+ },
635
+
636
+ /**
637
+ * @public
638
+ */
639
+ openPage: function (page) {
640
+ jQuery('#ocseditor-'+page+'-page').fadeIn();
641
+ },
642
+
643
+ /**
644
+ * @public
645
+ */
646
+ closePage: function (object) {
647
+ jQuery(object).parents('.ocseditor-page').fadeOut();
648
+ },
649
+
650
+ /**
651
+ * @public
652
+ */
653
+ help: function (help_section) {
654
+ this._ajax({
655
+ data: {
656
+ what: 'help',
657
+ input: help_section
658
+ },
659
+ success: function (msg) {
660
+ var jhelp_page = jQuery('#ocseditor-help-page');
661
+ var jpage_content = jhelp_page.find('.page-content');
662
+ var height = jhelp_page.height() - jpage_content.position().top - 15;
663
+ jpage_content.css({
664
+ overflow: 'auto',
665
+ height: height
666
+ });
667
+ jpage_content.html(msg);
668
+ }
669
+ });
670
+ jQuery('#ocseditor-help-page .page-content').html('<div class=\"loading rule-param-wait\">'+this.options.loading_label+'</div>');
671
+ this.openPage('help');
672
+ }
673
+ }
674
+
package.xml ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <package>
3
+ <name>Chronopost_Chronorelais</name>
4
+ <version>0.1.4</version>
5
+ <stability>stable</stability>
6
+ <license uri="http://opensource.org/licenses/osl-3.0.php">OSL v3.0</license>
7
+ <channel>community</channel>
8
+ <extends/>
9
+ <summary>Cette extension officielle permet de proposer &#xE0; vos clients le mode de livraison Chronopost</summary>
10
+ <description>CHRONOPOSTChronopost offre le choix parmi 2 solutions de livraison en France et 1 &#xE0; l&#x2019;international pour toutes vos commandes en ligne :&#x2013; Chronopost livraison Express &#xE0; domicile. Colis livr&#xE9; le lendemain avant 13h &#xE0; l&#x2019;adresse de votre choix&#x2013; Chrono Relais, colis disponible le lendemain &#xE0; partir de 13h dans l&#x2019;un de 3500 points Chrono Relais de votre choix&#x2013; Chrono Express : livraison express partout dans le monde. L&#x2019;Europe livr&#xE9;e en 1 &#xE0; 3 jours et le reste du monde en 3 &#xE0; 5 jours.
11
+
12
+ Afin de vous accompagner dans le d&#xE9;veloppement des sites e-marchands sur la plateforme Magento, vous trouverez dans le module Chronopost un package de solutions :&#x2013; La g&#xE9;olocalisation des points Chrono Relais&#x2013; Le calcul du co&#xFB;t du transport (via logiciel QuickCost)&#x2013; Le suivi int&#xE9;gr&#xE9;&#x2013; Le choix entre 3 solutions possibles d&#x2019;&#xE9;tiquetage des envois selon les besoins de l&#x2019;e-commer&#xE7;antTest&#xE9; et valid&#xE9; sur Magento 1.4 et.1.5--&gt; Un manuel d'installation est &#xE0; votre disposition dans la partie 'Docs' afin de vous guider dans l'installation du module. (A lire imp&#xE9;rativement)ATTENTION : Pour toutes mise en production du module Chronopost, un contrat avec Chronopost est n&#xE9;cessaire. Si vous n&#x2019;avez pas de contrat merci de prendre contact &#xE0; l&#x2019;adresse suivante : mychrono@chronopost.fr</description>
13
+ <notes>New shipping module</notes>
14
+ <authors><author><name>Benjamin GOSSELET</name><user>auto-converted</user><email>chronopost@adexos.fr</email></author></authors>
15
+ <date>2011-08-29</date>
16
+ <time>10:34:22</time>
17
+ <contents><target name="magedesign"><dir name="adminhtml"><dir name="default"><dir name="default"><dir name="template"><dir name="chronorelais"><dir name="import"><file name="form.phtml" hash="356aadf2bb0182b23f7af38888a0cd38"/></dir></dir></dir></dir></dir></dir><dir name="frontend"><dir name="default"><dir name="default"><dir name="layout"><file name="chronorelais.xml" hash="054fa1c126747c9c24c9c87057fa2c35"/></dir><dir name="template"><dir name="chronorelais"><dir name="checkout"><dir name="onepage"><dir name="shipping_method"><file name="available.phtml" hash="7377a159a92db28c30f86ad52921a5b0"/><file name="chronorelais.phtml" hash="066b7b46e68ab109c497ac167d8cd333"/></dir><file name="shipping_method.phtml" hash="4f084424b6dcdb187753f09357f46898"/></dir></dir><dir name="sales"><dir name="order"><file name="history.phtml" hash="f95a1860a4cf463f6fca48273cc45eaf"/><file name="recent.phtml" hash="8045fbbe75510efc55da31455d2cc47a"/></dir></dir></dir></dir></dir></dir></dir></target><target name="magecommunity"><dir name="Chronopost"><dir name="Chronorelais"><dir name="Block"><dir name="Adminhtml"><dir name="System"><dir name="Config"><dir name="Form"><dir name="Field"><file name="Config.php" hash="b38741ddd97fcae5dd276239fb3c6b70"/></dir></dir></dir></dir></dir><dir name="Checkout"><dir name="Onepage"><dir name="Shipping"><dir name="Method"><file name="Chronorelais.php" hash="c4d908310310e4cd90833378df260599"/></dir></dir></dir></dir><dir name="Export"><dir name="Orders"><file name="Grid.php" hash="d79a797a01c1e7405d78fa08a1cd8805"/></dir><file name="Orders.php" hash="9ada10bd85cb58122e722b3e82c71e37"/></dir><dir name="Import"><file name="Form.php" hash="56c6e3787c05e58d57b48ec4b1421468"/></dir><dir name="Sales"><dir name="Order"><dir name="Shipment"><file name="View.php" hash="f5407d7d14aa59acb844479da5046900"/></dir></dir><dir name="Shipment"><file name="Copy of Grid.php" hash="f72d35dcf2b3be9d8d5f24342c0633f4"/><file name="Grid-bkp-03-02-11.php" hash="e3b798fa5259cca5e9d3a08a75fb3f76"/><file name="Grid.php" hash="ffdfa3caf30f292211f4a7c65b54a866"/></dir><file name="Impression.php" hash="619599b136b9cc49f01dba5b08ee8428"/></dir><file name="Detail.php" hash="005fa3b6e5918c6c9779402fab5713f2"/><file name="Filter.php" hash="28f80e3ab34f6ff03b61f070ccbac697"/></dir><dir name="Controller"><file name="Abstract.php" hash="cea89f06a2ca68d9c7e7c54b2304ae85"/></dir><dir name="controllers"><dir name="Checkout"><file name="OnepageController.php" hash="180def68d8f23900be5bb3f5f2214fc3"/></dir><dir name="Sales"><dir name="Order"><file name="ShipmentController.php" hash="748e773c4558f24f1cf54e462fa24a88"/></dir><file name="ImpressionController.php" hash="a5692a173c2c941f2ab8c8bef02a6ddd"/></dir><file name="AjaxController.php" hash="c9b22b5a4efdb4fcb4efd2d990099967"/><file name="ExportController.php" hash="8fbffc0b31a55ac422a52e5972c05b01"/><file name="ImportController.php" hash="f2a840c80d8a2c267a20950b7d11e42f"/><file name="RelaisController.php" hash="5d48155ddb7cc2d4effbbfdeb4f3946d"/></dir><dir name="etc"><file name="config.xml" hash="34bbd312fc384b1a983926ef44e5fe65"/><file name="system.xml" hash="024697b3c6f3808ef1f89d44bd422a72"/></dir><dir name="Helper"><file name="Data.php" hash="70531f8f903a63986c063f65553d643d"/></dir><dir name="includes"><file name="ChronorelaisShippingHelper.php" hash="045b38347b338ed5a96f19570f871247"/><file name="countries.inc.php" hash="d21cd393c7c0ebc83beccc99950d6ab1"/></dir><dir name="Model"><dir name="Carrier"><file name="AbstractChronorelais.php" hash="f4957f6d660c4adb0328f9f2d73da1e2"/><file name="AbstractChronorelaisShipping.php" hash="1bad472a2f4a2450db9049aa89600ea0"/><file name="Chronoexpress.php" hash="bc867a6b98966ada549a0b81ec334b64"/><file name="Chronopost.php" hash="c4d4525447d2801d28d921eaedc35a9a"/><file name="Chronorelais.php" hash="5cfcb83c23d05585fdc50f8b2747fc40"/></dir><dir name="Config"><dir name="Source"><file name="Civility.php" hash="fe6ec6eebe6faffdd0bb65479d91cd5d"/><file name="EndOfLineCharacter.php" hash="3fe6b6069a9efdc29ad0d3f7d1cf4794"/><file name="FieldDelimiter.php" hash="3e023d40aeca50932e62ff97eed6317e"/><file name="FieldSeparator.php" hash="ce30c5974a893bd5467334d574dd578a"/><file name="FileCharset.php" hash="6cc4ebab95735bd121af16e0eedd90d6"/><file name="FileExtension.php" hash="597c3e78e7584bf7c4b7b2ebad6d2a65"/><file name="PrintMode.php" hash="67e8a6e98e12c7e72624ba5322076c00"/></dir></dir><dir name="Sales"><dir name="Quote"><dir name="Address"><dir name="Total"><file name="Shipping.php" hash="2e69db363011f84ef2cdb5d0e9d4c4df"/></dir></dir></dir></dir></dir><dir name="sql"><dir name="chronorelais_setup"><file name="mysql4-install-0.1.0.php" hash="c307802a7bd10c1ecce06799b04569c2"/><file name="mysql4-upgrade-0.1.0-0.1.1.php" hash="ea3358055a851a96b673c721202045be"/><file name="mysql4-upgrade-0.1.1-0.1.2.php" hash="961f41dc1012d0917504f9bb5f5d106c"/><file name="mysql4-upgrade-0.1.2-0.1.3.php" hash="b85470889421f652c3d01b96072f579c"/><file name="mysql4-upgrade-0.1.3-0.1.4.php" hash="def69d0ae26b0d130d2ce6e0838e5d7f"/></dir></dir></dir></dir></target><target name="magelocale"><dir name="en_US"><file name="Chronopost_Chronorelais.csv" hash="351140a6ab727666e06cc7fe5d28c1b0"/></dir><dir name="fr_FR"><file name="Chronopost_Chronorelais.csv" hash="723a027f77a05e598cefe3c522bd5c0c"/></dir></target><target name="mageskin"><dir name="frontend"><dir name="default"><dir name="default"><dir name="chronorelais"><file name="ac.png" hash="0c04f70da35d43a2636cfbd6ad2b10d5"/><file name="chronopost.png" hash="93e5b22e2f280923df8d503f5c8e5b92"/><file name="chronorelais.css" hash="990db2d6f277650fb487161bcf4b0eb5"/><file name="chronorelais.png" hash="0383895b061b4a1210f9435fcf3a726a"/><file name="chronorelaismap.js" hash="41d3d363b046ed8ad5ff6a799341a507"/><file name="home.png" hash="7904b495e94047eb3406e260bc660cce"/><file name="ico_ac_shaded.gif" hash="e55d9b2071fb976cf5331b6273a40731"/><file name="Picto_Chrono_Relais.png" hash="1ea0f0c410d237adf23d5905cd8431f5"/><file name="Thumbs.db" hash="2e16ed23c37d1aa29a6caf73f513a648"/></dir></dir></dir></dir></target><target name="mage"><dir name="js"><dir name="chronopost"><dir name="chronorelais"><file name="ocseditor.css" hash="1bfc847153768d6729cdad7cb1abe443"/><file name="ocseditor.js" hash="20c49b6384de72fe7788c47cd3bf2272"/></dir></dir></dir></target><target name="mageetc"><dir name="modules"><file name="WSChronopost_Chronorelais.xml" hash="31f440b1638ad23dce89a5f08a178cbe"/></dir></target></contents>
18
+ <compatible/>
19
+ <dependencies/>
20
+ </package>
skin/frontend/default/default/chronorelais/Picto_Chrono_Relais.png ADDED
Binary file
skin/frontend/default/default/chronorelais/Thumbs.db ADDED
Binary file
skin/frontend/default/default/chronorelais/ac.png ADDED
Binary file
skin/frontend/default/default/chronorelais/chronopost.png ADDED
Binary file
skin/frontend/default/default/chronorelais/chronorelais.css ADDED
@@ -0,0 +1,46 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* styles for chrono relais */
2
+
3
+ .chronorelais-list { }
4
+ .sp-methods-chronorelais { padding:5px 20px;}
5
+ sp-methods-chronorelais dd li { clear:both;}
6
+ .chronorelaismap { margin:20px 0px 10px 0px; }
7
+ .chronorelaismap .mappostalcode { margin-bottom:10px; text-align:right;}
8
+ .sp-methods .method-description { clear:both; }
9
+ .sp-methods .method-radio, .sp-methods .method-image, .sp-methods .method-contents { }
10
+ .sp-methods .method-image { padding:0 10px;}
11
+
12
+ /*****************************
13
+ sw-Gmap
14
+ *******************************/
15
+ #chronomap { height:450px; width:100%; overflow:hidden!mportant; font:82.5%/1.3 Arial,Helvetica,sans-serif; background-color: #E5E3DF; border: 1px solid #aaa;}
16
+ #chronomap *{float:none;overflow:visible;font-family: Arial,sans-serif;}
17
+ #chronomap a {color:#0000cc;outline:none;}
18
+ #chronomap h4{font-size:14px;margin-bottom:6px;border-bottom:1px solid #ccc;}
19
+ #chronomap h2{font-size:16px;margin:2px 10px 6px 0; font-weight:bold;}
20
+
21
+ /*****************************
22
+ Infowindow
23
+ *******************************/
24
+ #chronomap .sw-infowindow a{cursor:pointer;}
25
+ #sw-infowindow-info{max-height:400px}
26
+ #sw-infowindow-hor{height:150px}
27
+ .sw-map-adresse-wrp{min-height:90px}
28
+ .sw-map-adresse{font-size:1.2em;margin:5px 0 8px 0;line-height:1.45em;}
29
+ .sw-map-tools a{font-size:12px;}
30
+ #chronomap .sw-desc{display:block;font-weight:bold;line-height:16px;float:none!important;width:auto;}
31
+ #chronomap .sw-help{display:block;float:none!important;width:auto;clear:both;}
32
+ .sw-map-itin-tools{font-size:11px;padding:8px 0;display:block;}
33
+ .sw-back-link{font-size:11px;display:block;text-align:right;margin:0px ;}
34
+ #sw-sendbymail-wrap{height:220px;overflow:hidden;}
35
+ #chronomap .sw-textarea{height:30px;}
36
+ .sw-tool-itineraire{height:220px;}
37
+ /*****************************
38
+ Tables
39
+ *******************************/
40
+ .sw-table {border-collapse:collapse; width:100%;}
41
+ .sw-table td {font-size:1.2em;border-bottom:1px solid #ccc; padding:1px 0px;}
42
+ .sw-table th{background:#eee;font-size:1.3em;border-top:1px solid #555}
43
+ #sw-table-horaire-client td ,#sw-table-horaire-depot td{width:50%;}
44
+ #sw-table-horaire-client{}
45
+ #sw-table-horaire-depot{margin-top:8px;}
46
+ /*****************************
skin/frontend/default/default/chronorelais/chronorelais.png ADDED
Binary file
skin/frontend/default/default/chronorelais/chronorelaismap.js ADDED
@@ -0,0 +1,463 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ var gmarkers = [];
2
+ var map;
3
+ var homeaddress = "";
4
+ var addressrelais = [];
5
+ var relaylatan = [];
6
+ var next_pt = 0;
7
+ var hidehomeicon = false;
8
+
9
+ function loadMyPoint(i) {
10
+ GEvent.trigger(gmarkers[i], "click");
11
+ }
12
+
13
+ var bounds = new GLatLngBounds();
14
+ function loadRelayMap(address, relaisArray, nextpt) {
15
+ if (GBrowserIsCompatible()) {
16
+ var geo = new GClientGeocoder();
17
+ var reasons=[];
18
+ reasons[G_GEO_SUCCESS] = "Success";
19
+ reasons[G_GEO_MISSING_ADDRESS] = "Missing Address: The address was either missing or had no value.";
20
+ reasons[G_GEO_UNKNOWN_ADDRESS] = "Unknown Address: No corresponding geographic location could be found for the specified address.";
21
+ reasons[G_GEO_UNAVAILABLE_ADDRESS]= "Unavailable Address: The geocode for the given address cannot be returned due to legal or contractual reasons.";
22
+ reasons[G_GEO_BAD_KEY] = "Bad Key: The API key is either invalid or does not match the domain for which it was given";
23
+ reasons[G_GEO_TOO_MANY_QUERIES] = "Too Many Queries: The daily geocoding quota for this site has been exceeded.";
24
+ reasons[G_GEO_SERVER_ERROR] = "Server error: The geocoding request could not be successfully processed.";
25
+
26
+ map = new GMap2(document.getElementById("chronomap"));
27
+ //map.addControl(new GLargeMapControl());
28
+ map.setUIToDefault();
29
+
30
+ var blueIcon = new GIcon();
31
+ blueIcon.iconSize = new GSize(45, 30);
32
+ blueIcon.iconAnchor = new GPoint(9, 34);
33
+ blueIcon.infoWindowAnchor = new GPoint(9, 2);
34
+ blueIcon.transparent = Picto_Chrono_Relais;
35
+ var homeicon = new GIcon();
36
+ homeicon.iconSize = new GSize(32, 37);
37
+ homeicon.iconAnchor = new GPoint(9, 34);
38
+ homeicon.infoWindowAnchor = new GPoint(9, 2);
39
+ homeicon.transparent = Home_Chrono_Icon;
40
+
41
+ if(!homeaddress && !hidehomeicon) {
42
+ var ship_address = getShipAddress(); //get shipping address to set home address
43
+ homeaddress = relaisArray.codePostal + " " + relaisArray.localite;
44
+ if(ship_address) { homeaddress = ship_address+" "+homeaddress; }
45
+
46
+ geo.getLocations(homeaddress , function(result) {
47
+ if (result.Status.code == G_GEO_SUCCESS) {
48
+ var p = result.Placemark[0].Point.coordinates;
49
+ var point = new GLatLng(p[1],p[0]);
50
+ var marker = new GMarker(point,{title:'home',icon:homeicon});
51
+ map.addOverlay(marker);
52
+ map.setCenter(point, 17-5);
53
+ }
54
+ });
55
+ }
56
+
57
+ function createTabbedMarker(point, relaisArray) {
58
+ //alert(point);
59
+ addressrelais.push(relaisArray);
60
+ var label = nextpt;
61
+ var relaypoint_id = relaisArray.identifiantChronopostPointA2PAS;
62
+ var marker = new GMarker(point,{title:relaisArray.nomEnseigne,icon:blueIcon});
63
+ var tab = new GInfoWindowTab ("Infos", '<div id="sw-infowindow-info" class="sw-infowindow">'+getMarkerInfoContent(relaisArray) + getActionsForm(label)+'</div>');
64
+ var tab2 = new GInfoWindowTab ("Horaires", '<div id="sw-infowindow-hor" class="sw-infowindow">'+"<h2>Horaires</h2>"+getHorairesTab(relaisArray, true)+'</div>') ;
65
+
66
+ GEvent.addListener(marker, "click", function() {
67
+ if(document.getElementById('s_method_chronorelais_'+relaisArray.identifiantChronopostPointA2PAS))
68
+ document.getElementById('s_method_chronorelais_'+relaisArray.identifiantChronopostPointA2PAS).checked = true;
69
+ marker.openInfoWindowTabsHtml([tab, tab2]);
70
+ });
71
+ //gmarkers.push(marker);
72
+ gmarkers[relaypoint_id] = marker;
73
+ return marker;
74
+ }
75
+
76
+ function showAddress(address, relaisArray) {
77
+ var search = address;
78
+ // ====== Perform the Geocoding ======
79
+ geo.getLocations(search, function (result)
80
+ {
81
+ // If that was successful
82
+ if (result.Status.code == G_GEO_SUCCESS) {
83
+ // Loop through the results, placing markers
84
+ //for (var i=0; i<result.Placemark.length; i++) {
85
+ for (var i=0; i<1; i++) {
86
+ var p = result.Placemark[i].Point.coordinates;
87
+ relaylatan.push(p);
88
+ var point = new GLatLng(p[1],p[0]);
89
+ var marker = createTabbedMarker(point, relaisArray);
90
+ map.addOverlay(marker);
91
+ // ==== Each time a point is found, extent the bounds ato include it =====
92
+ bounds.extend(point);
93
+ }
94
+ // centre the map on the first result
95
+ //!homeaddress && hidehomeicon &&
96
+ if(nextpt==5) {
97
+ var p = result.Placemark[0].Point.coordinates;
98
+ map.setCenter(new GLatLng(p[1],p[0]),17-5);
99
+ // ===== determine the zoom level from the bounds =====
100
+ map.setZoom(map.getBoundsZoomLevel(bounds));
101
+ // ===== determine the centre from the bounds ======
102
+ map.setCenter(bounds.getCenter());
103
+ }
104
+ }
105
+ // ====== Decode the error status ======
106
+ else {
107
+ var reason="Code "+result.Status.code;
108
+ if (reasons[result.Status.code]) {
109
+ reason = reasons[result.Status.code]
110
+ }
111
+ alert('Could not find "'+search+ '" ' + reason);
112
+ }
113
+ }
114
+ );
115
+ }
116
+ showAddress(address, relaisArray);
117
+
118
+ } else {
119
+ alert("Sorry, the Google Maps API is not compatible with this browser");
120
+ }
121
+ } // end of loadRelayMap function
122
+
123
+ function addEvent( obj, type, fn ) {
124
+ if ( obj.attachEvent ) {
125
+ obj["e"+type+fn] = fn;
126
+ obj[type+fn] = function() { obj["e"+type+fn]( window.event ) };
127
+ obj.attachEvent( "on"+type, obj[type+fn] );
128
+ }
129
+ else{
130
+ obj.addEventListener( type, fn, false );
131
+ }
132
+ }
133
+
134
+ function getMarkerInfoContent(relaisArray){
135
+ var icoPath = Picto_Chrono_Relais;
136
+ var content="<div class=\"sw-map-adresse-wrp\" style=\"background-image: url("+ icoPath +"); background-repeat: no-repeat;padding-left:50px;\">"
137
+ + "<h2>"+relaisArray.nomEnseigne+"</h2>"
138
+ + "<div class=\"sw-map-adresse\">"
139
+ + parseAdresse(relaisArray)
140
+ + relaisArray.codePostal + " " + relaisArray.localite
141
+ + "</div></div>";
142
+ return content;
143
+ }
144
+ function getActionsForm(label)
145
+ {
146
+ var html = '<div class="sw-map-tools"><a href="javascript:printPage('+label+')">Imprimer</a>'
147
+ + '</div>';
148
+ return html;
149
+ }
150
+
151
+ function getHorairesTab(anArray, highlight)
152
+ {
153
+ var userAgent = navigator.userAgent.toLowerCase();
154
+ var msie = /msie/.test( userAgent ) && !/opera/.test( userAgent );
155
+
156
+ var rs = "" ;
157
+ rs = "<table id=\"sw-table-horaire\" class=\"sw-table\"";
158
+ if(msie) {
159
+ rs += " style=\"width:auto;\"";
160
+ }
161
+ rs += ">"
162
+ + "<tr><td>Lun:</td>"+ parseHorairesOuverture(anArray.horairesOuvertureLundi, 1, highlight) +"</tr>"
163
+ + "<tr><td>Mar:</td>"+ parseHorairesOuverture(anArray.horairesOuvertureMardi, 2, highlight) +"</tr>"
164
+ + "<tr><td>Mer:</td>"+ parseHorairesOuverture(anArray.horairesOuvertureMercredi, 3, highlight) +"</tr>"
165
+ + "<tr><td>Jeu:</td>"+ parseHorairesOuverture(anArray.horairesOuvertureJeudi, 4, highlight) +"</tr>"
166
+ + "<tr><td>Ven:</td>"+ parseHorairesOuverture(anArray.horairesOuvertureVendredi, 5, highlight) +"</tr>"
167
+ + "<tr><td>Sam:</td>"+ parseHorairesOuverture(anArray.horairesOuvertureSamedi, 6, highlight) +"</tr>"
168
+ + "<tr><td>Dim:</td>"+ parseHorairesOuverture(anArray.horairesOuvertureDimanche, 0, highlight) +"</tr>"
169
+ + "</table>" ;
170
+ return rs ;
171
+ }
172
+
173
+ function parseAdresse(anArray)
174
+ {
175
+ var address = anArray.adresse1 + "<br />" ;
176
+ if (anArray.adresse2)
177
+ address += anArray.adresse2 + "<br />" ;
178
+ if (anArray.adresse3)
179
+ address += anArray.adresse3 + "<br />" ;
180
+ return address ;
181
+ }
182
+
183
+ function parseHorairesOuverture(value , day, highlight)
184
+ {
185
+ var rs = "" ;
186
+
187
+ var now = new Date() ;
188
+ var today = now.getDay() ; // number of day
189
+ var attributedCell = "" ;
190
+ var reg = new RegExp(" ", "g");
191
+
192
+ var horaires = value.split(reg) ;
193
+
194
+ for (var i=0; i < horaires.length; i++)
195
+ {
196
+ // first define the attributes for the current cell
197
+ if ( highlight == true && day == today)
198
+ {
199
+ attributedCell = "style=\"color:red;\"" ;
200
+ }
201
+ else
202
+ {
203
+ attributedCell = "" ;
204
+ }
205
+
206
+ // so, re-format time
207
+ if (horaires[i] == "00:00-00:00")
208
+ {
209
+ horaires[i] = "<td "+attributedCell+">Ferm&eacute;</td>" ;
210
+ }
211
+ else
212
+ {
213
+ horaires[i] = "<td "+attributedCell+">"+horaires[i]+"</td>" ;
214
+ }
215
+
216
+ // yeah, concatenates result to the returned value
217
+ rs += horaires[i] ;
218
+ }
219
+
220
+ return rs ;
221
+ }
222
+
223
+ function printPage(i)
224
+ {
225
+ var fen=open("","Impression");
226
+ fen.focus();
227
+ var baseURL = "http://www.chronopost.fr/transport-express/webdav/site/chronov4/groups/administrators/public/Chronomaps/" ;
228
+ var latlngpoint = relaylatan[i-1];
229
+ if(latlngpoint) {
230
+ fen.location.href = baseURL
231
+ + "print-result.html?request=print&"
232
+ + btQueryString(addressrelais[i-1], true)
233
+ + "&rtype=chronorelais"
234
+ + "&icnname=ac"
235
+ + "&lat=" + latlngpoint[1]
236
+ + "&lng=" + latlngpoint[0]
237
+ + "&sw-form-type-point=opt_chrlas"
238
+ + "&is_print_direction=" + false
239
+ + "&from_addr="
240
+ + "&to_addr=";
241
+ }
242
+ }
243
+
244
+ function btQueryString(anArray, needEscape)
245
+ {
246
+ var rs = "" ;
247
+ for (key in anArray)
248
+ {
249
+ if (needEscape == true)
250
+ {
251
+ if(anArray[key]) {
252
+ if (rs != "")
253
+ rs += "&"
254
+ rs += key +"=" + escape(anArray[key]) ;
255
+ }
256
+ }
257
+ else
258
+ {
259
+ if(anArray[key]) {
260
+ if (rs != "")
261
+ rs += "_-_"
262
+ rs += key +"=" + anArray[key] ;
263
+ }
264
+ }
265
+ }
266
+ return rs ;
267
+ }
268
+
269
+ function getShipAddress() {
270
+ var ship_address = '';
271
+ if($('shipping:same_as_billing').checked) {
272
+ if ($('billing-address-select') && $('billing-address-select').value) {
273
+ var e = $('billing-address-select');
274
+ var address_value = e.options[e.selectedIndex].text;
275
+ var shipping_address = address_value.split(',');
276
+ if(shipping_address[1]) {
277
+ ship_address = shipping_address[1];
278
+ }
279
+ } else {
280
+ if($('billing:street1')) { ship_address = $('billing:street1').value; }
281
+ if($('billing:street2')) { ship_address = ship_address+" "+$('billing:street2').value; }
282
+ if($('billing:street3')) { ship_address = ship_address+" "+$('billing:street3').value; }
283
+ }
284
+ } else {
285
+ if ($('shipping-address-select') && $('shipping-address-select').value) {
286
+ var e = $('shipping-address-select');
287
+ var address_value = e.options[e.selectedIndex].text;
288
+ var shipping_address = address_value.split(',');
289
+ if(shipping_address[1]) {
290
+ ship_address = shipping_address[1];
291
+ }
292
+ } else {
293
+ if($('shipping:street1')) { ship_address = $('shipping:street1').value; }
294
+ if($('shipping:street2')) { ship_address = ship_address+" "+$('shipping:street2').value; }
295
+ if($('shipping:street3')) { ship_address = ship_address+" "+$('shipping:street3').value; }
296
+ }
297
+ }
298
+ return ship_address;
299
+ }
300
+
301
+ /** Map content end **/
302
+
303
+
304
+ // shipping method
305
+ var ShippingMethod = Class.create();
306
+ ShippingMethod.prototype = {
307
+ initialize: function(form, saveUrl){
308
+ this.form = form;
309
+ if ($(this.form)) {
310
+ $(this.form).observe('submit', function(event){this.save();Event.stop(event);}.bind(this));
311
+ }
312
+ this.saveUrl = saveUrl;
313
+ this.validator = new Validation(this.form);
314
+ this.onSave = this.nextStep.bindAsEventListener(this);
315
+ this.onComplete = this.resetLoadWaiting.bindAsEventListener(this);
316
+ },
317
+
318
+ validate: function() {
319
+ var methods = document.getElementsByName('shipping_method');
320
+ if (methods.length==0) {
321
+ alert(Translator.translate('Your order cannot be completed at this time as there is no shipping methods available for it. Please make neccessary changes in your shipping address.'));
322
+ return false;
323
+ }
324
+
325
+ if(!this.validator.validate()) {
326
+ return false;
327
+ }
328
+
329
+ for (var i=0; i<methods.length; i++) {
330
+ if (methods[i].checked) {
331
+ return true;
332
+ }
333
+ }
334
+ alert(Translator.translate('Please specify shipping method.'));
335
+ return false;
336
+ },
337
+
338
+ getrelais: function(url){
339
+ if (checkout.loadWaiting!=false) return;
340
+ if (this.validate()) {
341
+ checkout.setLoadWaiting('shipping-method');
342
+ hidehomeicon = false;
343
+ var request = new Ajax.Request(
344
+ url,
345
+ {
346
+ method:'post',
347
+ onComplete: this.onComplete,
348
+ onSuccess: this.onSave,
349
+ onFailure: checkout.ajaxFailure.bind(checkout),
350
+ parameters: Form.serialize(this.form)
351
+ }
352
+ );
353
+ }
354
+ },
355
+
356
+ changePostalCode: function(url){
357
+ if (checkout.loadWaiting!=false) return;
358
+ if (this.validate()) {
359
+ if(!$('mappostalcode').value) { return false; }
360
+ checkout.setLoadWaiting('shipping-method');
361
+ $('mappostalcodebtn').hide();
362
+ $('postalcode-please-wait').show();
363
+ $('postalcode-please-wait').style.opacity = '0.5';
364
+ hidehomeicon = true;
365
+ var request = new Ajax.Request(
366
+ url,
367
+ {
368
+ method:'post',
369
+ onComplete: this.onComplete,
370
+ onSuccess: this.onSave,
371
+ onFailure: checkout.ajaxFailure.bind(checkout),
372
+ parameters: Form.serialize(this.form)
373
+ }
374
+ );
375
+ }
376
+ },
377
+
378
+ hiderelais: function(url){
379
+ if($('checkout-shipping-method-chronorelais-load')) {
380
+ $('checkout-shipping-method-chronorelais-load').innerHTML = "";
381
+ }
382
+ },
383
+
384
+ save: function(){
385
+
386
+ if (checkout.loadWaiting!=false) return;
387
+ if (this.validate()) {
388
+ checkout.setLoadWaiting('shipping-method');
389
+ var request = new Ajax.Request(
390
+ this.saveUrl,
391
+ {
392
+ method:'post',
393
+ onComplete: this.onComplete,
394
+ onSuccess: this.onSave,
395
+ onFailure: checkout.ajaxFailure.bind(checkout),
396
+ parameters: Form.serialize(this.form)
397
+ }
398
+ );
399
+ }
400
+ },
401
+
402
+ resetLoadWaiting: function(transport){
403
+ checkout.setLoadWaiting(false);
404
+ },
405
+
406
+ nextStep: function(transport){
407
+ if (transport && transport.responseText){
408
+ try{
409
+ response = eval('(' + transport.responseText + ')');
410
+ }
411
+ catch (e) {
412
+ response = {};
413
+ }
414
+ }
415
+
416
+ if (response.error) {
417
+ alert(response.message);
418
+ if($('mappostalcodebtn')) { $('mappostalcodebtn').show(); }
419
+ if($('postalcode-please-wait')) { $('postalcode-please-wait').hide(); }
420
+ return false;
421
+ }
422
+
423
+ if (response.update_section) {
424
+ $('checkout-'+response.update_section.name+'-load').update(response.update_section.html);
425
+ response.update_section.html.evalScripts();
426
+
427
+ if(response.relaypoints) {
428
+ if(response.relaypoints.length>0) {
429
+ var relayaddress = "";
430
+ gmarkers = [];
431
+ addressrelais = [];
432
+ relaylatan = [];
433
+ homeaddress = "";
434
+ next_pt = 0;
435
+ bounds = new GLatLngBounds();
436
+ for(var s=0; s<response.relaypoints.length; s++) {
437
+ next_pt = s+1;
438
+ relayaddress = response.relaypoints[s].adresse1;
439
+ if(response.relaypoints[s].codePostal)
440
+ relayaddress += " "+response.relaypoints[s].codePostal;
441
+ if(response.relaypoints[s].localite)
442
+ relayaddress += " "+response.relaypoints[s].localite;
443
+ loadRelayMap(relayaddress, response.relaypoints[s], next_pt);
444
+ }
445
+ }
446
+ }
447
+ }
448
+
449
+ payment.initWhatIsCvvListeners();
450
+
451
+ if (response.goto_section) {
452
+ checkout.gotoSection(response.goto_section);
453
+ checkout.reloadProgressBlock();
454
+ return;
455
+ }
456
+
457
+ if (response.payment_methods_html) {
458
+ $('checkout-payment-method-load').update(response.payment_methods_html);
459
+ }
460
+
461
+ checkout.setShippingMethod();
462
+ }
463
+ }
skin/frontend/default/default/chronorelais/home.png ADDED
Binary file
skin/frontend/default/default/chronorelais/ico_ac_shaded.gif ADDED
Binary file