Temando_Temando - Version 1.0.0

Version Notes

Temando Shipping Extension – Starter Version
• Delivery options at checkout
• Shipping calculator at checkout
• Access multiple couriers
• Address verification
• Shipping label production
• Manifesting, connote and parcel tracking

Download this release

Release Info

Developer Temando
Extension Temando_Temando
Version 1.0.0
Comparing to
See all releases


Version 1.0.0

Files changed (147) hide show
  1. app/code/community/Temando/Temando/Block/Adminhtml/Manifest.php +29 -0
  2. app/code/community/Temando/Temando/Block/Adminhtml/Manifest/Filter/Form.php +51 -0
  3. app/code/community/Temando/Temando/Block/Adminhtml/Manifest/Grid.php +150 -0
  4. app/code/community/Temando/Temando/Block/Adminhtml/Manifest/Grid/Renderer/Checkbox.php +33 -0
  5. app/code/community/Temando/Temando/Block/Adminhtml/Shipment.php +15 -0
  6. app/code/community/Temando/Temando/Block/Adminhtml/Shipment/Edit.php +212 -0
  7. app/code/community/Temando/Temando/Block/Adminhtml/Shipment/Edit/Form.php +22 -0
  8. app/code/community/Temando/Temando/Block/Adminhtml/Shipment/Edit/Tab/Abstract.php +64 -0
  9. app/code/community/Temando/Temando/Block/Adminhtml/Shipment/Edit/Tab/Form.php +36 -0
  10. app/code/community/Temando/Temando/Block/Adminhtml/Shipment/Edit/Tab/Form/Anytime.php +8 -0
  11. app/code/community/Temando/Temando/Block/Adminhtml/Shipment/Edit/Tab/Form/Anywhere.php +8 -0
  12. app/code/community/Temando/Temando/Block/Adminhtml/Shipment/Edit/Tab/Form/Boxes.php +25 -0
  13. app/code/community/Temando/Temando/Block/Adminhtml/Shipment/Edit/Tab/Form/Insurance.php +38 -0
  14. app/code/community/Temando/Temando/Block/Adminhtml/Shipment/Edit/Tab/Form/Products.php +18 -0
  15. app/code/community/Temando/Temando/Block/Adminhtml/Shipment/Edit/Tab/Form/Quotes.php +61 -0
  16. app/code/community/Temando/Temando/Block/Adminhtml/Shipment/Edit/Tab/Form/Status.php +26 -0
  17. app/code/community/Temando/Temando/Block/Adminhtml/Shipment/Edit/Tabs.php +14 -0
  18. app/code/community/Temando/Temando/Block/Adminhtml/Shipment/Grid.php +101 -0
  19. app/code/community/Temando/Temando/Block/Adminhtml/System/Config/Form/Field/Insurance.php +84 -0
  20. app/code/community/Temando/Temando/Block/Adminhtml/System/Config/Form/Field/Required.php +47 -0
  21. app/code/community/Temando/Temando/Block/Adminhtml/System/Config/Form/Fieldset/General.php +24 -0
  22. app/code/community/Temando/Temando/Block/Cart/Shipping.php +99 -0
  23. app/code/community/Temando/Temando/Block/Onepage/Shipping/Method/Available.php +7 -0
  24. app/code/community/Temando/Temando/Block/Onepage/Shipping/Method/Available/Single.php +51 -0
  25. app/code/community/Temando/Temando/Block/Product/Shipping.php +80 -0
  26. app/code/community/Temando/Temando/Block/Product/Shipping/Methods.php +27 -0
  27. app/code/community/Temando/Temando/Helper/Data.php +433 -0
  28. app/code/community/Temando/Temando/Helper/Functions.php +76 -0
  29. app/code/community/Temando/Temando/Model/Api/Client.php +203 -0
  30. app/code/community/Temando/Temando/Model/Api/Request.php +191 -0
  31. app/code/community/Temando/Temando/Model/Api/Request/Anything.php +102 -0
  32. app/code/community/Temando/Temando/Model/Api/Request/Anythings.php +172 -0
  33. app/code/community/Temando/Temando/Model/Api/Request/Anytime.php +60 -0
  34. app/code/community/Temando/Temando/Model/Api/Request/Anywhere.php +46 -0
  35. app/code/community/Temando/Temando/Model/Box.php +35 -0
  36. app/code/community/Temando/Temando/Model/Carrier.php +54 -0
  37. app/code/community/Temando/Temando/Model/Entity/Attribute/Source/Packaging.php +63 -0
  38. app/code/community/Temando/Temando/Model/Entity/Attribute/Source/Packaging/Mode.php +64 -0
  39. app/code/community/Temando/Temando/Model/Manifest.php +12 -0
  40. app/code/community/Temando/Temando/Model/Mysql4/Box.php +11 -0
  41. app/code/community/Temando/Temando/Model/Mysql4/Box/Collection.php +12 -0
  42. app/code/community/Temando/Temando/Model/Mysql4/Carrier.php +11 -0
  43. app/code/community/Temando/Temando/Model/Mysql4/Carrier/Collection.php +12 -0
  44. app/code/community/Temando/Temando/Model/Mysql4/Manifest.php +11 -0
  45. app/code/community/Temando/Temando/Model/Mysql4/Manifest/Collection.php +12 -0
  46. app/code/community/Temando/Temando/Model/Mysql4/Quote.php +11 -0
  47. app/code/community/Temando/Temando/Model/Mysql4/Quote/Collection.php +127 -0
  48. app/code/community/Temando/Temando/Model/Mysql4/Shipment.php +11 -0
  49. app/code/community/Temando/Temando/Model/Mysql4/Shipment/Collection.php +29 -0
  50. app/code/community/Temando/Temando/Model/Observer.php +147 -0
  51. app/code/community/Temando/Temando/Model/Option/Abstract.php +204 -0
  52. app/code/community/Temando/Temando/Model/Option/Action/Abstract.php +13 -0
  53. app/code/community/Temando/Temando/Model/Option/Action/Carbon.php +15 -0
  54. app/code/community/Temando/Temando/Model/Option/Action/Footprints.php +15 -0
  55. app/code/community/Temando/Temando/Model/Option/Action/Insurance.php +15 -0
  56. app/code/community/Temando/Temando/Model/Option/Action/Markup.php +125 -0
  57. app/code/community/Temando/Temando/Model/Option/Boolean.php +46 -0
  58. app/code/community/Temando/Temando/Model/Option/Carbonoffset.php +78 -0
  59. app/code/community/Temando/Temando/Model/Option/Footprints.php +55 -0
  60. app/code/community/Temando/Temando/Model/Option/Insurance.php +78 -0
  61. app/code/community/Temando/Temando/Model/Options.php +118 -0
  62. app/code/community/Temando/Temando/Model/Pcs.php +106 -0
  63. app/code/community/Temando/Temando/Model/Quote.php +320 -0
  64. app/code/community/Temando/Temando/Model/Shipment.php +377 -0
  65. app/code/community/Temando/Temando/Model/Shipping/Carrier/Temando.php +503 -0
  66. app/code/community/Temando/Temando/Model/Shipping/Carrier/Temando/Source/Method.php +74 -0
  67. app/code/community/Temando/Temando/Model/Status.php +24 -0
  68. app/code/community/Temando/Temando/Model/System/Config/Backend/Form/Field/Required/Businessresidential.php +17 -0
  69. app/code/community/Temando/Temando/Model/System/Config/Backend/Form/Field/Required/Country.php +32 -0
  70. app/code/community/Temando/Temando/Model/System/Config/Backend/Form/Field/Required/Location.php +42 -0
  71. app/code/community/Temando/Temando/Model/System/Config/Backend/Form/Field/Required/Text.php +17 -0
  72. app/code/community/Temando/Temando/Model/System/Config/Source.php +82 -0
  73. app/code/community/Temando/Temando/Model/System/Config/Source/Carbon.php +19 -0
  74. app/code/community/Temando/Temando/Model/System/Config/Source/Client/Type.php +17 -0
  75. app/code/community/Temando/Temando/Model/System/Config/Source/Country.php +19 -0
  76. app/code/community/Temando/Temando/Model/System/Config/Source/Errorprocess.php +17 -0
  77. app/code/community/Temando/Temando/Model/System/Config/Source/Footprints.php +19 -0
  78. app/code/community/Temando/Temando/Model/System/Config/Source/Insurance.php +19 -0
  79. app/code/community/Temando/Temando/Model/System/Config/Source/Labeltype.php +19 -0
  80. app/code/community/Temando/Temando/Model/System/Config/Source/Origin/Type.php +17 -0
  81. app/code/community/Temando/Temando/Model/System/Config/Source/Payment.php +17 -0
  82. app/code/community/Temando/Temando/Model/System/Config/Source/Pricing.php +25 -0
  83. app/code/community/Temando/Temando/Model/System/Config/Source/Readytime.php +17 -0
  84. app/code/community/Temando/Temando/Model/System/Config/Source/Regions.php +23 -0
  85. app/code/community/Temando/Temando/Model/System/Config/Source/Rule/Action/Adjustment/Type.php +27 -0
  86. app/code/community/Temando/Temando/Model/System/Config/Source/Rule/Action/Filter.php +21 -0
  87. app/code/community/Temando/Temando/Model/System/Config/Source/Rule/Condition/Time.php +18 -0
  88. app/code/community/Temando/Temando/Model/System/Config/Source/Rule/Condition/Type.php +18 -0
  89. app/code/community/Temando/Temando/Model/System/Config/Source/Rule/Type.php +20 -0
  90. app/code/community/Temando/Temando/Model/System/Config/Source/Sales/Order/Status.php +25 -0
  91. app/code/community/Temando/Temando/Model/System/Config/Source/Shipment/Class.php +27 -0
  92. app/code/community/Temando/Temando/Model/System/Config/Source/Shipment/Packaging.php +38 -0
  93. app/code/community/Temando/Temando/Model/System/Config/Source/Shipment/Packaging/Mode.php +16 -0
  94. app/code/community/Temando/Temando/Model/System/Config/Source/Shipment/Service.php +19 -0
  95. app/code/community/Temando/Temando/Model/System/Config/Source/Shipment/Status.php +17 -0
  96. app/code/community/Temando/Temando/Model/System/Config/Source/Unit.php +56 -0
  97. app/code/community/Temando/Temando/Model/System/Config/Source/Unit/Measure.php +31 -0
  98. app/code/community/Temando/Temando/Model/System/Config/Source/Unit/Weight.php +31 -0
  99. app/code/community/Temando/Temando/controllers/Adminhtml/JsonController.php +55 -0
  100. app/code/community/Temando/Temando/controllers/Adminhtml/ManifestController.php +238 -0
  101. app/code/community/Temando/Temando/controllers/Adminhtml/ShipmentController.php +521 -0
  102. app/code/community/Temando/Temando/controllers/PcsController.php +313 -0
  103. app/code/community/Temando/Temando/etc/adminhtml.xml +82 -0
  104. app/code/community/Temando/Temando/etc/config.xml +194 -0
  105. app/code/community/Temando/Temando/etc/system.xml +633 -0
  106. app/code/community/Temando/Temando/sql/temando_setup/mysql4-install-1.0.0.php +303 -0
  107. app/design/adminhtml/default/default/layout/temando.xml +53 -0
  108. app/design/adminhtml/default/default/template/temando/temando/manifest.phtml +27 -0
  109. app/design/adminhtml/default/default/template/temando/temando/origin-avs.phtml +11 -0
  110. app/design/adminhtml/default/default/template/temando/temando/region.phtml +123 -0
  111. app/design/adminhtml/default/default/template/temando/temando/shipment.phtml +23 -0
  112. app/design/adminhtml/default/default/template/temando/temando/shipment/anytime.phtml +76 -0
  113. app/design/adminhtml/default/default/template/temando/temando/shipment/anywhere.phtml +103 -0
  114. app/design/adminhtml/default/default/template/temando/temando/shipment/boxes.phtml +165 -0
  115. app/design/adminhtml/default/default/template/temando/temando/shipment/insurance.phtml +54 -0
  116. app/design/adminhtml/default/default/template/temando/temando/shipment/products.phtml +56 -0
  117. app/design/adminhtml/default/default/template/temando/temando/shipment/quotes.phtml +60 -0
  118. app/design/adminhtml/default/default/template/temando/temando/shipment/status.phtml +46 -0
  119. app/design/frontend/base/default/layout/temando.xml +91 -0
  120. app/design/frontend/base/default/template/temando/temando/checkout/cart/shipping.phtml +132 -0
  121. app/design/frontend/base/default/template/temando/temando/customer/address/edit.phtml +175 -0
  122. app/design/frontend/base/default/template/temando/temando/onestep/options.phtml +85 -0
  123. app/design/frontend/base/default/template/temando/temando/onestep/shipping_method.phtml +66 -0
  124. app/design/frontend/base/default/template/temando/temando/pcs.phtml +19 -0
  125. app/design/frontend/base/default/template/temando/temando/product/shipping.phtml +53 -0
  126. app/design/frontend/base/default/template/temando/temando/product/shipping/methods.phtml +27 -0
  127. app/design/frontend/base/default/template/temando/temando/shipping_method/available.phtml +2 -0
  128. app/design/frontend/base/default/template/temando/temando/shipping_method/available/options_single.phtml +108 -0
  129. app/etc/modules/Temando_Temando.xml +9 -0
  130. js/temando/autocomplete.js +338 -0
  131. js/temando/avs.js +61 -0
  132. package.xml +43 -0
  133. skin/adminhtml/default/default/js/temando.js +54 -0
  134. skin/adminhtml/default/default/temando/images/ajax-s-load.gif +0 -0
  135. skin/adminhtml/default/default/temando/images/bg_notifications.gif +0 -0
  136. skin/adminhtml/default/default/temando/images/shadow.png +0 -0
  137. skin/adminhtml/default/default/temando/images/temando_logo.jpg +0 -0
  138. skin/adminhtml/default/default/temando/styles.css +41 -0
  139. skin/frontend/base/default/css/temando/autocomplete.css +8 -0
  140. skin/frontend/base/default/css/temando/images/ajax-s-load.gif +0 -0
  141. skin/frontend/base/default/css/temando/images/find_ext.png +0 -0
  142. skin/frontend/base/default/css/temando/images/i_shipping.gif +0 -0
  143. skin/frontend/base/default/css/temando/images/shadow.png +0 -0
  144. skin/frontend/base/default/css/temando/product.css +39 -0
  145. skin/frontend/base/default/css/temando/styles.css +43 -0
  146. skin/frontend/base/default/js/temando/checkout.js +239 -0
  147. skin/frontend/base/default/js/temando/product.js +161 -0
app/code/community/Temando/Temando/Block/Adminhtml/Manifest.php ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class Temando_Temando_Block_Adminhtml_Manifest extends Mage_Adminhtml_Block_Widget_Grid_Container
3
+ {
4
+
5
+ public function __construct()
6
+ {
7
+ $this->_blockGroup = 'temando';
8
+ $this->_controller = 'adminhtml_manifest';
9
+ $this->_headerText = Mage::helper('temando')->__('Manage Shipments');
10
+ parent::__construct();
11
+ $this->setTemplate('temando/temando/manifest.phtml');
12
+ $this->removeButton('add');
13
+
14
+ $add_button_method = 'addButton';
15
+ if (!method_exists($this, $add_button_method)) {
16
+ $add_button_method = '_addButton';
17
+ }
18
+
19
+ $this->$add_button_method('add_form_submit', array(
20
+ 'label' => Mage::helper('temando')->__('Add Manifest'),
21
+ 'onclick' => 'addFormSubmit()'
22
+ ));
23
+ $this->$add_button_method('confirm', array(
24
+ 'label' => Mage::helper('temando')->__('confirm Manifests'),
25
+ 'onclick' => 'setLocation(\'' . $this->getUrl('*/*/confirm') .'\')',
26
+ ));
27
+ }
28
+
29
+ }
app/code/community/Temando/Temando/Block/Adminhtml/Manifest/Filter/Form.php ADDED
@@ -0,0 +1,51 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Temando_Temando_Block_Adminhtml_Manifest_Filter_Form extends Mage_Adminhtml_Block_Widget_Form
4
+ {
5
+ /**
6
+ * Add fields to base fieldset which are general to sales reports
7
+ *
8
+ * @return Mage_Sales_Block_Adminhtml_Report_Filter_Form
9
+ */
10
+ protected function _prepareForm()
11
+ {
12
+ $actionUrl = $this->getUrl('*/*/add');
13
+ $form = new Varien_Data_Form(
14
+ array('id' => 'add_form', 'action' => $actionUrl, 'method' => 'post')
15
+ );
16
+ $htmlIdPrefix = 'add_manifest_';
17
+ $form->setHtmlIdPrefix($htmlIdPrefix);
18
+ $fieldset = $form->addFieldset('base_fieldset', array('legend'=>Mage::helper('temando')->__('Create New Manifest')));
19
+
20
+ $dateFormatIso = Mage::app()->getLocale()->getDateFormat(Mage_Core_Model_Locale::FORMAT_TYPE_SHORT);
21
+
22
+ $fieldset->addField('warehouse_id', 'select', array(
23
+ 'name' => 'warehouse_id',
24
+ 'options' => Mage::helper('temando')->getLocationList(),
25
+ 'label' => Mage::helper('temando')->__('Location'),
26
+ 'title' => Mage::helper('temando')->__('Location')
27
+ ));
28
+
29
+ $fieldset->addField('carrier_id', 'multiselect', array(
30
+ 'name' => 'carrier_id[]',
31
+ 'values' => Mage::getModel('temando/shipping_carrier_temando_source_method')->toOptionArray(),
32
+ 'label' => Mage::helper('temando')->__('Carrier'),
33
+ 'required' => true
34
+ ));
35
+
36
+ $fieldset->addField('from', 'date', array(
37
+ 'name' => 'from',
38
+ 'format' => $dateFormatIso,
39
+ 'image' => $this->getSkinUrl('images/grid-cal.gif'),
40
+ 'label' => Mage::helper('temando')->__('Date'),
41
+ 'title' => Mage::helper('temando')->__('Date'),
42
+ 'time' => false,
43
+ 'required' => true
44
+ ));
45
+
46
+ $form->setUseContainer(true);
47
+ $this->setForm($form);
48
+
49
+ return parent::_prepareForm();
50
+ }
51
+ }
app/code/community/Temando/Temando/Block/Adminhtml/Manifest/Grid.php ADDED
@@ -0,0 +1,150 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Temando_Temando_Block_Adminhtml_Manifest_Grid extends Mage_Adminhtml_Block_Widget_Grid
4
+ {
5
+
6
+ public function __construct()
7
+ {
8
+ parent::__construct();
9
+ $this->setDefaultSort('created_at');
10
+ $this->setDefaultDir('DESC');
11
+ $this->setSaveParametersInSession(true);
12
+ }
13
+
14
+ protected function _prepareCollection()
15
+ {
16
+ $collection = Mage::getModel('temando/manifest')->getCollection();
17
+ /* @var $collection Temando_Temando_Model_Manifest */
18
+ $this->setCollection($collection);
19
+ return parent::_prepareCollection();
20
+ }
21
+
22
+ protected function _prepareColumns()
23
+ {
24
+
25
+ $this->addColumn('created_at', array(
26
+ 'header' => Mage::helper('temando')->__('Created At'),
27
+ 'width' => '100px',
28
+ 'type' => 'datetime',
29
+ 'index' => 'created_at',
30
+ ));
31
+
32
+ $this->addColumn('location_id', array(
33
+ 'header' => Mage::helper('temando')->__('Location'),
34
+ 'index' => 'location_id',
35
+ 'type' => 'text',
36
+ 'width' => '200px',
37
+ ));
38
+
39
+ $this->addColumn('carrier_id', array(
40
+ 'header' => Mage::helper('temando')->__('Carrier'),
41
+ 'index' => 'carrier_id',
42
+ 'type' => 'options',
43
+ 'width' => '100px',
44
+ 'options' => Mage::getModel('temando/shipping_carrier_temando_source_method')->getOptions(),
45
+ ));
46
+
47
+ $this->addColumn('start_date', array(
48
+ 'header' => Mage::helper('temando')->__('Date'),
49
+ 'width' => '100px',
50
+ 'type' => 'date',
51
+ 'index' => 'start_date',
52
+ ));
53
+
54
+ $this->addColumn('status', array(
55
+ 'header' => Mage::helper('temando')->__('Type'),
56
+ 'index' => 'type',
57
+ 'type' => 'options',
58
+ 'width' => '100px',
59
+ 'options' => array('Awaiting Confirmation' => 'Awaiting Confirmation', 'Confirmed' => 'Confirmed'),
60
+ ));
61
+
62
+ $this->addColumn('action_man',
63
+ array(
64
+ 'header' => Mage::helper('temando')->__('Manifest Document'),
65
+ 'width' => '100',
66
+ 'type' => 'action',
67
+ 'getter' => 'getId',
68
+ 'actions' => array(
69
+ array(
70
+ 'caption' => Mage::helper('temando')->__('Download'),
71
+ 'url' => array('base'=> '*/*/manifest'),
72
+ 'field' => 'id'
73
+ ),
74
+ ),
75
+ 'filter' => false,
76
+ 'sortable' => false,
77
+ 'is_system' => true,
78
+ ));
79
+
80
+ $this->addColumn('action_lab',
81
+ array(
82
+ 'header' => Mage::helper('temando')->__('Label Document'),
83
+ 'width' => '100',
84
+ 'type' => 'action',
85
+ 'getter' => 'getId',
86
+ 'actions' => array(
87
+ array(
88
+ 'caption' => Mage::helper('temando')->__('Download'),
89
+ 'url' => array('base'=> '*/*/label'),
90
+ 'field' => 'id'
91
+ ),
92
+ ),
93
+ 'filter' => false,
94
+ 'sortable' => false,
95
+ 'is_system' => true,
96
+ ));
97
+
98
+ return parent::_prepareColumns();
99
+ }
100
+
101
+ public function getRowUrl($row)
102
+ {
103
+ }
104
+
105
+ protected function _prepareMassaction___()
106
+ {
107
+ $this->setMassactionIdField('manifest_id');
108
+ $this->getMassactionBlock()->setFormFieldName('manifest');
109
+
110
+ $this->getMassactionBlock()->addItem('confirm', array(
111
+ 'label'=> Mage::helper('catalog')->__('Confirm'),
112
+ 'url' => $this->getUrl('*/*/massConfirm'),
113
+ 'confirm' => Mage::helper('temando')->__('Are you sure?')
114
+ ));
115
+ }
116
+
117
+ /**
118
+ * Prepare grid massaction column
119
+ *
120
+ * @return unknown
121
+ */
122
+ protected function _prepareMassactionColumn()
123
+ {
124
+ $columnId = 'massaction';
125
+ $massactionColumn = $this->getLayout()->createBlock('adminhtml/widget_grid_column')
126
+ ->setData(array(
127
+ 'index' => $this->getMassactionIdField(),
128
+ 'type' => 'massaction',
129
+ 'name' => $this->getMassactionBlock()->getFormFieldName(),
130
+ 'align' => 'center',
131
+ 'is_system' => true,
132
+ 'renderer' => 'temando/adminhtml_manifest_grid_renderer_checkbox',
133
+ ));
134
+
135
+ if ($this->getNoFilterMassactionColumn()) {
136
+ $massactionColumn->setData('filter', false);
137
+ }
138
+
139
+ $massactionColumn->setSelected($this->getMassactionBlock()->getSelected())
140
+ ->setGrid($this)
141
+ ->setId($columnId);
142
+
143
+ $oldColumns = $this->_columns;
144
+ $this->_columns = array();
145
+ $this->_columns[$columnId] = $massactionColumn;
146
+ $this->_columns = array_merge($this->_columns, $oldColumns);
147
+ return $this;
148
+ }
149
+
150
+ }
app/code/community/Temando/Temando/Block/Adminhtml/Manifest/Grid/Renderer/Checkbox.php ADDED
@@ -0,0 +1,33 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Temando_Temando_Block_Adminhtml_Manifest_Grid_Renderer_Checkbox extends Mage_Adminhtml_Block_Widget_Grid_Column_Renderer_Massaction
4
+ {
5
+
6
+ protected function _getCheckboxHtml($value, $checked)
7
+ {
8
+ $disabled = '';
9
+ $checked = ' checked="checked"';
10
+ if ($this->getDisabledRow()) {
11
+ $disabled = ' disabled="disabled"';
12
+ $checked = '';
13
+ }
14
+
15
+ return '<input type="checkbox" name="'.$this->getColumn()->getName().'" value="' . $value . '" class="massaction-checkbox"'.$checked.$disabled.' />';
16
+ }
17
+ /**
18
+ * Renders grid column
19
+ *
20
+ * @param Varien_Object $row
21
+ * @return string
22
+ */
23
+ public function render(Varien_Object $row)
24
+ {
25
+ if ($row->getType() == 'Confirmed') {
26
+ $this->setDisabledRow(true);
27
+ }
28
+
29
+ return parent::render($row);
30
+ }
31
+
32
+ }
33
+
app/code/community/Temando/Temando/Block/Adminhtml/Shipment.php ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Temando_Temando_Block_Adminhtml_Shipment extends Mage_Adminhtml_Block_Widget_Grid_Container
4
+ {
5
+
6
+ public function __construct()
7
+ {
8
+ $this->_blockGroup = 'temando';
9
+ $this->_controller = 'adminhtml_shipment';
10
+ $this->_headerText = Mage::helper('temando')->__('Manage Shipments');
11
+ parent::__construct();
12
+ $this->removeButton('add');
13
+ }
14
+
15
+ }
app/code/community/Temando/Temando/Block/Adminhtml/Shipment/Edit.php ADDED
@@ -0,0 +1,212 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Temando_Temando_Block_Adminhtml_Shipment_Edit extends Mage_Adminhtml_Block_Widget_Form_Container
4
+ {
5
+
6
+ protected $_shipment;
7
+
8
+ public function __construct()
9
+ {
10
+ parent::__construct();
11
+ $this->_blockGroup = 'temando';
12
+ $this->_controller = 'adminhtml_shipment';
13
+
14
+ $this->removeButton('save');
15
+ $this->removeButton('delete');
16
+
17
+ $add_button_method = 'addButton';
18
+ if (!method_exists($this, $add_button_method)) {
19
+ $add_button_method = '_addButton';
20
+ }
21
+
22
+ if ($this->getShipment()->getStatus() == Temando_Temando_Model_System_Config_Source_Shipment_Status::PENDING) {
23
+ $this->$add_button_method('getquote', array(
24
+ 'label' => Mage::helper('temando')->__('Save and Get Quotes'),
25
+ 'id' => 'getquote',
26
+ 'onclick' => 'saveAndGetQuotes()',
27
+ 'value' => '',
28
+ 'class' => 'save',
29
+ ));
30
+ }
31
+
32
+ if ($this->getShipment()->getStatus() == Temando_Temando_Model_System_Config_Source_Shipment_Status::BOOKED) {
33
+ $class = 'go';
34
+ $title = Mage::helper('temando')->__('View Consignment');
35
+
36
+ $labelType = Mage::helper('temando')->getConfigData('options/label_type');
37
+ $hasConsignment = true;
38
+
39
+ if ((!$this->getShipment()->getConsignmentDocument() && $labelType == Temando_Temando_Model_System_Config_Source_Labeltype::STANDARD) ||
40
+ (!$this->getShipment()->getLabelDocument() && $labelType == Temando_Temando_Model_System_Config_Source_Labeltype::THERMAL)) {
41
+ $class .= ' disabled';
42
+ $hasConsignment = false;
43
+ $title = Mage::helper('temando')->__('No Consignment');
44
+ }
45
+
46
+ $this->$add_button_method('consignment', array(
47
+ 'label' => $title,
48
+ 'id' => 'consignment',
49
+ 'onclick' => $hasConsignment ? "window.location = '" . $this->getUrl('*/*/consignment', array('id' => $this->getRequest()->getParam('id'))) . "'" : "",
50
+ 'value' => '',
51
+ 'class' => $class,
52
+ ));
53
+
54
+ $this->_removeButton('reset');
55
+ }
56
+
57
+ $max_boxes = 40;
58
+ $script = "
59
+ function saveAndGetQuotes() {
60
+ editForm.submit($('edit_form').action+'and/getquotes/');
61
+ }
62
+
63
+ function saveAndEditNext() {
64
+ editForm.submit($('edit_form').action+'and/editnext/');
65
+ }
66
+
67
+ function box_add() {
68
+ num_boxes = $$('table#boxes tbody tr').length - 1;
69
+ if (num_boxes < $max_boxes) {
70
+ if (!box_add.highest_num) {
71
+ box_add.highest_num = num_boxes;
72
+ }
73
+ // add a new box (row) to the table
74
+ new_row = new Element('tr');
75
+ new_row.id = 'box_row_' + ++box_add.highest_num;
76
+ new_row
77
+ .addClassName(box_add.highest_num % 2 ? 'odd' : 'even')
78
+ .addClassName('new_box')
79
+ .insert($('blank_box_row').innerHTML
80
+ .replace(/@@id@@/g, box_add.highest_num)
81
+ .replace(/box_blank/g, 'box'));
82
+
83
+ $$('table#boxes tbody')[0].insert(new_row);
84
+ return box_add.highest_num;
85
+ } else {
86
+ return false;
87
+ }
88
+ }
89
+
90
+ function box_clear() {
91
+ // remove all rows in the table.
92
+ $$('table#boxes tr.existing_box, table#boxes tr.new_box').each(function (row) {
93
+ row.remove();
94
+ });
95
+ }
96
+
97
+ function box_remove(num) {
98
+ row = $('box_row_' + num);
99
+ if ($('box_' + num + '_id') && $('boxes_deleted')) {
100
+ if (!$('boxes_deleted').value.length == 0) {
101
+ $('boxes_deleted').value += ',';
102
+ }
103
+ $('boxes_deleted').value += $('box_' + num + '_id').value;
104
+ }
105
+ if (row) {
106
+ row.remove();
107
+ }
108
+ }
109
+
110
+ function box_import() {
111
+ default_boxes = new Array();
112
+ {$this->_getProductsJson('default_boxes')}
113
+ for (var i = 0; i < default_boxes.length; i++) {
114
+ box = default_boxes[i];
115
+ num = box_add();
116
+ if (num) {
117
+ $('box_' + num + '_comment').value = box.comment;
118
+ $('box_' + num + '_packaging').value = box.packaging;
119
+ $('box_' + num + '_fragile').value = box.fragile;
120
+ $('box_' + num + '_qty').value = box.qty;
121
+ $('box_' + num + '_value').value = box.value;
122
+ $('box_' + num + '_weight').value = box.weight;
123
+ $('box_' + num + '_weight_unit').value = box.weight_unit;
124
+ $('box_' + num + '_height').value = box.height;
125
+ $('box_' + num + '_length').value = box.length;
126
+ $('box_' + num + '_width').value = box.width;
127
+ $('box_' + num + '_measure_unit').value = box.measure_unit;
128
+ }
129
+ }
130
+ }
131
+ ";
132
+
133
+ $this->_formScripts[] = $script;
134
+ }
135
+
136
+ /**
137
+ * Gets the shipment being edited.
138
+ *
139
+ * @return Temando_Temando_Model_Shipment
140
+ */
141
+ public function getShipment()
142
+ {
143
+ if (!$this->_shipment) {
144
+ $this->_shipment = Mage::registry('temando_shipment_data');
145
+ }
146
+ return $this->_shipment;
147
+ }
148
+
149
+ /**
150
+ * Gets the current order for the shipment being edited.
151
+ *
152
+ * @return Mage_Sales_Model_Order
153
+ */
154
+ public function getOrder()
155
+ {
156
+ if($this->getShipment()) {
157
+ return $this->getShipment()->getOrder();
158
+ }
159
+ return null;
160
+ }
161
+
162
+ public function getHeaderText()
163
+ {
164
+ if ($this->getShipment() && $this->getShipment()->getId()) {
165
+ return $foo= Mage::helper('temando')->__(
166
+ 'Order # %s | %s',
167
+ $this->htmlEscape($this->getShipment()->getOrder()->getRealOrderId()),
168
+ $this->htmlEscape($this->formatDate($this->getShipment()->getOrder()->getCreatedAtDate(), 'medium', true))
169
+ );
170
+ }
171
+ }
172
+
173
+ protected function _getProductsJson($variable_name)
174
+ {
175
+ $products = '';
176
+ foreach ($this->getShipment()->getOrder()->getAllItems() as $item) {
177
+ if ($item->getParentItemId()) {
178
+ // do not create box for child products
179
+ continue;
180
+ }
181
+ /* @var $item Mage_Sales_Model_Order_Item */
182
+ $product = Mage::getModel('catalog/product')->load($item->getProductId());
183
+ /* @var $product Mage_Catalog_Model_Product */
184
+ $helper = Mage::helper('temando');
185
+ /* @var $helper Temando_Temando_Helper_Data */
186
+ $weight = (float) $product->getWeight();
187
+ $height = (float) $product->getTemandoHeight();
188
+ $length = (float) $product->getTemandoLength();
189
+ $width = (float) $product->getTemandoWidth();
190
+ $packaging = $product->getTemandoPackaging();
191
+ $fragile = $product->getTemandoFragile();
192
+
193
+ $products .= "
194
+ $variable_name.push({
195
+ 'comment': '" . addslashes($product->getName()) . "',
196
+ 'packaging': '{$packaging}',
197
+ 'fragile': '{$fragile}',
198
+ 'qty': '{$item->getQtyToShip()}',
199
+ 'value': '{$item->getRowTotal()}',
200
+ 'weight': '$weight',
201
+ 'weight_unit': '{$helper->getConfigData('units/weight')}',
202
+ 'height': '$height',
203
+ 'length': '$length',
204
+ 'width': '$width',
205
+ 'measure_unit': '{$helper->getConfigData('units/measure')}'
206
+ });
207
+ ";
208
+ }
209
+ return $products;
210
+ }
211
+
212
+ }
app/code/community/Temando/Temando/Block/Adminhtml/Shipment/Edit/Form.php ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Temando_Temando_Block_Adminhtml_Shipment_Edit_Form extends Mage_Adminhtml_Block_Widget_Form
4
+ {
5
+
6
+ protected function _prepareForm()
7
+ {
8
+ $form = new Varien_Data_Form(
9
+ array(
10
+ 'id' => 'edit_form',
11
+ 'action' => $this->getUrl('*/*/save', array('id' => $this->getRequest()->getParam('id'))),
12
+ 'method' => 'post',
13
+ 'enctype' => 'multipart/form-data'
14
+ )
15
+ );
16
+
17
+ $form->setUseContainer(true);
18
+ $this->setForm($form);
19
+ return parent::_prepareForm();
20
+ }
21
+
22
+ }
app/code/community/Temando/Temando/Block/Adminhtml/Shipment/Edit/Tab/Abstract.php ADDED
@@ -0,0 +1,64 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ abstract class Temando_Temando_Block_Adminhtml_Shipment_Edit_Tab_Abstract extends Mage_Adminhtml_Block_Template
4
+ {
5
+
6
+ protected $_helper = null;
7
+
8
+ public function __construct()
9
+ {
10
+ parent::__construct();
11
+ $this->setParentBlock(Mage::getBlockSingleton('temando/adminhtml_shipment_edit'));
12
+ }
13
+
14
+ /**
15
+ * Gets the shipment being edited.
16
+ *
17
+ * @return Temando_Temando_Model_Shipment
18
+ */
19
+ public function getShipment()
20
+ {
21
+ return $this->getParentBlock()->getShipment();
22
+ }
23
+
24
+ /**
25
+ * Gets the saved Temando quotes for this order from the database.
26
+ *
27
+ * @return Temando_Temando_Model_Mysql4_Quote_Collection
28
+ */
29
+ public function getQuotes()
30
+ {
31
+ return $this->getShipment()->getQuotes(true);
32
+ }
33
+
34
+ public function formatCurrency($price)
35
+ {
36
+ return Mage::helper('core')->currency($price);
37
+ }
38
+
39
+ public function getWeightUnitText($unit = null)
40
+ {
41
+ if (!$unit) {
42
+ $unit = $this->getTemandoHelper()->getConfigData('units/weight');
43
+ }
44
+ return Mage::getModel('temando/system_config_source_unit_weight')
45
+ ->getBriefOptionLabel($unit);
46
+ }
47
+
48
+ public function getMeasureUnitText($unit = null)
49
+ {
50
+ if (!$unit) {
51
+ $unit = $this->getTemandoHelper()->getConfigData('units/measure');
52
+ }
53
+ return Mage::getModel('temando/system_config_source_unit_measure')
54
+ ->getBriefOptionLabel($unit);
55
+ }
56
+
57
+ public function getTemandoHelper() {
58
+ if (!$this->_helper) {
59
+ $this->_helper = Mage::helper('temando');
60
+ }
61
+ return $this->_helper;
62
+ }
63
+
64
+ }
app/code/community/Temando/Temando/Block/Adminhtml/Shipment/Edit/Tab/Form.php ADDED
@@ -0,0 +1,36 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Temando_Temando_Block_Adminhtml_Shipment_Edit_Tab_Form
4
+ extends Temando_Temando_Block_Adminhtml_Shipment_Edit_Tab_Abstract
5
+ implements Mage_Adminhtml_Block_Widget_Tab_Interface
6
+ {
7
+
8
+ protected $_template = 'temando/temando/shipment.phtml';
9
+
10
+ public function __construct()
11
+ {
12
+ parent::__construct();
13
+ $this->setTemplate($this->_template);
14
+ }
15
+
16
+ public function getTabLabel()
17
+ {
18
+ return $this->__('Information');
19
+ }
20
+
21
+ public function getTabTitle()
22
+ {
23
+ return $this->__('Information');
24
+ }
25
+
26
+ public function canShowTab()
27
+ {
28
+ return true;
29
+ }
30
+
31
+ public function isHidden()
32
+ {
33
+ return false;
34
+ }
35
+
36
+ }
app/code/community/Temando/Temando/Block/Adminhtml/Shipment/Edit/Tab/Form/Anytime.php ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Temando_Temando_Block_Adminhtml_Shipment_Edit_Tab_Form_Anytime extends Temando_Temando_Block_Adminhtml_Shipment_Edit_Tab_Abstract
4
+ {
5
+
6
+
7
+
8
+ }
app/code/community/Temando/Temando/Block/Adminhtml/Shipment/Edit/Tab/Form/Anywhere.php ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Temando_Temando_Block_Adminhtml_Shipment_Edit_Tab_Form_Anywhere extends Temando_Temando_Block_Adminhtml_Shipment_Edit_Tab_Abstract
4
+ {
5
+
6
+
7
+
8
+ }
app/code/community/Temando/Temando/Block/Adminhtml/Shipment/Edit/Tab/Form/Boxes.php ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Temando_Temando_Block_Adminhtml_Shipment_Edit_Tab_Form_Boxes extends Temando_Temando_Block_Adminhtml_Shipment_Edit_Tab_Abstract
4
+ {
5
+
6
+ /**
7
+ * Array of all available packaging types (default & custom)
8
+ *
9
+ * @var array
10
+ */
11
+ protected $_packagingTypes = null;
12
+
13
+ /**
14
+ * Returns array of all available packaging types
15
+ */
16
+ public function getPackagingTypes()
17
+ {
18
+ if(is_null($this->_packagingTypes)) {
19
+ $this->_packagingTypes = Mage::getModel('temando/system_config_source_shipment_packaging')->toOptionArray();
20
+ }
21
+
22
+ return $this->_packagingTypes;
23
+ }
24
+
25
+ }
app/code/community/Temando/Temando/Block/Adminhtml/Shipment/Edit/Tab/Form/Insurance.php ADDED
@@ -0,0 +1,38 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Temando_Temando_Block_Adminhtml_Shipment_Edit_Tab_Form_Insurance extends Temando_Temando_Block_Adminhtml_Shipment_Edit_Tab_Abstract
4
+ {
5
+
6
+ public function getTotalGoodsValue()
7
+ {
8
+ $order_id = $this->getShipment()->getOrderId();
9
+ $goods_value = 0;
10
+ foreach (Mage::getModel('sales/order')->load($order_id)->getAllVisibleItems() as $item) {
11
+ $value = $item->getValue();
12
+ if (!$value) {
13
+ $value = $item->getRowTotal();
14
+ }
15
+ if (!$value) {
16
+ $qty = $item->getQty();
17
+ if (!$qty) {
18
+ $qty = $item->getQtyOrdered();
19
+ }
20
+ $value = $item->getPrice() * $qty;
21
+ }
22
+
23
+ $goods_value += $value;
24
+ }
25
+
26
+ return $goods_value;
27
+ }
28
+
29
+ public function isAdminSelect()
30
+ {
31
+ if ($this->getShipment() && !is_null(Mage::getSingleton('adminhtml/session')->getData('insurance_' . $this->getShipment()->getId()))) {
32
+ return true;
33
+ }
34
+
35
+ return false;
36
+ }
37
+
38
+ }
app/code/community/Temando/Temando/Block/Adminhtml/Shipment/Edit/Tab/Form/Products.php ADDED
@@ -0,0 +1,18 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Temando_Temando_Block_Adminhtml_Shipment_Edit_Tab_Form_Products extends Temando_Temando_Block_Adminhtml_Shipment_Edit_Tab_Abstract
4
+ {
5
+
6
+ /**
7
+ * Gets a Magento catalog product belonging to a Magento order item.
8
+ *
9
+ * @param Mage_Sales_Model_Order_Item $item the Magento order item
10
+ *
11
+ * @return Mage_Catalog_Model_Product
12
+ */
13
+ public function getProductFromItem(Mage_Sales_Model_Order_Item $item)
14
+ {
15
+ return Mage::getModel('catalog/product')->load($item->getProductId());
16
+ }
17
+
18
+ }
app/code/community/Temando/Temando/Block/Adminhtml/Shipment/Edit/Tab/Form/Quotes.php ADDED
@@ -0,0 +1,61 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Temando_Temando_Block_Adminhtml_Shipment_Edit_Tab_Form_Quotes extends Temando_Temando_Block_Adminhtml_Shipment_Edit_Tab_Abstract
4
+ {
5
+
6
+ protected $_cheapest_quote_id;
7
+ protected $_fastest_quote_id;
8
+ protected $_customer_selected_quote_id;
9
+
10
+ public function __construct() {
11
+ parent::__construct();
12
+ if (($quotes = $this->getQuotes()->load())) {
13
+ if(($cheapest_quote = $quotes->getCheapest())) {
14
+ $this->_cheapest_quote_id = $cheapest_quote->getId();
15
+ }
16
+ if(($fastest_quote = $quotes->getFastest())) {
17
+ $this->_fastest_quote_id = $fastest_quote->getId();
18
+ }
19
+ }
20
+
21
+ if ($this->getShipment()) {
22
+ $this->_customer_selected_quote_id = $this->getShipment()->getCustomerSelectedQuoteId();
23
+ }
24
+ }
25
+
26
+ public function formatQuotePrice(Temando_Temando_Model_Quote $quote)
27
+ {
28
+ return
29
+ $quote->getCurrency() . ' ' .
30
+ $this->formatCurrency($quote->getTotalPrice()) .
31
+ ' (inc. ' .
32
+ $this->formatCurrency($quote->getTax()) .
33
+ ' tax)';
34
+ }
35
+
36
+ public function getQuoteNotes(Temando_Temando_Model_Quote $quote)
37
+ {
38
+ $text = '';
39
+
40
+ if ($this->_cheapest_quote_id == $quote->getId()) {
41
+ $text .= 'Cheapest';
42
+ }
43
+
44
+ if ($this->_fastest_quote_id == $quote->getId()) {
45
+ if ($text) {
46
+ $text .= ', ';
47
+ }
48
+ $text .= 'Fastest';
49
+ }
50
+
51
+ if ($this->_customer_selected_quote_id == $quote->getId()) {
52
+ if ($text) {
53
+ $text .= ', ';
54
+ }
55
+ $text .= 'Customer Selected';
56
+ }
57
+
58
+ return $text;
59
+ }
60
+
61
+ }
app/code/community/Temando/Temando/Block/Adminhtml/Shipment/Edit/Tab/Form/Status.php ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Temando_Temando_Block_Adminhtml_Shipment_Edit_Tab_Form_Status extends Temando_Temando_Block_Adminhtml_Shipment_Edit_Tab_Abstract
4
+ {
5
+ /**
6
+ * @var Temando_Temando_Model_Quote
7
+ */
8
+ protected $_customer_selected_quote = null;
9
+
10
+ /**
11
+ * Gets the description of the Temando quote selected by the customer.
12
+ *
13
+ * @return Temando_Temando_Model_Quote
14
+ */
15
+ public function getCustomerSelectedQuoteDescription()
16
+ {
17
+ return $this->getShipment()->getCustomerSelectedQuoteDescription();
18
+ }
19
+
20
+ public function getShipmentStatusText()
21
+ {
22
+ return Mage::getModel('temando/system_config_source_shipment_status')
23
+ ->getOptionLabel($this->getShipment()->getStatus());
24
+ }
25
+
26
+ }
app/code/community/Temando/Temando/Block/Adminhtml/Shipment/Edit/Tabs.php ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Temando_Temando_Block_Adminhtml_Shipment_Edit_Tabs extends Mage_Adminhtml_Block_Widget_Tabs
4
+ {
5
+
6
+ public function __construct()
7
+ {
8
+ parent::__construct();
9
+ $this->setId('temando_shipment_edit_tabs');
10
+ $this->setDestElementId('edit_form');
11
+ $this->setTitle(Mage::helper('temando')->__('Shipment View'));
12
+ }
13
+
14
+ }
app/code/community/Temando/Temando/Block/Adminhtml/Shipment/Grid.php ADDED
@@ -0,0 +1,101 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Temando_Temando_Block_Adminhtml_Shipment_Grid extends Mage_Adminhtml_Block_Widget_Grid
4
+ {
5
+
6
+ public function __construct()
7
+ {
8
+ parent::__construct();
9
+ $this->setSaveParametersInSession(true);
10
+ }
11
+
12
+ protected function _prepareCollection()
13
+ {
14
+ $collection = Mage::getModel('temando/shipment')->getCollection();
15
+ $collection->join('sales/order', 'main_table.order_id=`sales/order`.entity_id', array('increment_id', 'created_at', 'shipping_amount'));
16
+ /* @var $collection Temando_Temando_Model_Shipment */
17
+
18
+ $collection->getSelect()->order(array(
19
+ 'main_table.status ASC',
20
+ 'created_at DESC'
21
+ ));
22
+
23
+ $this->setCollection($collection);
24
+ return parent::_prepareCollection();
25
+ }
26
+
27
+ protected function _prepareColumns()
28
+ {
29
+ $this->addColumn('order_number', array(
30
+ 'header' => Mage::helper('temando')->__('Order #'),
31
+ 'width' => '100px',
32
+ 'index' => 'increment_id',
33
+ ));
34
+
35
+ $this->addColumn('created_at', array(
36
+ 'header' => Mage::helper('temando')->__('Purchased On'),
37
+ 'width' => '160px',
38
+ 'type' => 'datetime',
39
+ 'index' => 'created_at',
40
+ 'filter_index' => '`sales/order`.created_at',
41
+ ));
42
+
43
+ $this->addColumn('status', array(
44
+ 'header' => Mage::helper('temando')->__('Status'),
45
+ 'index' => 'status',
46
+ 'type' => 'options',
47
+ 'width' => '100px',
48
+ 'options' => Mage::getSingleton('temando/system_config_source_shipment_status')->getOptions(),
49
+ 'filter_index' => 'main_table.status',
50
+ ));
51
+
52
+ $this->addColumn('anticipated_cost', array(
53
+ 'header' => Mage::helper('temando')->__('Anticipated Cost'),
54
+ 'align' => 'left',
55
+ 'type' => 'currency',
56
+ 'currency_code' => 'AUD',
57
+ 'index' => 'anticipated_cost',
58
+ ));
59
+
60
+ $this->addColumn('shipping_paid', array(
61
+ 'header' => Mage::helper('temando')->__('Shipping Paid'),
62
+ 'align' => 'left',
63
+ 'type' => 'currency',
64
+ 'currency_code' => Mage::app()->getStore()->getCurrentCurrencyCode(),
65
+ 'index' => 'shipping_amount',
66
+ ));
67
+
68
+ $this->addColumn('selected_quote_description', array(
69
+ 'header' => Mage::helper('temando')->__('Customer Selected Quote'),
70
+ 'align' => 'left',
71
+ 'index' => 'customer_selected_quote_description',
72
+ ));
73
+
74
+ $this->addColumn('action', array(
75
+ 'header' => Mage::helper('temando')->__('Action'),
76
+ 'width' => '100',
77
+ 'type' => 'action',
78
+ 'getter' => 'getId',
79
+ 'actions' => array(
80
+ 'view' => array(
81
+ 'caption' => Mage::helper('temando')->__('View'),
82
+ 'url' => array('base' => '*/*/edit'),
83
+ 'field' => 'id'
84
+ )
85
+ ),
86
+ 'filter' => false,
87
+ 'sortable' => false,
88
+ 'index' => 'stores',
89
+ 'is_system' => true,
90
+ ));
91
+
92
+ return parent::_prepareColumns();
93
+ }
94
+
95
+
96
+ public function getRowUrl($row)
97
+ {
98
+ return $this->getUrl('*/*/edit', array('id' => $row->getId()));
99
+ }
100
+
101
+ }
app/code/community/Temando/Temando/Block/Adminhtml/System/Config/Form/Field/Insurance.php ADDED
@@ -0,0 +1,84 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Temando_Temando_Block_Adminhtml_System_Config_Form_Field_Insurance extends Temando_Temando_Block_Adminhtml_System_Config_Form_Field_Required
4
+ {
5
+
6
+ protected $_confirm_text = array(
7
+ "optional" => "<table><tr><td class='c1'>%optional_input%</td><td class='c2'>I confirm that I have read &amp; understood the terms &amp; conditions outlined in the <a href='http://www.temando.com/downloads/Product%20Disclosure%20Statement%20and%20Wording.pdf' target='_blank'>Product Disclosure Statement and wording</a>, the <a href='http://www.temando.com/downloads/Financial%20Services%20Guide.pdf' target='_blank'>Financial Services Guide</a> and the <a href='http://www.temando.com/downloads/Privacy%20Statement.pdf' target='_blank'>Privacy Statement</a> and will take advantage of this offer.</td></tr></table>",
8
+ "mandatory" => "<textarea style='height: 100px; width: 100%'>Athough every care is taken by the transport company whilst transporting and storing the item being transacted, it may still become lost or damaged.
9
+
10
+ In some instances, the transport company may be required to compensate you for the loss of or damage to the item. However, there are many circumstances in which they may not be required to compensate you, such as when the loss or damage is caused by an act of God, or other events beyond their control. This insurance assists to fill this gap.
11
+
12
+ Whilst every effort has been made to insure your item, you should understand that the following items are not insured (this is a summary of the exclusions and you should refer to the Terms and Conditions for a complete understanding):
13
+
14
+ - Money, deeds, securities, treasury notes, tickets, vouchers, stamps, duty stamps, any other cash equivalents,
15
+
16
+ - Designs and/or patterns and/or plans and/or manuscripts and/or any other documents,
17
+
18
+ - Electronic data or computer software stored on computers or hardware
19
+
20
+ - Any living creature
21
+
22
+ - Precious Metals, Precious Stones or Semi-precious Stones that are sent by themselves, i.e. this does not mean fixed items, e.g. rings, earrings),
23
+
24
+ - Motor Vehicles and boats (note, this does not mean car parts, which can be covered).
25
+
26
+ Please also note that the insurance only covers items where the origin address and the delivery address are both located in Australia. In other words, if you are sending your item to a country that is not Australia, then there is no insurance. Conversely, if you are resident in a country other than Australia, but sending the item to Australia the insurance will not apply either.</textarea>
27
+ <table style='padding-top: 10px;'><tr><td class='c1'>%mandatory_input%</td><td class='c2'>I confirm that I have read &amp; understood the terms &amp; conditions outlined in the <a href='http://www.temando.com/downloads/Product%20Disclosure%20Statement%20and%20Wording.pdf' target='_blank'>Product Disclosure Statement and wording</a>, the <a href='http://www.temando.com/downloads/Financial%20Services%20Guide.pdf' target='_blank'>Financial Services Guide</a> and the <a href='http://www.temando.com/downloads/Privacy%20Statement.pdf' target='_blank'>Privacy Statement</a> and will take advantage of this offer.</td></tr></table>",
28
+ "disabled" => "<div class='error-msg' style='height: 35px; border: 0 !important; background-color: transparent !important; padding-left: 33px; padding-top: 9px; color: #2F2F2F !important;'>Even though Insurance will be unavailable to your buyers, you may still insure shipments as a seller.</div>
29
+ <textarea style='height: 100px; width: 100%'>Athough every care is taken by the transport company whilst transporting and storing the item being transacted, it may still become lost or damaged.
30
+
31
+ In some instances, the transport company may be required to compensate you for the loss of or damage to the item. However, there are many circumstances in which they may not be required to compensate you, such as when the loss or damage is caused by an act of God, or other events beyond their control. This insurance assists to fill this gap.
32
+
33
+ Whilst every effort has been made to insure your item, you should understand that the following items are not insured (this is a summary of the exclusions and you should refer to the Terms and Conditions for a complete understanding):
34
+
35
+ - Money, deeds, securities, treasury notes, tickets, vouchers, stamps, duty stamps, any other cash equivalents,
36
+
37
+ - Designs and/or patterns and/or plans and/or manuscripts and/or any other documents,
38
+
39
+ - Electronic data or computer software stored on computers or hardware
40
+
41
+ - Any living creature
42
+
43
+ - Precious Metals, Precious Stones or Semi-precious Stones that are sent by themselves, i.e. this does not mean fixed items, e.g. rings, earrings),
44
+
45
+ - Motor Vehicles and boats (note, this does not mean car parts, which can be covered).
46
+
47
+ Please also note that the insurance only covers items where the origin address and the delivery address are both located in Australia. In other words, if you are sending your item to a country that is not Australia, then there is no insurance. Conversely, if you are resident in a country other than Australia, but sending the item to Australia the insurance will not apply either.</textarea>
48
+ <table style='padding-top: 10px;'><tr><td class='c1'>%disabled_input%</td><td class='c2'>I confirm that I have read &amp; understood the terms &amp; conditions outlined in the <a href='http://www.temando.com/downloads/Product%20Disclosure%20Statement%20and%20Wording.pdf' target='_blank'>Product Disclosure Statement and wording</a>, the <a href='http://www.temando.com/downloads/Financial%20Services%20Guide.pdf' target='_blank'>Financial Services Guide</a> and the <a href='http://www.temando.com/downloads/Privacy%20Statement.pdf' target='_blank'>Privacy Statement</a> and will take advantage of this offer.</td></tr></table>",
49
+ );
50
+
51
+
52
+ /**
53
+ * @see Mage_Adminhtml_Block_System_Config_Form_Field::render()
54
+ */
55
+ public function render(Varien_Data_Form_Element_Abstract $element)
56
+ {
57
+ $comment_confirm = $this->_getConfirmHtml($element->getValue());
58
+ $element->setOnchange("$$('.confirm-insurance').each(function(control){control.style.display = 'none';}); $('insurance_'+this.value).style.display = '';");
59
+ $element->setComment($element->getComment());
60
+ $return = parent::render($element);
61
+ $return .= "<tr><td>&nbsp;</td><td colspan='3'>" . $comment_confirm . "</td></tr>";
62
+ return $return;
63
+ }
64
+
65
+ protected function _getConfirmHtml($value)
66
+ {
67
+ $return = '';
68
+ foreach ($this->_confirm_text as $k => $v) {
69
+ $checked = (Mage::getStoreConfig('temando/insurance/confirm_' . $k)=='Y')?true:false;
70
+ if ($k != $value) {
71
+ $checked = false;
72
+ }
73
+
74
+ $field = "<input type='hidden' name='groups[insurance][fields][confirm_" . $k . "][value]' " . ($checked?'disabled="disabled""':'') . " value='N' id='optional_confirm_no' />";
75
+ $field .= "<input type='checkbox' name='groups[insurance][fields][confirm_" . $k ."][value]' value='Y' " . ($checked?'checked="checked"':'') . ' onclick="if($(\'' . $k .'_confirm_no\')){$(\'' . $k .'_confirm_no\').disabled=this.checked;}" />';
76
+ $html = "<div class='confirm-insurance' id='insurance_" . $k . "'" . (($value != $k)?" style='display: none;'":"") . ">" . $v . "</div>";
77
+ $html = str_replace('%' . $k . '_input%', $field, $html);
78
+ $return .= $html;
79
+ }
80
+
81
+ return $return;
82
+ }
83
+
84
+ }
app/code/community/Temando/Temando/Block/Adminhtml/System/Config/Form/Field/Required.php ADDED
@@ -0,0 +1,47 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Temando_Temando_Block_Adminhtml_System_Config_Form_Field_Required extends Mage_Adminhtml_Block_System_Config_Form_Field
4
+ {
5
+
6
+ protected $_element;
7
+
8
+ /**
9
+ * (non-PHPdoc)
10
+ * @see Mage_Adminhtml_Block_System_Config_Form_Field::render()
11
+ *
12
+ * Adds the "required" star to the form field.
13
+ */
14
+ public function render(Varien_Data_Form_Element_Abstract $element)
15
+ {
16
+ $this->_element = $element;
17
+ $html = parent::render($this->_element);
18
+
19
+ $html = $this->_addStar($html);
20
+ $html = $this->_addRequiredClass($html);
21
+
22
+ return $html;
23
+ }
24
+
25
+ protected function _addStar($html)
26
+ {
27
+ $search = '<label for="' . $this->_element->getHtmlId() . '">' . $this->_element->getLabel() . '</label>';
28
+ $replacement = '<label for="' . $this->_element->getHtmlId() . '">' . $this->_element->getLabel() . ' <span class="required">*</span></label>';
29
+
30
+ return str_replace($search, $replacement, $html);
31
+ }
32
+
33
+ protected function _addRequiredClass($html)
34
+ {
35
+ $search = array(
36
+ '#(<input.*class=")([^<>"]*)(".*>)#',
37
+ '#(<select.*class=")([^<>"]*)(".*>)#',
38
+ );
39
+ $replacement = array(
40
+ '$1required-entry $2$3',
41
+ '$1validate-select $2$3',
42
+ );
43
+
44
+ return preg_replace($search, $replacement, $html);
45
+ }
46
+
47
+ }
app/code/community/Temando/Temando/Block/Adminhtml/System/Config/Form/Fieldset/General.php ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Temando_Temando_Block_Adminhtml_System_Config_Form_Fieldset_General extends Mage_Adminhtml_Block_System_Config_Form_Fieldset
4
+ {
5
+
6
+ /**
7
+ * @see Mage_Adminhtml_Block_System_Config_Form_Fieldset::_getHeaderHtml()
8
+ *
9
+ * Passes the output text through a basic replacement function to find
10
+ * instances of "{{store url="..."}}" and replace these with the correct
11
+ * Magento URLs.
12
+ */
13
+ protected function _getHeaderHtml($element)
14
+ {
15
+ $html = parent::_getHeaderHtml($element);
16
+ $pattern = '#{{store url="(.*?)"}}#';
17
+
18
+ return preg_replace_callback($pattern, create_function('$elements', '
19
+ // $elements[1] is the 1st parenthesized expression
20
+ return Mage::getModel("adminhtml/url")->getUrl($elements[1]);
21
+ '), $html);
22
+ }
23
+
24
+ }
app/code/community/Temando/Temando/Block/Cart/Shipping.php ADDED
@@ -0,0 +1,99 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Temando_Temando_Block_Cart_Shipping extends Mage_Checkout_Block_Cart_Shipping
4
+ {
5
+
6
+
7
+ public function getCityActive()
8
+ {
9
+ return (bool)Mage::getStoreConfig('carriers/temando/active') || parent::getCityActive();
10
+ }
11
+
12
+ /**
13
+ * Check if one of carriers require state/province
14
+ *
15
+ * @return bool
16
+ */
17
+ public function isStateProvinceRequired()
18
+ {
19
+ return (bool)Mage::getStoreConfig('carriers/temando/active') || parent::isStateProvinceRequired();
20
+ }
21
+
22
+ /**
23
+ * Check if one of carriers require city
24
+ *
25
+ * @return bool
26
+ */
27
+ public function isCityRequired()
28
+ {
29
+ return (bool)Mage::getStoreConfig('carriers/temando/active') || parent::isCityRequired();
30
+ }
31
+
32
+ /**
33
+ * Check if one of carriers require zip code
34
+ *
35
+ * @return bool
36
+ */
37
+ public function isZipCodeRequired()
38
+ {
39
+ return (bool)Mage::getStoreConfig('carriers/temando/active') || parent::isZipCodeRequired();
40
+ }
41
+
42
+ public function getEstimatePostcode()
43
+ {
44
+ $return = parent::getEstimatePostcode();
45
+ if (!$return && Mage::helper('temando')->getSessionPostcode()) {
46
+ $return = Mage::helper('temando')->getSessionPostcode();
47
+ }
48
+
49
+ return $return;
50
+ }
51
+
52
+ public function getEstimateCity()
53
+ {
54
+ $return = parent::getEstimateCity();
55
+ if (!$return && Mage::helper('temando')->getSessionCity()) {
56
+ $return = Mage::helper('temando')->getSessionCity();
57
+ }
58
+
59
+ return $return;
60
+ }
61
+
62
+ public function getEstimateRegionId()
63
+ {
64
+ $return = parent::getEstimateRegionId();
65
+ if (!$return && Mage::helper('temando')->getSessionRegionId()) {
66
+ $return = Mage::helper('temando')->getSessionRegionId();
67
+ }
68
+
69
+ return $return;
70
+ }
71
+
72
+ public function getEstimateRegion()
73
+ {
74
+ $return = parent::getEstimateRegion();
75
+ if (!$return && Mage::helper('temando')->getSessionRegion()) {
76
+ $return = Mage::helper('temando')->getSessionRegion();
77
+ }
78
+
79
+ return $return;
80
+ }
81
+
82
+ /**
83
+ * Translate block sentence
84
+ *
85
+ * @return string
86
+ */
87
+ public function __()
88
+ {
89
+ $args = func_get_args();
90
+ if ((count($args) == 1) && ('City' == $args[0])) {
91
+ $args[0] = 'Suburb';
92
+ }
93
+
94
+ $expr = new Mage_Core_Model_Translate_Expr(array_shift($args), $this->getModuleName());
95
+ array_unshift($args, $expr);
96
+ return Mage::app()->getTranslator()->translate($args);
97
+ }
98
+
99
+ }
app/code/community/Temando/Temando/Block/Onepage/Shipping/Method/Available.php ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Temando_Temando_Block_Onepage_Shipping_Method_Available
4
+ extends Mage_Checkout_Block_Onepage_Shipping_Method_Available
5
+ {
6
+
7
+ }
app/code/community/Temando/Temando/Block/Onepage/Shipping/Method/Available/Single.php ADDED
@@ -0,0 +1,51 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Temando_Temando_Block_Onepage_Shipping_Method_Available_Single extends Temando_Temando_Block_Onepage_Shipping_Method_Available
4
+ {
5
+ /**
6
+ * One shipping method only?
7
+ *
8
+ * @return boolean
9
+ */
10
+ public function getSole()
11
+ {
12
+ $groups = $this->getShippingRates();
13
+ if(count($groups) == 1) {
14
+ $rates = array_pop($groups);
15
+ if(count($rates) == 1) return true;
16
+ }
17
+ return false;
18
+ }
19
+
20
+ /**
21
+ * @return Temando_Temando_Model_Options
22
+ */
23
+ public function getOptions()
24
+ {
25
+ $options = Mage::registry('temando_current_options');
26
+ if(!$options) {
27
+ $options = array();
28
+ }
29
+
30
+ return $options;
31
+ }
32
+
33
+
34
+ /**
35
+ * Returns class for a shipping rate element (radio button)
36
+ * (used in conjunction with extras tick boxes)
37
+ *
38
+ * @param string $code Shipping rate code
39
+ * @return string
40
+ */
41
+ public function getClassFromRateCode($code)
42
+ {
43
+ $class = '';
44
+ if(preg_match('/^temando_/', $code)) {
45
+ preg_match_all('/(insurance|carbonoffset|footprints)_(Y|N)/', $code, $matches);
46
+ $class = implode(' ', $matches[0]);
47
+ }
48
+ return $class;
49
+ }
50
+
51
+ }
app/code/community/Temando/Temando/Block/Product/Shipping.php ADDED
@@ -0,0 +1,80 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Temando_Temando_Block_Product_Shipping extends Mage_Core_Block_Template
4
+ {
5
+
6
+ /**
7
+ * Initialize block
8
+ *
9
+ */
10
+ protected function _construct()
11
+ {
12
+ $this->setId('temando_shipping');
13
+ }
14
+
15
+ public function getCountryId()
16
+ {
17
+ if (Mage::getSingleton('customer/session')->getData('estimate_product_shipping')) {
18
+ return Mage::getSingleton('customer/session')->getData('estimate_product_shipping')->getCountryId();
19
+ }
20
+
21
+ return 'AU';
22
+ }
23
+
24
+ public function getProductId()
25
+ {
26
+ if (Mage::registry('current_product')) {
27
+ return Mage::registry('current_product')->getId();
28
+ }
29
+
30
+ return '0';
31
+ }
32
+
33
+ public function getRegionId()
34
+ {
35
+ if (Mage::getSingleton('customer/session')->getData('estimate_product_shipping')) {
36
+ return Mage::getSingleton('customer/session')->getData('estimate_product_shipping')->getRegionId();
37
+ }
38
+
39
+ return '';
40
+ }
41
+
42
+ public function getCity()
43
+ {
44
+ if (Mage::getSingleton('customer/session')->getData('estimate_product_shipping')) {
45
+ return Mage::getSingleton('customer/session')->getData('estimate_product_shipping')->getCity();
46
+ }
47
+
48
+ return '';
49
+ }
50
+
51
+ public function getPostcode()
52
+ {
53
+ if (Mage::getSingleton('customer/session')->getData('estimate_product_shipping')) {
54
+ return Mage::getSingleton('customer/session')->getData('estimate_product_shipping')->getPostcode();
55
+ }
56
+
57
+ return '';
58
+ }
59
+
60
+ public function getPcs()
61
+ {
62
+ if (Mage::getSingleton('customer/session')->getData('estimate_product_shipping')) {
63
+ return Mage::getSingleton('customer/session')->getData('estimate_product_shipping')->getPcs();
64
+ }
65
+
66
+ return '';
67
+ }
68
+
69
+ public function getCountryOptions()
70
+ {
71
+ return Mage::helper('temando')->getAllowedCountries();
72
+ }
73
+
74
+ public function getQty()
75
+ {
76
+ return '1';
77
+ }
78
+
79
+
80
+ }
app/code/community/Temando/Temando/Block/Product/Shipping/Methods.php ADDED
@@ -0,0 +1,27 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+
4
+ class Temando_Temando_Block_Product_Shipping_Methods extends Mage_Core_Block_Template
5
+ {
6
+
7
+ public function getEstimateRates()
8
+ {
9
+ $rates = Mage::registry('product_rates');
10
+ return $rates;
11
+ //return Mage::registry('product_rates');
12
+ }
13
+
14
+
15
+ public function getCarrierName($carrierCode)
16
+ {
17
+ if ($name = Mage::getStoreConfig('carriers/'.$carrierCode.'/title')) {
18
+ return $name;
19
+ }
20
+ return $carrierCode;
21
+ }
22
+
23
+ public function formatPrice($price)
24
+ {
25
+ return Mage::app()->getStore()->convertPrice($price, true);
26
+ }
27
+ }
app/code/community/Temando/Temando/Helper/Data.php ADDED
@@ -0,0 +1,433 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Temando_Temando_Helper_Data extends Mage_Core_Helper_Abstract {
4
+
5
+ const DEFAULT_WAREHOUSE_NAME = 'Magento Warehouse';
6
+
7
+ private $_temandoAttributes = array(
8
+ 'temando_packaging_mode',
9
+ 'temando_packaging',
10
+ 'temando_fragile',
11
+ 'temando_length',
12
+ 'temando_width',
13
+ 'temando_height'
14
+ );
15
+
16
+ protected $_allowedCountries = array(
17
+ 'AU' => 'Australia',
18
+ );
19
+
20
+ /**
21
+ * Retrieves an element from the module configuration data.
22
+ *
23
+ * @param string $field
24
+ */
25
+ public function getConfigData($field) {
26
+ $path = 'temando/' . $field;
27
+ return Mage::getStoreConfig($path);
28
+ }
29
+
30
+ /**
31
+ * Returns array of allowed countries based on Magento system configuration
32
+ * and Temando plugin allowed countries.
33
+ *
34
+ * @param boolean $asJson
35
+ * @return array
36
+ */
37
+ public function getAllowedCountries($asJson = false) {
38
+ $specific = Mage::getStoreConfig('carriers/temando/sallowspecific');
39
+ //check if all allowed and return selected
40
+ if($specific == 1) {
41
+ $availableCountries = explode(',', Mage::getStoreConfig('carriers/temando/specificcountry'));
42
+ $countries = array_intersect_key($this->_allowedCountries, array_flip($availableCountries));
43
+ if($asJson) {
44
+ return Mage::helper('core')->jsonEncode($countries);
45
+ } else {
46
+ return $countries;
47
+ }
48
+ }
49
+ //return all allowed
50
+ if($asJson) {
51
+ return Mage::helper('core')->jsonEncode($this->_allowedCountries);
52
+ } else {
53
+ return $this->_allowedCountries;
54
+ }
55
+ }
56
+
57
+ /**
58
+ * Applies Temando attributes to sales quote item object
59
+ *
60
+ * @param Mage_Sales_Model_Order_Item $item
61
+ */
62
+ public function applyTemandoParamsToItem($item)
63
+ {
64
+ $attribs = $this->getTemandoProductAttributes($item);
65
+ foreach($attribs as $key => $val) {
66
+ $item->setData($key, $val);
67
+ }
68
+ }
69
+
70
+ /**
71
+ * Returns values for Temando specific product attributes. Currently handles simple
72
+ * and configurable products only. Default attribute values from configuration are
73
+ * returned if product temando retrieval mode is set to 'Use Defaults'
74
+ *
75
+ * @param Mage_Sales_Model_Order_Item $item
76
+ * @param Mage_Catalog_Model_Product $product
77
+ * @return array Temando specific product attributes
78
+ */
79
+ public function getTemandoProductAttributes($item = null, $product = null)
80
+ {
81
+ $attribs = array();
82
+ if($item) {
83
+ //Mage_Sales_Model_Order_Item = need to check if configurable
84
+ $product = Mage::getModel('catalog/product')->load($item->getProductId());
85
+ if ($product->isConfigurable()) {
86
+ //configurable product - get selected simple product
87
+ $simple_product = $this->getSelectedSimpleProductFromConfigurable($item);
88
+ if($simple_product->getId() && $simple_product->getTemandoPackagingMode()) {
89
+ //simple product found and retrieval mode is set to 'As Defined' => Retrieve attributes
90
+ foreach($this->_temandoAttributes as $attribname) {
91
+ $attribs[$attribname] = $simple_product->getData($attribname);
92
+ }
93
+ } else if($simple_product->getId() && !$simple_product->getTemandoPackagingMode()) {
94
+ //simple product found and retrieval mode set to 'Use Defaults'
95
+ //try to take from configurable parent product before looking at defaults
96
+ if($product->getTemandoPackagingMode()) {
97
+ foreach($this->_temandoAttributes as $attribname) {
98
+ $attribs[$attribname] = $product->getData($attribname);
99
+ }
100
+ } else {
101
+ //simple and parent-configurable set to 'Use Defaults'
102
+ $attribs = $this->getDefaultTemandoAttributes();
103
+ }
104
+ } //attribs array could be empty if there's an error retrieving simple product from configurable
105
+ //apply simple product weight to parent configurable
106
+ if ($simple_product->getId()) {
107
+ $item->setWeight($simple_product->getWeight());
108
+ }
109
+ } else {
110
+ //assuming simple product here ... possible bug if other product type used
111
+ if($product->getTemandoPackagingMode()) {
112
+ //retrieval mode set to 'As Defined' => Retrieve attributes
113
+ foreach($this->_temandoAttributes as $attribname) {
114
+ $attribs[$attribname] = $product->getData($attribname);
115
+ }
116
+ } else {
117
+ $attribs = $this->getDefaultTemandoAttributes();
118
+ }
119
+ }
120
+ } else {
121
+ //Request from within admin panel direct on product object
122
+ if($product instanceof Mage_Catalog_Model_Product) {
123
+ foreach($this->_temandoAttributes as $attribname) {
124
+ $attribs[$attribname] = $product->getData($attribname);
125
+ }
126
+ }
127
+ }
128
+ return $attribs;
129
+ }
130
+
131
+ /**
132
+ * Gets the date when a package will be ready to ship. Adjusts dates so
133
+ * that they always fall on a weekday.
134
+ *
135
+ * @param <type> $ready_time timestamp for when the package will be ready
136
+ * to ship, defaults to 10 days from current date
137
+ */
138
+ public function getReadyDate($ready_time = NULL) {
139
+ if (is_null($ready_time)) {
140
+ $ready_time = strtotime('+10 days');
141
+ }
142
+ if (is_numeric($ready_time) && $ready_time >= strtotime(date('Y-m-d'))) {
143
+ $weekend_days = array('6', '7');
144
+ while (in_array(date('N', $ready_time), $weekend_days)) {
145
+ $ready_time = strtotime('+1 day', $ready_time);
146
+ }
147
+ return $ready_time;
148
+ }
149
+ }
150
+
151
+ /**
152
+ * Gets selected simple product from configurable
153
+ * (using the fact that getSku() on item returns selected simple product sku)
154
+ *
155
+ * @param Mage_Sales_Model_Order_Item $item
156
+ * @return Mage_Catalog_Model_Product
157
+ */
158
+ public function getSelectedSimpleProductFromConfigurable($item) {
159
+ $simpleProductId = Mage::getModel('catalog/product')->getIdBySku($item->getSku());
160
+ return Mage::getModel('catalog/product')->load($simpleProductId);
161
+ }
162
+
163
+ /**
164
+ * Retrieve Default Temando Product Attributes from Configuration
165
+ *
166
+ * @return array
167
+ */
168
+ public function getDefaultTemandoAttributes()
169
+ {
170
+ return array(
171
+ 'temando_packaging_mode' => 0, //defaults
172
+ 'temando_packaging' => $this->getConfigData('defaults/packaging'),
173
+ 'temando_fragile' => $this->getConfigData('defaults/fragile'),
174
+ 'temando_length' => (float)$this->getConfigData('defaults/length'),
175
+ 'temando_width' => (float)$this->getConfigData('defaults/width'),
176
+ 'temando_height' => (float)$this->getConfigData('defaults/height'),
177
+ );
178
+ }
179
+
180
+ /**
181
+ * Converts given weight from configured unit to grams
182
+ *
183
+ * @param float $value Weight to convert
184
+ * @param string $currentUnit Current weight unit
185
+ * @return float Converted weight in grams
186
+ */
187
+ public function getWeightInGrams($value, $currentUnit = null)
188
+ {
189
+ $value = floatval($value);
190
+ $currentUnit = $currentUnit ? $currentUnit : $this->getConfigData('units/weight');
191
+ //from units as specified in configuration
192
+ switch($currentUnit) {
193
+ case Temando_Temando_Model_System_Config_Source_Unit_Weight::KILOGRAMS:
194
+ return $value * 1000; break;
195
+
196
+ case Temando_Temando_Model_System_Config_Source_Unit_Weight::OUNCES:
197
+ return $value * 28.3495; break;
198
+
199
+ case Temando_Temando_Model_System_Config_Source_Unit_Weight::POUNDS:
200
+ return $value * 453.592; break;
201
+
202
+ default: return $value; break;
203
+ }
204
+ }
205
+
206
+ /**
207
+ * Converts given distance from configured unit to centimetres
208
+ *
209
+ * @param float $value Distance to convert
210
+ * @param string $currentUnit Current measure unit
211
+ * @return float Converted distance in centimetres
212
+ */
213
+ public function getDistanceInCentimetres($value, $currentUnit = null)
214
+ {
215
+ $value = floatval($value);
216
+ $currentUnit = $currentUnit ? $currentUnit : $this->getConfigData('units/measure');
217
+ switch($currentUnit) {
218
+ case Temando_Temando_Model_System_Config_Source_Unit_Measure::METRES:
219
+ return $value * 100; break;
220
+
221
+ case Temando_Temando_Model_System_Config_Source_Unit_Measure::FEET:
222
+ return $value * 30.48; break;
223
+
224
+ case Temando_Temando_Model_System_Config_Source_Unit_Measure::INCHES:
225
+ return $value * 2.54; break;
226
+
227
+ default: return $value; break;
228
+ }
229
+ }
230
+
231
+ /**
232
+ * Returns Client ID from system configuration
233
+ *
234
+ * @return string
235
+ */
236
+ public function getClientId() {
237
+ return $this->getConfigData('general/client');
238
+ }
239
+
240
+ /**
241
+ * Retrieves cached address validation results
242
+ *
243
+ * @param string $words
244
+ * @return array of results or false if no cache
245
+ */
246
+ public function getSuggestionsCache($words) {
247
+ if (is_file($this->getFileCacheByWords($words))) {
248
+ return file_get_contents($this->getFileCacheByWords($words));
249
+ }
250
+
251
+ return false;
252
+ }
253
+
254
+ /**
255
+ * Returns path to the cache file
256
+ *
257
+ * @param string $words
258
+ * @return string
259
+ */
260
+ public function getFileCacheByWords($words) {
261
+ $key = md5(strtolower(join('_', $words)));
262
+ $path = Mage::getBaseDir('cache');
263
+ return $path . DS . 'temando' . DS . $key[0] . DS . $key[1] . DS . $key . '.cache';
264
+ }
265
+
266
+ /**
267
+ * Register cached results
268
+ * (saves results into a cache file or removes file if results empty)
269
+ *
270
+ * @param string $words
271
+ * @param string $value
272
+ * @return void
273
+ */
274
+ public function setSuggestionsCache($words, $value) {
275
+ if (strlen(join(' ', $words)) > 4) {
276
+ return;
277
+ }
278
+
279
+ $file = $this->getFileCacheByWords($words);
280
+ $dir = dirname($file);
281
+ if (!is_dir($dir)) {
282
+ mkdir($dir, 0777, true);
283
+ }
284
+
285
+ $fd = @fopen($file, 'w');
286
+ if (!$fd) {
287
+ return;
288
+ }
289
+
290
+ $size = fwrite($fd, $value);
291
+ fclose($fd);
292
+ if ($size != strlen($value)) {
293
+ unlink($file);
294
+ }
295
+ }
296
+
297
+ /**
298
+ * Returns region name saved in customers session
299
+ * @return string|null
300
+ */
301
+ public function getSessionRegion() {
302
+ $data = Mage::getSingleton('customer/session')->getData('estimate_product_shipping');
303
+ if ($data) {
304
+ return Mage::getModel('directory/region')->load($data['region_id'])->getName();
305
+ }
306
+
307
+ return null;
308
+ }
309
+
310
+ /**
311
+ * Returns city name saved in customers session
312
+ * @return string|null
313
+ */
314
+ public function getSessionCity() {
315
+ $data = Mage::getSingleton('customer/session')->getData('estimate_product_shipping');
316
+ if ($data) {
317
+ return $data['city'];
318
+ }
319
+
320
+ return null;
321
+ }
322
+
323
+ /**
324
+ * Returns postal code saved in customers session
325
+ * @return string|null
326
+ */
327
+ public function getSessionPostcode() {
328
+ $data = Mage::getSingleton('customer/session')->getData('estimate_product_shipping');
329
+ if ($data) {
330
+ return $data['postcode'];
331
+ }
332
+
333
+ return null;
334
+ }
335
+
336
+ /**
337
+ * Returns id of the region saved in customers session
338
+ * @return int|null
339
+ */
340
+ public function getSessionRegionId() {
341
+ $data = Mage::getSingleton('customer/session')->getData('estimate_product_shipping');
342
+ if ($data) {
343
+ return $data['region_id'];
344
+ }
345
+
346
+ return null;
347
+ }
348
+
349
+ /**
350
+ * Return list of available origin locations
351
+ *
352
+ * @return array
353
+ */
354
+ public function getLocationList() {
355
+ return array(
356
+ self::DEFAULT_WAREHOUSE_NAME => self::DEFAULT_WAREHOUSE_NAME
357
+ );
358
+ }
359
+
360
+ /**
361
+ * Returns location create/update request array
362
+ *
363
+ * @return array
364
+ */
365
+ public function getOriginRequestArray(Varien_Object $data) {
366
+ return array(
367
+ 'description' => self::DEFAULT_WAREHOUSE_NAME,
368
+ 'type' => 'Origin',
369
+ 'contactName' => $data->getContactName(),
370
+ 'companyName' => $data->getCompanyName(),
371
+ 'street' => $data->getStreet(),
372
+ 'suburb' => $data->getCity(),
373
+ 'state' => $data->getRegion(),
374
+ 'code' => $data->getPostcode(),
375
+ 'country' => $data->getCountry(),
376
+ 'phone1' => $data->getPhone1(),
377
+ 'phone2' => $data->getPhone2(),
378
+ 'fax' => $data->getFax(),
379
+ 'email' => $data->getEmail(),
380
+ 'loadingFacilities' => $data->getLoadingFacilities() ? 'Y' : 'N',
381
+ 'forklift' => $data->getForklift() ? 'Y' : 'N',
382
+ 'dock' => $data->getDock() ? 'Y' : 'N',
383
+ 'limitedAccess' => $data->getLimitedAccess() ? 'Y' : 'N',
384
+ 'postalBox' => $data->getPobox() ? 'Y' : 'N'
385
+ );
386
+ }
387
+
388
+ /**
389
+ * Returns true if street address is a PO Box
390
+ *
391
+ * @param string $street
392
+ * @return boolean
393
+ */
394
+ public function isStreetWithPO($street) {
395
+ if (!is_string($street)) {
396
+ return false;
397
+ }
398
+
399
+ if (preg_match('/p[\. ]*o[\.]*\s*?box/', strtolower($street))) {
400
+ return true;
401
+ }
402
+
403
+ $templates = array('PO Box', 'P.O. Box', 'P.O Box', 'PO. Box', 'p o box');
404
+ foreach ($templates as $t) {
405
+ if (strpos(strtolower($street), strtolower($t)) !== false) {
406
+ return true;
407
+ }
408
+ }
409
+
410
+ return false;
411
+ }
412
+
413
+ /**
414
+ * Returns true if shipping quote is dynamic quote obtained
415
+ * from Temando API
416
+ *
417
+ * @param int $quote_id
418
+ * @return boolean
419
+ */
420
+ public function isQuoteDynamic($quote_id) {
421
+ $fixed_carriers = array(
422
+ Temando_Temando_Model_Carrier::FLAT_RATE,
423
+ Temando_Temando_Model_Carrier::FREE,
424
+ );
425
+
426
+ if (in_array($quote_id, $fixed_carriers)) {
427
+ return false;
428
+ }
429
+
430
+ return true;
431
+ }
432
+
433
+ }
app/code/community/Temando/Temando/Helper/Functions.php ADDED
@@ -0,0 +1,76 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Description of Functions
4
+ *
5
+ * @author martin
6
+ */
7
+ class Temando_Temando_Helper_Functions extends Mage_Core_Helper_Abstract {
8
+
9
+ public function getFastestQuote($quotes)
10
+ {
11
+ $fastest = null;
12
+ foreach ($quotes as $quote) {
13
+ $fastest = $this->_getFaster($quote, $fastest);
14
+ }
15
+ return $fastest;
16
+ }
17
+
18
+ protected function _getFaster($a, $b)
19
+ {
20
+ // if one is null, return the other.
21
+ if (is_null($a)) {
22
+ return $b;
23
+ }
24
+ if (is_null($b)) {
25
+ return $a;
26
+ }
27
+
28
+ // average ETA
29
+ $a_eta = ($a->getEtaFrom() + $a->getEtaTo()) / 2;
30
+ $b_eta = ($b->getEtaFrom() + $b->getEtaTo()) / 2;
31
+
32
+ if ($a_eta != $b_eta) {
33
+ // different speed, return faster
34
+ return $a_eta <= $b_eta ? $a : $b;
35
+ } else {
36
+ // same speed, return cheaper
37
+ return self::_getCheaper($a, $b);
38
+ }
39
+ }
40
+
41
+ public function getCheapestQuote($quotes)
42
+ {
43
+ $cheapest = null;
44
+ foreach ($quotes as $quote) {
45
+ $cheapest = $this->_getCheaper($quote, $cheapest);
46
+ }
47
+ return $cheapest;
48
+ }
49
+
50
+ protected function _getCheaper($a, $b)
51
+ {
52
+ // if one is null, return the other (if both are null, null is returned).
53
+ if (is_null($a)) {
54
+ return $b;
55
+ }
56
+ if (is_null($b)) {
57
+ return $a;
58
+ }
59
+
60
+ return $a->getTotalPrice() <= $b->getTotalPrice() ? $a : $b;
61
+ }
62
+
63
+ public function getCheapestAndFastestQuotes($quotes)
64
+ {
65
+ $cheapest = $this->getCheapestQuote($quotes);
66
+ $fastest = $this->getFastestQuote($quotes);
67
+
68
+ if($cheapest->getId() === $fastest->getId())
69
+ return array($cheapest);
70
+
71
+ return array($cheapest, $fastest);
72
+ }
73
+
74
+ }
75
+
76
+
app/code/community/Temando/Temando/Model/Api/Client.php ADDED
@@ -0,0 +1,203 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class DebugSoapClient extends SoapClient {
4
+
5
+ public function __doRequest($request, $location, $action, $version, $one_way = 0) {
6
+ Mage::log($request, null, 'raw-request.xml', true);
7
+ $response = parent::__doRequest($request, $location, $action, $version, $one_way);
8
+ Mage::log($response, null, 'raw-response.xml', true);
9
+ return $response;
10
+ }
11
+
12
+ }
13
+
14
+ class Temando_Temando_Model_Api_Client extends Mage_Core_Model_Abstract {
15
+
16
+ protected $_client = null;
17
+ protected $_is_sand = null;
18
+
19
+ public function __construct() {
20
+ parent::__construct();
21
+ }
22
+
23
+ public function connect($username = null, $password = null, $sandbox = false) {
24
+ $this->_is_sand = $sandbox;
25
+ if ($sandbox) {
26
+ $url = "https://training-api3.temando.com/schema/2009_06/server.wsdl";
27
+ } else {
28
+ $url = "https://api.temando.com/schema/2009_06/server.wsdl";
29
+ }
30
+
31
+ if (!$username) {
32
+ $username = Mage::helper('temando')->getConfigData('general/username');
33
+ }
34
+ if (!$password) {
35
+ $password = Mage::helper('temando')->getConfigData('general/password');
36
+ }
37
+
38
+ // The WSDL cache should be set to on to prevent the WSDL being loaded everytime.
39
+ ini_set("soap.wsdl_cache_enabled", "1");
40
+
41
+ // Create a new SoapClient referencing the Temando WSDL file.
42
+ $this->_client = new SoapClient($url, array('soap_version' => SOAP_1_2, 'trace' => TRUE));
43
+
44
+ // Define the security string that wraps your login details. Due to limitations
45
+ // with the PHP language this header information can only be provided via a string.
46
+ $headerSecurityStr = "<Security><UsernameToken><Username>" . htmlentities($username) . "</Username>" .
47
+ "<Password>" . htmlentities($password) . "</Password></UsernameToken></Security>";
48
+
49
+ // Create a new SoapVar using the header security string.
50
+ $headerSecurityVar = new SoapVar($headerSecurityStr, XSD_ANYXML);
51
+
52
+ // Create a new SoapHeader containing all your login details.
53
+ $soapHeader = new SoapHeader('wsse:http://schemas.xmlsoap.org/ws/2002/04/secext', 'soapenv:Header', $headerSecurityVar);
54
+
55
+ // Add the SoapHeader to your SoapClient.
56
+ $this->_client->__setSoapHeaders(array($soapHeader));
57
+
58
+ return $this;
59
+ }
60
+
61
+ /**
62
+ * Gets quotes for a delivery.
63
+ *
64
+ * @param array $request the request parameters, in an array format.
65
+ * @return array
66
+ */
67
+ public function getQuotesByRequest($request) {
68
+ return $this->getQuotes($request);
69
+ }
70
+
71
+ public function getQuotes($request) {
72
+ if (!$this->_client) {
73
+ return false;
74
+ }
75
+
76
+ if (!$this->_is_sand) {
77
+ $request['clientId'] = Mage::helper('temando')->getClientId();
78
+ }
79
+
80
+ $response = $this->_client->getQuotes($request);
81
+
82
+ //make sure we have an array
83
+ if (!isset($response->quotes->quote)) {
84
+ $response->quotes->quote = array();
85
+ } else if (isset($response->quotes->quote) && !is_array($response->quotes->quote)) {
86
+ $response->quotes->quote = array(0 => $response->quotes->quote);
87
+ }
88
+
89
+ $quotes = array();
90
+ foreach ($response->quotes->quote as $quoteData) {
91
+ $quotes[] = Mage::getModel('temando/quote')->loadResponse($quoteData);
92
+ }
93
+
94
+ return $quotes;
95
+ }
96
+
97
+ public function makeBookingByRequest($request) {
98
+ return $this->makeBooking($request);
99
+ }
100
+
101
+ public function makeBooking($request) {
102
+ if (!$this->_is_sand) {
103
+ $request['clientId'] = Mage::helper('temando')->getClientId();
104
+ }
105
+ if (!$this->_client) {
106
+ return false;
107
+ }
108
+
109
+ return $this->_client->makeBooking($request);
110
+ }
111
+
112
+ public function getRequest($request) {
113
+ if (!$this->_client) {
114
+ return false;
115
+ }
116
+
117
+ return $this->_client->getRequest($request);
118
+ }
119
+
120
+ public function confirmManifest($request) {
121
+ if (!$this->_client) {
122
+ return false;
123
+ }
124
+
125
+ return $this->_client->confirmManifest($request);
126
+ }
127
+
128
+ public function getManifest($request) {
129
+ if (!$this->_client) {
130
+ return false;
131
+ }
132
+
133
+ return $this->_client->getManifest($request);
134
+ }
135
+
136
+ /**
137
+ * get list of location
138
+ *
139
+ * @param $request
140
+ * @return bool
141
+ */
142
+ public function getLocations($request) {
143
+ if (!$this->_client) {
144
+ return false;
145
+ }
146
+
147
+ return $this->_client->getLocations($request);
148
+ }
149
+
150
+ /**
151
+ * create location
152
+ *
153
+ * @param $request
154
+ * @return bool
155
+ */
156
+ public function createLocation($request) {
157
+ if (!$this->_client) {
158
+ return false;
159
+ }
160
+
161
+ $request['clientId'] = Mage::helper('temando')->getClientId();
162
+
163
+ return $this->_client->createLocation($request);
164
+ }
165
+
166
+ /**
167
+ * update location
168
+ *
169
+ * @param $request
170
+ * @return bool
171
+ */
172
+ public function updateLocation($request) {
173
+ if (!$this->_client) {
174
+ return false;
175
+ }
176
+
177
+ $request['clientId'] = Mage::helper('temando')->getClientId();
178
+
179
+ return $this->_client->updateLocation($request);
180
+ }
181
+
182
+ /**
183
+ * Gets the multiplier for insurance (currently 1%).
184
+ *
185
+ * To add insurance to a quote, the total price should be multiplied by
186
+ * this value.
187
+ */
188
+ public function getInsuranceMultiplier() {
189
+ return 1.01; // 1%
190
+ }
191
+
192
+
193
+ public function getClient($request) {
194
+ if (!$this->_client) {
195
+ return false;
196
+ }
197
+
198
+ return $this->_client->getClient($request);
199
+ }
200
+
201
+
202
+
203
+ }
app/code/community/Temando/Temando/Model/Api/Request.php ADDED
@@ -0,0 +1,191 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Temando_Temando_Model_Api_Request extends Mage_Core_Model_Abstract
4
+ {
5
+ /**
6
+ * @var Temando_Temando_Model_Api_Request_Anythings
7
+ */
8
+ protected $_anythings = null;
9
+
10
+ /**
11
+ * @var Temando_Temando_Model_Api_Request_Anywhere
12
+ */
13
+ protected $_anywhere = null;
14
+
15
+ /**
16
+ * @var Temando_Temando_Model_Api_Request_Anytime
17
+ */
18
+ protected $_anytime = null;
19
+
20
+ /**
21
+ * @var array
22
+ */
23
+ protected $_quotes = null;
24
+
25
+ /**
26
+ * If request includes anytime component
27
+ *
28
+ * @var boolean
29
+ */
30
+ protected $use_anytime = false;
31
+
32
+
33
+ public function _construct()
34
+ {
35
+ parent::_construct();
36
+ $this->_init('temando/api_request');
37
+
38
+ $this->_anythings = Mage::getModel('temando/api_request_anythings');
39
+ $this->_anywhere = Mage::getModel('temando/api_request_anywhere');
40
+ $this->_anytime = Mage::getModel('temando/api_request_anytime');
41
+ }
42
+
43
+ public function setItems($items)
44
+ {
45
+ $this->_anythings->setItems($items);
46
+ return $this;
47
+ }
48
+
49
+ public function setDestination($country, $postcode, $city, $street = null)
50
+ {
51
+ $this->_anywhere
52
+ ->setDestinationCountry($country)
53
+ ->setDestinationPostcode($postcode)
54
+ ->setDestinationCity($city)
55
+ ->setDestinationStreet($street);
56
+ return $this;
57
+ }
58
+
59
+ public function setReady($timestamp = null, $time_of_day = 'AM')
60
+ {
61
+ if (!is_null($timestamp)) {
62
+ $this->use_anytime = true;
63
+ }
64
+
65
+ $this->_anytime
66
+ ->setReadyDate($timestamp)
67
+ ->setReadyTimeOfDay($time_of_day);
68
+ return $this;
69
+ }
70
+
71
+ /**
72
+ * Gets all available Temando quotes for this request.
73
+ *
74
+ * @return Temando_Temando_Model_Mysql4_Quote_Collection
75
+ */
76
+ public function getQuotes()
77
+ {
78
+ if (!$this->_fetchQuotes()) {
79
+ // validation failed
80
+ return false;
81
+ }
82
+
83
+ $quotes = Mage::getModel('temando/quote')->getCollection()
84
+ ->addFieldToFilter('magento_quote_id', $this->getMagentoQuoteId());
85
+
86
+ return $quotes;
87
+ }
88
+
89
+ /**
90
+ * Fetches the quotes and saves them into the database.
91
+ *
92
+ * @throws Exception
93
+ */
94
+ protected function _fetchQuotes()
95
+ {
96
+ $request = $this->toRequestArray();
97
+
98
+ if (!$request) {
99
+ return false;
100
+ }
101
+
102
+ try {
103
+ $api = Mage::getModel('temando/api_client')->connect(
104
+ $this->getUsername(), $this->getPassword(), $this->getSandbox()
105
+ );
106
+ $quotes = $api->getQuotes($request);
107
+ } catch(Exception $e) {
108
+ throw $e;
109
+ }
110
+
111
+ // filter by allowed carriers, if the filter has been set
112
+ $filtered_quotes = $quotes;
113
+ if (is_array($this->getAllowedCarriers())) {
114
+ $filtered_quotes = array();
115
+ foreach ($quotes as $quote) {
116
+ /* @var $quote Temando_Temando_Model_Quote */
117
+ $quote_carrier_id = $quote->getCarrier()->getCarrierId();
118
+ if (in_array($quote_carrier_id, $this->getAllowedCarriers())) {
119
+ $filtered_quotes[] = $quote;
120
+ }
121
+ }
122
+ }
123
+
124
+ $this->_saveQuotes($filtered_quotes);
125
+
126
+ return true;
127
+ }
128
+
129
+ /**
130
+ * Saves an array of quotes to the database.
131
+ *
132
+ * @param array $quotes an array of Temando_Temando_Model_Quote objects.
133
+ */
134
+ protected function _saveQuotes($quotes)
135
+ {
136
+ // delete all old Temando quotes for this Magento quote
137
+ $old_quotes = Mage::getModel('temando/quote')->getCollection()
138
+ ->addFieldToFilter('magento_quote_id', $this->getMagentoQuoteId());
139
+ foreach ($old_quotes as $quote) {
140
+ /* @var $quote Temando_Temando_Model_Quote */
141
+ $quote->delete();
142
+ }
143
+
144
+ // add new Temando quotes to the database
145
+ foreach ($quotes as $quote) {
146
+ $quote->setMagentoQuoteId($this->getMagentoQuoteId())
147
+ ->save();
148
+ }
149
+
150
+ return $this;
151
+ }
152
+
153
+
154
+ public function toRequestArray()
155
+ {
156
+ if (!$this->validate()) {
157
+ return false;
158
+ }
159
+
160
+ $goodsValue = $this->_anythings->getGoodsValue();
161
+ $return = array(
162
+ 'anythings' => $this->_anythings->toRequestArray(),
163
+ 'anywhere' => $this->_anywhere->toRequestArray(),
164
+ );
165
+
166
+ if ($goodsValue) {
167
+ $return['general'] = array(
168
+ 'goodsValue' => round($goodsValue, 2),
169
+ );
170
+ }
171
+
172
+ if ($this->use_anytime) {
173
+ $return['anytime'] = $this->_anytime->toRequestArray();
174
+ }
175
+
176
+ return $return;
177
+ }
178
+
179
+ public function validate()
180
+ {
181
+ return
182
+ $this->getMagentoQuoteId() &&
183
+ $this->_anythings instanceof Temando_Temando_Model_Api_Request_Anythings &&
184
+ $this->_anywhere instanceof Temando_Temando_Model_Api_Request_Anywhere &&
185
+ $this->_anytime instanceof Temando_Temando_Model_Api_Request_Anytime &&
186
+ $this->_anythings->validate() &&
187
+ $this->_anywhere->validate() &&
188
+ $this->_anytime->validate();
189
+ }
190
+
191
+ }
app/code/community/Temando/Temando/Model/Api/Request/Anything.php ADDED
@@ -0,0 +1,102 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Temando_Temando_Model_Api_Request_Anything extends Mage_Core_Model_Abstract
4
+ {
5
+ const GOODS_CLASS = 'General Goods';
6
+ const GOODS_SUBCLASS = 'Household Goods';
7
+ const PALLET_TYPE = 'Plain';
8
+ const PALLET_NATURE = 'Not Required';
9
+
10
+ /**
11
+ * @var Mage_Sales_Model_Order_Item
12
+ */
13
+ protected $_item = null;
14
+
15
+ public function _construct()
16
+ {
17
+ parent::_construct();
18
+ $this->_init('temando/api_request_anything');
19
+ }
20
+
21
+ public function setItem($item)
22
+ {
23
+ if ($item instanceof Mage_Sales_Model_Quote_Item || $item instanceof Mage_Sales_Model_Order_Item ||
24
+ $item instanceof Mage_Sales_Model_Quote_Address_Item || $item instanceof Temando_Temando_Model_Box) {
25
+ $this->_item = $item;
26
+ }
27
+ return $this;
28
+ }
29
+
30
+ /**
31
+ * Gets the order item for this Anything object.
32
+ *
33
+ * @return Mage_Sales_Model_Order_Item
34
+ */
35
+ public function getItem()
36
+ {
37
+ if ($this->_item) {
38
+ return $this->_item;
39
+ }
40
+ return false;
41
+ }
42
+
43
+ public function toRequestArray()
44
+ {
45
+ if (!$this->validate()) {
46
+ return false;
47
+ }
48
+
49
+ if ($this->_item instanceof Temando_Temando_Model_Box) {
50
+ $anything = array(
51
+ 'class' => 'General Goods',
52
+ 'subclass' => 'Household Goods',
53
+ 'packaging' => Mage::getModel('temando/system_config_source_shipment_packaging')->getOptionLabel($this->_item->getPackaging()),
54
+ 'quantity' => (int)($this->_item->getQty()),
55
+ 'distanceMeasurementType' => Temando_Temando_Model_System_Config_Source_Unit_Measure::CENTIMETRES,
56
+ 'weightMeasurementType' => Temando_Temando_Model_System_Config_Source_Unit_Weight::GRAMS,
57
+ 'weight' => Mage::helper('temando')->getWeightInGrams($this->_item->getWeight(), $this->_item->getWeightUnit()),
58
+ 'length' => Mage::helper('temando')->getDistanceInCentimetres($this->_item->getLength(), $this->_item->getMeasureUnit()),
59
+ 'width' => Mage::helper('temando')->getDistanceInCentimetres($this->_item->getWidth(), $this->_item->getMeasureUnit()),
60
+ 'height' => Mage::helper('temando')->getDistanceInCentimetres($this->_item->getHeight(), $this->_item->getMeasureUnit()),
61
+ 'qualifierFreightGeneralFragile' => $this->_item->getFragile() == '1' ? 'Y' : 'N',
62
+ 'description' => $this->_item->getComment()
63
+ );
64
+ if($this->_item->getPackaging() == Temando_Temando_Model_System_Config_Source_Shipment_Packaging::PALLET) {
65
+ $anything['palletType'] = self::PALLET_TYPE;
66
+ $anything['palletNature'] = self::PALLET_NATURE;
67
+ }
68
+
69
+ } else {
70
+
71
+ Mage::helper('temando')->applyTemandoParamsToItem($this->_item);
72
+ $anything = array(
73
+ 'class' => 'General Goods',
74
+ 'subclass' => 'Household Goods',
75
+ 'packaging' => Mage::getModel('temando/system_config_source_shipment_packaging')->getOptionLabel($this->_item->getTemandoPackaging()),
76
+ 'quantity' => (int)($this->_item->getQty() ? $this->_item->getQty() : $this->_item->getQtyOrdered()),
77
+ 'distanceMeasurementType' => Temando_Temando_Model_System_Config_Source_Unit_Measure::CENTIMETRES,
78
+ 'weightMeasurementType' => Temando_Temando_Model_System_Config_Source_Unit_Weight::GRAMS,
79
+ 'weight' => Mage::helper('temando')->getWeightInGrams($this->_item->getWeight(),Mage::helper('temando')->getConfigData('units/weight')),
80
+ 'length' => Mage::helper('temando')->getDistanceInCentimetres($this->_item->getTemandoLength(), Mage::helper('temando')->getConfigData('units/measure')),
81
+ 'width' => Mage::helper('temando')->getDistanceInCentimetres($this->_item->getTemandoWidth(), Mage::helper('temando')->getConfigData('units/measure')),
82
+ 'height' => Mage::helper('temando')->getDistanceInCentimetres($this->_item->getTemandoHeight(), Mage::helper('temando')->getConfigData('units/measure')),
83
+ 'qualifierFreightGeneralFragile' => $this->_item->getTemandoFragile() == '1' ? 'Y' : 'N',
84
+ 'description' => $this->_item->getName()
85
+ );
86
+ if($this->_item->getTemandoPackaging() == Temando_Temando_Model_System_Config_Source_Shipment_Packaging::PALLET) {
87
+ $anything['palletType'] = self::PALLET_TYPE;
88
+ $anything['palletNature'] = self::PALLET_NATURE;
89
+ }
90
+
91
+ }
92
+ return $anything;
93
+ }
94
+ public function validate()
95
+ {
96
+ return $this->_item instanceof Mage_Sales_Model_Quote_Item ||
97
+ $this->_item instanceof Mage_Sales_Model_Order_Item ||
98
+ $this->_item instanceof Mage_Sales_Model_Quote_Address_Item ||
99
+ $this->_item instanceof Temando_Temando_Model_Box;
100
+ }
101
+
102
+ }
app/code/community/Temando/Temando/Model/Api/Request/Anythings.php ADDED
@@ -0,0 +1,172 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Temando_Temando_Model_Api_Request_Anythings extends Mage_Core_Model_Abstract {
4
+
5
+ /**
6
+ * @var array
7
+ */
8
+ protected $_anythings;
9
+ protected $_need_optimize = false;
10
+
11
+ public function _construct() {
12
+ parent::_construct();
13
+ $this->_init('temando/api_request_anythings');
14
+ $this->_anythings = array();
15
+ }
16
+
17
+ public function setItems($items) {
18
+ $this->_anythings = array();
19
+ foreach ($items as $item) {
20
+ if ($item->getParentItem() || $item->getIsVirtual()) {
21
+ // do not add child products or virtual items
22
+ continue;
23
+ }
24
+
25
+ if ($item->getProduct() && $item->getProduct()->isVirtual()) {
26
+ // do not add virtual product
27
+ continue;
28
+ }
29
+
30
+ if ($item->getFreeShipping()) {
31
+ continue;
32
+ }
33
+
34
+ $this->addItem($item);
35
+ }
36
+ return $this;
37
+ }
38
+
39
+ public function addItem($item) {
40
+ if ($item instanceof Mage_Sales_Model_Quote_Item || $item instanceof Mage_Sales_Model_Order_Item || $item instanceof Mage_Sales_Model_Quote_Address_Item || $item instanceof Temando_Temando_Model_Box) {
41
+ if ($item instanceof Mage_Sales_Model_Quote_Item || $item instanceof Mage_Sales_Model_Order_Item || $item instanceof Mage_Sales_Model_Quote_Address_Item) {
42
+ $this->_need_optimize = true;
43
+ }
44
+
45
+ $this->_anythings[] = Mage::getModel('temando/api_request_anything')
46
+ ->setItem($item);
47
+ }
48
+ return $this;
49
+ }
50
+
51
+ public function getItems() {
52
+ return $this->_anythings;
53
+ }
54
+
55
+ public function validate() {
56
+ if (!count($this->_anythings)) {
57
+ // no child items
58
+ return false;
59
+ }
60
+
61
+ // validate each child item
62
+ foreach ($this->_anythings as $anything) {
63
+ /* @var $anything Temando_Temando_Model_Api_Request_Anything */
64
+ if (!$anything->validate()) {
65
+ return false;
66
+ }
67
+ }
68
+ return true;
69
+ }
70
+
71
+ /**
72
+ * Prepares array of anythings for XML API SOAP call
73
+ *
74
+ * @return boolean
75
+ */
76
+ public function toRequestArray() {
77
+ if (!$this->validate()) {
78
+ return false;
79
+ }
80
+ $output = $this->_consolidate();
81
+ return $output;
82
+ }
83
+
84
+ /**
85
+ * Returns combined value of request items.
86
+ *
87
+ * @return float
88
+ */
89
+ public function getGoodsValue()
90
+ {
91
+ $goodsValue = 0;
92
+ foreach($this->_anythings as $anything) {
93
+ /* @var $anything Temando_Temando_Model_Api_Request_Anything */
94
+ $item = $anything->getItem();
95
+ if($item instanceof Temando_Temando_Model_Box) {
96
+ $goodsValue += $item->getValue();
97
+ } else {
98
+ $goodsValue += ($item->getQty() * $item->getPrice());
99
+ }
100
+ }
101
+ return (float) $goodsValue;
102
+ }
103
+
104
+ /**
105
+ * Basic satchel or carton consolidation - 1x satchel or carton for items up to 5kg of weight
106
+ *
107
+ * @return string
108
+ */
109
+ protected function _consolidate() {
110
+ $only_satchel_and_carton = true;
111
+ $has_carton = false;
112
+ $output = array();
113
+ foreach ($this->_anythings as $anything) {
114
+ $request = $anything->toRequestArray();
115
+ if ($request && !in_array($request['packaging'], array('Satchel/Bag', 'Carton'))) {
116
+ $only_satchel_and_carton = false;
117
+ }
118
+ if ($request && ($request['packaging'] == 'Carton')) {
119
+ $has_carton = true;
120
+ }
121
+ if ($this->_need_optimize && $request && in_array($request['packaging'], array('Satchel/Bag', 'Parcel'))) {
122
+ $grams_weight = $request['weight'];
123
+ // locate all items or add new box
124
+ for ($i = 0; $i < $request['quantity']; $i++) {
125
+ $adding = false;
126
+ $found = false;
127
+ foreach ($output as $k => $v) {
128
+ $cur_weight = $v['weight'];
129
+ if ($v && ($v['packaging'] == $request['packaging']) && (5000 > ($grams_weight + $cur_weight))) {
130
+ if ($v['quantity'] > 1) {
131
+ $v['quantity']--;
132
+ $adding = $v;
133
+ $adding['quantity'] = 1;
134
+ $adding['weight'] = $grams_weight + $cur_weight;
135
+ $adding['weightMeasurementType'] = Temando_Temando_Model_System_Config_Source_Unit_Weight::GRAMS;
136
+ } else {
137
+ $v['weight'] = $grams_weight + $cur_weight;
138
+ $v['weightMeasurementType'] = Temando_Temando_Model_System_Config_Source_Unit_Weight::GRAMS;
139
+ }
140
+
141
+ $found = true;
142
+ $output[$k] = $v;
143
+ break;
144
+ }
145
+ }
146
+
147
+ if (!$found) {
148
+ $_t = $request;
149
+ $_t['quantity'] = 1;
150
+ $_t['grams'] = $grams_weight;
151
+ $adding = $_t;
152
+ }
153
+
154
+ if ($adding) {
155
+ $output[] = $adding;
156
+ }
157
+ }
158
+ } else {
159
+ $output[] = $request;
160
+ }
161
+
162
+ if ($only_satchel_and_carton && $has_carton) {
163
+ foreach ($output as $k => $v) {
164
+ $v['packaging'] = 'Carton';
165
+ $output[$k] = $v;
166
+ }
167
+ }
168
+ }
169
+ return $output;
170
+ }
171
+
172
+ }
app/code/community/Temando/Temando/Model/Api/Request/Anytime.php ADDED
@@ -0,0 +1,60 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Temando_Temando_Model_Api_Request_Anytime extends Mage_Core_Model_Abstract {
4
+
5
+ /**
6
+ * @var string
7
+ */
8
+ protected $_ready_time_of_day = null;
9
+
10
+ /**
11
+ * @var string
12
+ */
13
+ protected $_ready_date = null;
14
+
15
+ public function _construct() {
16
+ parent::_construct();
17
+ $this->_init('temando/api_request_anytime');
18
+ }
19
+
20
+ /**
21
+ * Set the date the product will be ready (in UTC).
22
+ *
23
+ * If setting the ready date to a weekend, the next week day will be used instead.
24
+ *
25
+ * Doesn't accept timestamps in the past.
26
+ *
27
+ * @param <type> $timestamp The timestamp when the package will be ready
28
+ * (only the date information is used, the time of day is set separately)
29
+ *
30
+ */
31
+ public function setReadyDate($timestamp = null) {
32
+ $this->_ready_date = Mage::helper('temando')->getReadyDate($timestamp);
33
+ return $this;
34
+ }
35
+
36
+ public function setReadyTimeOfDay($time_of_day = 'AM') {
37
+ if (strtoupper($time_of_day) === 'AM' || strtoupper($time_of_day) === 'PM') {
38
+ $this->_ready_time_of_day = strtoupper($time_of_day);
39
+ }
40
+ return $this;
41
+ }
42
+
43
+ public function validate() {
44
+ return
45
+ ($this->_ready_time_of_day == 'AM' || $this->_ready_time_of_day == 'PM') &&
46
+ is_numeric($this->_ready_date);
47
+ }
48
+
49
+ public function toRequestArray() {
50
+ if (!$this->validate()) {
51
+ return false;
52
+ }
53
+
54
+ return array(
55
+ 'readyDate' => date('Y-m-d', $this->_ready_date),
56
+ 'readyTime' => $this->_ready_time_of_day,
57
+ );
58
+ }
59
+
60
+ }
app/code/community/Temando/Temando/Model/Api/Request/Anywhere.php ADDED
@@ -0,0 +1,46 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Temando_Temando_Model_Api_Request_Anywhere extends Mage_Core_Model_Abstract
4
+ {
5
+
6
+ public function _construct()
7
+ {
8
+ parent::_construct();
9
+ $this->_init('temando/api_request_anywhere');
10
+ }
11
+
12
+ public function toRequestArray()
13
+ {
14
+ if (!$this->validate()) {
15
+ return false;
16
+ }
17
+
18
+ $data = array(
19
+ 'itemNature' => 'Domestic',
20
+ 'itemMethod' => 'Door to Door',
21
+ 'destinationCountry' => $this->getDestinationCountry(),
22
+ 'destinationCode' => $this->getDestinationPostcode(),
23
+ 'destinationSuburb' => $this->getDestinationCity(),
24
+ 'destinationIs' => 'Residence',
25
+ 'destinationBusNotifyBefore' => 'N',
26
+ 'destinationBusLimitedAccess' => 'N',
27
+ 'originBusNotifyBefore' => 'Y',
28
+ 'originDescription' => Temando_Temando_Helper_Data::DEFAULT_WAREHOUSE_NAME
29
+ );
30
+
31
+ if (Mage::helper('temando')->isStreetWithPO($this->getDestinationStreet())) {
32
+ $data['destinationResPostalBox'] = 'Y';
33
+ }
34
+
35
+ return $data;
36
+ }
37
+
38
+ public function validate()
39
+ {
40
+ return
41
+ $this->getDestinationCountry() &&
42
+ $this->getDestinationPostcode() &&
43
+ $this->getDestinationCity();
44
+ }
45
+
46
+ }
app/code/community/Temando/Temando/Model/Box.php ADDED
@@ -0,0 +1,35 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @method string getShipmentId()
5
+ * @method string getComment()
6
+ * @method string getQty()
7
+ * @method string getLength()
8
+ * @method string getWidth()
9
+ * @method string getHeight()
10
+ * @method string getMeasureUnit()
11
+ * @method string getWeight()
12
+ * @method string getWeightUnit()
13
+ * @method string getFragile()
14
+ *
15
+ * @method Temando_Temando_Model_Box setShipmentId()
16
+ * @method Temando_Temando_Model_Box setComment()
17
+ * @method Temando_Temando_Model_Box setQty()
18
+ * @method Temando_Temando_Model_Box setLength()
19
+ * @method Temando_Temando_Model_Box setWidth()
20
+ * @method Temando_Temando_Model_Box setHeight()
21
+ * @method Temando_Temando_Model_Box setMeasureUnit()
22
+ * @method Temando_Temando_Model_Box setWeight()
23
+ * @method Temando_Temando_Model_Box setWeightUnit()
24
+ * @method Temando_Temando_Model_Box setFragile()
25
+ */
26
+ class Temando_Temando_Model_Box extends Mage_Core_Model_Abstract
27
+ {
28
+
29
+ public function _construct()
30
+ {
31
+ parent::_construct();
32
+ $this->_init('temando/box');
33
+ }
34
+
35
+ }
app/code/community/Temando/Temando/Model/Carrier.php ADDED
@@ -0,0 +1,54 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @method Temando_Temando_Model_Carrier setCarrierId()
5
+ * @method Temando_Temando_Model_Carrier setCompanyName()
6
+ * @method Temando_Temando_Model_Carrier setCompanyContact()
7
+ * @method Temando_Temando_Model_Carrier setStreetAddress()
8
+ * @method Temando_Temando_Model_Carrier setStreetSuburb()
9
+ * @method Temando_Temando_Model_Carrier setStreetCity()
10
+ * @method Temando_Temando_Model_Carrier setStreetState()
11
+ * @method Temando_Temando_Model_Carrier setStreetPostode()
12
+ * @method Temando_Temando_Model_Carrier setStreetCountry()
13
+ * @method Temando_Temando_Model_Carrier setPostalAddress()
14
+ * @method Temando_Temando_Model_Carrier setPostalSuburb()
15
+ * @method Temando_Temando_Model_Carrier setPostalCity()
16
+ * @method Temando_Temando_Model_Carrier setPostalState()
17
+ * @method Temando_Temando_Model_Carrier setPostalPostcode()
18
+ * @method Temando_Temando_Model_Carrier setPostalCountry()
19
+ * @method Temando_Temando_Model_Carrier setPhone()
20
+ * @method Temando_Temando_Model_Carrier setEmail()
21
+ * @method Temando_Temando_Model_Carrier setWebsite()
22
+ *
23
+ * @method string getCarrierId()
24
+ * @method string getCompanyName()
25
+ * @method string getCompanyContact()
26
+ * @method string getStreetAddress()
27
+ * @method string getStreetSuburb()
28
+ * @method string getStreetCity()
29
+ * @method string getStreetState()
30
+ * @method string getStreetPostode()
31
+ * @method string getStreetCountry()
32
+ * @method string getPostalAddress()
33
+ * @method string getPostalSuburb()
34
+ * @method string getPostalCity()
35
+ * @method string getPostalState()
36
+ * @method string getPostalPostcode()
37
+ * @method string getPostalCountry()
38
+ * @method string getPhone()
39
+ * @method string getEmail()
40
+ * @method string getWebsite()
41
+ */
42
+ class Temando_Temando_Model_Carrier extends Mage_Core_Model_Abstract
43
+ {
44
+
45
+ const FLAT_RATE = 'flat';
46
+ const FREE = 'free';
47
+
48
+ public function _construct()
49
+ {
50
+ parent::_construct();
51
+ $this->_init('temando/carrier');
52
+ }
53
+
54
+ }
app/code/community/Temando/Temando/Model/Entity/Attribute/Source/Packaging.php ADDED
@@ -0,0 +1,63 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Temando_Temando_Model_Entity_Attribute_Source_Packaging extends Mage_Eav_Model_Entity_Attribute_Source_Abstract
4
+ {
5
+
6
+ public function getAllOptions()
7
+ {
8
+ if (is_null($this->_options)) {
9
+ $this->_options = Mage::getModel('temando/system_config_source_shipment_packaging')->toOptionArray();
10
+ }
11
+ return $this->_options;
12
+ }
13
+
14
+ /**
15
+ * Retrieve Column(s) for Flat
16
+ *
17
+ * @return array
18
+ */
19
+ public function getFlatColums()
20
+ {
21
+ $columns = array();
22
+ $columns[$this->getAttribute()->getAttributeCode()] = array(
23
+ 'type' => 'int(11)',
24
+ 'unsigned' => true,
25
+ 'is_null' => true,
26
+ 'default' => null,
27
+ 'extra' => null
28
+ );
29
+
30
+ return $columns;
31
+ }
32
+
33
+ /**
34
+ * Retrieve Indexes(s) for Flat
35
+ *
36
+ * @return array
37
+ */
38
+ public function getFlatIndexes()
39
+ {
40
+ $indexes = array();
41
+
42
+ $index = 'IDX_' . strtoupper($this->getAttribute()->getAttributeCode());
43
+ $indexes[$index] = array(
44
+ 'type' => 'index',
45
+ 'fields' => array($this->getAttribute()->getAttributeCode())
46
+ );
47
+
48
+ return $indexes;
49
+ }
50
+
51
+ /**
52
+ * Retrieve Select For Flat Attribute update
53
+ *
54
+ * @param int $store
55
+ * @return Varien_Db_Select|null
56
+ */
57
+ public function getFlatUpdateSelect($store)
58
+ {
59
+ return Mage::getResourceModel('eav/entity_attribute')
60
+ ->getFlatUpdateSelect($this->getAttribute(), $store);
61
+ }
62
+
63
+ }
app/code/community/Temando/Temando/Model/Entity/Attribute/Source/Packaging/Mode.php ADDED
@@ -0,0 +1,64 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Temando_Temando_Model_Entity_Attribute_Source_Packaging_Mode extends Mage_Eav_Model_Entity_Attribute_Source_Abstract
4
+ {
5
+
6
+ public function getAllOptions()
7
+ {
8
+ if (is_null($this->_options)) {
9
+ $this->_options = Mage::getModel('temando/system_config_source_shipment_packaging_mode')->toOptionArray();
10
+ }
11
+ return $this->_options;
12
+ }
13
+
14
+ /**
15
+ * Retrieve Column(s) for Flat
16
+ *
17
+ * @return array
18
+ */
19
+ public function getFlatColums()
20
+ {
21
+ $columns = array();
22
+ $columns[$this->getAttribute()->getAttributeCode()] = array(
23
+ 'type' => 'int(11)',
24
+ 'unsigned' => true,
25
+ 'is_null' => true,
26
+ 'default' => null,
27
+ 'extra' => null
28
+ );
29
+
30
+ return $columns;
31
+ }
32
+
33
+ /**
34
+ * Retrieve Indexes(s) for Flat
35
+ *
36
+ * @return array
37
+ */
38
+ public function getFlatIndexes()
39
+ {
40
+ $indexes = array();
41
+
42
+ $index = 'IDX_' . strtoupper($this->getAttribute()->getAttributeCode());
43
+ $indexes[$index] = array(
44
+ 'type' => 'index',
45
+ 'fields' => array($this->getAttribute()->getAttributeCode())
46
+ );
47
+
48
+ return $indexes;
49
+ }
50
+
51
+ /**
52
+ * Retrieve Select For Flat Attribute update
53
+ *
54
+ * @param int $store
55
+ * @return Varien_Db_Select|null
56
+ */
57
+ public function getFlatUpdateSelect($store)
58
+ {
59
+ return Mage::getResourceModel('eav/entity_attribute')
60
+ ->getFlatUpdateSelect($this->getAttribute(), $store);
61
+ }
62
+
63
+ }
64
+
app/code/community/Temando/Temando/Model/Manifest.php ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Temando_Temando_Model_Manifest extends Mage_Core_Model_Abstract
4
+ {
5
+
6
+ public function _construct()
7
+ {
8
+ parent::_construct();
9
+ $this->_init('temando/manifest');
10
+ }
11
+
12
+ }
app/code/community/Temando/Temando/Model/Mysql4/Box.php ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Temando_Temando_Model_Mysql4_Box extends Mage_Core_Model_Mysql4_Abstract
4
+ {
5
+
6
+ public function _construct()
7
+ {
8
+ $this->_init('temando/box', 'id');
9
+ }
10
+
11
+ }
app/code/community/Temando/Temando/Model/Mysql4/Box/Collection.php ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Temando_Temando_Model_Mysql4_Box_Collection extends Mage_Core_Model_Mysql4_Collection_Abstract
4
+ {
5
+
6
+ public function _construct()
7
+ {
8
+ parent::_construct();
9
+ $this->_init('temando/box');
10
+ }
11
+
12
+ }
app/code/community/Temando/Temando/Model/Mysql4/Carrier.php ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Temando_Temando_Model_Mysql4_Carrier extends Mage_Core_Model_Mysql4_Abstract
4
+ {
5
+
6
+ public function _construct()
7
+ {
8
+ $this->_init('temando/carrier', 'id');
9
+ }
10
+
11
+ }
app/code/community/Temando/Temando/Model/Mysql4/Carrier/Collection.php ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Temando_Temando_Model_Mysql4_Carrier_Collection extends Mage_Core_Model_Mysql4_Collection_Abstract
4
+ {
5
+
6
+ public function _construct()
7
+ {
8
+ parent::_construct();
9
+ $this->_init('temando/carrier');
10
+ }
11
+
12
+ }
app/code/community/Temando/Temando/Model/Mysql4/Manifest.php ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Temando_Temando_Model_Mysql4_Manifest extends Mage_Core_Model_Mysql4_Abstract
4
+ {
5
+
6
+ public function _construct()
7
+ {
8
+ $this->_init('temando/manifest', 'id');
9
+ }
10
+
11
+ }
app/code/community/Temando/Temando/Model/Mysql4/Manifest/Collection.php ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Temando_Temando_Model_Mysql4_Manifest_Collection extends Mage_Core_Model_Mysql4_Collection_Abstract
4
+ {
5
+
6
+ public function _construct()
7
+ {
8
+ parent::_construct();
9
+ $this->_init('temando/manifest');
10
+ }
11
+
12
+ }
app/code/community/Temando/Temando/Model/Mysql4/Quote.php ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Temando_Temando_Model_Mysql4_Quote extends Mage_Core_Model_Mysql4_Abstract
4
+ {
5
+
6
+ public function _construct()
7
+ {
8
+ $this->_init('temando/quote', 'id');
9
+ }
10
+
11
+ }
app/code/community/Temando/Temando/Model/Mysql4/Quote/Collection.php ADDED
@@ -0,0 +1,127 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Temando_Temando_Model_Mysql4_Quote_Collection extends Mage_Core_Model_Mysql4_Collection_Abstract
4
+ {
5
+
6
+ protected $_options = null;
7
+
8
+ public function _construct()
9
+ {
10
+ parent::_construct();
11
+ $this->_init('temando/quote');
12
+ }
13
+
14
+ public function __clone()
15
+ {
16
+ $this->load();
17
+ $new_items = array();
18
+ foreach ($this->_items as $item) {
19
+ $new_items[] = clone $item;
20
+ }
21
+ $this->_items = $new_items;
22
+ }
23
+
24
+ /**
25
+ * Gets the fastest quote in the collection.
26
+ *
27
+ * Because quotes' ETAs are specified as a range (e.g. "1-4 days"), the
28
+ * average of the range is used to make the comparison.
29
+ *
30
+ * @return Temando_Temando_Model_Quote
31
+ */
32
+ public function getFastest()
33
+ {
34
+ $fastest = null;
35
+ foreach ($this->_items as $item) {
36
+ $fastest = $this->_getFaster($item, $fastest);
37
+ }
38
+ return $fastest;
39
+ }
40
+
41
+ /**
42
+ * Returns the faster of two quotes.
43
+ *
44
+ * Because quotes' ETAs are specified as a range (e.g. "1-4 days"), the
45
+ * average of the range is used to make the comparison.
46
+ *
47
+ * If one is null, the other is returned. If both are the same average
48
+ * speed, the first quote is returned.
49
+ *
50
+ * @param Temando_Temando_Model_Quote $a the first quote.
51
+ * @param Temando_Temando_Model_Quote $b the second quote.
52
+ *
53
+ * @return Temando_Temando_Model_Quote
54
+ */
55
+ protected function _getFaster($a, $b)
56
+ {
57
+ // if one is null, return the other.
58
+ if (is_null($a)) {
59
+ return $b;
60
+ }
61
+ if (is_null($b)) {
62
+ return $a;
63
+ }
64
+
65
+ // average ETA
66
+ $a_eta = ($a->getEtaFrom() + $a->getEtaTo()) / 2;
67
+ $b_eta = ($b->getEtaFrom() + $b->getEtaTo()) / 2;
68
+
69
+ if ($a_eta != $b_eta) {
70
+ // different speed, return faster
71
+ return $a_eta <= $b_eta ? $a : $b;
72
+ } else {
73
+ // same speed, return cheaper
74
+ return $this->_getCheaper($a, $b);
75
+ }
76
+ }
77
+
78
+ /**
79
+ * Gets the cheapest quote in the collection.
80
+ *
81
+ * @return Temando_Temando_Model_Quote
82
+ */
83
+ public function getCheapest()
84
+ {
85
+ $cheapest = null;
86
+ foreach ($this->_items as $item) {
87
+ $cheapest = $this->_getCheaper($item, $cheapest);
88
+ }
89
+ return $cheapest;
90
+ }
91
+
92
+ /**
93
+ * Returns the cheaper of two quotes.
94
+ *
95
+ * If one is null, the other is returned. If both are the same price, the
96
+ * first quote is returned.
97
+ *
98
+ * @param Temando_Temando_Model_Quote $a the first quote.
99
+ * @param Temando_Temando_Model_Quote $b the second quote.
100
+ *
101
+ * @return Temando_Temando_Model_Quote
102
+ */
103
+ protected function _getCheaper($a, $b)
104
+ {
105
+ // if one is null, return the other (if both are null, null is returned).
106
+ if (is_null($a)) {
107
+ return $b;
108
+ }
109
+ if (is_null($b)) {
110
+ return $a;
111
+ }
112
+
113
+ return $a->getTotalPrice() <= $b->getTotalPrice() ? $a : $b;
114
+ }
115
+
116
+ /**
117
+ * Don't try to load the collection if specific items have been added.
118
+ *
119
+ * @see Varien_Data_Collection::addItem()
120
+ */
121
+ public function addItem(Varien_Object $item)
122
+ {
123
+ $this->_setIsLoaded();
124
+ return parent::addItem($item);
125
+ }
126
+
127
+ }
app/code/community/Temando/Temando/Model/Mysql4/Shipment.php ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Temando_Temando_Model_Mysql4_Shipment extends Mage_Core_Model_Mysql4_Abstract
4
+ {
5
+
6
+ public function _construct()
7
+ {
8
+ $this->_init('temando/shipment', 'id');
9
+ }
10
+
11
+ }
app/code/community/Temando/Temando/Model/Mysql4/Shipment/Collection.php ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Temando_Temando_Model_Mysql4_Shipment_Collection extends Mage_Core_Model_Mysql4_Collection_Abstract
4
+ {
5
+
6
+ public function _construct()
7
+ {
8
+ parent::_construct();
9
+ $this->_init('temando/shipment');
10
+ }
11
+
12
+ /**
13
+ * Returns the shipment associated to an order or null if none
14
+ *
15
+ * NO SUPPORT FOR PARTIAL-SHIPMENTS HERE; ONLY 1 IS RETURNED
16
+ *
17
+ * @param string $orderId
18
+ * @return null|\Temando_Temando_Model_Shipment
19
+ */
20
+ public function loadByOrderId($orderId) {
21
+ if(!$orderId) return false;
22
+
23
+ $this->addFieldToFilter('order_id', $orderId)->load();
24
+ if($this->count())
25
+ return $this->getFirstItem ();
26
+
27
+ return false;
28
+ }
29
+ }
app/code/community/Temando/Temando/Model/Observer.php ADDED
@@ -0,0 +1,147 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Temando_Temando_Model_Observer
4
+ {
5
+
6
+ /**
7
+ * Handles sales_order_place_after event
8
+ */
9
+ public function createTemandoShipment(Varien_Event_Observer $observer)
10
+ {
11
+ $order = $observer->getOrder();
12
+ /* @var $order Mage_Sales_Model_Order */
13
+
14
+ $shippingMethod = $order->getShippingMethod();
15
+ $__t = explode('_', $shippingMethod);
16
+ if ($__t[0] != 'temando') {
17
+ return;
18
+ }
19
+
20
+ $selected_quote_id = preg_replace('#^[^_]*_#', '', $shippingMethod);
21
+ $selected_options = preg_replace('#^([^_]*_){2}#', '', $shippingMethod);
22
+
23
+ $selected_quote = Mage::getModel('temando/quote')->load($selected_quote_id);
24
+ if(!$selected_quote->getId()) {
25
+ //try loading cheapeast quote
26
+ try {
27
+ $selected_quote = $this->loadCheapestQuote($order);
28
+ /* @var $selected_quote Temando_Temando_Model_Quote */
29
+ } catch (Exception $e) {
30
+ $selected_quote = null;
31
+ }
32
+ }
33
+
34
+ $temando_shipment = Mage::getModel('temando/shipment');
35
+ /* @var $temando_shipment Temando_Temando_Model_Shipment */
36
+
37
+ if(Mage::helper('temando')->isQuoteDynamic($selected_quote_id)) {
38
+ //DYNAMIC: carrier quote selected by customer - must have at least 1 available quote
39
+ $temando_shipment
40
+ ->setAdminSelectedQuoteId($selected_quote->getId())
41
+ ->setCustomerSelectedQuoteId($selected_quote->getId())
42
+ ->setCustomerSelectedOptions($selected_options);
43
+ $selected_quote = $temando_shipment->getSelectedQuotePermutation();
44
+ $temando_shipment
45
+ ->setCustomerSelectedQuoteDescription($selected_quote->getDescription())
46
+ ->setAnticipatedCost($selected_quote->getTotalPrice());
47
+
48
+ } else {
49
+ //STATIC: flat rate / free shipping selected by customer
50
+ $temando_shipment
51
+ ->setCustomerSelectedQuoteDescription($selected_quote_id == Temando_Temando_Model_Carrier::FLAT_RATE ? 'Flat Rate' : 'Free Shipping')
52
+ ->setCustomerSelectedOptions('insurance_N_carbonoffset_N_footprints_N');
53
+
54
+ if($selected_quote instanceof Temando_Temando_Model_Quote) {
55
+ //set cheapest as admin selected
56
+ $temando_shipment->setAdminSelectedQuoteId($selected_quote->getId())
57
+ ->setAnticipatedCost($selected_quote->getTotalPrice());
58
+ }
59
+ }
60
+
61
+ $email = $order->getShippingAddress()->getEmail();
62
+ if(!$email) {
63
+ $email = $order->getCustomerEmail();
64
+ }
65
+
66
+ $temando_shipment
67
+ ->setOrderId($order->getId() ? $order->getId() : null)
68
+ ->setStatus(Temando_Temando_Model_System_Config_Source_Shipment_Status::PENDING)
69
+ ->setDestinationContactName($order->getShippingAddress()->getName())
70
+ ->setDestinationCompanyName($order->getShippingAddress()->getCompany())
71
+ ->setDestinationStreet(str_replace("\n", ', ', $order->getShippingAddress()->getStreetFull()))
72
+ ->setDestinationRegion($order->getShippingAddress()->getRegionCode())
73
+ ->setDestinationPhone($order->getShippingAddress()->getTelephone())
74
+ ->setDestinationEmail($email)
75
+ ->setDestinationCountry($order->getShippingAddress()->getCountryId())
76
+ ->setDestinationPostcode($order->getShippingAddress()->getPostcode())
77
+ ->setDestinationCity($order->getShippingAddress()->getCity())
78
+ ->setReadyTime('AM')
79
+ ->save();
80
+
81
+ foreach ($order->getAllVisibleItems() as $item) {
82
+ $product = Mage::getModel('catalog/product')->load($item->getProductId());
83
+ if($product->isVirtual()) { continue; }
84
+
85
+ Mage::helper('temando')->applyTemandoParamsToItem($item);
86
+
87
+ $qty = $item->getQty() ? $item->getQty() : $item->getQtyOrdered();
88
+ $box = Mage::getModel('temando/box');
89
+ /* @var $box Temando_Temando_Model_Box */
90
+ $box
91
+ ->setShipmentId($temando_shipment->getId())
92
+ ->setComment($item->getName())
93
+ ->setQty($item->getQty())
94
+ ->setValue($item->getRowTotalInclTax())
95
+ ->setLength($item->getTemandoLength())
96
+ ->setWidth($item->getTemandoWidth())
97
+ ->setHeight($item->getTemandoHeight())
98
+ ->setMeasureUnit(Mage::helper('temando')->getConfigData('units/measure'))
99
+ ->setWeight($item->getWeight()*$qty)
100
+ ->setWeightUnit(Mage::helper('temando')->getConfigData('units/weight'))
101
+ ->setPackaging($item->getTemandoPackaging())
102
+ ->setFragile($item->getTemandoFragile())
103
+ ->save();
104
+ }
105
+ }
106
+
107
+
108
+ protected function loadCheapestQuote($order)
109
+ {
110
+ $allowed_carriers = explode(',', Mage::getStoreConfig('carriers/temando/allowed_methods'));
111
+ $request = Mage::getModel('temando/api_request');
112
+ /* @var $request Temando_Temando_Model_Api_Request */
113
+ $request
114
+ ->setUsername(Mage::helper('temando')->getConfigData('general/username'))
115
+ ->setPassword(Mage::helper('temando')->getConfigData('general/password'))
116
+ ->setSandbox(Mage::helper('temando')->getConfigData('general/sandbox'))
117
+ ->setMagentoQuoteId($order->getQuoteId())
118
+ ->setDestination(
119
+ $order->getShippingAddress()->getCountry(),
120
+ $order->getShippingAddress()->getPostcode(),
121
+ $order->getShippingAddress()->getCity(),
122
+ $order->getShippingAddress()->getStreet1())
123
+ ->setItems($order->getAllItems())
124
+ ->setReady()
125
+ ->setAllowedCarriers($allowed_carriers);
126
+
127
+ $quotes = $request->getQuotes()->getItems();
128
+ return Mage::helper('temando/functions')->getCheapestQuote($quotes);
129
+ }
130
+
131
+
132
+ public function hookCartSaveAddress($observer)
133
+ {
134
+ $post = $observer->getControllerAction()->getRequest()->getPost();
135
+ if (Mage::getStoreConfig('carriers/temando/active') && isset($post['country_id']) && ('AU' == $post['country_id']) && isset($post['region_id']) && isset($post['estimate_city']) && isset($post['estimate_postcode']) && isset($post['pcs'])) {
136
+ $data = array(
137
+ 'country_id' => $post['country_id'],
138
+ 'region_id' => $post['region_id'],
139
+ 'city' => $post['estimate_city'],
140
+ 'postcode' => $post['estimate_postcode'],
141
+ 'pcs' => $post['pcs'],
142
+ );
143
+ Mage::getSingleton('customer/session')->setData('estimate_product_shipping', new Varien_Object($data));
144
+ }
145
+ }
146
+
147
+ }
app/code/community/Temando/Temando/Model/Option/Abstract.php ADDED
@@ -0,0 +1,204 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ abstract class Temando_Temando_Model_Option_Abstract extends Varien_Object
4
+ {
5
+
6
+ /**
7
+ * The key of this option in a collection.
8
+ *
9
+ * @var string
10
+ */
11
+ protected $_id = null;
12
+
13
+ /**
14
+ * The name of this option as shown on the frontend.
15
+ *
16
+ * @var string
17
+ */
18
+ protected $_name = null;
19
+
20
+ /**
21
+ * The desc of this option as shown on the frontend.
22
+ *
23
+ * @var string
24
+ */
25
+ protected $_desc = null;
26
+
27
+ /**
28
+ * An associative array of the valid values for this option.
29
+ *
30
+ * @var array
31
+ */
32
+ protected $_values = array();
33
+
34
+ /**
35
+ * The forced value, if one exists, otherwise NULL.
36
+ */
37
+ protected $_forced_value = null;
38
+
39
+ /**
40
+ * The type of the action object that applies to this option.
41
+ *
42
+ * @var string
43
+ */
44
+ protected $_action_type = '';
45
+
46
+ /**
47
+ * The object that performs the action that applies to this option.
48
+ *
49
+ * @var Temando_Temando_Model_Option_Action_Abstract
50
+ */
51
+ protected $_action = null;
52
+
53
+
54
+ /**
55
+ * Calls the _setupValues() method to initialise the values array.
56
+ *
57
+ * (non-PHPdoc)
58
+ *
59
+ * @see Varien_Object::_construct()
60
+ */
61
+ protected function _construct()
62
+ {
63
+ parent::_construct();
64
+ $this->_setupValues();
65
+ $this->_setupAction();
66
+ }
67
+
68
+ /**
69
+ * Sets up the $this->_values array.
70
+ *
71
+ * Called in the self::_construct() method.
72
+ */
73
+ abstract protected function _setupValues();
74
+
75
+ /**
76
+ * Sets up the action that applies to this option.
77
+ *
78
+ * Called in the self::_construct() method.
79
+ */
80
+ protected function _setupAction()
81
+ {
82
+ $model_name = 'temando/option_action_' . $this->_action_type;
83
+ $this->_action = Mage::getModel($model_name);
84
+
85
+ if (!$this->_action) {
86
+ throw Mage::exception('Temando_Temando', 'Incorrect action model for option.');
87
+ }
88
+ }
89
+
90
+ /**
91
+ * Use the ID in this class, for use in collections etc.
92
+ *
93
+ * (non-PHPdoc)
94
+ *
95
+ * @see Varien_Object::getId()
96
+ */
97
+ public function getId()
98
+ {
99
+ return $this->_id;
100
+ }
101
+
102
+ /**
103
+ * Gets the name of this option as shown on the frontend.
104
+ *
105
+ * @return string
106
+ */
107
+ public function getName()
108
+ {
109
+ return $this->_name;
110
+ }
111
+
112
+ /**
113
+ * Gets the valid values for this option as an associative array.
114
+ *
115
+ * Format is as follows:
116
+ *
117
+ * array(
118
+ * $value => $label,
119
+ * // ...
120
+ * )
121
+ *
122
+ * where $value is what's used internally and $label is shown on the
123
+ * frontend.
124
+ *
125
+ * @return array
126
+ */
127
+ public function getValues()
128
+ {
129
+ return $this->_values;
130
+ }
131
+
132
+ /**
133
+ * Gets the label for a given value of this option.
134
+ */
135
+ public function getLabel($value)
136
+ {
137
+ if (array_key_exists($value, $this->_values)) {
138
+ return $this->_values[$value];
139
+ }
140
+ return null;
141
+ }
142
+
143
+ /**
144
+ * Gets the description for the option
145
+ */
146
+ public function getDescription()
147
+ {
148
+ return $this->_desc;
149
+ }
150
+
151
+ /**
152
+ * Sets one of the values for this option as the only available selection.
153
+ *
154
+ * The $forced_value parameter should be a key in the array returned by
155
+ * $this->getValues(), otherwise no action is taken.
156
+ *
157
+ * @return Temando_Temando_Model_Option_Abstract
158
+ */
159
+ public function setForcedValue($forced_value)
160
+ {
161
+ if (array_key_exists($forced_value, $this->_values) || $forced_value === null) {
162
+ $this->_forced_value = $forced_value;
163
+ }
164
+
165
+ return $this;
166
+ }
167
+
168
+ /**
169
+ * Gets the forced value for this option (if there is one), otherwise NULL.
170
+ *
171
+ * A forced option is one that can't be changed by the customer.
172
+ */
173
+ public function getForcedValue()
174
+ {
175
+ return $this->_forced_value;
176
+ }
177
+
178
+ /**
179
+ * Applies a given value of this option to a quote.
180
+ *
181
+ * A copy of the quote is returned, with the option's effects applied.
182
+ *
183
+ * @param Temando_Temando_Model_Quote $quote
184
+ * @return Temando_Temando_Model_Option_Abstract
185
+ */
186
+ public function apply($value, &$quote)
187
+ {
188
+ $this->_apply($value, $quote);
189
+ return $this;
190
+ }
191
+
192
+ /**
193
+ * Does the actual applying of the quote, based on the value of the option.
194
+ *
195
+ * Returns true if the action was applied, or false if it wasn't.
196
+ *
197
+ * (Overridden in child classes)
198
+ *
199
+ * @param $value
200
+ * @param Temando_Temando_Model_Quote $quote
201
+ */
202
+ abstract protected function _apply($value, &$quote);
203
+
204
+ }
app/code/community/Temando/Temando/Model/Option/Action/Abstract.php ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ abstract class Temando_Temando_Model_Option_Action_Abstract extends Varien_Object
4
+ {
5
+
6
+ /**
7
+ * Applies the action to a given quote.
8
+ *
9
+ * @param Temando_Temando_Model_Quote $quote
10
+ */
11
+ abstract public function apply(&$quote);
12
+
13
+ }
app/code/community/Temando/Temando/Model/Option/Action/Carbon.php ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Temando_Temando_Model_Option_Action_Carbon extends Temando_Temando_Model_Option_Action_Abstract
4
+ {
5
+
6
+ public function apply(&$quote)
7
+ {
8
+ /* @var $quote Temando_Temando_Model_Quote */
9
+ $price = $quote->getTotalPrice();
10
+ $carbon_price = $quote->getCarbonTotalPrice();
11
+
12
+ $quote->setTotalPrice($price + $carbon_price);
13
+ }
14
+
15
+ }
app/code/community/Temando/Temando/Model/Option/Action/Footprints.php ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Temando_Temando_Model_Option_Action_Footprints extends Temando_Temando_Model_Option_Action_Abstract
4
+ {
5
+
6
+ public function apply(&$quote)
7
+ {
8
+ /* @var $quote Temando_Temando_Model_Quote */
9
+ $price = $quote->getTotalPrice();
10
+ $footprints_price = $quote->getFootprintsTotalPrice();
11
+
12
+ $quote->setTotalPrice($price + $footprints_price);
13
+ }
14
+
15
+ }
app/code/community/Temando/Temando/Model/Option/Action/Insurance.php ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Temando_Temando_Model_Option_Action_Insurance extends Temando_Temando_Model_Option_Action_Abstract
4
+ {
5
+
6
+ public function apply(&$quote)
7
+ {
8
+ /* @var $quote Temando_Temando_Model_Quote */
9
+ $price = $quote->getTotalPrice();
10
+ $insurance_price = $quote->getInsuranceTotalPrice();
11
+
12
+ $quote->setTotalPrice($price + $insurance_price);
13
+ }
14
+
15
+ }
app/code/community/Temando/Temando/Model/Option/Action/Markup.php ADDED
@@ -0,0 +1,125 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Temando_Temando_Model_Option_Action_Markup extends Temando_Temando_Model_Option_Action_Abstract
4
+ {
5
+
6
+ /**
7
+ * The markup amount.
8
+ *
9
+ * This can be either a percentage or fixed amount (controlled
10
+ * by $this->_markup_type).
11
+ *
12
+ * @var float
13
+ */
14
+ protected $_markup = self::DEFAULT_MARKUP;
15
+
16
+ /**
17
+ * Controls the way the markup amount ($this->_markup) is interpreted
18
+ * (either a fixed amount, or percentage).
19
+ *
20
+ * Shold be one of:
21
+ * - Mage_Shipping_Model_Carrier_Abstract::HANDLING_TYPE_FIXED // == 'F'
22
+ * - Mage_Shipping_Model_Carrier_Abstract::HANDLING_TYPE_PERCENT // == 'P'
23
+ *
24
+ * @var unknown_type
25
+ */
26
+ protected $_markup_type = self::DEFAULT_MARKUP_TYPE;
27
+
28
+
29
+ /**
30
+ * The default markup amount.
31
+ *
32
+ * @var float
33
+ */
34
+ const DEFAULT_MARKUP = 1;
35
+
36
+ /**
37
+ * The default markup type.
38
+ *
39
+ * @var string
40
+ */
41
+ const DEFAULT_MARKUP_TYPE = Mage_Shipping_Model_Carrier_Abstract::HANDLING_TYPE_PERCENT;
42
+
43
+ /**
44
+ * Sets the markup amount.
45
+ *
46
+ * This can be either a percentage or a fixed amount (controlled by
47
+ * $this->setMarkupType()).
48
+ *
49
+ * @param unknown_type $type
50
+ *
51
+ * @return Temando_Temando_Model_Option_Action_Markup
52
+ */
53
+ public function setMarkup($amount)
54
+ {
55
+ if (is_numeric($amount)) {
56
+ $this->_markup = $amount;
57
+ }
58
+
59
+ return $this;
60
+ }
61
+
62
+ /**
63
+ * Gets the markup amount.
64
+ *
65
+ * @return float
66
+ */
67
+ public function getMarkup()
68
+ {
69
+ return (float) $this->_markup;
70
+ }
71
+
72
+ /**
73
+ * Controls the way the markup amount (set with $this->setMarkup()) is
74
+ * interpreted (either a fixed amount, or percentage).
75
+ *
76
+ * Shold be one of:
77
+ * - Mage_Shipping_Model_Carrier_Abstract::HANDLING_TYPE_FIXED // == 'F'
78
+ * - Mage_Shipping_Model_Carrier_Abstract::HANDLING_TYPE_PERCENT // == 'P'
79
+ *
80
+ * @param string $type
81
+ *
82
+ * @return Temando_Temando_Model_Option_Action_Markup
83
+ */
84
+ public function setMarkupType($type)
85
+ {
86
+ $valid = (
87
+ $type === Mage_Shipping_Model_Carrier_Abstract::HANDLING_TYPE_FIXED ||
88
+ $type === Mage_Shipping_Model_Carrier_Abstract::HANDLING_TYPE_PERCENT
89
+ );
90
+
91
+ if ($valid) {
92
+ $this->_markup_type = $type;
93
+ }
94
+
95
+ return $this;
96
+ }
97
+
98
+ /**
99
+ * Gets the markup type (either a fixed amount, or percentage).
100
+ *
101
+ * @return string
102
+ */
103
+ public function getMarkupType()
104
+ {
105
+ return $this->_markup_type;
106
+ }
107
+
108
+ public function apply(&$quote)
109
+ {
110
+ $price = $quote->getTotalPrice();
111
+
112
+ switch ($this->getMarkupType()) {
113
+ case Mage_Shipping_Model_Carrier_Abstract::HANDLING_TYPE_FIXED:
114
+ $price += $this->getMarkup();
115
+ break;
116
+
117
+ case Mage_Shipping_Model_Carrier_Abstract::HANDLING_TYPE_PERCENT:
118
+ $price *= 1 + ($this->getMarkup() / 100);
119
+ break;
120
+ }
121
+
122
+ $quote->setTotalPrice($price);
123
+ }
124
+
125
+ }
app/code/community/Temando/Temando/Model/Option/Boolean.php ADDED
@@ -0,0 +1,46 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * A boolean (yes/no) option.
5
+ *
6
+ * The action (specified by $this->_action_type) is applied to quotes if the
7
+ * value is self::YES, otherwise no action is taken.
8
+ *
9
+ * @method Temando_Temando_Model_Option_Boolean setYesAllowed
10
+ * @method Temando_Temando_Model_Option_Boolean setNoAllowed
11
+ * @method boolean getYesAllowed
12
+ * @method boolean getNoAllowed
13
+ */
14
+ abstract class Temando_Temando_Model_Option_Boolean extends Temando_Temando_Model_Option_Abstract
15
+ {
16
+
17
+ const YES = 'Y';
18
+ const NO = 'N';
19
+
20
+ protected function _setupValues()
21
+ {
22
+ $this->_values= array(
23
+ self::YES => Mage::helper('temando')->__('Yes'),
24
+ self::NO => Mage::helper('temando')->__('No'),
25
+ );
26
+ }
27
+
28
+ /**
29
+ * Only apply the action if the forced value is self::YES, or the value
30
+ * is self::YES (as long as the forced value isn't self::NO).
31
+ *
32
+ * (non-PHPdoc)
33
+ *
34
+ * @see Temando_Temando_Model_Option_Abstract::_apply()
35
+ */
36
+ protected function _apply($value, &$quote)
37
+ {
38
+ if (($value === self::YES && $this->getForcedValue() !== self::NO) || $this->getForcedValue() === self::YES) {
39
+ $this->_action->apply($quote);
40
+ return true;
41
+ } else {
42
+ return false;
43
+ }
44
+ }
45
+
46
+ }
app/code/community/Temando/Temando/Model/Option/Carbonoffset.php ADDED
@@ -0,0 +1,78 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Temando_Temando_Model_Option_Carbonoffset extends Temando_Temando_Model_Option_Boolean
4
+ {
5
+
6
+ protected $_id = 'carbonoffset';
7
+ protected $_name = 'Include Carbon Offset';
8
+ protected $_action_type = 'carbon';
9
+ protected $_desc = "The Gaia Partnership's CO2counter calculates the carbon emissions that are attributed to your transport needs. If you do not wish to offset the carbon emissions from your transport service please unselect the tick box above.";
10
+
11
+ /**
12
+ * Sets the current "setting" for carbon offsets.
13
+ *
14
+ * This should be one of the options from the carbon offset source model
15
+ * (Temando_Temando_Model_System_Config_Source_Carbon). These include
16
+ * "disabled", "optional", and "mandatory". Depending on which setting is
17
+ * active, the customer's choice of carbon offsets will be restricted.
18
+ */
19
+ public function setSetting($value)
20
+ {
21
+ switch ($value) {
22
+ case Temando_Temando_Model_System_Config_Source_Carbon::DISABLED:
23
+ $this->setForcedValue(self::NO);
24
+ break;
25
+
26
+ case Temando_Temando_Model_System_Config_Source_Carbon::MANDATORY:
27
+ $this->setForcedValue(self::YES);
28
+ break;
29
+
30
+ case Temando_Temando_Model_System_Config_Source_Carbon::OPTIONAL:
31
+ $this->setForcedValue(null); // no forced value
32
+ break;
33
+ }
34
+
35
+ return $this;
36
+ }
37
+
38
+ /**
39
+ * Sets the markup amount.
40
+ *
41
+ * @param float $value
42
+ */
43
+ public function setMarkup($value)
44
+ {
45
+ $this->_action->setMarkup($value);
46
+ return $this;
47
+ }
48
+
49
+ /**
50
+ * Controls the way the markup amount (set with $this->setMarkup()) is
51
+ * interpreted (either a fixed amount, or percentage).
52
+ *
53
+ * @param string $type
54
+ */
55
+ public function setMarkupType($type)
56
+ {
57
+ $this->_action->setMarkupType($type);
58
+ return $this;
59
+ }
60
+
61
+ /**
62
+ * The parent function applies the action depending on the value, here we
63
+ * also update the quote's information to indicate that it includes
64
+ * the carbon offset.
65
+ *
66
+ * (non-PHPdoc)
67
+ *
68
+ * @see Temando_Temando_Model_Option_Boolean::_apply()
69
+ */
70
+ protected function _apply($value, &$quote)
71
+ {
72
+ /* @var $quote Temando_Temando_Model_Quote */
73
+ if (parent::_apply($value, $quote)) {
74
+ $quote->setCarbonIncluded(true);
75
+ }
76
+ }
77
+
78
+ }
app/code/community/Temando/Temando/Model/Option/Footprints.php ADDED
@@ -0,0 +1,55 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Temando_Temando_Model_Option_Footprints extends Temando_Temando_Model_Option_Boolean
4
+ {
5
+
6
+ protected $_id = 'footprints';
7
+ protected $_name = 'Include Charitable Micro donation';
8
+ protected $_action_type = 'footprints';
9
+ protected $_desc = "Include a $1 donation to charity in your transaction. The Footprints Network aggregates thousands of donations from online transactions to fund community development projects. Visit Footprintsnetwork.org to view projects.";
10
+
11
+ /**
12
+ * Sets the current "setting" for footprints.
13
+ *
14
+ * This should be one of the options from the footprints source model
15
+ * (Temando_Temando_Model_System_Config_Source_Footprints). These include
16
+ * "disabled", "optional", and "mandatory". Depending on which setting is
17
+ * active, the customer's choice of footprints will be restricted.
18
+ */
19
+ public function setSetting($value)
20
+ {
21
+ switch ($value) {
22
+ case Temando_Temando_Model_System_Config_Source_Footprints::DISABLED:
23
+ $this->setForcedValue(self::NO);
24
+ break;
25
+
26
+ case Temando_Temando_Model_System_Config_Source_Footprints::MANDATORY:
27
+ $this->setForcedValue(self::YES);
28
+ break;
29
+
30
+ case Temando_Temando_Model_System_Config_Source_Footprints::OPTIONAL:
31
+ $this->setForcedValue(null); // no forced value
32
+ break;
33
+ }
34
+
35
+ return $this;
36
+ }
37
+
38
+ /**
39
+ * The parent function applies the action depending on the value, here we
40
+ * also update the quote's information to indicate that it includes
41
+ * the footprints.
42
+ *
43
+ * (non-PHPdoc)
44
+ *
45
+ * @see Temando_Temando_Model_Option_Boolean::_apply()
46
+ */
47
+ protected function _apply($value, &$quote)
48
+ {
49
+ /* @var $quote Temando_Temando_Model_Quote */
50
+ if (parent::_apply($value, $quote)) {
51
+ $quote->setFootprintsIncluded(true);
52
+ }
53
+ }
54
+
55
+ }
app/code/community/Temando/Temando/Model/Option/Insurance.php ADDED
@@ -0,0 +1,78 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Temando_Temando_Model_Option_Insurance extends Temando_Temando_Model_Option_Boolean
4
+ {
5
+
6
+ protected $_id = 'insurance';
7
+ protected $_name = 'Include Delivery Insurance';
8
+ protected $_action_type = 'insurance';
9
+ protected $_desc = 'For your convenience, the company arranging the transport of your newly purchased item provides you with insurance for a nominal fee of 1.1% of your purchase price (inclusive of GST).';
10
+
11
+ /**
12
+ * Sets the current "setting" for insurance.
13
+ *
14
+ * This should be one of the options from the Insurance source model
15
+ * (Temando_Temando_Model_System_Config_Source_Insurance). These include
16
+ * "disabled", "optional", and "mandatory". Depending on which setting is
17
+ * active, the customer's choice of insurance will be restricted.
18
+ */
19
+ public function setSetting($value)
20
+ {
21
+ switch ($value) {
22
+ case Temando_Temando_Model_System_Config_Source_Insurance::DISABLED:
23
+ $this->setForcedValue(self::NO);
24
+ break;
25
+
26
+ case Temando_Temando_Model_System_Config_Source_Insurance::MANDATORY:
27
+ $this->setForcedValue(self::YES);
28
+ break;
29
+
30
+ case Temando_Temando_Model_System_Config_Source_Insurance::OPTIONAL:
31
+ $this->setForcedValue(null); // no forced value
32
+ break;
33
+ }
34
+
35
+ return $this;
36
+ }
37
+
38
+ /**
39
+ * Sets the markup amount.
40
+ *
41
+ * @param float $value
42
+ */
43
+ public function setMarkup($value)
44
+ {
45
+ $this->_action->setMarkup($value);
46
+ return $this;
47
+ }
48
+
49
+ /**
50
+ * Controls the way the markup amount (set with $this->setMarkup()) is
51
+ * interpreted (either a fixed amount, or percentage).
52
+ *
53
+ * @param string $type
54
+ */
55
+ public function setMarkupType($type)
56
+ {
57
+ $this->_action->setMarkupType($type);
58
+ return $this;
59
+ }
60
+
61
+ /**
62
+ * The parent function applies the action depending on the value, here we
63
+ * also update the quote's information to indicate that it includes
64
+ * insurance.
65
+ *
66
+ * (non-PHPdoc)
67
+ *
68
+ * @see Temando_Temando_Model_Option_Boolean::_apply()
69
+ */
70
+ protected function _apply($value, &$quote)
71
+ {
72
+ /* @var $quote Temando_Temando_Model_Quote */
73
+ if (parent::_apply($value, $quote)) {
74
+ $quote->setInsuranceIncluded(true);
75
+ }
76
+ }
77
+
78
+ }
app/code/community/Temando/Temando/Model/Options.php ADDED
@@ -0,0 +1,118 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Temando_Temando_Model_Options extends Varien_Data_Collection
4
+ {
5
+
6
+ /**
7
+ * Applies all options to a quote, returning a quote for every combination.
8
+ *
9
+ * For example, if there are three boolean options available, there will
10
+ * be eight quotes returned. In general, for (n) options with (m) values,
11
+ * there will be (m^n) quotes returned.
12
+ *
13
+ * @param Temando_Temando_Model_Quote $quote
14
+ */
15
+ public function applyAll($quote)
16
+ {
17
+ if (!($quote instanceof Temando_Temando_Model_Quote)) {
18
+ return null;
19
+ }
20
+
21
+ /* @var $quote Temando_Temando_Model_Quote */
22
+ $quotes = array();
23
+ foreach ($this->_listPermutations() as $permutation) {
24
+ // apply every option to the quote
25
+ $permutation_id = '';
26
+ $new_quote = clone $quote;
27
+ $valid = true;
28
+
29
+ // apply all options to the new quote
30
+ foreach ($permutation as $option_id => $option_value) {
31
+ $option = $this->getItemById($option_id);
32
+ /* @var $option Temando_Temando_Model_Option_Abstract */
33
+ $extras = $new_quote->getExtras();
34
+ if ($valid) {
35
+ if ($option_value == 'Y' && (!is_array($extras) || !array_key_exists($option_id, $extras))) {
36
+ $valid = false;
37
+ }
38
+
39
+ if ($extras && isset($extras[$option_id])) {
40
+ $extra_field = $extras[$option_id];
41
+ if (isset($extra_field['mandatory']) && ($option_value == 'N') && ($extra_field['mandatory'] == 'Y')) {
42
+ $valid = false;
43
+ }
44
+ }
45
+ }
46
+
47
+ $option->apply($option_value, $new_quote);
48
+
49
+ $permutation_id .= $option_id . '_' . $option_value . '_';
50
+ }
51
+
52
+ // remove last underscore
53
+ $permutation_id = substr($permutation_id, 0, -1);
54
+
55
+ if ($valid) {
56
+ $quotes[$permutation_id] = $new_quote;
57
+ }
58
+ }
59
+
60
+ return $quotes;
61
+ }
62
+
63
+ /**
64
+ * Works out all the possible permutations for a given set of options.
65
+ *
66
+ * This function works recursively to build every combination of values
67
+ * for every option.
68
+ *
69
+ * The return value is in the following format:
70
+ *
71
+ * array(
72
+ * array(
73
+ * 'option_1_id' => 'option_1_value_a',
74
+ * 'option_2_id' => 'option_2_value_a',
75
+ * // ...
76
+ * ),
77
+ * array(
78
+ * 'option_1_id' => 'option_1_value_a',
79
+ * 'option_2_id' => 'option_2_value_b',
80
+ * // ...
81
+ * ),
82
+ * // ...
83
+ * );
84
+ *
85
+ * @param array $options
86
+ * @param array $progress
87
+ *
88
+ * @return array
89
+ */
90
+ protected function _listPermutations($options = null, $progress = array())
91
+ {
92
+ if ($options === null) {
93
+ $options = $this->_items;
94
+ }
95
+
96
+ if (count($options) > 0) {
97
+ // remove head of list and keep it in $current_option
98
+ $current_option = each($options);
99
+ array_shift($options);
100
+
101
+ // build up permutations
102
+ $permutations = array();
103
+
104
+ foreach ($current_option['value']->getValues() as $value => $label) {
105
+ // only use this value if there's no forced value, or if this is the forced value.
106
+ if ($current_option['value']->getForcedValue() === null || $current_option['value']->getForcedValue() == $value) {
107
+ $progress[$current_option['key']] = $value;
108
+ $permutations = array_merge($permutations, $this->_listPermutations($options, $progress));
109
+ }
110
+ }
111
+
112
+ return $permutations;
113
+ } else {
114
+ return array($progress);
115
+ }
116
+ }
117
+
118
+ }
app/code/community/Temando/Temando/Model/Pcs.php ADDED
@@ -0,0 +1,106 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * @method Temando_Temando_Model_Pcs setCountry()
4
+ * @method Temando_Temando_Model_Pcs setQuery()
5
+ *
6
+ * @method string getCountry()
7
+ * @method string getQuery()
8
+ */
9
+
10
+ class Temando_Temando_Model_Pcs extends Mage_Core_Model_Abstract
11
+ {
12
+ /**
13
+ * Address validation Temando AVS URL
14
+ */
15
+ const AVS_URL = "http://avs.temando.com/avs/search/country/%s/%s.json";
16
+
17
+ /**
18
+ * The HTTP Client
19
+ * @var Varien_Http_Client
20
+ */
21
+ protected $_client = null;
22
+
23
+ /**
24
+ * Default country (only one country in allowed countries)
25
+ * @var string
26
+ */
27
+ protected $_defaultCountry = null;
28
+
29
+
30
+ public function _construct()
31
+ {
32
+ parent::_construct();
33
+ $this->_prepareClient()->_loadDefaultCountry();
34
+ }
35
+
36
+ /**
37
+ * Returns address postcode/country combinations as an array.
38
+ * Empty array is returned if no suggestions are found.
39
+ *
40
+ * @return array
41
+ */
42
+ public function getSuggestions()
43
+ {
44
+ if(!$this->_validate()) {
45
+ return array();
46
+ }
47
+
48
+ $url = sprintf(self::AVS_URL, strtoupper($this->getCountry()), rawurlencode($this->getQuery()));
49
+ try {
50
+ $this->_client->setUri($url);
51
+ $responseBody = $this->_client->request(Varien_Http_Client::GET)->getBody();
52
+ return Mage::helper('core')->jsonDecode($responseBody);
53
+ } catch (Exception $e) {
54
+ Mage::log($e->getMessage(), null, 'temando.log', true);
55
+ return array();
56
+ }
57
+ }
58
+
59
+ /**
60
+ * Checks current request - country & query
61
+ *
62
+ * @return boolean
63
+ */
64
+ protected function _validate()
65
+ {
66
+ if (strlen(trim($this->getCountry())) === 0 && $this->_defaultCountry) {
67
+ $this->setCountry($this->_defaultCountry);
68
+ }
69
+ return strlen(trim($this->getCountry())) > 0 &&
70
+ strlen(trim($this->getQuery())) > 0;
71
+
72
+ }
73
+
74
+ /**
75
+ * Initializes http client to communicate with AVS service
76
+ *
77
+ * @return \Temando_Temando_Model_Pcs
78
+ */
79
+ protected function _prepareClient()
80
+ {
81
+ if(!$this->_client) {
82
+ $this->_client = new Varien_Http_Client();
83
+ $this->_client->setConfig(array('maxredirects' => 0, 'timeout' => 15));
84
+ }
85
+ return $this;
86
+ }
87
+
88
+ /**
89
+ * Loads default destination country
90
+ *
91
+ * @return \Temando_Temando_Model_Pcs
92
+ */
93
+ protected function _loadDefaultCountry()
94
+ {
95
+ if(is_null($this->_defaultCountry)) {
96
+ $allowed = Mage::helper('temando')->getAllowedCountries();
97
+ if (count($allowed) === 1) {
98
+ //one allowed country - load as default
99
+ reset($allowed);
100
+ $this->_defaultCountry = key($allowed);
101
+ }
102
+ }
103
+ return $this;
104
+ }
105
+
106
+ }
app/code/community/Temando/Temando/Model/Quote.php ADDED
@@ -0,0 +1,320 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @method Temando_Temando_Model_Quote setGenerated()
5
+ * @method Temando_Temando_Model_Quote setAccepted()
6
+ * @method Temando_Temando_Model_Quote setTotalPrice()
7
+ * @method Temando_Temando_Model_Quote setBasePrice()
8
+ * @method Temando_Temando_Model_Quote setTax()
9
+ * @method Temando_Temando_Model_Quote setCurrency()
10
+ * @method Temando_Temando_Model_Quote setDeliveryMethod()
11
+ * @method Temando_Temando_Model_Quote setUsingGeneralRail()
12
+ * @method Temando_Temando_Model_Quote setUsingGeneralRoad()
13
+ * @method Temando_Temando_Model_Quote setUsingGeneralSea()
14
+ * @method Temando_Temando_Model_Quote setUsingExpressAir()
15
+ * @method Temando_Temando_Model_Quote setUsingExpressRoad()
16
+ * @method Temando_Temando_Model_Quote setEtaFrom()
17
+ * @method Temando_Temando_Model_Quote setEtaTo()
18
+ * @method Temando_Temando_Model_Quote setGuaranteedEta()
19
+ * @method Temando_Temando_Model_Quote setLoaded()
20
+ * @method Temando_Temando_Model_Quote setInsuranceIncluded()
21
+ * @method Temando_Temando_Model_Quote setCarbonIncluded()
22
+ * @method Temando_Temando_Model_Quote setFootprintsIncluded()
23
+ * @method Temando_Temando_Model_Quote setFootprintsTotalPrice()
24
+ *
25
+ * @method string getGenerated()
26
+ * @method string getAccepted()
27
+ * @method string getTotalPrice()
28
+ * @method string getBasePrice()
29
+ * @method string getTax()
30
+ * @method string getCurrency()
31
+ * @method string getDeliveryMethod()
32
+ * @method string getUsingGeneralRail()
33
+ * @method string getUsingGeneralRoad()
34
+ * @method string getUsingGeneralSea()
35
+ * @method string getUsingExpressAir()
36
+ * @method string getUsingExpressRoad()
37
+ * @method string getEtaFrom()
38
+ * @method string getEtaTo()
39
+ * @method string getGuaranteedEta()
40
+ * @method string getLoaded()
41
+ * @method boolean getInsuranceIncluded()
42
+ * @method boolean getCarbonIncluded()
43
+ * @method boolean getFootprintsIncluded()
44
+ * @method float getFootprintsTotalPrice()
45
+ */
46
+ class Temando_Temando_Model_Quote extends Mage_Core_Model_Abstract
47
+ {
48
+
49
+ protected $_carrier = null;
50
+
51
+ public function _construct()
52
+ {
53
+ parent::_construct();
54
+ $this->_init('temando/quote');
55
+ }
56
+
57
+ public function __clone()
58
+ {
59
+ $this->_carrier = clone $this->getCarrier();
60
+ }
61
+
62
+ /**
63
+ * Sets the carrier providing this quote.
64
+ *
65
+ * @param <type> $carrier_id
66
+ *
67
+ * @return Temando_Temando_Model_Quote
68
+ */
69
+ public function setCarrier($carrier_id)
70
+ {
71
+ $carrier = Mage::getModel('temando/carrier')
72
+ ->load($carrier_id);
73
+
74
+ if ($carrier->getId() == $carrier_id) {
75
+ // exists in the database
76
+ $this->_carrier = $carrier;
77
+ $this->setData('carrier_id', $carrier_id);
78
+ }
79
+ return $this;
80
+ }
81
+
82
+ /**
83
+ * Gets the carrier providing this quote.
84
+ *
85
+ * @return Temando_Temando_Model_Carrier
86
+ */
87
+ public function getCarrier()
88
+ {
89
+ if (!$this->_carrier) {
90
+ $this->setCarrier($this->getCarrierId());
91
+ }
92
+ return $this->_carrier;
93
+ }
94
+
95
+ /**
96
+ * Loads values into this object from a
97
+ *
98
+ * @param stdClass $response the SOAP response directly from the Temando
99
+ * API.
100
+ */
101
+ public function loadResponse(stdClass $response)
102
+ {
103
+ if ($response instanceof stdClass) {
104
+ $carrier = Mage::getModel('temando/carrier')->load($response->carrier->id, 'carrier_id');
105
+ /* @var $carrier Temando_Temando_Model_Carrier */
106
+
107
+ $carrier
108
+ ->setCarrierId(isset($response->carrier->id) ? $response->carrier->id : '')
109
+ ->setCompanyName(isset($response->carrier->companyName) ? $response->carrier->companyName : '')
110
+ ->setCompanyContact(isset($response->carrier->companyContact) ? $response->carrier->companyContact : '')
111
+ ->setStreetAddress(isset($response->carrier->streetAddress) ? $response->carrier->streetAddress : '')
112
+ ->setStreetSuburb(isset($response->carrier->streetSuburb) ? $response->carrier->streetSuburb : '')
113
+ ->setStreetCity(isset($response->carrier->streetCity) ? $response->carrier->streetCity : '')
114
+ ->setStreetState(isset($response->carrier->streetState) ? $response->carrier->streetState : '')
115
+ ->setStreetPostcode(isset($response->carrier->streetCode) ? $response->carrier->streetCode : '')
116
+ ->setStreetCountry(isset($response->carrier->streetCountry) ? $response->carrier->streetCountry : '')
117
+ ->setPostalAddress(isset($response->carrier->postalAddress) ? $response->carrier->postalAddress : '')
118
+ ->setPostalSuburb(isset($response->carrier->postalSuburb) ? $response->carrier->postalSuburb : '')
119
+ ->setPostalCity(isset($response->carrier->postalCity) ? $response->carrier->postalCity : '')
120
+ ->setPostalState(isset($response->carrier->postalState) ? $response->carrier->postalState : '')
121
+ ->setPostalPostcode(isset($response->carrier->postalCode) ? $response->carrier->postalCode : '')
122
+ ->setPostalCountry(isset($response->carrier->postalCountry) ? $response->carrier->postalCountry : '')
123
+ ->setPhone(isset($response->carrier->phone1) ? $response->carrier->phone1 : '')
124
+ ->setEmail(isset($response->carrier->email) ? $response->carrier->email : '')
125
+ ->setWebsite(isset($response->carrier->website) ? $response->carrier->website : '')
126
+ ->save();
127
+
128
+ $extras = $response->extras->extra;
129
+ if (!is_array($extras)) {
130
+ $extras = array($extras);
131
+ }
132
+
133
+ $extras_array = array();
134
+
135
+ foreach ($extras as $extra) {
136
+ $extra_id = trim(strtolower($extra->summary));
137
+ $extra_id = str_replace(' ', '', $extra_id);
138
+ $extras_array[$extra_id] = array(
139
+ 'summary' => $extra->summary,
140
+ 'details' => $extra->details,
141
+ 'totalPrice' => $extra->totalPrice,
142
+ 'basePrice' => $extra->basePrice,
143
+ 'tax' => $extra->tax,
144
+ );
145
+ }
146
+
147
+ $this
148
+ ->setCarrier($carrier->getId())
149
+ ->setAccepted($response->accepted == 'Y')
150
+ ->setTotalPrice($response->totalPrice)
151
+ ->setBasePrice($response->basePrice)
152
+ ->setTax($response->tax)
153
+ ->setCurrency($response->currency)
154
+ ->setDeliveryMethod($response->deliveryMethod)
155
+ ->setEtaFrom($response->etaFrom)
156
+ ->setEtaTo($response->etaTo)
157
+ ->setGuaranteedEta($response->guaranteedEta == 'Y')
158
+ ->setExtras($extras_array)
159
+ ->setCarbonTotalPrice(array_key_exists('carbonoffset', $extras_array) ? $extras_array['carbonoffset']['totalPrice'] : 0)
160
+ ->setInsuranceTotalPrice(array_key_exists('insurance', $extras_array) ? $extras_array['insurance']['totalPrice'] : 0)
161
+ ->setFootprintsTotalPrice(array_key_exists('footprints', $extras_array) ? $extras_array['footprints']['totalPrice'] : 0)
162
+ ->setLoaded(true);
163
+ }
164
+ return $this;
165
+ }
166
+
167
+ public function toBookingRequestArray($options)
168
+ {
169
+ $extras = $this->getExtras();
170
+
171
+ if (isset($options['insurance']) && ($options['insurance'] === 'Y')) {
172
+ $insurance = $extras['insurance'];
173
+ } else {
174
+ $insurance = false;
175
+ }
176
+
177
+ if (isset($options['carbonoffset']) && ($options['carbonoffset'] === 'Y')) {
178
+ $carbon = $extras['carbonoffset'];
179
+ } else {
180
+ $carbon = false;
181
+ }
182
+
183
+ if (isset($options['footprints']) && ($options['footprints'] === 'Y')) {
184
+ $footprints = $extras['footprints'];
185
+ } else {
186
+ $footprints = false;
187
+ }
188
+
189
+ $request = array(
190
+ 'totalPrice' => $this->getTotalPrice(),
191
+ 'basePrice' => $this->getBasePrice(),
192
+ 'tax' => $this->getTax(),
193
+ 'currency' => $this->getCurrency(),
194
+ 'deliveryMethod' => $this->getDeliveryMethod(),
195
+ 'etaFrom' => $this->getEtaFrom(),
196
+ 'etaTo' => $this->getEtaTo(),
197
+ 'guaranteedEta' => $this->getGuaranteedEta() ? 'Y' : 'N',
198
+ 'carrierId' => $this->getCarrier()->getCarrierId(),
199
+ );
200
+
201
+ if ($carbon || $insurance || $footprints) {
202
+ $request['extras'] = array();
203
+ $request['extras']['extra'] = array();
204
+ }
205
+
206
+ if ($carbon) {
207
+ $request['extras']['extra'][] = $carbon;
208
+ }
209
+ if ($insurance) {
210
+ $request['extras']['extra'][] = $insurance;
211
+ }
212
+ if ($footprints) {
213
+ $request['extras']['extra'][] = $footprints;
214
+ }
215
+
216
+ return $request;
217
+ }
218
+
219
+ public function setExtras($extras)
220
+ {
221
+ $this->setData('extras', serialize($extras));
222
+ return $this;
223
+ }
224
+
225
+ public function getExtras()
226
+ {
227
+ if ($this->getData('extras')) {
228
+ return unserialize($this->getData('extras'));
229
+ }
230
+ return null;
231
+ }
232
+
233
+ public function getDescription($showMethod = true, $showEta = true)
234
+ {
235
+ $title = '';
236
+ $title .= $this->getCarrier()->getCompanyName();
237
+
238
+ if ($showMethod && $showEta) {
239
+ $title .= ' - ' . $this->getDeliveryMethod(). ' [' . $this->getEtaDescription() . ']';
240
+ } else if ($showMethod) {
241
+ $title .= ' - ' . $this->getDeliveryMethod();
242
+ } else if ($showEta) {
243
+ $title .= ' [' . $this->getEtaDescription(). ']';
244
+ }
245
+
246
+ return $title . ' ' . $this->getExtraTitle();;
247
+ }
248
+
249
+
250
+ public function getTotalPriceIncSelectedExtras()
251
+ {
252
+ $price = $this->getTotalPrice();
253
+ if($this->getInsuranceIncluded()) {
254
+ $price += $this->getInsuranceTotalPrice();
255
+ }
256
+ if($this->getCarbonIncluded()) {
257
+ $price += $this->getCarbonTotalPrice();
258
+ }
259
+ if($this->getFootprintsIncluded()) {
260
+ $price += $this->getFootprintsTotalPrice();
261
+ }
262
+
263
+ return $price;
264
+
265
+ }
266
+
267
+ public function getExtraTitle()
268
+ {
269
+ $title = '';
270
+ if ($this->getInsuranceIncluded()) {
271
+ $title .= ', includes insurance';
272
+ }
273
+ if ($this->getCarbonIncluded()) {
274
+ if ($this->getInsuranceIncluded()) {
275
+ $title .= ' and ';
276
+ } else {
277
+ $title .= ', includes ';
278
+ }
279
+ $title .= ' carbon offset';
280
+ }
281
+ if ($this->getFootprintsIncluded()) {
282
+ if ($this->getInsuranceIncluded() || $this->getCarbonIncluded()) {
283
+ $title .= ' and ';
284
+ } else {
285
+ $title .= ', includes ';
286
+ }
287
+ $title .= ' footprints';
288
+ }
289
+
290
+ return $title;
291
+ }
292
+
293
+ public function getEtaDescription()
294
+ {
295
+ $title = $this->getEtaFrom();
296
+
297
+ if ($this->getEtaFrom() != $this->getEtaTo()) {
298
+ $title .= ' - ' . $this->getEtaTo();
299
+ }
300
+
301
+ $title .= ' day';
302
+
303
+ if ($this->getEtaTo() > 1) {
304
+ $title .= 's';
305
+ }
306
+
307
+ return $title;
308
+ }
309
+
310
+ /**
311
+ * Returns the average ETA.
312
+ *
313
+ * e.g. for an ETA of 1-4 days, the average is 2.5 days.
314
+ */
315
+ public function getAverageEta()
316
+ {
317
+ return ($this->getEtaFrom() + $this->getEtaTo()) / 2;
318
+ }
319
+
320
+ }
app/code/community/Temando/Temando/Model/Shipment.php ADDED
@@ -0,0 +1,377 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @method int getId()
5
+ * @method int getOrderId()
6
+ * @method string getCustomerSelectedQuoteId()
7
+ * @method string getCustomerSelectedQuoteDescription()
8
+ * @method string getAdminSelectedQuoteId()
9
+ * @method float getAnticipatedCost()
10
+ * @method int getStatus()
11
+ * @method int getBookingRequestId()
12
+ * @method boolean getInsurance()
13
+ * @method string getDestinationCountry()
14
+ * @method string getDestinationPostcode()
15
+ * @method string getDestinationCity()
16
+ * @method string getReadyDate()
17
+ * @method string getReadyTime()
18
+ * @method string getCustomerSelectedOptions()
19
+ * @method string getOrderItems()
20
+ *
21
+ * @method Temando_Temando_Model_Shipment setId()
22
+ * @method Temando_Temando_Model_Shipment setOrderId()
23
+ * @method Temando_Temando_Model_Shipment setCustomerSelectedQuoteId()
24
+ * @method Temando_Temando_Model_Shipment setCustomerSelectedQuoteDescription()
25
+ * @method Temando_Temando_Model_Shipment setAdminSelectedQuoteId()
26
+ * @method Temando_Temando_Model_Shipment setAnticipatedCost()
27
+ * @method Temando_Temando_Model_Shipment setStatus()
28
+ * @method Temando_Temando_Model_Shipment setBookingRequestId()
29
+ * @method Temando_Temando_Model_Shipment setDestinationCountry()
30
+ * @method Temando_Temando_Model_Shipment setDestinationPostcode()
31
+ * @method Temando_Temando_Model_Shipment setDestinationCity()
32
+ * @method Temando_Temando_Model_Shipment setReadyDate()
33
+ * @method Temando_Temando_Model_Shipment setReadyTime()
34
+ * @method Temando_Temando_Model_Shipment setCustomerSelectedOptions()
35
+ * @method Temando_Temando_Model_Shipment setOrderItems()
36
+ *
37
+ */
38
+ class Temando_Temando_Model_Shipment extends Mage_Core_Model_Abstract
39
+ {
40
+
41
+ /**
42
+ * @var Mage_Sales_Model_Order
43
+ */
44
+ protected $_order = null;
45
+
46
+ /**
47
+ * @var array
48
+ */
49
+ protected $_boxes = null;
50
+
51
+ public function _construct()
52
+ {
53
+ parent::_construct();
54
+ $this->_init('temando/shipment');
55
+ }
56
+
57
+ /**
58
+ * Overridden to enforce the use of custom getters.
59
+ *
60
+ * Certain core functions use (e.g.) getData('created_at') instead of
61
+ * getCreatedAt(). This makes sure the correct data is returned.
62
+ *
63
+ * Using _afterLoad() to load the Magento order and populate
64
+ * $this->_data['created_at'] won't work: _afterLoad() isn't called
65
+ * when objects are loaded in a collection.
66
+ *
67
+ * @see Varien_Object::getData()
68
+ */
69
+ public function getData($key = '', $index = null)
70
+ {
71
+ switch ($key) {
72
+ case 'selected_quote_description': return $this->getSelectedQuoteDescription();
73
+ case 'created_at': return $this->getCreatedAt();
74
+ case 'order_number': return $this->getOrderNumber();
75
+ case 'shipping_paid': return $this->getShippingPaid();
76
+ default:
77
+ }
78
+ return parent::getData($key, $index);
79
+ }
80
+
81
+ /**
82
+ * Gets the Magento order associated with this shipment.
83
+ *
84
+ * @return Mage_Sales_Model_Order
85
+ */
86
+ public function getOrder()
87
+ {
88
+ if (!$this->_order && $this->getId()) {
89
+ $this->_order = Mage::getModel('sales/order')->load($this->getOrderId());
90
+ }
91
+ return $this->_order;
92
+ }
93
+
94
+ /**
95
+ * Gets the creation date of this shipment.
96
+ */
97
+ public function getCreatedAt()
98
+ {
99
+ if ($this->getOrder()) {
100
+ return $this->getOrder()->getCreatedAt();
101
+ }
102
+ return null;
103
+ }
104
+
105
+ /**
106
+ * Gets the Magento order number (as shown to customers, e.g. 100000123)
107
+ */
108
+ public function getOrderNumber()
109
+ {
110
+ if ($this->getOrder()) {
111
+ return $this->getOrder()->getIncrementId();
112
+ }
113
+ return null;
114
+ }
115
+
116
+ public function getBoxes()
117
+ {
118
+ return Mage::getModel('temando/box')->getCollection()
119
+ ->addFieldToFilter('shipment_id', $this->getId());
120
+ }
121
+
122
+ /**
123
+ * Gets the carrier description.
124
+ *
125
+ * If the Temando shipment status is Pending or Cancelled, this will be the
126
+ * shipment method selected by the user during checkout. If the Temando
127
+ * shipment status is Booked, then it will describe the booked quote.
128
+ *
129
+ * @return string
130
+ */
131
+ public function getSelectedQuoteDescription()
132
+ {
133
+ $quote = $this->getSelectedQuotePermutation();
134
+ if (is_object($quote) && $quote->getId()) {
135
+ return $quote->getDescription();
136
+ } else {
137
+ return $this->getCustomerSelectedQuoteDescription();
138
+ }
139
+ return null;
140
+ }
141
+
142
+ /**
143
+ * Gets the selected quote.
144
+ *
145
+ * If the Temando shipment status is Pending or Cancelled, this will be the
146
+ * quote selected by the user during checkout. If the Temando shipment
147
+ * status is Booked, then it will be the booked quote.
148
+ *
149
+ * @return Temando_Temando_Model_Quote
150
+ */
151
+ public function getSelectedQuote()
152
+ {
153
+ $quote = null;
154
+
155
+ switch ($this->getStatus()) {
156
+ case Temando_Temando_Model_System_Config_Source_Shipment_Status::BOOKED:
157
+ $quote = Mage::getModel('temando/quote')
158
+ ->load($this->getAdminSelectedQuoteId());
159
+ break;
160
+ case Temando_Temando_Model_System_Config_Source_Shipment_Status::PENDING:
161
+ default:
162
+ $quote = Mage::getModel('temando/quote')
163
+ ->load($this->getCustomerSelectedQuoteId());
164
+ break;
165
+ }
166
+
167
+ return $quote;
168
+ }
169
+
170
+ /**
171
+ * Gets the quote using $this->getQuote(), and applies the selected
172
+ * options to it as well.
173
+ *
174
+ * @return Temando_Temando_Model_Quote
175
+ */
176
+ public function getSelectedQuotePermutation()
177
+ {
178
+ $quote = $this->getSelectedQuote();
179
+
180
+ /* @var $quote Temando_Temando_Model_Quote */
181
+ if ($quote !== null) {
182
+ $options = Mage::getModel('temando/options');
183
+ /* @var $options Temando_Temando_Model_Options */
184
+
185
+ $option_array = $this->getOptions();
186
+ foreach ($option_array as $option) {
187
+ $options->addItem($option);
188
+ }
189
+
190
+ $permutations = $options->applyAll($quote);
191
+
192
+ if ($permutations) {
193
+ return reset($permutations);
194
+ }
195
+ }
196
+ }
197
+
198
+ /**
199
+ * Gets the shipping amount the customer paid on this order.
200
+ */
201
+ public function getShippingPaid()
202
+ {
203
+ if ($this->getOrder()) {
204
+ return $this->getOrder()->getShippingAmount();
205
+ }
206
+ return null;
207
+ }
208
+
209
+ /**
210
+ * Fixes up database-style dates after loading.
211
+ *
212
+ * @see Mage_Core_Model_Abstract::_afterLoad()
213
+ */
214
+ public function _afterLoad()
215
+ {
216
+ if ($this->getData('ready_date') == '0000-00-00') {
217
+ $this->unsReadyDate();
218
+ }
219
+ if ($this->getData('ready_time') == '') {
220
+ $this->unsReadyTime();
221
+ }
222
+ }
223
+
224
+ /**
225
+ * Gets Temando quotes for this shipment.
226
+ */
227
+ public function fetchQuotes($username = null, $password = null, $sandbox = false)
228
+ {
229
+ /* @var $request Temando_Temando_Model_Api_Request */
230
+
231
+ $request = Mage::getModel('temando/api_request');
232
+ $request
233
+ ->setUsername($username)
234
+ ->setPassword($password)
235
+ ->setSandbox($sandbox)
236
+ ->setMagentoQuoteId($this->getOrder()->getQuoteId())
237
+ ->setDestination(
238
+ $this->getDestinationCountry(),
239
+ $this->getDestinationPostcode(),
240
+ $this->getDestinationCity(),
241
+ $this->getDestinationStreet())
242
+ ->setItems($this->getBoxes());
243
+ if ($this->getReadyDate()) {
244
+ $request->setReady(strtotime($this->getReadyDate()), $this->getReadyTime());
245
+ } else {
246
+ $request->setReady(null);
247
+ }
248
+
249
+ $allowed_carriers = explode(',', Mage::getStoreConfig('carriers/temando/allowed_methods'));
250
+ $request->setAllowedCarriers($allowed_carriers);
251
+
252
+ $request->getQuotes();
253
+ }
254
+
255
+ /**
256
+ * Clears all quotes from the database relating to this shipment.
257
+ */
258
+ public function clearQuotes()
259
+ {
260
+ $old_quotes = Mage::getModel('temando/quote')->getCollection()
261
+ ->addFieldToFilter('magento_quote_id', $this->getOrder()->getQuoteId());
262
+ foreach ($old_quotes as $quote) {
263
+ /* @var $quote Temando_Temando_Model_Quote */
264
+ $quote->delete();
265
+ }
266
+ return $this;
267
+ }
268
+
269
+
270
+ /**
271
+ * Gets the quotes for this shipment from the database
272
+ *
273
+ * @param boolean $use_options
274
+ *
275
+ * @return Temando_Temando_Model_Mysql4_Quote_Collection
276
+ */
277
+ public function getQuotes($use_options = false)
278
+ {
279
+ if ($use_options) {
280
+ $option_array = $this->getOptions();
281
+ $options = Mage::getModel('temando/options');
282
+ /* @var $options Temando_Temando_Model_Options */
283
+ foreach ($option_array as $option) {
284
+ $options->addItem($option);
285
+ }
286
+
287
+ /* @var $quotes Temando_Temando_Model_Mysql4_Quote_Collection */
288
+ $quotes = Mage::getModel('temando/quote')->getCollection();
289
+ if (!$this->getQuotes()->count()) {
290
+ $quotes
291
+ ->addFieldToFilter('magento_quote_id', $this->getOrder()->getQuoteId());
292
+ } else {
293
+ foreach ($this->getQuotes() as $quote_id => $quote) {
294
+ /* @var $quote Temando_Temando_Model_Quote */
295
+ $permutations = $options->applyAll($quote);
296
+ if ($add_quote = reset($permutations)) {
297
+ $quotes->addItem($add_quote);
298
+ }
299
+ }
300
+ }
301
+
302
+ return $quotes;
303
+ } else {
304
+ return Mage::getModel('temando/quote')->getCollection()
305
+ ->addFieldToFilter('magento_quote_id', $this->getOrder()->getQuoteId());
306
+ }
307
+ }
308
+
309
+
310
+ /**
311
+ * Gets the customer selected options as an array.
312
+ *
313
+ * e.g. for a options string like "insurance_0_carbon_1", this will give:
314
+ *
315
+ * array(
316
+ * 'insurance' => 0,
317
+ * 'carbon' => 1,
318
+ * )
319
+ *
320
+ * @return array
321
+ */
322
+ public function getOptionsArray()
323
+ {
324
+ $string = $this->getCustomerSelectedOptions();
325
+ $elements = explode('_', $string);
326
+
327
+ $options = array();
328
+
329
+ for ($i = 0; $i < count($elements); $i += 2) {
330
+ $options[$elements[$i]] = $elements[$i + 1];
331
+ }
332
+
333
+ return $options;
334
+ }
335
+
336
+ /**
337
+ * Gets the customer selected options as an array of Option objects.
338
+ *
339
+ * Each Option object will have the "forced value" set to the value that
340
+ * the customer selected.
341
+ *
342
+ * @return array
343
+ */
344
+ public function getOptions()
345
+ {
346
+ $options = array();
347
+ foreach ($this->getOptionsArray() as $id => $value) {
348
+ // try to instantiate model based on option ID
349
+ if ('carbon' == $id) {
350
+ $id = 'carbonoffset';
351
+ }
352
+
353
+ if ('insurance' == $id) {
354
+ $_t = $this->getData();
355
+ if (isset($_t['id'])) {
356
+ $i_id = $_t['id'];
357
+ if (!is_null(Mage::getSingleton('adminhtml/session')->getData('insurance_' . $i_id))) {
358
+ $value = Mage::getSingleton('adminhtml/session')->getData('insurance_' . $i_id);
359
+ }
360
+ }
361
+ }
362
+ try {
363
+ $option = Mage::getModel('temando/option_' . $id);
364
+ } catch(Exception $e) {
365
+ $option = false;
366
+ }
367
+ if ($option) {
368
+ /* @var $option Temando_Temando_Model_Option_Abstract */
369
+ $option->setForcedValue($value);
370
+ $options[] = $option;
371
+ }
372
+ }
373
+
374
+ return $options;
375
+ }
376
+
377
+ }
app/code/community/Temando/Temando/Model/Shipping/Carrier/Temando.php ADDED
@@ -0,0 +1,503 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * @method Temando_Temando_Model_Shipping_Carrier_Temando setIsProductPage(boolean $flag)
4
+ * @method Temando_Temando_Model_Shipping_Carrier_Temando setIsCartPage(boolean $flag)
5
+ *
6
+ * @method boolean getIsProductPage()
7
+ * @method boolean getIsCartPage()
8
+ */
9
+
10
+
11
+ class Temando_Temando_Model_Shipping_Carrier_Temando
12
+ extends Mage_Shipping_Model_Carrier_Abstract
13
+ implements Mage_Shipping_Model_Carrier_Interface
14
+ {
15
+ /**
16
+ * Error Constants
17
+ */
18
+ const ERR_INVALID_COUNTRY = 'To and From addresses must be within Australia';
19
+ const ERR_INVALID_DEST = 'Please enter a delivery address to view available shipping methods';
20
+ const ERR_NO_METHODS = 'No shipping methods available';
21
+ const ERR_INTERNATIONAL = 'International delivery is not available at this time.';
22
+
23
+ /**
24
+ * Error Map
25
+ *
26
+ * @var array
27
+ */
28
+ protected static $_errors_map = array(
29
+ "The 'destinationCountry', 'destinationCode' and 'destinationSuburb' elements (within the 'Anywhere' type) do not contain valid values. These values must match with the predefined settings in the Temando system."
30
+ => "Invalid suburb / postcode combination."
31
+ );
32
+
33
+ /**
34
+ * Carrier's code
35
+ *
36
+ * @var string
37
+ */
38
+ protected $_code = 'temando';
39
+
40
+ /**
41
+ * Carrier's title
42
+ *
43
+ * @var string
44
+ */
45
+ protected $_title = 'Temando';
46
+
47
+ /**
48
+ * Rates result
49
+ *
50
+ * @var array|null
51
+ */
52
+ protected $_rates;
53
+
54
+ /**
55
+ * @var Mage_Shipping_Model_Rate_Request
56
+ */
57
+ protected $_rate_request;
58
+
59
+ /**
60
+ * Current pricing method as set in Temando Settings
61
+ *
62
+ * @var string
63
+ */
64
+ protected $_pricing_method;
65
+
66
+ /**
67
+ * Check if carrier has shipping tracking option available
68
+ *
69
+ * @return boolean
70
+ */
71
+ public function isTrackingAvailable()
72
+ {
73
+ return true;
74
+ }
75
+
76
+ /**
77
+ * Check if carrier has shipping label option available
78
+ *
79
+ * @return boolean
80
+ */
81
+ public function isShippingLabelsAvailable()
82
+ {
83
+ return false;
84
+ }
85
+
86
+
87
+ public function __construct()
88
+ {
89
+ parent::__construct();
90
+ $this->_pricing_method = $this->getConfigData('pricing/method');
91
+ $this->setIsProductPage(("etemando" == Mage::app()->getRequest()->getModuleName()) && ("pcs" == Mage::app()->getRequest()->getControllerName()));
92
+ $this->setIsCartPage(("checkout" == Mage::app()->getRequest()->getModuleName()) && ("cart" == Mage::app()->getRequest()->getControllerName()));
93
+ }
94
+
95
+ /**
96
+ * Checks if the to address is within allowed countries
97
+ *
98
+ * @return boolean
99
+ */
100
+ protected function _canShip(Mage_Shipping_Model_Rate_Request $request)
101
+ {
102
+ return array_key_exists($request->getDestCountryId(), Mage::helper('temando')->getAllowedCountries());
103
+ }
104
+
105
+ /**
106
+ * Creates a rate method based on a Temando API quote.
107
+ *
108
+ * @param Mage_Shipping_Model_Rate_Result_Method the quote from the
109
+ * Temando API.
110
+ *
111
+ * @return Mage_Shipping_Model_Rate_Result_Method
112
+ */
113
+ protected function _getRateFromQuote($quote, $method_id)
114
+ {
115
+ $price = $this->getFinalPriceWithHandlingFee($quote->getTotalPrice());
116
+ $title = $quote->getDescription($this->getConfigData('options/show_transit_type'), $this->getConfigData('options/show_transit_time'));
117
+
118
+ $method = Mage::getModel('shipping/rate_result_method')
119
+ ->setCarrier($this->_code)
120
+ ->setCarrierTitle($this->_title)
121
+ ->setMethodTitle($title)
122
+ ->setMethod($method_id)
123
+ ->setPrice($price)
124
+ ->setCost($quote->getTotalPrice());
125
+
126
+ return $method;
127
+ }
128
+
129
+ /**
130
+ * Creates the flat rate method, with the price set in the config. An
131
+ * optional parameter allows the price to be overridden.
132
+ *
133
+ * @return Mage_Shipping_Model_Rate_Result_Method
134
+ */
135
+ protected function _getFlatRateMethod($price = false, $free = false)
136
+ {
137
+ if ($price === false) {
138
+ $cost = $this->getConfigData('pricing/shipping_fee');
139
+ $price = $this->getFinalPriceWithHandlingFee($cost);
140
+ } else {
141
+ $cost = $price;
142
+ }
143
+
144
+ $title = $free ? 'Free Shipping' : 'Flat Rate';
145
+ $method = Mage::getModel('shipping/rate_result_method')
146
+ ->setCarrier($this->_code)
147
+ ->setCarrierTitle($this->_title)
148
+ ->setMethodTitle($title)
149
+ ->setMethod($free ? Temando_Temando_Model_Carrier::FREE : Temando_Temando_Model_Carrier::FLAT_RATE)
150
+ ->setPrice($price)
151
+ ->setCost($cost);
152
+
153
+ return $method;
154
+ }
155
+
156
+ /**
157
+ * Returns shipping rate result error method
158
+ *
159
+ * @param string $errorText
160
+ * @return Mage_Shipping_Model_Rate_Result_Error
161
+ */
162
+ protected function _getErrorMethod($errorText)
163
+ {
164
+ $error = Mage::getModel('shipping/rate_result_error');
165
+ $error->setCarrier($this->_code);
166
+ $error->setCarrierTitle($this->_title);
167
+ if (isset(self::$_errors_map[$errorText])) {
168
+ $errorText = self::$_errors_map[$errorText];
169
+ }
170
+ $error->setErrorMessage($errorText);
171
+
172
+ return $error;
173
+ }
174
+
175
+ /**
176
+ * Creates a string describing the applicable elements of a rate request.
177
+ *
178
+ * This is used to determine if the quotes fetched last time should be
179
+ * refreshed, or if they can remain valid.
180
+ *
181
+ * @param Mage_Shipping_Model_Rate_Request $rate_request
182
+ *
183
+ * @return boolean
184
+ */
185
+ protected function _createRequestString(Mage_Shipping_Model_Rate_Request $request, $salesQuoteId)
186
+ {
187
+ $requestString = $salesQuoteId . '|';
188
+ foreach ($request->getAllItems() as $item) {
189
+ $requestString .= $item->getProductId() . 'x' . $item->getQty();
190
+ }
191
+
192
+ $requestString .= '|' . $request->getDestCity();
193
+ $requestString .= '|' . $request->getDestCountryId();
194
+ $requestString .= '|' . $request->getDestPostcode();
195
+
196
+ return $requestString;
197
+ }
198
+
199
+ /**
200
+ * Returns available shipping methods for current request based on pricing method
201
+ * specified in Temando Settings
202
+ *
203
+ * @param Mage_Shipping_Model_Rate_Request $request
204
+ * @return Mage_Shipping_Model_Rate_Result|Mage_Shipping_Model_Rate_Result_Error
205
+ */
206
+ public function collectRates(Mage_Shipping_Model_Rate_Request $request)
207
+ {
208
+ $result = Mage::getModel('shipping/rate_result');
209
+ /* @var $result Mage_Shipping_Model_Rate_Result */
210
+
211
+ //check origin/destination country
212
+ if (!$this->_canShip($request)) {
213
+ return $this->_getErrorMethod(self::ERR_INVALID_COUNTRY);
214
+ }
215
+
216
+ //OneStepCheckout inserts '-' in city/pcode if no default configured
217
+ if (!$request->getDestCountryId() || !$request->getDestPostcode() || !$request->getDestCity() ||
218
+ $request->getDestPostcode() == '-' || $request->getDestCity() == '-') {
219
+ return $this->_getErrorMethod(self::ERR_INVALID_DEST);
220
+ }
221
+
222
+ //check if eligible for free shipping
223
+ if ($this->isFreeShipping($request)) {
224
+ $result->append($this->_getFlatRateMethod('0.00', true));
225
+ return $result;
226
+ }
227
+
228
+ //check for flat rate
229
+ if ($this->_pricing_method == Temando_Temando_Model_System_Config_Source_Pricing::FLAT_RATE) {
230
+ $result->append($this->_getFlatRateMethod());
231
+ return $result;
232
+ }
233
+
234
+ //prepare extras
235
+ $insurance = Mage::getModel('temando/option_insurance')->setSetting(Mage::getStoreConfig('temando/insurance/status'));
236
+ $carbon = Mage::getModel('temando/option_carbonoffset')->setSetting(Mage::getStoreConfig('temando/carbon/status'));
237
+ $footprints = Mage::getModel('temando/option_footprints')->setSetting(Mage::getStoreConfig('temando/footprints/status'));
238
+
239
+ if ($this->getIsProductPage() || $this->getIsCartPage())
240
+ {
241
+ if (!in_array($insurance->getForcedValue(), array(Temando_Temando_Model_Option_Boolean::YES, Temando_Temando_Model_Option_Boolean::NO))) {
242
+ $insurance->setForcedValue(Temando_Temando_Model_Option_Boolean::NO);
243
+ }
244
+
245
+ if (!in_array($carbon->getForcedValue(), array(Temando_Temando_Model_Option_Boolean::YES, Temando_Temando_Model_Option_Boolean::NO))) {
246
+ $carbon->setForcedValue(Temando_Temando_Model_Option_Boolean::NO);
247
+ }
248
+
249
+ if (!in_array($footprints->getForcedValue(), array(Temando_Temando_Model_Option_Boolean::YES, Temando_Temando_Model_Option_Boolean::NO))) {
250
+ $footprints->setForcedValue(Temando_Temando_Model_Option_Boolean::NO);
251
+ }
252
+ }
253
+ /* @var Temando_Temando_Model_Options $options */
254
+ $options = Mage::getModel('temando/options')->addItem($insurance)->addItem($carbon)->addItem($footprints);
255
+
256
+ //get magento sales quote id
257
+ $salesQuoteId = Mage::getSingleton('checkout/session')->getQuoteId();
258
+ if (!$salesQuoteId && Mage::app()->getStore()->isAdmin()) {
259
+ $salesQuoteId = Mage::getSingleton('adminhtml/session_quote')->getQuote()->getId();
260
+ }
261
+ if (!$salesQuoteId && $this->getIsProductPage()) {
262
+ $salesQuoteId = 100000000 + mt_rand(0, 100000);
263
+ }
264
+
265
+ //save current extras
266
+ if (is_null(Mage::registry('temando_current_options'))) {
267
+ Mage::register('temando_current_options', $options);
268
+ }
269
+
270
+ //get available shipping methods (quotes from the API)
271
+ //check if request same as previous
272
+ $lastRequest = Mage::getSingleton('checkout/session')->getTemandoRequestString();
273
+ if ($lastRequest == $this->_createRequestString($request, $salesQuoteId))
274
+ {
275
+ //request is the same as previous, load existing quotes from DB
276
+ $quotes = Mage::getModel('temando/quote')->getCollection()
277
+ ->addFieldToFilter('magento_quote_id', $salesQuoteId)
278
+ ->getItems();
279
+ }
280
+ else
281
+ {
282
+ try {
283
+ $apiRequest = Mage::getModel('temando/api_request');
284
+ $apiRequest
285
+ ->setUsername($this->getConfigData('general/username'))
286
+ ->setPassword($this->getConfigData('general/password'))
287
+ ->setSandbox($this->getConfigData('general/sandbox'))
288
+ ->setMagentoQuoteId($salesQuoteId)
289
+ ->setDestination(
290
+ $request->getDestCountryId(),
291
+ $request->getDestPostcode(),
292
+ $request->getDestCity(),
293
+ $request->getDestStreet())
294
+ ->setItems($request->getAllItems())
295
+ ->setReady(Mage::helper('temando')->getReadyDate())
296
+ ->setAllowedCarriers($this->getAllowedMethods());
297
+
298
+ $coll = $apiRequest->getQuotes();
299
+ if ($coll instanceof Temando_Temando_Model_Mysql4_Quote_Collection) {
300
+ $quotes = $coll->getItems();
301
+ }
302
+ } catch (Exception $e) {
303
+ switch(Mage::helper('temando')->getConfigData('pricing/error_process')) {
304
+ case Temando_Temando_Model_System_Config_Source_Errorprocess::VIEW:
305
+ return $this->_getErrorMethod($e->getMessage());
306
+ break;
307
+ case Temando_Temando_Model_System_Config_Source_Errorprocess::FLAT:
308
+ $result->append($this->_getFlatRateMethod());
309
+ return $result;
310
+ break;
311
+ }
312
+ }
313
+ }
314
+
315
+ //process filters and apply extras
316
+ if(empty($quotes)) {
317
+ return $this->_getErrorMethod(self::ERR_NO_METHODS);
318
+ } else {
319
+ switch($this->_pricing_method) {
320
+ case Temando_Temando_Model_System_Config_Source_Pricing::DYNAMIC_CHEAPEST:
321
+ $quotes = Mage::helper('temando/functions')->getCheapestQuote($quotes);
322
+ break;
323
+ case Temando_Temando_Model_System_Config_Source_Pricing::DYNAMIC_FASTEST:
324
+ $quotes = Mage::helper('temando/functions')->getFastestQuote($quotes);
325
+ break;
326
+ case Temando_Temando_Model_System_Config_Source_Pricing::DYNAMIC_FASTEST_AND_CHEAPEST:
327
+ $quotes = Mage::helper('temando/functions')->getCheapestAndFastestQuotes($quotes);
328
+ break;
329
+ }
330
+ if(!is_array($quotes)) { $quotes = array($quotes); }
331
+ foreach($quotes as $id => $quote)
332
+ {
333
+ $permutations = $options->applyAll($quote);
334
+ foreach($permutations as $permId => $permutation) {
335
+ $result->append($this->_getRateFromQuote($permutation, $quote->getId() . '_' . $permId));
336
+ }
337
+ }
338
+
339
+ }
340
+
341
+ Mage::getSingleton('checkout/session')->setTemandoRequestString($this->_createRequestString($request, $salesQuoteId));
342
+ return $result;
343
+ }
344
+
345
+ /**
346
+ * Returns true if request is elegible for free shipping, false otherwise
347
+ *
348
+ * @param Mage_Shipping_Model_Rate_Request $request
349
+ * @return boolean
350
+ */
351
+ public function isFreeShipping($request)
352
+ {
353
+ //check pricing method first
354
+ if($this->_pricing_method == Temando_Temando_Model_System_Config_Source_Pricing::FREE) {
355
+ return true;
356
+ }
357
+
358
+ //check if all items have free shipping or free shipping over amount enabled and valid for this request
359
+ $allItemsFree = true; $total = 0;
360
+ foreach ($request->getAllItems() as $item) {
361
+ /* @var $item Mage_Sales_Model_Quote_Item */
362
+ if ($item->getProduct()->isVirtual() || $item->getParentItem()) { continue; }
363
+ if ($item->getFreeShipping()) { continue; }
364
+
365
+ $value = $item->getValue();
366
+ if (!$value) { $value = $item->getRowTotalInclTax(); }
367
+ if (!$value) { $value = $item->getRowTotal(); }
368
+ if (!$value) {
369
+ $qty = $item->getQty() ? $item->getQty() : $item->getQtyOrdered();
370
+ $value = $item->getPrice() * $qty;
371
+ }
372
+ $total += $value;
373
+ //not all items with free shipping if here
374
+ $allItemsFree = false;
375
+ }
376
+
377
+ if($allItemsFree ||
378
+ ($this->getConfigData('free_shipping_enable') && $total >= $this->getConfigData('free_shipping_subtotal'))) {
379
+ return true;
380
+ }
381
+
382
+ return false;
383
+ }
384
+
385
+ /**
386
+ * Return list of allowed carriers
387
+ *
388
+ * @return array
389
+ */
390
+ public function getAllowedMethods()
391
+ {
392
+ return explode(',', Mage::getStoreConfig('carriers/temando/allowed_methods'));
393
+ }
394
+
395
+ public function getTrackingInfo($tracking_number)
396
+ {
397
+ $api = Mage::getModel('temando/api_client');
398
+ $api->connect(
399
+ Mage::helper('temando')->getConfigData('general/username'),
400
+ Mage::helper('temando')->getConfigData('general/password'),
401
+ Mage::helper('temando')->getConfigData('general/sandbox'));
402
+
403
+ $_t = explode('Request Id: ', $tracking_number);
404
+ if (isset($_t[1])) {
405
+ $tracking_number = $_t[1];
406
+ }
407
+
408
+ $status = $api->getRequest(array('requestId' => $tracking_number));
409
+
410
+ $result = Mage::getModel('shipping/tracking_result_abstract')
411
+ ->setTracking($tracking_number);
412
+ /* @var $result Mage_Shipping_Model_Tracking_Result_Abstract */
413
+ if ($status && $status->request->quotes && $status->request->quotes->quote) {
414
+ if (isset($status->request->quotes->quote->carrier->companyName)) {
415
+ $result->setCarrierTitle($status->request->quotes->quote->carrier->companyName);
416
+ }
417
+
418
+ if (isset($status->request->quotes->quote->trackingStatus)) {
419
+ $result->setStatus($status->request->quotes->quote->trackingStatus);
420
+ } else {
421
+ $result->setStatus(Mage::helper('temando')->__('Unavailable'));
422
+ }
423
+
424
+ $text = '';
425
+ if (isset($status->request->quotes->quote->trackingFurtherDetails)) {
426
+ $text .= $status->request->quotes->quote->trackingFurtherDetails;
427
+ }
428
+ if (isset($status->request->quotes->quote->trackingLastChecked)) {
429
+ $text .= 'Last Update: ' . date('Y-m-d h:ia', strtotime($status->request->quotes->quote->trackingLastChecked));
430
+ }
431
+
432
+ if ($text) {
433
+ $result->setTrackSummary($text);
434
+ }
435
+ } else {
436
+ $result->setErrorMessage(Mage::helper('temando')->__('An error occurred while fetching the shipment status.'));
437
+ }
438
+
439
+ return $result;
440
+ }
441
+
442
+ public function getConfigData($field)
443
+ {
444
+ if (in_array($field, array('handling_fee', 'handling_type'))) {
445
+ $field = 'pricing/' . $field;
446
+ }
447
+
448
+ $parent = parent::getConfigData($field);
449
+ return $parent !== null ? $parent : Mage::helper('temando')->getConfigData($field);
450
+ }
451
+
452
+ /**
453
+ * Returns Temando carrier code
454
+ *
455
+ * @return string
456
+ */
457
+ public function getCode()
458
+ {
459
+ return $this->_code;
460
+ }
461
+
462
+ /**
463
+ * Returns Temando carrier title
464
+ *
465
+ * @return string
466
+ */
467
+ public function getTitle()
468
+ {
469
+ return $this->_title;
470
+ }
471
+
472
+ /**
473
+ * Is state province required
474
+ *
475
+ * @return bool
476
+ */
477
+ public function isStateProvinceRequired()
478
+ {
479
+ return false;
480
+ }
481
+
482
+ /**
483
+ * Check if city option required
484
+ *
485
+ * @return boolean
486
+ */
487
+ public function isCityRequired()
488
+ {
489
+ return true;
490
+ }
491
+
492
+ /**
493
+ * Determine whether zip-code is required for the country of destination
494
+ *
495
+ * @param string|null $countryId
496
+ * @return bool
497
+ */
498
+ public function isZipCodeRequired($countryId = null)
499
+ {
500
+ return true;
501
+ }
502
+
503
+ }
app/code/community/Temando/Temando/Model/Shipping/Carrier/Temando/Source/Method.php ADDED
@@ -0,0 +1,74 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Temando_Temando_Model_Shipping_Carrier_Temando_Source_Method
4
+ {
5
+
6
+ public function toOptionArray()
7
+ {
8
+ $options = array();
9
+
10
+ $carriers = Mage::getModel('temando/carrier')->getCollection();
11
+ foreach ($carriers as $carrier) {
12
+ $options[] = array('value' => $carrier->getCarrierId(), 'label' => $carrier->getCompanyName());
13
+ }
14
+
15
+ return $options;
16
+ }
17
+
18
+
19
+ /**
20
+ * Gets all the options in the key => value type array.
21
+ *
22
+ * @return array
23
+ */
24
+ public function getOptions($please_select = false)
25
+ {
26
+ if ($please_select) {
27
+ $options = array(null => '--Please Select--');
28
+ }
29
+
30
+ $carriers = Mage::getModel('temando/carrier')->getCollection();
31
+ foreach ($carriers as $carrier) {
32
+ if(!$carrier->getCarrierId())
33
+ continue;
34
+
35
+ $options[$carrier->getCarrierId()] = $carrier->getCompanyName();
36
+ }
37
+
38
+ return $options;
39
+ }
40
+
41
+ /**
42
+ * Gets all the options for html form.
43
+ *
44
+ * @return array ( 0 => array(
45
+ * 'label' = 'my label',
46
+ * 'value' = 'my value'
47
+ * )
48
+ * );
49
+ */
50
+ public function getOptionsForForm($enabledOnly = false)
51
+ {
52
+ $options = array();
53
+ $carriers = Mage::getModel('temando/carrier')->getCollection();
54
+ foreach ($carriers as $carrier) {
55
+ if(!$carrier->getCarrierId())
56
+ continue;
57
+
58
+ //skip carriers which are not allowed in config
59
+ if($enabledOnly) {
60
+ $allowedCarriers = explode(',', Mage::getStoreConfig('carriers/temando/allowed_methods'));
61
+ if(!in_array($carrier->getCarrierId(), $allowedCarriers)) {
62
+ continue;
63
+ }
64
+ }
65
+
66
+ $options[] = array(
67
+ 'label' => $carrier->getCompanyName(),
68
+ 'value' => $carrier->getCarrierId()
69
+ );
70
+ }
71
+
72
+ return $options;
73
+ }
74
+ }
app/code/community/Temando/Temando/Model/Status.php ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Temando_Temando_Model_Status extends Varien_Object
4
+ {
5
+
6
+ const STATUS_ENABLED = 1;
7
+ const STATUS_DISABLED = 2;
8
+
9
+ /**
10
+ * Gets the available statuses.
11
+ *
12
+ * The results are in the format array(code => description).
13
+ *
14
+ * @return array
15
+ */
16
+ static public function getOptionArray()
17
+ {
18
+ return array(
19
+ self::STATUS_ENABLED => Mage::helper('temando')->__('Enabled'),
20
+ self::STATUS_DISABLED => Mage::helper('temando')->__('Disabled')
21
+ );
22
+ }
23
+
24
+ }
app/code/community/Temando/Temando/Model/System/Config/Backend/Form/Field/Required/Businessresidential.php ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Temando_Temando_Model_System_Config_Backend_Form_Field_Required_Businessresidential extends Mage_Core_Model_Config_Data
4
+ {
5
+
6
+ protected function _beforeSave()
7
+ {
8
+ $value = $this->getValue();
9
+ $types = array('Business', 'Residence');
10
+
11
+ if (!in_array($value, $types)) {
12
+ Mage::throwException(Mage::helper('temando')->__('Please select a location type from the list.', $value));
13
+ }
14
+ return $this;
15
+ }
16
+
17
+ }
app/code/community/Temando/Temando/Model/System/Config/Backend/Form/Field/Required/Country.php ADDED
@@ -0,0 +1,32 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Temando_Temando_Model_System_Config_Backend_Form_Field_Required_Country extends Mage_Core_Model_Config_Data
4
+ {
5
+
6
+ protected function _beforeSave()
7
+ {
8
+ $value = $this->getValue();
9
+ $collection = Mage::getModel('directory/country')->getCollection();
10
+ if (is_callable($collection, "getAllIds")) {
11
+ $countries = $collection->getAllIds();
12
+
13
+ if (!in_array($value, $countries)) {
14
+ Mage::throwException(Mage::helper('temando')->__('Please select a country from the list.', $value));
15
+ }
16
+ } else {
17
+ $countries = $collection->toOptionArray();
18
+ $found = false;
19
+ foreach ($countries as $c) {
20
+ if ($c['value'] == $value) {
21
+ $found = true;
22
+ }
23
+ }
24
+ if (!$found) {
25
+ Mage::throwException(Mage::helper('temando')->__('Please select a country from the list.', $value));
26
+ }
27
+ }
28
+
29
+ return $this;
30
+ }
31
+
32
+ }
app/code/community/Temando/Temando/Model/System/Config/Backend/Form/Field/Required/Location.php ADDED
@@ -0,0 +1,42 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Temando_Temando_Model_System_Config_Backend_Form_Field_Required_Location extends Temando_Temando_Model_System_Config_Backend_Form_Field_Required_Text
4
+ {
5
+
6
+ /**
7
+ * Processing object after save data
8
+ *
9
+ * @return Mage_Core_Model_Abstract
10
+ */
11
+ protected function _afterSave()
12
+ {
13
+ try {
14
+ $api = Mage::getModel('temando/api_client');
15
+ $api->connect(
16
+ Mage::helper('temando')->getConfigData('general/username'),
17
+ Mage::helper('temando')->getConfigData('general/password'),
18
+ Mage::helper('temando')->getConfigData('general/sandbox')
19
+ );
20
+
21
+ //try to update 'Magento Warehouse'
22
+ $magentoWarehouse = Mage::helper('temando')->getOriginRequestArray(new Varien_Object($this->getFieldsetData()));
23
+ try {
24
+ $api->updateLocation(array('location' => $magentoWarehouse));
25
+ } catch (Exception $e) {
26
+ try {
27
+ //if error updating location, location probably does not exist - try to create
28
+ Mage::log($e->getMessage());
29
+ $api->createLocation(array('location' => $magentoWarehouse));
30
+ } catch (Exception $e) {
31
+ Mage::getSingleton('adminhtml/session')->addError(Mage::helper('temando')->__('An error occured when synchronizing origin location data with temando.com. Please resave your configuration.'));
32
+ Mage::log($e->getMessage());
33
+ }
34
+ }
35
+ } catch (Exception $e) {
36
+ Mage::log($e->getMessage());
37
+ }
38
+
39
+ return parent::_afterSave();
40
+ }
41
+
42
+ }
app/code/community/Temando/Temando/Model/System/Config/Backend/Form/Field/Required/Text.php ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Temando_Temando_Model_System_Config_Backend_Form_Field_Required_Text extends Mage_Core_Model_Config_Data
4
+ {
5
+
6
+ protected function _beforeSave()
7
+ {
8
+ $value = $this->getValue();
9
+ $config = $this->getFieldConfig();
10
+
11
+ if (!Zend_Validate::is($value, 'NotEmpty')) {
12
+ Mage::throwException(Mage::helper('temando')->__('"' . $config->label . '" is a required field.', $value));
13
+ }
14
+ return $this;
15
+ }
16
+
17
+ }
app/code/community/Temando/Temando/Model/System/Config/Source.php ADDED
@@ -0,0 +1,82 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ abstract class Temando_Temando_Model_System_Config_Source
4
+ {
5
+
6
+ /**
7
+ * The array of options in the configuration item.
8
+ *
9
+ * This array's keys are the values used in the database etc. and the
10
+ * values of this array are used as labels on the frontend.
11
+ *
12
+ * @var array
13
+ */
14
+ protected $_options;
15
+
16
+ public function __construct()
17
+ {
18
+ $this->_setupOptions();
19
+ }
20
+
21
+ /**
22
+ * Sets up the $_options array with the correct values.
23
+ *
24
+ * This function is called in the constructor.
25
+ *
26
+ * @return Temando_Temando_Model_System_Config_Source_Abstract
27
+ */
28
+ protected abstract function _setupOptions();
29
+
30
+ /**
31
+ * Gets all the options in the key => value type array.
32
+ *
33
+ * @return array
34
+ */
35
+ public function getOptions($please_select = false)
36
+ {
37
+ $options = $this->_options;
38
+ if ($please_select) {
39
+ $options = array(null => '--Please Select--') + $options;
40
+ }
41
+ return $options;
42
+ }
43
+
44
+ /**
45
+ * Converts the options into a format suitable for use in the admin area.
46
+ *
47
+ * @return array
48
+ */
49
+ public function toOptionArray()
50
+ {
51
+ return $this->_toOptionArray($this->_options);
52
+ }
53
+
54
+ protected function _toOptionArray($input)
55
+ {
56
+ $array = array();
57
+
58
+ foreach ($input as $key => $value) {
59
+ $array[] = array(
60
+ 'value' => $key,
61
+ 'label' => $value,
62
+ );
63
+ }
64
+
65
+ return $array;
66
+ }
67
+
68
+ /**
69
+ * Looks up an option by key and gets the label.
70
+ *
71
+ * @param mixed $value
72
+ * @return mixed
73
+ */
74
+ public function getOptionLabel($value)
75
+ {
76
+ if (array_key_exists($value, $this->_options)) {
77
+ return $this->_options[$value];
78
+ }
79
+ return null;
80
+ }
81
+
82
+ }
app/code/community/Temando/Temando/Model/System/Config/Source/Carbon.php ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Temando_Temando_Model_System_Config_Source_Carbon extends Temando_Temando_Model_System_Config_Source
4
+ {
5
+
6
+ const DISABLED = 'disabled';
7
+ const OPTIONAL = 'optional';
8
+ const MANDATORY = 'mandatory';
9
+
10
+ protected function _setupOptions()
11
+ {
12
+ $this->_options = array(
13
+ self::DISABLED => 'Disabled',
14
+ self::OPTIONAL => 'Optional',
15
+ self::MANDATORY => 'Mandatory',
16
+ );
17
+ }
18
+
19
+ }
app/code/community/Temando/Temando/Model/System/Config/Source/Client/Type.php ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Temando_Temando_Model_System_Config_Source_Client_Type extends Temando_Temando_Model_System_Config_Source
4
+ {
5
+
6
+ const INDIVIDUAL = 'Individual';
7
+ const COMPANY = 'Company';
8
+
9
+ protected function _setupOptions()
10
+ {
11
+ $this->_options = array(
12
+ self::INDIVIDUAL => Mage::helper('temando')->__('Individual'),
13
+ self::COMPANY => Mage::helper('temando')->__('Company'),
14
+ );
15
+ }
16
+
17
+ }
app/code/community/Temando/Temando/Model/System/Config/Source/Country.php ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Temando_Temando_Model_System_Config_Source_Country extends Temando_Temando_Model_System_Config_Source
4
+ {
5
+
6
+ protected $_options;
7
+
8
+ public function _setupOptions() {
9
+
10
+ if(!$this->_options) {
11
+ $countries = Mage::getResourceModel('directory/country_collection')->loadData()->toOptionArray(false);
12
+
13
+ foreach($countries as $country => $arr) {
14
+ $this->_options[$arr['value']] = $arr['label'];
15
+ }
16
+ }
17
+ }
18
+
19
+ }
app/code/community/Temando/Temando/Model/System/Config/Source/Errorprocess.php ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Temando_Temando_Model_System_Config_Source_Errorprocess extends Temando_Temando_Model_System_Config_Source
4
+ {
5
+
6
+ const VIEW = 'view';
7
+ const FLAT = 'flat';
8
+
9
+ protected function _setupOptions()
10
+ {
11
+ $this->_options = array(
12
+ self::FLAT => 'Show flat rate',
13
+ self::VIEW => 'Show error message',
14
+ );
15
+ }
16
+
17
+ }
app/code/community/Temando/Temando/Model/System/Config/Source/Footprints.php ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Temando_Temando_Model_System_Config_Source_Footprints extends Temando_Temando_Model_System_Config_Source
4
+ {
5
+
6
+ const DISABLED = 'disabled';
7
+ const OPTIONAL = 'optional';
8
+ const MANDATORY = 'mandatory';
9
+
10
+ protected function _setupOptions()
11
+ {
12
+ $this->_options = array(
13
+ self::DISABLED => 'Disabled',
14
+ self::OPTIONAL => 'Optional',
15
+ self::MANDATORY => 'Mandatory',
16
+ );
17
+ }
18
+
19
+ }
app/code/community/Temando/Temando/Model/System/Config/Source/Insurance.php ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Temando_Temando_Model_System_Config_Source_Insurance extends Temando_Temando_Model_System_Config_Source
4
+ {
5
+
6
+ const DISABLED = 'disabled';
7
+ const OPTIONAL = 'optional';
8
+ const MANDATORY = 'mandatory';
9
+
10
+ protected function _setupOptions()
11
+ {
12
+ $this->_options = array(
13
+ self::DISABLED => 'Disabled',
14
+ self::OPTIONAL => 'Optional',
15
+ self::MANDATORY => 'Mandatory',
16
+ );
17
+ }
18
+
19
+ }
app/code/community/Temando/Temando/Model/System/Config/Source/Labeltype.php ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Temando_Temando_Model_System_Config_Source_Labeltype extends Temando_Temando_Model_System_Config_Source
4
+ {
5
+
6
+ const NO = '';
7
+ const STANDARD = 'Standard';
8
+ const THERMAL = 'Thermal';
9
+
10
+ protected function _setupOptions()
11
+ {
12
+ $this->_options = array(
13
+ self::NO => 'No',
14
+ self::STANDARD => 'Plain Paper',
15
+ self::THERMAL => 'Thermal',
16
+ );
17
+ }
18
+
19
+ }
app/code/community/Temando/Temando/Model/System/Config/Source/Origin/Type.php ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Temando_Temando_Model_System_Config_Source_Origin_Type extends Temando_Temando_Model_System_Config_Source
4
+ {
5
+
6
+ const BUSINESS = 'Business';
7
+ const RESIDENTIAL = 'Residence';
8
+
9
+ public function _setupOptions()
10
+ {
11
+ $this->_options = array(
12
+ self::BUSINESS => Mage::helper('temando')->__('Business'),
13
+ self::RESIDENTIAL => Mage::helper('temando')->__('Residential'),
14
+ );
15
+ }
16
+
17
+ }
app/code/community/Temando/Temando/Model/System/Config/Source/Payment.php ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Temando_Temando_Model_System_Config_Source_Payment extends Temando_Temando_Model_System_Config_Source
4
+ {
5
+
6
+ const CREDIT = 'Credit';
7
+ const ACCOUNT = 'Account';
8
+
9
+ protected function _setupOptions()
10
+ {
11
+ $this->_options = array(
12
+ self::CREDIT => 'Credit',
13
+ self::ACCOUNT => 'Account'
14
+ );
15
+ }
16
+
17
+ }
app/code/community/Temando/Temando/Model/System/Config/Source/Pricing.php ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Temando_Temando_Model_System_Config_Source_Pricing extends Temando_Temando_Model_System_Config_Source
4
+ {
5
+
6
+ const FREE = 'free';
7
+ const FLAT_RATE = 'flat';
8
+ const DYNAMIC = 'dynamic';
9
+ const DYNAMIC_FASTEST = 'dynamicfast';
10
+ const DYNAMIC_CHEAPEST = 'dynamiccheap';
11
+ const DYNAMIC_FASTEST_AND_CHEAPEST = 'dynamicfastcheap';
12
+
13
+ protected function _setupOptions()
14
+ {
15
+ $this->_options = array(
16
+ self::FREE => 'Free Shipping',
17
+ self::FLAT_RATE => 'Fixed Price / Flat Rate',
18
+ self::DYNAMIC => 'Dynamic Pricing (All)',
19
+ self::DYNAMIC_CHEAPEST => 'Dynamic Pricing (Cheapest only)',
20
+ self::DYNAMIC_FASTEST => 'Dynamic Pricing (Fastest only)',
21
+ self::DYNAMIC_FASTEST_AND_CHEAPEST => 'Dynamic Pricing (Cheapest and Fastest only)',
22
+ );
23
+ }
24
+
25
+ }
app/code/community/Temando/Temando/Model/System/Config/Source/Readytime.php ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Temando_Temando_Model_System_Config_Source_Readytime extends Temando_Temando_Model_System_Config_Source
4
+ {
5
+
6
+ const AM = 'AM';
7
+ const PM = 'PM';
8
+
9
+ protected function _setupOptions()
10
+ {
11
+ $this->_options = array(
12
+ self::AM => Mage::helper('temando')->__('AM'),
13
+ self::PM => Mage::helper('temando')->__('PM'),
14
+ );
15
+ }
16
+
17
+ }
app/code/community/Temando/Temando/Model/System/Config/Source/Regions.php ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Temando_Temando_Model_System_Config_Source_Regions extends Temando_Temando_Model_System_Config_Source
4
+ {
5
+
6
+ protected function _setupOptions()
7
+ {
8
+ $this->_options = array();
9
+
10
+ $regions = Mage::getModel('directory/region')->getCollection();
11
+ /* @var $regions Mage_Directory_Model_Mysql4_Region_Collection */
12
+ // $option_array = $regions
13
+ // ->addCountryFilter('AU');
14
+
15
+ $this->_options = array();
16
+
17
+ foreach ($regions as $region) {
18
+ /* @var $region Mage_Directory_Model_Region */
19
+ $this->_options[strtoupper($region->getCode())] = $region->getName();
20
+ }
21
+ }
22
+
23
+ }
app/code/community/Temando/Temando/Model/System/Config/Source/Rule/Action/Adjustment/Type.php ADDED
@@ -0,0 +1,27 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Temando_Temando_Model_System_Config_Source_Rule_Action_Adjustment_Type
4
+ extends Temando_Temando_Model_System_Config_Source {
5
+
6
+ const DO_NOT_USE = null;
7
+ const MARKUP_FIXED = '1';
8
+ const MARKUP_PERCENT = '2';
9
+ const SUBSIDY_FIXED = '3';
10
+ const SUBSIDY_PERCENT = '4';
11
+ const MINMAX = '5';
12
+ const CAPPED = '6';
13
+
14
+
15
+ protected function _setupOptions() {
16
+ $this->_options = array(
17
+ self::DO_NOT_USE => Mage::helper('temando')->__(' -- '),
18
+ self::MARKUP_FIXED => Mage::helper('temando')->__('Markup (fixed)'),
19
+ self::MARKUP_PERCENT => Mage::helper('temando')->__('Markup (percentage)'),
20
+ self::SUBSIDY_FIXED => Mage::helper('temando')->__('Subsidy (fixed)'),
21
+ self::SUBSIDY_PERCENT => Mage::helper('temando')->__('Subsidy (percentage)'),
22
+ self::MINMAX => Mage::helper('temando')->__('Min/Max Range'),
23
+ self::CAPPED => Mage::helper('temando')->__('Override')
24
+ );
25
+ }
26
+
27
+ }
app/code/community/Temando/Temando/Model/System/Config/Source/Rule/Action/Filter.php ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Temando_Temando_Model_System_Config_Source_Rule_Action_Filter
4
+ extends Temando_Temando_Model_System_Config_Source {
5
+
6
+ const DYNAMIC_ALL = 1;
7
+ const DYNAMIC_FASTEST = 2;
8
+ const DYNAMIC_CHEAPEST = 3;
9
+ const DYNAMIC_FASTEST_AND_CHEAPEST = 4;
10
+
11
+ protected function _setupOptions()
12
+ {
13
+ $this->_options = array(
14
+ self::DYNAMIC_ALL => 'All Quotes',
15
+ self::DYNAMIC_CHEAPEST => 'Cheapest only',
16
+ self::DYNAMIC_FASTEST => 'Fastest only',
17
+ self::DYNAMIC_FASTEST_AND_CHEAPEST => 'Cheapest and Fastest only',
18
+ );
19
+ }
20
+
21
+ }
app/code/community/Temando/Temando/Model/System/Config/Source/Rule/Condition/Time.php ADDED
@@ -0,0 +1,18 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Temando_Temando_Model_System_Config_Source_Rule_Condition_Time
4
+ extends Temando_Temando_Model_System_Config_Source {
5
+
6
+ const DO_NOT_USE = null;
7
+ const BEFORE = '1';
8
+ const AFTER = '2';
9
+
10
+ protected function _setupOptions() {
11
+ $this->_options = array(
12
+ self::DO_NOT_USE => Mage::helper('temando')->__(' -- '),
13
+ self::BEFORE => Mage::helper('temando')->__('before'),
14
+ self::AFTER => Mage::helper('temando')->__('after')
15
+ );
16
+ }
17
+
18
+ }
app/code/community/Temando/Temando/Model/System/Config/Source/Rule/Condition/Type.php ADDED
@@ -0,0 +1,18 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Temando_Temando_Model_System_Config_Source_Rule_Condition_Type
4
+ extends Temando_Temando_Model_System_Config_Source {
5
+
6
+ const WEIGHT = '1';
7
+ const SUBTOTAL = '2';
8
+ const ZONE = '3';
9
+
10
+ protected function _setupOptions() {
11
+ $this->_options = array(
12
+ self::WEIGHT => Mage::helper('temando')->__('Weight'),
13
+ self::SUBTOTAL => Mage::helper('temando')->__('Subtotal'),
14
+ self::ZONE => Mage::helper('temando')->__('Zone')
15
+ );
16
+ }
17
+
18
+ }
app/code/community/Temando/Temando/Model/System/Config/Source/Rule/Type.php ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Temando_Temando_Model_System_Config_Source_Rule_Type
4
+ extends Temando_Temando_Model_System_Config_Source {
5
+
6
+ const FLATRATE = '1';
7
+ const FREE = '2';
8
+ const DYNAMIC = '3';
9
+ const RESTRICT = '4';
10
+
11
+ protected function _setupOptions() {
12
+ $this->_options = array(
13
+ self::FLATRATE => Mage::helper('temando')->__('Flat Rate'),
14
+ self::FREE => Mage::helper('temando')->__('Free Shipping'),
15
+ self::DYNAMIC => Mage::helper('temando')->__('Dynamic'),
16
+ self::RESTRICT => Mage::helper('temando')->__('Restrict'),
17
+ );
18
+ }
19
+
20
+ }
app/code/community/Temando/Temando/Model/System/Config/Source/Sales/Order/Status.php ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Temando_Temando_Model_System_Config_Source_Sales_Order_Status {
4
+
5
+
6
+ public function toOptionArray($isMultiselect=false) {
7
+
8
+ $statuses = Mage::getSingleton('sales/order_config')->getStatuses();
9
+
10
+ $options = array();
11
+
12
+ foreach ($statuses as $code => $label) {
13
+ $options[] = array(
14
+ 'value' => $code,
15
+ 'label' => $label
16
+ );
17
+ }
18
+ if(!$isMultiselect){
19
+ array_unshift($options, array('value'=>'', 'label'=> Mage::helper('adminhtml')->__('--Please Select--')));
20
+ }
21
+ return $options;
22
+ }
23
+
24
+ }
25
+
app/code/community/Temando/Temando/Model/System/Config/Source/Shipment/Class.php ADDED
@@ -0,0 +1,27 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Temando_Temando_Model_System_Config_Source_Shipment_Class extends Temando_Temando_Model_System_Config_Source
4
+ {
5
+
6
+ const GENERAL_GOODS = 0;
7
+ const FREIGHT = 1;
8
+ const VEHICLE = 2;
9
+ const BOAT = 3;
10
+ const ANIMAL = 4;
11
+ const REFRIGERATED = 5;
12
+ const OTHER = 6;
13
+
14
+ protected function _setupOptions()
15
+ {
16
+ $this->_options = array(
17
+ self::GENERAL_GOODS => 'General Goods',
18
+ self::FREIGHT => 'Freight',
19
+ self::VEHICLE => 'Vehicle',
20
+ self::BOAT => 'Boat',
21
+ self::ANIMAL => 'Animal',
22
+ self::REFRIGERATED => 'Refrigerated',
23
+ self::OTHER => 'Other',
24
+ );
25
+ }
26
+
27
+ }
app/code/community/Temando/Temando/Model/System/Config/Source/Shipment/Packaging.php ADDED
@@ -0,0 +1,38 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Temando_Temando_Model_System_Config_Source_Shipment_Packaging extends Temando_Temando_Model_System_Config_Source
4
+ {
5
+ const BOX = 0;
6
+ const CARTON = 1;
7
+ const CRATE = 2;
8
+ const CYLINDER = 3;
9
+ const DOCUMENT_ENVELOPE = 4;
10
+ const FLAT_PACK = 5;
11
+ const LETTER = 6;
12
+ const PALLET = 7;
13
+ const PARCEL = 8;
14
+ const SATCHEL_OR_BAG = 9;
15
+ const SKID = 10;
16
+ const UNPACKAGED_OR_NA = 11;
17
+ const WHEEL_OR_TYRE = 12;
18
+
19
+ protected function _setupOptions()
20
+ {
21
+ $this->_options = array(
22
+ self::BOX => 'Box',
23
+ self::CARTON => 'Carton',
24
+ self::CRATE => 'Crate',
25
+ self::CYLINDER => 'Cylinder',
26
+ self::DOCUMENT_ENVELOPE => 'Document Envelope',
27
+ self::FLAT_PACK => 'Flat Pack',
28
+ self::LETTER => 'Letter',
29
+ self::PALLET => 'Pallet',
30
+ self::PARCEL => 'Parcel',
31
+ self::SATCHEL_OR_BAG => 'Satchel/Bag',
32
+ self::SKID => 'Skid',
33
+ self::UNPACKAGED_OR_NA => 'Unpackaged or N/A',
34
+ self::WHEEL_OR_TYRE => 'Wheel/Tyre'
35
+ );
36
+ }
37
+
38
+ }
app/code/community/Temando/Temando/Model/System/Config/Source/Shipment/Packaging/Mode.php ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Temando_Temando_Model_System_Config_Source_Shipment_Packaging_Mode extends Temando_Temando_Model_System_Config_Source
4
+ {
5
+ const USE_DEFAULTS = 0;
6
+ const AS_DEFINED = 1;
7
+
8
+ protected function _setupOptions()
9
+ {
10
+ $this->_options = array(
11
+ self::USE_DEFAULTS => 'Use Defaults',
12
+ self::AS_DEFINED => 'As Defined',
13
+ );
14
+ }
15
+
16
+ }
app/code/community/Temando/Temando/Model/System/Config/Source/Shipment/Service.php ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Temando_Temando_Model_System_Config_Source_Shipment_Service extends Temando_Temando_Model_System_Config_Source
4
+ {
5
+
6
+ const SAME_DAY = 1;
7
+ const EXPRESS = 2;
8
+ const STANDARD = 3;
9
+
10
+ protected function _setupOptions()
11
+ {
12
+ $this->_options = array(
13
+ self::SAME_DAY => 'Same Day',
14
+ self::EXPRESS => 'Express',
15
+ self::STANDARD => 'Standard',
16
+ );
17
+ }
18
+
19
+ }
app/code/community/Temando/Temando/Model/System/Config/Source/Shipment/Status.php ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Temando_Temando_Model_System_Config_Source_Shipment_Status extends Temando_Temando_Model_System_Config_Source
4
+ {
5
+
6
+ const PENDING = '0';
7
+ const BOOKED = '1';
8
+
9
+ protected function _setupOptions()
10
+ {
11
+ $this->_options = array(
12
+ self::PENDING => Mage::helper('temando')->__('Pending'),
13
+ self::BOOKED => Mage::helper('temando')->__('Booked'),
14
+ );
15
+ }
16
+
17
+ }
app/code/community/Temando/Temando/Model/System/Config/Source/Unit.php ADDED
@@ -0,0 +1,56 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ abstract class Temando_Temando_Model_System_Config_Source_Unit extends Temando_Temando_Model_System_Config_Source
4
+ {
5
+
6
+ /**
7
+ * Same as the parent::_options array, except with brief labels as values.
8
+ *
9
+ * As the $_options array will contain the name of the unit (e.g. "Metres",
10
+ * "Inches"), this will contain a shorter description e.g. the units when
11
+ * used after a measurement ("m.", "in.", etc).
12
+ *
13
+ * @var array
14
+ */
15
+ protected $_brief_options;
16
+
17
+ public function __construct()
18
+ {
19
+ parent::__construct();
20
+ $this->_setupBriefOptions();
21
+ }
22
+
23
+ /**
24
+ * Sets up the $_brief_options array with the correct values.
25
+ *
26
+ * This function is called in the constructor.
27
+ *
28
+ * @return Temando_Temando_Model_System_Config_Source_Abstract
29
+ */
30
+ protected abstract function _setupBriefOptions();
31
+
32
+ /**
33
+ * Looks up an option by key and gets the label.
34
+ *
35
+ * @param mixed $value
36
+ * @return mixed
37
+ */
38
+ public function getBriefOptionLabel($value)
39
+ {
40
+ if (array_key_exists($value, $this->_brief_options)) {
41
+ return $this->_brief_options[$value];
42
+ }
43
+ return null;
44
+ }
45
+
46
+ public function toBriefOptionArray()
47
+ {
48
+ return $this->_toOptionArray($this->_brief_options);
49
+ }
50
+
51
+ public function getOptionValue($value)
52
+ {
53
+ return array_search($value, array_flip($this->_brief_options));
54
+ }
55
+
56
+ }
app/code/community/Temando/Temando/Model/System/Config/Source/Unit/Measure.php ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Temando_Temando_Model_System_Config_Source_Unit_Measure extends Temando_Temando_Model_System_Config_Source_Unit
4
+ {
5
+
6
+ const CENTIMETRES = 'Centimetres';
7
+ const METRES = 'Metres';
8
+ const INCHES = 'Inches';
9
+ const FEET = 'Feet';
10
+
11
+ protected function _setupOptions()
12
+ {
13
+ $this->_options = array(
14
+ self::CENTIMETRES => 'Centimetres',
15
+ self::METRES => 'Metres',
16
+ self::INCHES => 'Inches',
17
+ self::FEET => 'Feet',
18
+ );
19
+ }
20
+
21
+ protected function _setupBriefOptions()
22
+ {
23
+ $this->_brief_options = array(
24
+ self::CENTIMETRES => 'cm',
25
+ self::METRES => 'm',
26
+ self::INCHES => 'in.',
27
+ self::FEET => 'ft.',
28
+ );
29
+ }
30
+
31
+ }
app/code/community/Temando/Temando/Model/System/Config/Source/Unit/Weight.php ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Temando_Temando_Model_System_Config_Source_Unit_Weight extends Temando_Temando_Model_System_Config_Source_Unit
4
+ {
5
+
6
+ const GRAMS = 'Grams';
7
+ const KILOGRAMS = 'Kilograms';
8
+ const OUNCES = 'Ounces';
9
+ const POUNDS = 'Pounds';
10
+
11
+ protected function _setupOptions()
12
+ {
13
+ $this->_options = array(
14
+ self::GRAMS => 'Grams',
15
+ self::KILOGRAMS => 'Kilograms',
16
+ self::OUNCES => 'Ounces',
17
+ self::POUNDS => 'Pounds',
18
+ );
19
+ }
20
+
21
+ protected function _setupBriefOptions()
22
+ {
23
+ $this->_brief_options = array(
24
+ self::GRAMS => 'g',
25
+ self::KILOGRAMS => 'kg',
26
+ self::OUNCES => 'oz.',
27
+ self::POUNDS => 'lb.',
28
+ );
29
+ }
30
+
31
+ }
app/code/community/Temando/Temando/controllers/Adminhtml/JsonController.php ADDED
@@ -0,0 +1,55 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Temando_Temando_Adminhtml_JsonController extends Mage_Adminhtml_Controller_Action {
4
+
5
+ /**
6
+ * Return JSON-encoded array of country regions
7
+ *
8
+ * @return string
9
+ */
10
+ public function countryRegionAction()
11
+ {
12
+ $arrRes = array();
13
+
14
+ $countryId = $this->getRequest()->getParam('parent');
15
+ $colRegions = Mage::getResourceModel('directory/region_collection')
16
+ ->addCountryFilter($countryId)
17
+ ->load();
18
+
19
+ $arrRegions = $this->_toOptionArray($colRegions);
20
+ if (!empty($arrRegions)) {
21
+ foreach ($arrRegions as $region) {
22
+ $arrRes[] = $region;
23
+ }
24
+ }
25
+
26
+ $this->getResponse()->setBody(Mage::helper('core')->jsonEncode($arrRes));
27
+ }
28
+
29
+ private function _toOptionArray(Mage_Directory_Model_Resource_Region_Collection $collection)
30
+ {
31
+ $options = array();
32
+ if(!empty($collection)) {
33
+ foreach($collection->getItems() as $region) {
34
+ $options[$region->getRegionId()] = array(
35
+ 'title' => $region->getDefaultName(),
36
+ 'value' => $region->getCode(),
37
+ 'label' => Mage::helper('temando')->__($region->getDefaultName())
38
+ );
39
+ }
40
+ }
41
+
42
+ if (count($options) > 0) {
43
+ array_unshift($options, array(
44
+ 'title '=> null,
45
+ 'value' => '',
46
+ 'label' => Mage::helper('temando')->__('-- Please select --')
47
+ ));
48
+ }
49
+
50
+ return $options;
51
+ }
52
+
53
+ }
54
+
55
+
app/code/community/Temando/Temando/controllers/Adminhtml/ManifestController.php ADDED
@@ -0,0 +1,238 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Temando_Temando_Adminhtml_ManifestController extends Mage_Adminhtml_Controller_Action
4
+ {
5
+
6
+ public function indexAction()
7
+ {
8
+ $this->loadLayout()
9
+ ->_setActiveMenu('temando/manifest')
10
+ ->_addBreadcrumb(Mage::helper('adminhtml')->__('Manage Manifests'), Mage::helper('adminhtml')->__('Manage Manifests'))
11
+ ->renderLayout();
12
+ }
13
+
14
+ /**
15
+ * Convert dates in array from localized to internal format
16
+ *
17
+ * @param array $array
18
+ * @param array $dateFields
19
+ * @return array
20
+ */
21
+ protected function _filterDates($array, $dateFields)
22
+ {
23
+ if (empty($dateFields)) {
24
+ return $array;
25
+ }
26
+ $filterInput = new Zend_Filter_LocalizedToNormalized(array(
27
+ 'date_format' => Mage::app()->getLocale()->getDateFormat(Mage_Core_Model_Locale::FORMAT_TYPE_SHORT)
28
+ ));
29
+ $filterInternal = new Zend_Filter_NormalizedToLocalized(array(
30
+ 'date_format' => Varien_Date::DATE_INTERNAL_FORMAT
31
+ ));
32
+
33
+ foreach ($dateFields as $dateField) {
34
+ if (array_key_exists($dateField, $array) && !empty($dateField)) {
35
+ $array[$dateField] = $filterInput->filter($array[$dateField]);
36
+ $array[$dateField] = $filterInternal->filter($array[$dateField]);
37
+ }
38
+ }
39
+ return $array;
40
+ }
41
+
42
+ public function addAction()
43
+ {
44
+ $postData = $this->getRequest()->getPost();
45
+ $post = $this->_filterDates($postData, array('from', 'to'));
46
+ $carriers = $this->getRequest()->getParam('carrier_id');
47
+ if (!is_array($carriers)) {
48
+ $carriers = array($carriers);
49
+ }
50
+
51
+ $carriers_options = Mage::getModel('temando/shipping_carrier_temando_source_method')->getOptions();
52
+ foreach ($carriers as $carrierId) {
53
+
54
+ if(!$carrierId)
55
+ continue;
56
+
57
+ $request = array(
58
+ 'carrierId' => $carrierId,
59
+ 'location' => $this->getRequest()->getParam('warehouse_id'),
60
+ 'readyDate' => isset($post['from'])?$post['from']:'',
61
+ 'type' => 'Awaiting Confirmation',
62
+ 'labelPrinterType' => Mage::helper('temando')->getConfigData('options/label_type')
63
+ );
64
+
65
+ try {
66
+ $api = Mage::getModel('temando/api_client');
67
+ /* @var $api Temando_Temando_Model_Api_Client */
68
+ $api->connect(
69
+ Mage::helper('temando')->getConfigData('general/username'),
70
+ Mage::helper('temando')->getConfigData('general/password'),
71
+ Mage::helper('temando')->getConfigData('general/sandbox'));
72
+ $result = $api->getManifest($request);
73
+ if (!$result) {
74
+ throw new Exception('Cannot send request');
75
+ }
76
+
77
+ $model = Mage::getModel('temando/manifest')
78
+ ->setData('location_id', $this->getRequest()->getParam('warehouse_id'))
79
+ ->setData('carrier_id', $carrierId)
80
+ ->setData('start_date', isset($post['from'])?$post['from']:'')
81
+ ->setData('end_date', isset($post['from'])?$post['from']:'')
82
+ ->setData('manifest_document_type', '')
83
+ ->setData('manifest_document', '')
84
+ ->setData('label_document_type', '')
85
+ ->setData('type', 'Awaiting Confirmation')
86
+ ->setData('label_document', '')
87
+ ;
88
+
89
+ $carrier_name = $carriers_options[$carrierId];
90
+ if (!isset($result->manifestDocument) || !((string)$result->manifestDocument)) {
91
+ throw new Exception('No data for carrier: ' . $carrier_name);
92
+ }
93
+
94
+ if (isset($result->manifestDocumentType)) {
95
+ $model->setData('manifest_document_type', (string)$result->manifestDocumentType);
96
+ }
97
+ if (isset($result->manifestDocument)) {
98
+ $model->setData('manifest_document', (string)$result->manifestDocument);
99
+ }
100
+ if (isset($result->labelDocumentType)) {
101
+ $model->setData('label_document_type', (string)$result->labelDocumentType);
102
+ }
103
+ if (isset($result->labelDocument)) {
104
+ $model->setData('label_document', (string)$result->labelDocument);
105
+ }
106
+
107
+ $model->save();
108
+ $this->_getSession()
109
+ ->addSuccess($this->__('Manifest successful added for carrier: ' . $carrier_name));
110
+ } catch (Exception $e) {
111
+ $this->_getSession()
112
+ ->addError($e->getMessage());
113
+ }
114
+ }
115
+
116
+ $this->_redirect('*/*/');
117
+ }
118
+
119
+ public function manifestAction()
120
+ {
121
+ $manifest = Mage::getModel('temando/manifest')
122
+ ->load($this->getRequest()->getParam('id'));
123
+ /* @var $manifest Temando_Temando_Model_Manifest */
124
+ if ($manifest->getId()) {
125
+ $document = base64_decode($manifest->getManifestDocument());
126
+ $document_length = strlen($document);
127
+ $extension = '.pdf';
128
+ $_t = explode('/', $manifest->getManifestDocumentType());
129
+ if (isset($_t[1])) {
130
+ $extension = "." . $_t[1];
131
+ }
132
+
133
+ if ($document_length) {
134
+ $this->getResponse()
135
+ ->setHttpResponseCode(200)
136
+ ->setHeader('Pragma', 'public', true)
137
+ ->setHeader('Cache-Control', 'must-revalidate, post-check=0, pre-check=0', true)
138
+ ->setHeader('Content-type', $manifest->getManifestDocumentType(), true)
139
+ ->setHeader('Content-Length', $document_length)
140
+ ->setHeader('Content-Disposition', 'attachment; filename="manifest-'.$manifest->getId().$extension.'"')
141
+ ->setHeader('Last-Modified', date('r'));
142
+ $this->getResponse()->clearBody();
143
+ $this->getResponse()->sendHeaders();
144
+ print $document;
145
+ }
146
+ }
147
+ }
148
+
149
+ public function labelAction()
150
+ {
151
+ $manifest = Mage::getModel('temando/manifest')
152
+ ->load($this->getRequest()->getParam('id'));
153
+ /* @var $manifest Temando_Temando_Model_Manifest */
154
+ if ($manifest->getId()) {
155
+ $document = base64_decode($manifest->getLabelDocument());
156
+ $document_length = strlen($document);
157
+ $extension = '.pdf';
158
+ $_t = explode('/', $manifest->getLabelDocumentType());
159
+ if (isset($_t[1])) {
160
+ $extension = "." . $_t[1];
161
+ }
162
+
163
+ if ($document_length) {
164
+ $this->getResponse()
165
+ ->setHttpResponseCode(200)
166
+ ->setHeader('Pragma', 'public', true)
167
+ ->setHeader('Cache-Control', 'must-revalidate, post-check=0, pre-check=0', true)
168
+ ->setHeader('Content-type', $manifest->getLabelDocumentType(), true)
169
+ ->setHeader('Content-Length', $document_length)
170
+ ->setHeader('Content-Disposition', 'attachment; filename="label-'.$manifest->getId().$extension.'"')
171
+ ->setHeader('Last-Modified', date('r'));
172
+ $this->getResponse()->clearBody();
173
+ $this->getResponse()->sendHeaders();
174
+ print $document;
175
+ }
176
+ }
177
+ }
178
+
179
+ public function confirmAction()
180
+ {
181
+ $manifests = Mage::getModel('temando/manifest')
182
+ ->getCollection()->addFieldToFilter('type', 'Awaiting Confirmation')->getItems();
183
+ $carriers_options = Mage::getModel('temando/shipping_carrier_temando_source_method')->getOptions();
184
+ foreach ($manifests as $manifest) {
185
+ $request = array(
186
+ 'carrierId' => $manifest->getCarrierId(),
187
+ 'location' => $manifest->getLocationId(),
188
+ 'startReadyDate' => $manifest->getStartDate(),
189
+ 'endReadyDate' => $manifest->getStartDate(),
190
+ /* @todo use store date, not server date */
191
+ 'confirmedReadyDate' => now(true),
192
+ 'labelPrinterType' => Mage::helper('temando')->getConfigData('options/label_type')
193
+ );
194
+
195
+ try {
196
+ $api = Mage::getModel('temando/api_client');
197
+ $api->connect(
198
+ Mage::helper('temando')->getConfigData('general/username'),
199
+ Mage::helper('temando')->getConfigData('general/password'),
200
+ Mage::helper('temando')->getConfigData('general/sandbox'),
201
+ true);
202
+ $result = $api->confirmManifest($request);
203
+ if (!$result) {
204
+ throw new Exception('Cannot send request');
205
+ }
206
+
207
+ $carrier_name = $carriers_options[$manifest->getCarrierId()];
208
+ if (!isset($result->manifestDocument) || !((string)$result->manifestDocument)) {
209
+ throw new Exception('No data for carrier: ' . $carrier_name . 'and date ' . $manifest->getStartDate());
210
+ }
211
+
212
+ if (isset($result->manifestDocumentType)) {
213
+ $manifest->setData('manifest_document_type', (string)$result->manifestDocumentType);
214
+ }
215
+ if (isset($result->manifestDocument)) {
216
+ $manifest->setData('manifest_document', (string)$result->manifestDocument);
217
+ }
218
+ if (isset($result->labelDocumentType)) {
219
+ $manifest->setData('label_document_type', (string)$result->labelDocumentType);
220
+ }
221
+ if (isset($result->labelDocument)) {
222
+ $manifest->setData('label_document', (string)$result->labelDocument);
223
+ }
224
+
225
+ $manifest->setData('type', 'Confirmed');
226
+ $manifest->save();
227
+ $this->_getSession()
228
+ ->addSuccess($this->__('Manifest successful confirmed for carrier: ' . $carrier_name . ' and date ' . $manifest->getStartDate()));
229
+ } catch (Exception $e) {
230
+ $this->_getSession()
231
+ ->addError($e->getMessage());
232
+ }
233
+ }
234
+
235
+ $this->_redirect('*/*/');
236
+ }
237
+
238
+ }
app/code/community/Temando/Temando/controllers/Adminhtml/ShipmentController.php ADDED
@@ -0,0 +1,521 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Temando_Temando_Adminhtml_ShipmentController extends Mage_Adminhtml_Controller_Action {
4
+
5
+ public function indexAction() {
6
+ $this->loadLayout()
7
+ ->_setActiveMenu('temando/shipment')
8
+ ->_addBreadcrumb(Mage::helper('adminhtml')->__('Shipment Manager'), Mage::helper('adminhtml')->__('Shipment Manager'))
9
+ ->renderLayout();
10
+ }
11
+
12
+ public function editAction() {
13
+ $id = $this->getRequest()->getParam('id');
14
+ $shipment = Mage::getModel('temando/shipment')->load($id);
15
+ /* @var $shipment Temando_Temando_Model_Shipment */
16
+
17
+ if ($shipment->getId()) {
18
+ $notices = array();
19
+
20
+ if (!count($shipment->getBoxes())) {
21
+ $notices[] = 'Quotes cannot be refreshed until at least one box is added to the shipment.';
22
+ }
23
+
24
+ foreach ($notices as $notice) {
25
+ $this->_getSession()->addNotice($this->__($notice));
26
+ }
27
+
28
+ $data = Mage::getSingleton('adminhtml/session')->getFormData(true);
29
+ if (!empty($data)) {
30
+ $shipment->addData($data);
31
+ }
32
+
33
+ Mage::register('temando_shipment_data', $shipment);
34
+
35
+ $this->loadLayout()
36
+ ->_setActiveMenu('temando/shipment');
37
+
38
+ $this->getLayout()->getBlock('head')->setCanLoadExtJs(true);
39
+
40
+ $this->renderLayout();
41
+ } else {
42
+ Mage::getSingleton('adminhtml/session')->addError($this->__('Shipment does not exist.'));
43
+ $this->_redirect('*/*/');
44
+ }
45
+ }
46
+
47
+ public function saveAction() {
48
+ if ($data = $this->getRequest()->getPost()) {
49
+ $shipment = Mage::getModel('temando/shipment');
50
+ /* @var $shipment Temando_Temando_Model_Shipment */
51
+
52
+ $result = $this->_validateFormData($data);
53
+ if (isset($data['insurance'])) {
54
+ Mage::getSingleton('adminhtml/session')->setData('insurance_' . $this->getRequest()->getParam('id'), $data['insurance']);
55
+ } else {
56
+ Mage::getSingleton('adminhtml/session')->unsetData('insurance_' . $this->getRequest()->getParam('id'));
57
+ }
58
+
59
+ foreach ($result['notices'] as $notice) {
60
+ $this->_getSession()->addNotice($notice);
61
+ }
62
+
63
+ if ($result['errors']) {
64
+ $this->_getSession()
65
+ ->addError('Validation errors:')
66
+ ->setFormData($data);
67
+ foreach ($result['errors'] as $error) {
68
+ $this->_getSession()->addError($error);
69
+ }
70
+ $this->_redirect('*/*/edit', array('id' => $this->getRequest()->getParam('id')));
71
+ return;
72
+ }
73
+
74
+ try {
75
+ if (!$data['ready']) {
76
+ $data['ready_date'] = null;
77
+ }
78
+ $shipment->setId($this->getRequest()->getParam('id'))
79
+ ->addData($data);
80
+
81
+ if ($data['boxes_deleted']) {
82
+ $box_ids = explode(',', $data['boxes_deleted']);
83
+ foreach ($box_ids as $box_id) {
84
+ $box = Mage::getModel('temando/box');
85
+ /* @var $box Temando_Temando_Model_Box */
86
+ $box->load($box_id);
87
+ if ($box->getId()) {
88
+ $box->delete();
89
+ }
90
+ }
91
+ }
92
+
93
+ if (isset($data['box']) && is_array($data['box'])) {
94
+ foreach ($data['box'] as $box_data) {
95
+ if (preg_match('/^custom_(\d+)/', $box_data['packaging'], $matches)) {
96
+ $customBox = Mage::getModel('temando/package')->load($matches[1]);
97
+ $box_data['packaging'] = $customBox->getPackaging();
98
+ }
99
+ $box = Mage::getModel('temando/box');
100
+ /* @var $box Temando_Temando_Model_Box */
101
+ if (isset($box_data['id'])) {
102
+ $box->load($box_data['id']);
103
+ }
104
+
105
+ $box->setShipmentId($shipment->getId())
106
+ ->addData($box_data)
107
+ ->save();
108
+ }
109
+ }
110
+
111
+ $shipment->clearQuotes()->save();
112
+ $shipment = Mage::getModel('temando/shipment')->load($shipment->getId());
113
+
114
+ if ($shipment->getBoxes()) {
115
+ $shipment->fetchQuotes(
116
+ Mage::helper('temando')->getConfigData('general/username'),
117
+ Mage::helper('temando')->getConfigData('general/password'),
118
+ Mage::helper('temando')->getConfigData('general/sandbox')
119
+ );
120
+ }
121
+
122
+ $this->_getSession()->addSuccess($this->__('The shipment data has been saved.'));
123
+
124
+ switch ($this->getRequest()->getParam('and')) {
125
+ case 'getquotes':
126
+ $this->_redirect('*/*/edit', array('id' => $shipment->getId()));
127
+ break;
128
+ case 'next':
129
+ // TODO: save and next
130
+ default:
131
+ $this->_redirect('*/*/');
132
+ break;
133
+ }
134
+ } catch (Exception $ex) {
135
+ $this->_getSession()->addError($ex->getMessage())->setFormData($data);
136
+ $this->_redirect('*/*/edit', array('id' => $this->getRequest()->getParam('id')));
137
+ }
138
+ return;
139
+ }
140
+
141
+ // nothing to save
142
+ $this->_redirect('*/*/');
143
+ }
144
+
145
+ protected function _validateFormData(&$data) {
146
+ $return = array(
147
+ 'notices' => array(),
148
+ 'errors' => array(),
149
+ );
150
+ if ($data['ready_date']) {
151
+ $timestamp = strtotime($data['ready_date']);
152
+ if ($timestamp) {
153
+ $data['ready_date'] = date('Y-m-d', $timestamp);
154
+ } else {
155
+ $return['errors'][] = 'Pick-up date is not a valid date.';
156
+ }
157
+ }
158
+ if (strtotime($data['ready_date'] . ' + 1 day') < date('U')) {
159
+ $return['notices'][] = 'Pick-up date is in the past.';
160
+ unset($data['ready_date']);
161
+ }
162
+ if (!in_array($data['ready_time'], array('AM', 'PM', ''))) {
163
+ $return['errors'][] = 'Pick-up time is not a valid selection.';
164
+ }
165
+
166
+ return $return;
167
+ }
168
+
169
+ public function bookAction() {
170
+ $shipment_id = $this->getRequest()->getParam('shipment');
171
+ $shipment = Mage::getModel('temando/shipment')
172
+ ->load($shipment_id);
173
+ /* @var $shipment Temando_Temando_Model_Shipment */
174
+
175
+ $quote_id = $this->getRequest()->getParam('quote');
176
+ $quote = Mage::getModel('temando/quote')
177
+ ->load($quote_id);
178
+ /* @var $quote Temando_Temando_Model_Quote */
179
+
180
+ $error = null;
181
+
182
+ if (!$shipment->getId()) {
183
+ $error = 'Shipment does not exist.';
184
+ } else {
185
+ if (!$quote->getId()) {
186
+ $error = 'Selected quote does not exist.';
187
+ } else {
188
+ foreach ($shipment->getOptions() as $o) {
189
+ if (("insurance" == $o->getId()) && ('Y' == $o->getForcedValue())) {
190
+ if ('Y' != Mage::helper('temando')->getConfigData('insurance/confirm_' . Mage::helper('temando')->getConfigData('insurance/status'))) {
191
+ $error = 'Please agree to the insurance terms & conditions at System -> Configuration -> Temando Settings -> Insurance.';
192
+ }
193
+ }
194
+ }
195
+
196
+ if (!$error) {
197
+ // try to make booking
198
+ try {
199
+ $booking_result = $this->_makeBooking($shipment, $quote);
200
+ } catch (Exception $ex) {
201
+ $error = $ex->getMessage();
202
+ }
203
+ }
204
+ }
205
+ }
206
+
207
+ if (!$error && $booking_result) {
208
+
209
+ if (!isset($booking_result->bookingNumber)) {
210
+ $booking_result->bookingNumber = null;
211
+ }
212
+ if (!isset($booking_result->consignmentNumber)) {
213
+ $booking_result->consignmentNumber = null;
214
+ }
215
+ if (!isset($booking_result->consignmentDocument)) {
216
+ $booking_result->consignmentDocument = null;
217
+ }
218
+ if (!isset($booking_result->consignmentDocumentType)) {
219
+ $booking_result->consignmentDocumentType = null;
220
+ }
221
+ if (!isset($booking_result->requestId)) {
222
+ $booking_result->requestId = null;
223
+ }
224
+ if (!isset($booking_result->labelDocument)) {
225
+ $booking_result->labelDocument = null;
226
+ }
227
+ if (!isset($booking_result->labelDocumentType)) {
228
+ $booking_result->labelDocumentType = '';
229
+ }
230
+ if (isset($booking_result->anytime)) {
231
+ $shipment->setReadyDate((string) $booking_result->anytime->readyDate);
232
+ $shipment->setReadyTime((string) $booking_result->anytime->readyTime);
233
+ }
234
+
235
+ $shipment
236
+ ->setAdminSelectedQuoteId($quote_id)
237
+ ->setBookingRequestId($booking_result->requestId)
238
+ ->setBookingNumber($booking_result->bookingNumber)
239
+ ->setConsignmentNumber($booking_result->consignmentNumber)
240
+ ->setConsignmentDocument($booking_result->consignmentDocument)
241
+ ->setConsignmentDocumentType($booking_result->consignmentDocumentType)
242
+ ->setLabelDocument($booking_result->labelDocument)
243
+ ->setLabelDocumentType($booking_result->labelDocumentType)
244
+ ->setStatus(Temando_Temando_Model_System_Config_Source_Shipment_Status::BOOKED)
245
+ ->setAnticipatedCost($shipment->getSelectedQuotePermutation()->getTotalPrice())
246
+ ->save();
247
+
248
+ $magento_shipment = Mage::getModel('sales/convert_order')
249
+ ->toShipment($shipment->getOrder());
250
+ /* @var $magento_shipment Mage_Sales_Model_Order_Shipment */
251
+
252
+ $totalQty = 0;
253
+ foreach ($shipment->getOrder()->getAllItems() as $item) {
254
+ if ($item->getQtyToShip() && !$item->getIsVirtual()) {
255
+ $magento_shipment_item = Mage::getModel('sales/convert_order')
256
+ ->itemToShipmentItem($item);
257
+
258
+ $qty = $item->getQtyToShip();
259
+
260
+ $magento_shipment_item->setQty($qty);
261
+ $magento_shipment->addItem($magento_shipment_item);
262
+
263
+ $totalQty += $qty;
264
+ }
265
+ }
266
+
267
+ $magento_shipment->setTotalQty($totalQty);
268
+
269
+ $track = Mage::getModel('sales/order_shipment_track');
270
+ /* @var Mage_Sales_Model_Order_Shipment_Track */
271
+ $number = '';
272
+ if ($booking_result->consignmentNumber) {
273
+ $number .= 'Consignment Number: ' . $booking_result->consignmentNumber;
274
+ }
275
+
276
+ if ($booking_result->requestId) {
277
+ if ($number) {
278
+ $number .= "\n<br />";
279
+ }
280
+
281
+ $number .= 'Request Id: ' . $booking_result->requestId;
282
+ }
283
+
284
+ $track
285
+ ->setCarrierCode(Mage::getModel('temando/shipping_carrier_temando')->getCarrierCode())
286
+ ->setTitle($quote->getCarrier()->getCompanyName())
287
+ ->setNumber($number);
288
+
289
+ $magento_shipment->addTrack($track)->register();
290
+
291
+ try {
292
+ $magento_shipment->getOrder()->setIsInProcess(true)->setCustomerNoteNotify(true);
293
+ Mage::getModel('core/resource_transaction')
294
+ ->addObject($shipment)
295
+ ->addObject($magento_shipment)
296
+ ->addObject($magento_shipment->getOrder())
297
+ ->save();
298
+ $magento_shipment->sendEmail();
299
+ } catch (Mage_Core_Exception $e) {
300
+ $error = $e->getMessage();
301
+ }
302
+
303
+ $this->_getSession()->addSuccess($this->__('Shipment booked.'));
304
+ }
305
+
306
+ if ($error) {
307
+ $this->_getSession()
308
+ ->addError($this->__($error))
309
+ /* ->setFormData($data) */;
310
+ }
311
+ $this->_redirect('*/*/edit', array('id' => $shipment_id));
312
+ }
313
+
314
+ protected function _makeBooking(Temando_Temando_Model_Shipment $shipment, Temando_Temando_Model_Quote $quote) {
315
+ $order = $shipment->getOrder();
316
+ /* @var $order Mage_Sales_Model_Order */
317
+
318
+ $request = Mage::getModel('temando/api_request');
319
+ /* @var $request Temando_Temando_Model_Api_Request */
320
+ $request
321
+ ->setMagentoQuoteId($order->getQuoteId())
322
+ ->setDestination(
323
+ $shipment->getDestinationCountry(),
324
+ $shipment->getDestinationPostcode(),
325
+ $shipment->getDestinationCity(),
326
+ $shipment->getDestinationStreet())
327
+ ->setItems($shipment->getBoxes()->getItems());
328
+ if ($shipment->getReadyDate()) {
329
+ $request->setReady(strtotime($shipment->getReadyDate()), $shipment->getReadyTime());
330
+ } else {
331
+ $request->setReady(null);
332
+ }
333
+
334
+ $request_array = $request->toRequestArray();
335
+ $request_array['origin'] = array(
336
+ 'description' => Temando_Temando_Helper_Data::DEFAULT_WAREHOUSE_NAME
337
+ );
338
+
339
+ $request_array['destination'] = array(
340
+ 'contactName' => $shipment->getDestinationContactName(),
341
+ 'companyName' => $shipment->getDestinationCompanyName(),
342
+ 'street' => $shipment->getDestinationStreet(),
343
+ 'suburb' => $shipment->getDestinationCity(),
344
+ 'code' => sprintf("%04d", $shipment->getDestinationPostcode()),
345
+ 'country' => $shipment->getDestinationCountry(),
346
+ 'phone1' => $shipment->getDestinationPhone(),
347
+ 'phone2' => '',
348
+ 'fax' => '',
349
+ 'email' => $shipment->getDestinationEmail(),
350
+ );
351
+
352
+ $option_array = $shipment->getOptionsArray();
353
+ if (!is_null(Mage::getSingleton('adminhtml/session')->getData('insurance_' . $shipment->getId()))) {
354
+ $option_array['insurance'] = Mage::getSingleton('adminhtml/session')->getData('insurance_' . $shipment->getId());
355
+ }
356
+
357
+ $request_array['quote'] = $quote->toBookingRequestArray($option_array);
358
+
359
+ $request_array['payment'] = array(
360
+ 'paymentType' => Mage::helper('temando')->getConfigData('general/payment_type'),
361
+ );
362
+
363
+ if (Mage::helper('temando')->getConfigData('options/label_type')) {
364
+ $request_array['labelPrinterType'] = Mage::helper('temando')->getConfigData('options/label_type');
365
+ }
366
+
367
+ $request_array['reference'] = $order->getIncrementId();
368
+
369
+ $api = Mage::getModel('temando/api_client');
370
+ /* @var $api Temando_Temando_Model_Api_Client */
371
+ $api->connect(
372
+ Mage::helper('temando')->getConfigData('general/username'),
373
+ Mage::helper('temando')->getConfigData('general/password'),
374
+ Mage::helper('temando')->getConfigData('general/sandbox')
375
+ );
376
+ return $api->makeBooking($request_array);
377
+ }
378
+
379
+ protected function _processBookingResult($booking_result, Temando_Temando_Model_Shipment $shipment, Temando_Temando_Model_Quote $quote) {
380
+ if ($booking_result) {
381
+
382
+ if (!isset($booking_result->bookingNumber)) {
383
+ $booking_result->bookingNumber = null;
384
+ }
385
+ if (!isset($booking_result->consignmentNumber)) {
386
+ $booking_result->consignmentNumber = null;
387
+ }
388
+ if (!isset($booking_result->consignmentDocument)) {
389
+ $booking_result->consignmentDocument = null;
390
+ }
391
+ if (!isset($booking_result->consignmentDocumentType)) {
392
+ $booking_result->consignmentDocumentType = null;
393
+ }
394
+ if (!isset($booking_result->requestId)) {
395
+ $booking_result->requestId = null;
396
+ }
397
+ if (!isset($booking_result->labelDocument)) {
398
+ $booking_result->labelDocument = null;
399
+ }
400
+ if (!isset($booking_result->labelDocumentType)) {
401
+ $booking_result->labelDocumentType = '';
402
+ }
403
+ if (isset($booking_result->anytime)) {
404
+ $shipment->setReadyDate((string) $booking_result->anytime->readyDate);
405
+ $shipment->setReadyTime((string) $booking_result->anytime->readyTime);
406
+ }
407
+
408
+ $shipment
409
+ ->setBookingRequestId($booking_result->requestId)
410
+ ->setBookingNumber($booking_result->bookingNumber)
411
+ ->setConsignmentNumber($booking_result->consignmentNumber)
412
+ ->setConsignmentDocument($booking_result->consignmentDocument)
413
+ ->setConsignmentDocumentType($booking_result->consignmentDocumentType)
414
+ ->setLabelDocument($booking_result->labelDocument)
415
+ ->setLabelDocumentType($booking_result->labelDocumentType)
416
+ ->setStatus(Temando_Temando_Model_System_Config_Source_Shipment_Status::BOOKED)
417
+ ->setAnticipatedCost($shipment->getSelectedQuotePermutation()->getTotalPrice())
418
+ ->save();
419
+
420
+ $magento_shipment = Mage::getModel('sales/convert_order')
421
+ ->toShipment($shipment->getOrder());
422
+ /* @var $magento_shipment Mage_Sales_Model_Order_Shipment */
423
+
424
+ $totalQty = 0;
425
+ foreach ($shipment->getOrder()->getAllItems() as $item) {
426
+ if ($item->getQtyToShip() && !$item->getIsVirtual()) {
427
+ $magento_shipment_item = Mage::getModel('sales/convert_order')
428
+ ->itemToShipmentItem($item);
429
+
430
+ $qty = $item->getQtyToShip();
431
+
432
+ $magento_shipment_item->setQty($qty);
433
+ $magento_shipment->addItem($magento_shipment_item);
434
+
435
+ $totalQty += $qty;
436
+ }
437
+ }
438
+
439
+ $magento_shipment->setTotalQty($totalQty);
440
+
441
+ $track = Mage::getModel('sales/order_shipment_track');
442
+ /* @var Mage_Sales_Model_Order_Shipment_Track */
443
+ $number = '';
444
+ if ($booking_result->consignmentNumber) {
445
+ $number .= 'Consignment Number: ' . $booking_result->consignmentNumber;
446
+ }
447
+
448
+ if ($booking_result->requestId) {
449
+ if ($number) {
450
+ $number .= "\n<br />";
451
+ }
452
+
453
+ $number .= 'Request Id: ' . $booking_result->requestId;
454
+ }
455
+
456
+ $track
457
+ ->setCarrierCode(Mage::getModel('temando/shipping_carrier_temando')->getCarrierCode())
458
+ ->setTitle($quote->getCarrier()->getCompanyName())
459
+ ->setNumber($number);
460
+
461
+ $magento_shipment
462
+ ->addTrack($track)
463
+ ->register();
464
+
465
+ try {
466
+ $magento_shipment->getOrder()->setIsInProcess(true)->setCustomerNoteNotify(true);
467
+ Mage::getModel('core/resource_transaction')
468
+ ->addObject($shipment)
469
+ ->addObject($magento_shipment)
470
+ ->addObject($magento_shipment->getOrder())
471
+ ->save();
472
+ $magento_shipment->sendEmail();
473
+ } catch (Mage_Core_Exception $e) {
474
+ $error = $e->getMessage();
475
+ }
476
+ }
477
+
478
+ return;
479
+ }
480
+
481
+ /**
482
+ * Serve shipping labels
483
+ */
484
+ public function consignmentAction() {
485
+ $shipment = Mage::getModel('temando/shipment')->load($this->getRequest()->getParam('id'));
486
+ /* @var $shipment Temando_Temando_Model_Shipment */
487
+
488
+ if ($shipment->getId()) {
489
+ $document = '';
490
+
491
+ $labelType = Mage::helper('temando')->getConfigData('options/label_type');
492
+ switch ($labelType) {
493
+ case Temando_Temando_Model_System_Config_Source_Labeltype::STANDARD:
494
+ if ($shipment->getConsignmentDocument())
495
+ $document = base64_decode($shipment->getConsignmentDocument());
496
+ break;
497
+ case Temando_Temando_Model_System_Config_Source_Labeltype::THERMAL:
498
+ if ($shipment->getLabelDocument())
499
+ $document = base64_decode($shipment->getLabelDocument());
500
+ break;
501
+ }
502
+
503
+ $document_length = strlen($document);
504
+
505
+ if ($document_length) {
506
+ $this->getResponse()
507
+ ->setHttpResponseCode(200)
508
+ ->setHeader('Pragma', 'public', true)
509
+ ->setHeader('Cache-Control', 'must-revalidate, post-check=0, pre-check=0', true)
510
+ ->setHeader('Content-type', $shipment->getConsignmentDocumentType(), true)
511
+ ->setHeader('Content-Length', $document_length)
512
+ ->setHeader('Content-Disposition', 'attachment; filename="order-' . $shipment->getOrderNumber() . '.pdf"')
513
+ ->setHeader('Last-Modified', date('r'));
514
+ $this->getResponse()->clearBody();
515
+ $this->getResponse()->sendHeaders();
516
+ print $document;
517
+ }
518
+ }
519
+ }
520
+
521
+ }
app/code/community/Temando/Temando/controllers/PcsController.php ADDED
@@ -0,0 +1,313 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Temando_Temando_PcsController extends Mage_Core_Controller_Front_Action
4
+ {
5
+ /**
6
+ * @var Temando_Temando_Model_Pcs
7
+ */
8
+ protected $_validator = null;
9
+
10
+ public function testAction()
11
+ {
12
+ $shippingMethod = 'temando_flat';
13
+ $selected_quote_id = preg_replace('#^[^_]*_#', '', $shippingMethod);
14
+
15
+ echo Mage::helper('temando')->isQuoteDynamic($selected_quote_id) ?
16
+ 'DYNAMIC' : 'FREE/FLAT';
17
+ }
18
+
19
+ private $_result = array (
20
+ 'query' => '',
21
+ 'suggestions' => array(),
22
+ 'data' => array(
23
+ 0 => array (
24
+ 0 => array(
25
+ 'city' => '',
26
+ 'region_id' => '',
27
+ 'postcode' => ''
28
+ )
29
+ )
30
+ )
31
+ );
32
+
33
+ public function construct() {
34
+ parent:: construct();
35
+
36
+ $this->loadLayout();
37
+ $this->renderLayout();
38
+ }
39
+
40
+ public function autocomplete($field) {
41
+
42
+ $query = $this->getRequest()->getParam('query');
43
+
44
+ $country = $this->getRequest()->getParam('country');
45
+
46
+ if (!$country || !array_key_exists($country, Mage::helper('temando')->getAllowedCountries())) {
47
+ return;
48
+ }
49
+
50
+ $stateId = $this->getRequest()->getParam('state_id');
51
+
52
+ $this->_result['query'] = $query;
53
+
54
+ $collection = Mage::getModel('temando/pcs')->getCollection();
55
+ $collection
56
+ ->addFieldToFilter('main_table.country_id', $country)
57
+ ->addFieldToFilter($field, array('like' => $query . ' %'));
58
+
59
+ if ($stateId) {
60
+ $collection->addFieldToFilter('main_table.region_id', $stateId);
61
+ }
62
+
63
+ $i = -1;
64
+ if (count($collection) > 0) {
65
+ $this->_result['data'] = array();
66
+ foreach ($collection as $item) {
67
+
68
+ $value = $item->getData($field);
69
+ if (!in_array($value, $this->_result['suggestions'])) {
70
+ $i++;
71
+ $this->_result['suggestions'][$i] = $value;
72
+ $this->_result['data'][$i][] = $item->getData();
73
+ } else {
74
+ $this->_result['data'][$i][] = $item->getData();
75
+ }
76
+ }
77
+ }
78
+
79
+
80
+ $core_helper = Mage::helper('core');
81
+ if (method_exists($core_helper, "jsonEncode")) {
82
+ return Mage::helper('core')->jsonEncode($this->_result);
83
+ } else {
84
+ return Zend_Json::encode($this->_result);
85
+ }
86
+
87
+ }
88
+
89
+ public function autocompletezipAction() {
90
+
91
+ echo $this->autocomplete('postcode'); die;
92
+
93
+ }
94
+
95
+ public function autocompletecityAction() {
96
+
97
+ echo $this->autocomplete('city'); die;
98
+
99
+ }
100
+
101
+ protected function _makeAutocomplete($query, $country = 'AU')
102
+ {
103
+ $this->_result['query'] = $query;
104
+
105
+ $this->_getValidator();
106
+ $this->_validator->setCountry($country)->setQuery($query);
107
+
108
+ $suggestions = $this->_validator->getSuggestions();
109
+
110
+ $i = -1;
111
+ if(!empty($suggestions)) {
112
+ //have results - load into result array
113
+ $this->_result['data'] = array();
114
+ foreach($suggestions as $item)
115
+ {
116
+ $fulltext = $item['name'] .', ';
117
+ $fulltext.= array_key_exists('postcodes', $item) && !empty($item['postcodes']) ? $item['postcodes'][0]['code'].' ' : ' ';
118
+ $fulltext.= $item['country']['iso_code2'];
119
+
120
+ if (!in_array($fulltext, $this->_result['suggestions'])) {
121
+ $i++; $this->_result['suggestions'][$i] = $fulltext;
122
+ }
123
+ $this->_result['data'][$i][] = array(
124
+ 'postcode' => array_key_exists('postcodes', $item) && !empty($item['postcodes']) ? $item['postcodes'][0]['code'] : '',
125
+ 'city' => $item['name'],
126
+ 'country_id'=> $item['country']['iso_code2'],
127
+ 'fulltext' => $fulltext
128
+ );
129
+ }
130
+ }
131
+ $core_helper = Mage::helper('core');
132
+ if (method_exists($core_helper, "jsonEncode")) {
133
+ $result = Mage::helper('core')->jsonEncode($this->_result);
134
+ } else {
135
+ $result = Zend_Json::encode($this->_result);
136
+ }
137
+
138
+ return $result;
139
+ }
140
+
141
+ public function autocompletecartAction() {
142
+
143
+ $query = $this->getRequest()->getParam('query');
144
+ $country = $this->getRequest()->getParam('country','AU');
145
+
146
+ echo $this->_makeAutocomplete($query, $country);
147
+ exit;
148
+ }
149
+
150
+ public function generateAction()
151
+ {
152
+ $array1 = array('0', '1', '2', '3', '4', '5', '6', '7', '8', '9');
153
+ $array2 = array('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j',
154
+ 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't',
155
+ 'u', 'v', 'w', 'x', 'y', 'z');
156
+
157
+ foreach ($array1 as $c) {
158
+ $this->_makeAutocomplete($c);
159
+ }
160
+
161
+ foreach ($array1 as $c1) {
162
+ foreach ($array1 as $c2) {
163
+ $this->_makeAutocomplete($c1 . $c2);
164
+ }
165
+ }
166
+
167
+ foreach ($array2 as $c) {
168
+ $this->_makeAutocomplete($c);
169
+ }
170
+
171
+ /*foreach ($array2 as $c1) {
172
+ foreach ($array2 as $c2) {
173
+ $this->_makeAutocomplete($c1 . $c2);
174
+ }
175
+ }*/
176
+
177
+ echo 'done'; exit;
178
+ }
179
+
180
+
181
+ public function productAction()
182
+ {
183
+ try {
184
+ $data = array(
185
+ 'country_id' => $this->getRequest()->getParam('country_id'),
186
+ 'city' => $this->getRequest()->getParam('city'),
187
+ 'postcode' => $this->getRequest()->getParam('postcode'),
188
+ );
189
+ Mage::getSingleton('customer/session')->setData('estimate_product_shipping', new Varien_Object($data));
190
+ $product_id = $this->getRequest()->getParam('product_id');
191
+ $product = Mage::getModel('catalog/product')->load($product_id);
192
+ $options = array();
193
+ foreach (explode(';', $this->getRequest()->getParam('options')) as $o) {
194
+ if (!$o) {
195
+ continue;
196
+ }
197
+
198
+ $_t = explode(':', $o);
199
+ if (isset($_t[1])) {
200
+ $options[$_t[0]] = $_t[1];
201
+ }
202
+ }
203
+ $quote = Mage::getModel('sales/quote');
204
+ $request = array('qty' => $this->getRequest()->getParam('qty'));
205
+ if (count($options)) {
206
+ $request['super_attribute'] = $options;
207
+ }
208
+
209
+ $options = array();
210
+ foreach (explode(';', $this->getRequest()->getParam('pr_options')) as $o) {
211
+ if (!$o) {
212
+ continue;
213
+ }
214
+
215
+ $_t = explode(':', $o);
216
+ if (isset($_t[1])) {
217
+ $options[$_t[0]] = $_t[1];
218
+ }
219
+ }
220
+
221
+ //get bundle products options
222
+ $bundle_options = array();
223
+ if($product->getTypeId() == Mage_Catalog_Model_Product_Type::TYPE_BUNDLE)
224
+ {
225
+ foreach (explode(';', $this->getRequest()->getParam('bl_options')) as $o) {
226
+ if (!$o) {
227
+ continue;
228
+ }
229
+
230
+ $_t = explode(':', $o);
231
+ if (isset($_t[1])) {
232
+ $bundle_options[$_t[0]] = $_t[1];
233
+ }
234
+ }
235
+ if(empty($bundle_options)) { //assign default values
236
+ $selectionCollection = $product->getTypeInstance(true)->getSelectionsCollection(
237
+ $product->getTypeInstance(true)->getOptionsIds($product), $product
238
+ );
239
+
240
+ foreach($selectionCollection as $option) {
241
+ if($option->getIsDefault() == true) {
242
+ $bundle_options[$option->getOptionId()] = $option->getSelectionId();
243
+ }
244
+ }
245
+ }
246
+ }
247
+
248
+ if (count($options)) {
249
+ $request['options'] = $options;
250
+ }
251
+
252
+ if(count($bundle_options)) {
253
+ $request['bundle_option'] = $bundle_options;
254
+ }
255
+
256
+ $item = $quote->addProduct($product, new Varien_Object($request));
257
+ if (!is_object($item)) {
258
+ throw new Exception('Cannot calculate shipping cost for separate item');
259
+ }
260
+ $item->setStoreId(Mage::app()->getStore()->getId());
261
+ $item->setQty($this->getRequest()->getParam('qty'));
262
+ $item->setPrice($product->getFinalPrice());
263
+ $request = Mage::getModel('shipping/rate_request');
264
+ foreach ($quote->getAllItems() as $i) {
265
+ if (!$i->getPrice()) {
266
+ $i->setPrice($product->getFinalPrice());
267
+ }
268
+ }
269
+
270
+ $request->setAllItems($quote->getAllItems());
271
+ $request->setDestCountryId($this->getRequest()->getParam('country_id'));
272
+ $request->setDestStreet('');
273
+ $request->setDestCity($this->getRequest()->getParam('city'));
274
+ $request->setDestPostcode($this->getRequest()->getParam('postcode'));
275
+ $request->setPackageValue($item->getTotal());
276
+ $request->setPackageValueWithDiscount($item->getTotal());
277
+ $request->setPackageWeight($this->getRequest()->getParam('qty')*$product->getWeight());
278
+ $request->setPackageQty($this->getRequest()->getParam('qty'));
279
+
280
+ /**
281
+ * Need for shipping methods that use insurance based on price of physical products
282
+ */
283
+ $request->setPackagePhysicalValue($item->getTotal());
284
+
285
+ $request->setFreeMethodWeight($item);
286
+ $request->setStoreId(Mage::app()->getStore()->getId());
287
+ $request->setWebsiteId(Mage::app()->getStore()->getWebsiteId());
288
+ $request->setFreeShipping(null);
289
+ /**
290
+ * Currencies need to convert in free shipping
291
+ */
292
+ $request->setBaseCurrency(Mage::app()->getStore()->getBaseCurrency());
293
+ $request->setPackageCurrency(Mage::app()->getStore()->getCurrentCurrency());
294
+ $request->setLimitCarrier(null);
295
+ $request->setOrig(false);
296
+ $result = Mage::getModel('shipping/shipping')->collectCarrierRates('temando', $request)->getResult();
297
+ Mage::register('product_rates', array('temando' => $result));
298
+ $this->loadLayout();
299
+ $this->renderLayout();
300
+ } catch (Exception $e) {
301
+ die($e->getMessage());
302
+ }
303
+ }
304
+
305
+ protected function _getValidator()
306
+ {
307
+ if(!$this->_validator) {
308
+ $this->_validator = Mage::getModel('temando/pcs');
309
+ }
310
+ return $this;
311
+ }
312
+
313
+ }
app/code/community/Temando/Temando/etc/adminhtml.xml ADDED
@@ -0,0 +1,82 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <config>
3
+ <menu>
4
+ <temando translate="title" module="temando">
5
+ <title>Temando</title>
6
+ <sort_order>71</sort_order>
7
+ <children>
8
+ <shipment translate="title" module="temando">
9
+ <title>Manage Shipments</title>
10
+ <sort_order>10</sort_order>
11
+ <action>temando/adminhtml_shipment</action>
12
+ </shipment>
13
+ <manifest translate="title" module="temando">
14
+ <title>Manage Manifests</title>
15
+ <sort_order>20</sort_order>
16
+ <action>temando/adminhtml_manifest</action>
17
+ </manifest>
18
+ <configuration translate="title" module="temando">
19
+ <title>Configuration Settings</title>
20
+ <sort_order>30</sort_order>
21
+ <children>
22
+ <temando_settings translate="title" module="temando">
23
+ <title>Temando Settings</title>
24
+ <sort_order>10</sort_order>
25
+ <action>adminhtml/system_config/edit/section/temando</action>
26
+ </temando_settings>
27
+ <shipping_methods>
28
+ <title>Shipping Methods</title>
29
+ <sort_order>20</sort_order>
30
+ <action>adminhtml/system_config/edit/section/carriers</action>
31
+ </shipping_methods>
32
+ </children>
33
+ </configuration>
34
+ </children>
35
+ </temando>
36
+ </menu>
37
+ <acl>
38
+ <resources>
39
+ <all>
40
+ <title>Allow Everything</title>
41
+ </all>
42
+ <admin>
43
+ <children>
44
+ <temando>
45
+ <title>Temando</title>
46
+ <sort_order>10</sort_order>
47
+ <children>
48
+ <shipment>
49
+ <title>Manage Shipments</title>
50
+ </shipment>
51
+ <manifest>
52
+ <title>Manage Manifests</title>
53
+ </manifest>
54
+ <configuration>
55
+ <title>Configuration Settings</title>
56
+ <children>
57
+ <temando_settings>
58
+ <title>Temando Settings</title>
59
+ </temando_settings>
60
+ <shipping_methods>
61
+ <title>Shipping Methods</title>
62
+ </shipping_methods>
63
+ </children>
64
+ </configuration>
65
+ </children>
66
+ </temando>
67
+ <system>
68
+ <children>
69
+ <config>
70
+ <children>
71
+ <temando>
72
+ <title>Temando Settings</title>
73
+ </temando>
74
+ </children>
75
+ </config>
76
+ </children>
77
+ </system>
78
+ </children>
79
+ </admin>
80
+ </resources>
81
+ </acl>
82
+ </config>
app/code/community/Temando/Temando/etc/config.xml ADDED
@@ -0,0 +1,194 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <config>
3
+ <modules>
4
+ <Temando_Temando>
5
+ <version>1.0.0</version>
6
+ </Temando_Temando>
7
+ </modules>
8
+ <global>
9
+ <models>
10
+ <temando>
11
+ <class>Temando_Temando_Model</class>
12
+ <resourceModel>temando_mysql4</resourceModel>
13
+ </temando>
14
+ <temando_mysql4>
15
+ <class>Temando_Temando_Model_Mysql4</class>
16
+ <entities>
17
+ <box><table>temando_box</table></box>
18
+ <quote><table>temando_quote</table></quote>
19
+ <shipment><table>temando_shipment</table></shipment>
20
+ <manifest><table>temando_manifest</table></manifest>
21
+ <carrier><table>temando_carrier</table></carrier>
22
+ </entities>
23
+ </temando_mysql4>
24
+ </models>
25
+ <blocks>
26
+ <temando>
27
+ <class>Temando_Temando_Block</class>
28
+ </temando>
29
+ <checkout>
30
+ <rewrite>
31
+ <cart_shipping>Temando_Temando_Block_Cart_Shipping</cart_shipping>
32
+ </rewrite>
33
+ </checkout>
34
+ </blocks>
35
+ <helpers>
36
+ <temando>
37
+ <class>Temando_Temando_Helper</class>
38
+ </temando>
39
+ </helpers>
40
+ <resources>
41
+ <temando_setup>
42
+ <setup>
43
+ <module>Temando_Temando</module>
44
+ <class>Mage_Eav_Model_Entity_Setup</class>
45
+ </setup>
46
+ <connection>
47
+ <use>core_setup</use>
48
+ </connection>
49
+ </temando_setup>
50
+ <temando_write>
51
+ <connection>
52
+ <use>core_write</use>
53
+ </connection>
54
+ </temando_write>
55
+ <temando_read>
56
+ <connection>
57
+ <use>core_read</use>
58
+ </connection>
59
+ </temando_read>
60
+ </resources>
61
+ <sales>
62
+ <shipping>
63
+ <carriers>
64
+ <temando>
65
+ <class>Temando_Temando_Model_Shipping_Carrier_Temando</class>
66
+ </temando>
67
+ </carriers>
68
+ </shipping>
69
+ </sales>
70
+ <events>
71
+ <sales_order_place_after>
72
+ <observers>
73
+ <temando_sales_order_place_after_handler>
74
+ <type>model</type>
75
+ <class>Temando_Temando_Model_Observer</class>
76
+ <method>createTemandoShipment</method>
77
+ <args></args>
78
+ </temando_sales_order_place_after_handler>
79
+ </observers>
80
+ </sales_order_place_after>
81
+ <controller_action_predispatch_checkout_cart_estimatePost>
82
+ <observers>
83
+ <retail_product_view>
84
+ <type>singleton</type>
85
+ <class>Temando_Temando_Model_Observer</class>
86
+ <method>hookCartSaveAddress</method>
87
+ </retail_product_view>
88
+ </observers>
89
+ </controller_action_predispatch_checkout_cart_estimatePost>
90
+ </events>
91
+ </global>
92
+ <frontend>
93
+ <routers>
94
+ <etemando>
95
+ <use>standard</use>
96
+ <args>
97
+ <module>Temando_Temando</module>
98
+ <frontName>etemando</frontName>
99
+ </args>
100
+ </etemando>
101
+ </routers>
102
+ <layout>
103
+ <updates>
104
+ <temando>
105
+ <file>temando.xml</file>
106
+ </temando>
107
+ </updates>
108
+ </layout>
109
+ </frontend>
110
+ <admin>
111
+ <routers>
112
+ <temando>
113
+ <use>admin</use>
114
+ <args>
115
+ <module>Temando_Temando</module>
116
+ <frontName>temando</frontName>
117
+ </args>
118
+ </temando>
119
+ </routers>
120
+ </admin>
121
+ <adminhtml>
122
+ <layout>
123
+ <updates>
124
+ <temando>
125
+ <file>temando.xml</file>
126
+ </temando>
127
+ </updates>
128
+ </layout>
129
+ </adminhtml>
130
+ <default>
131
+ <temando>
132
+ <general>
133
+ <active><![CDATA[0]]></active>
134
+ <sandbox><![CDATA[1]]></sandbox>
135
+ <client><![CDATA[42571]]></client>
136
+ <username><![CDATA[TEMANDOTEST]]></username>
137
+ <password><![CDATA[password]]></password>
138
+ <title><![CDATA[Temando]]></title>
139
+ <payment_type><![CDATA[Account]]></payment_type>
140
+ </general>
141
+ <options>
142
+ <show_transit_type><![CDATA[1]]></show_transit_type>
143
+ <show_transit_time><![CDATA[1]]></show_transit_time>
144
+ </options>
145
+ <insurance>
146
+ <status><![CDATA[optional]]></status>
147
+ </insurance>
148
+ <carbon>
149
+ <status><![CDATA[optional]]></status>
150
+ </carbon>
151
+ <footprints>
152
+ <status><![CDATA[optional]]></status>
153
+ </footprints>
154
+ <pricing>
155
+ <method><![CDATA[dynamic]]></method>
156
+ <shipping_fee><![CDATA[0]]></shipping_fee>
157
+ <handling_fee><![CDATA[0]]></handling_fee>
158
+ <handling_type><![CDATA[F]]></handling_type>
159
+ </pricing>
160
+ <units>
161
+ <measure><![CDATA[Centimetres]]></measure>
162
+ <weight><![CDATA[Kilograms]]></weight>
163
+ </units>
164
+ <defaults>
165
+ <class><![CDATA[General Goods]]></class>
166
+ <subclass><![CDATA[Household Goods]]></subclass>
167
+ <packaging><![CDATA[0]]></packaging>
168
+ <fragile><![CDATA[0]]></fragile>
169
+ <length><![CDATA[10]]></length>
170
+ <width><![CDATA[10]]></width>
171
+ <height><![CDATA[10]]></height>
172
+ </defaults>
173
+ <origin>
174
+ <country><![CDATA[AU]]></country>
175
+ </origin>
176
+ </temando>
177
+ <carriers>
178
+ <temando>
179
+ <active>0</active>
180
+ <model>temando/shipping_carrier_temando</model>
181
+ <allowed_methods></allowed_methods>
182
+ <weightunit>Grams</weightunit>
183
+ <name>Temando</name>
184
+ <title>Temando</title>
185
+ <always_use_defaults>0</always_use_defaults>
186
+ <specificerrmsg>This shipping method is currently unavailable. If you would like to ship using this shipping method, please contact us.</specificerrmsg>
187
+ <sallowspecific>1</sallowspecific>
188
+ <specificcountry>AU</specificcountry>
189
+ <showmethod></showmethod>
190
+ <sort_order>0</sort_order>
191
+ </temando>
192
+ </carriers>
193
+ </default>
194
+ </config>
app/code/community/Temando/Temando/etc/system.xml ADDED
@@ -0,0 +1,633 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <config>
3
+ <sections>
4
+ <temando>
5
+ <label>Temando Settings</label>
6
+ <tab>sales</tab>
7
+ <frontend_type>text</frontend_type>
8
+ <sort_order>321</sort_order>
9
+ <show_in_default>1</show_in_default>
10
+ <show_in_website>1</show_in_website>
11
+ <show_in_store>1</show_in_store>
12
+ <groups>
13
+ <general translate="label">
14
+ <label>General</label>
15
+ <frontend_model>temando/adminhtml_system_config_form_fieldset_general</frontend_model>
16
+ <sort_order>10</sort_order>
17
+ <show_in_default>1</show_in_default>
18
+ <show_in_website>1</show_in_website>
19
+ <show_in_store>1</show_in_store>
20
+ <comment>
21
+ <![CDATA[
22
+ <div style="padding:10px;background-color:#fff;border:1px solid #ddd;margin-bottom:7px;">
23
+ If you don't have a Temando account, you can <a href="https://www.temando.com/register/" target="_blank">Sign Up</a> immediately.
24
+ </div>
25
+ ]]>
26
+ </comment>
27
+ <fields>
28
+ <sandbox translate="label">
29
+ <label>Sandbox</label>
30
+ <frontend_type>select</frontend_type>
31
+ <sort_order>20</sort_order>
32
+ <source_model>adminhtml/system_config_source_yesno</source_model>
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
+ <comment><![CDATA[If set to "Yes", the sandbox (testing) service will be used (usually set to "No" on a live site)]]></comment>
37
+ </sandbox>
38
+ <client>
39
+ <label>Client ID</label>
40
+ <frontend_type>text</frontend_type>
41
+ <sort_order>30</sort_order>
42
+ <frontend_model>temando/adminhtml_system_config_form_field_required</frontend_model>
43
+ <backend_model>temando/system_config_backend_form_field_required_text</backend_model>
44
+ <show_in_default>1</show_in_default>
45
+ <show_in_website>1</show_in_website>
46
+ <show_in_store>1</show_in_store>
47
+ </client>
48
+ <username translate="label">
49
+ <label>Login ID</label>
50
+ <frontend_type>text</frontend_type>
51
+ <frontend_model>temando/adminhtml_system_config_form_field_required</frontend_model>
52
+ <backend_model>temando/system_config_backend_form_field_required_text</backend_model>
53
+ <sort_order>40</sort_order>
54
+ <show_in_default>1</show_in_default>
55
+ <show_in_website>1</show_in_website>
56
+ <show_in_store>1</show_in_store>
57
+ </username>
58
+ <password translate="label">
59
+ <label>Password</label>
60
+ <frontend_type>password</frontend_type>
61
+ <frontend_model>temando/adminhtml_system_config_form_field_required</frontend_model>
62
+ <backend_model>temando/system_config_backend_form_field_required_text</backend_model>
63
+ <sort_order>50</sort_order>
64
+ <show_in_default>1</show_in_default>
65
+ <show_in_website>1</show_in_website>
66
+ <show_in_store>1</show_in_store>
67
+ </password>
68
+ <payment_type translate="label">
69
+ <label>Payment Type</label>
70
+ <frontend_type>select</frontend_type>
71
+ <source_model>temando/system_config_source_payment</source_model>
72
+ <sort_order>60</sort_order>
73
+ <show_in_default>1</show_in_default>
74
+ <show_in_website>1</show_in_website>
75
+ <show_in_store>1</show_in_store>
76
+ <comment><![CDATA[If choosing "credit", please ensure you have sufficient credit in your Temando account]]></comment>
77
+ </payment_type>
78
+ </fields>
79
+ </general>
80
+ <options translate="label">
81
+ <label>Options</label>
82
+ <frontend_type>text</frontend_type>
83
+ <sort_order>20</sort_order>
84
+ <show_in_default>1</show_in_default>
85
+ <show_in_website>1</show_in_website>
86
+ <show_in_store>1</show_in_store>
87
+ <fields>
88
+ <show_product_estimate translate="label">
89
+ <label>Show Estimate Shipping on Product Page</label>
90
+ <frontend_type>select</frontend_type>
91
+ <sort_order>10</sort_order>
92
+ <source_model>adminhtml/system_config_source_yesno</source_model>
93
+ <show_in_default>1</show_in_default>
94
+ <show_in_website>1</show_in_website>
95
+ <show_in_store>1</show_in_store>
96
+ <comment><![CDATA[Set to yes to enable a shipping estimation widget on the product page.]]></comment>
97
+ </show_product_estimate>
98
+ <label_type translate="label">
99
+ <label>Shipping Label Type</label>
100
+ <frontend_type>select</frontend_type>
101
+ <source_model>temando/system_config_source_labeltype</source_model>
102
+ <sort_order>20</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
+ </label_type>
107
+ <show_transit_type translate="label">
108
+ <label>Show Transit Type</label>
109
+ <frontend_type>select</frontend_type>
110
+ <sort_order>30</sort_order>
111
+ <source_model>adminhtml/system_config_source_yesno</source_model>
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
+ </show_transit_type>
116
+ <show_transit_time translate="label">
117
+ <label>Show Transit Time</label>
118
+ <frontend_type>select</frontend_type>
119
+ <sort_order>40</sort_order>
120
+ <source_model>adminhtml/system_config_source_yesno</source_model>
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
+ </show_transit_time>
125
+ </fields>
126
+ </options>
127
+ <insurance translate="label">
128
+ <label>Insurance</label>
129
+ <frontend_type>text</frontend_type>
130
+ <sort_order>30</sort_order>
131
+ <show_in_default>1</show_in_default>
132
+ <show_in_website>1</show_in_website>
133
+ <show_in_store>1</show_in_store>
134
+ <fields>
135
+ <status translate="label">
136
+ <label>Insurance</label>
137
+ <frontend_type>select</frontend_type>
138
+ <frontend_model>temando/adminhtml_system_config_form_field_insurance</frontend_model>
139
+ <sort_order>10</sort_order>
140
+ <source_model>temando/system_config_source_insurance</source_model>
141
+ <show_in_default>1</show_in_default>
142
+ <show_in_website>1</show_in_website>
143
+ <show_in_store>1</show_in_store>
144
+ <comment>
145
+ <![CDATA[
146
+ Disabled - This option is unavailable to users.<br/>
147
+ Optional - The option is presented during checkout.<br/>
148
+ Mandatory - Insurance must be added to all orders.
149
+ ]]>
150
+ </comment>
151
+ </status>
152
+ </fields>
153
+ </insurance>
154
+ <carbon translate="label">
155
+ <label>Carbon Offset</label>
156
+ <frontend_type>text</frontend_type>
157
+ <sort_order>40</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
+ <fields>
162
+ <status translate="label">
163
+ <label>Carbon Offset</label>
164
+ <frontend_type>select</frontend_type>
165
+ <sort_order>10</sort_order>
166
+ <source_model>temando/system_config_source_carbon</source_model>
167
+ <show_in_default>1</show_in_default>
168
+ <show_in_website>1</show_in_website>
169
+ <show_in_store>1</show_in_store>
170
+ <comment>
171
+ <![CDATA[
172
+ Disabled - This option is unavailable to users.<br/>
173
+ Optional - The option is presented during checkout.<br/>
174
+ Mandatory - Carbon offsets are added to all orders.
175
+ ]]>
176
+ </comment>
177
+ </status>
178
+ </fields>
179
+ </carbon>
180
+ <footprints translate="label">
181
+ <label>Footprints</label>
182
+ <frontend_type>text</frontend_type>
183
+ <sort_order>50</sort_order>
184
+ <show_in_default>1</show_in_default>
185
+ <show_in_website>1</show_in_website>
186
+ <show_in_store>1</show_in_store>
187
+ <fields>
188
+ <status translate="label">
189
+ <label>Footprints</label>
190
+ <frontend_type>select</frontend_type>
191
+ <sort_order>10</sort_order>
192
+ <source_model>temando/system_config_source_footprints</source_model>
193
+ <show_in_default>1</show_in_default>
194
+ <show_in_website>1</show_in_website>
195
+ <show_in_store>1</show_in_store>
196
+ <comment>
197
+ <![CDATA[
198
+ Disabled - This option is unavailable to users.<br/>
199
+ Optional - The option is presented during checkout.<br/>
200
+ Mandatory - Footprints charges are added to all orders.
201
+ ]]>
202
+ </comment>
203
+ </status>
204
+ </fields>
205
+ </footprints>
206
+ <pricing translate="label">
207
+ <label>Pricing</label>
208
+ <frontend_type>text</frontend_type>
209
+ <sort_order>60</sort_order>
210
+ <show_in_default>1</show_in_default>
211
+ <show_in_website>1</show_in_website>
212
+ <show_in_store>1</show_in_store>
213
+ <fields>
214
+ <error_process translate="label">
215
+ <label>Error from Temando processing</label>
216
+ <frontend_type>select</frontend_type>
217
+ <source_model>temando/system_config_source_errorprocess</source_model>
218
+ <sort_order>5</sort_order>
219
+ <show_in_default>1</show_in_default>
220
+ <show_in_website>1</show_in_website>
221
+ <show_in_store>1</show_in_store>
222
+ <comment>
223
+ <![CDATA[
224
+ Show error message to customer from Temando or show flat rate shipping method.
225
+ ]]>
226
+ </comment>
227
+ </error_process>
228
+ <method translate="label">
229
+ <label>Pricing Method</label>
230
+ <frontend_type>select</frontend_type>
231
+ <source_model>temando/system_config_source_pricing</source_model>
232
+ <sort_order>10</sort_order>
233
+ <show_in_default>1</show_in_default>
234
+ <show_in_website>1</show_in_website>
235
+ <show_in_store>1</show_in_store>
236
+ <comment>
237
+ <![CDATA[
238
+ <strong>Free Shipping</strong> - no charge to customer.<br/>
239
+ <strong>Fixed Price / Flat Rate</strong> - customer always pays the amount set in "Shipping Price" below.<br/>
240
+ <strong>Dynamic Pricing</strong><br/>
241
+ - <strong>All</strong>: All quotes from carriers in "allowed carriers" above are shown for the customer to choose from.<br/>
242
+ - <strong>Cheapest</strong>: Only the cheapest quote is shown.<br/>
243
+ - <strong>Fastest</strong>: Only the fastest quote is shown.<br/>
244
+ - <strong>Cheapest and Fastest</strong>: The customer can choose between the cheapest or the fastest quote.
245
+ ]]>
246
+ </comment>
247
+ </method>
248
+ <shipping_fee translate="label">
249
+ <label>Shipping Price</label>
250
+ <frontend_type>text</frontend_type>
251
+ <sort_order>20</sort_order>
252
+ <show_in_default>1</show_in_default>
253
+ <show_in_website>1</show_in_website>
254
+ <show_in_store>1</show_in_store>
255
+ </shipping_fee>
256
+ <handling_fee translate="label">
257
+ <label>Handling Fee / Markup</label>
258
+ <frontend_type>text</frontend_type>
259
+ <sort_order>30</sort_order>
260
+ <show_in_default>1</show_in_default>
261
+ <show_in_website>1</show_in_website>
262
+ <show_in_store>1</show_in_store>
263
+ </handling_fee>
264
+ <handling_type translate="label">
265
+ <label>Handling Fee Calculation</label>
266
+ <frontend_type>select</frontend_type>
267
+ <source_model>shipping/source_handlingType</source_model>
268
+ <sort_order>40</sort_order>
269
+ <show_in_default>1</show_in_default>
270
+ <show_in_website>1</show_in_website>
271
+ <show_in_store>0</show_in_store>
272
+ </handling_type>
273
+ </fields>
274
+ </pricing>
275
+ <units translate="label">
276
+ <label>Units</label>
277
+ <frontend_type>text</frontend_type>
278
+ <sort_order>60</sort_order>
279
+ <show_in_default>1</show_in_default>
280
+ <show_in_website>1</show_in_website>
281
+ <show_in_store>1</show_in_store>
282
+ <fields>
283
+ <measure translate="label">
284
+ <label>Measure Unit</label>
285
+ <frontend_type>select</frontend_type>
286
+ <source_model>temando/system_config_source_unit_measure</source_model>
287
+ <sort_order>10</sort_order>
288
+ <show_in_default>1</show_in_default>
289
+ <show_in_website>1</show_in_website>
290
+ <show_in_store>1</show_in_store>
291
+ <comment><![CDATA[The units used for product measurements]]></comment>
292
+ </measure>
293
+ <weight translate="label">
294
+ <label>Weight Unit</label>
295
+ <frontend_type>select</frontend_type>
296
+ <source_model>temando/system_config_source_unit_weight</source_model>
297
+ <sort_order>20</sort_order>
298
+ <show_in_default>1</show_in_default>
299
+ <show_in_website>1</show_in_website>
300
+ <show_in_store>1</show_in_store>
301
+ <comment><![CDATA[The units used for product weights]]></comment>
302
+ </weight>
303
+ </fields>
304
+ </units>
305
+ <defaults translate="label">
306
+ <label>Packaging</label>
307
+ <frontend_type>text</frontend_type>
308
+ <sort_order>70</sort_order>
309
+ <show_in_default>1</show_in_default>
310
+ <show_in_website>1</show_in_website>
311
+ <show_in_store>1</show_in_store>
312
+ <comment><![CDATA[Default values will be used for all products that do not have product specific dimensions & packaging information configured.]]></comment>
313
+ <fields>
314
+ <packaging translate="label">
315
+ <label>Packaging</label>
316
+ <frontend_type>select</frontend_type>
317
+ <frontend_model>temando/adminhtml_system_config_form_field_required</frontend_model>
318
+ <source_model>temando/system_config_source_shipment_packaging</source_model>
319
+ <sort_order>10</sort_order>
320
+ <show_in_default>1</show_in_default>
321
+ <show_in_website>1</show_in_website>
322
+ <show_in_store>1</show_in_store>
323
+ </packaging>
324
+ <fragile translate="label">
325
+ <label>Fragile</label>
326
+ <frontend_type>select</frontend_type>
327
+ <frontend_model>temando/adminhtml_system_config_form_field_required</frontend_model>
328
+ <source_model>adminhtml/system_config_source_yesno</source_model>
329
+ <sort_order>20</sort_order>
330
+ <show_in_default>1</show_in_default>
331
+ <show_in_website>1</show_in_website>
332
+ <show_in_store>1</show_in_store>
333
+ </fragile>
334
+ <length translate="label">
335
+ <label>Length</label>
336
+ <frontend_model>temando/adminhtml_system_config_form_field_required</frontend_model>
337
+ <frontend_type>text</frontend_type>
338
+ <sort_order>30</sort_order>
339
+ <show_in_default>1</show_in_default>
340
+ <show_in_website>1</show_in_website>
341
+ <show_in_store>1</show_in_store>
342
+ </length>
343
+ <width translate="label">
344
+ <label>Width</label>
345
+ <frontend_model>temando/adminhtml_system_config_form_field_required</frontend_model>
346
+ <frontend_type>text</frontend_type>
347
+ <sort_order>40</sort_order>
348
+ <show_in_default>1</show_in_default>
349
+ <show_in_website>1</show_in_website>
350
+ <show_in_store>1</show_in_store>
351
+ </width>
352
+ <height translate="label">
353
+ <label>Height</label>
354
+ <frontend_model>temando/adminhtml_system_config_form_field_required</frontend_model>
355
+ <frontend_type>text</frontend_type>
356
+ <sort_order>50</sort_order>
357
+ <show_in_default>1</show_in_default>
358
+ <show_in_website>1</show_in_website>
359
+ <show_in_store>1</show_in_store>
360
+ <comment><![CDATA[If unknown use 10x10x10]]></comment>
361
+ </height>
362
+ </fields>
363
+ </defaults>
364
+ <origin translate="label">
365
+ <label>Stock origin (warehouse) details</label>
366
+ <frontend_type>text</frontend_type>
367
+ <sort_order>80</sort_order>
368
+ <show_in_default>1</show_in_default>
369
+ <show_in_website>0</show_in_website>
370
+ <show_in_store>0</show_in_store>
371
+ <comment><![CDATA[Please enter the details of your pick-up location for all products.]]></comment>
372
+ <fields>
373
+ <contact_name translate="label">
374
+ <label>Contact Name</label>
375
+ <frontend_type>text</frontend_type>
376
+ <frontend_model>temando/adminhtml_system_config_form_field_required</frontend_model>
377
+ <backend_model>temando/system_config_backend_form_field_required_text</backend_model>
378
+ <sort_order>10</sort_order>
379
+ <show_in_default>1</show_in_default>
380
+ <show_in_website>0</show_in_website>
381
+ <show_in_store>0</show_in_store>
382
+ </contact_name>
383
+ <company_name translate="label">
384
+ <label>Company Name</label>
385
+ <frontend_type>text</frontend_type>
386
+ <sort_order>20</sort_order>
387
+ <show_in_default>1</show_in_default>
388
+ <show_in_website>0</show_in_website>
389
+ <show_in_store>0</show_in_store>
390
+ </company_name>
391
+ <street translate="label">
392
+ <label>Street</label>
393
+ <frontend_type>text</frontend_type>
394
+ <frontend_model>temando/adminhtml_system_config_form_field_required</frontend_model>
395
+ <backend_model>temando/system_config_backend_form_field_required_text</backend_model>
396
+ <sort_order>30</sort_order>
397
+ <show_in_default>1</show_in_default>
398
+ <show_in_website>0</show_in_website>
399
+ <show_in_store>0</show_in_store>
400
+ </street>
401
+ <city translate="label">
402
+ <label>City</label>
403
+ <frontend_type>text</frontend_type>
404
+ <frontend_model>temando/adminhtml_system_config_form_field_required</frontend_model>
405
+ <backend_model>temando/system_config_backend_form_field_required_text</backend_model>
406
+ <sort_order>40</sort_order>
407
+ <show_in_default>1</show_in_default>
408
+ <show_in_website>0</show_in_website>
409
+ <show_in_store>0</show_in_store>
410
+ </city>
411
+ <postcode translate="label">
412
+ <label>Postcode</label>
413
+ <frontend_type>text</frontend_type>
414
+ <frontend_model>temando/adminhtml_system_config_form_field_required</frontend_model>
415
+ <backend_model>temando/system_config_backend_form_field_required_text</backend_model>
416
+ <sort_order>50</sort_order>
417
+ <show_in_default>1</show_in_default>
418
+ <show_in_website>1</show_in_website>
419
+ <show_in_store>0</show_in_store>
420
+ </postcode>
421
+ <country translate="label">
422
+ <label>Country</label>
423
+ <frontend_type>select</frontend_type>
424
+ <frontend_model>temando/adminhtml_system_config_form_field_required</frontend_model>
425
+ <frontend_class>temando-countries</frontend_class>
426
+ <source_model>adminhtml/system_config_source_country</source_model>
427
+ <sort_order>60</sort_order>
428
+ <show_in_default>1</show_in_default>
429
+ <show_in_website>0</show_in_website>
430
+ <show_in_store>0</show_in_store>
431
+ </country>
432
+ <region translate="label">
433
+ <label>Region/State</label>
434
+ <frontend_type>text</frontend_type>
435
+ <frontend_model>temando/adminhtml_system_config_form_field_required</frontend_model>
436
+ <sort_order>70</sort_order>
437
+ <show_in_default>1</show_in_default>
438
+ <show_in_website>0</show_in_website>
439
+ <show_in_store>0</show_in_store>
440
+ </region>
441
+ <type translate="label">
442
+ <label>Type</label>
443
+ <frontend_type>select</frontend_type>
444
+ <frontend_model>temando/adminhtml_system_config_form_field_required</frontend_model>
445
+ <backend_model>temando/system_config_backend_form_field_required_businessresidential</backend_model>
446
+ <source_model>temando/system_config_source_origin_type</source_model>
447
+ <sort_order>80</sort_order>
448
+ <show_in_default>1</show_in_default>
449
+ <show_in_website>0</show_in_website>
450
+ <show_in_store>0</show_in_store>
451
+ </type>
452
+ <phone1 translate="label">
453
+ <label>Phone 1</label>
454
+ <frontend_type>text</frontend_type>
455
+ <frontend_model>temando/adminhtml_system_config_form_field_required</frontend_model>
456
+ <backend_model>temando/system_config_backend_form_field_required_text</backend_model>
457
+ <sort_order>90</sort_order>
458
+ <show_in_default>1</show_in_default>
459
+ <show_in_website>0</show_in_website>
460
+ <show_in_store>0</show_in_store>
461
+ </phone1>
462
+ <phone2 translate="label">
463
+ <label>Phone 2</label>
464
+ <frontend_type>text</frontend_type>
465
+ <sort_order>100</sort_order>
466
+ <show_in_default>1</show_in_default>
467
+ <show_in_website>0</show_in_website>
468
+ <show_in_store>0</show_in_store>
469
+ </phone2>
470
+ <fax translate="label">
471
+ <label>Fax</label>
472
+ <frontend_type>text</frontend_type>
473
+ <sort_order>110</sort_order>
474
+ <show_in_default>1</show_in_default>
475
+ <show_in_website>0</show_in_website>
476
+ <show_in_store>0</show_in_store>
477
+ </fax>
478
+ <email translate="label">
479
+ <label>Email</label>
480
+ <frontend_type>text</frontend_type>
481
+ <frontend_model>temando/adminhtml_system_config_form_field_required</frontend_model>
482
+ <backend_model>temando/system_config_backend_form_field_required_location</backend_model>
483
+ <sort_order>120</sort_order>
484
+ <show_in_default>1</show_in_default>
485
+ <show_in_website>0</show_in_website>
486
+ <show_in_store>0</show_in_store>
487
+ </email>
488
+ <loading_facilities translate="label">
489
+ <label>Loading Facilities</label>
490
+ <frontend_type>select</frontend_type>
491
+ <source_model>adminhtml/system_config_source_yesno</source_model>
492
+ <sort_order>130</sort_order>
493
+ <show_in_default>1</show_in_default>
494
+ <show_in_website>0</show_in_website>
495
+ <show_in_store>0</show_in_store>
496
+ <comment><![CDATA[Does the warehouse have loading facilities?]]></comment>
497
+ </loading_facilities>
498
+ <forklift translate="label">
499
+ <label>Forklift</label>
500
+ <frontend_type>select</frontend_type>
501
+ <source_model>adminhtml/system_config_source_yesno</source_model>
502
+ <sort_order>140</sort_order>
503
+ <show_in_default>1</show_in_default>
504
+ <show_in_website>0</show_in_website>
505
+ <show_in_store>0</show_in_store>
506
+ <comment><![CDATA[Does the warehouse have a forklift?]]></comment>
507
+ </forklift>
508
+ <dock translate="label">
509
+ <label>Dock</label>
510
+ <frontend_type>select</frontend_type>
511
+ <source_model>adminhtml/system_config_source_yesno</source_model>
512
+ <sort_order>150</sort_order>
513
+ <show_in_default>1</show_in_default>
514
+ <show_in_website>0</show_in_website>
515
+ <show_in_store>0</show_in_store>
516
+ <comment><![CDATA[Does the warehouse have a dock?]]></comment>
517
+ </dock>
518
+ <limited_access translate="label">
519
+ <label>Limited Access</label>
520
+ <frontend_type>select</frontend_type>
521
+ <source_model>adminhtml/system_config_source_yesno</source_model>
522
+ <sort_order>160</sort_order>
523
+ <show_in_default>1</show_in_default>
524
+ <show_in_website>0</show_in_website>
525
+ <show_in_store>0</show_in_store>
526
+ <comment><![CDATA[Does the warehouse have limited access?]]></comment>
527
+ </limited_access>
528
+ <pobox translate="label">
529
+ <label>PO Box</label>
530
+ <frontend_type>select</frontend_type>
531
+ <source_model>adminhtml/system_config_source_yesno</source_model>
532
+ <sort_order>160</sort_order>
533
+ <show_in_default>1</show_in_default>
534
+ <show_in_website>0</show_in_website>
535
+ <show_in_store>0</show_in_store>
536
+ <comment><![CDATA[Is the address of this warehouse a postal box?]]></comment>
537
+ </pobox>
538
+ </fields>
539
+ </origin>
540
+ </groups>
541
+ </temando>
542
+ <carriers>
543
+ <groups>
544
+ <temando translate="label">
545
+ <label>Temando</label>
546
+ <frontend_type>text</frontend_type>
547
+ <sort_order>99999</sort_order>
548
+ <show_in_default>1</show_in_default>
549
+ <show_in_website>1</show_in_website>
550
+ <show_in_store>1</show_in_store>
551
+ <fields>
552
+ <active translate="label">
553
+ <label>Enabled</label>
554
+ <frontend_type>select</frontend_type>
555
+ <config_path>carriers/temando/active</config_path>
556
+ <source_model>adminhtml/system_config_source_yesno</source_model>
557
+ <sort_order>10</sort_order>
558
+ <show_in_default>1</show_in_default>
559
+ <show_in_website>1</show_in_website>
560
+ <show_in_store>1</show_in_store>
561
+ </active>
562
+ <sallowspecific translate="label">
563
+ <label>Ship to applicable countries</label>
564
+ <frontend_type>select</frontend_type>
565
+ <config_path>carriers/temando/sallowspecific</config_path>
566
+ <sort_order>20</sort_order>
567
+ <frontend_class>shipping-applicable-country</frontend_class>
568
+ <source_model>adminhtml/system_config_source_shipping_allspecificcountries</source_model>
569
+ <show_in_default>1</show_in_default>
570
+ <show_in_website>1</show_in_website>
571
+ <show_in_store>1</show_in_store>
572
+ </sallowspecific>
573
+ <specificcountry translate="label">
574
+ <label>Ship to specific countries</label>
575
+ <frontend_type>multiselect</frontend_type>
576
+ <sort_order>30</sort_order>
577
+ <source_model>adminhtml/system_config_source_country</source_model>
578
+ <show_in_default>1</show_in_default>
579
+ <show_in_website>1</show_in_website>
580
+ <show_in_store>1</show_in_store>
581
+ </specificcountry>
582
+ <showmethod translate="label">
583
+ <label>Show method if not applicable</label>
584
+ <frontend_type>select</frontend_type>
585
+ <sort_order>40</sort_order>
586
+ <source_model>adminhtml/system_config_source_yesno</source_model>
587
+ <show_in_default>1</show_in_default>
588
+ <show_in_website>1</show_in_website>
589
+ <show_in_store>1</show_in_store>
590
+ </showmethod>
591
+ <free_shipping_enable translate="label">
592
+ <label>Free Shipping with Minimum Order Amount</label>
593
+ <frontend_type>select</frontend_type>
594
+ <source_model>adminhtml/system_config_source_enabledisable</source_model>
595
+ <sort_order>50</sort_order>
596
+ <show_in_default>1</show_in_default>
597
+ <show_in_website>1</show_in_website>
598
+ <show_in_store>1</show_in_store>
599
+ </free_shipping_enable>
600
+ <free_shipping_subtotal translate="label">
601
+ <label>Minimum Order Amount for Free Shipping</label>
602
+ <frontend_type>text</frontend_type>
603
+ <sort_order>60</sort_order>
604
+ <show_in_default>1</show_in_default>
605
+ <show_in_website>1</show_in_website>
606
+ <show_in_store>1</show_in_store>
607
+ </free_shipping_subtotal>
608
+ <specificerrmsg translate="label">
609
+ <label>Displayed Error Message</label>
610
+ <frontend_type>textarea</frontend_type>
611
+ <config_path>carriers/temando/specificerrmsg</config_path>
612
+ <sort_order>70</sort_order>
613
+ <show_in_default>1</show_in_default>
614
+ <show_in_website>1</show_in_website>
615
+ <show_in_store>1</show_in_store>
616
+ </specificerrmsg>
617
+ <allowed_methods translate="label">
618
+ <label>Allowed Carriers</label>
619
+ <frontend_type>multiselect</frontend_type>
620
+ <config_path>carriers/temando/allowed_methods</config_path>
621
+ <sort_order>80</sort_order>
622
+ <source_model>temando/shipping_carrier_temando_source_method</source_model>
623
+ <show_in_default>1</show_in_default>
624
+ <show_in_website>1</show_in_website>
625
+ <show_in_store>1</show_in_store>
626
+ <comment><![CDATA[Use CTRL + click to select multiple carriers]]></comment>
627
+ </allowed_methods>
628
+ </fields>
629
+ </temando>
630
+ </groups>
631
+ </carriers>
632
+ </sections>
633
+ </config>
app/code/community/Temando/Temando/sql/temando_setup/mysql4-install-1.0.0.php ADDED
@@ -0,0 +1,303 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ set_time_limit(0);
4
+
5
+ /* @var $this Mage_Eav_Model_Entity_Setup */
6
+ /* @var $installer Mage_Eav_Model_Entity_Setup */
7
+
8
+ $installer = $this;
9
+ $installer->startSetup();
10
+
11
+ // Add custom Temando attributes
12
+ $installer->addAttributeGroup('catalog_product', 'Default', 'Temando', 90);
13
+ $installer->addAttribute('catalog_product', 'temando_packaging_mode',
14
+ array(
15
+ 'type' => 'int',
16
+ 'label' => 'Packaging Mode',
17
+ 'group' => 'Temando',
18
+ 'global' => Mage_Catalog_Model_Resource_Eav_Attribute::SCOPE_GLOBAL,
19
+ 'source' => 'temando/entity_attribute_source_packaging_mode',
20
+ 'input' => 'select',
21
+ 'default' => false,
22
+ 'visible' => true,
23
+ 'required' => false,
24
+ 'user_defined' => false,
25
+ 'searchable' => true,
26
+ 'filterable' => true,
27
+ 'comparable' => false,
28
+ 'visible_on_front' => false,
29
+ 'unique' => false
30
+ )
31
+ );
32
+
33
+ $installer->addAttribute('catalog_product', 'temando_packaging',
34
+ array(
35
+ 'type' => 'varchar',
36
+ 'label' => 'Packaging',
37
+ 'group' => 'Temando',
38
+ 'global' => Mage_Catalog_Model_Resource_Eav_Attribute::SCOPE_GLOBAL,
39
+ 'source' => 'temando/entity_attribute_source_packaging',
40
+ 'input' => 'select',
41
+ 'visible' => true,
42
+ 'required' => false,
43
+ 'user_defined' => false,
44
+ 'searchable' => false,
45
+ 'filterable' => false,
46
+ 'comparable' => false,
47
+ 'visible_on_front' => false,
48
+ 'unique' => false
49
+ )
50
+ );
51
+
52
+ $installer->addAttribute('catalog_product', 'temando_fragile',
53
+ array(
54
+ 'type' => 'int',
55
+ 'label' => 'Fragile',
56
+ 'group' => 'Temando',
57
+ 'global' => Mage_Catalog_Model_Resource_Eav_Attribute::SCOPE_GLOBAL,
58
+ 'source' => 'eav/entity_attribute_source_boolean',
59
+ 'input' => 'select',
60
+ 'default' => false,
61
+ 'visible' => true,
62
+ 'required' => false,
63
+ 'user_defined' => false,
64
+ 'searchable' => false,
65
+ 'filterable' => false,
66
+ 'comparable' => false,
67
+ 'visible_on_front' => false,
68
+ 'unique' => false
69
+ )
70
+ );
71
+
72
+ $installer->addAttribute('catalog_product', 'temando_length',
73
+ array(
74
+ 'type' => 'decimal',
75
+ 'label' => 'Length',
76
+ 'group' => 'Temando',
77
+ 'global' => Mage_Catalog_Model_Resource_Eav_Attribute::SCOPE_GLOBAL,
78
+ 'visible' => true,
79
+ 'required' => false,
80
+ 'user_defined' => false,
81
+ 'searchable' => false,
82
+ 'filterable' => false,
83
+ 'comparable' => false,
84
+ 'visible_on_front' => false,
85
+ 'unique' => false
86
+ )
87
+ );
88
+
89
+ $installer->addAttribute('catalog_product', 'temando_width',
90
+ array(
91
+ 'type' => 'decimal',
92
+ 'label' => 'Width',
93
+ 'group' => 'Temando',
94
+ 'global' => Mage_Catalog_Model_Resource_Eav_Attribute::SCOPE_GLOBAL,
95
+ 'visible' => true,
96
+ 'required' => false,
97
+ 'user_defined' => false,
98
+ 'searchable' => false,
99
+ 'filterable' => false,
100
+ 'comparable' => false,
101
+ 'visible_on_front' => false,
102
+ 'unique' => false
103
+ )
104
+ );
105
+
106
+ $installer->addAttribute('catalog_product', 'temando_height',
107
+ array(
108
+ 'type' => 'decimal',
109
+ 'label' => 'Height',
110
+ 'group' => 'Temando',
111
+ 'global' => Mage_Catalog_Model_Resource_Eav_Attribute::SCOPE_GLOBAL,
112
+ 'visible' => true,
113
+ 'required' => false,
114
+ 'user_defined' => false,
115
+ 'searchable' => false,
116
+ 'filterable' => false,
117
+ 'comparable' => false,
118
+ 'visible_on_front' => false,
119
+ 'unique' => false
120
+ )
121
+ );
122
+
123
+ // Create custom tables
124
+ $installer->run("
125
+ DROP TABLE IF EXISTS {$this->getTable('temando_carrier')};
126
+ CREATE TABLE {$this->getTable('temando_carrier')} (
127
+ `id` int(13) UNSIGNED NOT NULL AUTO_INCREMENT,
128
+ `carrier_id` bigint(20) NOT NULL,
129
+ `company_name` varchar(250) NOT NULL,
130
+ `company_contact` text NOT NULL,
131
+ `street_address` text NOT NULL,
132
+ `street_suburb` varchar(255) NOT NULL,
133
+ `street_city` varchar(255) NOT NULL,
134
+ `street_state` varchar(255) NOT NULL,
135
+ `street_postcode` varchar(255) NOT NULL,
136
+ `street_country` varchar(255) NOT NULL,
137
+ `postal_address` text NOT NULL,
138
+ `postal_suburb` varchar(255) NOT NULL,
139
+ `postal_city` varchar(255) NOT NULL,
140
+ `postal_state` varchar(255) NOT NULL,
141
+ `postal_postcode` varchar(255) NOT NULL,
142
+ `postal_country` varchar(255) NOT NULL,
143
+ `phone` varchar(255) NOT NULL,
144
+ `email` varchar(255) NOT NULL,
145
+ `website` varchar(255) NOT NULL,
146
+ PRIMARY KEY (`id`)
147
+ ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
148
+
149
+ INSERT INTO {$this->getTable('temando_carrier')} (`id`, `carrier_id`, `company_name`) VALUES
150
+ (1, 54381, 'Allied Express'),
151
+ (2, 54426, 'Allied Express (Bulk)'),
152
+ (3, 54359, 'Startrack'),
153
+ (4, 54396, 'Startrack - Auth To Leave'),
154
+ (5, 54360, 'Bluestar Logistics'),
155
+ (6, 54429, 'Bluestar Logistics Bulk'),
156
+ (7, 54433, 'Capital Transport Courier'),
157
+ (8, 54432, 'Capital Transport HDS'),
158
+ (9, 54425, 'Couriers Please'),
159
+ (10, 54343, 'DHL'),
160
+ (11, 54430, 'DHL MultiZone'),
161
+ (12, 54431, 'DHL SingleZone'),
162
+ (13, 54427, 'Fastway Couriers Adhoc'),
163
+ (14, 54428, 'Fastway Couriers Bulk'),
164
+ (15, 54344, 'Hunter Express'),
165
+ (16, 54398, 'Hunter Express (bulk)'),
166
+ (17, 54358, 'Mainfreight'),
167
+ (18, 54410, 'Northline');
168
+ ");
169
+
170
+ $installer->run("
171
+ DROP TABLE IF EXISTS {$this->getTable('temando_quote')};
172
+ CREATE TABLE {$this->getTable('temando_quote')} (
173
+ `id` bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT,
174
+ `magento_quote_id` int(10) UNSIGNED NOT NULL,
175
+ `carrier_id` int(13) UNSIGNED NOT NULL,
176
+ `accepted` boolean NOT NULL DEFAULT '0',
177
+ `total_price` decimal(12, 4) NOT NULL,
178
+ `base_price` decimal(12, 4) NOT NULL,
179
+ `tax` decimal(12, 4) NOT NULL,
180
+ `insurance_total_price` decimal(12, 4) NOT NULL,
181
+ `carbon_total_price` decimal(12, 4) NOT NULL,
182
+ `footprints_total_price` decimal(12, 4) NOT NULL,
183
+ `currency` varchar(10) NOT NULL,
184
+ `delivery_method` text NOT NULL,
185
+ `eta_from` int(10) UNSIGNED NOT NULL DEFAULT '0',
186
+ `eta_to` int(10) UNSIGNED NOT NULL DEFAULT '0',
187
+ `guaranteed_eta` boolean NOT NULL DEFAULT '0',
188
+ `extras` TEXT NOT NULL,
189
+ PRIMARY KEY (`id`),
190
+ INDEX (`carrier_id`),
191
+ CONSTRAINT `fk_carrier_id`
192
+ FOREIGN KEY (`carrier_id`)
193
+ REFERENCES {$this->getTable('temando_carrier')} (`id`)
194
+ ON DELETE CASCADE
195
+ ON UPDATE CASCADE
196
+ ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
197
+ ");
198
+
199
+ $installer->run("
200
+ DROP TABLE IF EXISTS {$this->getTable('temando_shipment')};
201
+ CREATE TABLE {$this->getTable('temando_shipment')} (
202
+ `id` bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT,
203
+ `order_id` int(10) UNSIGNED NOT NULL,
204
+ `customer_selected_quote_id` bigint(20) UNSIGNED NULL DEFAULT NULL,
205
+ `customer_selected_options` TEXT NOT NULL,
206
+ `customer_selected_quote_description` TEXT NOT NULL,
207
+ `admin_selected_quote_id` bigint(20) UNSIGNED NULL DEFAULT NULL,
208
+ `anticipated_cost` decimal(12,4) UNSIGNED NOT NULL,
209
+ `status` int(10) NOT NULL DEFAULT '0',
210
+ `booking_request_id` int(13) UNSIGNED NOT NULL,
211
+ `booking_number` varchar(255) NOT NULL,
212
+ `consignment_number` varchar(255) NOT NULL,
213
+ `consignment_document` longtext NOT NULL,
214
+ `consignment_document_type` varchar(32) NOT NULL,
215
+ `label_document` longtext not null,
216
+ `label_document_type` varchar(32) NOT NULL,
217
+ `destination_contact_name` varchar(255) NOT NULL,
218
+ `destination_company_name` varchar(255) NOT NULL,
219
+ `destination_street` varchar(255) NOT NULL,
220
+ `destination_city` varchar(255) NOT NULL,
221
+ `destination_postcode` varchar(255) NOT NULL,
222
+ `destination_region` varchar(255) NOT NULL,
223
+ `destination_country` varchar(255) NOT NULL,
224
+ `destination_phone` varchar(255) NOT NULL,
225
+ `destination_email` varchar(255) NOT NULL,
226
+ `ready_date` DATE NULL DEFAULT NULL,
227
+ `ready_time` VARCHAR(2) NOT NULL,
228
+ PRIMARY KEY (`id`)
229
+ ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
230
+ ");
231
+
232
+
233
+ $installer->run("
234
+ DROP TABLE IF EXISTS {$this->getTable('temando_box')};
235
+ CREATE TABLE {$this->getTable('temando_box')} (
236
+ `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
237
+ `shipment_id` int(13) NOT NULL,
238
+ `comment` text NOT NULL,
239
+ `qty` int(11) NOT NULL DEFAULT '1',
240
+ `value` decimal(12,4) NOT NULL,
241
+ `length` decimal(12,4) NOT NULL,
242
+ `width` decimal(12,4) NOT NULL,
243
+ `height` decimal(12,4) NOT NULL,
244
+ `measure_unit` varchar(255) NOT NULL,
245
+ `weight` decimal(12,4) NOT NULL,
246
+ `weight_unit` varchar(255) NOT NULL,
247
+ `fragile` tinyint(1) NOT NULL DEFAULT '0',
248
+ `packaging` int(255) NOT NULL,
249
+ PRIMARY KEY (`id`),
250
+ KEY `shipment_id` (`shipment_id`)
251
+ ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
252
+ ");
253
+
254
+ $installer->run("
255
+ DROP TABLE IF EXISTS {$this->getTable('temando_manifest')};
256
+ CREATE TABLE {$this->getTable('temando_manifest')} (
257
+ `id` int(11) NOT NULL AUTO_INCREMENT,
258
+ `location_id` varchar(255) NOT NULL DEFAULT '',
259
+ `carrier_id` int(10) NOT NULL DEFAULT 0,
260
+ `start_date` date NOT NULL,
261
+ `end_date` date NOT NULL,
262
+ `manifest_document_type` varchar(250) NOT NULL DEFAULT '',
263
+ `manifest_document` longtext NOT NULL,
264
+ `label_document_type` varchar(250) NOT NULL DEFAULT '',
265
+ `label_document` longtext NOT NULL,
266
+ `type` varchar(255) NOT NULL DEFAULT 'Awaiting Confirmation',
267
+ `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
268
+ PRIMARY KEY (`id`),
269
+ INDEX (`type`)
270
+ ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
271
+ ;");
272
+
273
+
274
+ // Insert a list of states into the regions database. Magento will then pick
275
+ // these up when displaying addresses and allow the user to select from a drop-down
276
+ // list, rather than having to type them in manually.
277
+ $regions = array(
278
+ array('code' => 'ACT', 'name' => 'Australia Capital Territory'),
279
+ array('code' => 'NSW', 'name' => 'New South Wales'),
280
+ array('code' => 'NT', 'name' => 'Northern Territory'),
281
+ array('code' => 'QLD', 'name' => 'Queensland'),
282
+ array('code' => 'SA', 'name' => 'South Australia'),
283
+ array('code' => 'TAS', 'name' => 'Tasmania'),
284
+ array('code' => 'VIC', 'name' => 'Victoria'),
285
+ array('code' => 'WA', 'name' => 'Western Australia')
286
+ );
287
+
288
+ $db = Mage::getSingleton('core/resource')->getConnection('core_read');
289
+
290
+ foreach ($regions as $region) {
291
+ // Check if this region has already been added
292
+ $result = $db->fetchOne("SELECT code FROM " . $this->getTable('directory_country_region') . " WHERE `country_id` = 'AU' AND `code` = '" . $region['code'] . "'");
293
+ if ($result != $region['code']) {
294
+ $installer->run(
295
+ "INSERT INTO `{$this->getTable('directory_country_region')}` (`country_id`, `code`, `default_name`) VALUES
296
+ ('AU', '" . $region['code'] . "', '" . $region['name'] . "');
297
+ INSERT INTO `{$this->getTable('directory_country_region_name')}` (`locale`, `region_id`, `name`) VALUES
298
+ ('en_US', LAST_INSERT_ID(), '" . $region['name'] . "'), ('en_AU', LAST_INSERT_ID(), '" . $region['name'] . "');"
299
+ );
300
+ }
301
+ }
302
+
303
+ $installer->endSetup();
app/design/adminhtml/default/default/layout/temando.xml ADDED
@@ -0,0 +1,53 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <layout>
3
+
4
+ <adminhtml_system_config_edit>
5
+ <reference name="head">
6
+ <action method="addItem"><type>skin_css</type><name>temando/styles.css</name></action>
7
+ <action method="addJs"><script>temando/autocomplete.js</script></action>
8
+ <action method="addJs"><script>temando/avs.js</script></action>
9
+ <block type="adminhtml/template" template="temando/temando/region.phtml" name="temando_region" output="toHtml" />
10
+ <block type="adminhtml/template" template="temando/temando/origin-avs.phtml" name="temando_origin_avs" output="toHtml" />
11
+ </reference>
12
+ </adminhtml_system_config_edit>
13
+
14
+ <temando_adminhtml_shipment_index>
15
+ <reference name="head">
16
+ <action method="addItem"><type>skin_css</type><name>temando/styles.css</name></action>
17
+ </reference>
18
+ <reference name="content">
19
+ <block type="temando/adminhtml_shipment" name="temando_shipment">
20
+ <block type="temando/adminhtml_shipment_grid" name="temando_shipment_grid" />
21
+ </block>
22
+ </reference>
23
+ </temando_adminhtml_shipment_index>
24
+
25
+ <temando_adminhtml_shipment_edit>
26
+ <reference name="head">
27
+ <block type="adminhtml/template" template="temando/temando/region.phtml" name="temando_region" output="toHtml" />
28
+ <action method="addItem"><type>skin_css</type><name>temando/styles.css</name></action>
29
+ <action method="addJs"><script>temando/autocomplete.js</script></action>
30
+ <action method="addJs"><script>temando/avs.js</script></action>
31
+ </reference>
32
+ <reference name="content">
33
+ <block type="temando/adminhtml_shipment_edit" name="temando_shipment_edit" />
34
+ </reference>
35
+ <reference name="left">
36
+ <block type="temando/adminhtml_shipment_edit_tabs" name="temando_shipment_edit_tabs">
37
+ <action method="addTab">
38
+ <name>temando_shipment_edit_tab_form</name>
39
+ <block>temando/adminhtml_shipment_edit_tab_form</block>
40
+ </action>
41
+ </block>
42
+ </reference>
43
+ </temando_adminhtml_shipment_edit>
44
+
45
+ <temando_adminhtml_manifest_index>
46
+ <reference name="content">
47
+ <block type="temando/adminhtml_manifest" template="temando/temando/manifest.phtml" name="temando_manifest">
48
+ <block type="temando/adminhtml_manifest_filter_form" name="grid.filter.form" />
49
+ </block>
50
+ </reference>
51
+ </temando_adminhtml_manifest_index>
52
+
53
+ </layout>
app/design/adminhtml/default/default/template/temando/temando/manifest.phtml ADDED
@@ -0,0 +1,27 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <div class="content-header">
2
+ <table cellspacing="0">
3
+ <tr>
4
+ <td style="<?php echo $this->getHeaderWidth() ?>"><?php echo $this->getHeaderHtml() ?></td>
5
+ <td class="form-buttons"><?php echo $this->getButtonsHtml() ?></td>
6
+ </tr>
7
+ </table>
8
+ </div>
9
+ <div>
10
+ <?php echo $this->getChildHtml('grid.filter.form') ?>
11
+ </div>
12
+ <div>
13
+ <?php echo $this->getGridHtml() ?>
14
+ </div>
15
+ <script type="text/javascript">
16
+ function addFormSubmit() {
17
+ var filters = $$('#add_form input', '#add_form select');
18
+ var elements = [];
19
+ for(var i in filters){
20
+ if(filters[i].value && filters[i].value.length && !filters[i].disabled) elements.push(filters[i]);
21
+ }
22
+ var validator = new Validation('add_form');
23
+ if (validator.validate()) {
24
+ $('add_form').submit();
25
+ }
26
+ }
27
+ </script>
app/design/adminhtml/default/default/template/temando/temando/origin-avs.phtml ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ <script type="text/javascript">
2
+ //<![CDATA[
3
+ var address_validation_url = '<?php echo $this->getUrl('etemando/pcs/autocompletecart', array('_secure' => Mage::app()->getStore()->isCurrentlySecure())); ?>';
4
+ var originAvs = new Avs(
5
+ address_validation_url,
6
+ 'temando_origin_postcode',
7
+ 'temando_origin_city',
8
+ 'temando_origin_country'
9
+ );
10
+ //]]
11
+ </script>
app/design/adminhtml/default/default/template/temando/temando/region.phtml ADDED
@@ -0,0 +1,123 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <script type="text/javascript">
2
+ //<![CDATA[
3
+
4
+ var temandoOrigin = Class.create();
5
+ temandoOrigin.prototype = {
6
+ initialize : function()
7
+ {
8
+ this.reload = false;
9
+ this.loader = new varienLoader(true);
10
+ this.regionsUrl = "<?php echo Mage::helper('adminhtml')->getUrl('temando/adminhtml_json/countryRegion') ?>";
11
+ this.arrRegNames = ['region','state','destination_region'];
12
+
13
+ this.bindCountryRegionRelation();
14
+ },
15
+ bindCountryRegionRelation : function(parentId)
16
+ {
17
+ if(parentId) {
18
+ // todo: fix bug in IE
19
+ var countryElements = $$('#'+parentId+' .temando-countries');
20
+ } else {
21
+ var countryElements = $$('.temando-countries');
22
+ }
23
+ for(var i=0; i<countryElements.size(); i++) {
24
+ Event.observe(countryElements[i], 'change', this.reloadRegionField.bind(this));
25
+ this.initRegionField(countryElements[i]);
26
+ if ($(countryElements[i].id+'_inherit')) {
27
+ Event.observe($(countryElements[i].id+'_inherit'), 'change', this.enableRegionZip.bind(this));
28
+ }
29
+ }
30
+ },
31
+ enableRegionZip : function(event)
32
+ {
33
+ this.reload = true;
34
+ var countryElement = Event.element(event);
35
+ if (countryElement && countryElement.id && !countryElement.checked) {
36
+ var regionElement = null;
37
+ for(var i = 0; i<this.arrRegNames.length; i++) {
38
+ regionElement = $(countryElement.id.replace(/country/, this.arrRegNames[i]));
39
+ if(regionElement !== null) break;
40
+ }
41
+ var zipElement = $(countryElement.id.replace(/country/, 'postcode'));
42
+ if(zipElement == null) {
43
+ zipElement = $(countryElement.id.replace(/country_id/, 'postcode'));
44
+ }
45
+ if (regionElement && regionElement.checked) {
46
+ regionElement.click();
47
+ }
48
+ if (zipElement && zipElement.checked) {
49
+ zipElement.click();
50
+ }
51
+ }
52
+ },
53
+ initRegionField : function(element)
54
+ {
55
+ var countryElement = element;
56
+ if (countryElement && countryElement.id) {
57
+ var regionElement = $(countryElement.id.replace(/country/, 'region'));
58
+ if(regionElement == null) {
59
+ regionElement = $(countryElement.id.replace(/country_id/, 'state'));
60
+ }
61
+ if (regionElement) {
62
+ this.regionElement = regionElement;
63
+ var url = this.regionsUrl+'parent/'+countryElement.value;
64
+ this.loader.load(url, {}, this.refreshRegionField.bind(this));
65
+ }
66
+ }
67
+ },
68
+ reloadRegionField : function(event)
69
+ {
70
+ this.reload = true;
71
+ var countryElement = Event.element(event);
72
+ if (countryElement && countryElement.id) {
73
+ var regionElement = null;
74
+ for(var i = 0; i<this.arrRegNames.length; i++) {
75
+ regionElement = $(countryElement.id.replace(/country/, this.arrRegNames[i]));
76
+ if(regionElement !== null) break;
77
+ }
78
+ if (regionElement) {
79
+ this.regionElement = regionElement;
80
+ var url = this.regionsUrl+'parent/'+countryElement.value;
81
+ this.loader.load(url, {}, this.refreshRegionField.bind(this));
82
+ }
83
+ }
84
+ },
85
+ refreshRegionField : function(serverResponse)
86
+ {
87
+ if (serverResponse) {
88
+ var data = eval('(' + serverResponse + ')');
89
+ var value = this.regionElement.value;
90
+ var disabled = this.regionElement.disabled;
91
+ if (data.length) {
92
+ var html = '<select name="'+this.regionElement.name+'" id="'+this.regionElement.id+'" class="select" title="'+this.regionElement.title+'"'+(disabled?" disabled":"")+'>';
93
+ for (var i in data) {
94
+ if(data[i].label) {
95
+ html+= '<option value="'+data[i].value+'"';
96
+ if(this.regionElement.value && (this.regionElement.value == data[i].value || this.regionElement.value == data[i].label)) {
97
+ html+= ' selected';
98
+ }
99
+ html+='>'+data[i].label+'<\/option>';
100
+ }
101
+ }
102
+ html+= '<\/select>';
103
+
104
+ var parentNode = this.regionElement.parentNode;
105
+ var regionElementId = this.regionElement.id;
106
+ parentNode.innerHTML = html;
107
+ this.regionElement = $(regionElementId);
108
+ } else if (this.reload) {
109
+ var html = '<input type="text" name="'+this.regionElement.name+'" id="'+this.regionElement.id+'" class="input-text" title="'+this.regionElement.title+'"'+(disabled?" disabled":"")+'>';
110
+ var parentNode = this.regionElement.parentNode;
111
+ var regionElementId = this.regionElement.id;
112
+ parentNode.innerHTML = html;
113
+ this.regionElement = $(regionElementId);
114
+ //this.regionElement.replace(html);
115
+ }
116
+ }
117
+ }
118
+ }
119
+
120
+ temandoAddress = new temandoOrigin();
121
+
122
+ //]]
123
+ </script>
app/design/adminhtml/default/default/template/temando/temando/shipment.phtml ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /* @var $this Temando_Temando_Block_Adminhtml_Shipment_Edit_Tab_Form */
4
+ ?>
5
+
6
+ <div>
7
+ <div class="box-left">
8
+ <?php echo $this->getLayout()->createBlock('temando/adminhtml_shipment_edit_tab_form_status')->setTemplate('temando/temando/shipment/status.phtml')->toHtml(); ?>
9
+ <?php echo $this->getLayout()->createBlock('temando/adminhtml_shipment_edit_tab_form_anytime')->setTemplate('temando/temando/shipment/anytime.phtml')->toHtml(); ?>
10
+ </div>
11
+ <div class="box-right">
12
+ <?php echo $this->getLayout()->createBlock('temando/adminhtml_shipment_edit_tab_form_anywhere')->setTemplate('temando/temando/shipment/anywhere.phtml')->toHtml(); ?>
13
+ <?php echo $this->getLayout()->createBlock('temando/adminhtml_shipment_edit_tab_form_insurance')->setTemplate('temando/temando/shipment/insurance.phtml')->toHtml(); ?>
14
+ </div>
15
+ <div class="clear"></div>
16
+
17
+ <?php echo $this->getLayout()->createBlock('temando/adminhtml_shipment_edit_tab_form_products')->setTemplate('temando/temando/shipment/products.phtml')->toHtml(); ?>
18
+ <?php echo $this->getLayout()->createBlock('temando/adminhtml_shipment_edit_tab_form_boxes')->setTemplate('temando/temando/shipment/boxes.phtml')->toHtml(); ?>
19
+
20
+ <?php if ($this->getShipment()->getStatus() == Temando_Temando_Model_System_Config_Source_Shipment_Status::PENDING && count($this->getQuotes())): ?>
21
+ <?php echo $this->getLayout()->createBlock('temando/adminhtml_shipment_edit_tab_form_quotes')->setTemplate('temando/temando/shipment/quotes.phtml')->toHtml(); ?>
22
+ <?php endif; ?>
23
+ </div>
app/design/adminhtml/default/default/template/temando/temando/shipment/anytime.phtml ADDED
@@ -0,0 +1,76 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /* @var $this Temando_Temando_Block_Adminhtml_Shipment_Edit_Tab_Form_Anytime */
3
+ ?>
4
+
5
+ <div class="entry-edit">
6
+ <div class="entry-edit-head">
7
+ <h4><?php echo $this->__('Pick-up Date'); ?></h4>
8
+ </div>
9
+ <div class="fieldset">
10
+ <?php if ($this->getShipment()->getStatus() == Temando_Temando_Model_System_Config_Source_Shipment_Status::PENDING): ?>
11
+ <table cellspacing="0" class="form-list">
12
+ <tr>
13
+ <td class="label"><input type="radio" name="ready" value="" onclick="$('select_pick_up').hide();" id="ready_0" /></td>
14
+ <td class="value"><label><?php echo $this->__('ASAP'); ?></label></td>
15
+ </tr>
16
+ <tr>
17
+ <td class="label"><input type="radio" name="ready" value="1" onclick="$('select_pick_up').show();" id="ready_1" /></td>
18
+ <td class="value"><label><?php echo $this->__('Select Date:'); ?></label></td>
19
+ </tr>
20
+ </table>
21
+ <?php endif; ?>
22
+ <div id="select_pick_up">
23
+ <table cellspacing="0" class="form-list">
24
+ <tr>
25
+ <td class="label"><label><?php echo $this->__('Date'); ?></label></td>
26
+ <td class="value">
27
+ <?php if ($this->getShipment()->getStatus() == Temando_Temando_Model_System_Config_Source_Shipment_Status::PENDING): ?>
28
+ <input id="ready_date" name="ready_date" value="<?php echo $this->getShipment()->getReadyDate(); ?>" class="input-text" />
29
+ <img id="ready_date_trigger" alt="Select date" title="Select date" class="v-middle" src="<?php echo $this->getSkinUrl('images/grid-cal.gif'); ?>" />
30
+ <script type="text/javascript">
31
+ //<![CDATA[
32
+ Calendar.setup({
33
+ inputField: "ready_date",
34
+ ifFormat: "%Y-%m-%e",
35
+ showsTime: false,
36
+ button: "ready_date_trigger",
37
+ align: "Bl",
38
+ singleClick : true
39
+ });
40
+ //]]>
41
+ </script>
42
+ <?php else: ?>
43
+ <?php echo $this->getShipment()->getReadyDate(); ?>
44
+ <?php endif; ?>
45
+ </td>
46
+ </tr>
47
+ <tr>
48
+ <td class="label"><label><?php echo $this->__('Time of Day'); ?></label></td>
49
+ <td class="value">
50
+ <?php if ($this->getShipment()->getStatus() == Temando_Temando_Model_System_Config_Source_Shipment_Status::PENDING): ?>
51
+ <select id="ready_time" name="ready_time" class="select">
52
+ <option value=""></option>
53
+ <?php foreach (Mage::getModel('temando/system_config_source_readytime')->toOptionArray() as $_time): ?>
54
+ <option value="<?php echo $_time['value']; ?>" <?php if ($_time['value'] == $this->getShipment()->getReadyTime()): ?> selected="selected"<?php endif;?>><?php echo $_time['label']; ?></option>
55
+ <?php endforeach; ?>
56
+ </select>
57
+ <?php else: ?>
58
+ <?php echo $this->getShipment()->getReadyTime(); ?>
59
+ <?php endif; ?>
60
+ </td>
61
+ </tr>
62
+ </table>
63
+ </div>
64
+ <?php if ($this->getShipment()->getStatus() == Temando_Temando_Model_System_Config_Source_Shipment_Status::PENDING): ?>
65
+ <script type="text/javascript">
66
+ <?php if ($this->getShipment()->getReadyDate()): ?>
67
+ $('ready_1').checked = true;
68
+ $('select_pick_up').show();
69
+ <?php else: ?>
70
+ $('ready_0').checked = true;
71
+ $('select_pick_up').hide();
72
+ <?php endif; ?>
73
+ </script>
74
+ <?php endif; ?>
75
+ </div>
76
+ </div>
app/design/adminhtml/default/default/template/temando/temando/shipment/anywhere.phtml ADDED
@@ -0,0 +1,103 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /* @var $this Temando_Temando_Block_Adminhtml_Shipment_Edit_Tab_Form_Anywhere */
3
+ $_shipment = $this->getShipment();
4
+ ?>
5
+
6
+ <div class="entry-edit">
7
+ <div class="entry-edit-head">
8
+ <h4><?php echo $this->__('Destination'); ?></h4>
9
+ </div>
10
+ <div class="fieldset">
11
+ <table cellspacing="0" class="form-list">
12
+ <tr>
13
+ <td class="label"><label><?php echo $this->__('Contact Name'); ?></label></td>
14
+ <?php if ($_shipment->getStatus() == Temando_Temando_Model_System_Config_Source_Shipment_Status::PENDING): ?>
15
+ <td class="value"><input type="text" id="destination_contact_name" name="destination_contact_name" value="<?php echo $_shipment->getDestinationContactName(); ?>" class="input-text" /></td>
16
+ <?php else: ?>
17
+ <td class="value"><?php echo $_shipment->getDestinationContactName(); ?></td>
18
+ <?php endif; ?>
19
+ </tr>
20
+ <tr>
21
+ <td class="label"><label><?php echo $this->__('Company Name'); ?></label></td>
22
+ <?php if ($_shipment->getStatus() == Temando_Temando_Model_System_Config_Source_Shipment_Status::PENDING): ?>
23
+ <td class="value"><input type="text" id="destination_company_name" name="destination_company_name" value="<?php echo $_shipment->getDestinationCompanyName(); ?>" class="input-text" /></td>
24
+ <?php else: ?>
25
+ <td class="value"><?php echo $_shipment->getDestinationCompanyName(); ?></td>
26
+ <?php endif; ?>
27
+ </tr>
28
+ <tr>
29
+ <td class="label"><label><?php echo $this->__('Street'); ?></label></td>
30
+ <?php if ($_shipment->getStatus() == Temando_Temando_Model_System_Config_Source_Shipment_Status::PENDING): ?>
31
+ <td class="value"><input type="text" id="destination_street" name="destination_street" value="<?php echo htmlspecialchars($_shipment->getDestinationStreet(), ENT_QUOTES); ?>" class="input-text" /></td>
32
+ <?php else: ?>
33
+ <td class="value"><?php echo $_shipment->getDestinationStreet(); ?></td>
34
+ <?php endif; ?>
35
+ </tr>
36
+ <tr>
37
+ <td class="label"><label><?php echo $this->__('Suburb'); ?></label></td>
38
+ <?php if ($_shipment->getStatus() == Temando_Temando_Model_System_Config_Source_Shipment_Status::PENDING): ?>
39
+ <td class="value"><input type="text" id="destination_city" name="destination_city" value="<?php echo $_shipment->getDestinationCity(); ?>" class="input-text" /></td>
40
+ <?php else: ?>
41
+ <td class="value"><?php echo $_shipment->getDestinationCity(); ?></td>
42
+ <?php endif; ?>
43
+ </tr>
44
+ <tr>
45
+ <td class="label"><label><?php echo $this->__('Region'); ?></label></td>
46
+ <?php if ($_shipment->getStatus() == Temando_Temando_Model_System_Config_Source_Shipment_Status::PENDING): ?>
47
+ <td class="value"><input type="text" id="destination_region" name="destination_region" value="<?php echo $_shipment->getDestinationRegion(); ?>" class="input-text" /></td>
48
+ <?php else: ?>
49
+ <td class="value"><?php echo $_shipment->getDestinationRegion(); ?></td>
50
+ <?php endif; ?>
51
+ </tr>
52
+ <tr>
53
+ <td class="label"><label><?php echo $this->__('Postcode'); ?></label></td>
54
+ <?php if ($_shipment->getStatus() == Temando_Temando_Model_System_Config_Source_Shipment_Status::PENDING): ?>
55
+ <td class="value"><input type="text" id="destination_postcode" name="destination_postcode" value="<?php echo $_shipment->getDestinationPostcode(); ?>" class="input-text" /></td>
56
+ <?php else: ?>
57
+ <td class="value"><?php echo $_shipment->getDestinationPostcode(); ?></td>
58
+ <?php endif; ?>
59
+ </tr>
60
+ <tr>
61
+ <td class="label"><label><?php echo $this->__('Country'); ?></label></td>
62
+ <td class="value">
63
+ <?php if ($_shipment->getStatus() == Temando_Temando_Model_System_Config_Source_Shipment_Status::PENDING): ?>
64
+ <select id="destination_country" name="destination_country" class="select temando-countries">
65
+ <?php foreach (Mage::getModel('directory/country')->getCollection()->toOptionArray() as $_country): ?>
66
+ <option value="<?php echo $_country['value']; ?>" <?php if ($_country['value'] == $_shipment->getDestinationCountry()): ?> selected="selected"<?php endif;?>><?php echo $_country['label']; ?></option>
67
+ <?php endforeach; ?>
68
+ </select>
69
+ <?php else: ?>
70
+ <?php echo Mage::getModel('directory/country')->load($_shipment->getDestinationCountry())->getName(); ?>
71
+ <?php endif; ?>
72
+ </td>
73
+ </tr>
74
+ <tr>
75
+ <td class="label"><label><?php echo $this->__('Phone'); ?></label></td>
76
+ <?php if ($_shipment->getStatus() == Temando_Temando_Model_System_Config_Source_Shipment_Status::PENDING): ?>
77
+ <td class="value"><input type="text" id="destination_phone" name="destination_phone" value="<?php echo $_shipment->getDestinationPhone(); ?>" class="input-text" /></td>
78
+ <?php else: ?>
79
+ <td class="value"><?php echo $_shipment->getDestinationPhone(); ?></td>
80
+ <?php endif; ?>
81
+ </tr>
82
+ <tr>
83
+ <td class="label"><label><?php echo $this->__('Email'); ?></label></td>
84
+ <?php if ($_shipment->getStatus() == Temando_Temando_Model_System_Config_Source_Shipment_Status::PENDING): ?>
85
+ <td class="value"><input type="text" id="destination_email" name="destination_email" value="<?php echo $_shipment->getDestinationEmail(); ?>" class="input-text" /></td>
86
+ <?php else: ?>
87
+ <td class="value"><?php echo $_shipment->getDestinationEmail(); ?></td>
88
+ <?php endif; ?>
89
+ </tr>
90
+ </table>
91
+ </div>
92
+ </div>
93
+ <script type="text/javascript">
94
+ //<[CDATA[
95
+ var shipping_estimator_url = '<?php echo $this->getUrl('etemando/pcs/autocompletecart', array('_secure' => Mage::app()->getStore()->isCurrentlySecure())); ?>';
96
+ var avs = new Avs(
97
+ shipping_estimator_url,
98
+ 'destination_postcode',
99
+ 'destination_city',
100
+ 'destination_country'
101
+ );
102
+ //]]>
103
+ </script>
app/design/adminhtml/default/default/template/temando/temando/shipment/boxes.phtml ADDED
@@ -0,0 +1,165 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /* @var $this Temando_Temando_Block_Adminhtml_Shipment_Edit_Tab_Form_Boxes */
4
+ ?>
5
+
6
+ <div class="entry-edit">
7
+ <div class="entry-edit-head">
8
+ <h4><?php echo $this->__('Boxes to Ship'); ?></h4>
9
+ <div class="form-buttons">
10
+ <table>
11
+ <tr>
12
+ <td class="filter-actions a-right last">
13
+ <button id="box_add_button" class="scalable add" onclick="javascript:box_add(); return false;"><span><?php echo $this->__('Add Box'); ?></span></button>
14
+ <button id="box_clear_button" class="scalable delete" onclick="box_clear(); return false;"><span><?php echo $this->__('Clear'); ?></span></button>
15
+ <button id="box_import_button" class="scalable" onclick="box_import(); return false;"><span><?php echo $this->__('Import from Above'); ?></span></button>
16
+ </td>
17
+ </tr>
18
+ </table>
19
+ </div>
20
+ </div>
21
+ </div>
22
+ <div class="grid np">
23
+ <div class="hor-scroll">
24
+ <table cellspacing="0" class="box np" id="boxes">
25
+ <col />
26
+ <col style="width: 150px;" />
27
+ <col style="width: 70px;" />
28
+ <col style="width: 50px;" />
29
+ <col style="width: 70px;" />
30
+ <col style="width: 120px;" />
31
+ <col style="width: 90px;" />
32
+ <col style="width: 90px;" />
33
+ <col style="width: 90px;" />
34
+ <col style="width: 60px;" />
35
+ <col style="width: 100px;" />
36
+ <thead>
37
+ <tr class="headings">
38
+ <td colspan="5" style="visibility:hidden;">
39
+ <input type="hidden" id="boxes_deleted" name="boxes_deleted" value="" />
40
+ </td>
41
+ <th colspan="4" class="a-center"><?php echo $this->__('Dimensions'); ?></th>
42
+ </tr>
43
+ <tr class="headings">
44
+ <th><?php echo $this->__('Comment'); ?></th>
45
+ <th class="a-center"><?php echo $this->__('Packaging'); ?></th>
46
+ <th class="a-center"><?php echo $this->__('Fragile'); ?></th>
47
+ <th class="a-center"><?php echo $this->__('Qty'); ?></th>
48
+ <th class="a-center"><?php echo $this->__('Value'); ?> ($)</th>
49
+ <th class="a-center"><?php echo $this->__('Weight'); ?></th>
50
+ <th class="a-center"><?php echo $this->__('Length'); ?></th>
51
+ <th class="a-center"><?php echo $this->__('Width'); ?></th>
52
+ <th class="a-center"><?php echo $this->__('Height'); ?></th>
53
+ <th class="a-center"><?php echo $this->__('Unit'); ?></th>
54
+ <th class="a-center last"><?php echo $this->__('Action'); ?></th>
55
+ </tr>
56
+ </thead>
57
+ <tbody>
58
+ <?php $_i = 0; foreach ($this->getShipment()->getBoxes() as $_box): /* @var $_box Temando_Temando_Model_Box */ ?>
59
+ <tr class="<?php echo ++$_i % 2 ? 'odd' : 'even'; ?> existing_box" id="box_row_<?php echo $_i; ?>">
60
+
61
+ <td>
62
+ <input type="hidden" id="box_<?php echo $_i; ?>_id" name="box[<?php echo $_i; ?>][id]" value="<?php echo $_box->getId(); ?>" />
63
+ <input type="text" id="box_<?php echo $_i; ?>_comment" name="box[<?php echo $_i; ?>][comment]" value="<?php echo $_box->getComment(); ?>" class="input-text" />
64
+ </td>
65
+ <td>
66
+ <select id="box_<?php echo $_i; ?>_packaging" name="box[<?php echo $_i; ?>][packaging]" class="select select-box-packaging">
67
+ <?php foreach ($this->getPackagingTypes() as $_option): ?>
68
+ <option value="<?php echo $_option['value']; ?>"<?php if ($_option['value'] == $_box->getPackaging()): ?> selected="selected"<?php endif; ?>><?php echo $_option['label']; ?></option>
69
+ <?php endforeach; ?>
70
+ </select>
71
+ </td>
72
+ <td class="a-center">
73
+ <select id="box_<?php echo $_i; ?>_fragile" name="box[<?php echo $_i; ?>][fragile]" class="select">
74
+ <?php foreach (Mage::getModel('adminhtml/system_config_source_yesno')->toOptionArray() as $_option): ?>
75
+ <option value="<?php echo $_option['value']; ?>"<?php if ($_option['value'] == $_box->getFragile()): ?> selected="selected"<?php endif; ?>><?php echo $_option['label']; ?></option>
76
+ <?php endforeach; ?>
77
+ </select>
78
+ </td>
79
+ <td><input type="text" id="box_<?php echo $_i; ?>_qty" name="box[<?php echo $_i; ?>][qty]" value="<?php echo (int)$_box->getQty(); ?>" class="input-text" /></td>
80
+ <td><input type="text" id="box_<?php echo $_i; ?>_value" name="box[<?php echo $_i; ?>][value]" value="<?php echo sprintf("%01.2f", $_box->getValue()); ?>" class="input-text" /></td>
81
+ <td>
82
+ <input type="text" id="box_<?php echo $_i; ?>_weight" name="box[<?php echo $_i; ?>][weight]" value="<?php echo (float) $_box->getWeight(); ?>" class="input-text" style="width: 40px;" />
83
+ <select id="box_<?php echo $_i; ?>_weight_unit" name="box[<?php echo $_i; ?>][weight_unit]" class="select">
84
+ <?php foreach (Mage::getModel('temando/system_config_source_unit_weight')->toBriefOptionArray() as $_option): ?>
85
+ <option value="<?php echo $_option['value']; ?>"<?php if ($_option['value'] == $_box->getWeightUnit()): ?> selected="selected"<?php endif; ?>><?php echo $_option['label']; ?></option>
86
+ <?php endforeach; ?>
87
+ </select>
88
+ </td>
89
+ <td>
90
+ <input type="text" id="box_<?php echo $_i; ?>_length" name="box[<?php echo $_i; ?>][length]" value="<?php echo (float) $_box->getLength(); ?>" class="input-text" style="width: 30px;" />
91
+ <span class="box_<?php echo $_i; ?>_measure_unit"><?php echo $this->getMeasureUnitText($_box->getMeasureUnit()); ?></span>
92
+ </td>
93
+ <td>
94
+ <input type="text" id="box_<?php echo $_i; ?>_width" name="box[<?php echo $_i; ?>][width]" value="<?php echo (float) $_box->getWidth(); ?>" class="input-text" style="width: 30px;" />
95
+ <span class="box_<?php echo $_i; ?>_measure_unit"><?php echo $this->getMeasureUnitText($_box->getMeasureUnit()); ?></span>
96
+ </td>
97
+ <td>
98
+ <input type="text" id="box_<?php echo $_i; ?>_height" name="box[<?php echo $_i; ?>][height]" value="<?php echo (float) $_box->getHeight(); ?>" class="input-text" style="width: 30px;" />
99
+ <span class="box_<?php echo $_i; ?>_measure_unit"><?php echo $this->getMeasureUnitText($_box->getMeasureUnit()); ?></span>
100
+ </td>
101
+ <td class="last">
102
+ <select id="box_<?php echo $_i; ?>_measure_unit" name="box[<?php echo $_i; ?>][measure_unit]" onchange="$$('.box_<?php echo $_i; ?>_measure_unit').each(function(field) {field.innerHTML = $$('#box_<?php echo $_i; ?>_measure_unit option[value=' + $('box_<?php echo $_i; ?>_measure_unit').value + ']')[0].innerHTML;});" class="select">
103
+ <?php foreach (Mage::getModel('temando/system_config_source_unit_measure')->toBriefOptionArray() as $_option): ?>
104
+ <option value="<?php echo $_option['value']; ?>"<?php if ($_option['value'] == $_box->getMeasureUnit()): ?> selected="selected"<?php endif; ?>><?php echo $_option['label']; ?></option>
105
+ <?php endforeach; ?>
106
+ </select>
107
+ </td>
108
+ <td>
109
+ <button id="box_<?php echo $_i; ?>_remove" class="scalable delete" onclick="box_remove(<?php echo $_i; ?>); return false;"><span><?php echo $this->__('Remove'); ?></span></button>
110
+ </td>
111
+ </tr>
112
+ <?php endforeach; ?>
113
+ <tr id="blank_box_row" style="display: none;">
114
+ <td><input type="text" id="box_blank_@@id@@_comment" name="box_blank[@@id@@][comment]" class="input-text" /></td>
115
+ <td>
116
+ <select id="box_blank_@@id@@_packaging" name="box_blank[@@id@@][packaging]" class="select select-box-packaging">
117
+ <?php foreach ($this->getPackagingTypes() as $_option): ?>
118
+ <option value="<?php echo $_option['value']; ?>"><?php echo $_option['label']; ?></option>
119
+ <?php endforeach; ?>
120
+ </select>
121
+ </td>
122
+ <td class="a-center">
123
+ <select id="box_blank_@@id@@_fragile" name="box_blank[@@id@@][fragile]" class="select">
124
+ <?php foreach (Mage::getModel('adminhtml/system_config_source_yesno')->toOptionArray() as $_option): ?>
125
+ <option value="<?php echo $_option['value']; ?>"><?php echo $_option['label']; ?></option>
126
+ <?php endforeach; ?>
127
+ </select>
128
+ </td>
129
+ <td><input type="text" id="box_blank_@@id@@_qty" name="box_blank[@@id@@][qty]" class="input-text" /></td>
130
+ <td><input type="text" id="box_blank_@@id@@_value" name="box_blank[@@id@@][value]" class="input-text" /></td>
131
+ <td>
132
+ <input type="text" id="box_blank_@@id@@_weight" name="box_blank[@@id@@][weight]" class="input-text" style="width: 40px;" />
133
+ <select id="box_blank_@@id@@_weight_unit" name="box_blank[@@id@@][weight_unit]" class="select">
134
+ <?php foreach (Mage::getModel('temando/system_config_source_unit_weight')->toBriefOptionArray() as $_option): ?>
135
+ <option value="<?php echo $_option['value']; ?>"<?php if ($_option['value'] == Mage::helper('temando')->getConfigData('weight_unit')): ?> selected="selected"<?php endif; ?>><?php echo $_option['label']; ?></option>
136
+ <?php endforeach; ?>
137
+ </select>
138
+ </td>
139
+ <td>
140
+ <input type="text" id="box_blank_@@id@@_length" name="box_blank[@@id@@][length]" class="input-text" style="width: 30px;" />
141
+ <span class="box_blank_@@id@@_measure_unit"><?php echo $this->getMeasureUnitText(Mage::helper('temando')->getConfigData('measure_unit')); ?></span>
142
+ </td>
143
+ <td>
144
+ <input type="text" id="box_blank_@@id@@_width" name="box_blank[@@id@@][width]" class="input-text" style="width: 30px;" />
145
+ <span class="box_blank_@@id@@_measure_unit"><?php echo $this->getMeasureUnitText(Mage::helper('temando')->getConfigData('measure_unit')); ?></span>
146
+ </td>
147
+ <td>
148
+ <input type="text" id="box_blank_@@id@@_height" name="box_blank[@@id@@][height]" class="input-text" style="width: 30px;" />
149
+ <span class="box_blank_@@id@@_measure_unit"><?php echo $this->getMeasureUnitText(Mage::helper('temando')->getConfigData('measure_unit')); ?></span>
150
+ </td>
151
+ <td class="last">
152
+ <select id="box_blank_@@id@@_measure_unit" name="box_blank[@@id@@][measure_unit]" onchange="$$('.box_blank_@@id@@_measure_unit').each(function(field) {field.innerHTML = $$('#box_blank_@@id@@_measure_unit option[value=' + $('box_blank_@@id@@_measure_unit').value + ']')[0].innerHTML;});" class="select">
153
+ <?php foreach (Mage::getModel('temando/system_config_source_unit_measure')->toBriefOptionArray() as $_option): ?>
154
+ <option value="<?php echo $_option['value']; ?>"<?php if ($_option['value'] == Mage::helper('temando')->getConfigData('measure_unit')): ?> selected="selected"<?php endif; ?>><?php echo $_option['label']; ?></option>
155
+ <?php endforeach; ?>
156
+ </select>
157
+ </td>
158
+ <td>
159
+ <button id="box_@@id@@_remove" class="scalable delete" onclick="box_remove(@@id@@); return false;"><span><?php echo $this->__('Remove'); ?></span></button>
160
+ </td>
161
+ </tr>
162
+ </tbody>
163
+ </table>
164
+ </div>
165
+ </div>
app/design/adminhtml/default/default/template/temando/temando/shipment/insurance.phtml ADDED
@@ -0,0 +1,54 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /* @var $this Temando_Temando_Block_Adminhtml_Shipment_Edit_Tab_Form_Insurance */
4
+
5
+ $_shipment = $this->getShipment();
6
+ $insurance_option = '';
7
+ foreach ($_shipment->getOptionsArray() as $k => $v) {
8
+ if ("insurance" == $k) {
9
+ $insurance_option = $v;
10
+ break;
11
+ }
12
+ }
13
+
14
+ $total_goods_value = $this->getTotalGoodsValue();
15
+
16
+ ?>
17
+
18
+ <div class="entry-edit">
19
+ <div class="entry-edit-head">
20
+ <h4><?php echo $this->__('Insurance'); ?></h4>
21
+ </div>
22
+ <div class="fieldset">
23
+ <?php switch ($this->getTemandoHelper()->getConfigData('insurance/status')) {
24
+ case Temando_Temando_Model_System_Config_Source_Insurance::OPTIONAL:
25
+ if ('Y' == $insurance_option) {
26
+ echo $this->__('The Buyer has indicated that they would like their shipment insured.');
27
+ echo "<br />";
28
+ echo "<span class='label'>Total Goods Value: &nbsp;&nbsp;&nbsp;<b>" . $this->formatCurrency($this->getTotalGoodsValue()) . "</b></span>";
29
+ echo "<div class='confirm-insurance'><table><tr><td class='c1'><input type='checkbox' name='insurance' value='N' " . ($this->isAdminSelect()?"checked='checked'":"") . " /></td><td class='c2'>I understand that the buyer has requested insurance and may have paid for it already, however, the buyer and I have since mutually agreed to send without insurance.</td></tr></table></div>";
30
+ } else {
31
+ echo $this->__('The Buyer indicated that they would not like their shipment insured.');
32
+ }
33
+
34
+ break;
35
+ case Temando_Temando_Model_System_Config_Source_Insurance::MANDATORY:
36
+ if ('N' == $insurance_option) {
37
+ echo $this->__('The Buyer indicated that they would not like their shipment insured.');
38
+ } else {
39
+ echo "For your convenience, you have nominated to include insurance for the transport of your sold items for a nominal fee of 1.1% of the purchase price (inclusive of GST).";
40
+ }
41
+
42
+ break;
43
+ case Temando_Temando_Model_System_Config_Source_Insurance::DISABLED:
44
+ if ('Y' == $insurance_option) {
45
+ echo $this->__('The Buyer has indicated that they would like their shipment insured.');
46
+ } else {
47
+ echo "<div class='confirm-insurance'><table><tr><td class='c1'><input type='checkbox' name='insurance' value='Y' " . ($this->isAdminSelect()?"checked='checked'":"") . " /></td><td class='c2'>I want to add insurance to this shipment.</td></tr></table></div>";
48
+ }
49
+
50
+ break;
51
+ }
52
+ ?>
53
+ </div>
54
+ </div>
app/design/adminhtml/default/default/template/temando/temando/shipment/products.phtml ADDED
@@ -0,0 +1,56 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /* @var $this Temando_Temando_Block_Adminhtml_Shipment_Edit_Tab_Form_Products */
4
+ ?>
5
+
6
+ <div class="entry-edit">
7
+ <div class="entry-edit-head">
8
+ <h4><?php echo $this->__('Items Ordered'); ?></h4>
9
+ </div>
10
+ </div>
11
+ <div class="grid np">
12
+ <div class="hor-scroll">
13
+ <table cellspacing="0" class="box np">
14
+ <col />
15
+ <col style="width: 100px;" />
16
+ <col style="width: 40px;" />
17
+ <col style="width: 70px;" />
18
+ <col style="width: 70px;" />
19
+ <col style="width: 70px;" />
20
+ <col style="width: 70px;" />
21
+ <thead>
22
+ <tr class="headings">
23
+ <td colspan="4" style="visibility:hidden;"></td>
24
+ <th colspan="3" class="a-center last"><?php echo $this->__('Dimensions'); ?></th>
25
+ </tr>
26
+ <tr class="headings">
27
+ <th><?php echo $this->__('Product'); ?></th>
28
+ <th><?php echo $this->__('SKU'); ?></th>
29
+ <th class="a-center"><?php echo $this->__('Qty'); ?></th>
30
+ <th class="a-center"><?php echo $this->__('Weight'); ?></th>
31
+ <th class="a-center"><?php echo $this->__('Length'); ?></th>
32
+ <th class="a-center last"><?php echo $this->__('Width'); ?></th>
33
+ <th class="a-center"><?php echo $this->__('Height'); ?></th>
34
+ </tr>
35
+ </thead>
36
+ <?php $_i = 0; foreach ($this->getShipment()->getOrder()->getItemsCollection() as $_item): ?>
37
+ <tbody>
38
+ <?php if (!$_item->getParentItem()): /* @var $_item Mage_Sales_Model_Order_Item */ ?>
39
+ <?php
40
+ Mage::helper('temando')->applyTemandoParamsToItem($_item);
41
+ ?>
42
+ <tr class="<?php echo ++$_i % 2 ? 'odd' : 'even'; ?>">
43
+ <td><?php echo $_item->getName(); ?></td>
44
+ <td><?php echo $_item->getSku(); ?></td>
45
+ <td><?php echo (float)$_item->getQtyOrdered(); ?></td>
46
+ <td><?php echo (float)$_item->getWeight() . ' ' . $this->getWeightUnitText(); ?></td>
47
+ <td><?php echo (float)$_item->getTemandoLength() . ' ' . $this->getMeasureUnitText(); ?></td>
48
+ <td><?php echo (float)$_item->getTemandoWidth() . ' ' . $this->getMeasureUnitText(); ?></td>
49
+ <td class="last"><?php echo (float)$_item->getTemandoHeight() . ' ' . $this->getMeasureUnitText(); ?></td>
50
+ </tr>
51
+ <?php endif; ?>
52
+ </tbody>
53
+ <?php endforeach; ?>
54
+ </table>
55
+ </div>
56
+ </div>
app/design/adminhtml/default/default/template/temando/temando/shipment/quotes.phtml ADDED
@@ -0,0 +1,60 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /* @var $this Temando_Temando_Block_Adminhtml_Shipment_Edit_Tab_Form_Quotes */
4
+ ?>
5
+
6
+ <div>
7
+ <div class="entry-edit">
8
+ <div class="entry-edit-head">
9
+ <h4><?php echo $this->__('Available Quotes'); ?></h4>
10
+ </div>
11
+ </div>
12
+ <div class="grid np">
13
+ <div class="hor-scroll">
14
+ <table cellspacing="0" class="box np">
15
+ <col style="width: 200px;" />
16
+ <col />
17
+ <col style="width: 120px;" />
18
+ <col style="width: 200px;" />
19
+ <col style="width: 150px;" />
20
+ <col style="width: 120px;" />
21
+ <thead>
22
+ <tr class="headings">
23
+ <th><?php echo $this->__('Carrier'); ?></th>
24
+ <th><?php echo $this->__('Delivery Method'); ?></th>
25
+ <th><?php echo $this->__('ETA'); ?></th>
26
+ <th><?php echo $this->__('Cost'); ?></th>
27
+ <th><?php echo $this->__('Notes'); ?></th>
28
+ <th class="last">&nbsp;</th>
29
+ </tr>
30
+ </thead>
31
+ <?php $_i = 0; foreach ($this->getQuotes() as $_quote): /* @var $_quote Temando_Temando_Model_Quote */ ?>
32
+ <tbody>
33
+ <tr class="<?php echo ++$_i % 2 ? 'odd' : 'even'; ?>">
34
+ <td><?php echo $_quote->getCarrier()->getCompanyName(); ?></td>
35
+ <td><?php echo $_quote->getDeliveryMethod(); ?></td>
36
+ <td><?php echo $_quote->getEtaDescription(); ?></td>
37
+ <td><?php echo $this->formatQuotePrice($_quote); ?></td>
38
+ <td><?php echo $this->getQuoteNotes($_quote); ?></td>
39
+ <td class="last">
40
+ <a href="<?php echo $this->getUrl('*/*/book', array('shipment' => $this->getShipment()->getId(), 'quote' => $_quote->getId())); ?>" onclick="javascript: return checkUnsavedChanges();"><?php echo $this->__('Make Booking'); ?></a>
41
+ </td>
42
+ </tr>
43
+ </tbody>
44
+ <?php endforeach; ?>
45
+ </table>
46
+ </div>
47
+ </div>
48
+ </div>
49
+ <script type="text/javascript">
50
+ //<![CDATA[
51
+ function checkUnsavedChanges() {
52
+ var changed = $$('.changed');
53
+ if(changed.size() === 1) {
54
+ //no changes
55
+ return true;
56
+ }
57
+ return confirm('Unsaved changes will be lost. Continue booking?');
58
+ }
59
+ //]]>
60
+ </script>
app/design/adminhtml/default/default/template/temando/temando/shipment/status.phtml ADDED
@@ -0,0 +1,46 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /* @var $this Temando_Temando_Block_Adminhtml_Shipment_Edit_Tab_Form_Status */
4
+ ?>
5
+
6
+ <div class="entry-edit">
7
+ <div class="entry-edit-head">
8
+ <h4><?php echo $this->__('Shipment Status'); ?></h4>
9
+ </div>
10
+ <div class="fieldset">
11
+ <table cellspacing="0" class="form-list">
12
+ <tbody>
13
+ <tr>
14
+ <td class="label"><label><?php echo $this->__('Shipment Status'); ?></label></td>
15
+ <td class="value"><strong><?php echo $this->getShipmentStatusText(); ?></strong></td>
16
+ </tr>
17
+ <tr>
18
+ <td class="label"><label><?php echo $this->__('Carrier Selected by Customer'); ?></label></td>
19
+ <td class="value"><strong><?php echo $this->getCustomerSelectedQuoteDescription(); ?></strong></td>
20
+ </tr>
21
+ <?php foreach ($this->getShipment()->getOptions() as $_option): ?>
22
+ <?php /* @var $_option Temando_Temando_Model_Option_Abstract */?>
23
+ <tr>
24
+ <td class="label"><label><?php echo $_option->getName(); ?></label></td>
25
+ <td class="value"><strong><?php echo $_option->getLabel($_option->getForcedValue()); ?></strong>
26
+ </tr>
27
+ <?php endforeach; ?>
28
+ <tr>
29
+ <td class="label"><label><?php echo $this->__('Shipping Paid by Customer'); ?></label></td>
30
+ <td class="value"><strong><?php echo $this->formatCurrency($this->getShipment()->getOrder()->getShippingAmount()); ?></strong></td>
31
+ </tr>
32
+ <?php if ($this->getShipment()->getStatus() == Temando_Temando_Model_System_Config_Source_Shipment_Status::BOOKED): ?>
33
+ <?php $_permutation = $this->getShipment()->getSelectedQuotePermutation(); ?>
34
+ <tr>
35
+ <td class="label"><label><?php echo $this->__('Final Carrier Selected'); ?></label></td>
36
+ <td class="value"><strong><?php echo $_permutation ? $_permutation->getDescription() : $this->getShipment()->getSelectedQuote()->getDescription(); ?></strong></td>
37
+ </tr>
38
+ <tr>
39
+ <td class="label"><label><?php echo $this->__('Final Shipping Amount'); ?></label></td>
40
+ <td class="value"><strong><?php echo $this->formatCurrency($this->getShipment()->getAnticipatedCost()); ?></strong></td>
41
+ </tr>
42
+ <?php endif; ?>
43
+ </tbody>
44
+ </table>
45
+ </div>
46
+ </div>
app/design/frontend/base/default/layout/temando.xml ADDED
@@ -0,0 +1,91 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <layout>
3
+
4
+ <default>
5
+ <reference name="head">
6
+ <action method="addJs"><script>temando/autocomplete.js</script></action>
7
+ <action method="addJs"><script>temando/avs.js</script></action>
8
+ <action method="addCss"><stylesheet>css/temando/autocomplete.css</stylesheet></action>
9
+ </reference>
10
+ </default>
11
+
12
+ <default>
13
+ <reference name="before_body_end">
14
+ <block type='core/template' name="pcs" template='temando/temando/pcs.phtml' />
15
+ </reference>
16
+ </default>
17
+
18
+ <etemando_pcs_product>
19
+ <reference name="root">
20
+ <block type="temando/product_shipping_methods" name="root" template="temando/temando/product/shipping/methods.phtml"/>
21
+ </reference>
22
+ </etemando_pcs_product>
23
+
24
+ <checkout_onepage_index>
25
+ <reference name="head">
26
+ <action method="addItem">
27
+ <type>skin_js</type>
28
+ <name>js/temando/checkout.js</name>
29
+ </action>
30
+ <action method="addCss">
31
+ <stylesheet>css/temando/styles.css</stylesheet>
32
+ </action>
33
+ </reference>
34
+ <reference name="checkout.onepage.shipping_method.available">
35
+ <block name="checkout.onepage.shipping_method.available" type="temando/onepage_shipping_method_available" template="temando/temando/shipping_method/available.phtml">
36
+ <block name="checkout.onepage.shipping_method.available.single" as="options_single" type="temando/onepage_shipping_method_available_single" template="temando/temando/shipping_method/available/options_single.phtml" />
37
+ </block>
38
+ </reference>
39
+ </checkout_onepage_index>
40
+
41
+ <checkout_onepage_shippingmethod>
42
+ <reference name="root">
43
+ <block name="root" type="temando/onepage_shipping_method_available" template="temando/temando/shipping_method/available.phtml" >
44
+ <block name="checkout.onepage.shipping_method.available.single" as="options_single" type="temando/onepage_shipping_method_available_single" template="temando/temando/shipping_method/available/options_single.phtml" />
45
+ </block>
46
+ </reference>
47
+ </checkout_onepage_shippingmethod>
48
+
49
+ <checkout_cart_index>
50
+ <reference name="checkout.cart.shipping">
51
+ <action method="setTemplate" ifconfig='carriers/temando/active'>
52
+ <template>temando/temando/checkout/cart/shipping.phtml</template>
53
+ </action>
54
+ </reference>
55
+
56
+ </checkout_cart_index>
57
+
58
+ <catalog_product_view>
59
+ <reference name="head">
60
+ <action method="addItem">
61
+ <type>skin_js</type>
62
+ <name>js/temando/product.js</name>
63
+ </action>
64
+ <action method="addCss">
65
+ <stylesheet>css/temando/product.css</stylesheet>
66
+ </action>
67
+ </reference>
68
+ <reference name="right">
69
+ <block type="temando/product_shipping" name="temando.product.shipping" before="-" template="temando/temando/product/shipping.phtml"/>
70
+ </reference>
71
+ </catalog_product_view>
72
+
73
+ <customer_address_form>
74
+ <reference name="my.account.wrapper">
75
+ <block type="customer/address_edit" name="customer_address_edit" template="temando/temando/customer/address/edit.phtml"/>
76
+ </reference>
77
+ </customer_address_form>
78
+
79
+ <checkout_multishipping_customer_address translate="label">
80
+ <reference name="customer_address_edit">
81
+ <block type="customer/address_edit" name="customer_address_edit" template="temando/temando/customer/address/edit.phtml"/>
82
+ </reference>
83
+ </checkout_multishipping_customer_address>
84
+
85
+ <paypal_express_review>
86
+ <reference name="before_body_end">
87
+ <remove name="pcs" />
88
+ </reference>
89
+ </paypal_express_review>
90
+
91
+ </layout>
app/design/frontend/base/default/template/temando/temando/checkout/cart/shipping.phtml ADDED
@@ -0,0 +1,132 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
28
+ /**
29
+ * @see Mage_Checkout_Block_Cart_Shipping
30
+ */
31
+ ?>
32
+ <div class="shipping">
33
+ <h2><?php echo $this->__('Estimate Shipping and Tax') ?></h2>
34
+ <div class="shipping-form">
35
+ <form action="<?php echo $this->getUrl('checkout/cart/estimatePost') ?>" method="post" id="shipping-zip-form">
36
+ <p><?php echo $this->__('Enter your destination to get a shipping estimate.') ?></p>
37
+ <ul id="shipping_estimation" class="form-list">
38
+ <li>
39
+ <label for="country" class="required"><em>*</em><?php echo $this->__('Country') ?></label>
40
+ <div class="input-box">
41
+ <?php echo Mage::getBlockSingleton('directory/data')->getCountryHtmlSelect($this->getEstimateCountryId()) ?>
42
+ </div>
43
+ </li>
44
+ <li>
45
+ <label for="city"<?php if ($this->isCityRequired()) echo ' class="required"' ?>><?php if ($this->isCityRequired()) echo '<em>*</em>' ?><?php echo $this->__('City') ?></label>
46
+ <div class="input-box">
47
+ <input class="input-text<?php if ($this->isCityRequired()):?> required-entry<?php endif;?>" id="city" type="text" name="estimate_city" value="<?php echo $this->htmlEscape($this->getEstimateCity()) ?>" />
48
+ </div>
49
+ </li>
50
+ <li>
51
+ <label for="postcode"<?php if ($this->isZipCodeRequired()) echo ' class="required"' ?>><?php if ($this->isZipCodeRequired()) echo '<em>*</em>' ?><?php echo $this->__('Zip/Postal Code') ?></label>
52
+ <div class="input-box">
53
+ <input class="input-text validate-postcode<?php if ($this->isZipCodeRequired()):?> required-entry<?php endif;?>" type="text" id="postcode" name="estimate_postcode" value="<?php echo $this->htmlEscape($this->getEstimatePostcode()) ?>" />
54
+ </div>
55
+ </li>
56
+ </ul>
57
+
58
+ <div class="buttons-set">
59
+ <button type="button" title="<?php echo $this->__('Get a Quote') ?>" onclick="coShippingMethodForm.submit()" class="button"><span><span><?php echo $this->__('Get a Quote') ?></span></span></button>
60
+ </div>
61
+ </form>
62
+
63
+ <?php if (($_shippingRateGroups = $this->getEstimateRates())): ?>
64
+ <form id="co-shipping-method-form" action="<?php echo $this->getUrl('checkout/cart/estimateUpdatePost') ?>">
65
+ <dl class="sp-methods">
66
+ <?php foreach ($_shippingRateGroups as $code => $_rates): ?>
67
+ <dt><?php echo $this->getCarrierName($code) ?></dt>
68
+ <dd>
69
+ <ul>
70
+ <?php foreach ($_rates as $_rate): ?>
71
+ <li<?php if ($_rate->getErrorMessage()) echo ' class="error-msg"';?>>
72
+ <?php if ($_rate->getErrorMessage()): ?>
73
+ <?php echo $_rate->getErrorMessage() ?>
74
+ <?php else: ?>
75
+ <input name="estimate_method" type="radio" value="<?php echo $this->htmlEscape($_rate->getCode()) ?>" id="s_method_<?php echo $_rate->getCode() ?>"<?php if($_rate->getCode()===$this->getAddressShippingMethod()) echo ' checked="checked"' ?> class="radio" />
76
+ <label for="s_method_<?php echo $_rate->getCode() ?>"><?php echo $_rate->getMethodTitle() ?>
77
+ <?php $_excl = $this->getShippingPrice($_rate->getPrice(), $this->helper('tax')->displayShippingPriceIncludingTax()); ?>
78
+ <?php $_incl = $this->getShippingPrice($_rate->getPrice(), true); ?>
79
+ <?php echo $_excl; ?>
80
+ <?php if ($this->helper('tax')->displayShippingBothPrices() && $_incl != $_excl): ?>
81
+ (<?php echo $this->__('Incl. Tax'); ?> <?php echo $_incl; ?>)
82
+ <?php endif; ?>
83
+ </label>
84
+ <?php endif ?>
85
+ </li>
86
+ <?php endforeach; ?>
87
+ </ul>
88
+ </dd>
89
+ <?php endforeach; ?>
90
+ </dl>
91
+ <div class="buttons-set">
92
+ <button type="submit" title="<?php echo $this->__('Update Total') ?>" class="button" name="do" value="<?php echo $this->__('Update Total') ?>"><span><span><?php echo $this->__('Update Total') ?></span></span></button>
93
+ </div>
94
+ </form>
95
+ <?php endif; ?>
96
+ <script type="text/javascript">
97
+ //<![CDATA[
98
+ var coShippingMethodForm = new VarienForm('shipping-zip-form');
99
+ var countriesWithOptionalZip = <?php echo $this->helper('directory')->getCountriesWithOptionalZip(true) ?>;
100
+
101
+ coShippingMethodForm.submit = function () {
102
+ var country = $F('country');
103
+ var optionalZip = false;
104
+
105
+ for (i=0; i < countriesWithOptionalZip.length; i++) {
106
+ if (countriesWithOptionalZip[i] == country) {
107
+ optionalZip = true;
108
+ }
109
+ }
110
+ if (optionalZip) {
111
+ $('postcode').removeClassName('required-entry');
112
+ }
113
+ else {
114
+ $('postcode').addClassName('required-entry');
115
+ }
116
+ return VarienForm.prototype.submit.bind(coShippingMethodForm)();
117
+ }
118
+ //]]>
119
+ </script>
120
+ </div>
121
+ </div>
122
+ <script type="text/javascript">
123
+ //<[CDATA[
124
+ var shipping_estimator_url = '<?php echo $this->getUrl('etemando/pcs/autocompletecart', array('_secure' => Mage::app()->getStore()->isCurrentlySecure())); ?>';
125
+ var avs = new Avs(
126
+ shipping_estimator_url,
127
+ 'postcode',
128
+ 'city',
129
+ 'country'
130
+ );
131
+ //]]>
132
+ </script>
app/design/frontend/base/default/template/temando/temando/customer/address/edit.phtml ADDED
@@ -0,0 +1,175 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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) 2012 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
28
+ /**
29
+ * Edit customer address template
30
+ *
31
+ * @see Mage_Customer_Block_Address_Edit
32
+ */
33
+ ?>
34
+ <?php if($this->getTitle()): ?>
35
+ <div class="page-title">
36
+ <h1><?php echo $this->getTitle() ?></h1>
37
+ </div>
38
+ <?php endif; ?>
39
+ <?php echo $this->getMessagesBlock()->getGroupedHtml() ?>
40
+ <form action="<?php echo $this->getSaveUrl() ?>" method="post" id="form-validate">
41
+ <div class="fieldset">
42
+ <?php echo $this->getBlockHtml('formkey')?>
43
+ <input type="hidden" name="success_url" value="<?php echo $this->getSuccessUrl() ?>" />
44
+ <input type="hidden" name="error_url" value="<?php echo $this->getErrorUrl() ?>" />
45
+ <h2 class="legend"><?php echo $this->__('Contact Information') ?></h2>
46
+ <ul class="form-list">
47
+ <li class="fields">
48
+ <?php echo $this->getNameBlockHtml() ?>
49
+ </li>
50
+ <li class="wide">
51
+ <label for="company"><?php echo $this->__('Company') ?></label>
52
+ <div class="input-box">
53
+ <input type="text" name="company" id="company" title="<?php echo $this->__('Company') ?>" value="<?php echo $this->escapeHtml($this->getAddress()->getCompany()) ?>" class="input-text <?php echo $this->helper('customer/address')->getAttributeValidationClass('company') ?>" />
54
+ </div>
55
+ </li>
56
+ <li class="fields">
57
+ <div class="field">
58
+ <label for="telephone" class="required"><em>*</em><?php echo $this->__('Telephone') ?></label>
59
+ <div class="input-box">
60
+ <input type="text" name="telephone" value="<?php echo $this->escapeHtml($this->getAddress()->getTelephone()) ?>" title="<?php echo $this->__('Telephone') ?>" class="input-text <?php echo $this->helper('customer/address')->getAttributeValidationClass('telephone') ?>" id="telephone" />
61
+ </div>
62
+ </div>
63
+ <div class="field">
64
+ <label for="fax"><?php echo $this->__('Fax') ?></label>
65
+ <div class="input-box">
66
+ <input type="text" name="fax" id="fax" title="<?php echo $this->__('Fax') ?>" value="<?php echo $this->escapeHtml($this->getAddress()->getFax()) ?>" class="input-text <?php echo $this->helper('customer/address')->getAttributeValidationClass('fax') ?>" />
67
+ </div>
68
+ </div>
69
+ </li>
70
+ </ul>
71
+ </div>
72
+ <div class="fieldset">
73
+ <h2 class="legend"><?php echo $this->__('Address') ?></h2>
74
+ <ul class="form-list">
75
+ <?php $_streetValidationClass = $this->helper('customer/address')->getAttributeValidationClass('street'); ?>
76
+ <li class="wide">
77
+ <label for="street_1" class="required"><em>*</em><?php echo $this->__('Street Address') ?></label>
78
+ <div class="input-box">
79
+ <input type="text" name="street[]" value="<?php echo $this->escapeHtml($this->getAddress()->getStreet(1)) ?>" title="<?php echo $this->__('Street Address') ?>" id="street_1" class="input-text <?php echo $_streetValidationClass ?>" />
80
+ </div>
81
+ </li>
82
+ <?php $_streetValidationClass = trim(str_replace('required-entry', '', $_streetValidationClass)); ?>
83
+ <?php for ($_i = 2, $_n = $this->helper('customer/address')->getStreetLines(); $_i <= $_n; $_i++): ?>
84
+ <li class="wide">
85
+ <div class="input-box">
86
+ <input type="text" name="street[]" value="<?php echo $this->escapeHtml($this->getAddress()->getStreet($_i)) ?>" title="<?php echo $this->__('Street Address %s', $_i) ?>" id="street_<?php echo $_i ?>" class="input-text <?php echo $_streetValidationClass ?>" />
87
+ </div>
88
+ </li>
89
+ <?php endfor; ?>
90
+ <?php if ($this->helper('customer/address')->isVatAttributeVisible()) : ?>
91
+ <li class="wide">
92
+ <label for="vat_id"><?php echo $this->__('VAT Number') ?></label>
93
+ <div class="input-box">
94
+ <input type="text" name="vat_id" value="<?php echo $this->escapeHtml($this->getAddress()->getVatId()) ?>" title="<?php echo $this->__('VAT Number') ?>" id="vat_id" class="input-text <?php echo $this->helper('customer/address')->getAttributeValidationClass('vat_id') ?>" />
95
+ </div>
96
+ </li>
97
+ <?php endif; ?>
98
+ <li class="fields">
99
+ <div class="field">
100
+ <label for="city" class="required"><em>*</em><?php echo $this->__('City') ?></label>
101
+ <div class="input-box">
102
+ <input type="text" name="city" value="<?php echo $this->escapeHtml($this->getAddress()->getCity()) ?>" title="<?php echo $this->__('City') ?>" class="input-text <?php echo $this->helper('customer/address')->getAttributeValidationClass('city') ?>" id="city" />
103
+ </div>
104
+ </div>
105
+ <div class="field">
106
+ <label for="region_id" class="required"><em>*</em><?php echo $this->__('State/Province') ?></label>
107
+ <div class="input-box">
108
+ <select id="region_id" name="region_id" title="<?php echo $this->__('State/Province') ?>" class="validate-select" style="display:none;">
109
+ <option value=""><?php echo $this->__('Please select region, state or province') ?></option>
110
+ </select>
111
+ <script type="text/javascript">
112
+ //<![CDATA[
113
+ $('region_id').setAttribute('defaultValue', "<?php echo $this->getAddress()->getRegionId() ?>");
114
+ //]]>
115
+ </script>
116
+ <input type="text" id="region" name="region" value="<?php echo $this->escapeHtml($this->getAddress()->getRegion()) ?>" title="<?php echo $this->__('State/Province') ?>" class="input-text <?php echo $this->helper('customer/address')->getAttributeValidationClass('region') ?>" />
117
+ </div>
118
+ </div>
119
+ </li>
120
+ <li class="fields">
121
+ <div class="field">
122
+ <label for="zip" class="required"><em>*</em><?php echo $this->__('Zip/Postal Code') ?></label>
123
+ <div class="input-box">
124
+ <input type="text" name="postcode" value="<?php echo $this->escapeHtml($this->getAddress()->getPostcode()) ?>" title="<?php echo $this->__('Zip/Postal Code') ?>" id="zip" class="input-text validate-zip-international <?php echo $this->helper('customer/address')->getAttributeValidationClass('postcode') ?>" />
125
+ </div>
126
+ </div>
127
+ <div class="field">
128
+ <label for="country" class="required"><em>*</em><?php echo $this->__('Country') ?></label>
129
+ <div class="input-box">
130
+ <?php echo $this->getCountryHtmlSelect() ?>
131
+ </div>
132
+ </div>
133
+ </li>
134
+ <li<?php if($this->canSetAsDefaultBilling()) echo ' class="control"' ?>>
135
+ <?php if($this->isDefaultBilling()): ?>
136
+ <strong><?php echo $this->__('Default Billing Address') ?></strong>
137
+ <?php elseif($this->canSetAsDefaultBilling()): ?>
138
+ <input type="checkbox" id="primary_billing" name="default_billing" value="1" title="<?php echo $this->__('Use as My Default Billing Address') ?>" class="checkbox" /><label for="primary_billing"><?php echo $this->__('Use as my default billing address') ?></label>
139
+ <?php else: ?>
140
+ <input type="hidden" name="default_billing" value="1" />
141
+ <?php endif; ?>
142
+ </li>
143
+ <li<?php if($this->canSetAsDefaultShipping()) echo ' class="control"' ?>>
144
+ <?php if($this->isDefaultShipping()): ?>
145
+ <strong><?php echo $this->__('Default Shipping Address') ?></strong>
146
+ <?php elseif($this->canSetAsDefaultShipping()): ?>
147
+ <input type="checkbox" id="primary_shipping" name="default_shipping" value="1" title="<?php echo $this->__('Use as My Default Shipping Address') ?>" class="checkbox" /><label for="primary_shipping"><?php echo $this->__('Use as my default shipping address') ?></label>
148
+ <?php else: ?>
149
+ <input type="hidden" name="default_shipping" value="1" />
150
+ <?php endif; ?>
151
+ </li>
152
+ </ul>
153
+ </div>
154
+ <div class="buttons-set">
155
+ <p class="required"><?php echo $this->__('* Required Fields') ?></p>
156
+ <p class="back-link"><a href="<?php echo $this->escapeUrl($this->getBackUrl()) ?>"><small>&laquo; </small><?php echo $this->__('Back') ?></a></p>
157
+ <button type="submit" title="<?php echo $this->__('Save Address') ?>" class="button"><span><span><?php echo $this->__('Save Address') ?></span></span></button>
158
+ </div>
159
+ </form>
160
+ <script type="text/javascript">
161
+ //<![CDATA[
162
+ var dataForm = new VarienForm('form-validate', true);
163
+ new RegionUpdater('country', 'region', 'region_id', <?php echo $this->helper('directory')->getRegionJson() ?>, undefined, 'zip');
164
+ //]]>
165
+ </script>
166
+ <script type="text/javascript">
167
+ //<![CDATA[
168
+ new Avs(
169
+ "<?php echo $this->getUrl('etemando/pcs/autocompletecart', array('_secure' => Mage::app()->getStore()->isCurrentlySecure())); ?>",
170
+ 'zip',
171
+ 'city',
172
+ 'country'
173
+ );
174
+ //]]>
175
+ </script>
app/design/frontend/base/default/template/temando/temando/onestep/options.phtml ADDED
@@ -0,0 +1,85 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /* @var $this Temando_Temando_Block_Onepage_Shipping_Method_Available_Single */
3
+ $_rates = $this->getTemandoShippingRates();
4
+ $_options = $this->getOptions();
5
+ $sole = $this->getSole();
6
+ ?>
7
+
8
+ <?php foreach ($_rates as $_rate): ?>
9
+ <dt style="margin-bottom: 5px;">
10
+
11
+ <?php if ($_rate->getErrorMessage()): ?>
12
+ <ul class="messages"><li class="error-msg"><ul><li><?php echo $_rate->getErrorMessage() ?></li></ul></li></ul>
13
+ <?php else: ?>
14
+ <input name="shipping_method" type="radio" value="<?php echo $_rate->getCode() ?>" id="s_method_<?php echo $_rate->getCode() ?>" class="validate-one-required-by-name <?php echo $this->getClassFromRateCode($_rate->getCode())?>"<?php if($sole) echo ' checked="checked"' ?>/>
15
+ <label for="s_method_<?php echo $_rate->getCode() ?>"><!--<b><?php echo $this->getCarrierName(Temando_Temando_Model_Hybrid::CARRIER_CODE) ?>:</b>--> <?php echo $_rate->getMethodTitle() ?>
16
+ <strong>
17
+ <?php $_excl = $this->getShippingPrice($_rate->getPrice(), $this->helper('tax')->displayShippingPriceIncludingTax()); ?>
18
+ <?php $_incl = $this->getShippingPrice($_rate->getPrice(), true); ?>
19
+
20
+ <?php echo $_excl; ?>
21
+ <?php if ($this->helper('tax')->displayShippingBothPrices() && $_incl != $_excl): ?>
22
+ (<?php echo $this->__('Incl. Tax'); ?> <?php echo $_incl; ?>)
23
+ <?php endif; ?>
24
+ </strong>
25
+ </label>
26
+ <?php endif ?>
27
+ </dt>
28
+ <?php endforeach; ?>
29
+ <div id="temando_checkboxes">
30
+ <br />
31
+ <table class='insurance'>
32
+ <tr>
33
+ <?php foreach($_options as $_option_id => $_option): ?>
34
+ <?php /* @var $_option Temando_Temando_Model_Option_Abstract */ ?>
35
+ <?php if ($_option instanceof Temando_Temando_Model_Option_Boolean): ?>
36
+ <?php if ($_option->getForcedValue() === Temando_Temando_Model_Option_Boolean::NO): ?>
37
+ <td class='c1' style="display: none;">
38
+ <?php else : ?>
39
+ <td class='c1'>
40
+ <?php endif; ?>
41
+ <input
42
+ type="checkbox"
43
+ <?php if ($_option->getForcedValue() !== Temando_Temando_Model_Option_Boolean::NO): ?>
44
+ checked="checked"
45
+ <?php endif; ?>
46
+ id="temando_checkbox_<?php echo $_option_id; ?>"
47
+ <?php if ($_option->getForcedValue() === Temando_Temando_Model_Option_Boolean::YES): ?>
48
+ disabled="disabled"
49
+ <?php endif; ?>
50
+ class="checkbox"
51
+ />
52
+ <label for="temando_checkbox_<?php echo $_option_id; ?>">
53
+ <?php echo $_option->getName(); ?>
54
+ </label>
55
+ <?php endif; ?>
56
+ </td>
57
+ <?php endforeach; ?>
58
+ </tr>
59
+ <tr>
60
+ <?php foreach($this->getOptions() as $_option_id => $_option): ?>
61
+ <?php /* @var $_option Temando_Temando_Model_Option_Abstract */ ?>
62
+ <?php if ($_option instanceof Temando_Temando_Model_Option_Boolean): ?>
63
+ <?php if ($_option->getForcedValue() === Temando_Temando_Model_Option_Boolean::NO): ?>
64
+ <td class='c2' style="display: none;">
65
+ <?php else : ?>
66
+ <td class='c2'>
67
+ <?php endif; ?>
68
+ <?php echo $_option->getDescription(); ?>
69
+ <?php endif; ?>
70
+ </td>
71
+ <?php endforeach; ?>
72
+ </tr>
73
+ </table>
74
+ </div>
75
+ <script type="text/javascript">
76
+ //<![CDATA[
77
+ $$('#temando_checkboxes input[type=checkbox]').each(function (control) {
78
+ Event.observe(control, 'click', function () {
79
+ option_update_onestep(control);
80
+ })
81
+ });
82
+ // Hide Temando quotes that don't match the checked options
83
+ option_update_onestep();
84
+ //]]>
85
+ </script>
app/design/frontend/base/default/template/temando/temando/onestep/shipping_method.phtml ADDED
@@ -0,0 +1,66 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /* @var $this Temando_Temando_Block_Onepage_Shipping_Method_Available_Single */
3
+ $sole = $this->getSole();
4
+ ?>
5
+
6
+ <?php if (!($_shippingRateGroups = $this->getShippingRates())): ?>
7
+ <strong><?php echo $this->__('Sorry, no quotes are available for this order at this time.') ?></strong>
8
+ <?php else: ?>
9
+ <?php if (count($_shippingRateGroups)=='1' && Mage::getStoreConfig('onestepcheckout/general/hide_shipping_method')):?>
10
+ <dl class="shipment-methods" style="display: none">
11
+ <?php foreach ($_shippingRateGroups as $code => $_rates): ?>
12
+ <dd><?php echo $this->getCarrierName($code) ?></dd>
13
+ <?php foreach ($_rates as $_rate): ?>
14
+ <dt style="margin-bottom: 5px;">
15
+ <?php if ($_rate->getErrorMessage()): ?>
16
+ <ul class="messages"><li class="error-msg"><ul><li><?php echo $_rate->getErrorMessage() ?></li></ul></li></ul>
17
+ <?php else: ?>
18
+ <input name="shipping_method" type="radio" value="<?php echo $_rate->getCode() ?>" id="s_method_<?php echo $_rate->getCode() ?>" checked="checked" />
19
+ <label for="s_method_<?php echo $_rate->getCode() ?>"><!--<b><?php echo $this->getCarrierName($code) ?>:</b>--> <?php echo $_rate->getMethodTitle() ?>
20
+ <strong>
21
+ <?php $_excl = $this->getShippingPrice($_rate->getPrice(), $this->helper('tax')->displayShippingPriceIncludingTax()); ?>
22
+ <?php $_incl = $this->getShippingPrice($_rate->getPrice(), true); ?>
23
+ <?php echo $_excl; ?>
24
+ <?php if ($this->helper('tax')->displayShippingBothPrices() && $_incl != $_excl): ?>
25
+ (<?php echo $this->__('Incl. Tax'); ?> <?php echo $_incl; ?>)
26
+ <?php endif; ?>
27
+ </strong>
28
+ </label>
29
+ <?php endif ?>
30
+ </dt>
31
+ <?php endforeach; ?>
32
+ <?php endforeach; ?>
33
+ </dl>
34
+ <?php else: ?>
35
+ <dl class="shipment-methods">
36
+ <?php foreach ($_shippingRateGroups as $code => $_rates): ?>
37
+ <dd><?php echo $this->getCarrierName($code) ?></dd>
38
+ <?php if($code == Temando_Temando_Model_Hybrid::CARRIER_CODE): ?>
39
+ <?php echo $this->getChildHtml('options') ?>
40
+ <?php else: ?>
41
+ <?php foreach ($_rates as $_rate): ?>
42
+ <dt style="margin-bottom: 5px;">
43
+
44
+ <?php if ($_rate->getErrorMessage()): ?>
45
+ <ul class="messages"><li class="error-msg"><ul><li><?php echo $_rate->getErrorMessage() ?></li></ul></li></ul>
46
+ <?php else: ?>
47
+ <input name="shipping_method" type="radio" class="validate-one-required-by-name" value="<?php echo $_rate->getCode() ?>" id="s_method_<?php echo $_rate->getCode() ?>"<?php if($_rate->getCode()===$this->getAddressShippingMethod() || $sole) echo ' checked="checked"' ?> />
48
+ <label for="s_method_<?php echo $_rate->getCode() ?>"><!--<b><?php echo $this->getCarrierName($code) ?>:</b>--> <?php echo $_rate->getMethodTitle() ?>
49
+ <strong>
50
+ <?php $_excl = $this->getShippingPrice($_rate->getPrice(), $this->helper('tax')->displayShippingPriceIncludingTax()); ?>
51
+ <?php $_incl = $this->getShippingPrice($_rate->getPrice(), true); ?>
52
+
53
+ <?php echo $_excl; ?>
54
+ <?php if ($this->helper('tax')->displayShippingBothPrices() && $_incl != $_excl): ?>
55
+ (<?php echo $this->__('Incl. Tax'); ?> <?php echo $_incl; ?>)
56
+ <?php endif; ?>
57
+ </strong>
58
+ </label>
59
+ <?php endif ?>
60
+ </dt>
61
+ <?php endforeach; ?>
62
+ <?php endif; ?>
63
+ <?php endforeach; ?>
64
+ </dl>
65
+ <?php endif; ?>
66
+ <?php endif; ?>
app/design/frontend/base/default/template/temando/temando/pcs.phtml ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <script type="text/javascript">
2
+
3
+ <?php if (Mage::getStoreConfig('carriers/temando/active')): ?>
4
+ new Avs(
5
+ "<?php echo $this->getUrl('etemando/pcs/autocompletecart', array('_secure' => Mage::app()->getStore()->isCurrentlySecure())); ?>",
6
+ 'billing:postcode',
7
+ 'billing:city',
8
+ 'billing:country_id'
9
+ );
10
+
11
+ new Avs(
12
+ "<?php echo $this->getUrl('etemando/pcs/autocompletecart', array('_secure' => Mage::app()->getStore()->isCurrentlySecure())); ?>",
13
+ 'shipping:postcode',
14
+ 'shipping:city',
15
+ 'shipping:country_id'
16
+ );
17
+ <?php endif;?>
18
+
19
+ </script>
app/design/frontend/base/default/template/temando/temando/product/shipping.phtml ADDED
@@ -0,0 +1,53 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php if (Mage::getStoreConfig('carriers/temando/active') && Mage::helper('temando')->getConfigData('options/show_product_estimate')): ?>
2
+ <div class="block block-shipping">
3
+ <div class="block-title">
4
+ <strong><span><?php echo $this->__('Estimate Shipping') ?></span></strong>
5
+ </div>
6
+ <div class="block-content">
7
+ <div class='estimate-form'>
8
+ <form action="" name="estimate_form" method="post" onsubmit="javascript: return false;">
9
+ <ul>
10
+ <li class="fields">
11
+ <div class="city-container">
12
+ <label for="city"><?php echo $this->__('Suburb/City'); ?></label>
13
+ <input type='text' name='city' id='city' value='<?php echo $this->getCity(); ?>' class="input-text" />
14
+ </div>
15
+ </li>
16
+ <li class="fields">
17
+ <div class="postcode-container">
18
+ <label for="postcode"><?php echo $this->__('Postal Code'); ?></label>
19
+ <input type='text' name='postcode' id='postcode' value='<?php echo $this->getPostcode(); ?>' class="input-text" />
20
+ </div>
21
+ </li>
22
+ <li class="fields">
23
+ <label for="country_id"><?php echo $this->__('Country'); ?></label>
24
+ <select id="country_id" name="country_id">
25
+ <?php foreach($this->getCountryOptions() as $code => $name): ?>
26
+ <option value="<?php echo $code ?>"><?php echo $name ?></option>
27
+ <?php endforeach; ?>
28
+ </select>
29
+ </li>
30
+ </ul>
31
+ <input type='hidden' name='product_id' id='product_id' value='<?php echo $this->getProductId(); ?>' />
32
+ <input type='hidden' name='options' id='options' value='<?php echo $this->getOptions(); ?>' />
33
+ <div class='estimate-button'>
34
+ <button type="button" title="<?php echo $this->__('Get a Quote'); ?>" class="button" onclick="getShippingRates()">
35
+ <span>
36
+ <span><?php echo $this->__('Get a Quote'); ?></span>
37
+ </span>
38
+ </button>
39
+ </div>
40
+ <div id='estimate_items'>
41
+ </div>
42
+ </form>
43
+ </div>
44
+ </div>
45
+ </div>
46
+ <script type="text/javascript">
47
+ //<![CDATA[
48
+ var shipping_estimator_url = '<?php echo $this->getUrl('etemando/pcs/product', array('_secure' => Mage::app()->getStore()->isCurrentlySecure())); ?>';
49
+ var avs_url = '<?php echo $this->getUrl('etemando/pcs/autocompletecart', array('_secure' => Mage::app()->getStore()->isCurrentlySecure())); ?>';
50
+ var avs = new Avs( avs_url, 'postcode', 'city', 'country_id');
51
+ //]]>
52
+ </script>
53
+ <?php endif; ?>
app/design/frontend/base/default/template/temando/temando/product/shipping/methods.phtml ADDED
@@ -0,0 +1,27 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php if (($_shippingRateGroups = $this->getEstimateRates())): ?>
2
+ <?php Mage::log($_shippingRateGroups, null, 'temando.log', true); ?>
3
+ <dl class="sp-methods">
4
+ <?php foreach ($_shippingRateGroups as $code => $_rates): ?>
5
+ <dt><?php echo $this->getCarrierName($code) ?></dt>
6
+ <dd>
7
+ <ul>
8
+ <?php foreach ($_rates->getAllRates() as $_rate): ?>
9
+ <li<?php if ($_rate->getErrorMessage()) echo ' class="error-msg"';?>>
10
+ <?php if ($_rate->getErrorMessage()): ?>
11
+ <?php echo $_rate->getErrorMessage() ?>
12
+ <?php else: ?>
13
+ <label for="s_method_<?php echo $_rate->getCode() ?>"><?php echo $_rate->getMethodTitle() ?>
14
+ <?php $_excl = $this->formatPrice($_rate->getPrice()); ?>
15
+ <?php echo $_excl; ?>
16
+ <?php /* if ($this->helper('tax')->displayShippingBothPrices() && $_incl != $_excl): ?>
17
+ (<?php echo $this->__('Incl. Tax'); ?> <?php echo $_incl; ?>)
18
+ <?php endif; */ ?>
19
+ </label>
20
+ <?php endif ?>
21
+ </li>
22
+ <?php endforeach; ?>
23
+ </ul>
24
+ </dd>
25
+ <?php endforeach; ?>
26
+ </dl>
27
+ <?php endif; ?>
app/design/frontend/base/default/template/temando/temando/shipping_method/available.phtml ADDED
@@ -0,0 +1,2 @@
 
 
1
+ <?php /*@var $this Temando_Temando_Block_Onepage_Shipping_Method_Available */ ?>
2
+ <?php echo $this->getChildHtml('options_single'); ?>
app/design/frontend/base/default/template/temando/temando/shipping_method/available/options_single.phtml ADDED
@@ -0,0 +1,108 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /* @var $this Temando_Temando_Block_Onepage_Shipping_Method_Available_Single */
3
+ $_options = $this->getOptions();
4
+ $_sole = $this->getSole();
5
+ $shippingMe = array();
6
+ ?>
7
+ <?php if (!($_shippingRateGroups = $this->getShippingRates())): ?>
8
+ <p><?php echo $this->__('Sorry, no quotes are available for this order at this time.') ?></p>
9
+ <?php else: ?>
10
+
11
+ <dl class="sp-methods">
12
+ <?php foreach ($_shippingRateGroups as $code => $_rates): ?>
13
+ <dt><?php echo $this->getCarrierName($code) ?></dt>
14
+ <dd>
15
+ <ul>
16
+ <?php foreach ($_rates as $_rate): ?>
17
+ <?php $shippingMe[] = "'".$_rate->getCode()."':".(float)$_rate->getPrice(); ?>
18
+ <li>
19
+ <?php if ($_rate->getErrorMessage()): ?>
20
+ <ul class="messages"><li class="error-msg"><ul><li><?php echo $_rate->getErrorMessage() ?></li></ul></li></ul>
21
+ <?php else: ?>
22
+ <?php if ($_sole) : ?>
23
+ <span class="no-display"><input name="shipping_method" type="radio" value="<?php echo $_rate->getCode() ?>" id="s_method_<?php echo $_rate->getCode() ?>" checked="checked" /></span>
24
+ <?php else: ?>
25
+ <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 <?php echo $this->getClassFromRateCode($_rate->getCode())?>" onchange="return includingShipping('<?php echo $_rate->getCode();?>');"/>
26
+ <?php if ($_rate->getCode()===$this->getAddressShippingMethod()): ?>
27
+ <script type="text/javascript">
28
+ //<![CDATA[
29
+ lastPrice = <?php echo (float)$_rate->getPrice(); ?>;
30
+ //]]>
31
+ </script>
32
+ <?php endif; ?>
33
+ <?php endif; ?>
34
+ <label for="s_method_<?php echo $_rate->getCode() ?>"><?php echo $_rate->getMethodTitle() ?>
35
+ <?php $_excl = $this->getShippingPrice($_rate->getPrice(), $this->helper('tax')->displayShippingPriceIncludingTax()); ?>
36
+ <?php $_incl = $this->getShippingPrice($_rate->getPrice(), true); ?>
37
+ <?php echo $_excl; ?>
38
+ <?php if ($this->helper('tax')->displayShippingBothPrices() && $_incl != $_excl): ?>
39
+ (<?php echo $this->__('Incl. Tax'); ?> <?php echo $_incl; ?>)
40
+ <?php endif; ?>
41
+ </label>
42
+ <?php endif; ?>
43
+ </li>
44
+ <?php endforeach; ?>
45
+ <?php if($code == 'temando'): ?>
46
+ <div id="temando_checkboxes">
47
+ <br />
48
+ <table class='insurance'>
49
+ <tr>
50
+ <?php foreach($_options as $_option_id => $_option): ?>
51
+ <?php /* @var $_option Temando_Temando_Model_Option_Abstract */ ?>
52
+ <?php if ($_option instanceof Temando_Temando_Model_Option_Boolean): ?>
53
+ <?php if ($_option->getForcedValue() === Temando_Temando_Model_Option_Boolean::NO): ?>
54
+ <td class='c1' style="display: none;">
55
+ <?php else : ?>
56
+ <td class='c1'>
57
+ <?php endif; ?>
58
+ <input
59
+ type="checkbox"
60
+ <?php if ($_option->getForcedValue() !== Temando_Temando_Model_Option_Boolean::NO): ?>
61
+ checked="checked"
62
+ <?php endif; ?>
63
+ id="temando_checkbox_<?php echo $_option_id; ?>"
64
+ <?php if ($_option->getForcedValue() === Temando_Temando_Model_Option_Boolean::YES): ?>
65
+ disabled="disabled"
66
+ <?php endif; ?>
67
+ class="checkbox"
68
+ />
69
+ <label for="temando_checkbox_<?php echo $_option_id; ?>">
70
+ <?php echo $_option->getName(); ?>
71
+ </label>
72
+ <?php endif; ?>
73
+ </td>
74
+ <?php endforeach; ?>
75
+ </tr>
76
+ <tr>
77
+ <?php foreach($_options as $_option_id => $_option): ?>
78
+ <?php /* @var $_option Temando_Temando_Model_Option_Abstract */ ?>
79
+ <?php if ($_option instanceof Temando_Temando_Model_Option_Boolean): ?>
80
+ <?php if ($_option->getForcedValue() === Temando_Temando_Model_Option_Boolean::NO): ?>
81
+ <td class='c2' style="display: none;">
82
+ <?php else : ?>
83
+ <td class='c2'>
84
+ <?php endif; ?>
85
+ <?php echo $_option->getDescription(); ?>
86
+ <?php endif; ?>
87
+ </td>
88
+ <?php endforeach; ?>
89
+ </tr>
90
+ </table>
91
+ </div>
92
+ <script type="text/javascript">
93
+ //<![CDATA[
94
+ $$('#temando_checkboxes input[type=checkbox]').each(function (control) {
95
+ Event.observe(control, 'click', function () {
96
+ option_update(<?php echo $_sole ? 'true' : 'false' ?>);
97
+ })
98
+ });
99
+ // Hide Temando quotes that don't match the checked options
100
+ option_update(<?php echo $_sole ? 'true' : 'false' ?>);
101
+ //]]>
102
+ </script>
103
+ <?php endif; ?>
104
+ </ul>
105
+ </dd>
106
+ <?php endforeach; ?>
107
+ </dl>
108
+ <?php endif; ?>
app/etc/modules/Temando_Temando.xml ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <config>
3
+ <modules>
4
+ <Temando_Temando>
5
+ <active>true</active>
6
+ <codePool>community</codePool>
7
+ </Temando_Temando>
8
+ </modules>
9
+ </config>
js/temando/autocomplete.js ADDED
@@ -0,0 +1,338 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+ *
3
+ * Ajax Autocomplete for Prototype, version 1.0.4
4
+ * (c) 2010 Tomas Kirda
5
+ *
6
+ * Ajax Autocomplete for Prototype is freely distributable under the terms of an MIT-style license.
7
+ * For details, see the web site: http://www.devbridge.com/projects/autocomplete/
8
+ *
9
+ */
10
+
11
+ var Autocomplete = function(el, options){
12
+ this.el = $(el);
13
+ this.id = this.el.identify();
14
+ this.el.setAttribute('autocomplete','off');
15
+ this.suggestions = [];
16
+ this.data = [];
17
+ this.badQueries = [];
18
+ this.selectedIndex = -1;
19
+ this.currentValue = this.el.value;
20
+ this.intervalId = 0;
21
+ this.cachedResponse = [];
22
+ this.instanceId = null;
23
+ this.onChangeInterval = null;
24
+ this.ignoreValueChange = false;
25
+ this.serviceUrl = options.serviceUrl;
26
+ this.options = {
27
+ autoSubmit:false,
28
+ minChars:1,
29
+ maxHeight:300,
30
+ deferRequestBy:300,
31
+ width:200,
32
+ container:null
33
+ };
34
+ this.countryEl = options.countryEl;
35
+ if(options){ Object.extend(this.options, options); }
36
+ if(Autocomplete.isDomLoaded){
37
+ this.initialize();
38
+ }else{
39
+ Event.observe(document, 'dom:loaded', this.initialize.bind(this), false);
40
+ }
41
+ };
42
+
43
+ Autocomplete.instances = [];
44
+ Autocomplete.isDomLoaded = false;
45
+
46
+ Autocomplete.getInstance = function(id){
47
+ var instances = Autocomplete.instances;
48
+ var i = instances.length;
49
+ while(i--){ if(instances[i].id === id){ return instances[i]; }}
50
+ };
51
+
52
+ Autocomplete.highlight = function(value, re){
53
+ return value.replace(re, function(match){ return '<strong>' + match + '<\/strong>' });
54
+ };
55
+
56
+ Autocomplete.prototype = {
57
+
58
+ killerFn: null,
59
+
60
+ initialize: function() {
61
+ var me = this;
62
+ this.killerFn = function(e) {
63
+ if (!$(Event.element(e)).up('.autocomplete')) {
64
+ me.killSuggestions();
65
+ me.disableKillerFn();
66
+ this.onAway();
67
+ }
68
+ } .bindAsEventListener(this);
69
+
70
+ if (!this.options.width) { this.options.width = this.el.getWidth(); }
71
+
72
+ var div = new Element('div', { style: 'position:absolute;' });
73
+ div.update('<div class="autocomplete-w1"><div class="autocomplete-w2"><div class="autocomplete" id="Autocomplete_' + this.id + '" style="display:none; width:' + this.options.width + 'px;"></div></div></div>');
74
+
75
+ this.options.container = $(this.options.container);
76
+ if (this.options.container) {
77
+ this.options.container.appendChild(div);
78
+ this.fixPosition = function() { };
79
+ } else {
80
+ document.body.appendChild(div);
81
+ }
82
+
83
+ this.mainContainerId = div.identify();
84
+ this.container = $('Autocomplete_' + this.id);
85
+ this.fixPosition();
86
+
87
+ Event.observe(this.el, window.opera ? 'keypress':'keydown', this.onKeyPress.bind(this));
88
+ Event.observe(this.el, 'keyup', this.onKeyUp.bind(this));
89
+ Event.observe(this.el, 'blur', this.enableKillerFn.bind(this));
90
+ Event.observe(this.el, 'focus', this.fixPosition.bind(this));
91
+ this.container.setStyle({ maxHeight: this.options.maxHeight + 'px' });
92
+ this.instanceId = Autocomplete.instances.push(this) - 1;
93
+ },
94
+
95
+ fixPosition: function() {
96
+ var offset = this.el.cumulativeOffset();
97
+ $(this.mainContainerId).setStyle({ top: (offset.top + this.el.getHeight()) + 'px', left: offset.left + 'px' });
98
+ },
99
+
100
+ enableKillerFn: function() {
101
+ Event.observe(document.body, 'click', this.killerFn);
102
+ },
103
+
104
+ disableKillerFn: function() {
105
+ Event.stopObserving(document.body, 'click', this.killerFn);
106
+ },
107
+
108
+ killSuggestions: function() {
109
+ this.stopKillSuggestions();
110
+ this.intervalId = window.setInterval(function() { this.hide(); this.stopKillSuggestions(); } .bind(this), 300);
111
+ },
112
+
113
+ stopKillSuggestions: function() {
114
+ window.clearInterval(this.intervalId);
115
+ },
116
+
117
+ onKeyPress: function(e) {
118
+ if (!this.enabled) { return; }
119
+ // return will exit the function
120
+ // and event will not fire
121
+ switch (e.keyCode) {
122
+ case Event.KEY_ESC:
123
+ this.el.value = this.currentValue;
124
+ this.hide();
125
+ break;
126
+ case Event.KEY_TAB:
127
+ case Event.KEY_RETURN:
128
+ if (this.selectedIndex === -1) {
129
+ this.hide();
130
+ return;
131
+ }
132
+ this.select(this.selectedIndex);
133
+ if (e.keyCode === Event.KEY_TAB) { return; }
134
+ break;
135
+ case Event.KEY_UP:
136
+ this.moveUp();
137
+ break;
138
+ case Event.KEY_DOWN:
139
+ this.moveDown();
140
+ break;
141
+ default:
142
+ return;
143
+ }
144
+ Event.stop(e);
145
+ },
146
+
147
+ onKeyUp: function(e) {
148
+ switch (e.keyCode) {
149
+ case Event.KEY_UP:
150
+ case Event.KEY_DOWN:
151
+ return;
152
+ }
153
+ clearInterval(this.onChangeInterval);
154
+ if (this.currentValue !== this.el.value) {
155
+ if (this.options.deferRequestBy > 0) {
156
+ // Defer lookup in case when value changes very quickly:
157
+ this.onChangeInterval = setInterval((function() {
158
+ this.onValueChange();
159
+ }).bind(this), this.options.deferRequestBy);
160
+ } else {
161
+ this.onValueChange();
162
+ }
163
+ }
164
+ },
165
+
166
+ onValueChange: function() {
167
+ clearInterval(this.onChangeInterval);
168
+ this.currentValue = this.el.value;
169
+ this.selectedIndex = -1;
170
+ if (this.ignoreValueChange) {
171
+ this.ignoreValueChange = false;
172
+ return;
173
+ }
174
+ if (this.currentValue === '' || this.currentValue.length < this.options.minChars) {
175
+ this.hide();
176
+ } else {
177
+ this.getSuggestions();
178
+ }
179
+ },
180
+
181
+ getSuggestions: function() {
182
+ if(this.countryEl != null) {
183
+ var cr = this.cachedResponse[this.currentValue+$(this.countryEl).value];
184
+ } else {
185
+ var cr = this.cachedResponse[this.currentValue];
186
+ }
187
+ if (cr && Object.isArray(cr.suggestions)) {
188
+ this.suggestions = cr.suggestions;
189
+ this.data = cr.data;
190
+ this.suggest();
191
+ } else if (!this.isBadQuery(this.currentValue)) {
192
+ this.onLoadStart();
193
+ if(this.countryEl != null) {
194
+ new Ajax.Request(this.serviceUrl, {
195
+ parameters: { query: this.currentValue, country: $(this.countryEl).value },
196
+ onComplete: this.processResponse.bind(this),
197
+ method: 'get'
198
+ });
199
+ } else {
200
+ new Ajax.Request(this.serviceUrl, {
201
+ parameters: { query: this.currentValue },
202
+ onComplete: this.processResponse.bind(this),
203
+ method: 'get'
204
+ });
205
+ }
206
+ }
207
+ },
208
+
209
+ isBadQuery: function(q) {
210
+ var i = this.badQueries.length;
211
+ while (i--) {
212
+ if (q.indexOf(this.badQueries[i]) === 0) { return true; }
213
+ }
214
+ return false;
215
+ },
216
+
217
+ hide: function() {
218
+ this.enabled = false;
219
+ this.selectedIndex = -1;
220
+ this.container.hide();
221
+ },
222
+
223
+ suggest: function() {
224
+ if (this.suggestions.length === 0) {
225
+ this.hide();
226
+ return;
227
+ }
228
+ var content = [];
229
+ var re = new RegExp('\\b' + this.currentValue.match(/\w+/g).join('|\\b'), 'gi');
230
+ this.suggestions.each(function(value, i) {
231
+ content.push((this.selectedIndex === i ? '<div class="selected"' : '<div'), ' title="', value, '" onclick="Autocomplete.instances[', this.instanceId, '].select(', i, ');" onmouseover="Autocomplete.instances[', this.instanceId, '].activate(', i, ');">', Autocomplete.highlight(value, re), '</div>');
232
+ } .bind(this));
233
+ this.enabled = true;
234
+ this.container.update(content.join('')).show();
235
+ },
236
+
237
+ processResponse: function(xhr) {
238
+ this.onLoadComplete();
239
+ var response;
240
+ try {
241
+ response = xhr.responseText.evalJSON();
242
+ if (!Object.isArray(response.data)) { response.data = []; }
243
+ } catch (err) { return; }
244
+ if(this.countryEl != null) {
245
+ this.cachedResponse[response.query+$(this.countryEl).value] = response;
246
+ } else {
247
+ this.cachedResponse[response.query] = response;
248
+ }
249
+ if (response.suggestions.length === 0) { this.badQueries.push(response.query); }
250
+ if (response.query === this.currentValue) {
251
+ this.suggestions = response.suggestions;
252
+ this.data = response.data;
253
+ this.suggest();
254
+ }
255
+ },
256
+
257
+ activate: function(index) {
258
+ var divs = this.container.childNodes;
259
+ var activeItem;
260
+ // Clear previous selection:
261
+ if (this.selectedIndex !== -1 && divs.length > this.selectedIndex) {
262
+ divs[this.selectedIndex].className = '';
263
+ }
264
+ this.selectedIndex = index;
265
+ if (this.selectedIndex !== -1 && divs.length > this.selectedIndex) {
266
+ activeItem = divs[this.selectedIndex]
267
+ activeItem.className = 'selected';
268
+ }
269
+ return activeItem;
270
+ },
271
+
272
+ deactivate: function(div, index) {
273
+ div.className = '';
274
+ if (this.selectedIndex === index) { this.selectedIndex = -1; }
275
+ },
276
+
277
+ select: function(i) {
278
+ var selectedValue = this.suggestions[i];
279
+ if (selectedValue) {
280
+ this.el.value = selectedValue;
281
+ if (this.options.autoSubmit && this.el.form) {
282
+ this.el.form.submit();
283
+ }
284
+ this.ignoreValueChange = true;
285
+ this.hide();
286
+ this.onSelect(i);
287
+ }
288
+ },
289
+
290
+ moveUp: function() {
291
+ if (this.selectedIndex === -1) { return; }
292
+ if (this.selectedIndex === 0) {
293
+ this.container.childNodes[0].className = '';
294
+ this.selectedIndex = -1;
295
+ this.el.value = this.currentValue;
296
+ return;
297
+ }
298
+ this.adjustScroll(this.selectedIndex - 1);
299
+ },
300
+
301
+ moveDown: function() {
302
+ if (this.selectedIndex === (this.suggestions.length - 1)) { return; }
303
+ this.adjustScroll(this.selectedIndex + 1);
304
+ },
305
+
306
+ adjustScroll: function(i) {
307
+ var container = this.container;
308
+ var activeItem = this.activate(i);
309
+ var offsetTop = activeItem.offsetTop;
310
+ var upperBound = container.scrollTop;
311
+ var lowerBound = upperBound + this.options.maxHeight - 25;
312
+ if (offsetTop < upperBound) {
313
+ container.scrollTop = offsetTop;
314
+ } else if (offsetTop > lowerBound) {
315
+ container.scrollTop = offsetTop - this.options.maxHeight + 25;
316
+ }
317
+ this.el.value = this.suggestions[i];
318
+ },
319
+
320
+ onSelect: function(i) {
321
+ (this.options.onSelect || Prototype.emptyFunction)(this.suggestions[i], this.data[i], this.options);
322
+ },
323
+
324
+ onLoadStart: function() {
325
+ (this.options.onLoadStart || Prototype.emptyFunction)(this.options);
326
+ },
327
+
328
+ onLoadComplete: function() {
329
+ (this.options.onLoadComplete || Prototype.emptyFunction)(this.options);
330
+ },
331
+
332
+ onAway: function() {
333
+ (this.options.onAway || Prototype.emptyFunction)(this.options);
334
+ }
335
+
336
+ };
337
+
338
+ Event.observe(document, 'dom:loaded', function(){ Autocomplete.isDomLoaded = true; }, false);
js/temando/avs.js ADDED
@@ -0,0 +1,61 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ var Avs = Class.create();
2
+
3
+ Avs.prototype = {
4
+ initialize: function(service_url, pcode, suburb, country){
5
+ this.serviceUrl = service_url;
6
+ this.prepareAutocomplete(pcode, pcode, suburb, country);
7
+ this.prepareAutocomplete(suburb, pcode, suburb, country);
8
+ this.registerCountryListener(country, pcode);
9
+ },
10
+ prepareAutocomplete: function(el, pcode, suburb, country) {
11
+ if($(el)) {
12
+ new Autocomplete(el, {
13
+ serviceUrl: this.serviceUrl,
14
+ countryEl: country,
15
+ onSelect: function(value, data) {
16
+ $(suburb).value = data[0].city;
17
+ $(pcode).value = data[0].postcode;
18
+ fireEvent($(pcode), 'change');
19
+ },
20
+ onLoadStart: function() {
21
+ $(el).addClassName('avs-active');
22
+ },
23
+ onLoadComplete: function() {
24
+ $(el).removeClassName('avs-active');
25
+ },
26
+ onAway: function() { }
27
+ });
28
+ }
29
+ },
30
+ registerCountryListener: function(countryId, pcodeId) {
31
+ if($(countryId)) {
32
+ Event.observe(countryId, 'change', function() {
33
+ if($(countryId).value == "GB") {
34
+ $(pcodeId).addClassName('validate-postcode-gb');
35
+ } else {
36
+ $(pcodeId).removeClassName('validate-postcode-gb');
37
+ }
38
+ });
39
+ }
40
+ }
41
+ };
42
+
43
+ if(typeof Validation != 'undefined') {
44
+ Validation.add('validate-postcode-gb', 'Please enter a valid UK postcode.', function(v) {
45
+ return Validation.get('IsEmpty').test(v) || /(^[A-Z]{1,2}[0-9R][0-9A-Z]?[\s]?[0-9][ABD-HJLNP-UW-Z]{2}$)/i.test(v);
46
+ });
47
+ }
48
+
49
+ function fireEvent(element,event){
50
+ if (document.createEventObject){
51
+ // dispatch for IE
52
+ var evt = document.createEventObject();
53
+ return element.fireEvent('on'+event,evt)
54
+ }
55
+ else{
56
+ // dispatch for firefox + others
57
+ var evt = document.createEvent("HTMLEvents");
58
+ evt.initEvent(event, true, true ); // event type,bubbling,cancelable
59
+ return !element.dispatchEvent(evt);
60
+ }
61
+ }
package.xml ADDED
@@ -0,0 +1,43 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <package>
3
+ <name>Temando_Temando</name>
4
+ <version>1.0.0</version>
5
+ <stability>stable</stability>
6
+ <license uri="http://opensource.org/licenses/osl-3.0.php">Open Software Licence</license>
7
+ <channel>community</channel>
8
+ <extends/>
9
+ <summary>Display delivery options and costs from multiple couriers at both a product and cart level. Streamline order shipping, print labels and much more.</summary>
10
+ <description>Temando Magento Shipping Extension-&#xD;
11
+ Temando is the industry&#x2019;s choice for eCommerce shipping. Temando offer a fully integrated shipping extension for Magento. The free starter version is available for download in Australia only.&#xD;
12
+ Temando Magento Shipping Extension &#x2013; Starter Version&#xD;
13
+ &#x2022; Delivery options at checkout &#xD;
14
+ &#x2022; Shipping calculator at checkout&#xD;
15
+ &#x2022; Access multiple couriers&#xD;
16
+ &#x2022; Address verification&#xD;
17
+ &#x2022; Shipping label production&#xD;
18
+ &#x2022; Manifesting, connote and parcel tracking&#xD;
19
+ Additional functionality - Temando Magento Shipping Extension&#xD;
20
+ The Temando Magento shipping extension is more than just shipping software. Advanced features are available in additional versions of the extension and these include: &#xD;
21
+ &#x2022; Ship from multiple locations/warehouses&#xD;
22
+ &#x2022; Shipping rule engine to manage postcode zones and promotions&#xD;
23
+ &#x2022; Use Temando&#x2019;s courier rates or load your own&#xD;
24
+ &#x2022; Insurance option at check out&#xD;
25
+ &#x2022; Carbon offset option at check out&#xD;
26
+ &#x2022; Process multiple bookings in batches&#xD;
27
+ &#x2022; Packaging logic to predict box sizes&#xD;
28
+ </description>
29
+ <notes>Temando Shipping Extension &#x2013; Starter Version&#xD;
30
+ &#x2022; Delivery options at checkout &#xD;
31
+ &#x2022; Shipping calculator at checkout&#xD;
32
+ &#x2022; Access multiple couriers&#xD;
33
+ &#x2022; Address verification&#xD;
34
+ &#x2022; Shipping label production&#xD;
35
+ &#x2022; Manifesting, connote and parcel tracking&#xD;
36
+ </notes>
37
+ <authors><author><name>Temando</name><user>Temando</user><email>marketing@temando.com</email></author></authors>
38
+ <date>2013-10-03</date>
39
+ <time>04:51:29</time>
40
+ <contents><target name="mageetc"><dir name="modules"><file name="Temando_Temando.xml" hash="61802a5dcba43fb186bf8c0ffac6950f"/></dir></target><target name="magecommunity"><dir name="Temando"><dir name="Temando"><dir name="Block"><dir name="Adminhtml"><dir name="Manifest"><dir name="Filter"><file name="Form.php" hash="7c19d09e25f806ef78a6cb0be54a395a"/></dir><dir name="Grid"><dir name="Renderer"><file name="Checkbox.php" hash="dbbf607c8fb511e62872cecb0ada8b88"/></dir></dir><file name="Grid.php" hash="4ea69275d91d98cc52d13e0f99398696"/></dir><file name="Manifest.php" hash="a07de17d6cd05d0b4793efddd6683331"/><dir name="Shipment"><dir name="Edit"><file name="Form.php" hash="d4d581256d38e9cd8b9ccf0242d18497"/><dir name="Tab"><file name="Abstract.php" hash="155de5f6e4727d461128291e8bcabe10"/><dir name="Form"><file name="Anytime.php" hash="2d3a4223b61a439bc55312b03eb7f883"/><file name="Anywhere.php" hash="27cffb5864d8999c85081bf3dc6714ce"/><file name="Boxes.php" hash="18b4b6325dc512621022eb912b187b28"/><file name="Insurance.php" hash="cbb8c1e5157b80a5af78efee20e016f7"/><file name="Products.php" hash="953cc0fe59529484e47e2c38ad7d3e0a"/><file name="Quotes.php" hash="8b135b7b568c5cd58da326070e02464e"/><file name="Status.php" hash="9c44fb52c6f9fd38f49942fa868c69d4"/></dir><file name="Form.php" hash="563c145f09c8b90d50d3b77f727fc7b5"/></dir><file name="Tabs.php" hash="1f65e9864e845110e9f86c80606a2652"/></dir><file name="Edit.php" hash="204d08be90ae6291dd6a792a606b95b8"/><file name="Grid.php" hash="cf0ddb34c0b15155c2967db445b951c6"/></dir><file name="Shipment.php" hash="aa9e8aaeb190b2b473a9fea9c461fd80"/><dir name="System"><dir name="Config"><dir name="Form"><dir name="Field"><file name="Insurance.php" hash="cd0f849df18e4643d88e756f9dde071c"/><file name="Required.php" hash="0659fe9b8ef9c4c373a1190d92495e36"/></dir><dir name="Fieldset"><file name="General.php" hash="7395ec95b32b67e34b33e5c0efc806a5"/></dir></dir></dir></dir></dir><dir name="Cart"><file name="Shipping.php" hash="8c10f6f5c6b37e1172b73475b9ef08fc"/></dir><dir name="Onepage"><dir name="Shipping"><dir name="Method"><dir name="Available"><file name="Single.php" hash="c8c8741458ce6a114111411d8eb4b6db"/></dir><file name="Available.php" hash="1e4764e6fec91175b92b8127e67df91d"/></dir></dir></dir><dir name="Product"><dir name="Shipping"><file name="Methods.php" hash="dd1dabfa05cd2e83668a67cabcfd579f"/></dir><file name="Shipping.php" hash="f46ba19649cfd0e6ef65c428e743d987"/></dir></dir><dir name="Helper"><file name="Data.php" hash="d7a203df15e248cb31179dcd3f322de2"/><file name="Functions.php" hash="be974e86582c6235f06fcbbe751d3aa6"/></dir><dir name="Model"><dir name="Api"><file name="Client.php" hash="f45ac8c6a64434b83c6a3fa29cddd6b6"/><dir name="Request"><file name="Anything.php" hash="4f09aeef29fb6f96fb16141732f796eb"/><file name="Anythings.php" hash="d3fb55824ed60a0e836db74805038fa2"/><file name="Anytime.php" hash="0c06ea38006ecbb72de2956328cba062"/><file name="Anywhere.php" hash="472902806c8c5304983b18c9c3cfbd5f"/></dir><file name="Request.php" hash="43825b6d395d9a5fff760c07eebbb105"/></dir><file name="Box.php" hash="e70430957f55d49f1232d005af69f3b2"/><file name="Carrier.php" hash="50756d3ea67163919a75725527e8426c"/><dir name="Entity"><dir name="Attribute"><dir name="Source"><dir name="Packaging"><file name="Mode.php" hash="9df70852ceade33a14cf218097f25a36"/></dir><file name="Packaging.php" hash="ae6e48d5e498d11a11feed2f00e03fa8"/></dir></dir></dir><file name="Manifest.php" hash="b870f55b33b3855754a5a4347e2acfec"/><dir name="Mysql4"><dir name="Box"><file name="Collection.php" hash="17e5ff275a0aa8b04a64caab93768198"/></dir><file name="Box.php" hash="105acbf44a10b982413168c199514319"/><dir name="Carrier"><file name="Collection.php" hash="174b62be56ac079b36ca9a11a99f6142"/></dir><file name="Carrier.php" hash="39ac233fc0ef641ed457c651fd3c2eeb"/><dir name="Manifest"><file name="Collection.php" hash="0c2a69f2d9d5c2e9111bed3253d823ed"/></dir><file name="Manifest.php" hash="536353cfe126f5d43ae95452104ba448"/><dir name="Quote"><file name="Collection.php" hash="dfcd02a112c7f3abf2c3202bed33538a"/></dir><file name="Quote.php" hash="63becb2e43f8fc6ac06844dc6789b303"/><dir name="Shipment"><file name="Collection.php" hash="c8d2075067d5639a81869e95d44feaf1"/></dir><file name="Shipment.php" hash="a8d05cbed0386249f61af2e73c76230b"/></dir><file name="Observer.php" hash="219fac88d7a6c4e6fa750524bed4d739"/><dir name="Option"><file name="Abstract.php" hash="845fdf3b2fee7a96635a84eb06130e6c"/><dir name="Action"><file name="Abstract.php" hash="8e556a5043c78ba9800a64cbea2743a0"/><file name="Carbon.php" hash="2bf7a9c3905a2c4a9dd88bb9bf602ab4"/><file name="Footprints.php" hash="74ee69751cde833b464d6fad7e8bc7b5"/><file name="Insurance.php" hash="1c312f12a62f57f555007530ad9ed722"/><file name="Markup.php" hash="978738810a3d2ebf9b08105c9080bf10"/></dir><file name="Boolean.php" hash="0c4403b4ab0ec33e4439dfc054025a03"/><file name="Carbonoffset.php" hash="bf4d22d25297028013e79780d3256823"/><file name="Footprints.php" hash="c9b88d2871350f7620440cec4c512fb9"/><file name="Insurance.php" hash="955a1d660d55e81bc0fdf4e580605f1a"/></dir><file name="Options.php" hash="c46e411a9090f01704b491d9f6c19886"/><file name="Pcs.php" hash="10771a0a344512c7f39aaacb6fbf1118"/><file name="Quote.php" hash="496a119ce659efedab8d3f7ccbcb1148"/><file name="Shipment.php" hash="40dc3d6299af2646bdae57dfe15f8ffd"/><dir name="Shipping"><dir name="Carrier"><dir name="Temando"><dir name="Source"><file name="Method.php" hash="beea2c319ccd644d6b82073041c2ff65"/></dir></dir><file name="Temando.php" hash="79d1310ee7ceb9d72f13b4dc10aeaa1a"/></dir></dir><file name="Status.php" hash="1748281382c1f2b910d7488925ab3d60"/><dir name="System"><dir name="Config"><dir name="Backend"><dir name="Form"><dir name="Field"><dir name="Required"><file name="Businessresidential.php" hash="6a4a4a22dece6e05986afbff0474e258"/><file name="Country.php" hash="7c15ab9b62776c3939f6680e81e1d994"/><file name="Location.php" hash="96507e0e7ed730c99f4dd5f6aa743016"/><file name="Text.php" hash="3961607ac0d632430b484ef141865806"/></dir></dir></dir></dir><dir name="Source"><file name="Carbon.php" hash="bafc416a404fc342fba9aefcef40bf4b"/><dir name="Client"><file name="Type.php" hash="835708cd4be50379608fb01f8dbd4850"/></dir><file name="Country.php" hash="0a2557957d861e4ea3ed193f47eba051"/><file name="Errorprocess.php" hash="23b94aa8e44a62fa81a5aa29ea31ac55"/><file name="Footprints.php" hash="1b4e3af5fcb8893d3392e7c6cc924b38"/><file name="Insurance.php" hash="3b60e9c82e8f9aa00c949ba45068d001"/><file name="Labeltype.php" hash="a5f7d209b06d65db647e2d3a6b4657ba"/><dir name="Origin"><file name="Type.php" hash="167e76f7b939e3c627b98ee0318ab264"/></dir><file name="Payment.php" hash="15b7ffb809d44e89a2a0d779e2b6d1e8"/><file name="Pricing.php" hash="8d0c73d3ffce5ad61d6aff4530c942b8"/><file name="Readytime.php" hash="dfe95a917cf3d4b5e26c7972e6574bc3"/><file name="Regions.php" hash="d5d46eeba382e53a8ede61aaba4836a4"/><dir name="Rule"><dir name="Action"><dir name="Adjustment"><file name="Type.php" hash="32b0133d904961669456aa2889985ce8"/></dir><file name="Filter.php" hash="ade56e85d4c9fea77b922629ba1db7c8"/></dir><dir name="Condition"><file name="Time.php" hash="075adcdcb0be9662b34c517665e912b7"/><file name="Type.php" hash="0622631836a3306e53a11e6b1e326e6d"/></dir><file name="Type.php" hash="5a2e0cee02f99c3f68536bf26cbea199"/></dir><dir name="Sales"><dir name="Order"><file name="Status.php" hash="39eceb8a78224871b19d5b09304a56be"/></dir></dir><dir name="Shipment"><file name="Class.php" hash="3291adbe6ba99934a2dbcf19f6b83e46"/><dir name="Packaging"><file name="Mode.php" hash="b245586603851d1a7b0470f6ca52974e"/></dir><file name="Packaging.php" hash="853ab9b82b429b2db6cace1da9429db9"/><file name="Service.php" hash="f866d8aca47fae13602885413f997ef5"/><file name="Status.php" hash="e74bb51a02f1357f44d8f0052c682181"/></dir><dir name="Unit"><file name="Measure.php" hash="01bbc3e2f7f688f9edf54f40bb46c686"/><file name="Weight.php" hash="6b74dde04ffdc951aeed3fb1db60599e"/></dir><file name="Unit.php" hash="b8e75f2efede007b004c47acadea6a84"/></dir><file name="Source.php" hash="c6a86ee4f9973a8793eec15660115b0c"/></dir></dir></dir><dir name="controllers"><dir name="Adminhtml"><file name="JsonController.php" hash="ce01376bdf43f939c802448c880cfd32"/><file name="ManifestController.php" hash="27026e27331606aa81eef04ede715b82"/><file name="ShipmentController.php" hash="2d03157bf86923e6fe802e9cb17e6225"/></dir><file name="PcsController.php" hash="f66d705f4e628be375190410f5ffde13"/></dir><dir name="etc"><file name="adminhtml.xml" hash="54b907ffca044093ae7edfb83d080df3"/><file name="config.xml" hash="b01bc37f82705aeac784f7a3a3d76829"/><file name="system.xml" hash="341895ab6b9d9421e78aafccdba54c85"/></dir><dir name="sql"><dir name="temando_setup"><file name="mysql4-install-1.0.0.php" hash="8f22dad6cc2162119422a468b8af9941"/></dir></dir></dir></dir></target><target name="magedesign"><dir name="adminhtml"><dir name="default"><dir name="default"><dir name="layout"><file name="temando.xml" hash="fafd045c42b263f370b1779f7a26d045"/></dir><dir name="template"><dir name="temando"><dir name="temando"><file name="manifest.phtml" hash="42425c5a9a479f803d5ff38258ef1afb"/><file name="origin-avs.phtml" hash="fb39b40b1171e2415860f9c7f162dedf"/><file name="region.phtml" hash="b4012e1a5fa90bcdcd1271ac05b8c763"/><dir name="shipment"><file name="anytime.phtml" hash="8a2ad03e2b01eed05d2929a21e480fd1"/><file name="anywhere.phtml" hash="766acc8aa797d1b64667c7c5060fdc99"/><file name="boxes.phtml" hash="9b97aba8d4ab21fa4d005d0b6f64cac1"/><file name="insurance.phtml" hash="ee70a81f5b1aa017c0095a3905cc55b1"/><file name="products.phtml" hash="a27abbbc5ea7d2437ce2596c8eb48e0a"/><file name="quotes.phtml" hash="1276987516b2f5c8d45b5d32697f3c28"/><file name="status.phtml" hash="3713124523aff92fac39d45548760f1f"/></dir><file name="shipment.phtml" hash="03f44e5048a9e23405abf6b2ca571c2b"/></dir></dir></dir></dir></dir></dir><dir name="frontend"><dir name="base"><dir name="default"><dir name="layout"><file name="temando.xml" hash="40e2612a14e6331b79263e58ea46e524"/></dir><dir name="template"><dir name="temando"><dir name="temando"><dir name="checkout"><dir name="cart"><file name="shipping.phtml" hash="9b527e2382b8723b754dcecd9f226c84"/></dir></dir><dir name="customer"><dir name="address"><file name="edit.phtml" hash="17b4da6acfcbdbac94ab507aaac3014f"/></dir></dir><dir name="onestep"><file name="options.phtml" hash="3e0bcc5ba754a31efca069df23637226"/><file name="shipping_method.phtml" hash="147758a6e7a9abc24133fe69167787eb"/></dir><file name="pcs.phtml" hash="2b6e59f811eb7e0a8f622b2f26cda4e2"/><dir name="product"><dir name="shipping"><file name="methods.phtml" hash="1117050cc8bdf9e1bf15189f91c6f56e"/></dir><file name="shipping.phtml" hash="a1d26bb6e8a6fe33a41d5ab00dd84681"/></dir><dir name="shipping_method"><dir name="available"><file name="options_single.phtml" hash="ceb901d5d7f8c8aa69865d6437b27436"/></dir><file name="available.phtml" hash="c42d3f047eed375641f2f0bd1a349392"/></dir></dir></dir></dir></dir></dir></dir></target><target name="mage"><dir name="js"><dir name="temando"><file name="autocomplete.js" hash="7d9495b3041c1b528c0d9d4809ba9e58"/><file name="avs.js" hash="76d449546d0e1109d09091e31b2b2ca3"/></dir></dir></target><target name="mageskin"><dir name="adminhtml"><dir name="default"><dir name="default"><dir name="js"><file name="temando.js" hash="37bda1e3240b9f46fdc1fa8d0937ceba"/></dir><dir name="temando"><dir name="images"><file name="ajax-s-load.gif" hash="0ea8ba3fe3e60b73eda7d6de57fd8e01"/><file name="bg_notifications.gif" hash="d2a0489d0c3714bed22f9b06f4b81d43"/><file name="shadow.png" hash="b5b27e0dd88d44d4a5d8e63bb61a1239"/><file name="temando_logo.jpg" hash="04d2dbd664ff68a4be7364113f30572f"/></dir><file name="styles.css" hash="2d9c985c31622016db01e966974d70be"/></dir></dir></dir></dir><dir name="frontend"><dir name="base"><dir name="default"><dir name="css"><dir name="temando"><file name="autocomplete.css" hash="90387e5610631653a4bd97c7af3d444e"/><dir name="images"><file name="ajax-s-load.gif" hash="0ea8ba3fe3e60b73eda7d6de57fd8e01"/><file name="find_ext.png" hash="a6ba701a9256a2c775255965df1918c7"/><file name="i_shipping.gif" hash="91a0d2cc2eb2391f90ec8a75c04b3183"/><file name="shadow.png" hash="b5b27e0dd88d44d4a5d8e63bb61a1239"/></dir><file name="product.css" hash="d1679e756012f66391758a09d0918986"/><file name="styles.css" hash="990cb30792de7e9b46042a7d09be73d3"/></dir></dir><dir name="js"><dir name="temando"><file name="checkout.js" hash="4db7a8cd7888f3c7ca93e70f0ee16b84"/><file name="product.js" hash="6f4765fa49efa0c5bc023460624a0b4e"/></dir></dir></dir></dir></dir></target></contents>
41
+ <compatible/>
42
+ <dependencies><required><php><min>5.2.13</min><max>6.0.0</max></php><extension><name>soap</name><min>1.2</min><max/></extension></required></dependencies>
43
+ </package>
skin/adminhtml/default/default/js/temando.js ADDED
@@ -0,0 +1,54 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ function clientTypeChangeListener() {
3
+ id_prefix = "fieldset_client_type_";
4
+ var classn = "fieldset-client-type";
5
+
6
+ $$("." + classn).each(function (fieldset) {
7
+ fieldset.hide();
8
+ fieldset.previous(".entry-edit-head").hide();
9
+ });
10
+
11
+ if ($(id_prefix + $("client_type").value.toLowerCase())) {
12
+ $(id_prefix + $("client_type").value.toLowerCase()).show();
13
+ $(id_prefix + $("client_type").value.toLowerCase()).previous(".entry-edit-head").show();
14
+ }
15
+
16
+ if ($("client_type").value.toLowerCase() === 'company') {
17
+ $('company_no').addClassName('required-entry').addClassName('validate-max-30');
18
+ } else {
19
+ $('company_no').removeClassName('required-entry').removeClassName('validate-max-30');
20
+ }
21
+ }
22
+
23
+ Event.observe(window, "load", function () {
24
+ clientTypeChangeListener();
25
+
26
+ $("client_type").observe("change", function () {
27
+ clientTypeChangeListener();
28
+ });
29
+ });
30
+
31
+
32
+ Validation.addAllThese([
33
+ ['validate-max-500', 'Please use less than 500 characters.', {
34
+ maxLength: 500
35
+ }],
36
+ ['validate-max-100', 'Please use less than 100 characters.', {
37
+ maxLength: 100
38
+ }],
39
+ ['validate-max-50', 'Please use less than 50 characters.', {
40
+ maxLength: 50
41
+ }],
42
+ ['validate-max-30', 'Please use less than 30 characters.', {
43
+ maxLength: 30
44
+ }],
45
+ ['validate-max-20', 'Please use less than 20 characters.', {
46
+ maxLength: 20
47
+ }],
48
+ ['validate-max-10', 'Please use less than 10 characters.', {
49
+ maxLength: 10
50
+ }],
51
+ ['validate-min-6', 'Please use at least 6 characters.', {
52
+ minLength: 6
53
+ }]
54
+ ]);
skin/adminhtml/default/default/temando/images/ajax-s-load.gif ADDED
Binary file
skin/adminhtml/default/default/temando/images/bg_notifications.gif ADDED
Binary file
skin/adminhtml/default/default/temando/images/shadow.png ADDED
Binary file
skin/adminhtml/default/default/temando/images/temando_logo.jpg ADDED
Binary file
skin/adminhtml/default/default/temando/styles.css ADDED
@@ -0,0 +1,41 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ div.confirm-insurance {
2
+
3
+ }
4
+
5
+ div.confirm-insurance {
6
+ border-spacing: 10px;
7
+ background: none repeat scroll 0 0 #F9F3E3;
8
+ border: 1px solid #BBAFA0;
9
+ margin: 10px;
10
+ padding: 10px;
11
+ }
12
+
13
+ div.confirm-insurance td.c2 {
14
+ padding-left: 15px;
15
+ font-size: 12px;
16
+ font-style: italic;
17
+ }
18
+
19
+ .tmd-grid-severity-critical,
20
+ .tmd-grid-severity-critical span,
21
+ .tmd-grid-severity-major,
22
+ .tmd-grid-severity-major span,
23
+ .tmd-grid-severity-minor,
24
+ .tmd-grid-severity-minor span,
25
+ .tmd-grid-severity-notice,
26
+ .tmd-grid-severity-notice span { display:block; height:16px; background-image:url(images/bg_notifications.gif); background-repeat:no-repeat; font:bold 10px/16px Arial, Helvetica, sans-serif; text-transform:uppercase; text-align:center; padding:0 0 0 7px; margin:1px 0; white-space:nowrap; color:#fff; }
27
+ .tmd-grid-severity-critical { background-position:0 0; }
28
+ .tmd-grid-severity-critical span { background-position:100% 0; padding:0 7px 0 0; }
29
+ .tmd-grid-severity-major { background-position:0 -16px; }
30
+ .tmd-grid-severity-major span { background-position:100% -16px; padding:0 7px 0 0; }
31
+ .tmd-grid-severity-minor { background-position:0 -32px; }
32
+ .tmd-grid-severity-minor span { background-position:100% -32px; padding:0 7px 0 0; }
33
+ .tmd-grid-severity-notice { background-position:0 -48px; }
34
+ .tmd-grid-severity-notice span { background-position:100% -48px; padding:0 7px 0 0; }
35
+
36
+ .autocomplete-w1 { background:url(images/shadow.png) no-repeat bottom right; position:absolute; z-index: 1000; top:4px; left:3px; /* IE6 fix: */ _background:none; _top:1px; }
37
+ .autocomplete-w2 { padding:0 6px 6px 0; }
38
+ .autocomplete { width:300px; border:1px solid #999; background:#FFF; cursor:default; text-align:left; max-height:350px; overflow:auto; margin:-6px 6px 6px -6px; /* IE specific: */ _height:350px; _margin:0px 6px 6px 0; overflow-x:hidden; }
39
+ .autocomplete .selected { background:#F0F0F0; }
40
+ .autocomplete div { padding:2px 5px; white-space:nowrap; }
41
+ .autocomplete strong { font-weight:normal; color:#3399FF; }
skin/frontend/base/default/css/temando/autocomplete.css ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
1
+ .autocomplete-w1 { background:url(images/shadow.png) no-repeat bottom right; position:absolute; z-index: 1000; top:4px; left:3px; /* IE6 fix: */ _background:none; _top:1px; }
2
+ .autocomplete-w2 { padding:0 6px 6px 0; }
3
+ .autocomplete { width:300px; border:1px solid #999; background:#FFF; cursor:default; text-align:left; max-height:350px; overflow:auto; margin:-6px 6px 6px -6px; /* IE specific: */ _height:350px; _margin:0px 6px 6px 0; overflow-x:hidden; }
4
+ .autocomplete .selected { background:#F0F0F0; }
5
+ .autocomplete div { padding:2px 5px; white-space:nowrap; }
6
+ .autocomplete strong { font-weight:normal; color:#3399FF; }
7
+
8
+ .avs-active { background: url("images/ajax-s-load.gif") no-repeat scroll right center transparent !important; }
skin/frontend/base/default/css/temando/images/ajax-s-load.gif ADDED
Binary file
skin/frontend/base/default/css/temando/images/find_ext.png ADDED
Binary file
skin/frontend/base/default/css/temando/images/i_shipping.gif ADDED
Binary file
skin/frontend/base/default/css/temando/images/shadow.png ADDED
Binary file
skin/frontend/base/default/css/temando/product.css ADDED
@@ -0,0 +1,39 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* Product page */
2
+ .block-shipping .block-title strong {
3
+ background-image: url("./images/i_shipping.gif");
4
+ background-position: 0 0;
5
+ background-repeat: no-repeat;
6
+ padding-left: 21px;
7
+ }
8
+ .estimate-form {
9
+ padding: 7px;
10
+ }
11
+ .estimate-form #pcs {
12
+ width: 150px;
13
+ padding: 4px;
14
+ padding-right: 26px;
15
+ /*border-radius: 4px 4px 4px 4px;
16
+ box-shadow: 0 0 10px #EEEEEE inset;*/
17
+ background-color: transparent;
18
+ }
19
+ .estimate-form .estimate-button {
20
+ padding-top:5px;
21
+ width: 100%;
22
+ text-align: right;
23
+ }
24
+ .estimate-form select {
25
+ margin-bottom: 5px;
26
+ width: 182px;
27
+ }
28
+
29
+ .postcode-container input, .city-container input {
30
+ margin: 2px 0px;
31
+ width: 176px;
32
+ }
33
+
34
+ .postcode-container label .city-container label{
35
+ background-color: #FAEBE7;
36
+ background-image: url("../images/i_msg-error.gif");
37
+ border-color: #F16048;
38
+ color: #DF280A;
39
+ }
skin/frontend/base/default/css/temando/styles.css ADDED
@@ -0,0 +1,43 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ table.insurance {
2
+ border-spacing: 10px;
3
+ }
4
+
5
+ table.insurance td.c1 {
6
+ background: none repeat scroll 0 0 #F9F3E3;
7
+ border: 1px solid #BBAFA0;
8
+ margin: 10px;
9
+ padding: 10px;
10
+ }
11
+
12
+ table.insurance td.c2 {
13
+ font-size: 11px;
14
+ font-style: italic;
15
+ padding-right: 8px;
16
+ }
17
+
18
+ table.insurance td label {
19
+ color: #F18200;
20
+ }
21
+
22
+ div.customer-instructions, div.customer-comment {
23
+ background: none repeat scroll 0 0 #F9F3E3;
24
+ border: 1px solid #BBAFA0;
25
+ margin: 10px;
26
+ padding: 15px;
27
+ width: 92%;
28
+ }
29
+
30
+ .note {
31
+ float: right;
32
+ clear: both;
33
+ font-style: italic;
34
+ font-size: x-small;
35
+ }
36
+
37
+ textarea.comment {
38
+ width: 100%;
39
+ }
40
+
41
+ input.instructions {
42
+ width: 100%;
43
+ }
skin/frontend/base/default/js/temando/checkout.js ADDED
@@ -0,0 +1,239 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ function option_update(sole)
2
+ {
3
+ if (sole) return;
4
+
5
+ // build class
6
+ classes = '';
7
+
8
+ checkboxes = $$('#temando_checkboxes input[type=checkbox]');
9
+ checkboxes.each(function (checkbox) {
10
+ if (checkbox.id.indexOf('temando_checkbox_') === 0) {
11
+ classes += '.' + checkbox.id.replace(/temando_checkbox_/, '') + '_' + (checkbox.checked ? 'Y' : 'N');
12
+ }
13
+ });
14
+
15
+ // hide all
16
+ $$('input[name^=shipping_method]').each(function (control) {
17
+ if(control.id.match(/^s_method_temando_(\d+)/) && !control.id.match(/^s_method_temando_(10000|10001)/)) {
18
+ control.up().hide();
19
+ control.checked = false;
20
+ }
21
+ });
22
+
23
+ // show those matching the classes
24
+ $$(classes).each(function (control) {
25
+ control.up().show();
26
+ });
27
+ }
28
+
29
+ function option_update_onestep()
30
+ {
31
+ // build class
32
+ classes = '';
33
+
34
+ checkboxes = $$('#temando_checkboxes input[type=checkbox]');
35
+ checkboxes.each(function (checkbox) {
36
+ if (checkbox.id.indexOf('temando_checkbox_') === 0) {
37
+ classes += '.' + checkbox.id.replace(/temando_checkbox_/, '') + '_' + (checkbox.checked ? 'Y' : 'N');
38
+ }
39
+ });
40
+
41
+ // hide all
42
+ $$('input[name^=shipping_method]').each(function (control) {
43
+ if(control.id.match(/^s_method_temando_(\d+)/) && !control.id.match(/^s_method_temando_(10000|10001)/)) {
44
+ control.up().hide();
45
+ control.checked = false;
46
+ }
47
+ });
48
+
49
+ // show those matching the classes
50
+ $$(classes).each(function (control) {
51
+ control.up().show();
52
+ });
53
+
54
+ //preselect shipping method if single
55
+ var visible = $$('input[name^=shipping_method]').findAll(function(el) { return el.offsetWidth > 0 && el.offsetHeight > 0; });
56
+ if(visible.size() == 1) {
57
+ var el = visible.first();
58
+ $$('input[name^=shipping_method]').each(function (control) {control.checked = false;});
59
+ el.checked = true;
60
+ fireEvent(el, 'click');
61
+ }
62
+ }
63
+
64
+ function includingShipping(getShippingCode) {
65
+ if ((typeof(shippingMe) !== 'undefined') && (shippingMe != null) && shippingMe && shippingMe.length) {
66
+ var newPrice = shippingMe[getShippingCode];
67
+ if (!lastPrice) {
68
+ lastPrice = newPrice;
69
+ if (window.quoteBaseGrandTotal != undefined) {
70
+ quoteBaseGrandTotal += newPrice;
71
+ }
72
+ }
73
+ if (newPrice != lastPrice) {
74
+ if (window.quoteBaseGrandTotal != undefined) {
75
+ quoteBaseGrandTotal += (newPrice-lastPrice);
76
+ }
77
+ lastPrice = newPrice;
78
+
79
+ }
80
+ }
81
+ if (window.quoteBaseGrandTotal != undefined && window.checkQuoteBaseGrandTotal != undefined) {
82
+ checkQuoteBaseGrandTotal = quoteBaseGrandTotal;
83
+ }
84
+ return false;
85
+ }
86
+
87
+ function refreshQuotes() {
88
+ //get checked options
89
+ var delivery_options = $$('input[id^=delivery_option_]');
90
+ var params = Form.serializeElements(delivery_options);
91
+
92
+ //refresh quotes
93
+ if (checkout.loadWaiting!=false) return;
94
+ var validator = new Validation(shipping.form);
95
+ if (validator.validate()) {
96
+ checkout.setLoadWaiting('shipping-method');
97
+ delivery_options.each(function(control) {
98
+ control.disabled = true;
99
+ });
100
+ params += params.length ? '&' + Form.serialize(shipping.form) : Form.serialize(shipping.form);
101
+ var request = new Ajax.Request(
102
+ shipping.saveUrl,
103
+ {
104
+ method:'post',
105
+ onComplete: shipping.onComplete,
106
+ onSuccess: shipping.onSave,
107
+ onFailure: checkout.ajaxFailure.bind(checkout),
108
+ parameters: params
109
+ }
110
+ );
111
+
112
+ }
113
+ }
114
+
115
+ function refreshQuotesOnestep(url, set_methods_url)
116
+ {
117
+ return function() {
118
+ var form = $('onestepcheckout-form');
119
+ var items = exclude_unchecked_checkboxes($$('input[name^=billing]').concat($$('select[name^=billing]').concat($$('input[id^=delivery_option_]'))));
120
+ //var delivery_options = $$('input[id^=delivery_option_]');
121
+ var names = items.pluck('name');
122
+ var values = items.pluck('value');
123
+ var parameters = {
124
+ shipping_method: $RF(form, 'shipping_method'),
125
+ delivery_option_click: true
126
+ };
127
+
128
+ var street_count = 0;
129
+ for(var x=0; x < names.length; x++) {
130
+ if(names[x] != 'payment[method]') {
131
+
132
+ var current_name = names[x];
133
+
134
+ if(names[x] == 'billing[street][]') {
135
+ current_name = 'billing[street][' + street_count + ']';
136
+ street_count = street_count + 1;
137
+ }
138
+
139
+ parameters[current_name] = values[x];
140
+ }
141
+ }
142
+
143
+ var use_for_shipping = $('billing:use_for_shipping_yes');
144
+ if(use_for_shipping && use_for_shipping.getValue() != '1') {
145
+ var items = $$('input[name^=shipping]').concat($$('select[name^=shipping]'));
146
+ var shipping_names = items.pluck('name');
147
+ var shipping_values = items.pluck('value');
148
+ var shipping_parameters = {};
149
+ var street_count = 0;
150
+
151
+ for(var x=0; x < shipping_names.length; x++) {
152
+ if(shipping_names[x] != 'shipping_method') {
153
+ var current_name = shipping_names[x];
154
+ if(shipping_names[x] == 'shipping[street][]') {
155
+ current_name = 'shipping[street][' + street_count + ']';
156
+ street_count = street_count + 1;
157
+ }
158
+
159
+ parameters[current_name] = shipping_values[x];
160
+ }
161
+ }
162
+ }
163
+
164
+ var shipment_methods = $$('div.onestepcheckout-shipping-method-block')[0];
165
+ var shipment_methods_found = false;
166
+
167
+ if(typeof shipment_methods != 'undefined') {
168
+ shipment_methods_found = true;
169
+ }
170
+
171
+ if(shipment_methods_found) {
172
+ shipment_methods.update('<div class="loading-ajax">&nbsp;</div>');
173
+ }
174
+
175
+ var payment_method = $RF(form, 'payment[method]');
176
+ parameters['payment_method'] = payment_method;
177
+ parameters['payment[method]'] = payment_method;
178
+
179
+ var payment_methods = $$('div.payment-methods')[0];
180
+ payment_methods.update('<div class="loading-ajax">&nbsp;</div>');
181
+
182
+ var totals = get_totals_element();
183
+ totals.update('<div class="loading-ajax">&nbsp;</div>');
184
+
185
+
186
+ new Ajax.Request(url, {
187
+ method: 'post',
188
+ onSuccess: function(transport) {
189
+ if(transport.status == 200) {
190
+
191
+ var data = transport.responseText.evalJSON();
192
+
193
+ // Update shipment methods
194
+ if(shipment_methods_found) {
195
+ shipment_methods.update(data.shipping_method);
196
+ }
197
+ payment_methods.replace(data.payment_method);
198
+ totals.update(data.summary);
199
+
200
+ // Add new event handlers
201
+
202
+ if(shipment_methods_found) {
203
+ $$('dl.shipment-methods input').invoke('observe', 'click', get_separate_save_methods_function(set_methods_url, true));
204
+ }
205
+
206
+ $$('div.payment-methods input[name^=payment\[method\]]').invoke('observe', 'click', get_separate_save_methods_function(set_methods_url));
207
+
208
+ $$('div.payment-methods input[name^=payment\[method\]]').invoke('observe', 'click', function() {
209
+ $$('div.onestepcheckout-payment-method-error').each(function(item) {
210
+ new Effect.Fade(item);
211
+ });
212
+ });
213
+
214
+ if(shipment_methods_found) {
215
+ $$('dl.shipment-methods input').invoke('observe', 'click', function() {
216
+ $$('div.onestepcheckout-shipment-method-error').each(function(item) {
217
+ new Effect.Fade(item);
218
+ });
219
+ });
220
+ }
221
+
222
+ if($RF(form, 'payment[method]') != null) {
223
+ try {
224
+ var payment_method = $RF(form, 'payment[method]');
225
+ $('container_payment_method_' + payment_method).show();
226
+ $('payment_form_' + payment_method).show();
227
+ } catch(err) {
228
+
229
+ }
230
+ }
231
+
232
+
233
+ }
234
+ },
235
+ parameters: parameters
236
+ });
237
+
238
+ }
239
+ }
skin/frontend/base/default/js/temando/product.js ADDED
@@ -0,0 +1,161 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ function pcsFocus()
2
+ {
3
+ var obj = $('pcs');
4
+ if (obj.value == empty_pcs_value) {
5
+ obj.value = '';
6
+ }
7
+
8
+ obj.style.color = '';
9
+ }
10
+
11
+ function pcsBlur()
12
+ {
13
+ var color= '';
14
+ var obj = $('pcs');
15
+ if (!obj.value || (obj.value == empty_pcs_value)) {
16
+ color= 'grey';
17
+ obj.value = empty_pcs_value;
18
+ }
19
+
20
+ obj.style.color = color;
21
+ }
22
+
23
+ function getShippingRates()
24
+ {
25
+ var qty_value = 1;
26
+ if ($('qty') && $('qty').value && parseInt($('qty').value) && (parseInt($('qty').value) > 0)) {
27
+ qty_value = parseInt($('qty').value);
28
+ }
29
+ if (!$('city').value || !$('postcode').value) {
30
+ alert('Please enter your location');
31
+ return false;
32
+ }
33
+ var options = {};
34
+ $$('select[name^=super_attribute]').each(function (control) {
35
+ if (false === options) {
36
+ return;
37
+ }
38
+ if (!control.value) {
39
+ options = false;
40
+ return;
41
+ } else {
42
+ options[control.name.substr(16, control.name.length - 17)] = control.value;
43
+ }
44
+ });
45
+ if (false == options) {
46
+ alert('Please select product options');
47
+ return false;
48
+ }
49
+ var options_str = '';
50
+ for (var i in options) {
51
+ options_str += i + ':' + options[i] + ';';
52
+ }
53
+ options = {};
54
+ $$('select[name^=options]').each(function (control) {
55
+ if (false === options) {
56
+ return;
57
+ }
58
+ if (control.hasClassName('required-entry')) {
59
+ if (!control.value) {
60
+ options = false;
61
+ return;
62
+ } else {
63
+ options[control.name.substr(8, control.name.length - 9)] = control.value;
64
+ }
65
+ }
66
+ });
67
+ $$('input[name^=options]').each(function (control) {
68
+ if (false === options) {
69
+ return;
70
+ }
71
+ if (control.hasClassName('validate-one-required-by-name')) {
72
+ var items = $$('input[name^=options]');
73
+ var value = false;
74
+ for (var k = 0; k < items.length; k++) {
75
+ if ((items[k].name == control.name) && items[k].checked) {
76
+ value = items[k].value;
77
+ }
78
+ }
79
+ if (!value) {
80
+ options = false;
81
+ return;
82
+ } else {
83
+ options[control.name.substr(8, control.name.length - 9)] = value;
84
+ }
85
+ }
86
+ });
87
+ if (false == options) {
88
+ alert('Please select product options');
89
+ return false;
90
+ }
91
+ var pr_options_str = '';
92
+ for (var i in options) {
93
+ pr_options_str += i + ':' + options[i] + ';';
94
+ }
95
+
96
+ //bundle products
97
+ options = {};
98
+ $$('select[name^=bundle_option]').each(function (control) {
99
+ if (false === options) {
100
+ return;
101
+ }
102
+ if (control.hasClassName('required-entry')) {
103
+ if (!control.value) {
104
+ options = false;
105
+ return;
106
+ } else {
107
+ options[control.name.substr(14, control.name.length - 15)] = control.value;
108
+ }
109
+ }
110
+ });
111
+ $$('input[name^=bundle_option]').each(function (control) {
112
+ if (false === options) {
113
+ return;
114
+ }
115
+ if (control.hasClassName('validate-one-required-by-name')) {
116
+ var items = $$('input[name^=bundle_option]');
117
+ var value = false;
118
+ for (var k = 0; k < items.length; k++) {
119
+ if ((items[k].name == control.name) && items[k].checked) {
120
+ value = items[k].value;
121
+ }
122
+ }
123
+ if (!value) {
124
+ options = false;
125
+ return;
126
+ } else {
127
+ options[control.name.substr(13, control.name.length - 14)] = value;
128
+ }
129
+ }
130
+ });
131
+ if (false == options) {
132
+ alert('Please select product options');
133
+ return false;
134
+ }
135
+ var bundle_options_str = '';
136
+ for (var i in options) {
137
+ bundle_options_str += i + ':' + options[i] + ';';
138
+ }
139
+
140
+ //get rid of '[' & ']' - for check-boxes with syntax xxx[14][]
141
+ var pattern = /(\[|\])/g;
142
+ bundle_options_str = bundle_options_str.replace(pattern, "");
143
+
144
+ $('estimate_items').update('Loading...');
145
+ new Ajax.Request(shipping_estimator_url, {
146
+ parameters: {
147
+ country_id: $('country_id').value,
148
+ city : $('city').value,
149
+ postcode : $('postcode').value,
150
+ product_id: $('product_id').value,
151
+ qty : qty_value,
152
+ options : options_str,
153
+ pr_options: pr_options_str,
154
+ bl_options: bundle_options_str
155
+ },
156
+ onComplete: function(resp){
157
+ $('estimate_items').update(resp.responseText);
158
+ },
159
+ method: 'post'
160
+ });
161
+ }