SFC_Autoship - Version 1.3.2.6

Version Notes

Subscribe Pro Extension Release

Download this release

Release Info

Developer StoreFront Consulting
Extension SFC_Autoship
Version 1.3.2.6
Comparing to
See all releases


Code changes from version 1.3.1.14 to 1.3.2.6

Files changed (90) hide show
  1. app/code/local/SFC/Autoship/Block/Adminhtml/Customer/Edit/Tabs.php +19 -0
  2. app/code/local/SFC/Autoship/Block/Adminhtml/Customer/Paymentprofiles/Edit.php +10 -1
  3. app/code/local/SFC/Autoship/Block/Adminhtml/Customer/Paymentprofiles/Paymentprofile.php +4 -4
  4. app/code/local/SFC/Autoship/Block/Adminhtml/Sales/Order/Create/Billing/Method/Form.php +56 -0
  5. app/code/local/SFC/Autoship/Block/Adminhtml/Sales/Order/Create/Product/Subscription.php +189 -0
  6. app/code/local/SFC/Autoship/Block/Adminhtml/System/Config/Form/TestConnectionButton.php +1 -1
  7. app/code/local/SFC/Autoship/Block/Cart/Product/Subscription.php +36 -0
  8. app/code/local/SFC/Autoship/Block/Checkout/Onepage/Payment/Methods.php +2 -11
  9. app/code/local/SFC/Autoship/Block/Mysubscriptions/Subscription.php +0 -2
  10. app/code/local/SFC/Autoship/Block/Payment/Form/Cc.php +17 -2
  11. app/code/local/SFC/Autoship/Block/Payment/Form/Cc/Saved.php +13 -0
  12. app/code/local/SFC/Autoship/Block/Payment/Profile/Edit.php +2 -2
  13. app/code/local/SFC/Autoship/Block/Product/Subscribe.php +6 -0
  14. app/code/local/SFC/Autoship/Block/Product/View.php +55 -0
  15. app/code/local/SFC/Autoship/Block/Subscription/Abstract.php +42 -0
  16. app/code/local/SFC/Autoship/Block/Subscription/Form/Payment.php +4 -15
  17. app/code/local/SFC/Autoship/Helper/Adminorder.php +226 -107
  18. app/code/local/SFC/Autoship/Helper/Api.php +772 -274
  19. app/code/local/SFC/Autoship/Helper/Payment.php +163 -89
  20. app/code/local/SFC/Autoship/Helper/PaymentError.php +91 -50
  21. app/code/local/SFC/Autoship/Helper/Platform.php +954 -324
  22. app/code/local/SFC/Autoship/Helper/Product.php +100 -53
  23. app/code/local/SFC/Autoship/Helper/Quote.php +784 -254
  24. app/code/local/SFC/Autoship/Helper/Schedule.php +65 -32
  25. app/code/local/SFC/Autoship/Helper/Subscription.php +489 -199
  26. app/code/local/SFC/Autoship/Helper/Vault.php +753 -250
  27. app/code/local/SFC/Autoship/Model/Api/Cart/Api.php +331 -0
  28. app/code/local/SFC/Autoship/Model/Checkout/Cart/Api.php +60 -46
  29. app/code/local/SFC/Autoship/Model/Checkout/Cart/Payment/Api.php +0 -57
  30. app/code/local/SFC/Autoship/Model/Checkout/Cart/Product/Api.php +202 -90
  31. app/code/local/SFC/Autoship/Model/Observer.php +156 -22
  32. app/code/local/SFC/Autoship/Model/Payment/Method.php +838 -251
  33. app/code/local/SFC/Autoship/Model/Payment/Profile.php +102 -71
  34. app/code/local/SFC/Autoship/Model/Payment/Profile/Address.php +39 -41
  35. app/code/local/SFC/Autoship/Model/Payment/Profile/Collection.php +80 -49
  36. app/code/local/SFC/Autoship/Model/Paypal/Express.php +36 -30
  37. app/code/local/SFC/Autoship/Model/Platform/Product.php +11 -15
  38. app/code/local/SFC/Autoship/Model/Quote/Address.php +77 -51
  39. app/code/local/SFC/Autoship/Model/Sales/Quote/Item.php +23 -0
  40. app/code/local/SFC/Autoship/Model/SalesRule/Rule/Condition/Product.php +131 -58
  41. app/code/local/SFC/Autoship/Model/SalesRule/Validator.php +225 -91
  42. app/code/local/SFC/Autoship/Model/Subscription.php +11 -2
  43. app/code/local/SFC/Autoship/controllers/Adminhtml/{PaymentprofileController.php → SppaymentprofileController.php} +5 -5
  44. app/code/local/SFC/Autoship/controllers/Adminhtml/{TestconnectionbuttonController.php → SptestconnectionbuttonController.php} +1 -1
  45. app/code/local/SFC/Autoship/controllers/MycreditcardsController.php +8 -8
  46. app/code/local/SFC/Autoship/controllers/MysubscriptionsController.php +89 -45
  47. app/code/local/SFC/Autoship/controllers/NewsubscriptionController.php +18 -18
  48. app/code/local/SFC/Autoship/etc/adminhtml.xml +8 -0
  49. app/code/local/SFC/Autoship/etc/api.xml +76 -0
  50. app/code/local/SFC/Autoship/etc/config.xml +40 -11
  51. app/code/local/SFC/Autoship/etc/system.xml +1 -1
  52. app/code/local/SFC/Autoship/sql/sfc_autoship_setup/mysql4-install-1.3.1.8.php +1 -1
  53. app/code/local/SFC/Autoship/sql/sfc_autoship_setup/mysql4-upgrade-1.3.1.15-1.3.1.16.php +35 -0
  54. app/code/local/SFC/Autoship/sql/sfc_autoship_setup/mysql4-upgrade-1.3.1.3-1.3.1.4.php +2 -2
  55. app/design/adminhtml/default/default/layout/autoship.xml +12 -4
  56. app/design/adminhtml/default/default/template/autoship/payment/form/cc.phtml +3 -2
  57. app/design/adminhtml/default/default/template/autoship/payment/form/cc_saved.phtml +34 -27
  58. app/design/adminhtml/default/default/template/autoship/sales/create_order/product/subscription.phtml +102 -0
  59. app/design/frontend/base/default/layout/autoship.xml +6 -1
  60. app/design/frontend/base/default/template/autoship/cart/product/subscription.phtml +49 -29
  61. app/design/frontend/base/default/template/autoship/checkout/success.phtml +3 -3
  62. app/design/frontend/base/default/template/autoship/giftcardaccount/onepage/payment/scripts.phtml +59 -0
  63. app/design/frontend/base/default/template/autoship/mysubscriptions.phtml +3 -3
  64. app/design/frontend/base/default/template/autoship/mysubscriptions/subscription/actions.phtml +14 -14
  65. app/design/frontend/base/default/template/autoship/mysubscriptions/subscription/billing_address.phtml +3 -3
  66. app/design/frontend/base/default/template/autoship/mysubscriptions/subscription/payment.phtml +6 -4
  67. app/design/frontend/base/default/template/autoship/mysubscriptions/subscription/product_info.phtml +2 -2
  68. app/design/frontend/base/default/template/autoship/mysubscriptions/subscription/shipping_address.phtml +3 -3
  69. app/design/frontend/base/default/template/autoship/mysubscriptions/subscription/subscription_info.phtml +6 -6
  70. app/design/frontend/base/default/template/autoship/newsubscription.phtml +1 -1
  71. app/design/frontend/base/default/template/autoship/newsubscription/billing_address.phtml +3 -3
  72. app/design/frontend/base/default/template/autoship/newsubscription/delivery_frequency.phtml +2 -2
  73. app/design/frontend/base/default/template/autoship/newsubscription/payment.phtml +6 -3
  74. app/design/frontend/base/default/template/autoship/newsubscription/shipping_address.phtml +3 -3
  75. app/design/frontend/base/default/template/autoship/newsubscription/summary.phtml +7 -7
  76. app/design/frontend/base/default/template/autoship/payment/form/cc_saved.phtml +41 -32
  77. app/design/frontend/base/default/template/autoship/payment/profile/edit.phtml +16 -14
  78. app/design/frontend/base/default/template/autoship/payment/profile/grid.phtml +8 -8
  79. app/design/frontend/base/default/template/autoship/payment/profile/new.phtml +14 -14
  80. app/design/frontend/base/default/template/autoship/product/subscribe.phtml +41 -23
  81. app/design/frontend/base/default/template/autoship/product/view/type/grouped/subscribe.phtml +4 -4
  82. app/design/frontend/base/default/template/autoship/subscription/form/payment.phtml +2 -2
  83. app/design/frontend/base/default/template/autoship/subscription/form/shipping.phtml +1 -1
  84. app/design/frontend/enterprise/default/layout/autoship.xml +6 -0
  85. package.xml +6 -6
  86. shell/autoship_customer_sync.php +75 -0
  87. shell/autoship_report_dl.php +99 -0
  88. skin/frontend/base/default/css/autoship.css +62 -46
  89. skin/frontend/base/default/js/autoship/mysubscription.js +81 -91
  90. skin/frontend/base/default/js/autoship/newsubscription.js +38 -60
app/code/local/SFC/Autoship/Block/Adminhtml/Customer/Edit/Tabs.php ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * @author Alan Barber <alan@cadence-labs.com>
4
+ */
5
+ class SFC_Autoship_Block_Adminhtml_Customer_Edit_Tabs extends Mage_Adminhtml_Block_Customer_Edit_Tabs
6
+ {
7
+ /**
8
+ * Add Payments Profile tab if allowed
9
+ * @return $this
10
+ * @throws Exception
11
+ */
12
+ public function addPaymentProfilesTab()
13
+ {
14
+ if (Mage::getSingleton('admin/session')->isAllowed('customer/paymentprofiles')) {
15
+ $this->addTab('paymentprofile', 'autoship/adminhtml_customer_paymentprofiles_paymentprofile');
16
+ }
17
+ return $this;
18
+ }
19
+ }
app/code/local/SFC/Autoship/Block/Adminhtml/Customer/Paymentprofiles/Edit.php CHANGED
@@ -26,7 +26,16 @@ class SFC_Autoship_Block_Adminhtml_Customer_Paymentprofiles_Edit extends Mage_Ad
26
  $this->_objectId = 'id';
27
  $this->_blockGroup = 'autoship';
28
  $this->_controller = 'adminhtml_customer_paymentprofiles';
29
- $this->_updateButton('save', 'label', Mage::helper('autoship')->__('Save Card'));
 
 
 
 
 
 
 
 
 
30
  $this->_removeButton('delete');
31
  $this->_removeButton('reset');
32
  }
26
  $this->_objectId = 'id';
27
  $this->_blockGroup = 'autoship';
28
  $this->_controller = 'adminhtml_customer_paymentprofiles';
29
+ // Get payment profile from registry
30
+ /** @var SFC_Autoship_Model_Payment_Profile $model */
31
+ $model = Mage::registry('paymentprofile_data');
32
+ if ($model && $model->getId()) {
33
+ if (!$model->isThirdParty()) {
34
+ $this->_updateButton('save', 'label', Mage::helper('autoship')->__('Save Card'));
35
+ } else {
36
+ $this->_removeButton('save');
37
+ }
38
+ }
39
  $this->_removeButton('delete');
40
  $this->_removeButton('reset');
41
  }
app/code/local/SFC/Autoship/Block/Adminhtml/Customer/Paymentprofiles/Paymentprofile.php CHANGED
@@ -64,7 +64,7 @@ class SFC_Autoship_Block_Adminhtml_Customer_Paymentprofiles_Paymentprofile
64
  protected function _prepareLayout()
65
  {
66
  // Build URL to add new payment profile
67
- $urlString = 'autoship_admin/adminhtml_paymentprofile/new';
68
  $url = $this->getUrl($urlString, array('customer_id' => Mage::registry('current_customer')->getId()));
69
 
70
  $button = $this->getLayout()->createBlock('adminhtml/widget_button');
@@ -171,7 +171,7 @@ class SFC_Autoship_Block_Adminhtml_Customer_Paymentprofiles_Paymentprofile
171
  public function getRowUrl($row)
172
  {
173
  return $this->getUrl(
174
- 'autoship_admin/adminhtml_paymentprofile/edit',
175
  array(
176
  'id' => $row->getId(),
177
  'customer_id' => $row->getData('magento_customer_id')
@@ -185,7 +185,7 @@ class SFC_Autoship_Block_Adminhtml_Customer_Paymentprofiles_Paymentprofile
185
  */
186
  public function getGridUrl()
187
  {
188
- return $this->getUrl('autoship_admin/adminhtml_paymentprofile/grid', array('_current' => true));
189
  }
190
 
191
  /**
@@ -204,7 +204,7 @@ class SFC_Autoship_Block_Adminhtml_Customer_Paymentprofiles_Paymentprofile
204
  $this->getMassactionBlock()->addItem('remove_profile', array(
205
  'label' => Mage::helper('autoship')->__('Delete Credit Card(s)'),
206
  'url' => $this->getUrl(
207
- 'autoship_admin/adminhtml_paymentprofile/massRemove',
208
  array(
209
  'customer_id' => $customer->getId(),
210
  )),
64
  protected function _prepareLayout()
65
  {
66
  // Build URL to add new payment profile
67
+ $urlString = 'adminhtml/sppaymentprofile/new';
68
  $url = $this->getUrl($urlString, array('customer_id' => Mage::registry('current_customer')->getId()));
69
 
70
  $button = $this->getLayout()->createBlock('adminhtml/widget_button');
171
  public function getRowUrl($row)
172
  {
173
  return $this->getUrl(
174
+ 'adminhtml/sppaymentprofile/edit',
175
  array(
176
  'id' => $row->getId(),
177
  'customer_id' => $row->getData('magento_customer_id')
185
  */
186
  public function getGridUrl()
187
  {
188
+ return $this->getUrl('adminhtml/sppaymentprofile/grid', array('_current' => true));
189
  }
190
 
191
  /**
204
  $this->getMassactionBlock()->addItem('remove_profile', array(
205
  'label' => Mage::helper('autoship')->__('Delete Credit Card(s)'),
206
  'url' => $this->getUrl(
207
+ 'adminhtml/sppaymentprofile/massRemove',
208
  array(
209
  'customer_id' => $customer->getId(),
210
  )),
app/code/local/SFC/Autoship/Block/Adminhtml/Sales/Order/Create/Billing/Method/Form.php ADDED
@@ -0,0 +1,56 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * @author Alan Barber <alan@cadence-labs.com>
4
+ */
5
+ class SFC_Autoship_Block_Adminhtml_Sales_Order_Create_Billing_Method_Form extends Mage_Adminhtml_Block_Sales_Order_Create_Billing_Method_Form
6
+ {
7
+ /**
8
+ * Check payment method model
9
+ *
10
+ * @param Mage_Payment_Model_Method_Abstract|null $method
11
+ * @return bool
12
+ */
13
+ protected function _canUseMethod($method)
14
+ {
15
+ $quote = $this->getQuote();
16
+
17
+ // Check config to see if extension functionality is enabled
18
+ if (Mage::getStoreConfig('autoship_general/general/enabled', $quote->getStore()) != '1') {
19
+ return parent::_canUseMethod($method);
20
+ }
21
+
22
+ // We should create subs during checkout, and we are checking a payment method other than Authorize.Net CIM
23
+ // If other payment method being used, only allow this when there are no subscriptions to create
24
+ // Get quote helper
25
+ /** @var SFC_Autoship_Helper_Quote $quoteHelper */
26
+ $quoteHelper = Mage::helper('autoship/quote');
27
+ // Check if quote has any subscriptions in it
28
+ if(!$quoteHelper->hasProductsToCreateNewSubscription($quote)) {
29
+ // Quote has no subscriptions,
30
+ // Go through normal qualification process for payment methods
31
+ return parent::_canUseMethod($method);
32
+ }
33
+ else {
34
+ // Quote has subscriptions, only allow payment methods compatible with subscriptions
35
+ // Get helper
36
+ /** @var SFC_Autoship_Helper_Platform $platformHelper */
37
+ $platformHelper = Mage::helper('autoship/platform');
38
+ /** @var SFC_Autoship_Helper_Api $apiHelper */
39
+ $apiHelper = Mage::helper('autoship/api');
40
+ $apiHelper->setConfigStore($quote->getStore());
41
+ // Lookup payment method code based on SP config
42
+ $configuredMethodCode = $platformHelper->getConfiguredPaymentMethodCode();
43
+ // Check for configured payment method code
44
+ if(0 === strpos($method->getCode(), $configuredMethodCode)) {
45
+ // This is the pay method which is allowed by Subscribe Pro config
46
+ // Run normal check
47
+ return parent::_canUseMethod($method);
48
+ }
49
+ else {
50
+ // This is some other payment method, not allowed when checking out and creating subscriptions
51
+ return false;
52
+ }
53
+
54
+ }
55
+ }
56
+ }
app/code/local/SFC/Autoship/Block/Adminhtml/Sales/Order/Create/Product/Subscription.php ADDED
@@ -0,0 +1,189 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * @author Alan Barber <alan@cadence-labs.com>
4
+ */
5
+ Class SFC_Autoship_Block_Adminhtml_Sales_Order_Create_Product_Subscription
6
+ extends Mage_Adminhtml_Block_Template
7
+ {
8
+ /**
9
+ * Get order item object from parent block
10
+ *
11
+ * @return Mage_Sales_Model_Quote_Item
12
+ */
13
+ public function getItem()
14
+ {
15
+ return $this->getParentBlock()->getData('item');
16
+ }
17
+
18
+ /**
19
+ * @return Mage_Sales_Model_Quote_Item
20
+ */
21
+ public function getQuoteItem()
22
+ {
23
+ return $this->getItem();
24
+ }
25
+
26
+ /**
27
+ * @return Mage_Catalog_Model_Product
28
+ */
29
+ public function getProduct()
30
+ {
31
+ return Mage::helper('autoship/quote')->getRelevantProductFromQuoteItem($this->getQuoteItem());
32
+ }
33
+
34
+ /**
35
+ * Return the product profile for the current product
36
+ *
37
+ * @return SFC_Autoship_Model_Platform_Product The Magento product profile entity object for the current product
38
+ */
39
+ public function getPlatformProduct()
40
+ {
41
+ return Mage::helper('autoship/platform')->getPlatformProduct($this->getProduct());
42
+ }
43
+
44
+ /**
45
+ * Indicates whether this product is eligible for subscription or not
46
+ *
47
+ * @return bool
48
+ */
49
+ public function isItemSubscriptionEligible()
50
+ {
51
+ // Check config to see if extension functionality is enabled
52
+ if (Mage::getStoreConfig('autoship_general/general/enabled') != '1') {
53
+ return false;
54
+ }
55
+
56
+ //Quote item is null when removing a product
57
+ if (!$this->getQuoteItem()) {
58
+ return false;
59
+ }
60
+
61
+ $platformProduct = $this->getPlatformProduct();
62
+
63
+ return $platformProduct->getEnabled();
64
+ }
65
+
66
+ /**
67
+ * Is this product a trial subscription product?
68
+ *
69
+ * @return boolean
70
+ */
71
+ public function isTrialProduct()
72
+ {
73
+ $platformProduct = $this->getPlatformProduct();
74
+
75
+ return ($platformProduct->getData('is_trial_product'));
76
+ }
77
+
78
+ /**
79
+ * Subscription option mode
80
+ *
81
+ * @return string
82
+ */
83
+ public function getSubscriptionOptionMode()
84
+ {
85
+ $platformProduct = $this->getPlatformProduct();
86
+
87
+ return ($platformProduct->getData('subscription_option_mode'));
88
+ }
89
+
90
+ /**
91
+ * Default subscription option
92
+ *
93
+ * @return string
94
+ */
95
+ public function getDefaultSubscriptionOption()
96
+ {
97
+ $platformProduct = $this->getPlatformProduct();
98
+
99
+ return ($platformProduct->getData('default_subscription_option'));
100
+ }
101
+
102
+ /**
103
+ * @return bool
104
+ */
105
+ public function isItemFlaggedToCreateNewSubscription()
106
+ {
107
+ // Check config to see if extension functionality is enabled
108
+ if (Mage::getStoreConfig('autoship_general/general/enabled') != '1') {
109
+ return false;
110
+ }
111
+
112
+ // Get quote item
113
+ $quoteItem = $this->getQuoteItem();
114
+ // Return subscription flag
115
+ return $quoteItem->getData('create_new_subscription_at_checkout');
116
+ }
117
+
118
+ /**
119
+ * Get new subscription interval set on current quote item
120
+ *
121
+ * @return string
122
+ */
123
+ public function getNewSubscriptionInterval()
124
+ {
125
+ // Get quote item
126
+ $quoteItem = $this->getQuoteItem();
127
+ // Return subscription flag
128
+ return $quoteItem->getData('new_subscription_interval');
129
+ }
130
+
131
+ /**
132
+ * Return eligible subscription intervals for this product
133
+ *
134
+ * @return array Array of eligible subscription interval strings (for example: One Month, Two Months, etc)
135
+ */
136
+ public function getIntervals()
137
+ {
138
+ return $this->getPlatformProduct()->getIntervals();
139
+ }
140
+
141
+ /**
142
+ * Gets minimal sales quantity
143
+ *
144
+ * @param Mage_Catalog_Model_Product $product
145
+ * @return int|null
146
+ */
147
+ public function getMinimalQty($product)
148
+ {
149
+ $stockItem = $product->getStockItem();
150
+ if ($stockItem) {
151
+ return ($stockItem->getMinSaleQty()
152
+ && $stockItem->getMinSaleQty() > 0 ? $stockItem->getMinSaleQty() * 1 : null);
153
+ }
154
+ return null;
155
+ }
156
+
157
+ /**
158
+ * Get default qty - either as preconfigured, or as 1.
159
+ * Also restricts it by minimal qty.
160
+ *
161
+ * @param null|Mage_Catalog_Model_Product $product
162
+ * @return int|float
163
+ */
164
+ public function getProductDefaultQty($product = null)
165
+ {
166
+ if (!$product) {
167
+ $product = $this->getProduct();
168
+ }
169
+
170
+ $qty = $this->getMinimalQty($product);
171
+ $config = $product->getPreconfiguredValues();
172
+ $configQty = $config->getQty();
173
+ if ($configQty > $qty) {
174
+ $qty = $configQty;
175
+ }
176
+
177
+ return $qty;
178
+ }
179
+
180
+ /**
181
+ * Return the discount text for display on product page
182
+ *
183
+ * @return string Discount text for product page
184
+ */
185
+ public function getDiscountText()
186
+ {
187
+ return Mage::helper('autoship/subscription')->getSubscriptionPriceText($this->getPlatformProduct(), $this->getProduct(), $this->getProductDefaultQty($this->getProduct()));
188
+ }
189
+ }
app/code/local/SFC/Autoship/Block/Adminhtml/System/Config/Form/TestConnectionButton.php CHANGED
@@ -46,7 +46,7 @@ class SFC_Autoship_Block_Adminhtml_System_Config_Form_TestConnectionButton exten
46
  public function getAjaxCheckUrl()
47
  {
48
  return Mage::helper('adminhtml')->getUrl(
49
- 'autoship_admin/adminhtml_testconnectionbutton/test',
50
  array(
51
  'website' => $this->getRequest()->getParam('website'),
52
  ));
46
  public function getAjaxCheckUrl()
47
  {
48
  return Mage::helper('adminhtml')->getUrl(
49
+ 'adminhtml/sptestconnectionbutton/test',
50
  array(
51
  'website' => $this->getRequest()->getParam('website'),
52
  ));
app/code/local/SFC/Autoship/Block/Cart/Product/Subscription.php CHANGED
@@ -71,6 +71,42 @@ class SFC_Autoship_Block_Cart_Product_Subscription extends Mage_Core_Block_Templ
71
  return $platformProduct->getEnabled();
72
  }
73
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
74
  /**
75
  * @return bool
76
  */
71
  return $platformProduct->getEnabled();
72
  }
73
 
74
+ /**
75
+ * Is this product a trial subscription product?
76
+ *
77
+ * @return boolean
78
+ */
79
+ public function isTrialProduct()
80
+ {
81
+ $platformProduct = $this->getPlatformProduct();
82
+
83
+ return ($platformProduct->getData('is_trial_product'));
84
+ }
85
+
86
+ /**
87
+ * Subscription option mode
88
+ *
89
+ * @return string
90
+ */
91
+ public function getSubscriptionOptionMode()
92
+ {
93
+ $platformProduct = $this->getPlatformProduct();
94
+
95
+ return ($platformProduct->getData('subscription_option_mode'));
96
+ }
97
+
98
+ /**
99
+ * Default subscription option
100
+ *
101
+ * @return string
102
+ */
103
+ public function getDefaultSubscriptionOption()
104
+ {
105
+ $platformProduct = $this->getPlatformProduct();
106
+
107
+ return ($platformProduct->getData('default_subscription_option'));
108
+ }
109
+
110
  /**
111
  * @return bool
112
  */
app/code/local/SFC/Autoship/Block/Checkout/Onepage/Payment/Methods.php CHANGED
@@ -64,17 +64,8 @@ class SFC_Autoship_Block_Checkout_Onepage_Payment_Methods extends SFC_Autoship_B
64
  // Check if quote has any subscriptions in it
65
  if(!$quoteHelper->hasProductsToCreateNewSubscription()) {
66
  // Quote has no subscriptions,
67
- // Check config setting for subscribe pro vault pay method
68
- if (0 === strpos($method->getCode(), SFC_Autoship_Helper_Platform::PAY_METHOD_CODE_SUBSCRIBE_PRO_VAULT) &&
69
- $method->getConfigData('active_non_subscription') != '1'
70
- ) {
71
- // This is SP vault pay method and "Enabled for Non-Subscription" is set to No
72
- return false;
73
- }
74
- else {
75
- // Go through normal qualification process for payment methods
76
- return parent::_canUseMethod($method);
77
- }
78
  }
79
  else {
80
  // Quote has subscriptions, only allow payment methods compatible with subscriptions
64
  // Check if quote has any subscriptions in it
65
  if(!$quoteHelper->hasProductsToCreateNewSubscription()) {
66
  // Quote has no subscriptions,
67
+ // Go through normal qualification process for payment methods
68
+ return parent::_canUseMethod($method);
 
 
 
 
 
 
 
 
 
69
  }
70
  else {
71
  // Quote has subscriptions, only allow payment methods compatible with subscriptions
app/code/local/SFC/Autoship/Block/Mysubscriptions/Subscription.php CHANGED
@@ -92,8 +92,6 @@ class SFC_Autoship_Block_Mysubscriptions_Subscription extends SFC_Autoship_Block
92
  default:
93
  return '';
94
 
95
- case SFC_Autoship_Helper_Platform::PAY_METHOD_CODE_PARADOX_TRANSARMOR:
96
- return $this->getUrl('transarmor/manage/');
97
  case SFC_Autoship_Helper_Platform::PAY_METHOD_CODE_SFC_CIM_10XX:
98
  return $this->getUrl('creditcards/index/new');
99
  case SFC_Autoship_Helper_Platform::PAY_METHOD_CODE_SFC_CIM:
92
  default:
93
  return '';
94
 
 
 
95
  case SFC_Autoship_Helper_Platform::PAY_METHOD_CODE_SFC_CIM_10XX:
96
  return $this->getUrl('creditcards/index/new');
97
  case SFC_Autoship_Helper_Platform::PAY_METHOD_CODE_SFC_CIM:
app/code/local/SFC/Autoship/Block/Payment/Form/Cc.php CHANGED
@@ -106,7 +106,7 @@ class SFC_Autoship_Block_Payment_Form_Cc extends Mage_Payment_Block_Form
106
  public function hasVerification()
107
  {
108
  if ($this->getMethod()) {
109
- $configData = $this->getMethod()->getConfigData('useccv');
110
  if (is_null($configData)) {
111
  return true;
112
  }
@@ -119,7 +119,7 @@ class SFC_Autoship_Block_Payment_Form_Cc extends Mage_Payment_Block_Form
119
 
120
  public function useSaveCardCheckbox()
121
  {
122
- $checkoutSaveCardCheckbox = (bool) $this->getMethod()->getConfigData('checkout_save_card_checkbox');
123
  $isGuestCheckout = ($this->getQuote()->getCheckoutMethod() == Mage_Sales_Model_Quote::CHECKOUT_METHOD_GUEST);
124
 
125
  return $checkoutSaveCardCheckbox && !$isGuestCheckout && !$this->forceSaveCard();
@@ -183,4 +183,19 @@ class SFC_Autoship_Block_Payment_Form_Cc extends Mage_Payment_Block_Form
183
  return $this->getQuote()->getBillingAddress();
184
  }
185
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
186
  }
106
  public function hasVerification()
107
  {
108
  if ($this->getMethod()) {
109
+ $configData = $this->getMethod()->getConfigData('useccv', $this->getQuote()->getStoreId());
110
  if (is_null($configData)) {
111
  return true;
112
  }
119
 
120
  public function useSaveCardCheckbox()
121
  {
122
+ $checkoutSaveCardCheckbox = (bool) $this->getMethod()->getConfigData('checkout_save_card_checkbox', $this->getQuote()->getStoreId());
123
  $isGuestCheckout = ($this->getQuote()->getCheckoutMethod() == Mage_Sales_Model_Quote::CHECKOUT_METHOD_GUEST);
124
 
125
  return $checkoutSaveCardCheckbox && !$isGuestCheckout && !$this->forceSaveCard();
183
  return $this->getQuote()->getBillingAddress();
184
  }
185
 
186
+ /**
187
+ * @return mixed
188
+ */
189
+ public function getCvv()
190
+ {
191
+ return $this->getInfoData('cc_cid');
192
+ }
193
+
194
+ /**
195
+ * @return int
196
+ */
197
+ public function getSaveCard()
198
+ {
199
+ return intval($this->getInfoData('save_card'));
200
+ }
201
  }
app/code/local/SFC/Autoship/Block/Payment/Form/Cc/Saved.php CHANGED
@@ -53,4 +53,17 @@ class SFC_Autoship_Block_Payment_Form_Cc_Saved extends SFC_Autoship_Block_Paymen
53
  return $vaultHelper->mapSubscribeProCardTypeToMagento($paymentProfile->getData('creditcard_type'), false);
54
  }
55
 
 
 
 
 
 
 
 
 
 
 
 
 
 
56
  }
53
  return $vaultHelper->mapSubscribeProCardTypeToMagento($paymentProfile->getData('creditcard_type'), false);
54
  }
55
 
56
+ /**
57
+ * Retrive has verification configuration
58
+ *
59
+ * @return boolean
60
+ */
61
+ public function hasVerification()
62
+ {
63
+ if ($this->getSavedPaymentProfile()->isThirdParty()) {
64
+ return false;
65
+ }
66
+ return parent::hasVerification();
67
+ }
68
+
69
  }
app/code/local/SFC/Autoship/Block/Payment/Profile/Edit.php CHANGED
@@ -44,11 +44,11 @@ class SFC_Autoship_Block_Payment_Profile_Edit extends Mage_Adminhtml_Block_Templ
44
  {
45
  if ($this->getIsNewProfile()) {
46
  // Creating a new profile
47
- return ' Enter New Credit Card ';
48
  }
49
  else {
50
  // Editing an existing profile
51
- return ' Edit Saved Credit Card XXXX' . $this->getData('cim_profile')->getData('creditcard_last_digits');
52
  }
53
  }
54
 
44
  {
45
  if ($this->getIsNewProfile()) {
46
  // Creating a new profile
47
+ return $this->helper('autoship')->__(' Enter New Credit Card ');
48
  }
49
  else {
50
  // Editing an existing profile
51
+ return $this->helper('autoship')->__(' Edit Saved Credit Card XXXX' . $this->getData('cim_profile')->getData('creditcard_last_digits'));
52
  }
53
  }
54
 
app/code/local/SFC/Autoship/Block/Product/Subscribe.php CHANGED
@@ -31,6 +31,12 @@ class SFC_Autoship_Block_Product_Subscribe extends SFC_Autoship_Block_Product_Vi
31
  return $this->getPlatformProduct()->getIntervals();
32
  }
33
 
 
 
 
 
 
 
34
  /**
35
  * Return the discount text for display on product page
36
  *
31
  return $this->getPlatformProduct()->getIntervals();
32
  }
33
 
34
+ public function getDefaultInterval()
35
+ {
36
+ // Lookup from product
37
+ return $this->getPlatformProduct()->getData('default_interval');
38
+ }
39
+
40
  /**
41
  * Return the discount text for display on product page
42
  *
app/code/local/SFC/Autoship/Block/Product/View.php CHANGED
@@ -67,6 +67,42 @@ class SFC_Autoship_Block_Product_View extends Mage_Catalog_Block_Product_View
67
  return $isProductEnabled;
68
  }
69
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
70
  /**
71
  * Return the price for purchasing the current product as a one time purchase, optionally format the returned price
72
  *
@@ -90,4 +126,23 @@ class SFC_Autoship_Block_Product_View extends Mage_Catalog_Block_Product_View
90
  return Mage::helper('autoship/subscription')->getSubscriptionPrice($this->getPlatformProduct(), $this->getProduct(), $this->getProductDefaultQty($this->getProduct()), $formatted);
91
  }
92
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
93
  }
67
  return $isProductEnabled;
68
  }
69
 
70
+ /**
71
+ * Is this product a trial subscription product?
72
+ *
73
+ * @return boolean
74
+ */
75
+ public function isTrialProduct()
76
+ {
77
+ $platformProduct = $this->getPlatformProduct();
78
+
79
+ return ($platformProduct->getData('is_trial_product'));
80
+ }
81
+
82
+ /**
83
+ * Subscription option mode
84
+ *
85
+ * @return string
86
+ */
87
+ public function getSubscriptionOptionMode()
88
+ {
89
+ $platformProduct = $this->getPlatformProduct();
90
+
91
+ return ($platformProduct->getData('subscription_option_mode'));
92
+ }
93
+
94
+ /**
95
+ * Default subscription option
96
+ *
97
+ * @return string
98
+ */
99
+ public function getDefaultSubscriptionOption()
100
+ {
101
+ $platformProduct = $this->getPlatformProduct();
102
+
103
+ return ($platformProduct->getData('default_subscription_option'));
104
+ }
105
+
106
  /**
107
  * Return the price for purchasing the current product as a one time purchase, optionally format the returned price
108
  *
126
  return Mage::helper('autoship/subscription')->getSubscriptionPrice($this->getPlatformProduct(), $this->getProduct(), $this->getProductDefaultQty($this->getProduct()), $formatted);
127
  }
128
 
129
+ /**
130
+ * Gets minimal sales quantity
131
+ *
132
+ * @param Mage_Catalog_Model_Product $product
133
+ * @return int|null
134
+ */
135
+ public function getMinimalQty($product)
136
+ {
137
+ $mageDefault = parent::getMinimalQty($product);
138
+ $platformProduct = $this->getPlatformProduct();
139
+ if ($platformProduct->getData('subscription_option_mode') == 'subscription_only') {
140
+ if ($platformProduct->getData('min_qty')) {
141
+ return (!is_null($mageDefault) && $mageDefault > $platformProduct->getData('min_qty'))
142
+ ? $mageDefault
143
+ : $platformProduct->getData('min_qty');
144
+ }
145
+ }
146
+ return $mageDefault;
147
+ }
148
  }
app/code/local/SFC/Autoship/Block/Subscription/Abstract.php CHANGED
@@ -83,6 +83,48 @@ class SFC_Autoship_Block_Subscription_Abstract extends Mage_Core_Block_Template
83
  }
84
  }
85
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
86
  /**
87
  * Return the price for purchasing the current product as a one time pruchase, optionally format the returned price
88
  *
83
  }
84
  }
85
 
86
+ public function getDefaultInterval()
87
+ {
88
+ // Lookup from product
89
+ return $this->getPlatformProduct()->getData('default_interval');
90
+ }
91
+
92
+ /**
93
+ * Is this product a trial subscription product?
94
+ *
95
+ * @return boolean
96
+ */
97
+ public function isTrialProduct()
98
+ {
99
+ $platformProduct = $this->getPlatformProduct();
100
+
101
+ return ($platformProduct->getData('is_trial_product'));
102
+ }
103
+
104
+ /**
105
+ * Subscription option mode
106
+ *
107
+ * @return string
108
+ */
109
+ public function getSubscriptionOptionMode()
110
+ {
111
+ $platformProduct = $this->getPlatformProduct();
112
+
113
+ return ($platformProduct->getData('subscription_option_mode'));
114
+ }
115
+
116
+ /**
117
+ * Default subscription option
118
+ *
119
+ * @return string
120
+ */
121
+ public function getDefaultSubscriptionOption()
122
+ {
123
+ $platformProduct = $this->getPlatformProduct();
124
+
125
+ return ($platformProduct->getData('default_subscription_option'));
126
+ }
127
+
128
  /**
129
  * Return the price for purchasing the current product as a one time pruchase, optionally format the returned price
130
  *
app/code/local/SFC/Autoship/Block/Subscription/Form/Payment.php CHANGED
@@ -124,7 +124,6 @@ class SFC_Autoship_Block_Subscription_Form_Payment extends SFC_Autoship_Block_Su
124
  {
125
  default:
126
  case SFC_Autoship_Helper_Platform::PAY_METHOD_CODE_SFC_CIM_10XX:
127
- case SFC_Autoship_Helper_Platform::PAY_METHOD_CODE_PARADOX_TRANSARMOR:
128
  return false;
129
 
130
  case SFC_Autoship_Helper_Platform::PAY_METHOD_CODE_SFC_CIM:
@@ -190,6 +189,7 @@ class SFC_Autoship_Block_Subscription_Form_Payment extends SFC_Autoship_Block_Su
190
  $cards[] = array(
191
  'payment_token' => $curProfile->getData('cim_payment_profile_id'),
192
  'creditcard_last_digits' => $curProfile->getData('customer_cardnumber'),
 
193
  );
194
  }
195
  break;
@@ -204,6 +204,7 @@ class SFC_Autoship_Block_Subscription_Form_Payment extends SFC_Autoship_Block_Su
204
  $cards[] = array(
205
  'payment_token' => $curProfile->getData('cim_payment_profile_id'),
206
  'creditcard_last_digits' => $curProfile->getData('customer_cardnumber'),
 
207
  );
208
  }
209
  break;
@@ -220,6 +221,7 @@ class SFC_Autoship_Block_Subscription_Form_Payment extends SFC_Autoship_Block_Su
220
  'creditcard_month' => $paymentProfile->getData('creditcard_month'),
221
  'creditcard_year' => $paymentProfile->getData('creditcard_year'),
222
  'edit_url' => Mage::getUrl('subscriptions/mycreditcards/edit') . 'id/' . $paymentProfile->getId(),
 
223
  );
224
  }
225
 
@@ -235,20 +237,7 @@ class SFC_Autoship_Block_Subscription_Form_Payment extends SFC_Autoship_Block_Su
235
  $cards[] = array(
236
  'payment_token' => $curProfile->getData('payment_token'),
237
  'creditcard_last_digits' => $curProfile->getData('customer_cardnumber'),
238
- );
239
- }
240
- break;
241
-
242
- case SFC_Autoship_Helper_Platform::PAY_METHOD_CODE_PARADOX_TRANSARMOR:
243
- // Lookup profiles for this customer
244
- $cardCollection = Mage::getModel('transarmor/card')->getCollection();
245
- $cardCollection
246
- ->addFieldToFilter('customer_id', $customer->getId());
247
- // Translate to std data structure
248
- foreach($cardCollection as $curCard) {
249
- $cards[] = array(
250
- 'payment_token' => $curCard->getData('trans_id'),
251
- 'creditcard_last_digits' => $curCard->getData('last4'),
252
  );
253
  }
254
  break;
124
  {
125
  default:
126
  case SFC_Autoship_Helper_Platform::PAY_METHOD_CODE_SFC_CIM_10XX:
 
127
  return false;
128
 
129
  case SFC_Autoship_Helper_Platform::PAY_METHOD_CODE_SFC_CIM:
189
  $cards[] = array(
190
  'payment_token' => $curProfile->getData('cim_payment_profile_id'),
191
  'creditcard_last_digits' => $curProfile->getData('customer_cardnumber'),
192
+ 'edit_url' => ''
193
  );
194
  }
195
  break;
204
  $cards[] = array(
205
  'payment_token' => $curProfile->getData('cim_payment_profile_id'),
206
  'creditcard_last_digits' => $curProfile->getData('customer_cardnumber'),
207
+ 'edit_url' => ''
208
  );
209
  }
210
  break;
221
  'creditcard_month' => $paymentProfile->getData('creditcard_month'),
222
  'creditcard_year' => $paymentProfile->getData('creditcard_year'),
223
  'edit_url' => Mage::getUrl('subscriptions/mycreditcards/edit') . 'id/' . $paymentProfile->getId(),
224
+ 'is_third_party' => $paymentProfile->isThirdParty()
225
  );
226
  }
227
 
237
  $cards[] = array(
238
  'payment_token' => $curProfile->getData('payment_token'),
239
  'creditcard_last_digits' => $curProfile->getData('customer_cardnumber'),
240
+ 'edit_url' => ''
 
 
 
 
 
 
 
 
 
 
 
 
 
241
  );
242
  }
243
  break;
app/code/local/SFC/Autoship/Helper/Adminorder.php CHANGED
@@ -1,4 +1,4 @@
1
- <?php //00612
2
  /**
3
  * Subscribe Pro - Subscriptions Management Extension
4
  *
@@ -15,109 +15,228 @@
15
  *
16
  */
17
 
18
- if(!extension_loaded('ionCube Loader')){$__oc=strtolower(substr(php_uname(),0,3));$__ln='/ioncube/ioncube_loader_'.$__oc.'_'.substr(phpversion(),0,3).(($__oc=='win')?'.dll':'.so');$__oid=$__id=realpath(ini_get('extension_dir'));$__here=dirname(__FILE__);if((@$__id[1])==':'){$__id=str_replace('\\','/',substr($__id,2));$__here=str_replace('\\','/',substr($__here,2));}$__rd=str_repeat('/..',substr_count($__id,'/')).$__here.'/';$__i=strlen($__rd);while($__i--){if($__rd[$__i]=='/'){$__lp=substr($__rd,0,$__i).$__ln;if(file_exists($__oid.$__lp)){$__ln=$__lp;break;}}}@dl($__ln);}else{die('The file '.__FILE__." is corrupted. Ensure that you use binary mode when transferring files with FTP and disable the 'TAR smart cr/lf feature' if using WinZIP\n");}if(function_exists('_il_exec')){return _il_exec();}die('The file <b>'.__FILE__.'</b> has been encoded with the <a href="http://www.ioncube.com">ionCube PHP Encoder</a> and requires the free '.basename($__ln).' <a href="http://www.ioncube.com/loader_download/">ionCube PHP Loader</a> to be installed.');
19
-
20
- ?>
21
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- kKiUvOCY4wJI2WfD7JNj+wlO5c3dcxMQrYsmL+1oeh5U6+msvKT/cUv4jV007TdcOx6U2FE54fv0
43
- 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
- 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
- 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
- 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
- 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
- mlLs6MPQDaHPtRdIR7lV7qD37b/NqH9ALhNwzPC2IF77tBWMolJrW1+61OlvIrI1yYTfYvx3BgPy
49
- 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
- SRjrsj44kyJ8h/L0J+rfx68WOIYxLIMbe2+Om8E3TCfod01HsYrlL+QxTsKCuGtE+6dJjBsMCv3l
51
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- yv9cgQ/cymlZPvGzjjbM7Wn6bQX+CAUZUim7eOmucg8Z9jpTgEGmESbMki+Evc6K8JDGqFvIAwiS
60
- 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
- QVM1G0q5vmLEecYwnXx3lq4r6SdqYLJP1N4NBTSKmMwoao9A0Q2UIj6Yy32BXQBJCOKt/qSX4KKX
62
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- QHTKAnkIR3hwI07goWhkA4dVtlaKj3eeO5AqwWdOvnLFFztBnzJtMi0KuuFVMrUgtwq4W5Rf76Uz
78
- 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
- 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
- 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
- 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
- hkVr45MIS1cQFXRnx8i9ByMvZ/yGQNfWNR1mP8+G1tC4RjWOBo4qf9lRfroSgCWLYWQRQgs3cbVm
83
- 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
- B1iUawCh33U1xyXLrhi5b987pTNHmO7xHut1AXuJeFQXTgudpNYbVQ73FiIXuqewO8PKgGitPvll
85
- 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
- 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
- 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
- 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
- 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
- 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
- bdrRm+sLOgpKuC0efC+msKTp3IKHfohA2SSg9wf9DLjgNroW20ZT8K8uLU4zYKC9dhm9j6i38lZy
92
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- jdZY+olJZgEoXDpd3GOcrcUZVH/Ojk8o/abybFzm4c7Av0b5oK/gozQgCn43Z55M390NQn47tD6I
107
- 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
- MSFeLfaxDlls+CzVEwOFM81J2vT8GY2e2hii0P+StgrEf+EugA66yRqHKDdCKQ6TMGeZ2IBWJUVc
109
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- kTJjPDDdDDX0EWjM4cAfA55qYYCSEYmOu9V6mY1t0IbBERnlBPfo37UW4fkDG+egeL+DOcQ0FeVo
118
- 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
- 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
- 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
- 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
- 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
123
- kjYHk/POMcLeCDg2SfoYZUTLWW==
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
  /**
3
  * Subscribe Pro - Subscriptions Management Extension
4
  *
15
  *
16
  */
17
 
18
+ /**
19
+ * Helper class - Access with Mage::helper('autoship/adminorder')
20
+ *
21
+ * Based on code from Mage_Adminhtml_Sales_Order_CreateController which calls Mage_Adminhtml_Model_Sales_Order_Create a lot
22
+ * With inspiration from {@link http://inchoo.net/ecommerce/magento/programmatically-create-order-in-magento/ Inchoo's Programmatically Creating and Order}
23
+ *
24
+ */
25
+ class SFC_Autoship_Helper_Adminorder extends Mage_Core_Helper_Abstract
26
+ {
27
+ /**
28
+ * Instance vars to hold details about quote / order
29
+ */
30
+ private $_storeId = '1';
31
+ private $_groupId = '1';
32
+ private $_paymentData;
33
+ private $_orderData;
34
+ private $_productQtys;
35
+ private $_customer;
36
+ private $_billingAddressId;
37
+ private $_shippingAddressId;
38
+
39
+ /**
40
+ * Set details for quote / order creation.
41
+ * Only SFC Authorize.NET CIM payment method is supported at this time
42
+ * @param Mage_Customer_Model_Customer $customer
43
+ * @param $storeId
44
+ * @param $productQtys
45
+ * @param $billingAddressId
46
+ * @param $shippingAddressId
47
+ * @param $cimPaymentProfileId
48
+ * @param $shippingMethod
49
+ */
50
+ public function setOrderDetails(Mage_Customer_Model_Customer $customer, $storeId, $productQtys, $billingAddressId,
51
+ $shippingAddressId, $cimPaymentProfileId, $shippingMethod)
52
+ {
53
+ // Save order info
54
+ $this->_storeId = $storeId;
55
+ $this->_customer = $customer;
56
+ $this->_billingAddressId = $billingAddressId;
57
+ $this->_shippingAddressId = $shippingAddressId;
58
+
59
+ // Save products array
60
+ $this->_productQtys = $productQtys;
61
+
62
+ // Build array of order data
63
+ $this->_orderData = array(
64
+ 'currency' => 'USD',
65
+ 'account' => array(
66
+ 'group_id' => $this->_groupId,
67
+ 'email' => $this->_customer->getEmail()
68
+ ),
69
+ 'shipping_method' => $shippingMethod,
70
+ );
71
+ // Build array of payment data
72
+ // Only SFC Authorize.NET CIM payment method is supported at this time
73
+ $this->_paymentData = array(
74
+ 'method' => SFC_AuthnetToken_Model_Cim::METHOD_CODE,
75
+ 'cc_cid' => null,
76
+ 'payment_profile_id' => $cimPaymentProfileId,
77
+ // TO DO: Lookup real cc last 4 digits
78
+ 'saved_cc_last_4' => '1111'
79
+ );
80
+ }
81
+
82
+ /**
83
+ * Retrieve order create model
84
+ *
85
+ * @return Mage_Adminhtml_Model_Sales_Order_Create
86
+ */
87
+ protected function _getOrderCreateModel()
88
+ {
89
+ return Mage::getSingleton('adminhtml/sales_order_create');
90
+ }
91
+
92
+ /**
93
+ * Retrieve session object
94
+ *
95
+ * @return Mage_Adminhtml_Model_Session_Quote
96
+ */
97
+ protected function _getSession()
98
+ {
99
+ return Mage::getSingleton('adminhtml/session_quote');
100
+ }
101
+
102
+ /**
103
+ * Initialize order creation session data
104
+ *
105
+ */
106
+ protected function _initSession($customerId, $storeId)
107
+ {
108
+ /* Get/identify customer */
109
+ $this->_getSession()->setCustomerId((int)$customerId);
110
+ /* Get/identify store */
111
+ $this->_getSession()->setStoreId((int)$storeId);
112
+
113
+ return $this;
114
+ }
115
+
116
+ /**
117
+ * Creates order from info in instance vars
118
+ */
119
+ public function createOrder()
120
+ {
121
+ try {
122
+ // Log
123
+ Mage::log('Initing quote session...', Zend_Log::INFO, SFC_Autoship_Helper_Data::LOG_FILE);
124
+ // Init session (Mage_Adminhtml_Model_Session_Quote)
125
+ $this->_initSession($this->_customer->getId(), $this->_storeId);
126
+ // Log
127
+ Mage::log('Creating quote...', Zend_Log::INFO, SFC_Autoship_Helper_Data::LOG_FILE);
128
+ // Create quote
129
+ $this->createQuote();
130
+ // Log
131
+ Mage::log('Setting payment method data...', Zend_Log::INFO, SFC_Autoship_Helper_Data::LOG_FILE);
132
+ // Set payment data on quote
133
+ $this->_getOrderCreateModel()->setPaymentData($this->_paymentData);
134
+ $this->_getOrderCreateModel()->getQuote()->getPayment()->addData($this->_paymentData);
135
+ // Set product options
136
+ // TO DO: Handle product options, configurable products, etc
137
+ /*
138
+ $item = $this->_getOrderCreateModel()->getQuote()->getItemByProduct($this->_product);
139
+ $item->addOption(new Varien_Object(
140
+ array(
141
+ 'product' => $this->_product,
142
+ 'code' => 'option_ids',
143
+ 'value' => '5' // Option id goes here. If more options, then comma separate
144
+ )
145
+ ));
146
+ $item->addOption(new Varien_Object(
147
+ array(
148
+ 'product' => $this->_product,
149
+ 'code' => 'option_5',
150
+ 'value' => 'Some value here'
151
+ )
152
+ ));
153
+ */
154
+ // Log
155
+ Mage::log('Placing order...', Zend_Log::INFO, SFC_Autoship_Helper_Data::LOG_FILE);
156
+ // Adjust Mage config
157
+ Mage::app()->getStore()->setConfig(Mage_Sales_Model_Order::XML_PATH_EMAIL_ENABLED, '0');
158
+ $order = $this->_getOrderCreateModel()->createOrder();
159
+ // Clear the session object
160
+ $this->_getSession()->clear();
161
+ // Unregister 'rule_data'
162
+ // TO DO: Why do we need to do this manually?
163
+ Mage::unregister('rule_data');
164
+ // Log
165
+ Mage::log('New order created: ' . $order->getIncrementId(), Zend_Log::INFO, SFC_Autoship_Helper_Data::LOG_FILE);
166
+
167
+ // Return newly created order
168
+ return $order;
169
+ }
170
+ catch (Exception $e) {
171
+ // Unregister 'rule_data'
172
+ // TO DO: Why do we need to do this manually?
173
+ Mage::unregister('rule_data');
174
+ // Log
175
+ Mage::log('Error placing order!', Zend_Log::ERR, SFC_Autoship_Helper_Data::LOG_FILE);
176
+ Mage::log('Error message: ' . $e->getMessage(), Zend_Log::ERR, SFC_Autoship_Helper_Data::LOG_FILE);
177
+ // Rethrow exception
178
+ throw $e;
179
+ }
180
+ }
181
+
182
+ /**
183
+ * Creates quote from info in instance vars
184
+ */
185
+ protected function createQuote()
186
+ {
187
+ // Log
188
+ Mage::log('Setting quote data...', Zend_Log::INFO, SFC_Autoship_Helper_Data::LOG_FILE);
189
+ $this->_getOrderCreateModel()->importPostData($this->_orderData);
190
+
191
+ // Log
192
+ Mage::log('Setting billing address...', Zend_Log::INFO, SFC_Autoship_Helper_Data::LOG_FILE);
193
+ // Create and set billing address
194
+ $customerAddress = Mage::getModel('customer/address')->load($this->_billingAddressId);
195
+ $billingAddress = Mage::getModel('sales/quote_address');
196
+ $billingAddress
197
+ ->importCustomerAddress($customerAddress)
198
+ ->setSaveInAddressBook(0)
199
+ ->setAddressType(Mage_Sales_Model_Quote_Address::TYPE_BILLING);
200
+ // There is a bug in Mage_Adminhtml_Model_Sales_Order_Create::setBillingAddress
201
+ // Work around this bug by calling setBillingAddress() directly on the quote object
202
+ $this->_getOrderCreateModel()->getQuote()->setBillingAddress($billingAddress);
203
+
204
+ // Log
205
+ Mage::log('Setting shipping address...', Zend_Log::INFO, SFC_Autoship_Helper_Data::LOG_FILE);
206
+ $customerAddress = Mage::getModel('customer/address')->load($this->_shippingAddressId);
207
+ $shippingAddress = Mage::getModel('sales/quote_address');
208
+ $shippingAddress
209
+ ->importCustomerAddress($customerAddress)
210
+ ->setSameAsBilling(0)
211
+ ->setSaveInAddressBook(0)
212
+ ->setAddressType(Mage_Sales_Model_Quote_Address::TYPE_SHIPPING);
213
+ $this->_getOrderCreateModel()->setShippingAddress($shippingAddress);
214
+
215
+ // Log
216
+ Mage::log('Adding products...', Zend_Log::INFO, SFC_Autoship_Helper_Data::LOG_FILE);
217
+ // Just like adding products from Magento admin grid
218
+ $this->_getOrderCreateModel()->addProducts($this->_productQtys);
219
+ // Log
220
+ Mage::log('Collecting shipping rates...', Zend_Log::INFO, SFC_Autoship_Helper_Data::LOG_FILE);
221
+ $this->_getOrderCreateModel()->collectShippingRates();
222
+ // Log
223
+ Mage::log('Setting payment data...', Zend_Log::INFO, SFC_Autoship_Helper_Data::LOG_FILE);
224
+ // Setting payment data
225
+ $this->_getOrderCreateModel()->getQuote()->getPayment()->addData($this->_paymentData);
226
+
227
+ // Log
228
+ Mage::log('Saving quote...', Zend_Log::INFO, SFC_Autoship_Helper_Data::LOG_FILE);
229
+ // Init rule data and save quote
230
+ $this->_getOrderCreateModel()
231
+ ->initRuleData()
232
+ ->saveQuote();
233
+
234
+ // Log
235
+ Mage::log('Setting payment data...', Zend_Log::INFO, SFC_Autoship_Helper_Data::LOG_FILE);
236
+ // Setting payment data (again)
237
+ $this->_getOrderCreateModel()->getQuote()->getPayment()->addData($this->_paymentData);
238
+
239
+ return $this;
240
+ }
241
+
242
+ }
app/code/local/SFC/Autoship/Helper/Api.php CHANGED
@@ -1,4 +1,4 @@
1
- <?php //00612
2
  /**
3
  * Subscribe Pro - Subscriptions Management Extension
4
  *
@@ -15,276 +15,774 @@
15
  *
16
  */
17
 
18
- if(!extension_loaded('ionCube Loader')){$__oc=strtolower(substr(php_uname(),0,3));$__ln='/ioncube/ioncube_loader_'.$__oc.'_'.substr(phpversion(),0,3).(($__oc=='win')?'.dll':'.so');$__oid=$__id=realpath(ini_get('extension_dir'));$__here=dirname(__FILE__);if((@$__id[1])==':'){$__id=str_replace('\\','/',substr($__id,2));$__here=str_replace('\\','/',substr($__here,2));}$__rd=str_repeat('/..',substr_count($__id,'/')).$__here.'/';$__i=strlen($__rd);while($__i--){if($__rd[$__i]=='/'){$__lp=substr($__rd,0,$__i).$__ln;if(file_exists($__oid.$__lp)){$__ln=$__lp;break;}}}@dl($__ln);}else{die('The file '.__FILE__." is corrupted. Ensure that you use binary mode when transferring files with FTP and disable the 'TAR smart cr/lf feature' if using WinZIP\n");}if(function_exists('_il_exec')){return _il_exec();}die('The file <b>'.__FILE__.'</b> has been encoded with the <a href="http://www.ioncube.com">ionCube PHP Encoder</a> and requires the free '.basename($__ln).' <a href="http://www.ioncube.com/loader_download/">ionCube PHP Loader</a> to be installed.');
19
-
20
- ?>
21
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- kPr4icy0NA1jqIzfp6w9xHaIYt2+IRXkDwSUH3KthgwKVeYTLtPS0yb65xxL6RWGfjT+0AG3qNJj
34
- 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
- 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
- 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
- ijak8CHKmNxyBQq/8XsMwrYc80IXzEavcXrn9lfPW1XvUH0jQ0y4rQ+gkOYbhCPFuvM2g1Z/mgZe
38
- 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
- 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
- 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
- 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
- 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
- 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
- +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
- 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
- rN2zbfAeLthZsq6p7aj9dtT9SfahpCrHhUMjsmBwLUxdOkyoInp/wrIKNNVdgj7Sz58hOvfl68OW
47
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- s1zzkAQ1sbrAlD607prLJ1pnsnyL+W1DGu564aLTJUcgM3VX3Pc1N0p+F+CDLcpwIZUrGDhk41AM
60
- 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
- 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
- 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
- r+hyp+N6GUfcEkp2SvMk549yIVIfGaNgoEdp0EU2OKg5hfwSpaSzQPRXHLU1oL9Sml4Wl9C6Ihha
64
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- LGftu6xZ4UVI7s0C3Du4IQn+69At/zCxjrFrYhS8zeYkDd13Ypz6mvSK2lW51pTjYxlQYoJiWSPm
83
- 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
- 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
- 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
- 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
- 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
- tdkUNIlbIN0crNlpf8iuaEFva3Sefdc7aN/1ve1urZxfP5ggM/BQcu3whPgKGIqXptPcCOnPt0+n
89
- rHZkBDc/8OmF+P4zw4QUdZisn83BDpMogsU5hMe89gmfgMqa+MBt6YbrcDy8tPpKkMd+mAWSFQWI
90
- ah7t7dP9JXWetwB8XGeL/xi1EqtJKe7O65w6ugduHpWxVem6d5ROsS+fXgoKSgIS9So+ScbFXtiM
91
- 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
- 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
- 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
- GKjFjH8KSqiMCWyG007YpuF7I/Gd09ATAZdSFHFAq/gLZUdmUIW+/Uunry9K4j38MLmQnauceGbM
95
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- TVTK/ArIa10Ql33zLTzzOslWtgFAqjEic7bdj6mhfi/IyWKiAAxPu6hvGY47kDVlSoukEwd9SPV/
105
- U6SU4JlZ9DKhpta6DGWFUa7XxZQTwtoTFlD1SY6UZ7CYvTLjBKe3pp1OeWaCcXlLw26Lt8C6A1A7
106
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- exOz3ie/8P8zGle9+gzhYVybWPkBAJU3M1MY81HAeFsA9PJnuCXGfWtYWQJLG7s93nxgPB0HdkZI
114
- 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
- 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
- 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
- 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
- J6VSUDYVXI92V6fcXvCAJAq1XjUuufLh4TMyUQHoc/ECUN7GuphWGOzk7OLKIzhK0IHgnvfeA3IM
119
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- Ws6KKbMk3UbQq7xJArRKyQ/iqZkCayzNVd6Fd2cEWsC2Ks5nD48SzoUvTxahhOmI2V+og33KVh2o
131
- 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
- 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
- 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
- 4XlFSZs5iyuI6JOjHmTqqpBjVGKIRm6LJ3913FjdPDHVsLTlCH5AXIa38JkMelfy9ATL4m7w9teI
135
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 19jl8hkT9j7QOW2bz+wcPnlA7JVaw6ghM1pgvfau/nQhU3Dc8f2mZVEiOmGYbQ1b8qiHWydRRSnS
144
- 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
- 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
- 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
- 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
- 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
- RFJub8aF0maCmBE2xa/0MQ6fVhG6i9ys63eYfS5DMpa49kAtNufsFp4VCbGf080/QmQoyaEhCxRT
150
- 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
- 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
- jpI+wpNWR9cZJRsTSQeQAFFWx+BSWVcA3lvqvk/lRSZmOy7pLN2oHCAdKxRf/vZGXO1JhI51ajx5
153
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- +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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 9IOOSwoCgUBxwrzZCtL9q7z/6FGtrqKWnncGSKoy8Jb7xXdMQJONtffQ565AI0SuUin0odjrA3DK
178
- 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
- 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
- 3RYuXWqvzYwcBTDK3/EGNS7HOGCW11Jl+dR/evGE7UcPDcLRSz3ii+JieGrKAPX5S4xbroRZo7G6
181
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- PEW7AdPPXKoLw3u2lAu/G8EEKa2YZ2L9nv3kIb2juZdWE0BHm6Sze9kmqCu7uQqTFu0zUJSCPRbc
192
- 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
- 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
- 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
- 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
- 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
- 9STKjYFYUPxNwRPvGp7LYOvQEbZU1UallrY0eWxTVUXVJK5qGeXBIkdNFdYZmRjRJDCvBGl9cvqw
198
- Pu9lgwGOUVazQv1wxY9y022xXKP6iCetHSb3jatFPXkucRLVrQCBxnv8Z7GkHA7umTVkq9M20Zzk
199
- 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
- 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
- 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
- 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
- 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
- Bi20R68hzZa4+UwmXAW5gR/s7qe6d4pEcjxZyfBxD0OtRcmLsnlb7HqmqdH9Xr3A3Z/W1WTRWNcn
205
- 03gnZE/DfhUw3Dt171e4deEdIpMFAn609EuzHN3ZVvoxSS9u+1pWl7l1cRlBJG4KWncYdITZvzu5
206
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- /uexhK3TYtczoFeZTunss4tBJT+do7di5m3gU/bPPSRM2H9NkvjECF279I5J4wTIstoEB3cwqfWz
236
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- HHLKZAUBbXWuNKYnXcdCnQqcfw4rDEMxsAA4Jivkv+CFOxed770JS50CrODK4jJqSVw4k6vzfuFm
248
- +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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- LckOtFzx1WLobSK4lKbvsFrjvJeMqJFhU7IjIwsMU4nTl8fw/TSYE7lF0x51NLwJYsQWSy9b8bx3
257
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- V6Wf5ulxeWGScTYB/9UBnQtDzKY4QLQ+ZeAr8AoXq5RxLQ9R2YHppz79X/DBgmiCueArv8AIaPXJ
288
- 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
- ZX5B3+sY6h7iidCtM23aifLJXMWMrA4U7LKUnPvgsfjR9gx2JHl1Om0KVxhEssPD5V4pVNWdI6ln
290
- ACR3vLT7Eti8wIsQFxv2GZM1
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
  /**
3
  * Subscribe Pro - Subscriptions Management Extension
4
  *
15
  *
16
  */
17
 
18
+ require('OAuth2/Client.php');
19
+ require('OAuth2/GrantType/IGrantType.php');
20
+ require('OAuth2/GrantType/Password.php');
21
+ require('OAuth2/GrantType/ClientCredentials.php');
22
+
23
+ class SFC_Autoship_Helper_Api extends Mage_Core_Helper_Abstract
24
+ {
25
+ // Log file name
26
+ const PLATFORM_API_PATH = '/services/v1';
27
+ const PLATFORM_API_PATH_20 = '/services/v2';
28
+ const PLATFORM_API_PATH_TOKEN = '/oauth/v2/token';
29
+
30
+ // Cache Type Tags
31
+ const CACHE_TYPE_CONFIG = 'SP_CONFIG';
32
+ const CACHE_TYPE_PRODUCTS = 'SP_PRODUCTS';
33
+
34
+ const CACHE_TOKEN_TAG = 'autoship_api_access_token';
35
+
36
+ /** @var Mage_Core_Model_Store|null */
37
+ private $_store = null;
38
+
39
+ public function __construct()
40
+ {
41
+ }
42
+
43
+ /**
44
+ * Set the primary key id of the store to use for all configuration scope
45
+ *
46
+ * @param int|Mage_Core_Model_Store $store Primary key id of the store to use
47
+ */
48
+ public function setConfigStore($store)
49
+ {
50
+ if ($store instanceof Mage_Core_Model_Store) {
51
+ $this->_store = $store;
52
+ }
53
+ else {
54
+ $this->_store = Mage::app()->getStore($store);
55
+ }
56
+ }
57
+
58
+ /**
59
+ * Return the store to use for pulling configuration settings
60
+ *
61
+ * @return Mage_Core_Model_Store
62
+ */
63
+ public function getConfigStore()
64
+ {
65
+ if ($this->_store == null) {
66
+ $this->_store = Mage::app()->getStore();
67
+ }
68
+ return $this->_store;
69
+ }
70
+
71
+ protected function getServicesUrl()
72
+ {
73
+ return 'https://' . Mage::getStoreConfig('autoship_general/platform_api/platform_host', $this->getConfigStore()) . self::PLATFORM_API_PATH;
74
+ }
75
+
76
+ protected function getServicesUrlV2()
77
+ {
78
+ return 'https://' . Mage::getStoreConfig('autoship_general/platform_api/platform_host', $this->getConfigStore()) . self::PLATFORM_API_PATH_20;
79
+ }
80
+
81
+ protected function getOAuthTokenUrl()
82
+ {
83
+ return 'https://' . Mage::getStoreConfig('autoship_general/platform_api/platform_host', $this->getConfigStore()) . self::PLATFORM_API_PATH_TOKEN;
84
+ }
85
+
86
+ public function fetchCustomers($params = array())
87
+ {
88
+ // Request customers
89
+ $customers = $this->makeRequest(
90
+ $this->getServicesUrl() . '/customers.json',
91
+ $params,
92
+ OAuth2\Client::HTTP_METHOD_GET);
93
+
94
+ // Return customers
95
+ return $customers;
96
+ }
97
+
98
+ public function fetchCustomer($customerId)
99
+ {
100
+ // Request customer
101
+ $customer = $this->makeRequest(
102
+ $this->getServicesUrl() . '/customers/' . $customerId . '.json',
103
+ array(),
104
+ OAuth2\Client::HTTP_METHOD_GET);
105
+
106
+ // Return customer
107
+ return $customer;
108
+ }
109
+
110
+ public function updateCustomer($customerId, $customer)
111
+ {
112
+ // Request customer
113
+ $customer = $this->makeRequest(
114
+ $this->getServicesUrl() . '/customers/' . $customerId . '.json',
115
+ json_encode($customer),
116
+ OAuth2\Client::HTTP_METHOD_PUT);
117
+
118
+ // Return customer
119
+ return $customer;
120
+ }
121
+
122
+ public function deleteCustomer($customerId)
123
+ {
124
+ // Request customer
125
+ $this->makeRequest(
126
+ $this->getServicesUrl() . '/customers/' . $customerId . '.json',
127
+ array(),
128
+ OAuth2\Client::HTTP_METHOD_DELETE);
129
+ }
130
+
131
+ public function postCustomer($customer)
132
+ {
133
+ // Request customer
134
+ $result = $this->makeRequest(
135
+ $this->getServicesUrl() . '/customers.json',
136
+ json_encode($customer),
137
+ OAuth2\Client::HTTP_METHOD_POST);
138
+
139
+ // Check result
140
+ // Return result for now
141
+ return $result;
142
+ }
143
+
144
+ public function fetchCustomerAddresses($customerId, $params = array())
145
+ {
146
+ // Request
147
+ $addresses = $this->makeRequest(
148
+ $this->getServicesUrl() . '/customers/' . $customerId . '/addresses.json',
149
+ $params,
150
+ OAuth2\Client::HTTP_METHOD_GET);
151
+
152
+ // Return
153
+ return $addresses;
154
+ }
155
+
156
+ public function fetchCustomerAddress($customerId, $addressId)
157
+ {
158
+ // Request
159
+ $address = $this->makeRequest(
160
+ $this->getServicesUrl() . '/customers/' . $customerId . '/addresses/' . $addressId . '.json',
161
+ array(),
162
+ OAuth2\Client::HTTP_METHOD_GET);
163
+
164
+ // Return
165
+ return $address;
166
+ }
167
+
168
+ public function updateCustomerAddress($customerId, $addressId, $address)
169
+ {
170
+ // Request
171
+ $address = $this->makeRequest(
172
+ $this->getServicesUrl() . '/customers/' . $customerId . '/addresses/' . $addressId . '.json',
173
+ json_encode($address),
174
+ OAuth2\Client::HTTP_METHOD_PUT);
175
+
176
+ // Return customer
177
+ return $address;
178
+ }
179
+
180
+ public function deleteCustomerAddress($customerId, $addressId)
181
+ {
182
+ // Request
183
+ $this->makeRequest(
184
+ $this->getServicesUrl() . '/customers/' . $customerId . '/addresses/' . $addressId . '.json',
185
+ array(),
186
+ OAuth2\Client::HTTP_METHOD_DELETE);
187
+ }
188
+
189
+ public function postCustomerAddress($customerId, $address)
190
+ {
191
+ // Request
192
+ $result = $this->makeRequest(
193
+ $this->getServicesUrl() . '/customers/' . $customerId . '/addresses.json',
194
+ json_encode($address),
195
+ OAuth2\Client::HTTP_METHOD_POST);
196
+
197
+ // Check result
198
+ // Return result for now
199
+ return $result;
200
+ }
201
+
202
+ public function fetchSubscriptions($params = array())
203
+ {
204
+ // Request subscriptions
205
+ $subscriptions = $this->makeRequest(
206
+ $this->getServicesUrl() . '/subscriptions.json',
207
+ $params,
208
+ OAuth2\Client::HTTP_METHOD_GET);
209
+
210
+ // Return subscriptions
211
+ return $subscriptions;
212
+ }
213
+
214
+ public function fetchSubscription($subscriptionId)
215
+ {
216
+ // Request subscription
217
+ $subscription = $this->makeRequest(
218
+ $this->getServicesUrl() . '/subscriptions/' . $subscriptionId . '.json',
219
+ array(),
220
+ OAuth2\Client::HTTP_METHOD_GET);
221
+
222
+ // Return subscription
223
+ return $subscription;
224
+ }
225
+
226
+ public function updateSubscription($subscriptionId, $subscription)
227
+ {
228
+ // Request subscription
229
+ $subscription = $this->makeRequest(
230
+ $this->getServicesUrl() . '/subscriptions/' . $subscriptionId . '.json',
231
+ json_encode($subscription),
232
+ OAuth2\Client::HTTP_METHOD_PUT);
233
+
234
+ // Return subscription
235
+ return $subscription;
236
+ }
237
+
238
+ public function cancelSubscription($subscriptionId)
239
+ {
240
+ // Request subscription
241
+ $response = $this->makeRequest(
242
+ $this->getServicesUrlV2() . '/subscriptions/' . $subscriptionId . '/cancel.json',
243
+ array(),
244
+ OAuth2\Client::HTTP_METHOD_POST);
245
+
246
+ // Return response
247
+ return $response;
248
+ }
249
+
250
+ public function pauseSubscription($subscriptionId)
251
+ {
252
+ // Request subscription
253
+ $response = $this->makeRequest(
254
+ $this->getServicesUrlV2() . '/subscriptions/' . $subscriptionId . '/pause.json',
255
+ array(),
256
+ OAuth2\Client::HTTP_METHOD_POST);
257
+
258
+ // Return response
259
+ return $response;
260
+ }
261
+
262
+ public function restartSubscription($subscriptionId)
263
+ {
264
+ // Request subscription
265
+ $response = $this->makeRequest(
266
+ $this->getServicesUrlV2() . '/subscriptions/' . $subscriptionId . '/restart.json',
267
+ array(),
268
+ OAuth2\Client::HTTP_METHOD_POST);
269
+
270
+ // Return response
271
+ return $response;
272
+ }
273
+
274
+ public function skipSubscription($subscriptionId)
275
+ {
276
+ // Request subscription
277
+ $response = $this->makeRequest(
278
+ $this->getServicesUrlV2() . '/subscriptions/' . $subscriptionId . '/skip.json',
279
+ array(),
280
+ OAuth2\Client::HTTP_METHOD_POST);
281
+
282
+ // Return response
283
+ return $response;
284
+ }
285
+
286
+ public function postSubscription($subscription)
287
+ {
288
+ // Request subscription
289
+ $result = $this->makeRequest(
290
+ $this->getServicesUrl() . '/subscriptions.json',
291
+ json_encode($subscription),
292
+ OAuth2\Client::HTTP_METHOD_POST);
293
+
294
+ // Check result
295
+ // Return result for now
296
+ return $result;
297
+ }
298
+
299
+ public function fetchSubscriptionProducts($subscriptionId, $params = array())
300
+ {
301
+ // Request
302
+ $products = $this->makeRequest(
303
+ $this->getServicesUrl() . '/subscriptions/' . $subscriptionId . '/products.json',
304
+ $params,
305
+ OAuth2\Client::HTTP_METHOD_GET);
306
+
307
+ // Return
308
+ return $products;
309
+ }
310
+
311
+ public function fetchSubscriptionProduct($subscriptionId, $productId)
312
+ {
313
+ // Request
314
+ $product = $this->makeRequest(
315
+ $this->getServicesUrl() . '/subscriptions/' . $subscriptionId . '/products/' . $productId . '.json',
316
+ array(),
317
+ OAuth2\Client::HTTP_METHOD_GET);
318
+
319
+ // Return
320
+ return $product;
321
+ }
322
+
323
+ public function updateSubscriptionProduct($subscriptionId, $productId, $product)
324
+ {
325
+ // Request
326
+ $product = $this->makeRequest(
327
+ $this->getServicesUrl() . '/subscriptions/' . $subscriptionId . '/products/' . $productId . '.json',
328
+ json_encode($product),
329
+ OAuth2\Client::HTTP_METHOD_PUT);
330
+
331
+ // Return customer
332
+ return $product;
333
+ }
334
+
335
+ public function deleteSubscriptionProduct($subscriptionId, $productId)
336
+ {
337
+ // Request
338
+ $this->makeRequest(
339
+ $this->getServicesUrl() . '/subscriptions/' . $subscriptionId . '/products/' . $productId . '.json',
340
+ array(),
341
+ OAuth2\Client::HTTP_METHOD_DELETE);
342
+ }
343
+
344
+ public function postSubscriptionProduct($subscriptionId, $product)
345
+ {
346
+ // Request
347
+ $result = $this->makeRequest(
348
+ $this->getServicesUrl() . '/subscriptions/' . $subscriptionId . '/products.json',
349
+ json_encode($product),
350
+ OAuth2\Client::HTTP_METHOD_POST);
351
+
352
+ // Check result
353
+ // Return result for now
354
+ return $result;
355
+ }
356
+
357
+ public function fetchProducts(array $params = array())
358
+ {
359
+ // Lookup products in cache
360
+ $products = $this->loadCache($this->getProductsCacheKey($params), self::CACHE_TYPE_PRODUCTS);
361
+ // Check if products found in cache
362
+ if ($products == null) {
363
+ // Request products from API
364
+ $products = $this->makeRequest(
365
+ $this->getServicesUrl() . '/products.json',
366
+ $params,
367
+ OAuth2\Client::HTTP_METHOD_GET);
368
+ // Save products in cache
369
+ $this->saveCache($products, $this->getProductsCacheKey($params), self::CACHE_TYPE_PRODUCTS);
370
+ }
371
+
372
+ // Return products
373
+ return $products;
374
+ }
375
+
376
+ protected function getProductsCacheKey(array $params)
377
+ {
378
+ $cacheKey = 'autoship_api_products';
379
+ foreach ($params as $param => $value) {
380
+ $cacheKey .= '_param_' . $param . '_value_' . $value;
381
+ }
382
+
383
+ return $cacheKey;
384
+ }
385
+
386
+ public function fetchProduct($productId)
387
+ {
388
+ // Lookup product in cache
389
+ $product = $this->loadCache($this->getProductCacheKey($productId), self::CACHE_TYPE_PRODUCTS);
390
+ // Check if product found in cache
391
+ if ($product == null) {
392
+ // Product not found in cache
393
+ // Request product from API
394
+ $product = $this->makeRequest(
395
+ $this->getServicesUrl() . '/products/' . $productId . '.json',
396
+ array(),
397
+ OAuth2\Client::HTTP_METHOD_GET);
398
+ // Save product in cache
399
+ $this->saveCache($product, $this->getProductCacheKey($productId), self::CACHE_TYPE_PRODUCTS);
400
+ }
401
+
402
+ // Return product
403
+ return $product;
404
+ }
405
+
406
+ protected function getProductCacheKey($productId)
407
+ {
408
+ return 'autoship_api_product_' . $productId;
409
+ }
410
+
411
+ public function updateProduct($productId, $product)
412
+ {
413
+ // Request product
414
+ $product = $this->makeRequest(
415
+ $this->getServicesUrl() . '/products/' . $productId . '.json',
416
+ json_encode($product),
417
+ OAuth2\Client::HTTP_METHOD_PUT);
418
+
419
+ // Return product
420
+ return $product;
421
+ }
422
+
423
+ public function deleteProduct($productId)
424
+ {
425
+ // Request product
426
+ $this->makeRequest(
427
+ $this->getServicesUrl() . '/products/' . $productId . '.json',
428
+ array(),
429
+ OAuth2\Client::HTTP_METHOD_DELETE);
430
+ }
431
+
432
+ public function postProduct($product)
433
+ {
434
+ // Request product
435
+ $result = $this->makeRequest(
436
+ $this->getServicesUrl() . '/products.json',
437
+ json_encode($product),
438
+ OAuth2\Client::HTTP_METHOD_POST);
439
+
440
+ // Check result
441
+ // Return result for now
442
+ return $result;
443
+ }
444
+
445
+ /**
446
+ * @param $code
447
+ * @return array
448
+ */
449
+ public function fetchReport($code)
450
+ {
451
+ //Request report
452
+ //Pass 'allow_result_string' so API helper doesn't throw an error just because the platform returned a CSV
453
+ $result = $this->makeRequest(
454
+ $this->getServicesUrlV2() . '/reports/' . $code,
455
+ array('allow_result_string' => true),
456
+ OAuth2\Client::HTTP_METHOD_GET
457
+ );
458
+
459
+ //Return result for now
460
+ return $result;
461
+ }
462
+
463
+ public function fetchConfig()
464
+ {
465
+ // Lookup config in cache
466
+ $config = $this->loadCache('autoship_api_config', self::CACHE_TYPE_CONFIG);
467
+ // Check if product found in cache
468
+ if ($config == null) {
469
+ // Product not found in cache
470
+ // Request $config from API
471
+ $config = $this->makeRequest(
472
+ $this->getServicesUrl() . '/accountconfig.json',
473
+ array(),
474
+ OAuth2\Client::HTTP_METHOD_GET);
475
+ // Save config in cache
476
+ $this->saveCache($config, 'autoship_api_config', self::CACHE_TYPE_CONFIG);
477
+ }
478
+
479
+ // Return $config
480
+ return $config;
481
+ }
482
+
483
+ public function makeVaultRequest($resource, $parameters = array(), $httpMethod = OAuth2\Client::HTTP_METHOD_GET)
484
+ {
485
+ return $this->makeRequest(
486
+ $this->getServicesUrl() . '/vault/' . $resource,
487
+ $parameters,
488
+ $httpMethod);
489
+ }
490
+
491
+ protected function makeRequest($url, $parameters = array(), $httpMethod = OAuth2\Client::HTTP_METHOD_GET)
492
+ {
493
+ // Make request
494
+ $response = $this->makeSingleRequestImpl($url, $parameters, $httpMethod);
495
+ // If token cache is enabled, check result for token issue
496
+ if (isset($response['code']) && $response['code'] == 401 && isset($response['result']['error']) && $response['result']['error'] == 'invalid_grant') {
497
+ if ($this->useCache(self::CACHE_TYPE_CONFIG)) {
498
+ // Request failed because of issue with access token. Try clearing cache & getting new token
499
+ $this->removeTokenFromCache();
500
+ $response = $this->makeSingleRequestImpl($url, $parameters, $httpMethod);
501
+ }
502
+ }
503
+
504
+ return $response;
505
+ }
506
+
507
+ protected function makeSingleRequestImpl($url, $parameters = array(), $httpMethod)
508
+ {
509
+ // Log
510
+ Mage::log('Platform API | Making request.', Zend_Log::INFO, SFC_Autoship_Helper_Data::API_LOG_FILE);
511
+ Mage::log('Request URL: ' . $url, Zend_Log::INFO, SFC_Autoship_Helper_Data::API_LOG_FILE);
512
+ Mage::log('Request Method: ' . $httpMethod, Zend_Log::INFO, SFC_Autoship_Helper_Data::API_LOG_FILE);
513
+ // Get config setting re: logging request
514
+ $bLogRequest = Mage::getStoreConfig('autoship_general/platform_api/log_request', $this->getConfigStore()) == '1';
515
+ if($bLogRequest) {
516
+ Mage::log($this->json_format($parameters), Zend_Log::INFO, SFC_Autoship_Helper_Data::API_LOG_FILE);
517
+ }
518
+ // Create client
519
+ $client = new OAuth2\Client(null, null);
520
+ // Turn curl logging on for client
521
+ if ($bLogRequest) {
522
+ // Get full path to log file
523
+ $logFilePath = Mage::getBaseDir('var') . DS . 'log' . DS . SFC_Autoship_Helper_Data::API_LOG_FILE;
524
+ $client->setLogFilePath($logFilePath);
525
+ }
526
+ // Grab and set token
527
+ $token = $this->getTokenForRequest();
528
+ $client->setAccessTokenType(OAuth2\Client::ACCESS_TOKEN_BEARER);
529
+ $client->setAccessToken($token);
530
+ // Make request
531
+ $response = $client->fetch($url, $parameters, $httpMethod, array('Accept' => 'application/json'),
532
+ OAuth2\Client::HTTP_FORM_CONTENT_JSON);
533
+ // Log response
534
+ Mage::log('Platform API | Response: ', Zend_Log::DEBUG, SFC_Autoship_Helper_Data::API_LOG_FILE);
535
+ Mage::log($response, Zend_Log::DEBUG, SFC_Autoship_Helper_Data::API_LOG_FILE);
536
+ // Check that we can parse response
537
+ if (!is_array($response) || !isset($response['result']) || !isset($response['code']) || !isset($response['content_type'])) {
538
+ Mage::log('Platform API | Parse error reading HTTP response!', Zend_Log::ERR, SFC_Autoship_Helper_Data::API_LOG_FILE);
539
+ Mage::throwException('Parse error reading HTTP response!');
540
+ }
541
+ $result = $response['result'];
542
+ // Check that we have contents of result, except for code 204
543
+ if (!is_array($result) && $response['code'] != 204 && (!isset($parameters['allow_result_string']) || !$parameters['allow_result_string'])) {
544
+ Mage::log('Platform API | Parse error reading HTTP response!', Zend_Log::ERR, SFC_Autoship_Helper_Data::API_LOG_FILE);
545
+ Mage::throwException('Parse error reading HTTP response!');
546
+ }
547
+ // Parse response
548
+ if ($response['code'] >= 400) {
549
+ // Some type of error response, lets log details
550
+ Mage::log('Platform API | Error response received, HTTP response code: ' . $response['code'], Zend_Log::ERR,
551
+ SFC_Autoship_Helper_Data::API_LOG_FILE);
552
+ }
553
+ else {
554
+ // Lets log all responses at DEBUG level
555
+ Mage::log('Platform API | Response received, HTTP response code: ' . $response['code'], Zend_Log::INFO,
556
+ SFC_Autoship_Helper_Data::API_LOG_FILE);
557
+ }
558
+
559
+ // Return response
560
+ return $response;
561
+ }
562
+
563
+ /**
564
+ * @param $jsonString
565
+ * @return mixed
566
+ */
567
+ protected function sanitizeJsonString($jsonString)
568
+ {
569
+ $jsonString = preg_replace('/"creditcard_number"\s*\:\s"[0-9]+"/', '"creditcard_number":"XXXXXXXXXXXXXXXX"', $jsonString);
570
+ $jsonString = preg_replace('/"creditcard_verification_value"\s*\:\s*"[0-9]+"/', '"creditcard_verification_value":"XXX"', $jsonString);
571
+ return $jsonString;
572
+ }
573
+
574
+ protected function getTokenForRequest()
575
+ {
576
+ // Check cache
577
+ $token = $this->retrieveTokenFromCache();
578
+ // If token not found in cache, lets get a new one from server
579
+ if ($token === false) {
580
+ // Log
581
+ Mage::log('Platform API | Requesting new access token from platform.', Zend_Log::INFO, SFC_Autoship_Helper_Data::API_LOG_FILE);
582
+ // Get config setting re: logging request
583
+ $bLogRequest = Mage::getStoreConfig('autoship_general/platform_api/log_request', $this->getConfigStore()) == '1';
584
+ // Lookup credentials
585
+ $clientId = Mage::helper('core')->decrypt(Mage::getStoreConfig('autoship_general/platform_api/client_id', $this->getConfigStore()));
586
+ $clientSecret = Mage::helper('core')->decrypt(Mage::getStoreConfig('autoship_general/platform_api/client_secret', $this->getConfigStore()));
587
+ // Create client
588
+ $client = new OAuth2\Client($clientId, $clientSecret);
589
+ // Turn curl logging on for client
590
+ if ($bLogRequest) {
591
+ // Get full path to log file
592
+ $logFilePath = Mage::getBaseDir('var') . DS . 'log' . DS . SFC_Autoship_Helper_Data::API_LOG_FILE;
593
+ $client->setLogFilePath($logFilePath);
594
+ }
595
+ // Build parameters
596
+ $params = array(
597
+ 'redirect_uri' => '',
598
+ );
599
+ // Get Token
600
+ $response = $client->getAccessToken(
601
+ $this->getOAuthTokenUrl(),
602
+ OAuth2\Client::GRANT_TYPE_CLIENT_CREDENTIALS,
603
+ $params);
604
+ // Log response
605
+ Mage::log('Platform API | Response to getAccessToken: ', Zend_Log::DEBUG, SFC_Autoship_Helper_Data::API_LOG_FILE);
606
+ Mage::log($response, Zend_Log::DEBUG, SFC_Autoship_Helper_Data::API_LOG_FILE);
607
+ // Check that we can parse response
608
+ if (!is_array($response) || !isset($response['result']) || !isset($response['code']) || !isset($response['content_type'])) {
609
+ Mage::log('Platform API | Parse error reading HTTP response!', Zend_Log::ERR, SFC_Autoship_Helper_Data::API_LOG_FILE);
610
+ Mage::throwException($this->__('Parse error reading HTTP response!'));
611
+ }
612
+ $result = $response['result'];
613
+ // Check that we can parse response for token and lifetime
614
+ if (!is_array($result) || !isset($result['access_token']) || !isset($result['expires_in'])) {
615
+ Mage::log('Platform API | Parse error reading getAccessToken HTTP response!', Zend_Log::ERR,
616
+ SFC_Autoship_Helper_Data::API_LOG_FILE);
617
+ Mage::throwException($this->__('Parse error reading getAccessToken HTTP response!'));
618
+ }
619
+ // Get access token and lifetime
620
+ $accessToken = $result['access_token'];
621
+ $lifeTime = $result['expires_in'];
622
+ // This is now our token
623
+ $token = $accessToken;
624
+ // Save it in cache
625
+ $this->saveTokenToCache($token, $lifeTime);
626
+ }
627
+
628
+ // Return token
629
+ return $token;
630
+ }
631
+
632
+ protected function saveTokenToCache($accessToken, $lifeTime = 3600)
633
+ {
634
+ $this->saveCache($accessToken, self::CACHE_TOKEN_TAG, self::CACHE_TYPE_CONFIG, $lifeTime - 60);
635
+ }
636
+
637
+ protected function retrieveTokenFromCache()
638
+ {
639
+ return $this->loadCache(self::CACHE_TOKEN_TAG, self::CACHE_TYPE_CONFIG);
640
+ }
641
+
642
+ protected function removeTokenFromCache()
643
+ {
644
+ $this->removeCache(self::CACHE_TOKEN_TAG, self::CACHE_TYPE_CONFIG);
645
+ }
646
+
647
+ protected function getCacheLifetime()
648
+ {
649
+ $lifetime = Mage::getStoreConfig('autoship_general/advanced/cache_lifetime', $this->getConfigStore());
650
+ if ($lifetime <= 0) {
651
+ $lifetime = 300;
652
+ }
653
+
654
+ return $lifetime;
655
+ }
656
+
657
+ protected function useCache($type)
658
+ {
659
+ if ($type == self::CACHE_TYPE_CONFIG) {
660
+ $useCache = Mage::app()->useCache('subscribe_pro_config');
661
+ }
662
+ else if ($type == self::CACHE_TYPE_PRODUCTS) {
663
+ $useCache = Mage::app()->useCache('subscribe_pro_products');
664
+ }
665
+ else {
666
+ $useCache = false;
667
+ }
668
+
669
+ return $useCache;
670
+ }
671
+
672
+ protected function saveCache($data, $key, $type, $lifetime = 0)
673
+ {
674
+ // Lookup lifetime if not passed as param
675
+ if ($lifetime <= 0) {
676
+ $lifetime = $this->getCacheLifetime();
677
+ }
678
+ // Add store id to key
679
+ $key .= '_store_' . $this->getConfigStore()->getId();
680
+ // Check use cache setting
681
+ if ($this->useCache($type)) {
682
+ // Save json encoded data to cache
683
+ Mage::app()->saveCache(json_encode($data), $key, array($type), $lifetime);
684
+ }
685
+ }
686
+
687
+ protected function loadCache($key, $type)
688
+ {
689
+ // Check use cache setting
690
+ if ($this->useCache($type)) {
691
+ // Add store id to key
692
+ $key .= '_store_' . $this->getConfigStore()->getId();
693
+ // Lookup data in cache
694
+ $data = Mage::app()->loadCache($key);
695
+ if ($data === false) {
696
+ return false;
697
+ }
698
+ else {
699
+ // JSON decode it and return
700
+ return json_decode($data, true);
701
+ }
702
+ }
703
+ else {
704
+ return false;
705
+ }
706
+ }
707
+
708
+ protected function removeCache($key, $type)
709
+ {
710
+ // Check use cache setting
711
+ if ($this->useCache($type)) {
712
+ // Add store id to key
713
+ $key .= '_store_' . $this->getConfigStore()->getId();
714
+ Mage::app()->removeCache($key);
715
+ }
716
+ }
717
+
718
+ /**
719
+ * Format a flat JSON string to make it more human-readable
720
+ * This function is taken from: https://github.com/GerHobbelt/nicejson-php/blob/master/nicejson.php
721
+ *
722
+ * @param string $json The original JSON string to process
723
+ * When the input is not a string it is assumed the input is RAW
724
+ * and should be converted to JSON first of all.
725
+ * @return string Indented version of the original JSON string
726
+ */
727
+ protected function json_format($json) {
728
+ if (!is_string($json)) {
729
+ if (phpversion() && phpversion() >= 5.4) {
730
+ return json_encode($json, JSON_PRETTY_PRINT);
731
+ }
732
+ $json = json_encode($json);
733
+ }
734
+ $result = '';
735
+ $pos = 0; // indentation level
736
+ $strLen = strlen($json);
737
+ $indentStr = "\t";
738
+ $newLine = "\n";
739
+ $prevChar = '';
740
+ $outOfQuotes = true;
741
+
742
+ for ($i = 0; $i < $strLen; $i++) {
743
+ // Grab the next character in the string
744
+ $char = substr($json, $i, 1);
745
+
746
+ // Are we inside a quoted string?
747
+ if ($char == '"' && $prevChar != '\\') {
748
+ $outOfQuotes = !$outOfQuotes;
749
+ }
750
+ // If this character is the end of an element,
751
+ // output a new line and indent the next line
752
+ else if (($char == '}' || $char == ']') && $outOfQuotes) {
753
+ $result .= $newLine;
754
+ $pos--;
755
+ for ($j = 0; $j < $pos; $j++) {
756
+ $result .= $indentStr;
757
+ }
758
+ }
759
+ // eat all non-essential whitespace in the input as we do our own here and it would only mess up our process
760
+ else if ($outOfQuotes && false !== strpos(" \t\r\n", $char)) {
761
+ continue;
762
+ }
763
+
764
+ // Add the character to the result string
765
+ $result .= $char;
766
+ // always add a space after a field colon:
767
+ if ($char == ':' && $outOfQuotes) {
768
+ $result .= ' ';
769
+ }
770
+
771
+ // If the last character was the beginning of an element,
772
+ // output a new line and indent the next line
773
+ if (($char == ',' || $char == '{' || $char == '[') && $outOfQuotes) {
774
+ $result .= $newLine;
775
+ if ($char == '{' || $char == '[') {
776
+ $pos++;
777
+ }
778
+ for ($j = 0; $j < $pos; $j++) {
779
+ $result .= $indentStr;
780
+ }
781
+ }
782
+ $prevChar = $char;
783
+ }
784
+
785
+ return $this->sanitizeJsonString($result);
786
+ }
787
+
788
+ }
app/code/local/SFC/Autoship/Helper/Payment.php CHANGED
@@ -1,4 +1,4 @@
1
- <?php //00612
2
  /**
3
  * Subscribe Pro - Subscriptions Management Extension
4
  *
@@ -15,91 +15,165 @@
15
  *
16
  */
17
 
18
- if(!extension_loaded('ionCube Loader')){$__oc=strtolower(substr(php_uname(),0,3));$__ln='/ioncube/ioncube_loader_'.$__oc.'_'.substr(phpversion(),0,3).(($__oc=='win')?'.dll':'.so');$__oid=$__id=realpath(ini_get('extension_dir'));$__here=dirname(__FILE__);if((@$__id[1])==':'){$__id=str_replace('\\','/',substr($__id,2));$__here=str_replace('\\','/',substr($__here,2));}$__rd=str_repeat('/..',substr_count($__id,'/')).$__here.'/';$__i=strlen($__rd);while($__i--){if($__rd[$__i]=='/'){$__lp=substr($__rd,0,$__i).$__ln;if(file_exists($__oid.$__lp)){$__ln=$__lp;break;}}}@dl($__ln);}else{die('The file '.__FILE__." is corrupted. Ensure that you use binary mode when transferring files with FTP and disable the 'TAR smart cr/lf feature' if using WinZIP\n");}if(function_exists('_il_exec')){return _il_exec();}die('The file <b>'.__FILE__.'</b> has been encoded with the <a href="http://www.ioncube.com">ionCube PHP Encoder</a> and requires the free '.basename($__ln).' <a href="http://www.ioncube.com/loader_download/">ionCube PHP Loader</a> to be installed.');
19
-
20
- ?>
21
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- +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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- QdXd59zbIIcqRRd4u36wQ77BMjiIfMeHaw9zti+FEQMtNXREfTAx1k0tBwRbBFnZXMGJov8i2Tg2
48
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- +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
- 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
- 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
- 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
- hfHacxO2Nu6s6bV6yzY1JfBRjsfvnbe0isdiWM1I9cbIV2qpc4LjfMEjcjdFEtl+DFdNQTUSHakd
82
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- cvNgDGmr80Ssqahy9egLX9wBAcuIqbs/BYvZvly3A0EhiYbfdou6lg8bYfLTkt2qKwNInEjvmAOv
91
- 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
- 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
- 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
- KunnshY1achQObKmKUBW516eXxCZesOrCeyHOh2U5OTJXxyMBKJUips1bRslcgoEDEPgMBdPvELv
95
- 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
- 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
- +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
- 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
- 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
- MHMTp3IaXEZs0j34oFKbiI5Z1T1wuabKhZg0Bp/16gk4A8egHX+KEdjylwKjNB48/irz9AZmX49Y
101
- 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
- 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
- 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
- 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
105
- QKEbilVHw+J9STIwyGO/hiUrrBgxDm==
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
  /**
3
  * Subscribe Pro - Subscriptions Management Extension
4
  *
15
  *
16
  */
17
 
18
+ /**
19
+ * Special code to make us compatible with Amasty_Payrestriction module
20
+ */
21
+ if (file_exists(realpath(dirname(__FILE__)) . '/../../../Amasty/Payrestriction/Helper/Payment/Data.php') &&
22
+ class_exists('Amasty_Payrestriction_Helper_Payment_Data'))
23
+ {
24
+ class SFC_Autoship_Helper_Payment_Base extends Amasty_Payrestriction_Helper_Payment_Data
25
+ {
26
+ }
27
+ }
28
+ else
29
+ {
30
+ class SFC_Autoship_Helper_Payment_Base extends Mage_Payment_Helper_Data
31
+ {
32
+ }
33
+ }
34
+
35
+ class SFC_Autoship_Helper_Payment extends SFC_Autoship_Helper_Payment_Base
36
+ {
37
+
38
+ public function getPaymentTokenFromMethodCode($code)
39
+ {
40
+ // Check if code includes key
41
+ $key = SFC_Autoship_Model_Payment_Method::METHOD_CODE . SFC_Autoship_Model_Payment_Method::METHOD_CODE_KEY_TOKEN;
42
+ if ($key == substr($code, 0, strlen($key))) {
43
+ $encodedMethodParts = explode(SFC_Autoship_Model_Payment_Method::METHOD_CODE_KEY_TOKEN, $code);
44
+ $paymentToken = $encodedMethodParts[1];
45
+
46
+ return $paymentToken;
47
+ }
48
+ else {
49
+ return null;
50
+ }
51
+ }
52
+
53
+
54
+ /**
55
+ * Retrieve method model object
56
+ *
57
+ * @param string $code
58
+ * @return Mage_Payment_Model_Method_Abstract|false
59
+ */
60
+ public function getMethodInstance($code)
61
+ {
62
+ // Log
63
+ Mage::log('SFC_Autoship_Helper_Payment::getMethodInstance', Zend_Log::INFO, SFC_Autoship_Helper_Data::LOG_FILE);
64
+
65
+ // Check if code includes key
66
+ $key = SFC_Autoship_Model_Payment_Method::METHOD_CODE . SFC_Autoship_Model_Payment_Method::METHOD_CODE_KEY_TOKEN;
67
+ if ($key == substr($code, 0, strlen($key))) {
68
+ $classKey = self::XML_PATH_PAYMENT_METHODS . '/' . SFC_Autoship_Model_Payment_Method::METHOD_CODE . '/model';
69
+ $class = Mage::getStoreConfig($classKey);
70
+ /** @var SFC_Autoship_Model_Payment_Method $model */
71
+ $model = Mage::getModel($class);
72
+
73
+ return $model;
74
+ }
75
+ else {
76
+ return parent::getMethodInstance($code);
77
+ }
78
+ }
79
+
80
+ /**
81
+ *
82
+ * @param mixed $store
83
+ * @param mixed $quote
84
+ * @return mixed
85
+ */
86
+ public function getStoreMethods($store = null, $quote = null)
87
+ {
88
+ // Log
89
+ Mage::log('SFC_Autoship_Helper_Payment::getStoreMethods', Zend_Log::INFO, SFC_Autoship_Helper_Data::LOG_FILE);
90
+ if(is_numeric($store)) {
91
+ Mage::log('Store Id: ' . $store, Zend_Log::INFO, SFC_Autoship_Helper_Data::LOG_FILE);
92
+ }
93
+ if($store != null && is_object($store)) {
94
+ Mage::log('Store Id: ' . $store->getId(), Zend_Log::INFO, SFC_Autoship_Helper_Data::LOG_FILE);
95
+ }
96
+ if(is_numeric($quote)) {
97
+ Mage::log('Quote Id: ' . $quote, Zend_Log::INFO, SFC_Autoship_Helper_Data::LOG_FILE);
98
+ }
99
+ if($quote != null && is_object($quote)) {
100
+ Mage::log('Quote Id: ' . $quote->getId(), Zend_Log::INFO, SFC_Autoship_Helper_Data::LOG_FILE);
101
+ }
102
+
103
+ /** @var SFC_Autoship_Helper_Vault $vaultHelper */
104
+ $vaultHelper = Mage::helper('autoship/vault');
105
+ /** @var SFC_Autoship_Helper_Api $apiHelper */
106
+ $apiHelper = Mage::helper('autoship/api');
107
+
108
+ // Call parent implementation
109
+ $parentMethods = parent::getStoreMethods($store, $quote);
110
+ // Build new list
111
+ $methods = array();
112
+ // Find payment method in list
113
+ /** @var Mage_Payment_Model_Method_Abstract $method */
114
+ foreach ($parentMethods as $method) {
115
+ // Check, is this method current method
116
+ if ($method->getCode() == SFC_Autoship_Model_Payment_Method::METHOD_CODE) {
117
+ // Get customer
118
+ $customer = $this->getCustomerForProfiles($quote);
119
+ if (strlen($customer->getId())) {
120
+ // Set website / store for config on API helper
121
+ $store = Mage::app()->getWebsite($customer->getData('website_id'))->getDefaultStore();
122
+ $apiHelper->setConfigStore($store);
123
+ $paymentProfiles = $vaultHelper->getPaymentProfilesForCustomer($customer->getData('email'));
124
+ // Iterate payment profiles
125
+ /** @var SFC_Autoship_Model_Payment_Profile $paymentProfile */
126
+ foreach ($paymentProfiles as $paymentProfile) {
127
+ // Build new method out of profile
128
+ /** @var $newMethodInstance */
129
+ $newMethodInstance = $this->getMethodInstance(SFC_Autoship_Model_Payment_Method::METHOD_CODE);
130
+ $newMethodInstance->setSavedPaymentProfile($paymentProfile);
131
+ $methods[] = $newMethodInstance;
132
+ }
133
+ }
134
+ }
135
+ // Add method from parent implementation
136
+ $methods[] = $method;
137
+ }
138
+
139
+ return $methods;
140
+ }
141
+
142
+ /**
143
+ * @return Mage_Core_Model_Store
144
+ */
145
+ protected function detectStore()
146
+ {
147
+ if (!Mage::app()->getStore()->isAdmin()) {
148
+ return Mage::app()->getStore();
149
+ }
150
+ else {
151
+ // If we are in admin store, try to find correct store from current quote
152
+ /** @var Mage_Adminhtml_Model_Session_Quote $adminhtmlQuoteSession */
153
+ $adminhtmlQuoteSession = Mage::getSingleton('adminhtml/session_quote');
154
+ $quote = $adminhtmlQuoteSession->getQuote();
155
+ $store = $quote->getStore();
156
+
157
+ return $store;
158
+ }
159
+ }
160
+
161
+ protected function getCustomerForProfiles($quote)
162
+ {
163
+ // If quote is null, use customer from session
164
+ if ($quote != null && is_object($quote) && $quote instanceof Mage_Sales_Model_Quote) {
165
+ $customer = $quote->getCustomer();
166
+
167
+ return $customer;
168
+ }
169
+ else {
170
+ /** @var Mage_Customer_Model_Session $customerSession */
171
+ $customerSession = Mage::getSingleton('customer/session');
172
+ /** @var Mage_Customer_Model_Customer $customer */
173
+ $customer = $customerSession->getCustomer();
174
+
175
+ return $customer;
176
+ }
177
+ }
178
+
179
+ }
app/code/local/SFC/Autoship/Helper/PaymentError.php CHANGED
@@ -1,4 +1,4 @@
1
- <?php //00612
2
  /**
3
  * Subscribe Pro - Subscriptions Management Extension
4
  *
@@ -15,53 +15,94 @@
15
  *
16
  */
17
 
18
- if(!extension_loaded('ionCube Loader')){$__oc=strtolower(substr(php_uname(),0,3));$__ln='/ioncube/ioncube_loader_'.$__oc.'_'.substr(phpversion(),0,3).(($__oc=='win')?'.dll':'.so');$__oid=$__id=realpath(ini_get('extension_dir'));$__here=dirname(__FILE__);if((@$__id[1])==':'){$__id=str_replace('\\','/',substr($__id,2));$__here=str_replace('\\','/',substr($__here,2));}$__rd=str_repeat('/..',substr_count($__id,'/')).$__here.'/';$__i=strlen($__rd);while($__i--){if($__rd[$__i]=='/'){$__lp=substr($__rd,0,$__i).$__ln;if(file_exists($__oid.$__lp)){$__ln=$__lp;break;}}}@dl($__ln);}else{die('The file '.__FILE__." is corrupted. Ensure that you use binary mode when transferring files with FTP and disable the 'TAR smart cr/lf feature' if using WinZIP\n");}if(function_exists('_il_exec')){return _il_exec();}die('The file <b>'.__FILE__.'</b> has been encoded with the <a href="http://www.ioncube.com">ionCube PHP Encoder</a> and requires the free '.basename($__ln).' <a href="http://www.ioncube.com/loader_download/">ionCube PHP Loader</a> to be installed.');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
19
 
20
- ?>
21
- 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
- UoBNgbnsOh6UI17Pv+IyetFa882L0CNJI5kCL9reaUTOP3XyRzy7aXUjor8cSfRiUiMyecUcKe3H
23
- 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
- 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
- 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
- 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
- a13BKr+SvzDK8lcOuhNQE9EkVwBynvoB/jgyrvaJG+1oOWkBqT3VLMs/49eWVq8Fu0rA1HlTNhRr
28
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- gQ/GrsyGc11guGGkWwQvmZV3ffLk0CWsJzT165rLvI/bw4a1aLbZnR9iSXTTSsXTn+HMjLIgth6f
39
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- S0EF9tdXnMJo67hVP2UM9A2XIAuWtHKhzSVvVbji36VJqOrIUTRXbJq+HsZZaOuuxZYe2mAOrMe4
51
- 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
- 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
- +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
- +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
- cjE4w6Q2vD+9lGKTe1jGt5DwGzHW0FGUcpJAp0pVykh/9MsZPf5F/DVR7ONUmvMgc8xoscL8oM7W
56
- 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
- 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
- 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
- RcbkfjBxsJLDd6dYk4oFuDLP6reVDeVew2ljQLekoE5sSpP6SIxRgy+Mq+WdshfAqQaUy40IoVUu
60
- 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
- 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
- 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
- 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
- r17D5pZHXiFSzmgXhLMEZVTIz4DsHDY9MwUx+uuKqlr1wRn3dXvyx2KdsybYY4vnxq+cSlzNyTuK
65
- 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
- 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
- 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
1
+ <?php
2
  /**
3
  * Subscribe Pro - Subscriptions Management Extension
4
  *
15
  *
16
  */
17
 
18
+ /**
19
+ * This class returns customer friendly error messages for all payment related errors
20
+ *
21
+ * How to modify error messages:
22
+ * - It's suggested to use Magento's translations to just change the error message text.
23
+ * - If you prefer to change the mapping logic, rewrite this helper class from your module.
24
+ *
25
+ */
26
+ class SFC_Autoship_Helper_PaymentError extends Mage_Core_Helper_Abstract
27
+ {
28
+
29
+ // Error types
30
+ const ERROR_TYPE_TECHNOLOGY = 'technology';
31
+ const ERROR_TYPE_CARD_NUMBER = 'card_number';
32
+ const ERROR_TYPE_CARD_TYPE = 'card_type';
33
+ const ERROR_TYPE_AVS = 'avs';
34
+ const ERROR_TYPE_CVV = 'cvv';
35
+ const ERROR_TYPE_EXP_DATE = 'exp_date';
36
+ const ERROR_TYPE_SOFT_DECLINE = 'soft_decline';
37
+ const ERROR_TYPE_HARD_DECLINE = 'hard_decline';
38
+ const ERROR_TYPE_CREDIT_FAILED = 'credit_failed';
39
+ const ERROR_TYPE_VOID_FAILED = 'void_failed';
40
+ const ERROR_TYPE_CAPTURE_FAILED = 'capture_failed';
41
+ const ERROR_TYPE_DUPLICATE_TRANSACTION = 'duplicate_transaction';
42
+ const ERROR_TYPE_FRAUD_REVIEW = 'fraud_review';
43
+
44
+ /**
45
+ * @param string $subscribeProErrorType
46
+ * @return null|string
47
+ */
48
+ public function getGatewayErrorMessage($subscribeProErrorType)
49
+ {
50
+ $errorMessageMap = array(
51
+ self::ERROR_TYPE_TECHNOLOGY => 'Your order did not go through due to a technical error. Please try again or contact customer support.',
52
+ self::ERROR_TYPE_CARD_NUMBER => 'There is an error with your credit card number. Please check the number and try again.',
53
+ self::ERROR_TYPE_CARD_TYPE => 'There is an error with your credit card type or your card type is not supported.',
54
+ self::ERROR_TYPE_AVS => 'Your order did not go through due to an issue with your credit card billing address. Please check the address or contact your bank and try again.',
55
+ self::ERROR_TYPE_CVV => 'Your order did not go through due to an issue matching your 3 or 4 digit credit card verification code.',
56
+ self::ERROR_TYPE_EXP_DATE => 'Your order did not go through due to an issue with your credit card expiration date.',
57
+ self::ERROR_TYPE_SOFT_DECLINE => 'Your order did not go through due to an issue with your credit card.',
58
+ self::ERROR_TYPE_HARD_DECLINE => 'Your order did not go through due to an issue with your credit card.',
59
+ self::ERROR_TYPE_CREDIT_FAILED => 'There was an error processing a credit for this transaction.',
60
+ self::ERROR_TYPE_VOID_FAILED => 'There was an error voiding this transaction.',
61
+ self::ERROR_TYPE_CAPTURE_FAILED => 'There was an error capturing funds for this transaction.',
62
+ self::ERROR_TYPE_DUPLICATE_TRANSACTION => 'Your order did not go through because it may have been a duplicate of another order. If you have only submitted your order once, please wait 10 minutes and try again.',
63
+ self::ERROR_TYPE_FRAUD_REVIEW => 'Your order did not go through due to an issue with your credit card.',
64
+ );
65
+
66
+ if (isset ($errorMessageMap[$subscribeProErrorType])) {
67
+ // Run error message through translate
68
+ return $this->__($errorMessageMap[$subscribeProErrorType]);
69
+ }
70
+ else {
71
+ return null;
72
+ }
73
+ }
74
+
75
+ /**
76
+ * @param string $attribute
77
+ * @param string $key
78
+ * @return null|string
79
+ */
80
+ public function getCreditCardErrorMessage($attribute, $key)
81
+ {
82
+ $errorMessageMap = array(
83
+ 'errors.expired' => array(
84
+ 'year' => 'Your order did not go through due to an issue with your credit card expiration date.',
85
+ 'month' => 'Your order did not go through due to an issue with your credit card expiration date.',
86
+ ),
87
+ 'errors.blank' => array(
88
+ 'year' => 'Your order did not go through due to an issue with your credit card expiration date.',
89
+ 'month' => 'Your order did not go through due to an issue with your credit card expiration date.',
90
+ 'number' => 'There is an error with your credit card number. Please check the number and try again.',
91
+ ),
92
+ 'errors.invalid' => array(
93
+ 'year' => 'Your order did not go through due to an issue with your credit card expiration date.',
94
+ 'month' => 'Your order did not go through due to an issue with your credit card expiration date.',
95
+ 'number' => 'There is an error with your credit card number. Please check the number and try again.',
96
+ ),
97
+ );
98
+
99
+ if (isset ($errorMessageMap[$key]) && isset ($errorMessageMap[$key][$attribute])) {
100
+ // Run error message through translate
101
+ return $this->__($errorMessageMap[$key][$attribute]);
102
+ }
103
+ else {
104
+ return null;
105
+ }
106
+ }
107
 
108
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/code/local/SFC/Autoship/Helper/Platform.php CHANGED
@@ -1,4 +1,4 @@
1
- <?php //00612
2
  /**
3
  * Subscribe Pro - Subscriptions Management Extension
4
  *
@@ -15,326 +15,956 @@
15
  *
16
  */
17
 
18
- if(!extension_loaded('ionCube Loader')){$__oc=strtolower(substr(php_uname(),0,3));$__ln='/ioncube/ioncube_loader_'.$__oc.'_'.substr(phpversion(),0,3).(($__oc=='win')?'.dll':'.so');$__oid=$__id=realpath(ini_get('extension_dir'));$__here=dirname(__FILE__);if((@$__id[1])==':'){$__id=str_replace('\\','/',substr($__id,2));$__here=str_replace('\\','/',substr($__here,2));}$__rd=str_repeat('/..',substr_count($__id,'/')).$__here.'/';$__i=strlen($__rd);while($__i--){if($__rd[$__i]=='/'){$__lp=substr($__rd,0,$__i).$__ln;if(file_exists($__oid.$__lp)){$__ln=$__lp;break;}}}@dl($__ln);}else{die('The file '.__FILE__." is corrupted. Ensure that you use binary mode when transferring files with FTP and disable the 'TAR smart cr/lf feature' if using WinZIP\n");}if(function_exists('_il_exec')){return _il_exec();}die('The file <b>'.__FILE__.'</b> has been encoded with the <a href="http://www.ioncube.com">ionCube PHP Encoder</a> and requires the free '.basename($__ln).' <a href="http://www.ioncube.com/loader_download/">ionCube PHP Loader</a> to be installed.');
19
-
20
- ?>
21
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- SE8IDZ9hN9+++ctI6vZqQCQnUQNhqRIpsBPkpV9dBD8ZzGhWYONtFH2c6ADmMjpEQ1nB5FSMWgxt
49
- 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
- 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
- +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
- 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
- 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
- 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
- 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
- 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
- +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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- +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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- TXtGOUaMGelNk6cea6M4LEMQCON39VyQ+2XL5/bLHZxilgdASCu2QPbaoXWtN9sTnqpbm57cvKy6
75
- pq0e61o0XQswXItANF+sGAlEUkJ9i7Zx7wSPxcJGTLBtagnZeuvclt91ETIwjxzfHgPOsFehkiF0
76
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- +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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- T1ic4JFbeYfFuVhf5blux/LwXEAXhuyz8SxYsngFoYLYwErj6p4OpCsRGW4gpDnUGcHFY504LzN1
102
- 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
- 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
- jov8xyeUvQQotNF5maliyiTezJ/yS0kbqpYMXREAcibHykepgaBtJJO+O3y8R+pyC9UsS7hlkKSp
105
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- hXsYKt+VJc9J0vZEGd1/ON7d9Ms6MupL7AdxMMyke85cBUYaSAlPGaQCOX7IE+Xip4td/CJgsALU
115
- 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
- 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
- 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
- jFWQVMhp6G87fw66GQ7mGRMOTZcetCCPP1YHHNS+ZsqOKkLxNqpeLznoU/5/vfD+SiDhCUcZo744
119
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- YfeYEowpSqxbCELLPNJL0nbr7FJaMbpU6+kfcsDNOyBjmHirU+nmQDuffBKsYj27wPmxEJwE8EMw
130
- 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
- KfbcQy2OTbfyP9bG54bcDMW3WKY2Zf8HMDpTWTUCN1NxMUWFG853kd2JjDY/5X1qD9rikCOfu6H7
132
- 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
- YWHYJ/3ZPBMQuLqZkJTodImA8Zag7UewWr4ME+TESNo4nIbmNyK94LsGS1fFYWO+9sza57QQi2VC
134
- xlke4I5HYwqJ/xxcJhx4xqb6Po9vPFxahk0uQNdvhsjU0+0exmdCptaowwBNcLOtqX6/apaodgx6
135
- lDFsDyN6wOVQZvFliMlV/AUv4dtHUR4UxCSwiRH1GyyjZytrIjBuWJTB3khXjF67sPcGl5XdtlEf
136
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- WNKABtq5D9Tg6uPQDkJuezmPdJCnlfoszTDFeGV+cFbO4pPmDMjHlbQkPYxnxNIsB6i2dyYLORwi
154
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- d4/X3lCkOmg4rnGUzljxHKIgqgUNkrCbvEDdw3AjQf9K5tBaqftn5W6RMatAw9E9mMh68qy3YdXR
177
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- x7oFlbU2IQ9bqjxUP/j+iTENSsyqYud9Rk64oYpbLXwMfnr0qEEEr0Y2qTEdFMgI+YzSOJ8/uWTm
210
- 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
- 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
- Gyka54iD9eKJQ5CWGhVmaNt/GOTZg9GeJwm6EcvE7RwYtWL7jzWuiwcWpyQTq8leUaI3lJCSAhjD
213
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- DNMxhzsTzgb5GYsCwrUnsX4JFvm5nFhEDZCL00g411ubOTLvJt1Uj8tq5rTgRUxhyOewj7p+8EnX
223
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- k7xJ2K0rcPjyBDhesLb7KzkcXVKKBKeHYoWTKR8lKweNskYtCiLkpjfhoAuzuVl86hDLaZx17+n7
234
- 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
- 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
- +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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- iTrS6OuJZJe06l6S7dNKtxhMbT+mEy3JRouThWX1tHX///rrpdOUuaZ+A/Gj6LVKSEqdY6QAPQz4
253
- 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
- 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
- tH+DnyD6P28C7lY3JIbhcFjhUxVMDWelx8qM4phqjXH2BWsW6rMmK83UHciWUdC8MLOUpElVfXbW
256
- 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
- WLGQmcnQ82j7UuvPYSFcFjznApKsnhkhWRbYYa9plyGADxdSMOGtPT8g4IQiSBCl2cPGt/bt8CMl
258
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 9/6RXxxkDnTU+PHI03riZ1yDcpkemTmohtBkwkbWPmrc+1bMekgRQGSKRt+YOMaMFdXvTzK5Cxno
271
- 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
- 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
- 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
- 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
- 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
- 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
- mEOxZsS20Mhrbuq8NvHfUxAlZFWDmRJxrktVzzKsauqZNB1Byyygx4SiOYqCOFy70/jmxlWeT1Xb
278
- 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
- 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
- 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
- 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
- 4zoF+rxKk6YmP2Rkf0WtSh8ksrkmdHVIgeJjYctnIGhnfp7TwZTEOpIUQjeE+LFCFW7VSQm7SFD8
283
- P8MnZnzekEZQE3j1+SpeTiPnAGKXGkQWRMy5Ke5Tld/GVFnTS6/mWs3kTKVkqHw/8rHBx45I6y/N
284
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- DhS4nXQHV3+2iup1ZtESdxJ+/js0UH9sDlfn06RQtnGdptSONKinOrPcwEfRjHuwhETDJo5OtNV6
297
- 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
- 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
- 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
- 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
- OC6pwoGfdbFdCVnLvieYc5Lz6Pv0lURy5cL6Es3jS7QHCdSUGNI1lAvMZnJawT8zx4zRDI15LEew
302
- jUIUH171bRarlR54f+rXvL+azyMa8mh0mg85/6wW81Nbg7SR3P9JSM3LwAXPGCVPhgrDYx007yQt
303
- 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
- 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
- eZHRcVbqdyfQ5jv9ptVIzhfjsZeZsWqCu4y6RdFs1U2TT5vmRj9PLSnoqC3mXJcM48mQCupLj2Gv
306
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- +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
- 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
- 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
- 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
- QeB7OA3jYRrXHaL5/82oSFMYACYJoOpwS5iISnPY0s638fKXDBJb6QEzqquwMH7QEg1R9xOcSyDt
329
- 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
- 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
- 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
- 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
- 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
- 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
- SzDNAGR/zoyr3mUKRYUi7PpKzZsUYdC4aGWLxEoHMyx01+7Fe7wH/3ZQMHcD6YiUcH/VXauXY2X0
336
- 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
- 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
- u9Wcf6jLJmPfpln6lJu5863fmg1ZjTpfq02OYiKefLjjZ0TTDE4IechGcFD4o3D1/C7FrXNgfqMw
339
- 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
- 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
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
  /**
3
  * Subscribe Pro - Subscriptions Management Extension
4
  *
15
  *
16
  */
17
 
18
+ /**
19
+ * Helper class to assist with retrieving and manipulating subscriptions and associated data
20
+ */
21
+ class SFC_Autoship_Helper_Platform extends Mage_Core_Helper_Abstract
22
+ {
23
+
24
+ // Define const to represent payment method codes
25
+ // These are necessary here so we aren't dependent on constants from modules which may or may not be installed.
26
+ const PAY_METHOD_CODE_SFC_CIM_10XX = 'authnettoken';
27
+ const PAY_METHOD_CODE_SFC_CIM = 'sfc_cim_core';
28
+ const PAY_METHOD_CODE_SUBSCRIBE_PRO_VAULT = 'subscribe_pro';
29
+ const PAY_METHOD_CODE_SFC_CYBERSOURCE = 'sfc_cybersource';
30
+ const PAY_METHOD_CODE_BRAINTREE = "braintree";
31
+
32
+ protected $_methodCodeMap = array();
33
+
34
+ protected $_accountConfig = null;
35
+
36
+ public function __construct()
37
+ {
38
+ // Map Mage payment method code to platform gateway
39
+ $this->_methodCodeMap = array(
40
+ self::PAY_METHOD_CODE_SFC_CIM_10XX => 'Authorize.Net CIM',
41
+ self::PAY_METHOD_CODE_SFC_CIM => 'Authorize.Net CIM',
42
+ self::PAY_METHOD_CODE_SUBSCRIBE_PRO_VAULT => 'Subscribe Pro Vault',
43
+ self::PAY_METHOD_CODE_SFC_CYBERSOURCE => 'CyberSource'
44
+ );
45
+ }
46
+
47
+ /**
48
+ * Retrieve subscription product profile info from platform (eligible intervals, min & max qty, discount, etc)
49
+ * Creates product on platform if it doesn't exist.
50
+ *
51
+ * @param Mage_Catalog_Model_Product $product Magento product object
52
+ * @return SFC_Autoship_Model_Platform_Product Platform product data structure
53
+ */
54
+ public function getPlatformProduct(Mage_Catalog_Model_Product $product)
55
+ {
56
+ /** @var SFC_Autoship_Helper_Api $apiHelper */
57
+ $apiHelper = Mage::helper('autoship/api');
58
+
59
+ // Lookup whether product enabled / disabled
60
+ $isProductEnabled = Mage::helper('autoship/product')->isAvailableForSubscription($product, $apiHelper->getConfigStore(), true);
61
+ if (!$isProductEnabled) {
62
+ $platformProduct = Mage::getModel('autoship/platform_product');
63
+ $platformProduct->setData('enabled', false);
64
+ return $platformProduct;
65
+ }
66
+
67
+ // Do API query by SKU for product info
68
+ $response = $apiHelper->fetchProducts(array('sku' => $product->getSku()));
69
+ //print_r($response);die;
70
+ // Check response
71
+ if ($response['code'] != 200) {
72
+ // API Error
73
+ Mage::throwException($this->__('API error!'));
74
+ }
75
+ // Check that we found product info
76
+ $result = $response['result'];
77
+ $platformProducts = $result['products'];
78
+ if (!is_array($platformProducts) || count($platformProducts) != 1) {
79
+ Mage::throwException($this->__('Product not found on Subscribe Pro platform!'));
80
+ }
81
+ // Map platform product data to Mage model object
82
+ $platformProductData = $platformProducts[0];
83
+ $platformProduct = Mage::getModel('autoship/platform_product');
84
+ $platformProduct->addData($platformProductData);
85
+ // Force enabled = true
86
+ // We are no longer honoring the is_subscription_enabled field from the platform
87
+ $platformProduct->setData('enabled', true);
88
+
89
+ // Return product
90
+ return $platformProduct;
91
+ }
92
+
93
+ /**
94
+ * Handle catalog_product_save_after Event and update product profile in DB and on platform
95
+ *
96
+ * @param Mage_Catalog_Model_Product $product Magento product object
97
+ */
98
+ public function handleOnSaveProduct(Mage_Catalog_Model_Product $product)
99
+ {
100
+ Mage::log('SFC_Autoship_Helper_Platform::handleOnSaveProduct', Zend_Log::INFO, SFC_Autoship_Helper_Data::LOG_FILE);
101
+ Mage::log('Product SKU: ' . $product->getSku(), Zend_Log::INFO, SFC_Autoship_Helper_Data::LOG_FILE);
102
+
103
+ /** @var SFC_Autoship_Helper_Product $productHelper */
104
+ $productHelper = Mage::helper('autoship/product');
105
+
106
+ // Get website ids for websites product is assigned to
107
+ $productWebsites = $product->getWebsiteIds();
108
+
109
+ // Iterate all websites / stores
110
+ $websites = Mage::app()->getWebsites(false);
111
+ /** @var Mage_Core_Model_Website $website */
112
+ foreach ($websites as $website) {
113
+ Mage::log('Website ID: ' . $website->getId() . ' code: ' . $website->getCode(), Zend_Log::INFO, SFC_Autoship_Helper_Data::LOG_FILE);
114
+ $store = $website->getDefaultStore();
115
+ if (!$store instanceof Mage_Core_Model_Store) {
116
+ Mage::log('No default store for website!', Zend_Log::ERR, SFC_Autoship_Helper_Data::LOG_FILE);
117
+ continue;
118
+ }
119
+ Mage::log('Website default store code: ' . $store->getCode(), Zend_Log::INFO, SFC_Autoship_Helper_Data::LOG_FILE);
120
+ Mage::log('Subscription features enabled: ' . Mage::getStoreConfig('autoship_general/general/enabled', $store),
121
+ Zend_Log::INFO, SFC_Autoship_Helper_Data::LOG_FILE);
122
+ // Check configuration for this store
123
+ if (Mage::getStoreConfig('autoship_general/general/enabled', $store) == '1') {
124
+ // Check if product is assigned to website
125
+ $productAssignedToWebsite = in_array($website->getId(), $productWebsites);
126
+ Mage::log('Product is assigned to website: ' . $productAssignedToWebsite, Zend_Log::INFO, SFC_Autoship_Helper_Data::LOG_FILE);
127
+ if ($productAssignedToWebsite) {
128
+ // Lookup whether product enabled / disabled
129
+ $isProductEnabled = $productHelper->isAvailableForSubscription($product, $store, false);
130
+ Mage::log('Is product enabled for subscription: ' . $isProductEnabled, Zend_Log::INFO, SFC_Autoship_Helper_Data::LOG_FILE);
131
+ // If enabled, update product on platform
132
+ if ($isProductEnabled) {
133
+ // Create / update product on platform
134
+ $this->updateProductOnPlatform($store, $product);
135
+ }
136
+ }
137
+ }
138
+ }
139
+ }
140
+
141
+ /**
142
+ * Update the product on the platform for a given store
143
+ *
144
+ * @param Mage_Core_Model_Store $store
145
+ * @param Mage_Catalog_Model_Product $product Magento product object
146
+ */
147
+ protected function updateProductOnPlatform(Mage_Core_Model_Store $store, Mage_Catalog_Model_Product $product)
148
+ {
149
+ Mage::log('SFC_Autoship_Helper_Platform::updateProductOnPlatform', Zend_Log::INFO, SFC_Autoship_Helper_Data::LOG_FILE);
150
+
151
+ // Get ref to core session object
152
+ /** @var Mage_Core_Model_Session $coreSession */
153
+ $coreSession = Mage::getSingleton('core/session');
154
+
155
+ // Reload product for this specific store
156
+ /** @var Mage_Catalog_Model_Product $product */
157
+ $product = Mage::getModel('catalog/product')->setData('store_id', $store->getId())->load($product->getId());
158
+
159
+ // Don't allow grouped product to be enabled for subscription
160
+ // Otherwise don't check product types or check for options here
161
+ if ($product->getTypeId() == Mage_Catalog_Model_Product_Type::TYPE_GROUPED) {
162
+ return;
163
+ }
164
+
165
+ // Update product on platform
166
+ // Try to update platform
167
+ try {
168
+ // Create / update product on platform
169
+ $this->createOrUpdateProductImpl($product, array(), $store);
170
+ }
171
+ catch (Exception $e) {
172
+ Mage::log('Failed to update product on platform with error: ' . $e->getMessage());
173
+ $coreSession->addError($this->__('Failed to update product on platform!'));
174
+ }
175
+ }
176
+
177
+ /**
178
+ * Create or update product info on the platform
179
+ *
180
+ * @param Mage_Catalog_Model_Product $product Magento product object
181
+ * @param array|null $data Subscription product settings to set on the platform
182
+ * @return int Id of newly created or updated product on platform
183
+ */
184
+ public function createOrUpdateProduct(Mage_Catalog_Model_Product $product, array $data = array())
185
+ {
186
+ // Create or Update via API
187
+ $platformProductData = $this->createOrUpdateProductImpl($product, $data);
188
+ // Grab id of product on platform
189
+ $platformProductId = $platformProductData['id'];
190
+
191
+ // Return id of updated product on platform
192
+ return $platformProductId;
193
+ }
194
+
195
+ /**
196
+ * Create or update product info on the platform
197
+ *
198
+ * @param Mage_Catalog_Model_Product $product Magento product object
199
+ * @param array $data Subscription product settings to set on the platform
200
+ * @param null $store
201
+ * @return array Platform product data structure
202
+ */
203
+ protected function createOrUpdateProductImpl(Mage_Catalog_Model_Product $product, array $data = array(), $store = null)
204
+ {
205
+ /** @var SFC_Autoship_Helper_Api $apiHelper */
206
+ $apiHelper = Mage::helper('autoship/api');
207
+ // Set store on api helper
208
+ if($store != null) {
209
+ $apiHelper->setConfigStore($store);
210
+ }
211
+
212
+ // Lookup whether product enabled / disabled
213
+ $isProductEnabled = Mage::helper('autoship/product')->isAvailableForSubscription($product, $store, false);
214
+ // Prepare new platform product info
215
+ $newPlatformProductData = array(
216
+ 'sku' => $product->getSku(),
217
+ 'name' => $product->getName(),
218
+ 'is_subscription_enabled' => $isProductEnabled,
219
+ 'price' => $product->getPrice(),
220
+ );
221
+ // Save optional fields if there were pass in the profile
222
+ if(isset($data['min_qty']) && strlen($data['min_qty'])) {
223
+ $newPlatformProductData['min_qty'] = $data['min_qty'];
224
+ }
225
+ if(isset($data['max_qty']) && strlen($data['max_qty'])) {
226
+ $newPlatformProductData['max_qty'] = $data['max_qty'];
227
+ }
228
+ if(isset($data['discount']) && strlen($data['discount'])) {
229
+ $newPlatformProductData['discount'] = $data['discount'];
230
+ }
231
+ if(isset($data['is_discount_percentage']) && strlen($data['is_discount_percentage'])) {
232
+ $newPlatformProductData['is_discount_percentage'] = $data['is_discount_percentage'];
233
+ }
234
+ // Save intervals if they were passed in the profile
235
+ if(isset($data['product_intervals']) && strlen($data['product_intervals'])) {
236
+ // Convert intervals to array
237
+ $intervalsArray = explode(',', trim($data['product_intervals'], ' ,'));
238
+ $newPlatformProductData['intervals'] = $intervalsArray;
239
+ }
240
+
241
+ // Do API query by SKU for product info
242
+ $response = $apiHelper->fetchProducts(array('sku' => $product->getSku()));
243
+ // Check response
244
+ if ($response['code'] != 200) {
245
+ // API Error
246
+ Mage::throwException($this->__('API error!'));
247
+ }
248
+ // Check that we found product info
249
+ $result = $response['result'];
250
+ $platformProducts = $result['products'];
251
+ if (is_array($platformProducts) && count($platformProducts) == 1) {
252
+ // Found product, lets update
253
+ $platformProduct = $platformProducts[0];
254
+ // Merge new platform data into fetched data
255
+ $platformProduct = array_merge($platformProduct, $newPlatformProductData);
256
+ // Call API
257
+ $response = $apiHelper->updateProduct($platformProduct['id'], $platformProduct);
258
+ // Check response for HTTP status code
259
+ if ($response['code'] != 201) {
260
+ Mage::throwException($this->__('Failed to update product on platform!'));
261
+ }
262
+
263
+ // Return product
264
+ return $platformProduct;
265
+ }
266
+ else {
267
+ if (!is_array($platformProducts) || !count($platformProducts)) {
268
+ // Didn't find product matching SKU
269
+ // Lets add this product to API
270
+ $response = $apiHelper->postProduct($newPlatformProductData);
271
+ // Check response
272
+ if ($response['code'] != 201) {
273
+ // API Error
274
+ Mage::throwException('API error!');
275
+ }
276
+ $result = $response['result'];
277
+ $platformProducts = $result['products'];
278
+ // Check that we have exactly 1 product
279
+ if (!is_array($platformProducts) || count($platformProducts) != 1) {
280
+ Mage::throwException($this->__('Failed to create product on platform!'));
281
+ }
282
+ // Now get product data
283
+ $platformProduct = $platformProducts[0];
284
+ if (!is_array($platformProduct) || !isset($platformProduct['id'])) {
285
+ Mage::throwException($this->__('Failed to read response from platform while creating product!'));
286
+ }
287
+
288
+ // Return product
289
+ return $platformProduct;
290
+ }
291
+ else {
292
+ // This shouldn't happen
293
+ Mage::throwException($this->__('Failed querying API for product SKU: ' . $product->getSku()));
294
+ }
295
+ }
296
+ }
297
+
298
+ /**
299
+ * Create a new subscription on the platform
300
+ *
301
+ * @param SFC_Autoship_Model_Subscription $subscription Magento subscription model object
302
+ * @return int Platform Subscription Id of the newly created or updated subscription record
303
+ */
304
+ public function createSubscription(SFC_Autoship_Model_Subscription $subscription)
305
+ {
306
+ // Get API Helper
307
+ /** @var SFC_Autoship_Helper_Api $apiHelper */
308
+ $apiHelper = Mage::helper('autoship/api');
309
+
310
+ //Get subscription in platform format
311
+ $platformSubscription = $this->convertMagentoSubscriptionToPlatform($subscription);
312
+
313
+ // Call API
314
+ $response = $apiHelper->postSubscription($platformSubscription);
315
+ // Check response for HTTP status code
316
+ if ($response['code'] != 201) {
317
+ Mage::throwException($this->__('Failed to create subscription on platform!'));
318
+ }
319
+ // Parse subscription id out of response
320
+ $result = $response['result'];
321
+ $subscriptions = $result['subscriptions'];
322
+ // Check that we have exactly 1 subscription
323
+ if (!is_array($subscriptions) || count($subscriptions) != 1) {
324
+ Mage::throwException($this->__('Failed to create subscription on platform!'));
325
+ }
326
+ // Now get customer_id of created subscription
327
+ $subscription = $subscriptions[0];
328
+ if (!is_array($subscription) || !isset($subscription['id'])) {
329
+ Mage::throwException($this->__('Failed to read response from platform while creating subscription!'));
330
+ }
331
+
332
+ // Return customer id
333
+ return $subscription['id'];
334
+ }
335
+
336
+ /**
337
+ * Create or update a customer on the platform
338
+ *
339
+ * @param Mage_Customer_Model_Customer @customer Magento customer - method will create or update this customer record on the platform
340
+ * @return int Platform Customer Id of the newly created or updated customer record
341
+ */
342
+ public function createOrUpdateCustomer(Mage_Customer_Model_Customer $customer)
343
+ {
344
+ // Get API Helper
345
+ /** @var SFC_Autoship_Helper_Api $apiHelper */
346
+ $apiHelper = Mage::helper('autoship/api');
347
+
348
+ // Query for current customer
349
+ $response = $apiHelper->fetchCustomers(
350
+ array(
351
+ 'email' => $customer->getData('email'),
352
+ ));
353
+ // Check response for HTTP status code
354
+ if ($response['code'] != 200) {
355
+ Mage::throwException('Failed to find ');
356
+ }
357
+ // Parse customer id out of response
358
+ $result = $response['result'];
359
+ $platformCustomers = $result['customers'];
360
+ // Check that we have found exactly 1 customer
361
+ if (!is_array($platformCustomers)) {
362
+ Mage::throwException($this->__('Failed to read response from platform while querying for customer!'));
363
+ }
364
+ if (count($platformCustomers) > 1) {
365
+ Mage::throwException($this->__('Found more than 1 matching customer on platform!'));
366
+ }
367
+ if (count($platformCustomers) == 1) {
368
+ // Found customer, now lets update him
369
+ // Get id of found customer
370
+ $platformCustomer = $platformCustomers[0];
371
+ if (!is_array($platformCustomer) || !isset($platformCustomer['id'])) {
372
+ Mage::throwException($this->__('Failed to read response from platform while querying for customer!'));
373
+ }
374
+
375
+ // Update this customer
376
+ return $this->updateCustomer($platformCustomer['id'], $customer);
377
+ }
378
+ else {
379
+ // Didn't find existing customer, lets create him
380
+ return $this->createCustomer($customer);
381
+ }
382
+ }
383
+
384
+ /**
385
+ * Get a customer by email, return false if the customer doesn't exist
386
+ * @param $email
387
+ * @return mixed bool|array
388
+ * @throws Mage_Core_Exception
389
+ */
390
+ public function getCustomer($email)
391
+ {
392
+ // Get API Helper
393
+ /** @var SFC_Autoship_Helper_Api $apiHelper */
394
+ $apiHelper = Mage::helper('autoship/api');
395
+
396
+ // Query for current customer
397
+ $response = $apiHelper->fetchCustomers(
398
+ array(
399
+ 'email' => $email
400
+ ));
401
+ // Check response for HTTP status code
402
+ if ($response['code'] != 200) {
403
+ Mage::log('SFC_Autoship_Helper_Platform::getCustomer Customer does not exist on platform with email: ' . $email, Zend_Log::INFO, SFC_Autoship_Helper_Data::LOG_FILE);
404
+ return false;
405
+ }
406
+ // Parse customer id out of response
407
+ $result = $response['result'];
408
+ $platformCustomers = $result['customers'];
409
+ // Check that we have found exactly 1 customer
410
+ if (!is_array($platformCustomers)) {
411
+ Mage::throwException($this->__('Failed to read response from platform while querying for customer!'));
412
+ }
413
+ if (count($platformCustomers) > 1) {
414
+ Mage::throwException($this->__('Found more than 1 matching customer on platform!'));
415
+ }
416
+ if (count($platformCustomers) == 1) {
417
+ Mage::log('SFC_Autoship_Helper_Platform::getCustomer Customer exists on platform with email: ' . $email, Zend_Log::INFO, SFC_Autoship_Helper_Data::LOG_FILE);
418
+ // Found customer, now lets update him
419
+ // Get id of found customer
420
+ $platformCustomer = $platformCustomers[0];
421
+ if (!is_array($platformCustomer) || !isset($platformCustomer['id'])) {
422
+ Mage::throwException($this->__('Failed to read response from platform while querying for customer!'));
423
+ }
424
+ return $platformCustomer;
425
+ }
426
+ return false;
427
+ }
428
+
429
+ /**
430
+ * Create a new customer on the platform
431
+ *
432
+ * @param Mage_Customer_Model_Customer @customer Magento customer - method will create this customer record on the platform
433
+ * @return int Platform Customer Id of the newly created customer record
434
+ */
435
+ public function createCustomer(Mage_Customer_Model_Customer $customer)
436
+ {
437
+ // Get API Helper
438
+ /** @var SFC_Autoship_Helper_Api $apiHelper */
439
+ $apiHelper = Mage::helper('autoship/api');
440
+
441
+ // Build an array of data representing the customer
442
+ // Get platform customer data structure
443
+ $platformCustomer = $this->convertMagentoCustomerToPlatform($customer);
444
+ // Call API
445
+ $response = $apiHelper->postCustomer($platformCustomer);
446
+ // Check response for HTTP status code
447
+ if ($response['code'] != 201) {
448
+ Mage::throwException($this->__('Failed to create customer on platform!'));
449
+ }
450
+ // Parse customer id out of response
451
+ $result = $response['result'];
452
+ $platformCustomers = $result['customers'];
453
+ // Check that we have exactly 1 customer
454
+ if (!is_array($platformCustomers) || count($platformCustomers) != 1) {
455
+ Mage::throwException($this->__('Failed to create customer on platform!'));
456
+ }
457
+ // Now get customer_id of created customer
458
+ $platformCustomer = $platformCustomers[0];
459
+ if (!is_array($platformCustomer) || !isset($platformCustomer['id'])) {
460
+ Mage::throwException($this->__('Failed to read response from platform while creating customer!'));
461
+ }
462
+
463
+ // Return customer id
464
+ return $platformCustomer['id'];
465
+ }
466
+
467
+ /**
468
+ * Update an existing customer on the platform
469
+ *
470
+ * @param int $platformCustomerId Id of the current customer record on the platform
471
+ * @param Mage_Customer_Model_Customer $customer Magento customer - this method will update the customer record on the platform with this data
472
+ * @return int Platform Customer Id of the update customer record
473
+ */
474
+ public function updateCustomer($platformCustomerId, Mage_Customer_Model_Customer $customer)
475
+ {
476
+ // Get API Helper
477
+ /** @var SFC_Autoship_Helper_Api $apiHelper */
478
+ $apiHelper = Mage::helper('autoship/api');
479
+
480
+ // Get platform customer data structure
481
+ $platformCustomer = $this->convertMagentoCustomerToPlatform($customer);
482
+ // Call API
483
+ $response = $apiHelper->updateCustomer($platformCustomerId, $platformCustomer);
484
+ // Check response for HTTP status code
485
+ if ($response['code'] != 201) {
486
+ Mage::throwException($this->__('Failed to update customer on platform!'));
487
+ }
488
+ // Parse customer id out of response
489
+ $result = $response['result'];
490
+ $platformCustomer = $result['customer'];
491
+ // Now get customer_id of created customer
492
+ if (!is_array($platformCustomer) || !isset($platformCustomer['id'])) {
493
+ Mage::throwException($this->__('Failed to read response from platform while updating customer!'));
494
+ }
495
+
496
+ // Return customer id
497
+ return $platformCustomer['id'];
498
+ }
499
+
500
+ protected function convertMagentoCustomerToPlatform(Mage_Customer_Model_Customer $customer)
501
+ {
502
+ // Build an array of data representing the customer
503
+ $platformCustomer = array(
504
+ 'magento_customer_id' => $customer->getId(),
505
+ 'email' => $customer->getData('email'),
506
+ 'first_name' => $customer->getData('firstname'),
507
+ 'middle_name' => $customer->getData('middlename'),
508
+ 'last_name' => $customer->getData('lastname'),
509
+ );
510
+ try {
511
+ if (class_exists('SFC_AuthnetToken_Model_Cim') || class_exists('SFC_CimCore_Model_Cim')) {
512
+ if (strlen($customer->getData('cim_customer_profile_id')) > 0) {
513
+ $platformCustomer['external_vault_customer_token'] = $customer->getData('cim_customer_profile_id');
514
+ }
515
+ }
516
+ } Catch (Exception $e) {
517
+ //When in dev mode 'class_exists' will throw an exception if the class can't be found
518
+ }
519
+
520
+ return $platformCustomer;
521
+ }
522
+
523
+ /**
524
+ * Gets subscriptions from the platform, into an array, filtered by $params
525
+ *
526
+ * @param Mage_Customer_Model_Customer $customer Customer for which to get subscriptions
527
+ * @param array $params Array of parameter => value pairs to filter the collection of subscriptions
528
+ * @return array Returns an array of SFC_Autoship_Model_Subscription model objects
529
+ */
530
+ public function getSubscriptions(Mage_Customer_Model_Customer $customer, $params = array())
531
+ {
532
+ // Check params is an array
533
+ if (!is_array($params)) {
534
+ Mage::throwException('Invalid parameters specified!');
535
+ }
536
+ // Add customer filter to params
537
+ $params['magento_customer_id'] = $customer->getId();
538
+
539
+ // Call All method
540
+ return $this->getAllSubscriptions($params);
541
+ }
542
+
543
+ /**
544
+ * Gets subscriptions from the platform, into an array, filtered by $params
545
+ *
546
+ * @param array $params Array of parameter => value pairs to filter the collection of subscriptions
547
+ * @return array Returns an array of SFC_Autoship_Model_Subscription model objects
548
+ */
549
+ public function getAllSubscriptions($params = array())
550
+ {
551
+ // Get API Helper
552
+ /** @var SFC_Autoship_Helper_Api $apiHelper */
553
+ $apiHelper = Mage::helper('autoship/api');
554
+
555
+ // Check params is an array
556
+ if (!is_array($params)) {
557
+ Mage::throwException('Invalid parameters specified!');
558
+ }
559
+ // Get subscriptions using API
560
+ $response = $apiHelper->fetchSubscriptions($params);
561
+ // Check response for HTTP status code
562
+ if ($response['code'] != 200) {
563
+ Mage::throwException($this->__('Failed to query for subscriptions!'));
564
+ }
565
+ // Parse subscriptions out of response
566
+ $result = $response['result'];
567
+ $platformSubscriptions = $result['subscriptions'];
568
+ // Iterate subscriptions and build subscription model objects
569
+ $subscriptions = array();
570
+ foreach ($platformSubscriptions as $platformSubscription) {
571
+ // Convert platform subscription to Magento model and save in array
572
+ $subscription = $this->convertPlatformSubscriptionToMagento($platformSubscription);
573
+ if(isset($params['magento_customer_id'])) {
574
+ $subscription['customer_id'] = $params['magento_customer_id'];
575
+ }
576
+ $subscriptions[] = $subscription;
577
+ }
578
+
579
+ // Return array of subscriptions
580
+ return $subscriptions;
581
+ }
582
+
583
+ /**
584
+ * Get a subscription by id
585
+ *
586
+ * @param int $subscriptionId Unique id of subscription on platform
587
+ * @return \SFC_Autoship_Model_Subscription Return the subscription model
588
+ */
589
+ public function getSubscription($subscriptionId)
590
+ {
591
+ // Get API Helper
592
+ /** @var SFC_Autoship_Helper_Api $apiHelper */
593
+ $apiHelper = Mage::helper('autoship/api');
594
+ // Call delete on API
595
+ $response = $apiHelper->fetchSubscription($subscriptionId);
596
+ // Check response for HTTP status code
597
+ if ($response['code'] != 200) {
598
+ Mage::throwException($this->__('Failed to GET subscription!'));
599
+ }
600
+ // Parse subscription from result
601
+ $result = $response['result'];
602
+ if (!isset($result['subscription']) || !is_array($result['subscription'])) {
603
+ Mage::throwException($this->__('Failed to parse GET subscription response!'));
604
+ }
605
+ $platformSubscription = $result['subscription'];
606
+ // Assume subscription is for current customer
607
+ /** @var Mage_Customer_Model_Session $customerSession */
608
+ $customerSession = Mage::getSingleton('customer/session');
609
+ $customer = $customerSession->getCustomer();
610
+ // Convert subscription to Mage model
611
+ $subscription = $this->convertPlatformSubscriptionToMagento($platformSubscription, $customer);
612
+
613
+ // Return subscription
614
+ return $subscription;
615
+ }
616
+
617
+ /**
618
+ * Update an existing subscription on the platform
619
+ *
620
+ * @param int $platformSubscriptionId Id of the current subscription record on the platform
621
+ * @param SFC_Autoship_Model_Subscription $subscription Mage subscription model object
622
+ * @return int Platform subscription Id of the update subscription record
623
+ */
624
+ public function updateSubscription($platformSubscriptionId, SFC_Autoship_Model_Subscription $subscription)
625
+ {
626
+ // Get API Helper
627
+ /** @var SFC_Autoship_Helper_Api $apiHelper */
628
+ $apiHelper = Mage::helper('autoship/api');
629
+
630
+ //Get subscription in platform format
631
+ $platformSubscription = $this->convertMagentoSubscriptionToPlatform($subscription, $platformSubscriptionId);
632
+
633
+ // Call API
634
+ $response = $apiHelper->updateSubscription($platformSubscriptionId, $platformSubscription);
635
+ // Check response for HTTP status code
636
+ if ($response['code'] != 201) {
637
+ Mage::throwException($this->__('Failed to update subscription on platform!'));
638
+ }
639
+ // Parse customer id out of response
640
+ $result = $response['result'];
641
+ $platformSubscription = $result['subscription'];
642
+ // Now get customer_id of created subscription
643
+ if (!is_array($platformSubscription) || !isset($platformSubscription['id'])) {
644
+ Mage::throwException($this->__('Failed to read response from platform while updating subscription!'));
645
+ }
646
+
647
+ // Return customer id
648
+ return $platformSubscription['id'];
649
+ }
650
+
651
+ /**
652
+ * Transform a Subscription model into an array that can be read by the platform
653
+ * @param SFC_Autoship_Model_Subscription $subscription
654
+ * @param null $platformSubscriptionId
655
+ * @return array
656
+ */
657
+ public function convertMagentoSubscriptionToPlatform(SFC_Autoship_Model_Subscription $subscription, $platformSubscriptionId = null)
658
+ {
659
+ // Get API Helper
660
+ /** @var SFC_Autoship_Helper_Api $apiHelper */
661
+ $apiHelper = Mage::helper('autoship/api');
662
+
663
+ if (!$subscription->getData('platform_customer_id')) {
664
+ // Get customer
665
+ $customer = $subscription->getCustomer();
666
+ // Create or update the customer
667
+ $platformCustomerId = $this->createOrUpdateCustomer($customer);
668
+ $subscription->setData('platform_customer_id', $platformCustomerId);
669
+ }
670
+
671
+ if (!$subscription->getData('product_sku')) {
672
+ $sku = Mage::getModel('catalog/product')->load($subscription->getData('product_id'))->getSku();
673
+ $subscription->setData('product_sku', $sku);
674
+ }
675
+
676
+ $platformSubscription = array(
677
+ 'customer_id' => $subscription->getData('platform_customer_id'),
678
+ 'subscription_products' => array(
679
+ array(
680
+ 'product_sku' => $subscription->getData('product_sku'),
681
+ 'qty' => $subscription->getData('qty')
682
+ )
683
+ ),
684
+ 'next_order_date' => substr($subscription->getData('next_order_date'), 0, 10),
685
+ 'interval' => $subscription->getData('interval'),
686
+ 'magento_shipping_address_id' => $subscription->getData('shipping_address_id'),
687
+ 'magento_shipping_method_code' => $subscription->getData('shipping_method'),
688
+ 'coupon_code' => $subscription->getData('coupon_code'),
689
+ 'skip_first_order' => $subscription->getData('skip_first_order'),
690
+ 'send_customer_notification' => $subscription->getData('send_customer_notification'),
691
+ 'magento_store_code' => $subscription->getData('magento_store_code')
692
+ );
693
+
694
+ // If expiration date set, set on platform
695
+ if($subscription->hasData('expiration_date')) {
696
+ $platformSubscription['expiration_date'] = $subscription->getData('expiration_date');
697
+ }
698
+
699
+ //If subscription is using fixed price
700
+ if ($subscription->hasData('use_fixed_price')) {
701
+ $platformSubscription['use_fixed_price'] = $subscription->getData('use_fixed_price');
702
+ }
703
+
704
+ //Set fixed price
705
+ if ($subscription->hasData('fixed_price')) {
706
+ $platformSubscription['fixed_price'] = $subscription->getData('fixed_price');
707
+ }
708
+
709
+ // If status is set, update
710
+ if($subscription->hasData('status')) {
711
+ $platformSubscription['status'] = $subscription->getData('status');
712
+ }
713
+
714
+ $options = $subscription->getData('magento_product_options');
715
+ if (is_array($options) && count($options)) {
716
+ $platformSubscription['subscription_products'][0]['magento_product_options'] = $options;
717
+ }
718
+
719
+ $additionalOptions = $subscription->getData('magento_additional_options');
720
+ if (is_array($additionalOptions) && count($additionalOptions)) {
721
+ $platformSubscription['subscription_products'][0]['magento_additional_options'] = $additionalOptions;
722
+ }
723
+
724
+ // Add payment details
725
+ // New, multi-gateway aware method
726
+ $platformSubscription['payment_profile'] = array(
727
+ 'billing_address' => array(
728
+ 'magento_address_id' => $subscription->getData('billing_address_id'),
729
+ 'first_name' => $subscription->getData('billing_first_name'),
730
+ 'last_name' => $subscription->getData('billing_last_name'),
731
+ ),
732
+ 'gateway' => array(
733
+ 'name' => $this->_methodCodeMap[$subscription->getData('payment_method_code')],
734
+ ),
735
+ 'payment_token' => $subscription->getData('payment_token'),
736
+ 'creditcard_last_digits' => substr($subscription->getData('customer_cardnumber'), -4),
737
+ );
738
+
739
+ return $platformSubscription;
740
+ }
741
+
742
+ /**
743
+ * Delete a subscription
744
+ *
745
+ * @param int $subscriptionId Unique id of subscription on platform
746
+ */
747
+ public function deleteSubscription($subscriptionId)
748
+ {
749
+ // Get API Helper
750
+ /** @var SFC_Autoship_Helper_Api $apiHelper */
751
+ $apiHelper = Mage::helper('autoship/api');
752
+ // Call delete on API
753
+ $response = $apiHelper->deleteSubscription($subscriptionId);
754
+ // Check response for HTTP status code
755
+ if ($response['code'] != 204) {
756
+ Mage::throwException($this->__('Failed to delete subscription!'));
757
+ }
758
+ }
759
+
760
+ /**
761
+ * Cancel a subscription
762
+ *
763
+ * @param int $subscriptionId Unique id of subscription on platform
764
+ */
765
+ public function cancelSubscription($subscriptionId)
766
+ {
767
+ // Get API Helper
768
+ /** @var SFC_Autoship_Helper_Api $apiHelper */
769
+ $apiHelper = Mage::helper('autoship/api');
770
+ // Call delete on API
771
+ $response = $apiHelper->cancelSubscription($subscriptionId);
772
+ // Check response for HTTP status code
773
+ if ($response['code'] != 204) {
774
+ Mage::throwException($this->__('Failed to cancel subscription!'));
775
+ }
776
+ }
777
+
778
+ /**
779
+ * Pause a subscription
780
+ *
781
+ * @param int $subscriptionId Unique id of subscription on platform
782
+ */
783
+ public function pauseSubscription($subscriptionId)
784
+ {
785
+ // Get API Helper
786
+ /** @var SFC_Autoship_Helper_Api $apiHelper */
787
+ $apiHelper = Mage::helper('autoship/api');
788
+ // Call delete on API
789
+ $response = $apiHelper->pauseSubscription($subscriptionId);
790
+ // Check response for HTTP status code
791
+ if ($response['code'] != 204) {
792
+ Mage::throwException($this->__('Failed to pause subscription!'));
793
+ }
794
+ }
795
+
796
+ /**
797
+ * Restart a subscription
798
+ *
799
+ * @param int $subscriptionId Unique id of subscription on platform
800
+ */
801
+ public function restartSubscription($subscriptionId)
802
+ {
803
+ // Get API Helper
804
+ /** @var SFC_Autoship_Helper_Api $apiHelper */
805
+ $apiHelper = Mage::helper('autoship/api');
806
+ // Call delete on API
807
+ $response = $apiHelper->restartSubscription($subscriptionId);
808
+ // Check response for HTTP status code
809
+ if ($response['code'] != 204) {
810
+ Mage::throwException($this->__('Failed to restart subscription!'));
811
+ }
812
+ }
813
+
814
+ /**
815
+ * Skip next delivery on a subscription
816
+ *
817
+ * @param int $subscriptionId Unique id of subscription on platform
818
+ */
819
+ public function skipSubscription($subscriptionId)
820
+ {
821
+ // Get API Helper
822
+ /** @var SFC_Autoship_Helper_Api $apiHelper */
823
+ $apiHelper = Mage::helper('autoship/api');
824
+ // Call delete on API
825
+ $response = $apiHelper->skipSubscription($subscriptionId);
826
+ // Check response for HTTP status code
827
+ if ($response['code'] != 204) {
828
+ Mage::throwException($this->__('Failed to skip next delivery on subscription!'));
829
+ }
830
+ }
831
+
832
+ public function getAccountConfig()
833
+ {
834
+ if($this->_accountConfig == null) {
835
+ // Get API Helper
836
+ /** @var SFC_Autoship_Helper_Api $apiHelper */
837
+ $apiHelper = Mage::helper('autoship/api');
838
+
839
+ // Query for current customer
840
+ $response = $apiHelper->fetchConfig();
841
+ // Check response for HTTP status code
842
+ if ($response['code'] != 200) {
843
+ Mage::throwException($this->__('Failed to find account configuration!'));
844
+ }
845
+ // Get config data out of response structure
846
+ $config = $response['result']['config'];
847
+ $this->_accountConfig = $config;
848
+ }
849
+
850
+ return $this->_accountConfig;
851
+ }
852
+
853
+ public function getConfiguredPaymentMethodCode()
854
+ {
855
+ // Get account configuration from platform
856
+ $accountConfig = $this->getAccountConfig();
857
+ if (isset($accountConfig['magento_payment_method'])) {
858
+ return $accountConfig['magento_payment_method'];
859
+ }
860
+ else {
861
+ return '';
862
+ }
863
+ }
864
+
865
+ public function getConfiguredGateway()
866
+ {
867
+ // Get account configuration from platform
868
+ $accountConfig = $this->getAccountConfig();
869
+ if (isset($accountConfig['payment_gateway'])) {
870
+ return $accountConfig['payment_gateway'];
871
+ }
872
+ else {
873
+ return '';
874
+ }
875
+ }
876
+
877
+ /**
878
+ * Converts subscription data from platform to Magento model object
879
+ *
880
+ * @param array $platformSubscription Subscription data returned from platform
881
+ * @param Mage_Customer_Model_Customer|null $customer
882
+ * @return SFC_Autoship_Model_Subscription Magento subscription model object
883
+ */
884
+ protected function convertPlatformSubscriptionToMagento(array $platformSubscription, Mage_Customer_Model_Customer $customer = null)
885
+ {
886
+ // Get API Helper
887
+ /** @var SFC_Autoship_Helper_Api $apiHelper */
888
+ $apiHelper = Mage::helper('autoship/api');
889
+
890
+ /** @var SFC_Autoship_Model_Subscription $subscription */
891
+ $subscription = Mage::getModel('autoship/subscription');
892
+
893
+ //First set the subscription id
894
+ $subscription->setData('subscription_id', $platformSubscription['id']);
895
+
896
+ //Iterate over all scalar (top-level) values returned by the platform helper, and set them on the subscription
897
+ //Exclude values where the subscription key is not the magento model key
898
+ $_mappedFields = array('id', 'customer_id', 'magento_shipping_address_id', 'magento_shipping_method_code');
899
+ foreach($platformSubscription as $k => $v) {
900
+ if (is_scalar($v) && !in_array($k, $_mappedFields)) {
901
+ $subscription->setData($k, $v);
902
+ }
903
+ }
904
+
905
+ $platformProducts = $platformSubscription['subscription_products'];
906
+ $platformProduct = $platformProducts[0];
907
+ /** @var Mage_Catalog_Model_Product $productModel */
908
+ $productModel = Mage::getModel('catalog/product');
909
+ $productId = $productModel->getIdBySku($platformProduct['product_sku']);
910
+ if (isset($platformProduct['id'])) {
911
+ $subscription->setData('platform_product_id', $platformProduct['id']);
912
+ } else {
913
+ $subscription->setData('platform_product_id', null);
914
+ }
915
+ $subscription->setData('product_sku', $platformProduct['product_sku']);
916
+ $subscription->setData('product_id', $productId);
917
+ $subscription->setData('qty', $platformProduct['qty']);
918
+
919
+ $subscription->setData('platform_customer_id', $platformSubscription['customer_id']);
920
+ if($customer != null) {
921
+ $subscription->setData('customer_id', $customer->getId());
922
+ }
923
+
924
+ if (isset($platformSubscription['payment_profile']['billing_address']['magento_address_id'])) {
925
+ $subscription->setData('billing_address_id', $platformSubscription['payment_profile']['billing_address']['magento_address_id']);
926
+ }
927
+ $subscription->setData('billing_first_name', $platformSubscription['payment_profile']['billing_address']['first_name']);
928
+ $subscription->setData('billing_last_name', $platformSubscription['payment_profile']['billing_address']['last_name']);
929
+ if (isset($platformSubscription['magento_shipping_address_id'])) {
930
+ $subscription->setData('shipping_address_id', $platformSubscription['magento_shipping_address_id']);
931
+ }
932
+ $subscription->setData('shipping_method', $platformSubscription['magento_shipping_method_code']);
933
+
934
+ // Save generic pay profile
935
+ $subscription->setData('payment_profile', $platformSubscription['payment_profile']);
936
+ // Handle payment gateway specific setting
937
+ $subscription->setData('payment_method_code', $this->getConfiguredPaymentMethodCode());
938
+ $subscription->setData('payment_token', $platformSubscription['payment_profile']['payment_token']);
939
+ $subscription->setData('creditcard_last_digits', $platformSubscription['payment_profile']['creditcard_last_digits']);
940
+ $subscription->setData('customer_cardnumber', $platformSubscription['payment_profile']['creditcard_last_digits']);
941
+
942
+ return $subscription;
943
+ }
944
+
945
+ /**
946
+ * @param $code
947
+ */
948
+ public function getReport($code)
949
+ {
950
+ // Get API Helper
951
+ /** @var SFC_Autoship_Helper_Api $apiHelper */
952
+ $apiHelper = Mage::helper('autoship/api');
953
+
954
+ $response = $apiHelper->fetchReport($code);
955
+
956
+ if ($response['code'] !== 200) {
957
+ Mage::log('SFC_Autoship_Helper_Platform::getReport Report does not exist on platform with code: ' . $code, Zend_Log::INFO, SFC_Autoship_Helper_Data::LOG_FILE);
958
+ }
959
+
960
+ $result = $response['result'];
961
+
962
+ if (!$result) {
963
+ Mage::log('SFC_Autoship_Helper_Platform::getReport Report has no result, with code: ' . $code, Zend_Log::INFO, SFC_Autoship_Helper_Data::LOG_FILE);
964
+ Mage::throwException($this->__('Failed to read result for report with code %s', $code));
965
+ }
966
+
967
+ return $result;
968
+ }
969
+
970
+ }
app/code/local/SFC/Autoship/Helper/Product.php CHANGED
@@ -1,4 +1,4 @@
1
- <?php //00612
2
  /**
3
  * Subscribe Pro - Subscriptions Management Extension
4
  *
@@ -15,56 +15,103 @@
15
  *
16
  */
17
 
18
- if(!extension_loaded('ionCube Loader')){$__oc=strtolower(substr(php_uname(),0,3));$__ln='/ioncube/ioncube_loader_'.$__oc.'_'.substr(phpversion(),0,3).(($__oc=='win')?'.dll':'.so');$__oid=$__id=realpath(ini_get('extension_dir'));$__here=dirname(__FILE__);if((@$__id[1])==':'){$__id=str_replace('\\','/',substr($__id,2));$__here=str_replace('\\','/',substr($__here,2));}$__rd=str_repeat('/..',substr_count($__id,'/')).$__here.'/';$__i=strlen($__rd);while($__i--){if($__rd[$__i]=='/'){$__lp=substr($__rd,0,$__i).$__ln;if(file_exists($__oid.$__lp)){$__ln=$__lp;break;}}}@dl($__ln);}else{die('The file '.__FILE__." is corrupted. Ensure that you use binary mode when transferring files with FTP and disable the 'TAR smart cr/lf feature' if using WinZIP\n");}if(function_exists('_il_exec')){return _il_exec();}die('The file <b>'.__FILE__.'</b> has been encoded with the <a href="http://www.ioncube.com">ionCube PHP Encoder</a> and requires the free '.basename($__ln).' <a href="http://www.ioncube.com/loader_download/">ionCube PHP Loader</a> to be installed.');
 
19
 
20
- ?>
21
- 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
- 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
- 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
- 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
- 0U0ncMQlRlzJgHaMVfCcL/YtkQwsJbSO9cd65AM+X98U4VX1H1KvI3cuG2Y9hNdVMS60af7du6eR
26
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- +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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- cX9LDvYToRkxb5HIZQqZPS8xPsmdOdT30NPiDBk3lHasCFWTzO8SHHKp6JGjKv9i9a2VnFeH7XAg
64
- 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
- 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
- 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
- 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
- K7i3uxe2anYQKIBWYq6bUXOWWb73SugeIOYuurVGioyrLXmqI436h+k5yVgLMXwdGIX2ZQh6gkPm
69
- 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
70
- ek20Fo5SkayddkDm9YEjiFB4qW==
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
  /**
3
  * Subscribe Pro - Subscriptions Management Extension
4
  *
15
  *
16
  */
17
 
18
+ class SFC_Autoship_Helper_Product extends Mage_Core_Helper_Abstract
19
+ {
20
 
21
+ private $platformConnectionVerified = false;
22
+
23
+ protected function _construct()
24
+ {
25
+ }
26
+
27
+ /**
28
+ * Determine if product is available for subscription on a given store
29
+ *
30
+ * @param Mage_Catalog_Model_Product|integer $product
31
+ * @param null|integer|Mage_Core_Model_Store $store
32
+ * @param bool $verifyApiConnection
33
+ * @return bool
34
+ */
35
+ public function isAvailableForSubscription($product, $store = null, $verifyApiConnection = true)
36
+ {
37
+ // Lookup current store if not passed in
38
+ if ($store == null) {
39
+ $store = Mage::app()->getStore();
40
+ }
41
+ // Lookup store from numeric ID
42
+ if (is_numeric($store)) {
43
+ $store = Mage::app()->getStore($store);
44
+ }
45
+ // Get product id
46
+ if ($product instanceof Mage_Catalog_Model_Product) {
47
+ $productId = $product->getId();
48
+ }
49
+ else {
50
+ $productId = $product;
51
+ }
52
+ // Get product resource object
53
+ /** @var Mage_Catalog_Model_Resource_Product $resource */
54
+ $resource = Mage::getModel('catalog/product')->getResource();
55
+ // Lookup whether product is enabled for the website
56
+ $websiteIds = $resource->getWebsiteIds($productId);
57
+ if (in_array($store->getWebsite()->getId(), $websiteIds)) {
58
+ // Product is enabled for website
59
+ // Lookup whether product enabled / disabled for subscription
60
+ $isProductEnabled = $resource->getAttributeRawValue($productId, 'subscription_enabled', $store) == '1';
61
+ }
62
+ else {
63
+ // Product not enabled for website, so by proxy we say not available for subscription
64
+ $isProductEnabled = false;
65
+ }
66
+
67
+ if ($isProductEnabled) {
68
+ if ($verifyApiConnection) {
69
+ return $this->verifyPlatformConnection($product, $store);
70
+ }
71
+ else {
72
+ return true;
73
+ }
74
+ }
75
+ else {
76
+ return false;
77
+ }
78
+ }
79
+
80
+ /**
81
+ * @param $product
82
+ * @param $store
83
+ * @return bool
84
+ */
85
+ protected function verifyPlatformConnection($product, $store)
86
+ {
87
+ if ($this->platformConnectionVerified) {
88
+ return true;
89
+ }
90
+ else {
91
+ /** @var SFC_Autoship_Helper_Platform $platformHelper */
92
+ $platformHelper = Mage::helper('autoship/platform');
93
+ /** @var SFC_Autoship_Helper_Api $apiHelper */
94
+ $apiHelper = Mage::helper('autoship/api');
95
+ $apiHelper->setConfigStore($store);
96
+ try {
97
+ // Fetch product, this will get it from cache, or fetch it
98
+ // Basically this is going to correspond to whether the request will be successful otherwise
99
+ // Its a cheap & dirty way to get a jump on API comm issue and pretend like product is not enabled for sub
100
+ $response = $apiHelper->fetchProducts(array('sku' => $product->getSku()));
101
+ // Set flag
102
+ $this->platformConnectionVerified = true;
103
+
104
+ return true;
105
+ }
106
+ catch(\Exception $e) {
107
+ // Set flag
108
+ $this->platformConnectionVerified = false;
109
+ // Log
110
+ Mage::log('Failed to verify connection to Subscribe Pro platform!', Zend_Log::ERR, SFC_Autoship_Helper_Data::API_LOG_FILE);
111
+
112
+ return false;
113
+ }
114
+ }
115
+ }
116
+
117
+ }
app/code/local/SFC/Autoship/Helper/Quote.php CHANGED
@@ -1,4 +1,4 @@
1
- <?php //00612
2
  /**
3
  * Subscribe Pro - Subscriptions Management Extension
4
  *
@@ -15,256 +15,786 @@
15
  *
16
  */
17
 
18
- if(!extension_loaded('ionCube Loader')){$__oc=strtolower(substr(php_uname(),0,3));$__ln='/ioncube/ioncube_loader_'.$__oc.'_'.substr(phpversion(),0,3).(($__oc=='win')?'.dll':'.so');$__oid=$__id=realpath(ini_get('extension_dir'));$__here=dirname(__FILE__);if((@$__id[1])==':'){$__id=str_replace('\\','/',substr($__id,2));$__here=str_replace('\\','/',substr($__here,2));}$__rd=str_repeat('/..',substr_count($__id,'/')).$__here.'/';$__i=strlen($__rd);while($__i--){if($__rd[$__i]=='/'){$__lp=substr($__rd,0,$__i).$__ln;if(file_exists($__oid.$__lp)){$__ln=$__lp;break;}}}@dl($__ln);}else{die('The file '.__FILE__." is corrupted. Ensure that you use binary mode when transferring files with FTP and disable the 'TAR smart cr/lf feature' if using WinZIP\n");}if(function_exists('_il_exec')){return _il_exec();}die('The file <b>'.__FILE__.'</b> has been encoded with the <a href="http://www.ioncube.com">ionCube PHP Encoder</a> and requires the free '.basename($__ln).' <a href="http://www.ioncube.com/loader_download/">ionCube PHP Loader</a> to be installed.');
19
-
20
- ?>
21
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- pHycz5S+kh8oWyp6jSjmkK5b0UpOp3zhpEHJ+fhapzB3+AcdY6RWiZBHilEibIrmDI4I7xTLedBW
66
- +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
- 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
- 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
- +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
- Lv3HI9BGSh0BNirTwHS1ExuYJ0g4UAqL4kO60jrpGrnXmeem7BLV1KBbeazB0lftYmm7yVVg3gY7
71
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- XJI3rtOuI+qVWvVvRMr0Gspi8UcWJIE2H4Lt/eHR9h7mtPg1RbQ7BzHbgrpGnVQbj3g2X4QOZNz5
92
- 5FzIEHGh9GpVIalHnaPbTQ9kPlV3k3iOVw530aVi1x2LRMLBYTKzBm5l9DJd/cO7Tdpp+DdwdSm6
93
- 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
- 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
- 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
- +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
- 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
- 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
- un2zzYY+O0FB/gicTuwoO44c8aaHD3T9PfdW0J0COXsLylm4qigYFRWQzyByRMX27LbWJvTA2wkV
100
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- anl0VVzFOdCsbpcLTb1UrWLfnhtHGf2FuYGrZeg7D01a5KVFA6/R/uz1I6lEMQN5GeAUMdHcicDd
109
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- +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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- cx7SdCP4ziDHfWXxQv6GiXfWQp33WyuSzV3PE0Rnz1k1oUTlh6d46Wt/fQYFLHT4pzl+QVQFr1S5
157
- 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
- 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
- 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
- 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
- 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
- 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
- bgpsqdPF7wkQHwyBMMZ8JbM7wHDw60t/ynB/U/rn4ZHrxods0CFSTW+BBX/nYSpBVCkGPXv4+LvG
164
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- c/1g8UC8IpKuAaZ93ZvHDj+YN2DokEc1ZnMi+A8FYU7mzmi7MIkWQFWaavSpOwrvTDT5X2qsxH2/
182
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- +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
- 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
- 4tH5DYougMY0Nf8Xdpw4fbPc0fXDwE0TO0pjsnYzFoBrV3ToBlvXbSYYxNaMwoSamQI4OZ5T9qvO
195
- 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
- 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
- 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
- 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
- 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
- AmZ2kd7N/EVBEWrywNwjpaF2owla6tBlaviXfq4Ntde3Qb/PWhYJyHBP6MQ5UwtLL78ctg6CVNuT
201
- +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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 0+fD4F3i77ZoVXA/yKuF2P9zUqY8qaVmTOmcGyGRVdJNGTlG5w5lT8R1nX7e2j9AzkHrZcR9SAI8
227
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- KRdJ3kOmXXyDioQ3gcnK2xgN5p2zaPLkM38p1iZQWNyzOeutycX2jy1aL115syVMRDObX0gUZmUJ
237
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- P+NJMhcLur1r2UshPIr1C6HMLF53gyQAc8z5BS8IKxvsdaMUeilZvY9a2I35u54RdGdq5RmjMsy+
252
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- OCX4wuWeJzkeseM0MKNrHPtPG5wiZkTioVtljoXHobrmztybE7UFh6zi7aQypHTyenXO35HjQK9D
268
- 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
- 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
- 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
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
  /**
3
  * Subscribe Pro - Subscriptions Management Extension
4
  *
15
  *
16
  */
17
 
18
+ class SFC_Autoship_Helper_Quote extends Mage_Core_Helper_Abstract
19
+ {
20
+ protected function _construct()
21
+ {
22
+ }
23
+
24
+ public function getRelevantProductFromQuoteItem(Mage_Sales_Model_Quote_Item $quoteItem)
25
+ {
26
+ if ($quoteItem->getProductType() == Mage_Catalog_Model_Product_Type::TYPE_CONFIGURABLE) {
27
+ return $quoteItem->getOptionByCode('simple_product')->getProduct();
28
+ }
29
+ else {
30
+ return $quoteItem->getProduct();
31
+ }
32
+ }
33
+
34
+ public function getRelevantProductFromOrderItem(Mage_Sales_Model_Order_Item $quoteItem)
35
+ {
36
+ if ($quoteItem->getProductType() == Mage_Catalog_Model_Product_Type::TYPE_CONFIGURABLE) {
37
+ return $quoteItem->getOptionByCode('simple_product')->getProduct();
38
+ }
39
+ else {
40
+ return $quoteItem->getProduct();
41
+ }
42
+ }
43
+
44
+ public function addAdditionalOptionsToOrderItem(Mage_Sales_Model_Order_Item $orderItem)
45
+ {
46
+ if($orderItem->getData('item_fulfils_subscription')) {
47
+ // Get options
48
+ $options = $orderItem->getProductOptions();
49
+ // Get existing additional_options
50
+ if(isset($options['additional_options']) && is_array($options['additional_options'])) {
51
+ $additionalOptions = $options['additional_options'];
52
+ }
53
+ else {
54
+ $additionalOptions = array();
55
+ }
56
+ // Add our details
57
+ $additionalOptions[] = array(
58
+ 'label' => $this->__('Product Subscription Id'),
59
+ 'value' => $orderItem->getData('subscription_id'),
60
+ );
61
+ $additionalOptions[] = array(
62
+ 'label' => $this->__('Subscription Interval'),
63
+ 'value' => $orderItem->getData('subscription_interval'),
64
+ );
65
+ // Set new additional_options on order item
66
+ $options['additional_options'] = $additionalOptions;
67
+ $orderItem->setProductOptions($options);
68
+ }
69
+ }
70
+
71
+ /**
72
+ * Does current quote (passed in quote or current shopping cart in session) have any products which are flagged for subscription?
73
+ *
74
+ * @param Mage_Sales_Model_Quote $quote Quote to check. If null, method will check quote from cart session
75
+ * @return bool
76
+ */
77
+ public function hasProductsToCreateNewSubscription(Mage_Sales_Model_Quote $quote = null)
78
+ {
79
+ // Get platform helper
80
+ /** @var SFC_Autoship_Helper_Product $productHelper */
81
+ $productHelper = Mage::helper('autoship/product');
82
+
83
+ // If passed in quote is empty, get quote from cart in session
84
+ if($quote == null) {
85
+ if (Mage::app()->getStore()->isAdmin()) {
86
+ $quote = Mage::getSingleton("adminhtml/session_quote")->getQuote();
87
+ } else {
88
+ // Get cart, quote and quote item
89
+ /** @var Mage_Checkout_Model_Cart $cart */
90
+ $cart = Mage::getSingleton('checkout/cart');
91
+ // Get quote
92
+ $quote = $cart->getQuote();
93
+ }
94
+ }
95
+ // Iterate items in quote
96
+ /** @var Mage_Sales_Model_Quote_Item $quoteItem */
97
+ foreach ($quote->getAllVisibleItems() as $quoteItem) {
98
+ // Get subscription product profile
99
+ $product = $this->getRelevantProductFromQuoteItem($quoteItem);
100
+ // Lookup whether product enabled / disabled for subscription
101
+ $isProductEnabled = $productHelper->isAvailableForSubscription($product, $quote->getStore());
102
+ // Check product profile, if this isn't a subscription product, ignore it
103
+ if ($isProductEnabled) {
104
+ // Check quote item flag which indicates we should create a new subscription for this product
105
+ if ($quoteItem->getData('create_new_subscription_at_checkout')) {
106
+ return true;
107
+ }
108
+ }
109
+ /*
110
+ // We longer take the platform's enabled flag on product as authoritative
111
+ $platformProduct = $platformHelper->getPlatformProduct($product);
112
+ // Check product profile, if this isn't a subscription product, ignore it
113
+ if ($platformProduct->getData('enabled')) {
114
+ // Check quote item flag which indicates we should create a new subscription for this product
115
+ if ($quoteItem->getData('create_new_subscription_at_checkout')) {
116
+ return true;
117
+ }
118
+ }
119
+ */
120
+ }
121
+
122
+ // Didn't find any, return false
123
+ return false;
124
+ }
125
+
126
+ public function hasSubscriptionReorderProduct(Mage_Sales_Model_Quote $quote = null)
127
+ {
128
+ // If passed in quote is empty, get quote from cart in session
129
+ if($quote == null) {
130
+ // Get cart, quote and quote item
131
+ /** @var Mage_Checkout_Model_Cart $cart */
132
+ $cart = Mage::getSingleton('checkout/cart');
133
+ // Get quote
134
+ $quote = $cart->getQuote();
135
+ }
136
+ // Iterate items in quote
137
+ /** @var Mage_Sales_Model_Quote_Item $quoteItem */
138
+ foreach ($quote->getAllVisibleItems() as $quoteItem) {
139
+ // Check quote item attributes
140
+ $itemFulfilsSubscription = $quoteItem->getData('item_fulfils_subscription');
141
+ $itemCreatesNewSubscription = $quoteItem->getData('create_new_subscription_at_checkout');
142
+ // Check quote item flag which indicates we should create a new subscription for this product
143
+ if ($itemFulfilsSubscription && !$itemCreatesNewSubscription) {
144
+ return true;
145
+ }
146
+ }
147
+
148
+ // Didn't find any, return false
149
+ return false;
150
+ }
151
+
152
+ /**
153
+ * @param Mage_Catalog_Model_Product $product
154
+ * @param null $params
155
+ */
156
+ public function onCheckoutCartAddProductComplete(Mage_Catalog_Model_Product $product, $params = null)
157
+ {
158
+ if (is_null($params)) {
159
+ // Get params from request
160
+ $request = Mage::app()->getRequest();
161
+ $params = $request->getParams();
162
+ }
163
+ // Filter delivery params
164
+ $deliveryOption = isset($params['delivery-option']) ? $params['delivery-option'] : '';
165
+ $deliveryInterval = isset($params['delivery-interval']) ? $params['delivery-interval'] : '';
166
+ $requestQty = isset($params['qty']) ? $params['qty'] : 1;
167
+
168
+ $this->updateProductInCart($product, $deliveryOption, $deliveryInterval);
169
+ }
170
+
171
+ /**
172
+ * @param Mage_Catalog_Model_Product $groupedProduct
173
+ * @param null $params
174
+ */
175
+ public function onCheckoutCartAddGroupedProductComplete(Mage_Catalog_Model_Product $groupedProduct, $params = null)
176
+ {
177
+ if (is_null($params)) {
178
+ // Get request info
179
+ // Get params from request
180
+ $request = Mage::app()->getRequest();
181
+ $params = $request->getParams();
182
+ }
183
+ $superGroupParam = isset($params['super_group']) ? $params['super_group'] : '';
184
+ $deliveryOptionParam = isset($params['delivery-option']) ? $params['delivery-option'] : '';
185
+ $deliveryIntervalParam = isset($params['delivery-interval']) ? $params['delivery-interval'] : '';
186
+
187
+ // Get product type instance
188
+ $typeInstance = $groupedProduct->getTypeInstance(true);
189
+ // Iterate through associated products and handle 1 at a time
190
+ /** @var Mage_Catalog_Model_Product $product */
191
+ foreach ($typeInstance->getAssociatedProducts($groupedProduct) as $product) {
192
+ // Check if product was added to the cart
193
+ if (isset($superGroupParam[$product->getId()])) {
194
+ // Check if quantity added was > 0
195
+ if ($superGroupParam[$product->getId()] > 0) {
196
+ // Get params
197
+ // Update cart
198
+ if (Mage::app()->getStore()->isAdmin()) {
199
+ //If in admin, there is no parent item, so transfer custom options
200
+ $product->setCustomOptions(array(
201
+ 'product_type' => new Varien_Object(array(
202
+ 'value' => 'grouped',
203
+ 'code' => 'product_type'
204
+ ))
205
+ ));
206
+ }
207
+ $this->updateProductInCart(
208
+ $product,
209
+ is_array($deliveryOptionParam) ? $deliveryOptionParam[$product->getId()] : '',
210
+ is_array($deliveryOptionParam) ? $deliveryIntervalParam[$product->getId()] : '');
211
+
212
+ }
213
+ }
214
+ }
215
+ }
216
+
217
+ /**
218
+ * @return Mage_Sales_Model_Quote
219
+ */
220
+ protected function _getQuote()
221
+ {
222
+ return Mage::app()->getStore()->isAdmin()
223
+ ? Mage::getSingleton("adminhtml/session_quote")->getQuote()
224
+ : Mage::getSingleton("checkout/cart")->getQuote();
225
+ }
226
+
227
+ /**
228
+ * @return Mage_Adminhtml_Model_Session_Quote|Mage_Checkout_Model_Session
229
+ */
230
+ protected function _getCheckoutSession()
231
+ {
232
+ return Mage::app()->getStore()->isAdmin()
233
+ ? Mage::getSingleton("adminhtml/session_quote")
234
+ : Mage::getSingleton("checkout/session");
235
+ }
236
+
237
+ protected function updateProductInCart($product, $deliveryOption, $deliveryInterval)
238
+ {
239
+ // Get platform helper
240
+ /** @var SFC_Autoship_Helper_Platform $platformHelper */
241
+ $platformHelper = Mage::helper('autoship/platform');
242
+ /** @var SFC_Autoship_Helper_Product $productHelper */
243
+ $productHelper = Mage::helper('autoship/product');
244
+
245
+ // Get quote
246
+ $quote = $this->_getQuote();
247
+
248
+ // Check if product is enabled
249
+ // In admin, if the product isn't available for subscription it won't have an ID yet
250
+ if (!$productHelper->isAvailableForSubscription($product, $quote->getStore())) {
251
+ return;
252
+ }
253
+
254
+ //Get quote item
255
+ $quoteItem = $quote->getItemByProduct($product);
256
+ if ($quoteItem == null || !strlen($quoteItem->getId())) {
257
+ // Not sure why this would ever happen, but just to be safe
258
+ // Return here in case the quote item hasn't been saved yet (*should* only happen if isn't enabled for subscription)
259
+ if (Mage::app()->getStore()->isAdmin() && !is_null($quoteItem)) {
260
+ return;
261
+ }
262
+ Mage::throwException($this->__('Cant find quote item which was added!'));
263
+ }
264
+
265
+ // Get subscription product profile
266
+ $platformProduct = $platformHelper->getPlatformProduct($product);
267
+
268
+ // Get new product qty from cart / quote
269
+ $quoteQty = $quoteItem->getQty();
270
+
271
+ // Apply default delivery option if none set
272
+ if (!strlen($deliveryOption)) {
273
+ if ($platformProduct->getData('subscription_option_mode') != 'subscription_only'
274
+ && $platformProduct->getData('default_subscription_option') == 'onetime_purchase'
275
+ ) {
276
+ $deliveryOption = 'one-time-delivery';
277
+ } else {
278
+ $deliveryOption = 'subscribe';
279
+ }
280
+ }
281
+
282
+ // Implement trial subscription functionality
283
+ if ($platformProduct->getData('is_trial_product')) {
284
+ // Force subscription delivery option
285
+ $deliveryOption = 'subscribe';
286
+ // Set trial price on quote item
287
+ $quoteItem->setCustomPrice($platformProduct->getData('trial_price'));
288
+ $quoteItem->setOriginalCustomPrice($platformProduct->getData('trial_price'));
289
+ }
290
+
291
+ // Only do error messages if added product is set for subscription
292
+ if ($deliveryOption == 'subscribe') {
293
+ // Check qty to max sure we're in min - max range for subscription
294
+ // Check the new quantity in the cart after addition
295
+ $removeItem = false;
296
+ if($quoteQty < $platformProduct->getData('min_qty')) {
297
+ $this->_getCheckoutSession()->addError(
298
+ $this->__('Item %s requires minimum quantity of %s for subscription.',
299
+ $product->getSku(),
300
+ $platformProduct->getData('min_qty')
301
+ ));
302
+ //If invalid qty and subscription only, remove the product
303
+ if ($platformProduct->getData('subscription_option_mode') == 'subscription_only') {
304
+ $removeItem = true;
305
+ }
306
+ }
307
+ if($quoteQty > $platformProduct->getData('max_qty')) {
308
+ $this->_getCheckoutSession()->addError(
309
+ $this->__('Item %s allows maximum quantity of %s for subscription.',
310
+ $product->getSku(),
311
+ $platformProduct->getData('max_qty')
312
+ ));
313
+ //If invalid qty and subscription only, remove the product
314
+ if ($platformProduct->getData('subscription_option_mode') == 'subscription_only') {
315
+ $removeItem = true;
316
+ }
317
+ }
318
+ //If we found a bug when adding the item (and it's admin) we have to remove it from cart
319
+ if ($removeItem) {
320
+ $product = $quoteItem->getProduct();
321
+ //We have to remove the item this way due to a bug in Magento
322
+ foreach($quote->getItemsCollection() as $key => $compItem) {
323
+ if ($compItem->getId() == $quoteItem->getId()) {
324
+ $quote->removeItem($key);
325
+ $quoteItem->delete();
326
+ break;
327
+ }
328
+ }
329
+ $quote->setTotalsCollectedFlag(false);
330
+ $quote->save();
331
+ if (!Mage::app()->getStore()->isAdmin()) {
332
+ Mage::app()->getResponse()->setRedirect($product->getProductUrl())->sendResponse();
333
+ exit;
334
+ }
335
+ return;
336
+ }
337
+ }
338
+
339
+ // Set data on quote item
340
+ // Only set subscription option on quote item if we are in we meet all conditions
341
+ if($quoteQty >= $platformProduct->getData('min_qty') && $quoteQty <= $platformProduct->getData('max_qty')) {
342
+ $quoteItem->setData('create_new_subscription_at_checkout', ($deliveryOption == 'subscribe'));
343
+ }
344
+ else {
345
+ $quoteItem->setData('create_new_subscription_at_checkout', false);
346
+ }
347
+ // Apply default interval if no interval set
348
+ if (!strlen($deliveryInterval)) {
349
+ $deliveryInterval = $platformProduct->getData('default_interval');
350
+ }
351
+ if (!strlen($deliveryInterval)) {
352
+ // If no default interval, go for the 1st one in the list
353
+ if (count($intervals = $platformProduct->getData('intervals'))) {
354
+ $deliveryInterval = $intervals[0];
355
+ }
356
+ }
357
+ // Set interval on quote item regardless
358
+ $quoteItem->setData('new_subscription_interval', $deliveryInterval);
359
+ // Save quote item
360
+ $quoteItem->save();
361
+ }
362
+
363
+ /**
364
+ * @param Mage_Checkout_Model_Cart $cart
365
+ * @param array $data
366
+ */
367
+ public function onCheckoutCartUpdateItemsAfter(Mage_Checkout_Model_Cart $cart, $data)
368
+ {
369
+ $this->updateQuoteItems($cart->getQuote(), $data);
370
+ }
371
+
372
+ /**
373
+ * Update the items in a quote based on the incoming date
374
+ * @param Mage_Sales_Model_Quote $quote
375
+ * @param $data
376
+ * @return $this
377
+ */
378
+ public function updateQuoteItems(Mage_Sales_Model_Quote $quote, $data)
379
+ {
380
+ // Get platform helper
381
+ /** @var SFC_Autoship_Helper_Platform $platformHelper */
382
+ $platformHelper = Mage::helper('autoship/platform');
383
+ /** @var SFC_Autoship_Helper_Product $productHelper */
384
+ $productHelper = Mage::helper('autoship/product');
385
+ /** @var SFC_Autoship_Helper_Api $apiHelper */
386
+ $apiHelper = Mage::helper('autoship/api');
387
+
388
+ $isAdmin = Mage::app()->getStore()->isAdmin();
389
+ $session = $this->_getCheckoutSession();
390
+
391
+ // Set store on api helper
392
+ $apiHelper->setConfigStore($quote->getStore());
393
+ // Iterate items in quote
394
+ /** @var Mage_Sales_Model_Quote_Item $quoteItem */
395
+ foreach ($quote->getAllVisibleItems() as $quoteItem) {
396
+ $hasError = false;
397
+ // Get corresponding data for this quote item
398
+ $itemDeliveryOption = isset($data[$quoteItem->getId()]['delivery-option']) ? $data[$quoteItem->getId()]['delivery-option'] : '';
399
+ $itemDeliveryInterval = isset($data[$quoteItem->getId()]['delivery-interval']) ? $data[$quoteItem->getId()]['delivery-interval'] : '';
400
+ // Get subscription product profile
401
+ $product = $this->getRelevantProductFromQuoteItem($quoteItem);
402
+ // Check if product is enabled for subscription
403
+ // Check product profile, if this isn't a subscription product, ignore it
404
+ if ($productHelper->isAvailableForSubscription($product, $quote->getStore())) {
405
+ // Get platform product
406
+ $platformProduct = $platformHelper->getPlatformProduct($product);
407
+ // Only do error messages if added product is set for subscription
408
+ if ($itemDeliveryOption == 'subscribe') {
409
+ // Check qty to max sure we're in min - max range for subscription
410
+ if($quoteItem->getQty() < $platformProduct->getData('min_qty')) {
411
+ $session->addError(
412
+ $this->__('Item %s requires minimum quantity of %s for subscription.',
413
+ $product->getSku(),
414
+ $platformProduct->getData('min_qty')
415
+ ));
416
+ $hasError = true;
417
+ }
418
+ if($quoteItem->getQty() > $platformProduct->getData('max_qty')) {
419
+ $session->addError(
420
+ $this->__('Item %s allows maximum quantity of %s for subscription.',
421
+ $product->getSku(),
422
+ $platformProduct->getData('max_qty')
423
+ ));
424
+ $hasError = true;
425
+ }
426
+ }
427
+
428
+ // Set data on quote item
429
+ // Only set subscription option on quote item if we are in we meet all conditions
430
+ if($quoteItem->getQty() >= $platformProduct->getData('min_qty') && $quoteItem->getQty() <= $platformProduct->getData('max_qty')) {
431
+ $quoteItem->setData('create_new_subscription_at_checkout', ($itemDeliveryOption == 'subscribe'));
432
+ }
433
+ else if ($platformProduct->getData('subscription_option_mode') != 'subscription_only') {
434
+ $quoteItem->setData('create_new_subscription_at_checkout', false);
435
+ }
436
+ $quoteItem->setData('new_subscription_interval', $itemDeliveryInterval);
437
+ /*
438
+ * We have to save the admin item if there is no error for the below situation:
439
+ * 1 item has an error and 1 does not
440
+ * Without saving the one that does not, all items will revert to "no subscription"
441
+ */
442
+ if ($isAdmin) {
443
+ if ($hasError && $quoteItem->getOrigData('create_new_subscription_at_checkout')
444
+ && $platformProduct->getData('subscription_option_mode') == 'subscription_only'
445
+ ) {
446
+ //If this product can only be subscription, and an invalid qty was requested, revert the quantity
447
+ $quoteItem->setQty($quoteItem->getOrigData('qty'));
448
+ $buyRequest = $quoteItem->getBuyRequest();
449
+ $buyRequest->setData('qty', $quoteItem->getOrigData('qty'));
450
+ $optionValue = @serialize($buyRequest->getData());
451
+ $quoteItem->getOptionByCode('info_buyRequest')->setData('value', $optionValue)->save();
452
+ $quoteItem->save();
453
+ } else if (!$hasError) {
454
+ //Otherwise if there's no error make an update
455
+ $quoteItem->save();
456
+ }
457
+ }
458
+ // if (!$hasError && $isAdmin) {
459
+ // $quoteItem->save();
460
+ // }
461
+ }
462
+ }
463
+ return $this;
464
+ }
465
+
466
+ /**
467
+ * @param Mage_Sales_Model_Quote_Item $quoteItem
468
+ * @param Mage_Sales_Model_Order_Item $orderItem
469
+ */
470
+ public function onSalesConvertQuoteItemToOrderItem(Mage_Sales_Model_Quote_Item $quoteItem, Mage_Sales_Model_Order_Item $orderItem)
471
+ {
472
+ // Map additional options from quote item (from the buy request) to order item
473
+ // TODO: It would be ideal if we can get the additional_options from buy request into additional_options option field in
474
+ // the quote item at time quote item is created
475
+ $buyRequest = unserialize($quoteItem->getOptionByCode('info_buyRequest')->getValue());
476
+ if (isset($buyRequest['additional_options']) && count($buyRequest['additional_options'])) {
477
+ $additionalOptions = $buyRequest['additional_options'];
478
+ $options = $orderItem->getProductOptions();
479
+ $options['additional_options'] = $additionalOptions;
480
+ $orderItem->setProductOptions($options);
481
+ }
482
+ // Set fields / attributes from quote on to order item
483
+ $orderItem->setData('item_fulfils_subscription', $quoteItem->getData('item_fulfils_subscription'));
484
+ $orderItem->setData('subscription_id', $quoteItem->getData('subscription_id'));
485
+ $orderItem->setData('subscription_interval', $quoteItem->getData('subscription_interval'));
486
+ // If this item fulfils a subscription, update additional_information
487
+ if($quoteItem->getData('item_fulfils_subscription')) {
488
+ $this->addAdditionalOptionsToOrderItem($orderItem);
489
+ }
490
+ }
491
+
492
+ /**
493
+ * @param Mage_Sales_Model_Order $order
494
+ * @param Mage_Sales_Model_Quote $quote
495
+ */
496
+ public function onSalesConvertOrderToQuote(Mage_Sales_Model_Order $order, Mage_Sales_Model_Quote $quote)
497
+ {
498
+ // Check for subscribe pro vault pay method
499
+ if (0 === strpos($order->getPayment()->getMethod(), SFC_Autoship_Helper_Platform::PAY_METHOD_CODE_SUBSCRIBE_PRO_VAULT)) {
500
+ // Quote was using SP vault pay method
501
+ // Reset payment data fields on order
502
+ $quote->getPayment()->setData('cc_type', '');
503
+ $quote->getPayment()->setData('cc_number', '');
504
+ $quote->getPayment()->setData('cc_exp_month', '');
505
+ $quote->getPayment()->setData('cc_exp_year', '');
506
+ $quote->getPayment()->setAdditionalInformation('save_card', '');
507
+ $quote->getPayment()->setAdditionalInformation('is_new_card', '');
508
+ $quote->getPayment()->setAdditionalInformation('payment_token', '');
509
+ $quote->getPayment()->setAdditionalInformation('obscured_cc_number', '');
510
+ }
511
+ }
512
+
513
+ /**
514
+ * @param Mage_Sales_Model_Quote $quote
515
+ * @return array
516
+ */
517
+ public function onCheckoutSubmitAllAfter(Mage_Sales_Model_Quote $quote)
518
+ {
519
+ // Create subscriptions
520
+ $createdSubscriptions = $this->createSubscriptionsFromQuote($quote);
521
+ // Check result
522
+ if(count($createdSubscriptions)) {
523
+ // At least 1 subscription was created, set flag to display message on thank you page
524
+ Mage::getSingleton('checkout/session')->setData('created_subscription_ids', array_keys($createdSubscriptions));
525
+ }
526
+ }
527
+
528
+ /**
529
+ * @param Mage_Sales_Model_Quote $quote
530
+ * @return array
531
+ */
532
+ protected function createSubscriptionsFromQuote(Mage_Sales_Model_Quote $quote)
533
+ {
534
+ /** @var SFC_Autoship_Helper_Product $productHelper */
535
+ $productHelper = Mage::helper('autoship/product');
536
+ /** @var SFC_Autoship_Helper_Api $apiHelper */
537
+ $apiHelper = Mage::helper('autoship/api');
538
+
539
+ // Set store on api helper
540
+ $apiHelper->setConfigStore($quote->getStore());
541
+
542
+ // Keep track of subscriptions created
543
+ $subscriptions = array();
544
+ // Maintain failed subscription count in session
545
+ Mage::getSingleton('checkout/session')->setData('failed_subscription_count', 0);
546
+ // Iterate shipping addresses
547
+ /** @var Mage_Sales_Model_Quote_Address $curAddress */
548
+ foreach ($quote->getAllShippingAddresses() as $curAddress) {
549
+ // Iterate items in address
550
+ /** @var Mage_Sales_Model_Quote_Item $quoteItem */
551
+ foreach ($curAddress->getAllItems() as $quoteItem) {
552
+ // Get subscription product profile
553
+ $product = $this->getRelevantProductFromQuoteItem($quoteItem);
554
+ // Check if product is enabled for subscription
555
+ // Check product profile, if this isn't a subscription product, ignore it
556
+ if ($productHelper->isAvailableForSubscription($product, $quote->getStore())) {
557
+ // Check quote item flag which indicates we should create a new subscription for this product
558
+ if ($quoteItem->getData('create_new_subscription_at_checkout')) {
559
+ $subscription = $this->createSubscriptionAndUpdateQuoteItem($quoteItem, $curAddress);
560
+ $subscriptions[] = $subscription;
561
+ }
562
+ }
563
+ }
564
+ }
565
+ // Now iterate virtual products
566
+ // Iterate items
567
+ /** @var Mage_Sales_Model_Quote_Item $quoteItem */
568
+ foreach ($quote->getAllItems() as $quoteItem) {
569
+ if ($quoteItem->getProductType() == Mage_Catalog_Model_Product_Type::TYPE_VIRTUAL || $quoteItem->getProductType() == Mage_Downloadable_Model_Product_Type::TYPE_DOWNLOADABLE) {
570
+ // Get subscription product profile
571
+ $product = $this->getRelevantProductFromQuoteItem($quoteItem);
572
+ // Check if product is enabled for subscription
573
+ // Check product profile, if this isn't a subscription product, ignore it
574
+ if ($productHelper->isAvailableForSubscription($product, $quote->getStore())) {
575
+ // Check quote item flag which indicates we should create a new subscription for this product
576
+ if ($quoteItem->getData('create_new_subscription_at_checkout')) {
577
+ // For virtual products, set billing address as shipping address
578
+ $subscription = $this->createSubscriptionAndUpdateQuoteItem($quoteItem, $quote->getBillingAddress());
579
+ $subscriptions[] = $subscription;
580
+ }
581
+ }
582
+ }
583
+ }
584
+
585
+ // Return array of created subs
586
+ return $subscriptions;
587
+ }
588
+
589
+ private function createSubscriptionAndUpdateQuoteItem(Mage_Sales_Model_Quote_Item $quoteItem, Mage_Sales_Model_Quote_Address $shippingAddress)
590
+ {
591
+ // Get platform helper
592
+ /** @var SFC_Autoship_Helper_Platform $platformHelper */
593
+ $platformHelper = Mage::helper('autoship/platform');
594
+ try {
595
+ // Create subscription from this item
596
+ $subscription =
597
+ $this->createSubscriptionFromQuoteItem($quoteItem, $shippingAddress, $quoteItem->getData('new_subscription_interval'));
598
+
599
+ Mage::dispatchEvent('sfc_autoship_before_create_subscription_from_quote_item',
600
+ array('subscription' => $subscription, 'quote_item' => $quoteItem));
601
+
602
+ // Create subscription via API
603
+ $subscriptionId = $platformHelper->createSubscription($subscription);
604
+ // Save in array
605
+ $subscriptions[$subscriptionId] = $subscription;
606
+ // Save subscription id and flag on quote item
607
+ $quoteItem->setData('subscription_id', $subscriptionId);
608
+ $quoteItem->setData('subscription_interval', $subscription->getData('interval'));
609
+ $quoteItem->setData('item_fulfils_subscription', true);
610
+ $quoteItem->save();
611
+ // Lookup order item
612
+ /** @var Mage_Sales_Model_Order_Item $orderItem */
613
+ $orderItem = Mage::getModel('sales/order_item')->load($quoteItem->getId(), 'quote_item_id');
614
+ // Save subscription id and flag on order item
615
+ if(strlen($orderItem->getId())) {
616
+ $orderItem->setData('subscription_id', $subscriptionId);
617
+ $orderItem->setData('subscription_interval', $subscription->getData('interval'));
618
+ $orderItem->setData('item_fulfils_subscription', true);
619
+ $this->addAdditionalOptionsToOrderItem($orderItem);
620
+ $orderItem->save();
621
+ }
622
+
623
+ Mage::dispatchEvent('sfc_autoship_after_create_subscription_from_quote_item',
624
+ array('subscription' => $subscription, 'quote_item' => $quoteItem));
625
+
626
+ return $subscription;
627
+ }
628
+ catch(\Exception $e) {
629
+ // Increment failed subscription count
630
+ Mage::getSingleton('checkout/session')->setData(
631
+ 'failed_subscription_count',
632
+ 1 + Mage::getSingleton('checkout/session')->getData('failed_subscription_count')
633
+ );
634
+ }
635
+ }
636
+
637
+ /**
638
+ * @param Mage_Sales_Model_Quote_Item $quoteItem
639
+ * @param Mage_Sales_Model_Quote_Address $shippingAddress
640
+ * @param string $interval
641
+ * @return SFC_Autoship_Model_Subscription
642
+ */
643
+ protected function createSubscriptionFromQuoteItem(Mage_Sales_Model_Quote_Item $quoteItem, Mage_Sales_Model_Quote_Address $shippingAddress, $interval)
644
+ {
645
+ // Get quote
646
+ $quote = $quoteItem->getQuote();
647
+ // Get customer
648
+ $customer = $quote->getCustomer();
649
+
650
+ // Create default subscription
651
+ /** @var SFC_Autoship_Model_Subscription $subscription */
652
+ $subscription = Mage::getModel('autoship/subscription');
653
+ $subscription->setData('next_order_date', date('Y-m-d'));
654
+ $product = $this->getRelevantProductFromQuoteItem($quoteItem);
655
+ $subscription->setData('product_id', $product->getId());
656
+ $subscription->setData('customer_id', $customer->getId());
657
+ $subscription->setData('billing_address_id', $quote->getBillingAddress()->getCustomerAddressId());
658
+ $subscription->setData('billing_first_name', $quote->getBillingAddress()->getFirstname());
659
+ $subscription->setData('billing_last_name', $quote->getBillingAddress()->getLastname());
660
+ $subscription->setData('magento_store_code', $quote->getStore()->getCode());
661
+ // Workaround for Magento issue with Registering during checkout
662
+ // UGH Magento!
663
+ if(strlen($shippingAddress->getCustomerAddressId())) {
664
+ $subscription->setData('shipping_address_id', $shippingAddress->getCustomerAddressId());
665
+ }
666
+ else {
667
+ $subscription->setData('shipping_address_id', $quote->getBillingAddress()->getCustomerAddressId());
668
+ }
669
+ $subscription->setData('shipping_method', $shippingAddress->getData('shipping_method'));
670
+ $subscription->setData('qty', $quoteItem->getQty());
671
+ $subscription->setData('interval', $interval);
672
+ // Set skip first order flag, since we just placed an order for today
673
+ $subscription->setData('skip_first_order', true);
674
+ // Save coupon code on subscription, if config setting enabled
675
+ if(Mage::getStoreConfig('autoship_subscription/options/allow_coupon', $quote->getStore()) == 1) {
676
+ $subscription->setData('coupon_code', $quote->getCouponCode());
677
+ }
678
+
679
+ // Handle product options, save them to subscription
680
+ $this->addProductOptionsToSubscription($subscription, $quoteItem);
681
+
682
+ // Set payment details on subscription based on quote / order
683
+ $this->addPaymentInfoToSubscription($subscription, $quoteItem);
684
+
685
+ // Return the new subscription model
686
+ return $subscription;
687
+ }
688
+
689
+ protected function addProductOptionsToSubscription(SFC_Autoship_Model_Subscription $subscription, Mage_Sales_Model_Quote_Item $quoteItem)
690
+ {
691
+ // Create array to hold product options and then be stored in subscription
692
+ $productOptions = array();
693
+ // Get buy request object
694
+ $buyRequest = $quoteItem->getBuyRequest();
695
+ // If this is a bundle product
696
+ if ($quoteItem->getProductType() == Mage_Catalog_Model_Product_Type::TYPE_BUNDLE) {
697
+ // Get bundle options from buy request
698
+ $bundleOption = $buyRequest->getData('bundle_option');
699
+ $bundleOptionQty = $buyRequest->getData('bundle_option_qty');
700
+ if (is_array($bundleOption) && count($bundleOption)) {
701
+ // Save bundle options with subscription
702
+ $productOptions['bundle_option'] = $bundleOption;
703
+ $productOptions['bundle_option_qty'] = $bundleOptionQty;
704
+ }
705
+ }
706
+ // Save custom options
707
+ $customOptions = $buyRequest->getData('options');
708
+ if (is_array($customOptions) && count($customOptions)) {
709
+ $productOptions['options'] = $customOptions;
710
+ }
711
+ // Store all options with subscription
712
+ $subscription->setData('magento_product_options', $productOptions);
713
+ }
714
+
715
+ protected function addPaymentInfoToSubscription(SFC_Autoship_Model_Subscription $subscription, Mage_Sales_Model_Quote_Item $quoteItem)
716
+ {
717
+ // Get quote
718
+ $quote = $quoteItem->getQuote();
719
+ // Get payment info
720
+ $payment = $quote->getPayment();
721
+
722
+ // Get helper
723
+ /** @var SFC_Autoship_Helper_Platform $platformHelper */
724
+ $platformHelper = Mage::helper('autoship/platform');
725
+ // Lookup payment method code based on SP config
726
+ $configuredMethodCode = $platformHelper->getConfiguredPaymentMethodCode();
727
+
728
+ // Assert that quote / order was placed using compatible payment method
729
+ if(0 !== strpos($payment->getMethod(), $configuredMethodCode)) {
730
+ Mage::throwException($this->__('Cannot create subscription(s) unless compatible payment method is selected!'));
731
+ }
732
+
733
+ // Set method code / gateway on sub
734
+ $subscription->setData('payment_method_code', $configuredMethodCode);
735
+
736
+ // Check payment method code / type
737
+ switch ($configuredMethodCode) {
738
+
739
+ case SFC_Autoship_Helper_Platform::PAY_METHOD_CODE_SFC_CIM_10XX:
740
+ case SFC_Autoship_Helper_Platform::PAY_METHOD_CODE_SFC_CIM:
741
+ // Check that quote payment has payment_profile_id, otherwise get order payment
742
+ if(!strlen($payment->getAdditionalInformation('payment_profile_id'))) {
743
+ // Lookup order corresponding to quote
744
+ $order = Mage::getModel('sales/order')->getCollection()
745
+ ->addFieldToFilter('quote_id', $quote->getId())
746
+ ->getFirstItem();
747
+ if(strlen($order->getId())) {
748
+ $payment = $order->getPayment();
749
+ }
750
+ }
751
+ // Set data on subscription
752
+ $subscription->setData('payment_token', $payment->getAdditionalInformation('payment_profile_id'));
753
+ $subscription->setData('customer_cardnumber', $payment->getAdditionalInformation('saved_cc_last_4'));
754
+ return;
755
+
756
+ case SFC_Autoship_Helper_Platform::PAY_METHOD_CODE_SUBSCRIBE_PRO_VAULT:
757
+ // Set data on subscription, just the payment token is enough for the SP platform to lookup the customer's payment profile
758
+ $subscription->setData('payment_token', $payment->getAdditionalInformation('payment_token'));
759
+ return;
760
+
761
+ case SFC_Autoship_Helper_Platform::PAY_METHOD_CODE_SFC_CYBERSOURCE:
762
+ // Check that quote payment has payment_profile_id, otherwise get order payment
763
+ if(!strlen($payment->getAdditionalInformation('payment_token'))) {
764
+ // Lookup order corresponding to quote
765
+ $order = Mage::getModel('sales/order')->getCollection()
766
+ ->addFieldToFilter('quote_id', $quote->getId())
767
+ ->getFirstItem();
768
+ if(strlen($order->getId())) {
769
+ $payment = $order->getPayment();
770
+ }
771
+ }
772
+ // Set data on subscription
773
+ $subscription->setData('payment_token', $payment->getAdditionalInformation('payment_token'));
774
+ $subscription->setData('customer_cardnumber', $payment->getData('cc_last4'));
775
+ return;
776
+
777
+ case SFC_Autoship_Helper_Platform::PAY_METHOD_CODE_BRAINTREE:
778
+ return;
779
+
780
+ case SFC_Autoship_Helper_Platform::PAY_METHOD_CODE_PARADOX_TRANSARMOR:
781
+ // Lookup order corresponding to quote
782
+ /** @var Mage_Sales_Model_Order $order */
783
+ $order = Mage::getModel('sales/order')->getCollection()
784
+ ->addFieldToFilter('quote_id', $quote->getId())
785
+ ->getFirstItem();
786
+ if(!strlen($order->getId())) {
787
+ Mage::throwException($this->__('Failed to find order corresponding to quote to create subscriptions for TransArmor quote!'));
788
+ }
789
+ /** @var Mage_Sales_Model_Order_Payment $payment */
790
+ $payment = $order->getPayment();
791
+ // Set data on subscription
792
+ $subscription->setData('payment_token', $payment->getAdditionalInformation('token'));
793
+ $subscription->setData('customer_cardnumber', $payment->getData('cc_last4'));
794
+ return;
795
+
796
+ }
797
+
798
+ }
799
+
800
+ }
app/code/local/SFC/Autoship/Helper/Schedule.php CHANGED
@@ -1,4 +1,4 @@
1
- <?php //00612
2
  /**
3
  * Subscribe Pro - Subscriptions Management Extension
4
  *
@@ -15,34 +15,67 @@
15
  *
16
  */
17
 
18
- if(!extension_loaded('ionCube Loader')){$__oc=strtolower(substr(php_uname(),0,3));$__ln='/ioncube/ioncube_loader_'.$__oc.'_'.substr(phpversion(),0,3).(($__oc=='win')?'.dll':'.so');$__oid=$__id=realpath(ini_get('extension_dir'));$__here=dirname(__FILE__);if((@$__id[1])==':'){$__id=str_replace('\\','/',substr($__id,2));$__here=str_replace('\\','/',substr($__here,2));}$__rd=str_repeat('/..',substr_count($__id,'/')).$__here.'/';$__i=strlen($__rd);while($__i--){if($__rd[$__i]=='/'){$__lp=substr($__rd,0,$__i).$__ln;if(file_exists($__oid.$__lp)){$__ln=$__lp;break;}}}@dl($__ln);}else{die('The file '.__FILE__." is corrupted. Ensure that you use binary mode when transferring files with FTP and disable the 'TAR smart cr/lf feature' if using WinZIP\n");}if(function_exists('_il_exec')){return _il_exec();}die('The file <b>'.__FILE__.'</b> has been encoded with the <a href="http://www.ioncube.com">ionCube PHP Encoder</a> and requires the free '.basename($__ln).' <a href="http://www.ioncube.com/loader_download/">ionCube PHP Loader</a> to be installed.');
19
-
20
- ?>
21
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- B7sexe2LYKBGpGCLNWNLXJdwVJR3uPU7BNRhSkyuNcGd/JRXjvUJ7BWbdMQE+OuGYBkELSO9qvgZ
35
- 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
- i81RIBveE3tF9GR2fhpzb6YHtrAKalZdon4vBUrVHZhg23GNtGzQhnPki3WGEUomYGR41dxAOe5R
37
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
48
- NMpnL3vG4v8UZ5YniGSs9BMwjT1uHte=
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
  /**
3
  * Subscribe Pro - Subscriptions Management Extension
4
  *
15
  *
16
  */
17
 
18
+ class SFC_Autoship_Helper_Schedule extends Mage_Core_Helper_Abstract
19
+ {
20
+ /*
21
+ * Get current system time (expected to be in UTC)
22
+ *
23
+ * @return DateTime Returns current sys time as TimeDate object
24
+ */
25
+ public function getCurrentDateTime()
26
+ {
27
+ // Lookup configured timezone
28
+ $timezone = Mage::getStoreConfig('general/locale/timezone');
29
+ // Get current time
30
+ $curDateTime = new DateTime('now');
31
+
32
+ // Return
33
+ return $curDateTime;
34
+ }
35
+
36
+ /*
37
+ * Get current system time(expected to be in UTC)
38
+ *
39
+ * @return string Returns current sys time as string
40
+ */
41
+ public function getCurrentTime()
42
+ {
43
+ // Get current DateTime obj
44
+ $curDateTime = $this->getCurrentDateTime();
45
+
46
+ // Return current time formatted nicely as string
47
+ return $curDateTime->format('H:i:s');
48
+ }
49
+
50
+ /*
51
+ * Get current system time (considering Magento time zone config setting)
52
+ *
53
+ * @return DateTime Returns current sys time as TimeDate object
54
+ */
55
+ public function getCurrentDateTimeUsingTimezone()
56
+ {
57
+ // Lookup configured timezone
58
+ $timezone = Mage::getStoreConfig('general/locale/timezone');
59
+ // Get current time
60
+ $curDateTime = new DateTime('now', new DateTimeZone($timezone));
61
+
62
+ // Return
63
+ return $curDateTime;
64
+ }
65
+
66
+ /*
67
+ * Get current system time (considering Magento time zone config setting)
68
+ *
69
+ * @return string Returns current sys time as string
70
+ */
71
+ public function getCurrentTimeUsingTimezone()
72
+ {
73
+ // Get current DateTime obj
74
+ $curDateTime = $this->getCurrentDateTimeUsingTimezone();
75
+
76
+ // Return current time formatted nicely as string
77
+ return $curDateTime->format('H:i:s');
78
+ }
79
+
80
+ }
81
+
app/code/local/SFC/Autoship/Helper/Subscription.php CHANGED
@@ -1,4 +1,4 @@
1
- <?php //00612
2
  /**
3
  * Subscribe Pro - Subscriptions Management Extension
4
  *
@@ -15,201 +15,491 @@
15
  *
16
  */
17
 
18
- if(!extension_loaded('ionCube Loader')){$__oc=strtolower(substr(php_uname(),0,3));$__ln='/ioncube/ioncube_loader_'.$__oc.'_'.substr(phpversion(),0,3).(($__oc=='win')?'.dll':'.so');$__oid=$__id=realpath(ini_get('extension_dir'));$__here=dirname(__FILE__);if((@$__id[1])==':'){$__id=str_replace('\\','/',substr($__id,2));$__here=str_replace('\\','/',substr($__here,2));}$__rd=str_repeat('/..',substr_count($__id,'/')).$__here.'/';$__i=strlen($__rd);while($__i--){if($__rd[$__i]=='/'){$__lp=substr($__rd,0,$__i).$__ln;if(file_exists($__oid.$__lp)){$__ln=$__lp;break;}}}@dl($__ln);}else{die('The file '.__FILE__." is corrupted. Ensure that you use binary mode when transferring files with FTP and disable the 'TAR smart cr/lf feature' if using WinZIP\n");}if(function_exists('_il_exec')){return _il_exec();}die('The file <b>'.__FILE__.'</b> has been encoded with the <a href="http://www.ioncube.com">ionCube PHP Encoder</a> and requires the free '.basename($__ln).' <a href="http://www.ioncube.com/loader_download/">ionCube PHP Loader</a> to be installed.');
19
-
20
- ?>
21
- HR+cPseEwO9Qlz6r9+DyeMAIMgm0+K7xLqVdcvEym5UsHKhOhktJVKwG0Ftuq3Q4XANwOmzljTgV
22
- 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
- 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
- 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
- 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
- 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
- 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
- SU1cT/0ji8O+w3Gzoy61oliDFrCPsKc6hc559gyWLh3TDkwzmySbb6B3mXQqpyZFy0FVbL/yqvPa
29
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- dSI1+wtFNB6JHY1aiC4e0GhGT5sOo703I1B4lpKpNEziAr+KxoNOo/tAKfRqp0BPMyOSnmoNsMO8
42
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- q/dRrdxIg9Er5xXYbySuWrPtvfEdNix4fz4B1+ipOXkpOIhvd+C4PNO/FbY1tJVNeVtXHaniTmBp
51
- hM/oWcTIi0K4ME3/BiAQLM92/t1V6A6hqqHWh2lhgzmrpcJPpVG5MFMy22NWxAIEnqxoDAk7U2UY
52
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 5XvcmxHbOD6QkKdFYQLhD+s2jhBJTIO1fS5P9sLIh9zU9/YP1dEEbXc6casTJwyEeMG9b0Dhq9Wd
66
- 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
- IKidOF8QHP6hJ5AQJDWnUbf5n78GLBjetywASpI6ohxqTZb5HOZTPyWCD8QOpCs35ll13EhRl3f1
68
- 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
- 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
- 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
- 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
- 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
- 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
- +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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- eAi2VShQRerkWUZiZItqOsipvo42KtZsDHAgs7+54IVGHlbhbpAE/DedlN4B7TPj38Rm3cjISa/9
91
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- ee6pYtQldQbraWgP6vq9zZ1Ek/LPcYLLzpKBS7e6bLTg64RD7aJ3MsaEX1QPWs4QC+yFZrDkK5NC
114
- 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
- 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
- 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
- +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
- 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
- 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
- ztQhPub1AItUkz3aiR7ZjxFaPUIOSu2l72sEu0CxQ1W5zT+y5eXcas0OApcfUwDCrCH6wRpD4ZQk
121
- 9QjzHFcWU20cOJjjmsGW/pcuIDCGvZK+s98eWxbbxGmrdD4c1Ke6z9s92c2pTxTJGjHpTS5G1TcR
122
- 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
- 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
- WHwnbgZwQlHRNiCNkp/3fj80RYQz2fUJ41MVFfLw81riEofSyL/j/0eD8plbRxakI1rpMQE6eRcu
125
- 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
- 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
- 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
- 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
- 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
- HBu6b+IWpekGSQrcgTitaJKAfaweADuuC3yQ8u6GPIvzUjMnrVoKPx8TPOQ7lKouLS24I2vOw2jh
131
- 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
- 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
- OaPci18PKTZLbLxzEFBRv9zHwfeYELXI4dni6eb+aOPhQ1wrTKeSkR0ACYxy90hLMU8EaL94GuIz
134
- +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
- 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
- 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
- pb7MRRBuQKp/7P6k4S4ZSxMQumYv6nzWVmUUMNNnhpRHVpKEQuxtIDyNOUpuVj0MIh27FXk69J7x
138
- 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
- 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
- 3jZE1BgoY4cEdJGmqENjmvV4z+in1Q2WSbSsqFHaEFcQXuKq8NOt+GiJ17U/UxE88wSveOsVInp3
141
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- ebkZ9sJBZjjFfoCzABh+PWJd8GY30AE4Pevdmyj0QakTmW4ayUWWM61a0xPdaw2BZ/f90TXNbrC5
158
- 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
- Ct9dWNP6+kmKiRVbqyijU3jNEUDMmLqaHsPNzl3mTUYDUFjpdZ6tMwVO6OZONsv7lvvUPJqZjvth
160
- J6BkrvMVMzHP3uwHMyfvmwoXMZlAMWINnGbRooL/EWMkga5HB/DMQsK/vV0gNpMqIh27X8lV0om0
161
- 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
- 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
- 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
- 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
- +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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- o2Wv1RWzhCtDJYAS7JRfqIFn4NmYLlFxjLVN4OhOIJA2ZvftYDx+Jl6aUTUgnyfZnJii8oPPw+pt
176
- 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
- ZVSsKcRxqFGiBM2MlgiQ2dGLuo1oXwvicVgon5v3FHhvIwbhxv2AFu5yw5tXNB4fJYC0Z/X7Gxjz
178
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 7tZvI67amcZldRL6zSgjW3q/o3D6ESGcdjtiBHywVDzLrqdXMBAhLByu/v7/E0cKr4/1RUm/Ryf7
191
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- nnyjeCDUPS3qRYL8ZSQXZ01ds0qLT7kHGzJqMUjNADQRR/4/N2sLWOCrQNy31mouVp2tJ6X5ungA
199
- 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
- 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
- O9+4vKya3AJeJPfpTxReKtDG7UVqEp+8naAiVOlschzj0tJWb7wX6XWFqtVmtbHINC3ince0jRUB
202
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- +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
- 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
- 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
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
  /**
3
  * Subscribe Pro - Subscriptions Management Extension
4
  *
15
  *
16
  */
17
 
18
+ /**
19
+ * Helper class to assist with displaying and formatting subscription
20
+ */
21
+ class SFC_Autoship_Helper_Subscription extends Mage_Core_Helper_Abstract
22
+ {
23
+
24
+ /**
25
+ * Return the price for purchasing the product as a one time purchase, optionally format the returned price
26
+ *
27
+ * @param Mage_Catalog_Model_Product $product Mage product object
28
+ * @param int $qty Product quantity for order, goes into catalog price calculation
29
+ * @param bool $formatted True to return the price formatted, false to return the raw price number
30
+ * @param null $inclTax
31
+ * @return string Price of product, either formatted or as a raw number
32
+ * @internal param bool $factorTax
33
+ */
34
+ public function getOneTimePurchasePrice(Mage_Catalog_Model_Product $product, $qty = 1, $formatted = false, $inclTax = null)
35
+ {
36
+ // Set customer group and store on product
37
+ $product->setStoreId(Mage::app()->getStore()->getId());
38
+ $product->setCustomerGroupId(Mage::getSingleton('customer/session')->getCustomer()->getGroupId());
39
+ // Lookup price - Get catalog rule / special price / tier pricing / etc calculation
40
+ $finalPrice = $product->getFinalPrice($qty);
41
+ // If the product isn't discounted then default back to the original price
42
+ if ($finalPrice===false) {
43
+ $finalPrice = $product->getPrice();
44
+ }
45
+ if (is_null($inclTax)) {
46
+ $inclTax = Mage::helper("tax")->displayPriceIncludingTax();
47
+ }
48
+ /**
49
+ * Get the final price based on whether or not we've included tax
50
+ */
51
+ $finalPrice = $inclTax ? $this->getProductPriceInclTax($product, $finalPrice) : $this->getProductPriceExclTax($product, $finalPrice);
52
+ // Format price if requested
53
+ if ($formatted) {
54
+ $finalPrice = Mage::helper('core')->currency($finalPrice, true, false);
55
+ }
56
+
57
+ // Return price
58
+ return $finalPrice;
59
+ }
60
+
61
+ protected function isProductDiscountedInCatalog(Mage_Catalog_Model_Product $product, $qty = 1)
62
+ {
63
+ // Lookup final price
64
+ $finalPrice = $this->getOneTimePurchasePrice($product, $qty);
65
+ //Adjust the normal price for tax settings
66
+ $productPrice = $this->adjustProductPriceForTax($product, $product->getPrice());
67
+
68
+ // Check if product discounted
69
+ $isProductDiscounted = ($finalPrice != $productPrice);
70
+
71
+ return $isProductDiscounted;
72
+ }
73
+
74
+ /**
75
+ * Return the price for purchasing the product with a subscription, optionally format the returned price
76
+ *
77
+ * @param SFC_Autoship_Model_Platform_Product $platformProduct Subscription profile for product
78
+ * @param Mage_Catalog_Model_Product $product Mage product object
79
+ * @param int $qty Product quantity for order, goes into catalog price calculation
80
+ * @param bool $formatted True to return the price formatted, false to return the raw price number
81
+ * @return string Price of product, either formatted or as a raw number
82
+ */
83
+ public function getSubscriptionPrice(SFC_Autoship_Model_Platform_Product $platformProduct, Mage_Catalog_Model_Product $product,
84
+ $qty = 1, $formatted = false)
85
+ {
86
+ // Trial product info
87
+ $isTrialProduct = $platformProduct->getData('is_trial_product');
88
+ $trialPrice = $platformProduct->getData('trial_price');
89
+ // Lookup discount % / amount
90
+ $discount = $platformProduct->getDiscount();
91
+ $isDiscountPercentage = $platformProduct->getData('is_discount_percentage');
92
+ // Lookup final price
93
+ $finalPrice = $this->getOneTimePurchasePrice($product, $qty);
94
+ // Get config settings
95
+ // Don't need $store param to getStoreConfig. This method only called from frontend where store already set.
96
+ $applyDiscountToCatalogPrice = Mage::getStoreConfig('autoship_subscription/discount/apply_discount_to_catalog_price');
97
+
98
+ // Check for trial product
99
+ if ($isTrialProduct) {
100
+ // Set trial price as subscription price
101
+ $subscriptionPrice = $trialPrice;
102
+ }
103
+ else {
104
+ // Calculate discount using all biz logic
105
+ if ($discount > 0.0) {
106
+ if (!$applyDiscountToCatalogPrice && $this->isProductDiscountedInCatalog($product, $qty)) {
107
+ // Don't apply any subscription discount, because config is turned off and product already has discount
108
+ $subscriptionPrice = $finalPrice;
109
+ }
110
+ else {
111
+ if ($isDiscountPercentage) {
112
+ /**
113
+ * In the case of a percentage discount, we need to apply a discount to only the portion of the product price
114
+ * that is "discountable"
115
+ */
116
+ $subscriptionPrice = $finalPrice - ($this->getDiscountableProductPrice($product, $qty) * $discount);
117
+ }
118
+ else {
119
+ $subscriptionPrice = $finalPrice - $discount;
120
+ }
121
+ }
122
+ }
123
+ else {
124
+ $subscriptionPrice = $finalPrice;
125
+ }
126
+ }
127
+
128
+ // Format price if requested
129
+ if ($formatted) {
130
+ $subscriptionPrice = Mage::helper('core')->currency($subscriptionPrice, true, false);
131
+ }
132
+
133
+ // Return price
134
+ return $subscriptionPrice;
135
+ }
136
+
137
+ /**
138
+ * Return the price for purchasing the product with a subscription, formatted and with text indicating the discount amount
139
+ *
140
+ * @param SFC_Autoship_Model_Platform_Product $platformProduct Subscription profile for product
141
+ * @param Mage_Catalog_Model_Product $product Mage product object
142
+ * @return string Price of product, formatted and with text indicating the discount
143
+ */
144
+ public function getSubscriptionPriceText(SFC_Autoship_Model_Platform_Product $platformProduct, Mage_Catalog_Model_Product $product, $qty = 1)
145
+ {
146
+ // Lookup config setting
147
+ // Trial product info
148
+ $isTrialProduct = $platformProduct->getData('is_trial_product');
149
+ // Don't need $store param to getStoreConfig. This method only called from frontend where store already set.
150
+ $applyDiscountToCatalogPrice = Mage::getStoreConfig('autoship_subscription/discount/apply_discount_to_catalog_price');
151
+ // Lookup discount % / amount
152
+ $discount = $platformProduct->getDiscount();
153
+ $isDiscountPercentage = $platformProduct->getData('is_discount_percentage');
154
+ // Lookup price, including discount using method from SFC_Autoship_Block_Product_View
155
+ $priceFormatted = $this->getSubscriptionPrice($platformProduct, $product, $qty, true);
156
+ //Start an array to keep track of variables which can be used in translation code
157
+ $translateVars = array($priceFormatted);
158
+ // Build output text
159
+ $priceText = '%s';
160
+ // Add discount text
161
+ if ($isTrialProduct) {
162
+ $priceText .= ' trial price.';
163
+ }
164
+ else {
165
+ if ($discount > 0.0 && ($applyDiscountToCatalogPrice || !$this->isProductDiscountedInCatalog($product, $qty))) {
166
+ if ($isDiscountPercentage) {
167
+ $translateVars[] = 100.0 * $discount;
168
+ //%% = literal '%' character
169
+ $priceText .= ' with %s%% subscription discount.';
170
+ if (Mage::helper("tax")->needPriceConversion() && !Mage::helper("tax")->discountTax() &&
171
+ Mage::helper("tax")->displayPriceIncludingTax()
172
+ ) {
173
+ //If we are displaying a discount in which the math doesn't add up, display an additional note so the user is aware
174
+ $translateVars[] = substr($priceText, 0, -1);
175
+ $priceText = '%s (incl. tax).';
176
+ }
177
+ }
178
+ else {
179
+ $translateVars[] = Mage::helper('core')->currency($discount, true, false);
180
+ $priceText .= ' with %s subscription discount.';
181
+ }
182
+ }
183
+ }
184
+
185
+ // return text
186
+ array_unshift($translateVars, $priceText);
187
+ // translate expects each variable as a separate argument (not 1 argument of an array of variables)
188
+ return call_user_func_array(array($this, '__'), $translateVars);
189
+ }
190
+
191
+ /**
192
+ * Estimate order totals for a subscription order
193
+ *
194
+ * @param SFC_Autoship_Model_Subscription $subscription Subscription
195
+ * @param SFC_Autoship_Model_Platform_Product $platformProduct Subscription profile for product
196
+ * @param Mage_Catalog_Model_Product $product Mage product object
197
+ * @return array Array containing estimated order totals
198
+ */
199
+ public function estimateSubscriptionOrderTotals(Mage_Customer_Model_Customer $customer,
200
+ SFC_Autoship_Model_Subscription $subscription, SFC_Autoship_Model_Platform_Product $platformProduct,
201
+ Mage_Catalog_Model_Product $product)
202
+ {
203
+ // Calculate basics
204
+ $productPrice = $this->getSubscriptionPrice($platformProduct, $product);
205
+ $lineItemQty = $subscription->getQty();
206
+ $lineItemPrice = $lineItemQty * $productPrice;
207
+ // Build estimate
208
+ $estimate = array(
209
+ 'product_total' => $lineItemPrice,
210
+ 'shipping' => 0.0,
211
+ 'tax' => 0.0,
212
+ 'total' => $lineItemPrice,
213
+ );
214
+
215
+ // Check that we have necessary subscription settings to create / update a quote
216
+ if (!strlen($subscription->getShippingAddressId()) ||
217
+ !strlen($subscription->getShippingMethod())
218
+ ) {
219
+ // Not all setting set yet to generate a quote
220
+ // Just pass through defaults
221
+ // Calculate total
222
+ $estimate['total'] = $estimate['product_total'] + $estimate['tax'] + $estimate['shipping'];
223
+ }
224
+ else {
225
+ // Create or update Magento quote with all settings
226
+ $quote = $this->createOrUpdateQuote($customer, $subscription, $platformProduct, $product);
227
+
228
+ // Get quote totals
229
+ // Adjust estimate based on Mage quote
230
+ $totals = $quote->getTotals();
231
+ foreach ($totals as $total) {
232
+ if ($total->getCode() == 'subtotal') {
233
+ $estimate['product_total'] = $total->getValue();
234
+ }
235
+ if ($total->getCode() == 'discount') {
236
+ $estimate['discount'] = $total->getValue();
237
+ }
238
+ if ($total->getCode() == 'tax') {
239
+ $estimate['tax'] = $total->getValue();
240
+ }
241
+ if ($total->getCode() == 'shipping') {
242
+ $estimate['shipping'] = $total->getValue();
243
+ }
244
+ if ($total->getCode() == 'grand_total') {
245
+ $estimate['total'] = $total->getValue();
246
+ }
247
+ }
248
+ }
249
+
250
+ // Return estimate
251
+ return $estimate;
252
+ }
253
+
254
+ public function createOrUpdateQuote(Mage_Customer_Model_Customer $customer, SFC_Autoship_Model_Subscription $subscription,
255
+ SFC_Autoship_Model_Platform_Product $platformProduct, Mage_Catalog_Model_Product $product)
256
+ {
257
+ /*@var $quote Mage_Sales_Model_Quote*/
258
+ $quote = null;
259
+ // We are storing a quoteId inside subscription object, check if we find existing quoteId
260
+ // If no existing quote, create a new one
261
+ if (!strlen($subscription->getQuoteId())) {
262
+ // Create new quote and set customer and product
263
+ $quote = $this->createQuote($customer, $subscription, $platformProduct, $product);
264
+ }
265
+ else {
266
+ // Otherwise, load existing quote
267
+ $quote = Mage::getModel('sales/quote');
268
+ $quote->load($subscription->getQuoteId());
269
+
270
+ // Update product
271
+ $quoteItem = $this->getQuoteItemByProduct($quote, $product, array(
272
+ 'product_id' => $product->getId(),
273
+ 'qty' => $subscription->getQty()
274
+ ));
275
+ $quoteItem->setQty($subscription->getQty());
276
+ }
277
+
278
+ /*
279
+ * Now set / update various info on Magento quote
280
+ */
281
+
282
+ // Set billing address
283
+ if (strlen($subscription->getBillingAddressId())) {
284
+ $customerBillingAddress = Mage::getModel('customer/address')->load((int)$subscription->getBillingAddressId());
285
+ $customerBillingAddress->explodeStreetAddress();
286
+ if ($customerBillingAddress->getRegionId()) {
287
+ $customerBillingAddress->setRegion($customerBillingAddress->getRegionId());
288
+ }
289
+ $quoteBillingAddress = Mage::getModel('sales/quote_address');
290
+ $quoteBillingAddress->importCustomerAddress($customerBillingAddress);
291
+ $quoteBillingAddress->implodeStreetAddress();
292
+ if (($validateRes = $quoteBillingAddress->validate()) !== true) {
293
+ // Address validation failed
294
+ throw Mage::Exception($this->__('Customer address validation failed!'));
295
+ }
296
+ $quoteBillingAddress->setEmail($quote->getCustomer()->getEmail());
297
+ $quote->setBillingAddress($quoteBillingAddress);
298
+ }
299
+
300
+ // Set shipping address
301
+ $customerShippingAddress = Mage::getModel('customer/address')->load((int)$subscription->getShippingAddressId());
302
+ $customerShippingAddress->explodeStreetAddress();
303
+ if ($customerShippingAddress->getRegionId()) {
304
+ $customerShippingAddress->setRegion($customerShippingAddress->getRegionId());
305
+ }
306
+ $quoteShippingAddress = Mage::getModel('sales/quote_address');
307
+ $quoteShippingAddress->importCustomerAddress($customerShippingAddress);
308
+ $quoteShippingAddress->implodeStreetAddress();
309
+ if (($validateRes = $quoteShippingAddress->validate()) !== true) {
310
+ // Address validation failed
311
+ throw Mage::Exception($this->__('Customer address validation failed!'));
312
+ }
313
+ $quoteShippingAddress
314
+ ->setCollectShippingRates(true)
315
+ ->setSameAsBilling(0);
316
+ $quote->setShippingAddress($quoteShippingAddress);
317
+ $quote->save();
318
+
319
+ // Get shipping rate
320
+ $rate = $quote->getShippingAddress()->collectShippingRates()->getShippingRateByCode($subscription->getShippingMethod());
321
+ if (!$rate) {
322
+ Mage::throwException($this->__('Shipping method not available!'));
323
+ }
324
+ $quote->getShippingAddress()->setShippingMethod($subscription->getShippingMethod());
325
+
326
+ // Set payment method
327
+ if (strlen($subscription->getCimPaymentProfileId())) {
328
+ $paymentProfile = $subscription->getPaymentProfile();
329
+ $curLast4 = substr($paymentProfile->getCustomerCardnumber(), -4);
330
+ $encodedMethodCode = 'authnettoken' . '_cc4_' . $curLast4;
331
+ $paymentData = array(
332
+ 'method' => $encodedMethodCode,
333
+ );
334
+ $quote->getShippingAddress()->setPaymentMethod($paymentData['method']);
335
+ $quote->getShippingAddress()->setCollectShippingRates(true);
336
+ try {
337
+ // Import payment data
338
+ $payment = $quote->getPayment();
339
+ $payment->importData($paymentData);
340
+ }
341
+ catch (Mage_Core_Exception $e) {
342
+ Mage::throwException($this->__('Payment method can not be set on quote!'));
343
+ }
344
+ }
345
+
346
+ try {
347
+ // Calculate totals on quote
348
+ $quote->setTotalsCollectedFlag(false)
349
+ ->collectTotals()
350
+ ->save();
351
+ }
352
+ catch (Mage_Core_Exception $e) {
353
+ Mage::throwException($this->__('Failed to calculate totals for quote!'));
354
+ }
355
+
356
+ // Return quote object
357
+ return $quote;
358
+ }
359
+
360
+ public function createQuote(Mage_Customer_Model_Customer $customer, SFC_Autoship_Model_Subscription $subscription,
361
+ SFC_Autoship_Model_Platform_Product $platformProduct, Mage_Catalog_Model_Product $product)
362
+ {
363
+ // Create quote
364
+ /*@var $quote Mage_Sales_Model_Quote*/
365
+ $quote = Mage::getModel('sales/quote');
366
+ $quote->setStoreId(Mage::app()->getStore()->getId())
367
+ ->setIsActive(false)
368
+ ->setIsMultiShipping(false)
369
+ ->save();
370
+
371
+ try {
372
+ // Build request and Add product
373
+ $productRequest = new Varien_Object();
374
+ $productRequest->setQty($subscription->getQty());
375
+ $productRequest->setProductId($product->getId());
376
+ $quoteItem = $quote->addProduct($product, $productRequest);
377
+ //$itemPrice = $this->getSubscriptionPrice($platformProduct, $product);
378
+ $quoteItem->setData('item_fulfils_subscription', true);
379
+ $quoteItem->setData('subscription_id', '0'); // Dummy value, just to get estimate
380
+ // We no longer use the custom price method
381
+ //$quoteItem->setCustomPrice($itemPrice);
382
+ //$quoteItem->setOriginalCustomPrice($itemPrice);
383
+ //$quoteItem->setNoDiscount(true);
384
+ }
385
+ catch (Mage_Core_Exception $e) {
386
+ Mage::throwException($this->__('Failed to add product to quote!'));
387
+ }
388
+
389
+ // Set customer
390
+ $quote
391
+ ->setCustomer($customer)
392
+ ->setCheckoutMethod(Mage_Checkout_Model_Type_Onepage::METHOD_CUSTOMER);
393
+
394
+ // Return new quote
395
+ return $quote;
396
+ }
397
+
398
+ /**
399
+ * Method inspired by Mage_Checkout_Model_Api_Resource_Product::_getQuoteItemByProduct
400
+ * Get QuoteItem by Product and request info
401
+ *
402
+ * @param Mage_Sales_Model_Quote $quote
403
+ * @param Mage_Catalog_Model_Product $product
404
+ * @param Varien_Object $requestInfo
405
+ * @return Mage_Sales_Model_Quote_Item
406
+ * @throw Mage_Core_Exception
407
+ */
408
+ protected function getQuoteItemByProduct(Mage_Sales_Model_Quote $quote, Mage_Catalog_Model_Product $product,
409
+ Varien_Object $requestInfo)
410
+ {
411
+ $cartCandidates = $product->getTypeInstance(true)
412
+ ->prepareForCartAdvanced(
413
+ $requestInfo,
414
+ $product,
415
+ Mage_Catalog_Model_Product_Type_Abstract::PROCESS_MODE_FULL
416
+ );
417
+
418
+ /**
419
+ * Error message
420
+ */
421
+ if (is_string($cartCandidates)) {
422
+ Mage::throwException($cartCandidates);
423
+ }
424
+
425
+ /**
426
+ * If prepare process return one object
427
+ */
428
+ if (!is_array($cartCandidates)) {
429
+ $cartCandidates = array($cartCandidates);
430
+ }
431
+
432
+ /** @var $item Mage_Sales_Model_Quote_Item */
433
+ $item = null;
434
+ foreach ($cartCandidates as $candidate) {
435
+ if ($candidate->getParentProductId()) {
436
+ continue;
437
+ }
438
+
439
+ $item = $quote->getItemByProduct($candidate);
440
+ }
441
+
442
+ if (is_null($item)) {
443
+ $item = Mage::getModel('sales/quote_item');
444
+ }
445
+
446
+ return $item;
447
+ }
448
+
449
+ /**
450
+ * Get the product price including tax
451
+ * @param Mage_Catalog_Model_Product $product
452
+ * @param $finalPrice
453
+ * @return float
454
+ */
455
+ public function getProductPriceInclTax(Mage_Catalog_Model_Product $product, $finalPrice)
456
+ {
457
+ $priceInclTax = Mage::helper("tax")->priceIncludesTax();
458
+ if (!$priceInclTax) {
459
+ $finalPrice = Mage::helper("tax")->getPrice($product, $finalPrice, true);
460
+ }
461
+ return $finalPrice;
462
+ }
463
+
464
+ /**
465
+ * Get the product price excluding tax
466
+ * @param Mage_Catalog_Model_Product $product
467
+ * @param $finalPrice
468
+ * @return float
469
+ */
470
+ public function getProductPriceExclTax(Mage_Catalog_Model_Product $product, $finalPrice)
471
+ {
472
+ $priceInclTax = Mage::helper("tax")->priceIncludesTax();
473
+ if ($priceInclTax) {
474
+ $finalPrice = Mage::helper("tax")->getPrice($product, $finalPrice, false);
475
+ }
476
+ return $finalPrice;
477
+ }
478
+
479
+ /**
480
+ * @param Mage_Catalog_Model_Product $product
481
+ * @param int $qty
482
+ * @return float
483
+ */
484
+ public function getDiscountableProductPrice(Mage_Catalog_Model_Product $product, $qty = 1)
485
+ {
486
+ $applyDiscountToTax = Mage::helper("tax")->discountTax();
487
+ $finalPrice = $this->getOneTimePurchasePrice($product, $qty, false, $applyDiscountToTax); //Get the one time Purchase price, with or without tax
488
+ return $finalPrice;
489
+ }
490
+
491
+ public function adjustProductPriceForTax(Mage_Catalog_Model_Product $product, $productPrice)
492
+ {
493
+ /**
494
+ * Adjust the product price based on tax settings
495
+ */
496
+ $displayWithTax = Mage::helper("tax")->displayPriceIncludingTax();
497
+ $priceInclTax = Mage::helper("tax")->priceIncludesTax();
498
+ if ($displayWithTax && !$priceInclTax) {
499
+ $productPrice = Mage::helper("tax")->getPrice($product, $productPrice, true);
500
+ } elseif ($priceInclTax && !$displayWithTax) {
501
+ $productPrice = Mage::helper("tax")->getPrice($product, $productPrice, false);
502
+ }
503
+ return $productPrice;
504
+ }
505
+ }
app/code/local/SFC/Autoship/Helper/Vault.php CHANGED
@@ -1,4 +1,4 @@
1
- <?php //00612
2
  /**
3
  * Subscribe Pro - Subscriptions Management Extension
4
  *
@@ -15,252 +15,755 @@
15
  *
16
  */
17
 
18
- if(!extension_loaded('ionCube Loader')){$__oc=strtolower(substr(php_uname(),0,3));$__ln='/ioncube/ioncube_loader_'.$__oc.'_'.substr(phpversion(),0,3).(($__oc=='win')?'.dll':'.so');$__oid=$__id=realpath(ini_get('extension_dir'));$__here=dirname(__FILE__);if((@$__id[1])==':'){$__id=str_replace('\\','/',substr($__id,2));$__here=str_replace('\\','/',substr($__here,2));}$__rd=str_repeat('/..',substr_count($__id,'/')).$__here.'/';$__i=strlen($__rd);while($__i--){if($__rd[$__i]=='/'){$__lp=substr($__rd,0,$__i).$__ln;if(file_exists($__oid.$__lp)){$__ln=$__lp;break;}}}@dl($__ln);}else{die('The file '.__FILE__." is corrupted. Ensure that you use binary mode when transferring files with FTP and disable the 'TAR smart cr/lf feature' if using WinZIP\n");}if(function_exists('_il_exec')){return _il_exec();}die('The file <b>'.__FILE__.'</b> has been encoded with the <a href="http://www.ioncube.com">ionCube PHP Encoder</a> and requires the free '.basename($__ln).' <a href="http://www.ioncube.com/loader_download/">ionCube PHP Loader</a> to be installed.');
19
-
20
- ?>
21
- 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
- 1dEBK6RMkbCBN9ualc3k5hRjowSh3+Q4+rwCB9Ut75p7sIJWd4BlfLzdhDik673syns5nWn3Z0kd
23
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- +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
- 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
- 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
- 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
- 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
- rNUdgrvZ0QwzLZu+Y8T4SRG5b5U580yhixaJbBsuxs7zbzeOR3420IOZhu4Hxsme2NnbN8lrNfAT
40
- 2bsj0iXXXRW/Rga97Ml0p0b3CZXJkK6XiAZH3Ic+oocupXCBxpe+egjw0JbxQxALY9ks3oCadm5x
41
- 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
- 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
- idDrfFDv27iz33P6lASChz1qtUhZm0nl+aJAG1EnZKXp/mi4eKip5iuOXB7wbm6MhcUvoKdrPHXj
44
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- qY+kjHvsOjX+Auk0LgLpjdvV0s2OUARvZxuT7lXmQS9Iwd6aBW5B9Q5BoQbSYNHDzygS30fVBQsG
54
- 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
- 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
- 9lRx1GFV3XKa0IQ085j3XtKO+U5jDTjA0G/zS+14iahWQTu5+Ow2FIzBKpry6jDYpwrPPfOkQLYs
57
- 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
- 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
- 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
- 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
- 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
- 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
- IYlsnYW3SCqontWAFL7NKrvpT1yTW43A98MsABd1wSHFlCiKTMD3KWCkWz0GQ+z3saDEqOR5UMHS
64
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- mNiMLadHCiacfB7TxTAK0SLP/Su3tSP3YOiLnT5NFUaoHK7IHivyoT34vNdbEIb9CVT4+kxRnBBh
72
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- gZj0J8Wd/FFskKe0UlRYDCXkTHPyI1yH2JqdoGTvGB/BiCTGwIvN8A2EDrlysrG8YespwebdxVUK
85
- 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
- RPuc+7MI3+8eUBFJlff3phjiU5oMj8uq58d3/iqeXb1QinjLAUH/1FKzJrhxNTIoPKxdLANV1GEW
87
- 30Rb4pNYRGAdxAAlXklNfSp7oKYMLOTIaX6K5m6047SDRgMkc4bZg2bbmLOOd2Q9DWZ6C6+DGgD+
88
- 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
- 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
- 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
- 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
- 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
- n8kGxMyIgYaTn8zgx687fq9frvvnLq5z6SGOq8jMr8iIAVg0IOjb0XzdwFAfBXb0C8I0FRQRqIEL
94
- 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
- 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
- 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
- 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
- 1p269/b0mxg6dJcjBLb1dhhT5V5pjBGx9BU0bi5OC/0GNiDhK9u6fe2OfvZZjoi/GG+0nCZzy0rk
99
- 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
- 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
- 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
- CAeTpDWYEFPfBxlf4Rtg4r+wlVAHu9Rb0/ZxLH36YCfAUP+HMFw5qA7o0piSVtCU+2OYdzhg2JEm
103
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- r0GmJJBdNqtk6GOYNrTN/DO7X98oydO6bbXd7PHK2Vbm6On31djsG3gFNxIDJAsW007D2JruUBok
111
- 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
- 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
- zgpU9OGqX8CIJAFEahe1n+ZUMSjIwGCX5IbtIVYpg+31m/zxUMIY7E/H5Kc8rqI9yM5NH5Qlzrrd
114
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- RLTSxm9QwnKinF6sDGsC9nGikP1Fr/Ym6aeW6ir2KEXIzyAWMohX2itRTYKzrSd13Au/kJBd1aqC
131
- 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
- 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
- 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
- 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
- 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
- 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
- NtT99ApYW4TGyr3brrKq5tUP8oQX8JNh9kX13lPWfPKob5MQBYNJVcqR4it5TkJN0WMzCftIEEHz
138
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 99uk3nUgIF0cY+1tQCvAsGt/DH3ZKj+3xME74NyoGoH8hQjsAhqQFh0JaXQ4MnEM8uwJLaZstMRD
149
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 9xKwk4Nm8H8/KUEjIwjKnIv0tEvSiFySfmO2ksQLp0mD/vE63xXFCIc2sSFS70h/OE8CaNS8gWDK
167
- +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
- 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
- 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
- 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
- 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
- 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
- SIspDLiwC5FEk6/nYfAE0lN56vqZWqx+ylsriwncp2ygn02xXz9SJT/sfQzv/Mh++UI2HVrLQZOk
174
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- AO2QNWX6xAiNt6F/ZdatC3I9b0OvVmD7A7ls20TCxTQ9JXM8mDaVFi/fDDP5j7b0esoO9r2zfVwA
191
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- FlYs0Nlxy2RCS35VmNsw0/VEViMTEGw54sxGduUjpHQRPDww5cU12upr4oNbPvZxDc15hmR/ci4P
201
- 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
- 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
- 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
- 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
- Nh8t0ZCKCVowWaulYoQwetUMS+7wjN+xFa1ybqSVD8NjbsqCdj43bHusrcbdrmMOMNjNocXNq2w2
206
- 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
- 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
- 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
- hbQb2eMWB6L5oXiq5YHoc71Ep4Olj5UEnwOQdlStgJX+MmC9dX2OwR5QVJE7xIBEwk/K54U7OsND
210
- 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
- 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
- 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
- WDWVFW5KEuAvzxf+0mhLzsQedIAR4QLrzrNL/SUsRhLTA9RillQ+avh+GLYwSFXOlNtacYG9jNvQ
214
- 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
- +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
- 0RA+TiRoOnUohuT2yu07LSc+E4i5g+ADMJeuCdLfDOMnMEcEMARQK07vaFCF/Seu1e7vLjaZtQkb
217
- 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
- 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
- 8MyK0EpMAbfLTiOBTGMCVVbsWsmgA6t8N5YWISvCZDPfdJNAtwt3ZjhWCmUFl3Tx6xBxNrmSHLXO
220
- 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
- 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
- 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
- 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
- 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
- J7vwAKcekWiPxBhgLfOra7RtKc3rDhv1c4I5HcSbiJSf/9MSFdXtw10Ra9ZRWaRE0QJr5ElzMNAK
226
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- BTAGFiaZ5RBOstKKxuUb/lt/1XRtDWptqqL17GmQl/ko7k0RZW1H5S6kOWHPUSxeuEsKwcOUWzHs
242
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
266
- Oc08/HHLsPfwVpIWu3klPIDcejsCcmgfo8GSUm==
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
  /**
3
  * Subscribe Pro - Subscriptions Management Extension
4
  *
15
  *
16
  */
17
 
18
+ /**
19
+ * Helper class to access Subscribe Pro Vault API
20
+ */
21
+ class SFC_Autoship_Helper_Vault extends Mage_Core_Helper_Abstract
22
+ {
23
+
24
+ /**
25
+ * @param $customerEmail
26
+ * @return array
27
+ */
28
+ public function getPaymentProfilesForCustomer($customerEmail)
29
+ {
30
+ // Make request
31
+ $response = $this->getApiHelper()->makeVaultRequest(
32
+ 'paymentprofiles',
33
+ array('customer_email' => $customerEmail),
34
+ 'GET');
35
+ // Check response
36
+ if ($response['code'] != 200) {
37
+ Mage::throwException($this->__('Failed to retrieve payment profiles!'));
38
+ }
39
+
40
+ // Return payment profile array from response
41
+ return $this->parsePaymentProfileArrayFromResponse($response);
42
+ }
43
+
44
+ public function createPaymentProfile(SFC_Autoship_Model_Payment_Profile $profile)
45
+ {
46
+ // Build request
47
+ $billingAddress = $profile->getData('billing_address');
48
+ $requestData = array(
49
+ 'payment_profile' => array(
50
+ 'magento_customer_id' => $profile->getData('magento_customer_id'),
51
+ 'customer_email' => $profile->getData('customer_email'),
52
+ 'creditcard_type' => $profile->getData('creditcard_type'),
53
+ 'creditcard_number' => $profile->getData('creditcard_number'),
54
+ 'creditcard_month' => $profile->getData('creditcard_month'),
55
+ 'creditcard_year' => $profile->getData('creditcard_year'),
56
+ 'billing_address' => $billingAddress->getData(),
57
+ ),
58
+ );
59
+ // Make request
60
+ $response = $this->getApiHelper()->makeVaultRequest(
61
+ 'paymentprofile',
62
+ json_encode($requestData),
63
+ 'POST');
64
+ // Check response
65
+ if ($response['code'] != 201) {
66
+ $this->throwErrorResponseException($response, 'Failed to create payment profile!');
67
+ }
68
+
69
+ // Return payment profile from response
70
+ return $this->parsePaymentProfileFromResponse($response);
71
+ }
72
+
73
+ public function createPaymentToken(Mage_Customer_Model_Address_Abstract $billingAddress, $cardNumber, $expMonth, $expYear, $cvv = null)
74
+ {
75
+ // Get billing address
76
+ $billingAddressModel = Mage::getModel('autoship/payment_profile_address')
77
+ ->updateFromCustomerAddress($billingAddress);
78
+ // Build request data
79
+ $requestData = array(
80
+ 'token' => array(
81
+ 'creditcard_number' => $cardNumber,
82
+ 'creditcard_month' => $expMonth,
83
+ 'creditcard_year' => $expYear,
84
+ 'billing_address' => $billingAddressModel->getData(),
85
+ ),
86
+ );
87
+ // Optionally add CVV
88
+ if ($cvv != null && strlen($cvv)) {
89
+ $requestData['token']['creditcard_verification_value'] = $cvv;
90
+ }
91
+ // Make request
92
+ $response = $this->getApiHelper()->makeVaultRequest(
93
+ 'token',
94
+ json_encode($requestData),
95
+ 'POST');
96
+ // Check response
97
+ if ($response['code'] != 201) {
98
+ $this->throwErrorResponseException($response, 'Failed to create payment token!');
99
+ }
100
+
101
+ // Return payment profile from response
102
+ return $this->parseTokenFromResponse($response);
103
+ }
104
+
105
+ /**
106
+ * @param $token
107
+ * @return mixed
108
+ */
109
+ public function getPaymentTokenDetails($token)
110
+ {
111
+ // Make request
112
+ $response = $this->getApiHelper()->makeVaultRequest(
113
+ 'tokens/' . $token,
114
+ array(),
115
+ 'GET');
116
+ // Check response
117
+ if ($response['code'] != 200) {
118
+ $this->throwErrorResponseException($response, 'Failed to retrieve payment token details!');
119
+ }
120
+
121
+ // Return payment profile from response
122
+ return $this->parseTokenFromResponse($response);
123
+ }
124
+
125
+ /**
126
+ * @param $paymentProfileId
127
+ * @return SFC_Autoship_Model_Payment_Profile
128
+ */
129
+ public function getPaymentProfile($paymentProfileId)
130
+ {
131
+ // Make request
132
+ $response = $this->getApiHelper()->makeVaultRequest(
133
+ 'paymentprofiles/' . $paymentProfileId,
134
+ array(),
135
+ 'GET');
136
+ // Check response
137
+ if ($response['code'] != 200) {
138
+ $this->throwErrorResponseException($response, 'Failed to retrieve payment profile!');
139
+ }
140
+
141
+ // Return payment profile from response
142
+ return $this->parsePaymentProfileFromResponse($response);
143
+ }
144
+
145
+ /**
146
+ * @param $paymentProfileId
147
+ * @return SFC_Autoship_Model_Payment_Profile
148
+ */
149
+ public function getPaymentProfileByToken($paymentToken)
150
+ {
151
+ // Make request
152
+ $response = $this->getApiHelper()->makeVaultRequest(
153
+ 'tokens/' . $paymentToken . '/paymentprofile',
154
+ array(),
155
+ 'GET');
156
+ // Check response
157
+ if ($response['code'] != 200) {
158
+ $this->throwErrorResponseException($response, 'Failed to retrieve payment profile!');
159
+ }
160
+
161
+ // Return payment profile from response
162
+ return $this->parsePaymentProfileFromResponse($response);
163
+ }
164
+
165
+ /**
166
+ * @param string $magentoCustomerId
167
+ * @param string $paymentToken
168
+ * @param Mage_Customer_Model_Address_Abstract|null $billingAddress
169
+ * @param null|string $expMonth
170
+ * @param null|string $expYear
171
+ * @return SFC_Autoship_Model_Payment_Profile
172
+ */
173
+ public function storeToken($magentoCustomerId, $paymentToken, Mage_Customer_Model_Address_Abstract $billingAddress = null, $expMonth = null, $expYear = null)
174
+ {
175
+ // Build request data
176
+ $requestData = array(
177
+ 'payment_profile' => array(
178
+ 'magento_customer_id' => $magentoCustomerId,
179
+ ),
180
+ );
181
+ // Optionally add billing address
182
+ if ($billingAddress != null) {
183
+ $billingAddressModel = Mage::getModel('autoship/payment_profile_address')
184
+ ->updateFromCustomerAddress($billingAddress);
185
+ $requestData['payment_profile']['billing_address'] = $billingAddressModel->getData();
186
+ }
187
+ // Optionally add expiration date
188
+ if (strlen($expMonth) && strlen($expYear)) {
189
+ $requestData['payment_profile']['creditcard_month'] = $expMonth;
190
+ $requestData['payment_profile']['creditcard_year'] = $expYear;
191
+ }
192
+ // Make request
193
+ $response = $this->getApiHelper()->makeVaultRequest(
194
+ 'tokens/' . $paymentToken . '/store',
195
+ json_encode($requestData),
196
+ 'POST');
197
+ // Check response
198
+ if ($response['code'] != 201) {
199
+ $this->throwErrorResponseException($response, 'Failed to store payment card!');
200
+ }
201
+
202
+ // Return payment profile from response
203
+ return $this->parsePaymentProfileFromResponse($response);
204
+ }
205
+
206
+ /**
207
+ * @param string $magentoCustomerId
208
+ * @param string $paymentToken
209
+ * @param Mage_Customer_Model_Address_Abstract|null $billingAddress
210
+ * @param null|string $expMonth
211
+ * @param null|string $expYear
212
+ * @return SFC_Autoship_Model_Payment_Profile
213
+ */
214
+ public function storeAndVerifyToken($magentoCustomerId, $paymentToken, Mage_Customer_Model_Address_Abstract $billingAddress = null, $expMonth = null, $expYear = null)
215
+ {
216
+ // Build request data
217
+ $requestData = array(
218
+ 'payment_profile' => array(
219
+ 'magento_customer_id' => $magentoCustomerId,
220
+ ),
221
+ );
222
+ // Optionally add billing address
223
+ if ($billingAddress != null) {
224
+ $billingAddressModel = Mage::getModel('autoship/payment_profile_address')
225
+ ->updateFromCustomerAddress($billingAddress);
226
+ $requestData['payment_profile']['billing_address'] = $billingAddressModel->getData();
227
+ }
228
+ // Optionally add expiration date
229
+ if (strlen($expMonth) && strlen($expYear)) {
230
+ $requestData['payment_profile']['creditcard_month'] = $expMonth;
231
+ $requestData['payment_profile']['creditcard_year'] = $expYear;
232
+ }
233
+ // Make request
234
+ $response = $this->getApiHelper()->makeVaultRequest(
235
+ 'tokens/' . $paymentToken . '/verifyandstore',
236
+ json_encode($requestData),
237
+ 'POST');
238
+ // Check response
239
+ if ($response['code'] != 201) {
240
+ $this->throwErrorResponseException($response, 'Failed to verify and store payment card!');
241
+ }
242
+
243
+ // Return payment profile from response
244
+ return $this->parsePaymentProfileFromResponse($response);
245
+ }
246
+
247
+ /**
248
+ * @param SFC_Autoship_Model_Payment_Profile $paymentProfile
249
+ * @return SFC_Autoship_Model_Payment_Profile
250
+ */
251
+ public function updatePaymentProfile(SFC_Autoship_Model_Payment_Profile $paymentProfile)
252
+ {
253
+ // Build request data
254
+ // Only fields we can update are billing addy, cc expiration date
255
+ $requestData = array(
256
+ 'payment_profile' => array(
257
+ 'creditcard_month' => $paymentProfile->getData('creditcard_month'),
258
+ 'creditcard_year' => $paymentProfile->getData('creditcard_year'),
259
+ 'billing_address' => $paymentProfile->getData('billing_address')->getData(),
260
+ ),
261
+ );
262
+ // Make request
263
+ $response = $this->getApiHelper()->makeVaultRequest(
264
+ 'paymentprofiles/' . $paymentProfile->getData('id'),
265
+ json_encode($requestData),
266
+ 'PUT');
267
+ // Check response
268
+ if ($response['code'] != 200) {
269
+ $this->throwErrorResponseException($response, 'Failed to update payment profile!');
270
+ }
271
+
272
+ // Return payment profile from response
273
+ return $this->parsePaymentProfileFromResponse($response);
274
+ }
275
+
276
+ /**
277
+ * @param SFC_Autoship_Model_Payment_Profile $paymentProfile
278
+ */
279
+ public function redactPaymentProfile(SFC_Autoship_Model_Payment_Profile $paymentProfile)
280
+ {
281
+ return $this->redactPaymentProfileId($paymentProfile->getData('id'));
282
+ }
283
+
284
+ /**
285
+ * @param string $paymentProfileId
286
+ */
287
+ public function redactPaymentProfileId($paymentProfileId)
288
+ {
289
+ // Make request
290
+ $response = $this->getApiHelper()->makeVaultRequest(
291
+ 'paymentprofiles/' . $paymentProfileId . '/redact',
292
+ json_encode(array()),
293
+ 'PUT');
294
+ // Check response
295
+ if ($response['code'] != 200) {
296
+ $this->throwErrorResponseException($response, 'Failed to redact payment profile!');
297
+ }
298
+ }
299
+
300
+ public function purchase(SFC_Autoship_Model_Payment_Profile $paymentProfile, $amount, $currencyCode, $additionalFields = array())
301
+ {
302
+ // Build request data
303
+ $requestData = array(
304
+ 'transaction' => $additionalFields,
305
+ );
306
+ $requestData['transaction']['amount'] = number_format(100 * $amount, 0, "", "");
307
+ $requestData['transaction']['currency_code'] = $currencyCode;
308
+
309
+ // Make request
310
+ $response = $this->getApiHelper()->makeVaultRequest(
311
+ 'paymentprofiles/' . $paymentProfile->getData('id') . '/purchase',
312
+ json_encode($requestData),
313
+ 'POST');
314
+ // Check response
315
+ if ($response['code'] != 201) {
316
+ $this->throwErrorResponseException($response, 'Failed to purchase!');
317
+ }
318
+ // Parse response
319
+ $platformTransaction = $this->parseTransactionFromResponse($response);
320
+ // Check transaction state in response
321
+ if ($platformTransaction['state'] != 'succeeded') {
322
+ $this->throwTransactionErrorException($platformTransaction, 'Failed to purchase!');
323
+ }
324
+
325
+ return $platformTransaction;
326
+ }
327
+
328
+ public function purchaseOneTime($paymentToken, $amount, $currencyCode, $additionalFields = array(), Mage_Customer_Model_Address_Abstract $billingAddress = null, $expMonth = null, $expYear = null)
329
+ {
330
+ // Build request data
331
+ $requestData = array(
332
+ 'transaction' => $additionalFields,
333
+ );
334
+ $requestData['transaction']['amount'] = number_format(100 * $amount, 0, "", "");
335
+ $requestData['transaction']['currency_code'] = $currencyCode;
336
+ // Optionally add billing address
337
+ if ($billingAddress != null) {
338
+ $billingAddressModel = Mage::getModel('autoship/payment_profile_address')
339
+ ->updateFromCustomerAddress($billingAddress);
340
+ $requestData['transaction']['billing_address'] = $billingAddressModel->getData();
341
+ }
342
+ // Optionally add expiration date
343
+ if (strlen($expMonth) && strlen($expYear)) {
344
+ $requestData['transaction']['creditcard_month'] = $expMonth;
345
+ $requestData['transaction']['creditcard_year'] = $expYear;
346
+ }
347
+ // Make request
348
+ $response = $this->getApiHelper()->makeVaultRequest(
349
+ 'tokens/' . $paymentToken . '/purchase',
350
+ json_encode($requestData),
351
+ 'POST');
352
+ // Check response
353
+ if ($response['code'] != 201) {
354
+ $this->throwErrorResponseException($response, 'Failed to purchase!');
355
+ }
356
+ // Parse response
357
+ $platformTransaction = $this->parseTransactionFromResponse($response);
358
+ // Check transaction state in response
359
+ if ($platformTransaction['state'] != 'succeeded') {
360
+ $this->throwTransactionErrorException($platformTransaction, 'Failed to purchase!');
361
+ }
362
+
363
+ return $platformTransaction;
364
+ }
365
+
366
+ public function authorize(SFC_Autoship_Model_Payment_Profile $paymentProfile, $amount, $currencyCode, $additionalFields = array())
367
+ {
368
+ // Build request data
369
+ $requestData = array(
370
+ 'transaction' => $additionalFields,
371
+ );
372
+ $requestData['transaction']['amount'] = number_format(100 * $amount, 0, "", "");
373
+ $requestData['transaction']['currency_code'] = $currencyCode;
374
+ // Make request
375
+ $response = $this->getApiHelper()->makeVaultRequest(
376
+ 'paymentprofiles/' . $paymentProfile->getData('id') . '/authorize',
377
+ json_encode($requestData),
378
+ 'POST');
379
+ // Check response
380
+ if ($response['code'] != 201) {
381
+ $this->throwErrorResponseException($response, 'Failed to authorize!');
382
+ }
383
+ // Parse response
384
+ $platformTransaction = $this->parseTransactionFromResponse($response);
385
+ // Check transaction state in response
386
+ if ($platformTransaction['state'] != 'succeeded') {
387
+ $this->throwTransactionErrorException($platformTransaction, 'Failed to authorize!');
388
+ }
389
+
390
+ return $platformTransaction;
391
+ }
392
+
393
+ public function authorizeOneTime($paymentToken, $amount, $additionalFields = array(), $currencyCode, Mage_Customer_Model_Address_Abstract $billingAddress = null, $expMonth = null, $expYear = null)
394
+ {
395
+ // Build request data
396
+ $requestData = array(
397
+ 'transaction' => $additionalFields,
398
+ );
399
+ $requestData['transaction']['amount'] = number_format(100 * $amount, 0, "", "");
400
+ $requestData['transaction']['currency_code'] = $currencyCode;
401
+ // Optionally add billing address
402
+ if ($billingAddress != null) {
403
+ $billingAddressModel = Mage::getModel('autoship/payment_profile_address')
404
+ ->updateFromCustomerAddress($billingAddress);
405
+ $requestData['transaction']['billing_address'] = $billingAddressModel->getData();
406
+ }
407
+ // Optionally add expiration date
408
+ if (strlen($expMonth) && strlen($expYear)) {
409
+ $requestData['transaction']['creditcard_month'] = $expMonth;
410
+ $requestData['transaction']['creditcard_year'] = $expYear;
411
+ }
412
+ // Make request
413
+ $response = $this->getApiHelper()->makeVaultRequest(
414
+ 'tokens/' . $paymentToken . '/authorize',
415
+ json_encode($requestData),
416
+ 'POST');
417
+ // Check response
418
+ if ($response['code'] != 201) {
419
+ $this->throwErrorResponseException($response, 'Failed to authorize!');
420
+ }
421
+ // Parse response
422
+ $platformTransaction = $this->parseTransactionFromResponse($response);
423
+ // Check transaction state in response
424
+ if ($platformTransaction['state'] != 'succeeded') {
425
+ $this->throwTransactionErrorException($platformTransaction, 'Failed to authorize!');
426
+ }
427
+
428
+ return $platformTransaction;
429
+ }
430
+
431
+ /**
432
+ * @param $transactionId
433
+ * @param int $amount Amount for partial capture, 0 for full capture
434
+ * @param string $currencyCode
435
+ * @return array
436
+ */
437
+ public function capture($transactionId, $amount = 0, $currencyCode = 'USD')
438
+ {
439
+ // Build request data
440
+ if ($amount > 0.0) {
441
+ $requestData = array(
442
+ 'transaction' => array(
443
+ 'amount' => number_format(100 * $amount, 0, "", ""),
444
+ 'currency_code' => $currencyCode,
445
+ ),
446
+ );
447
+ }
448
+ else {
449
+ $requestData = array();
450
+ }
451
+ // Make request
452
+ $response = $this->getApiHelper()->makeVaultRequest(
453
+ 'transactions/' . $transactionId . '/capture',
454
+ json_encode($requestData),
455
+ 'POST');
456
+ // Check response
457
+ if ($response['code'] != 201) {
458
+ $this->throwErrorResponseException($response, 'Failed to capture!');
459
+ }
460
+ // Parse response
461
+ $platformTransaction = $this->parseTransactionFromResponse($response);
462
+ // Check transaction state in response
463
+ if ($platformTransaction['state'] != 'succeeded') {
464
+ $this->throwTransactionErrorException($platformTransaction, 'Failed to capture!');
465
+ }
466
+
467
+ return $platformTransaction;
468
+ }
469
+
470
+ public function verify(SFC_Autoship_Model_Payment_Profile $paymentProfile, $currencyCode, $additionalFields = array())
471
+ {
472
+ // Build request data
473
+ $requestData = array(
474
+ 'transaction' => $additionalFields,
475
+ );
476
+ $requestData['transaction']['currency_code'] = $currencyCode;
477
+ // Make request
478
+ $response = $this->getApiHelper()->makeVaultRequest(
479
+ 'paymentprofiles/' . $paymentProfile->getData('id') . '/verify',
480
+ json_encode($requestData),
481
+ 'POST');
482
+ // Check response
483
+ if ($response['code'] != 201) {
484
+ $this->throwErrorResponseException($response, 'Failed to verify!');
485
+ }
486
+ // Parse response
487
+ $platformTransaction = $this->parseTransactionFromResponse($response);
488
+ // Check transaction state in response
489
+ if ($platformTransaction['state'] != 'succeeded') {
490
+ $this->throwTransactionErrorException($platformTransaction, 'Failed to verify!');
491
+ }
492
+
493
+ return $platformTransaction;
494
+ }
495
+
496
+ /**
497
+ * @param $transactionId
498
+ * @param int $amount Amount for partial capture, 0 for full capture
499
+ * @param string $currencyCode
500
+ * @return array
501
+ */
502
+ public function credit($transactionId, $amount = 0, $currencyCode = 'USD')
503
+ {
504
+ // Build request data
505
+ if ($amount > 0.0) {
506
+ $requestData = array(
507
+ 'transaction' => array(
508
+ 'amount' => number_format(100 * $amount, 0, "", ""),
509
+ 'currency_code' => $currencyCode,
510
+ ),
511
+ );
512
+ }
513
+ else {
514
+ $requestData = array();
515
+ }
516
+ // Make request
517
+ $response = $this->getApiHelper()->makeVaultRequest(
518
+ 'transactions/' . $transactionId . '/credit',
519
+ json_encode($requestData),
520
+ 'POST');
521
+ // Check response
522
+ if ($response['code'] != 201) {
523
+ $this->throwErrorResponseException($response, 'Failed to credit!');
524
+ }
525
+ // Parse response
526
+ $platformTransaction = $this->parseTransactionFromResponse($response);
527
+ // Check transaction state in response
528
+ if ($platformTransaction['state'] != 'succeeded') {
529
+ $this->throwTransactionErrorException($platformTransaction, 'Failed to credit!');
530
+ }
531
+
532
+ return $platformTransaction;
533
+ }
534
+
535
+ /**
536
+ * @param $transactionId
537
+ * @return array
538
+ */
539
+ public function void($transactionId)
540
+ {
541
+ // Make request
542
+ $response = $this->getApiHelper()->makeVaultRequest(
543
+ 'transactions/' . $transactionId . '/void',
544
+ json_encode(array()),
545
+ 'POST');
546
+ // Check response
547
+ if ($response['code'] != 201) {
548
+ $this->throwErrorResponseException($response, 'Failed to void!');
549
+ }
550
+ // Parse response
551
+ $platformTransaction = $this->parseTransactionFromResponse($response);
552
+ // Check transaction state in response
553
+ if ($platformTransaction['state'] != 'succeeded') {
554
+ $this->throwTransactionErrorException($platformTransaction, 'Failed to void!');
555
+ }
556
+
557
+ return $platformTransaction;
558
+ }
559
+
560
+ protected function getAllCardTypeMappings()
561
+ {
562
+ // Map of card types
563
+ // Subscribe Pro / Spreedly type => Magento type
564
+ $cardTypes = array(
565
+ 'visa' => 'VI',
566
+ 'master' => 'MC',
567
+ 'american_express' => 'AE',
568
+ 'discover' => 'DI',
569
+ 'jcb' => 'JCB',
570
+ );
571
+
572
+ return $cardTypes;
573
+ }
574
+
575
+ public function mapMagentoCardTypeToSubscribePro($type, $throwExceptionOnTypeNotFound = true)
576
+ {
577
+ // Map of card types
578
+ $cardTypes = $this->getAllCardTypeMappings();
579
+ $cardTypes = array_flip($cardTypes);
580
+
581
+ if (isset($cardTypes[$type])) {
582
+ return $cardTypes[$type];
583
+ }
584
+ else {
585
+ if ($throwExceptionOnTypeNotFound) {
586
+ Mage::throwException($this->__('Invalid credit card type: %s', $type));
587
+ }
588
+ else {
589
+ return null;
590
+ }
591
+ }
592
+ }
593
+
594
+ public function mapSubscribeProCardTypeToMagento($type, $throwExceptionOnTypeNotFound = true)
595
+ {
596
+ // Map of card types
597
+ $cardTypes = $this->getAllCardTypeMappings();
598
+
599
+ if (isset($cardTypes[$type])) {
600
+ return $cardTypes[$type];
601
+ }
602
+ else {
603
+ if ($throwExceptionOnTypeNotFound) {
604
+ Mage::throwException($this->__('Invalid credit card type: ' . $type));
605
+ }
606
+ else {
607
+ return null;
608
+ }
609
+ }
610
+ }
611
+
612
+ /**
613
+ * @return SFC_Autoship_Helper_Api
614
+ */
615
+ protected function getApiHelper()
616
+ {
617
+ /** @var SFC_Autoship_Helper_Api $apiHelper */
618
+ $apiHelper = Mage::helper('autoship/api');
619
+
620
+ return $apiHelper;
621
+ }
622
+
623
+ /**
624
+ * @param array $response
625
+ * @return SFC_Autoship_Model_Payment_Profile
626
+ */
627
+ protected function parsePaymentProfileFromResponse(array $response)
628
+ {
629
+ // Check that response is well formed
630
+ if (!isset($response['result']) ||
631
+ !isset($response['result']['payment_profile']) ||
632
+ !is_array($response['result']['payment_profile'])
633
+ ) {
634
+ Mage::throwException($this->__('API response format error for payment profile!'));
635
+ }
636
+ $result = $response['result'];
637
+ $platformPaymentProfile = $result['payment_profile'];
638
+ // Convert response into a model
639
+ $paymentProfile = SFC_Autoship_Model_Payment_Profile::makePaymentProfileFromVaultData($platformPaymentProfile);
640
+
641
+ return $paymentProfile;
642
+ }
643
+
644
+ protected function parsePaymentProfileArrayFromResponse(array $response)
645
+ {
646
+ // Check that response is well formed
647
+ if (!isset($response['result']) ||
648
+ !isset($response['result']['payment_profiles']) ||
649
+ !is_array($response['result']['payment_profiles'])
650
+ ) {
651
+ Mage::throwException('API response format error for payment profiles!');
652
+ }
653
+ $result = $response['result'];
654
+ $platformPaymentProfiles = $result['payment_profiles'];
655
+ // Iterate through payment profiles, convert each
656
+ $paymentProfiles = array();
657
+ foreach ($platformPaymentProfiles as $platformPaymentProfile) {
658
+ // Convert response into a model
659
+ $paymentProfile = SFC_Autoship_Model_Payment_Profile::makePaymentProfileFromVaultData($platformPaymentProfile);
660
+ // Add model to array
661
+ $paymentProfiles[] = $paymentProfile;
662
+ }
663
+
664
+ return $paymentProfiles;
665
+ }
666
+
667
+ /**
668
+ * @param array $response
669
+ * @return SFC_Autoship_Model_Payment_Profile
670
+ */
671
+ protected function parseTransactionFromResponse(array $response)
672
+ {
673
+ // Check that response is well formed
674
+ if (!isset($response['result']) ||
675
+ !isset($response['result']['transaction']) ||
676
+ !is_array($response['result']['transaction'])
677
+ ) {
678
+ Mage::throwException($this->__('API response format error for transaction!'));
679
+ }
680
+ $result = $response['result'];
681
+ $platformTransaction = $result['transaction'];
682
+
683
+ if (isset($platformTransaction['state']) && $platformTransaction['state'] != 'succeeded') {
684
+ // Build error detail string
685
+ $errorDetailString = '';
686
+ if (isset($platformTransaction['id'])) {
687
+ $errorDetailString .= 'Transaction ID: ' . $platformTransaction['id'] . "\n";
688
+ }
689
+ if (isset($platformTransaction['response_message'])) {
690
+ $errorDetailString .= 'Response Message: ' . $platformTransaction['response_message'];
691
+ }
692
+ // Save error details in registry, so we can return it later
693
+ Mage::unregister('subscribepro_transaction_error_detail');
694
+ Mage::register('subscribepro_transaction_error_detail', $errorDetailString);
695
+ }
696
+
697
+ return $platformTransaction;
698
+ }
699
+
700
+ /**
701
+ * @param array $response
702
+ * @return SFC_Autoship_Model_Payment_Profile
703
+ */
704
+ protected function parseTokenFromResponse(array $response)
705
+ {
706
+ // Check that response is well formed
707
+ if (!isset($response['result']) ||
708
+ !isset($response['result']['token']) ||
709
+ !is_array($response['result']['token'])
710
+ ) {
711
+ Mage::throwException($this->__('API response format error for token!'));
712
+ }
713
+ $result = $response['result'];
714
+ $token = $result['token'];
715
+
716
+ return $token;
717
+ }
718
+
719
+ /**
720
+ * @param array $response
721
+ * @param string $defaultMessage
722
+ * @throws Mage_Core_Exception
723
+ * @throws SFC_Autoship_Helper_PaymentError_Exception
724
+ */
725
+ protected function throwErrorResponseException(array $response, $defaultMessage)
726
+ {
727
+ /** @var SFC_Autoship_Helper_PaymentError $errorHelper */
728
+ $errorHelper = Mage::helper('autoship/paymentError');
729
+ // Check that response is well formed
730
+ if (isset($response['result']) &&
731
+ isset($response['result']['errors']) &&
732
+ is_array($response['result']['errors'])
733
+ ) {
734
+ // Get 1st error
735
+ $error = $response['result']['errors'][0];
736
+ if (isset($error['attribute']) && $error['key']) {
737
+ // Get attribute & key
738
+ $attribute = $error['attribute'];
739
+ $key = $error['key'];
740
+ // If attribute and key translate to an error message, throw it in exception
741
+ $message = $errorHelper->getCreditCardErrorMessage($attribute, $key);
742
+ if (strlen($message)) {
743
+ throw new SFC_Autoship_Helper_PaymentError_Exception($message);
744
+ }
745
+ }
746
+ }
747
+
748
+ // Otherwise throw default message
749
+ Mage::throwException($this->__($defaultMessage));
750
+ }
751
+
752
+ protected function throwTransactionErrorException(array $platformTransaction, $defaultMessage)
753
+ {
754
+ /** @var SFC_Autoship_Helper_PaymentError $errorHelper */
755
+ $errorHelper = Mage::helper('autoship/paymentError');
756
+ // Check that response is well formed and has error type
757
+ if (isset($platformTransaction['subscribe_pro_error_type'])) {
758
+ // Map error type
759
+ $message = $errorHelper->getGatewayErrorMessage($platformTransaction['subscribe_pro_error_type']);
760
+ if (strlen($message)) {
761
+ throw new SFC_Autoship_Helper_PaymentError_Exception($message);
762
+ }
763
+ }
764
+
765
+ // Otherwise throw default message
766
+ Mage::throwException($this->__($defaultMessage));
767
+ }
768
+
769
+ }
app/code/local/SFC/Autoship/Model/Api/Cart/Api.php ADDED
@@ -0,0 +1,331 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class SFC_Autoship_Model_Api_Cart_Api extends Mage_Checkout_Model_Api_Resource
4
+ {
5
+
6
+ /**
7
+ * Customer address types
8
+ */
9
+ const ADDRESS_BILLING = Mage_Sales_Model_Quote_Address::TYPE_BILLING;
10
+ const ADDRESS_SHIPPING = Mage_Sales_Model_Quote_Address::TYPE_SHIPPING;
11
+
12
+ /**
13
+ * Customer checkout types
14
+ */
15
+ const MODE_CUSTOMER = Mage_Checkout_Model_Type_Onepage::METHOD_CUSTOMER;
16
+
17
+ /**
18
+ * Set customer on a quote / shopping cart.
19
+ * The Subscribe Pro platform uses this method rather the standard Magento API method: cart_customer.set
20
+ * We use this method to support "find existing customer by ID, email or both" semantics.
21
+ * This method only works to set an existing customer on a quote. This method sets the quote to "customer mode" checkout,
22
+ * I.E. Mage_Checkout_Model_Type_Onepage::METHOD_CUSTOMER
23
+ *
24
+ * @param int $quoteId
25
+ * @param array $customerData
26
+ * @return int
27
+ * @throws Mage_Api_Exception
28
+ */
29
+ public function setCustomer($quoteId, $customerData)
30
+ {
31
+ // Get quote from quote ID
32
+ $quote = $this->_getQuote($quoteId, null);
33
+
34
+ // Check input
35
+ if (!is_array($customerData) || count($customerData) == 0) {
36
+ $this->throwApiFault('sp_cart_customer_format');
37
+ }
38
+
39
+ // Get customer identifying fields
40
+ $customerId = $this->getField($customerData, 'customer_id');
41
+ $email = $this->getField($customerData, 'email');
42
+
43
+ // Check inputs, did we get customer ID, email, both or neither?
44
+ // Lookup customer model
45
+ /** @var Mage_Customer_Model_Customer $customer */
46
+ $customer = Mage::getModel('customer/customer');
47
+ if (!strlen($customerId) && !strlen($email)) {
48
+ $this->throwApiFault('sp_cart_customer_format');
49
+ }
50
+ elseif (strlen($customerId) && !strlen($email)) {
51
+ $customer->load($customerId);
52
+ }
53
+ elseif (!strlen($customerId) && strlen($email)) {
54
+ // Need to set website_id to load a customer by email
55
+ $customer->setData('website_id', $quote->getStore()->getWebsiteId());
56
+ $customer->loadByEmail($email);
57
+ }
58
+ else {
59
+ // $customerId & $email are present
60
+ // Load by ID first
61
+ $customer->load($customerId);
62
+ // Now compare email
63
+ if (strlen($customer->getId()) && $customer->getData('email') != $email) {
64
+ $this->throwApiFault('sp_cart_customer_not_found', "ID: $customerId Email: $email", "Customer not found. Email and customer ID don't match.");
65
+ }
66
+ }
67
+
68
+ // Check customer model
69
+ if (!strlen($customer->getId())) {
70
+ $this->throwApiFault('sp_cart_customer_not_found', "ID: $customerId Email: $email");
71
+ }
72
+
73
+ // Always assume customer mode
74
+ $customer->setData('mode', self::MODE_CUSTOMER);
75
+
76
+ // Attach customer to quote
77
+ // This logic is duplicated from Mage_Checkout_Model_Cart_Customer_Api::set
78
+ try {
79
+ $quote
80
+ ->setCustomer($customer)
81
+ ->setCheckoutMethod($customer->getMode())
82
+ ->setPasswordHash($customer->encryptPassword($customer->getPassword()))
83
+ ->save();
84
+ }
85
+ catch (Mage_Core_Exception $e) {
86
+ $this->throwApiFault('sp_cart_customer_not_set', "ID: $customerId Email: $email", 'Failed to set customer on quote with error: ' . $e->getMessage());
87
+ }
88
+
89
+ return true;
90
+ }
91
+
92
+ /**
93
+ * Set billing and / or shipping addresses on a quote / shopping cart.
94
+ * The Subscribe Pro platform uses this method rather the standard Magento API method: cart_customer.addresses
95
+ * We use this method to get consistent results across many Magneto editions / versions.
96
+ *
97
+ * @param int $quoteId
98
+ * @param array $addressData
99
+ * @return int
100
+ */
101
+ public function setAddresses($quoteId, $addressData)
102
+ {
103
+ // Get quote from quote ID
104
+ $quote = $this->_getQuote($quoteId, null);
105
+
106
+ // Check input
107
+ if (!is_array($addressData) || count($addressData) == 0) {
108
+ $this->throwApiFault('sp_cart_address_format');
109
+ }
110
+
111
+ // Iterate addresses
112
+ foreach ($addressData as $addressItem) {
113
+ // Get mode
114
+ if (!isset($addressItem['mode'])) {
115
+ $this->throwApiFault('sp_cart_address_format');
116
+ }
117
+ $addressMode = $addressItem['mode'];
118
+ if ($addressMode != self::ADDRESS_BILLING && $addressMode != self::ADDRESS_SHIPPING) {
119
+ $this->throwApiFault('sp_cart_address_mode', $addressMode . ' address');
120
+ }
121
+
122
+ // Build a quote address
123
+ /** @var $quoteAddress Mage_Sales_Model_Quote_Address */
124
+ $quoteAddress = Mage::getModel('sales/quote_address');
125
+
126
+ // Map it
127
+ $this->mapAddressDataToQuoteAddress($addressItem, $quoteAddress);
128
+
129
+ // Process and set address on quote
130
+ $this->magentoAddressSettingLogic($quote, $quoteAddress, $addressMode);
131
+ }
132
+
133
+ // Now save quote and addresses
134
+ // This logic is duplicated from Mage_Checkout_Model_Cart_Customer_Api::setAddresses
135
+ try {
136
+ $quote
137
+ ->collectTotals()
138
+ ->save();
139
+ }
140
+ catch (Exception $e) {
141
+ $this->throwApiFault('sp_cart_address_save', 'Error saving addresses for quote: ' . null, $e->getMessage());
142
+ }
143
+
144
+ // We made it here, setting addresses was successful
145
+ return true;
146
+ }
147
+
148
+ /**
149
+ * Map one array of address data into a Mage_Sales_Model_Quote_Address
150
+ *
151
+ * Must pass 'country_id' field in 2 or 3 digit ISO code format.
152
+ * If regions are loaded in Magento directory for the given country:
153
+ * * The region passed in is validated and error is thrown if its an unknown region
154
+ * * Must pass a region name or region code in the 'region' field which matches a region in the Magento DB
155
+ * * The 'region' and 'region_id' fields on the Mage_Sales_Model_Quote_Address will then be populated
156
+ * If no regions are loaded in Magento DB for the specified country:
157
+ * * Must pass region name in the 'region field
158
+ * * 'region' field in Mage_Sales_Model_Quote_Address is populated
159
+ * * 'region_id' field in Mage_Sales_Model_Quote_Address will be NULL
160
+ *
161
+ * @param array $addressItem
162
+ * @param Mage_Sales_Model_Quote_Address $quoteAddress
163
+ * @throws Mage_Api_Exception
164
+ */
165
+ protected function mapAddressDataToQuoteAddress(array $addressItem, Mage_Sales_Model_Quote_Address $quoteAddress)
166
+ {
167
+ // Straight field mapping
168
+ $quoteAddress->setData('firstname', $this->getField($addressItem, 'firstname'));
169
+ $quoteAddress->setData('lastname', $this->getField($addressItem, 'lastname'));
170
+ $quoteAddress->setData('company', $this->getField($addressItem, 'company'));
171
+ $quoteAddress->setData('street', $this->getField($addressItem, 'street'));
172
+ $quoteAddress->setData('city', $this->getField($addressItem, 'city'));
173
+ $quoteAddress->setData('postcode', $this->getField($addressItem, 'postcode'));
174
+ $quoteAddress->setData('telephone', $this->getField($addressItem, 'telephone'));
175
+ $quoteAddress->setData('fax', $this->getField($addressItem, 'fax'));
176
+
177
+ //
178
+ // Map Country
179
+ $countryCode = $this->getField($addressItem, 'country_id');
180
+ // Default to US if no country code specified
181
+ if (!strlen($countryCode)) {
182
+ $countryCode = 'US';
183
+ }
184
+ /** @var Mage_Directory_Model_Country $country */
185
+ $country = Mage::getModel('directory/country');
186
+ $country->loadByCode($countryCode);
187
+ if (!strlen($country->getId())) {
188
+ $this->throwApiFault('sp_cart_address_country_code', $this->getField($addressItem, 'mode') . ' address', "Country code did not match known ISO 2 or 3 digit code: $countryCode");
189
+ }
190
+ // Found a matching country in directory
191
+ $quoteAddress->setData('country_id', $country->getId());
192
+
193
+ //
194
+ // Map region
195
+ $regionName = $this->getField($addressItem, 'region');
196
+ if (strlen($regionName)) {
197
+ // Lookup by region code
198
+ /** @var Mage_Directory_Model_Region $region */
199
+ $region = Mage::getModel('directory/region');
200
+ $region->loadByCode($regionName, $countryCode);
201
+ if (!strlen($region->getId())) {
202
+ // Lookup by region name
203
+ $region->loadByName($regionName, $countryCode);
204
+ }
205
+ // If we found a region, assign it
206
+ if (strlen($region->getId())) {
207
+ $quoteAddress->setData('region_id', $region->getId());
208
+ $quoteAddress->setData('region', $region->getName());
209
+ }
210
+ else {
211
+ // We didn't find the region in DB, just assign it verbatim
212
+ $quoteAddress->setData('region', $regionName);
213
+ }
214
+ }
215
+ }
216
+
217
+ /**
218
+ * @param array $data
219
+ * @param $fieldName
220
+ * @return null
221
+ */
222
+ protected function getField(array $data, $fieldName)
223
+ {
224
+ if (!isset($data[$fieldName]) || !strlen($data[$fieldName])) {
225
+ return null;
226
+ }
227
+ else {
228
+ return $data[$fieldName];
229
+ }
230
+ }
231
+
232
+ /**
233
+ * Logic which gets applied after setting address on quote
234
+ * This was taken from Mage_Checkout_Model_Cart_Customer_Api::setAddresses in Magento CE 1.9.x
235
+ *
236
+ * @param Mage_Sales_Model_Quote $quote
237
+ * @param Mage_Sales_Model_Quote_Address $address
238
+ * @param $addressMode
239
+ * @throws Mage_Api_Exception
240
+ */
241
+ protected function magentoAddressSettingLogic(Mage_Sales_Model_Quote $quote, Mage_Sales_Model_Quote_Address $address, $addressMode)
242
+ {
243
+ // Implode it
244
+ $address->implodeStreetAddress();
245
+
246
+ // Validate it
247
+ if (($validateRes = $address->validate())!==true) {
248
+ $this->throwApiFault('sp_cart_address_validation', $addressMode . ' address', implode(PHP_EOL, $validateRes));
249
+ }
250
+
251
+ // Save it to quote
252
+ switch($addressMode) {
253
+ case self::ADDRESS_BILLING:
254
+ $address->setEmail($quote->getCustomer()->getEmail());
255
+
256
+ if (!$quote->isVirtual()) {
257
+ $usingCase = isset($addressItem['use_for_shipping']) ? (int)$addressItem['use_for_shipping'] : 0;
258
+ switch($usingCase) {
259
+ case 0:
260
+ $shippingAddress = $quote->getShippingAddress();
261
+ $shippingAddress->setSameAsBilling(0);
262
+ break;
263
+ case 1:
264
+ $billingAddress = clone $address;
265
+ $billingAddress->unsAddressId()->unsAddressType();
266
+
267
+ $shippingAddress = $quote->getShippingAddress();
268
+ $shippingMethod = $shippingAddress->getShippingMethod();
269
+ $shippingAddress->addData($billingAddress->getData())
270
+ ->setSameAsBilling(1)
271
+ ->setShippingMethod($shippingMethod)
272
+ ->setCollectShippingRates(true);
273
+ break;
274
+ }
275
+ }
276
+ $quote->setBillingAddress($address);
277
+ break;
278
+
279
+ case self::ADDRESS_SHIPPING:
280
+ $address->setCollectShippingRates(true)
281
+ ->setSameAsBilling(0);
282
+ $quote->setShippingAddress($address);
283
+ break;
284
+ }
285
+
286
+ }
287
+
288
+ /**
289
+ * Dispatches fault
290
+ *
291
+ * @param int $code
292
+ * @param null|string $customMessage
293
+ * @param null|string $customMessageParenthetical
294
+ * @throws Mage_Api_Exception
295
+ */
296
+ protected function throwApiFault($code, $customMessageParenthetical = null, $customMessage = null)
297
+ {
298
+ // Process custom message
299
+ if (strlen($customMessage)) {
300
+ $message = $customMessage;
301
+ }
302
+ else {
303
+ $faults = $this->_getConfig()->getFaults('sp_cart');
304
+ if (!is_array($faults) || !isset($faults[$code])) {
305
+ throw new Mage_Api_Exception('unknown');
306
+ }
307
+ $message = isset($faults[$code]['message']) ? $faults[$code]['message'] : '';
308
+ }
309
+
310
+ // Add parenthetical
311
+ if (strlen($customMessageParenthetical)) {
312
+ $message = "($customMessageParenthetical) " . $message;
313
+ }
314
+
315
+ // Add SP API message tag
316
+ $message = Mage::helper("autoship")->__('Subscribe Pro API: %s', $message);
317
+
318
+ throw new Mage_Api_Exception($code, $message);
319
+ }
320
+
321
+ /**
322
+ * Retrieve webservice configuration
323
+ *
324
+ * @return Mage_Api_Model_Config
325
+ */
326
+ protected function _getConfig()
327
+ {
328
+ return Mage::getSingleton('api/config');
329
+ }
330
+
331
+ }
app/code/local/SFC/Autoship/Model/Checkout/Cart/Api.php CHANGED
@@ -1,4 +1,4 @@
1
- <?php //00612
2
  /**
3
  * Subscribe Pro - Subscriptions Management Extension
4
  *
@@ -14,49 +14,63 @@
14
  * @link http://www.subscribepro.com/
15
  *
16
  */
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
17
 
18
- if(!extension_loaded('ionCube Loader')){$__oc=strtolower(substr(php_uname(),0,3));$__ln='/ioncube/ioncube_loader_'.$__oc.'_'.substr(phpversion(),0,3).(($__oc=='win')?'.dll':'.so');$__oid=$__id=realpath(ini_get('extension_dir'));$__here=dirname(__FILE__);if((@$__id[1])==':'){$__id=str_replace('\\','/',substr($__id,2));$__here=str_replace('\\','/',substr($__here,2));}$__rd=str_repeat('/..',substr_count($__id,'/')).$__here.'/';$__i=strlen($__rd);while($__i--){if($__rd[$__i]=='/'){$__lp=substr($__rd,0,$__i).$__ln;if(file_exists($__oid.$__lp)){$__ln=$__lp;break;}}}@dl($__ln);}else{die('The file '.__FILE__." is corrupted. Ensure that you use binary mode when transferring files with FTP and disable the 'TAR smart cr/lf feature' if using WinZIP\n");}if(function_exists('_il_exec')){return _il_exec();}die('The file <b>'.__FILE__.'</b> has been encoded with the <a href="http://www.ioncube.com">ionCube PHP Encoder</a> and requires the free '.basename($__ln).' <a href="http://www.ioncube.com/loader_download/">ionCube PHP Loader</a> to be installed.');
19
-
20
- ?>
21
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- +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
- 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
- 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
- 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
- yWIq1GG6VcVX84XMt4Rg7uHcMpe0jDB+Y4tQ6z1vbFxF60TNdK8YGfPtJqB4klbqijJCXJ0CySDr
46
- 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
- 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
- kox3ndQ3ZXh7b1Cr5hs57j8b7g7LZYRyp+c1wo+7P1Mcj/dsyn7rHaWEtpLLVn06L7GRZxmcoDn2
49
- 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
- 30A+59KD1X0HQWvT1B3yyKfiJjVI6fd+L0BqiZ/uuhT+gicrXKkAATKI/byYZD/ltas705a9x29D
51
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
62
- qzQY+HepE0==
1
+ <?php
2
  /**
3
  * Subscribe Pro - Subscriptions Management Extension
4
  *
14
  * @link http://www.subscribepro.com/
15
  *
16
  */
17
+ /**
18
+ * Shopping cart api
19
+ *
20
+ * Override this class and handle passing existing payment tokens to various payment methods.
21
+ *
22
+ */
23
+
24
+ class SFC_Autoship_Model_Checkout_Cart_Api extends Mage_Checkout_Model_Cart_Api
25
+ {
26
+
27
+ /**
28
+ * Create an order from the shopping cart (quote)
29
+ *
30
+ * @param $quoteId
31
+ * @param $store
32
+ * @param $agreements array
33
+ * @return string
34
+ */
35
+ public function createOrder($quoteId, $store = null, $agreements = null)
36
+ {
37
+ // Quote helper to handle this event
38
+ /** @var SFC_Autoship_Helper_Quote $quoteHelper */
39
+ $quoteHelper = Mage::helper('autoship/quote');
40
+
41
+ // Get quote
42
+ $quote = $this->_getQuote($quoteId, $store);
43
+ if (empty($store)) {
44
+ $store = $quote->getStoreId();
45
+ }
46
+
47
+ // Check config to see if extension functionality is enabled
48
+ if (Mage::getStoreConfig('autoship_general/general/enabled', $store) != '1') {
49
+ return parent::createOrder($quoteId, $store, $agreements);
50
+ }
51
+
52
+ // Fire event indicating a subscription re-order
53
+ if ($quoteHelper->hasSubscriptionReorderProduct($quote)) {
54
+ Mage::dispatchEvent('sfc_autoship_before_subscription_reorder_place',
55
+ array('quote_id' => $quoteId, 'quote' => $quote));
56
+ }
57
+
58
+ try {
59
+ // Call parent
60
+ return parent::createOrder($quoteId, $store, $agreements);
61
+ }
62
+ catch (\Mage_Api_Exception $apiException) {
63
+ // In case of exception, look for transaction error detail in registry
64
+ $errorDetailString = Mage::registry('subscribepro_transaction_error_detail');
65
+ // Build new customer message with error detail
66
+ $customMessage = $apiException->getCustomMessage();
67
+ if (strlen($errorDetailString)) {
68
+ $customMessage = "Credit card transaction failed!\n" . $errorDetailString;
69
+ }
70
+ // Rethrow exception with more detailed error message
71
+ $this->_fault($apiException->getMessage(), $customMessage);
72
+ }
73
+ }
74
+
75
 
76
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/code/local/SFC/Autoship/Model/Checkout/Cart/Payment/Api.php DELETED
@@ -1,57 +0,0 @@
1
- <?php //00612
2
- /**
3
- * Subscribe Pro - Subscriptions Management Extension
4
- *
5
- * PHP version 5
6
- *
7
- * LICENSE: This source file is subject to commercial source code license of SUBSCRIBE PRO INC.
8
- *
9
- * @category SFC
10
- * @package SFC_Autoship
11
- * @author Garth Brantley <garth@subscribepro.com>
12
- * @copyright 2009-2014 SUBSCRIBE PRO INC. All Rights Reserved.
13
- * @license http://www.subscribepro.com/terms-of-service/ Subscribe Pro Terms of Service
14
- * @link http://www.subscribepro.com/
15
- *
16
- */
17
-
18
- if(!extension_loaded('ionCube Loader')){$__oc=strtolower(substr(php_uname(),0,3));$__ln='/ioncube/ioncube_loader_'.$__oc.'_'.substr(phpversion(),0,3).(($__oc=='win')?'.dll':'.so');$__oid=$__id=realpath(ini_get('extension_dir'));$__here=dirname(__FILE__);if((@$__id[1])==':'){$__id=str_replace('\\','/',substr($__id,2));$__here=str_replace('\\','/',substr($__here,2));}$__rd=str_repeat('/..',substr_count($__id,'/')).$__here.'/';$__i=strlen($__rd);while($__i--){if($__rd[$__i]=='/'){$__lp=substr($__rd,0,$__i).$__ln;if(file_exists($__oid.$__lp)){$__ln=$__lp;break;}}}@dl($__ln);}else{die('The file '.__FILE__." is corrupted. Ensure that you use binary mode when transferring files with FTP and disable the 'TAR smart cr/lf feature' if using WinZIP\n");}if(function_exists('_il_exec')){return _il_exec();}die('The file <b>'.__FILE__.'</b> has been encoded with the <a href="http://www.ioncube.com">ionCube PHP Encoder</a> and requires the free '.basename($__ln).' <a href="http://www.ioncube.com/loader_download/">ionCube PHP Loader</a> to be installed.');
19
-
20
- ?>
21
- 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
- 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
- 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
- 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
- toOncMQlLd7k/eQ2F/U+/tXMhH6iN3ii30Ov9GA/1mjuNQ58uTxav6vs3Wx7msEQFuZyB8m8C1G1
26
- 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
- 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
- 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
- ltuph9jHbTY9SkePG60jW1nt5bQ5ilQzd7Xqj9rKZVs37YiergsPjKOdk5DOi95aXnGsmXS2fExa
30
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- M4UtbXm0Y66fzNuJFzvwW395qHsGuBDcyO1Zbvs09PPNTY+9ulhxzhNJLKM7FVC2n3RASllJL0Fn
42
- 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
- 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
- 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
- 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
- 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
- DdGKo7XkahiFQifL78BtGyC5B6akhuzkYClTyCScIbrYEzv1GXFnw9ISuvFnauA1WEyABR+cV1cY
48
- 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
- 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
- f/6xmEnfXGzGAYA56/rZDEmKIpJTImBWmAC6QBNEdhjV/DjJj++d6kW5OUPumm3tPjiefe0zgj7J
51
- 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
- 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
- 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
- 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
- 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
- 7XcG8phvcKGghfyPbiw6G/UD0p9rmcymHZiwe9uNmzmPFyQsu5t0rzJQhXNlnusWGm/CAQN+HZVe
57
- 4e5UxsrpHJKl1CpvylAvrABYT0==
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/code/local/SFC/Autoship/Model/Checkout/Cart/Product/Api.php CHANGED
@@ -1,4 +1,4 @@
1
- <?php //00612
2
  /**
3
  * Subscribe Pro - Subscriptions Management Extension
4
  *
@@ -14,93 +14,205 @@
14
  * @link http://www.subscribepro.com/
15
  *
16
  */
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
17
 
18
- if(!extension_loaded('ionCube Loader')){$__oc=strtolower(substr(php_uname(),0,3));$__ln='/ioncube/ioncube_loader_'.$__oc.'_'.substr(phpversion(),0,3).(($__oc=='win')?'.dll':'.so');$__oid=$__id=realpath(ini_get('extension_dir'));$__here=dirname(__FILE__);if((@$__id[1])==':'){$__id=str_replace('\\','/',substr($__id,2));$__here=str_replace('\\','/',substr($__here,2));}$__rd=str_repeat('/..',substr_count($__id,'/')).$__here.'/';$__i=strlen($__rd);while($__i--){if($__rd[$__i]=='/'){$__lp=substr($__rd,0,$__i).$__ln;if(file_exists($__oid.$__lp)){$__ln=$__lp;break;}}}@dl($__ln);}else{die('The file '.__FILE__." is corrupted. Ensure that you use binary mode when transferring files with FTP and disable the 'TAR smart cr/lf feature' if using WinZIP\n");}if(function_exists('_il_exec')){return _il_exec();}die('The file <b>'.__FILE__.'</b> has been encoded with the <a href="http://www.ioncube.com">ionCube PHP Encoder</a> and requires the free '.basename($__ln).' <a href="http://www.ioncube.com/loader_download/">ionCube PHP Loader</a> to be installed.');
19
-
20
- ?>
21
- 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
- cWwREPWP1bA0Ur9lrllB7F0U0g5tetxnDlaMjc8igxinzvjp6xMct+yEI6pL3w1Ae75jBIDuACih
23
- jXB+qk8Ry1VM/zA33ePGTuF7i0Qgvc82HzKQCluhuD95EwJGO4G2TlowfrOQCCtlZwzozz/Pvc2X
24
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- tSyhBMM/JpJNEWj+x5bRngK866x+P7QRvhziCfG/rieKTbi/45qzsodAy6RExFx8mXR44zR2q5Ee
33
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- enpaqXLglWZkILrVLwy4Fv0tGybhWh5s2b82wH0pZMNUIK50PGDrVHU0Ik/X7hGb/h7VuPq9wp2Q
42
- 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
- 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
- bK9Yb8bjAVDZD4vRUIs+FUaIYshkm0JekPDZJF+JiR3Z7pZmaO+EZQ0o4XSwjcqQUlgPIsrfQv3U
45
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- YH/dLOkcQU1zboHvLg2kk8kppbLpLN6SjgCTdVK222ebL6eYvjJui2m8WOviSJQWjiI6eV5LOyNh
61
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- mK5Iq57AMLuzyGjKGmKFHRZymUeepDDqB0dFLlIi6uaPJnjqtb/YPvImHEo5HeBMXcdRGu2hVGvI
72
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
1
+ <?php
2
  /**
3
  * Subscribe Pro - Subscriptions Management Extension
4
  *
14
  * @link http://www.subscribepro.com/
15
  *
16
  */
17
+ /**
18
+ * Shopping cart api for product
19
+ *
20
+ * Override this class and add the 'no_discount' and 'custom_price' options for product request,
21
+ * these options behave the same way those fields do in the admin ordering grid.
22
+ *
23
+ */
24
+
25
+ class SFC_Autoship_Model_Checkout_Cart_Product_Api extends Mage_Checkout_Model_Cart_Product_Api
26
+ {
27
+
28
+ /**
29
+ * @param $quoteId
30
+ * @param $productsData
31
+ * @param $store
32
+ * @return bool
33
+ */
34
+ public function add($quoteId, $productsData, $store = null)
35
+ {
36
+ $quote = $this->_getQuote($quoteId, $store);
37
+ if (empty($store)) {
38
+ $store = $quote->getStoreId();
39
+ }
40
+
41
+ // Check config to see if extension functionality is enabled
42
+ if (Mage::getStoreConfig('autoship_general/general/enabled', $store) != '1') {
43
+ return parent::add($quoteId, $productsData, $store);
44
+ }
45
+
46
+ $productsData = $this->_prepareProductsData($productsData);
47
+ if (empty($productsData)) {
48
+ $this->_fault('invalid_product_data');
49
+ }
50
+
51
+ $errors = array();
52
+ foreach ($productsData as $productItem) {
53
+ if (isset($productItem['product_id'])) {
54
+ $productByItem = $this->_getProduct($productItem['product_id'], $store, 'id');
55
+ }
56
+ else {
57
+ if (isset($productItem['sku'])) {
58
+ /* SFC Changes - Workaround for earlier Magento versions that can't get product by the sku - Starts Here */
59
+ // Magento bug is in Mage_Catalog_Helper_Product::getProduct method
60
+ $sku = $productItem['sku'];
61
+ // Lookup product id by sku
62
+ $productId = Mage::getModel('catalog/product')->getIdBySku($sku);
63
+ if ($productId <= 0) {
64
+ $this->_fault('add_product_fault', Mage::helper("autoship")->__('Failed to find product with SKU: %s', $sku));
65
+ }
66
+ $productByItem = $this->_getProduct($productId, $store, 'id');
67
+ if (!$productByItem instanceof Mage_Catalog_Model_Product) {
68
+ $this->_fault('add_product_fault', Mage::helper("autoship")->__('Failed to find product with SKU: %s', $sku));
69
+ }
70
+ /* SFC Changes - Workaround for earlier Magento versions that can't get product by the sku - Ends Here */
71
+ }
72
+ else {
73
+ $errors[] = Mage::helper('checkout')->__('One item of products do not have identifier or sku');
74
+ continue;
75
+ }
76
+ }
77
+
78
+ $productRequest = $this->_getProductRequest($productItem);
79
+ try {
80
+ $result = $quote->addProduct($productByItem, $productRequest);
81
+ if (is_string($result)) {
82
+ Mage::throwException($result);
83
+ }
84
+ /* SFC Changes / Additions - Start Here */
85
+ $quoteItem = $result;
86
+ // In the case of bundle products, make sure we grab the parent quote item
87
+ if($quoteItem->getParentItem() != null && $quoteItem->getParentItem()->getProductType() == 'bundle') {
88
+ $quoteItem = $quoteItem->getParentItem();
89
+ }
90
+ // Now set custom attributes on quote item
91
+ if (isset($productRequest['custom_price'])) {
92
+ $quoteItem->setCustomPrice($productRequest['custom_price']);
93
+ $quoteItem->setOriginalCustomPrice($productRequest['custom_price']);
94
+ }
95
+ if (isset($productRequest['no_discount'])) {
96
+ $quoteItem->setNoDiscount($productRequest['no_discount']);
97
+ }
98
+ // Save subscription flag and id from API created orders
99
+ if (isset($productRequest['item_fulfils_subscription'])) {
100
+ $quoteItem->setData('item_fulfils_subscription', $productRequest['item_fulfils_subscription']);
101
+ }
102
+ if (isset($productRequest['subscription_id'])) {
103
+ $quoteItem->setData('subscription_id', $productRequest['subscription_id']);
104
+ }
105
+ if (isset($productRequest['subscription_interval'])) {
106
+ $quoteItem->setData('subscription_interval', $productRequest['subscription_interval']);
107
+ }
108
+ /* SFC Changes / Additions - End Here */
109
+ }
110
+ catch (Mage_Core_Exception $e) {
111
+ $errors[] = $e->getMessage();
112
+ }
113
+ }
114
+
115
+ if (!empty($errors)) {
116
+ $this->_fault('add_product_fault', implode(PHP_EOL, $errors));
117
+ }
118
+
119
+ try {
120
+ $quote->collectTotals()->save();
121
+ }
122
+ catch (Exception $e) {
123
+ $this->_fault('add_product_quote_save_fault', $e->getMessage());
124
+ }
125
+
126
+ return true;
127
+ }
128
+
129
+ /**
130
+ * @param $quoteId
131
+ * @param $productsData
132
+ * @param $store
133
+ * @return bool
134
+ */
135
+ public function update($quoteId, $productsData, $store = null)
136
+ {
137
+ $quote = $this->_getQuote($quoteId, $store);
138
+ if (empty($store)) {
139
+ $store = $quote->getStoreId();
140
+ }
141
+
142
+ // Check config to see if extension functionality is enabled
143
+ if (Mage::getStoreConfig('autoship_general/general/enabled', $store) != '1') {
144
+ return parent::update($quoteId, $productsData, $store);
145
+ }
146
+
147
+ $productsData = $this->_prepareProductsData($productsData);
148
+ if (empty($productsData)) {
149
+ $this->_fault('invalid_product_data');
150
+ }
151
+
152
+ $errors = array();
153
+ foreach ($productsData as $productItem) {
154
+ if (isset($productItem['product_id'])) {
155
+ $productByItem = $this->_getProduct($productItem['product_id'], $store, 'id');
156
+ }
157
+ else {
158
+ if (isset($productItem['sku'])) {
159
+ $productByItem = $this->_getProduct($productItem['sku'], $store, 'sku');
160
+ }
161
+ else {
162
+ $errors[] = Mage::helper('checkout')->__('One item of products do not have identifier or sku');
163
+ continue;
164
+ }
165
+ }
166
+
167
+ /** @var $quoteItem Mage_Sales_Model_Quote_Item */
168
+ $quoteItem = $this->_getQuoteItemByProduct($quote, $productByItem,
169
+ $this->_getProductRequest($productItem));
170
+ if (is_null($quoteItem->getId())) {
171
+ $errors[] = Mage::helper('checkout')->__('One item of products is not belong any of quote item');
172
+ continue;
173
+ }
174
+
175
+ if ($productItem['qty'] > 0) {
176
+ $quoteItem->setQty($productItem['qty']);
177
+ }
178
+
179
+ /* SFC Changes / Additions - Start Here */
180
+ $productRequest = $this->_getProductRequest($productItem);
181
+ if (isset($productRequest['custom_price'])) {
182
+ $quoteItem->setCustomPrice($productRequest['custom_price']);
183
+ $quoteItem->setOriginalCustomPrice($productRequest['custom_price']);
184
+ }
185
+ if (isset($productRequest['no_discount'])) {
186
+ $quoteItem->setNoDiscount($productRequest['no_discount']);
187
+ }
188
+ // TODO: It would be ideal if we can get the additional_options from buy request into additional_options option field in
189
+ // the quote item at time quote item is created
190
+ // Currently this isn't working:
191
+ /*
192
+ if (isset($productRequest['additional_options'])) {
193
+ $quoteItem->addOption(array(
194
+ 'code' => 'additional_options',
195
+ 'product_id' => $quoteItem->getProductId(),
196
+ 'value' => serialize($productRequest['additional_options'])
197
+ )
198
+ );
199
+ }
200
+ */
201
+ /* SFC Changes / Additions - End Here */
202
+ }
203
+
204
+ if (!empty($errors)) {
205
+ $this->_fault('update_product_fault', implode(PHP_EOL, $errors));
206
+ }
207
+
208
+ try {
209
+ $quote->save();
210
+ }
211
+ catch (Exception $e) {
212
+ $this->_fault('update_product_quote_save_fault', $e->getMessage());
213
+ }
214
+
215
+ return true;
216
+ }
217
 
218
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/code/local/SFC/Autoship/Model/Observer.php CHANGED
@@ -66,25 +66,22 @@ class SFC_Autoship_Model_Observer
66
  // Get data from $observer
67
  $product = $observer->getData('product');
68
 
69
- // Check if this is a grouped product or simple
70
  $productType = $product->getTypeId();
71
 
72
  // Call helper to handle this event
73
  /** @var SFC_Autoship_Helper_Quote $quoteHelper */
74
  $quoteHelper = Mage::helper('autoship/quote');
75
  // Check product type
76
- if ($productType == Mage_Catalog_Model_Product_Type::TYPE_SIMPLE) {
77
- $quoteHelper->onCheckoutCartAddProductComplete($product);
78
- }
79
- else if ($productType == Mage_Catalog_Model_Product_Type::TYPE_CONFIGURABLE) {
80
- $quoteHelper->onCheckoutCartAddProductComplete($product);
81
  }
82
- else if ($productType == Mage_Catalog_Model_Product_Type::TYPE_BUNDLE) {
 
 
 
83
  $quoteHelper->onCheckoutCartAddProductComplete($product);
84
  }
85
- else if ($productType == Mage_Catalog_Model_Product_Type::TYPE_GROUPED) {
86
- $quoteHelper->onCheckoutCartAddGroupedProductComplete($product);
87
- }
88
 
89
  }
90
 
@@ -232,18 +229,6 @@ class SFC_Autoship_Model_Observer
232
  public function onSalesQuoteAddressDiscountItem(Varien_Event_Observer $observer)
233
  {
234
  Mage::log('SFC_Autoship_Model_Observer::onSalesQuoteAddressDiscountItem', Zend_Log::INFO, SFC_Autoship_Helper_Data::LOG_FILE);
235
-
236
- // When we enter this method (triggered by event):
237
- // The discount is being calculated by Mage_SalesRule_Model_Quote_Discount class.
238
- // In the case of parent products on the quote (the only ones we're concerned about as long as we only support simple products):
239
- // The discount has not yet been calculated using cart rule
240
- // The discount has not yet been applied to the address
241
- // In the case of child product on the quote:
242
- // The discount has already been calculate on quote address item and set in these fields:
243
- // $item->getDiscountAmount();
244
- // $item->getBaseDiscountAmount();
245
- // The discount has not yet been applied to the address
246
- //
247
  }
248
 
249
  /**
@@ -278,4 +263,153 @@ class SFC_Autoship_Model_Observer
278
  return $this;
279
  }
280
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
281
  }
66
  // Get data from $observer
67
  $product = $observer->getData('product');
68
 
69
+ // Get product type
70
  $productType = $product->getTypeId();
71
 
72
  // Call helper to handle this event
73
  /** @var SFC_Autoship_Helper_Quote $quoteHelper */
74
  $quoteHelper = Mage::helper('autoship/quote');
75
  // Check product type
76
+ if ($productType == Mage_Catalog_Model_Product_Type::TYPE_GROUPED) {
77
+ $quoteHelper->onCheckoutCartAddGroupedProductComplete($product);
 
 
 
78
  }
79
+ //else if ($productType == Mage_Catalog_Model_Product_Type::TYPE_SIMPLE) {
80
+ //else if ($productType == Mage_Catalog_Model_Product_Type::TYPE_CONFIGURABLE) {
81
+ //else if ($productType == Mage_Catalog_Model_Product_Type::TYPE_BUNDLE) {
82
+ else {
83
  $quoteHelper->onCheckoutCartAddProductComplete($product);
84
  }
 
 
 
85
 
86
  }
87
 
229
  public function onSalesQuoteAddressDiscountItem(Varien_Event_Observer $observer)
230
  {
231
  Mage::log('SFC_Autoship_Model_Observer::onSalesQuoteAddressDiscountItem', Zend_Log::INFO, SFC_Autoship_Helper_Data::LOG_FILE);
 
 
 
 
 
 
 
 
 
 
 
 
232
  }
233
 
234
  /**
263
  return $this;
264
  }
265
 
266
+ /**
267
+ * @param Varien_Event_Observer $observer
268
+ * @return $this
269
+ */
270
+ public function onAdminhtmlSalesOrderCreateProcessData(Varien_Event_Observer $observer)
271
+ {
272
+ /** @var Mage_Adminhtml_Model_Sales_Order_Create $orderCreateModel */
273
+ $orderCreateModel = $observer->getEvent()->getOrderCreateModel();
274
+
275
+ // Check config to see if extension functionality is enabled
276
+ if (Mage::getStoreConfig('autoship_general/general/enabled', $orderCreateModel->getQuote()->getStore()) != '1') {
277
+ return $this;
278
+ }
279
+
280
+ //If request has 'item' present, we have updated, added, or removed an item
281
+ if (Mage::app()->getRequest()->has('item')) {
282
+
283
+ //Update all quote item
284
+ Mage::helper("autoship/quote")->updateQuoteItems($orderCreateModel->getQuote(), Mage::app()->getRequest()->getPost('item'), true);
285
+
286
+ $action = Mage::app()->getRequest()->getActionName();
287
+
288
+ if (!Mage::app()->getRequest()->getPost('update_items') && !($action == 'save')) {
289
+
290
+ //Process all newly added items, so we can set their defaults
291
+ foreach (Mage::app()->getRequest()->getPost('item') as $productId => $config) {
292
+ //Validation on the product id has already been done at this point
293
+ $config['qty'] = isset($config['qty']) ? (float)$config['qty'] : 1;
294
+ $product = Mage::getModel('catalog/product')
295
+ ->setStore($orderCreateModel->getQuote()->getStore())
296
+ ->setStoreId($orderCreateModel->getQuote()->getStore()->getId())
297
+ ->load($productId);
298
+
299
+ $cartProduct = $product;
300
+
301
+ if ($cartProduct->getTypeId() == Mage_Catalog_Model_Product_Type::TYPE_BUNDLE) {
302
+ //In order to ensure the custom options match from product<-->quote item, we run it through prepareForCartAdvanced
303
+ $cartCandidates = $product->getTypeInstance(true)
304
+ ->prepareForCartAdvanced(new Varien_Object($config), $product, null);
305
+
306
+ if (sizeof($cartCandidates) < 1) {
307
+ Mage::throwException("Unable to add bundle product with sku: " . $product->getSku() . ' to cart');
308
+ }
309
+
310
+ /** @var Mage_Catalog_Model_Product $candidate */
311
+ foreach($cartCandidates as $candidate) {
312
+ //Ensure we get the bundled product
313
+ if ($candidate->getTypeId() == Mage_Catalog_Model_Product_Type::TYPE_BUNDLE) {
314
+ $cartProduct = $candidate;
315
+ break;
316
+ }
317
+ }
318
+ }
319
+
320
+ //Different logic for grouped
321
+ if ($cartProduct->getTypeId() == Mage_Catalog_Model_Product_Type::TYPE_GROUPED) {
322
+ Mage::helper("autoship/quote")->onCheckoutCartAddGroupedProductComplete($cartProduct, $config);
323
+ } else {
324
+ Mage::helper("autoship/quote")->onCheckoutCartAddProductComplete($cartProduct, $config);
325
+ }
326
+ }
327
+ }
328
+
329
+ //Recollect
330
+ $orderCreateModel->recollectCart();
331
+
332
+ }
333
+
334
+ return $this;
335
+ }
336
+
337
+ /**
338
+ * When a customer is saved, check if they exist on the platform. If so, update the platform with their data
339
+ * @param $obs
340
+ * @return $this
341
+ */
342
+ public function onCustomerSave($obs)
343
+ {
344
+ /** @var Mage_Customer_Model_Customer $customer */
345
+ $customer = $obs->getCustomer();
346
+ //Make sure the customer isn't brand new and actually has an original email
347
+ if (!$customer->isObjectNew()
348
+ && $customer->getOrigData('email')
349
+ && $customer->dataHasChangedFor('email')) {
350
+
351
+ /** @var SFC_Autoship_Helper_Platform $platformHelper */
352
+ $platformHelper = Mage::helper("autoship/platform");
353
+
354
+ /** @var SFC_Autoship_Helper_Api $apiHelper */
355
+ $apiHelper = Mage::helper("autoship/api");
356
+
357
+ //Update config store to match store customer is associated to?
358
+ $apiHelper->setConfigStore($customer->getStore());
359
+
360
+ $platformCustomer = $platformHelper->getCustomer($customer->getOrigData('email'));
361
+ if ($platformCustomer) {
362
+ Mage::log('SFC_Autoship_Model_Observer::onCustomerSave Customer with email: ' . $customer->getEmail() . ' was changed, updating platform', Zend_Log::INFO, SFC_Autoship_Helper_Data::LOG_FILE);
363
+ $platformHelper->updateCustomer($platformCustomer['id'], $customer);
364
+ } else {
365
+ Mage::log('SFC_Autoship_Model_Observer::onCustomerSave Customer with email: ' . $customer->getEmail() . ' was changed, but does not exist on platform', Zend_Log::INFO, SFC_Autoship_Helper_Data::LOG_FILE);
366
+ }
367
+ }
368
+ return $this;
369
+ }
370
+
371
+ /**
372
+ * When re-ordering via admin, ensure we don't copy another subscription's id over
373
+ * @see Mage_Adminhtml_Model_Sales_Order_Create::initFromOrderItem
374
+ * @param $observer
375
+ */
376
+ public function onSalesConvertOrderItemToQuoteItem($observer)
377
+ {
378
+ /** @var Mage_Sales_Model_Quote_Item $item */
379
+ $item = $observer->getQuoteItem();
380
+
381
+ // For bundled product, only 1 item will be passed to the observer
382
+ // This item *might* be the bundled product or it might not be
383
+ // If it's not, go ahead and grab the bundled product from the parent
384
+ // Seems to be a bug in magento, @see Mage_Adminhtml_Model_Sales_Order_Create::initFromOrderItem
385
+ if ($item->getParentItem() && $item->getParentItem()->getProduct()->getTypeId() == Mage_Catalog_Model_Product_Type::TYPE_BUNDLE) {
386
+ $item = $item->getParentItem();
387
+ }
388
+ /** @var SFC_Autoship_Helper_Product $productHelper */
389
+ $productHelper = Mage::helper('autoship/product');
390
+
391
+ $product = $item->getProduct();
392
+
393
+ // Check if product is enabled, otherwise don't bother updating the custom options
394
+ if (!$productHelper->isAvailableForSubscription($product, $item->getQuote()->getStore())) {
395
+ return;
396
+ }
397
+
398
+ //Remove the subscription, so re-ordering doesn't result in 2 subscription ids
399
+ $item->removeOption('additional_options');
400
+ $item->setSubscriptionId(null)->save();
401
+
402
+ //Set basic config
403
+ $config = array(
404
+ 'qty' => $item->getQty()
405
+ );
406
+
407
+ //Different logic for grouped
408
+ if ($product->getTypeId() == Mage_Catalog_Model_Product_Type::TYPE_GROUPED) {
409
+ Mage::helper("autoship/quote")->onCheckoutCartAddGroupedProductComplete($product, $config);
410
+ } else {
411
+ Mage::helper("autoship/quote")->onCheckoutCartAddProductComplete($product, $config);
412
+ }
413
+ }
414
+
415
  }
app/code/local/SFC/Autoship/Model/Payment/Method.php CHANGED
@@ -1,4 +1,4 @@
1
- <?php //00612
2
  /**
3
  * Subscribe Pro - Subscriptions Management Extension
4
  *
@@ -13,255 +13,842 @@
13
  * @license http://www.subscribepro.com/terms-of-service/ Subscribe Pro Terms of Service
14
  * @link http://www.subscribepro.com/
15
  *
 
 
 
16
  */
17
 
18
- if(!extension_loaded('ionCube Loader')){$__oc=strtolower(substr(php_uname(),0,3));$__ln='/ioncube/ioncube_loader_'.$__oc.'_'.substr(phpversion(),0,3).(($__oc=='win')?'.dll':'.so');$__oid=$__id=realpath(ini_get('extension_dir'));$__here=dirname(__FILE__);if((@$__id[1])==':'){$__id=str_replace('\\','/',substr($__id,2));$__here=str_replace('\\','/',substr($__here,2));}$__rd=str_repeat('/..',substr_count($__id,'/')).$__here.'/';$__i=strlen($__rd);while($__i--){if($__rd[$__i]=='/'){$__lp=substr($__rd,0,$__i).$__ln;if(file_exists($__oid.$__lp)){$__ln=$__lp;break;}}}@dl($__ln);}else{die('The file '.__FILE__." is corrupted. Ensure that you use binary mode when transferring files with FTP and disable the 'TAR smart cr/lf feature' if using WinZIP\n");}if(function_exists('_il_exec')){return _il_exec();}die('The file <b>'.__FILE__.'</b> has been encoded with the <a href="http://www.ioncube.com">ionCube PHP Encoder</a> and requires the free '.basename($__ln).' <a href="http://www.ioncube.com/loader_download/">ionCube PHP Loader</a> to be installed.');
19
-
20
- ?>
21
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- INckXwH87t6uimnprp0QArhfNNDFhkax/L1f/S3GrqYku4bhX30I/zyNZkVbCDqVy1XAvO1c6uG5
30
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- WSZ/84m5VK/dglVZLSVzKnTUHTJsEEXOWX+JfZAmG29CJ3yaF/xMSh+L382WBa77BgEKdVS5sOTT
62
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- +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
- 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
- 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
- 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
- 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
- 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
- 9cBcHK/1kv8nD7YXQl+9zI2az0HTQXNK4eDC3j9+m93YPbc5OvJwmQ7OmwvnEgjr1wPpFlxTSsCv
93
- q937mCKPgMFzKk/e82acVlygeShmrEMpItloR+Wmhufmp/ZyZKaupuGd+XoD6ZYAzUGYpnJhPJgG
94
- W8monL9c5MLAb3gUI/HsR9EKXicJhTG0ia4P06Id2PWadiRe5QQWq7Obp+rybD101yi7C+7j8QVU
95
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- aZzcjhCEotrrVCUm2yYcQi5IZTPckQsOOmE5OinZ2X77/LxlYpl7TTP0IM2LlSpXOt1cGZZg0XII
137
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- UUJlAL4dygEwYJ1pRCIBm15OqVGKwv2K52Rp9ooXdrVI6anfMTCufC4h607P2dx+FKgk+ijwltHt
160
- 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
- 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
- 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
- 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
- RCvg+stvde59Ld0wYz5lwR3/lJiwSndnjxRaKnv3Aejrl1mOB0mdjxdde6NcHDEjmLM8t1HJVJvR
165
- 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
- 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
- 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
- mDhYtlX+93K0fdHpKP+n1JwoJII3M24o8iXuRFLE2z6KcYkUFvj/Kj6BRVu2P5Y8vwMUi+uTsf+c
169
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- pGvorDjBH136gY8atD8pUro0wf0Meea2+Xy0cKp9BODNun/Zlr1lZVAUo0ai75PUhyIn6a1ZbbSk
177
- MtXe2HhcFs8Fna5Tf1af/N4JSc2BuipIhQpde4P9PFkaWSrzLpaHItIYJtx5hTk04ouRo/dIWiEX
178
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- +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
- 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
- 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
- 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
- 17oVy0GRD+HEqjqeXOUFbOoOyp5HXXyMiXSNQlr5Mds4uxXeFu8PvwHqsxJ/SB7qCbPSLCYb5O+S
195
- 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
- xCXRxgu0lGqrKTThXockdOFvMiPeGDI1j+cqNf8kuolLgdxkmj22ZdhS7nNmL+JbSUqb+BlvImj9
197
- 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
- Gpvow+RN955uR+bNo2NUyHtfVwTA0QQ3G1QpL6UK9Be0qRqFeLfAwEcp5N7aZOuMkiTtVrXfTAU4
199
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- RxPmfeL3zrnnJvfJzQ7ubJ3qv/cBp/2qT4ZBS7/pUV9MUS4dxoB10ZG6TMe9/Q8DidwzSemAvIc4
211
- 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
- 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
- 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
- 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
- USiOyrJt9SVU7T18uVAzYnWnCWStelf8QAy/uhAp6X9Wvl2oqsz/1GXdndRROGQIagUYOjZn7NIS
216
- p1tosCqae3x4qZO7nl2+XTO1CqFMPik2juJ8dwQKeOZdzmCedvEggDZHCJVeLQqY4F2sTMqXV5dO
217
- 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
- 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
- vjtmEWqfnSantBPCajkPSLgduOFNfCrb6lL2Vg3Zidb/arBSKg4Vl+FrCU0n38S0HeoTdsxpLshZ
220
- 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
- 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
- 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
- DetWQuIvUkVz8YovKr2xjxDSu6MKz0ufWgYAs4fK9tvpf961liIQW8zijaTzo/3znKuQxLuew+S4
224
- kh5jWY3/PhDaPatiFQWtWjlvFNvj+WbNAwQQ+kfXrs82nDaCge+QrYWvlv3/TsXeR5R4x6dv8iZw
225
- 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
- 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
- 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
- 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
- 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
- +UYyiBt3KWTQDP9MXNdwpDXBefxvV+WLip6yZGnKeqeI05K/Vlhv4rQ1twxoBl+o90wDxaTdd0Rf
231
- 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
- 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
- RB3KJIs4mN9N6f1DbUMHYa3X3cMFd595RQfyw5nx0UxOmq97MeeV80aC9KeIhddwffjsSGHs8OEk
234
- 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
- rxuJL3WQsUhIPJrRDaiazhoJmG9ne675u64Di5G4cUQ+Txso6KoHmWNOQhD74sVVAjNMG13pkkrT
236
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- FWZp+a+7eaq1Iv8QDHmC6pvBTE7yuJfyXrXEjRync3AUo2szmg5iHECLo0MGlTqSHIYWrk0XYA0n
260
- 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
- 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
- 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
- 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
- 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
- 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
- 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
267
- aR3jmFGn
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
  /**
3
  * Subscribe Pro - Subscriptions Management Extension
4
  *
13
  * @license http://www.subscribepro.com/terms-of-service/ Subscribe Pro Terms of Service
14
  * @link http://www.subscribepro.com/
15
  *
16
+ * @SuppressWarnings(PHPMD.LongVariable)
17
+ * @SuppressWarnings(PHPMD.TooManyMethods)
18
+ * @SuppressWarnings(PHPMD.TooManyFields)
19
  */
20
 
21
+ class SFC_Autoship_Model_Payment_Method extends Mage_Payment_Model_Method_Cc
22
+ {
23
+ const METHOD_CODE = 'subscribe_pro';
24
+ const METHOD_CODE_KEY_TOKEN = '_token_';
25
+
26
+ /**
27
+ * Payment method code
28
+ */
29
+ protected $_code = self::METHOD_CODE;
30
+
31
+ /**
32
+ * Form block type
33
+ */
34
+ protected $_formBlockType = 'autoship/payment_form_cc';
35
+ protected $_formBlockTypeSaved = 'autoship/payment_form_cc_saved';
36
+
37
+ /**
38
+ * Info block type
39
+ */
40
+ protected $_infoBlockType = 'autoship/payment_info_cc';
41
+
42
+ /**
43
+ * Availability options
44
+ */
45
+ protected $_isGateway = true;
46
+ protected $_canAuthorize = true;
47
+ protected $_canCapture = true;
48
+ protected $_canCapturePartial = true;
49
+ protected $_canRefund = true;
50
+ protected $_canRefundInvoicePartial = true;
51
+ protected $_canVoid = true;
52
+ protected $_canUseInternal = true;
53
+ protected $_canUseCheckout = true;
54
+ protected $_canUseForMultishipping = true;
55
+ protected $_canSaveCc = false;
56
+ protected $_canFetchTransactionInfo = true;
57
+
58
+ /**
59
+ * Members to hold saved card instance data *
60
+ */
61
+ protected $_savedPaymentProfile = null;
62
+
63
+ /**
64
+ * Turn this method instance into a method representing once particular saved card / profile
65
+ */
66
+ public function setSavedPaymentProfile(SFC_Autoship_Model_Payment_Profile $paymentProfile)
67
+ {
68
+ $this->_savedPaymentProfile = $paymentProfile;
69
+ }
70
+
71
+ /**
72
+ * @return SFC_Autoship_Model_Payment_Profile
73
+ */
74
+ public function getSavedPaymentProfile()
75
+ {
76
+ return $this->_savedPaymentProfile;
77
+ }
78
+
79
+ /**
80
+ * Retrieve payment method title
81
+ *
82
+ * @return string
83
+ */
84
+ public function getTitle()
85
+ {
86
+ // If this is a saved card instance, title is saved card last digits
87
+ if ($this->_savedPaymentProfile instanceof SFC_Autoship_Model_Payment_Profile) {
88
+ return Mage::helper('autoship')->__('Use my Saved Credit Card (%s)', $this->_savedPaymentProfile->getData('creditcard_last_digits'));
89
+ }
90
+ else {
91
+ return $this->getConfigData('title');
92
+ }
93
+ }
94
+
95
+ /**
96
+ * Retrieve payment method code
97
+ *
98
+ * @return string
99
+ */
100
+ public function getCode()
101
+ {
102
+ if (empty($this->_code)) {
103
+ Mage::throwException(Mage::helper('payment')->__('Cannot retrieve the payment method code.'));
104
+ }
105
+ if ($this->_savedPaymentProfile instanceof SFC_Autoship_Model_Payment_Profile) {
106
+ return self::METHOD_CODE . self::METHOD_CODE_KEY_TOKEN . $this->_savedPaymentProfile->getData('payment_token');
107
+ }
108
+ else {
109
+ return $this->_code;
110
+ }
111
+ }
112
+
113
+ /**
114
+ * Retrieve block type for method form generation
115
+ *
116
+ * @return string
117
+ */
118
+ public function getFormBlockType()
119
+ {
120
+ if ($this->_savedPaymentProfile instanceof SFC_Autoship_Model_Payment_Profile) {
121
+ return $this->_formBlockTypeSaved;
122
+ }
123
+ else {
124
+ return $this->_formBlockType;
125
+ }
126
+ }
127
+
128
+ /**
129
+ * Retrieve information from payment configuration
130
+ *
131
+ * @param string $field
132
+ * @param int|string|null|Mage_Core_Model_Store $storeId
133
+ *
134
+ * @return mixed
135
+ */
136
+ public function getConfigData($field, $storeId = null)
137
+ {
138
+ if (null === $storeId) {
139
+ $storeId = $this->getStore();
140
+ }
141
+ $path = 'payment/' . self::METHOD_CODE . '/' . $field;
142
+
143
+ return Mage::getStoreConfig($path, $storeId);
144
+ }
145
+
146
+ /**
147
+ * Assign data to info model instance
148
+ *
149
+ * @param mixed $data
150
+ * @return $this
151
+ */
152
+ public function assignData($data)
153
+ {
154
+ // Get Mage_Payment_Model_Info instance from quote
155
+ $info = $this->getInfoInstance();
156
+
157
+ //Clear out additional information that may have been set previously in the session
158
+ $info->setAdditionalInformation(array());
159
+
160
+ // Call parent assignData
161
+ parent::assignData($data);
162
+
163
+ // Check config and cc number
164
+ if ($this->getConfigData('use_transparent_redirect') != '1' && isset($data['cc_number']) && strlen($data['cc_number']) && strpos($data['cc_number'], 'XXXX') === false) {
165
+ // Get quote
166
+ /** @var Mage_Sales_Model_Quote $quote */
167
+ $quote = $info->getQuote();
168
+ // In this case, we aren't using transparent redirect, nor using an existing token, someone has passed in full CC number, create new token
169
+ $this->createNewPaymentToken($quote, $data);
170
+ }
171
+
172
+ // Customer entering new card
173
+ // Save basic fields in additional info
174
+ if (isset($data['save_card'])) {
175
+ $info->setAdditionalInformation('save_card', $data['save_card']);
176
+ }
177
+ if (isset($data['is_new_card'])) {
178
+ $info->setAdditionalInformation('is_new_card', $data['is_new_card']);
179
+ }
180
+ if (isset($data['payment_token'])) {
181
+ $info->setAdditionalInformation('payment_token', $data['payment_token']);
182
+ }
183
+ if (isset($data['cc_number'])) {
184
+ $info->setAdditionalInformation('obscured_cc_number', $data['cc_number']);
185
+ }
186
+ if (isset($data['third_party_token'])) {
187
+ $info->setAdditionalInformation('is_third_party', true);
188
+ }
189
+
190
+ return $this;
191
+ }
192
+
193
+ /**
194
+ * Check whether payment method can be used
195
+ *
196
+ * @param Mage_Sales_Model_Quote|null $quote
197
+ *
198
+ * @return bool
199
+ */
200
+ public function isAvailable($quote = null)
201
+ {
202
+ // If $quote object not populated, call parent method
203
+ if ($quote == null) {
204
+ // Call parent
205
+ return parent::isAvailable($quote);
206
+ }
207
+ // Check the checkout method selected and look for guest checkout
208
+ if ($quote != null && $quote->getCheckoutMethod() == Mage_Checkout_Model_Type_Onepage::METHOD_GUEST) {
209
+ // Check configuration settings
210
+ if (Mage::getStoreConfig('payment/' . self::METHOD_CODE . '/allow_guest_checkout', $quote->getStore()) == '1') {
211
+ // Guest checkout option is enabled, call parent method to see if payment method is available
212
+ return parent::isAvailable($quote);
213
+ }
214
+ else {
215
+ // return No for guest checkout situation when guest checkout option disabled
216
+ return false;
217
+ }
218
+ }
219
+
220
+ // If all else fails, call the parent method
221
+ return parent::isAvailable($quote);
222
+ }
223
+
224
+ /**
225
+ * Check whether payment method is applicable to quote
226
+ * Purposed to allow use in controllers some logic that was implemented in blocks only before
227
+ *
228
+ * @param Mage_Sales_Model_Quote $quote
229
+ * @param int|null $checksBitMask
230
+ * @return bool
231
+ */
232
+ public function isApplicableToQuote($quote, $checksBitMask)
233
+ {
234
+ /** @var SFC_Autoship_Helper_Quote $quoteHelper */
235
+ $quoteHelper = Mage::helper('autoship/quote');
236
+
237
+ if ($quoteHelper->hasProductsToCreateNewSubscription()) {
238
+ //Remove the check for zero dollar checkout on this method, as its code is not 'free' but it does support zero dollar checkout
239
+ if ($checksBitMask) {
240
+ $checksBitMask = $checksBitMask & ~self::CHECK_ZERO_TOTAL;
241
+ }
242
+ } else {
243
+ if ($this->getConfigData('active_non_subscription') != '1') {
244
+ return false;
245
+ }
246
+ }
247
+ return parent::isApplicableToQuote($quote, $checksBitMask);
248
+ }
249
+
250
+ public function hasVerification()
251
+ {
252
+ // Always ignore verification code in admin ordering
253
+ if (Mage::app()->getStore()->isAdmin()
254
+ || ($this->getSavedPaymentProfile() instanceof SFC_Autoship_Model_Payment_Profile
255
+ && $this->getSavedPaymentProfile()->isThirdParty())) {
256
+ return false;
257
+ }
258
+ else {
259
+ return parent::hasVerification();
260
+ }
261
+ }
262
+
263
+ /**
264
+ * Validate payment method information object
265
+ * @return $this
266
+ * @throws SFC_Autoship_Helper_PaymentError_Exception
267
+ */
268
+ public function validate()
269
+ {
270
+ //Don't validate if we're in the API
271
+ if (Mage::app()->getFrontController()->getRequest()->getModuleName() == 'api') {
272
+ return true;
273
+ }
274
+
275
+ foreach($this->_getValidateFields($this->getInfoInstance()) as $field) {
276
+ if (!$this->_validateField($field, $this->getInfoInstance())) {
277
+ throw new SFC_Autoship_Helper_PaymentError_Exception(Mage::helper("autoship")->__('Payment form field: \'' . $field . '\' is missing from POST!'));
278
+ }
279
+ }
280
+ //We are letting vault do any additional validation
281
+ return true;
282
+ }
283
+
284
+ /**
285
+ * Determine which fields should be validated
286
+ * @param Mage_Payment_Model_Info $infoInstance
287
+ * @return array
288
+ */
289
+ protected function _getValidateFields(Mage_Payment_Model_Info $infoInstance)
290
+ {
291
+ if ($infoInstance->getAdditionalInformation('is_third_party')) {
292
+ //If third party we'll only be validating the cc & token
293
+ $_required_keys = array('cc_number', 'additional_information/payment_token');
294
+ } else {
295
+ //Otherwise validate all fields provided
296
+ $_required_keys = array('cc_number', 'cc_exp_month', 'cc_exp_year', 'additional_information/payment_token');
297
+ if ($this->hasVerification()) {
298
+ $_required_keys[] = 'cc_cid';
299
+ }
300
+ }
301
+ return $_required_keys;
302
+ }
303
+
304
+ /**
305
+ * Validate a field on the info instance.
306
+ * @param $field
307
+ * @param Mage_Payment_Model_Info $infoInstance
308
+ * @return mixed
309
+ */
310
+ protected function _validateField($field, Mage_Payment_Model_Info $infoInstance)
311
+ {
312
+ $method = 'getData';
313
+ if (preg_match('/^additional_information\//', $field)) {
314
+ $method = 'getAdditionalInformation';
315
+ $field = preg_replace('/^additional_information\//', '', $field);
316
+ }
317
+ return $infoInstance->{$method}($field);
318
+ }
319
+
320
+ /**
321
+ * Send authorize request to gateway
322
+ *
323
+ * @param Mage_Payment_Model_Info|\Varien_Object $payment
324
+ * @param float $amount
325
+ * @return $this
326
+ */
327
+ public function authorize(Varien_Object $payment, $amount)
328
+ {
329
+ // Log
330
+ Mage::log('====== SFC_Autoship_Model_Payment_Method::authorize called ======', Zend_Log::INFO,
331
+ SFC_Autoship_Helper_Data::LOG_FILE);
332
+
333
+ /** @var SFC_Autoship_Helper_Vault $vaultHelper */
334
+ $vaultHelper = Mage::helper('autoship/vault');
335
+ /** @var SFC_Autoship_Helper_Api $apiHelper */
336
+ $apiHelper = Mage::helper('autoship/api');
337
+
338
+ // Get order, etc from $payment
339
+ /** @var Mage_Sales_Model_Order $order */
340
+ $order = $payment->getOrder();
341
+ /** @var Mage_Customer_Model_Customer $customer */
342
+ $customer = $order->getCustomer();
343
+
344
+ // Set website / store for config on API helper
345
+ $store = Mage::app()->getWebsite($customer->getData('website_id'))->getDefaultStore();
346
+ $apiHelper->setConfigStore($store);
347
+ // Check if we should do profile transaction or one-time transaction
348
+ if ($payment->getAdditionalInformation('save_card') == '1' || $payment->getAdditionalInformation('is_new_card') != '1') {
349
+ // We are using existing pay profile or storing new one
350
+ // Get payment profile
351
+ $paymentProfile = $this->_createOrFetchPaymentProfile(
352
+ $payment,
353
+ $order->getBillingAddress(),
354
+ $payment->getData('cc_exp_month'),
355
+ $payment->getData('cc_exp_year'));
356
+ // Create transaction
357
+ if ($amount > 0.00) {
358
+ //Authorize if positive amount
359
+ $platformTransaction = $vaultHelper->authorize(
360
+ $paymentProfile,
361
+ $amount,
362
+ $order->getData('base_currency_code'),
363
+ array(
364
+ 'email' => $order->getCustomerEmail(),
365
+ 'order_id' => $order->getIncrementId(),
366
+ 'ip' => $order->getRemoteIp(),
367
+ )
368
+ );
369
+ } else {
370
+ //Otherwise verify
371
+ Mage::log('====== SFC_Autoship_Model_Payment_Method::authorize called, but only verifying due to $0.00! ======', Zend_Log::INFO, SFC_Autoship_Helper_Data::LOG_FILE);
372
+ $platformTransaction = $vaultHelper->verify(
373
+ $paymentProfile,
374
+ $order->getData('base_currency_code'),
375
+ array(
376
+ 'email' => $order->getCustomerEmail(),
377
+ 'order_id' => $order->getIncrementId(),
378
+ 'ip' => $order->getRemoteIp(),
379
+ )
380
+ );
381
+ }
382
+ }
383
+ else {
384
+
385
+ //Don't allow $0.00 for a one-time purchase, should use the 'free' method
386
+ if ($amount <= 0) {
387
+ Mage::throwException(Mage::helper('autoship')->__('Invalid amount for authorization.'));
388
+ }
389
+
390
+ // Create one-time transaction
391
+ $platformTransaction = $vaultHelper->authorizeOneTime(
392
+ $payment->getAdditionalInformation('payment_token'),
393
+ $amount,
394
+ array(
395
+ 'email' => $order->getCustomerEmail(),
396
+ 'order_id' => $order->getIncrementId(),
397
+ 'ip' => $order->getRemoteIp(),
398
+ ),
399
+ $order->getData('base_currency_code'),
400
+ $order->getBillingAddress(),
401
+ $payment->getData('cc_exp_month'),
402
+ $payment->getData('cc_exp_year')
403
+ );
404
+ // Save cc type in $payment
405
+ $ccType = $vaultHelper->mapSubscribeProCardTypeToMagento($platformTransaction['creditcard_type'], false);
406
+ if (strlen($ccType)) {
407
+ $payment->setCcType($ccType);
408
+ }
409
+ }
410
+
411
+ // Save transaction details in $payment
412
+ $payment
413
+ ->setIsTransactionClosed(0)
414
+ ->setCcTransId($platformTransaction['id'])
415
+ ->setTransactionId($platformTransaction['id'])
416
+ ->setAdditionalInformation('transaction_token', $platformTransaction['token'])
417
+ ->setAdditionalInformation('gateway_transaction_id', $platformTransaction['gateway_transaction_id'])
418
+ ->setAdditionalInformation('transaction_type', $platformTransaction['type'])
419
+ ;
420
+ // Save AVS and CVV results when available
421
+ if ($payment instanceof Mage_Sales_Model_Order_Payment) {
422
+ if (isset($platformTransaction['avs_code'])) {
423
+ $payment->setCcAvsStatus($platformTransaction['avs_code']);
424
+ }
425
+ if (isset($platformTransaction['cvv_code'])) {
426
+ $payment->setCcCidStatus($platformTransaction['cvv_code']);
427
+ }
428
+ }
429
+ /*
430
+ // Create transaction
431
+ // Magento seems to be creating this transaction already
432
+ // $payment->addTransaction(Mage_Sales_Model_Order_Payment_Transaction::TYPE_AUTH);
433
+ */
434
+
435
+ return $this;
436
+ }
437
+
438
+ /**
439
+ * Send capture request to gateway
440
+ *
441
+ * @param Mage_Payment_Model_Info|\Varien_Object $payment
442
+ * @param float $amount
443
+ * @return $this
444
+ */
445
+ public function capture(Varien_Object $payment, $amount)
446
+ {
447
+ // Log
448
+ Mage::log('====== SFC_Autoship_Model_Payment_Method::capture called ======', Zend_Log::INFO, SFC_Autoship_Helper_Data::LOG_FILE);
449
+
450
+ /** @var SFC_Autoship_Helper_Vault $vaultHelper */
451
+ $vaultHelper = Mage::helper('autoship/vault');
452
+ /** @var SFC_Autoship_Helper_Api $apiHelper */
453
+ $apiHelper = Mage::helper('autoship/api');
454
+
455
+ // Check if we're doing an auth n capture transaction or if we are just capturing and already auth'd transaction
456
+ // Look for a value in cc_trans_id and also that the saved payment_action was 'authorize'
457
+ if (strlen($payment->getData('cc_trans_id')) > 0 && $payment->getAdditionalInformation('transaction_type') == 'Authorization') {
458
+
459
+ if ($amount <= 0) {
460
+ //Don't allow prior auth capture for $0.00 transaction?
461
+ Mage::throwException(Mage::helper('autoship')->__('Invalid amount for capture.'));
462
+ }
463
+
464
+ /*
465
+ * We are doing PriorAuthCapture here...
466
+ */
467
+
468
+ // Get order, etc from $payment
469
+ /** @var Mage_Sales_Model_Order $order */
470
+ $order = $payment->getOrder();
471
+
472
+ // Set website / store for config on API helper
473
+ $store = Mage::app()->getStore($payment->getOrder()->getStoreId());
474
+ $apiHelper->setConfigStore($store);
475
+
476
+ // Use API to create a new prior auth-capture transaction
477
+ $platformTransaction = $vaultHelper->capture($payment->getCcTransId(), $amount, $order->getData('base_currency_code'));
478
+
479
+ // Save transaction details in $payment
480
+ $payment
481
+ ->setIsTransactionClosed(0)
482
+ ->setParentTransactionId($payment->getData('cc_trans_id'))
483
+ ->setTransactionId($platformTransaction['id'])
484
+ // ->setParentTransactionId($payment->getData('cc_trans_id'))
485
+ // ->setCcTransId($platformTransaction['id'])
486
+ // ->setTransactionId($platformTransaction['id'])
487
+ // ->setAdditionalInformation('transaction_token', $platformTransaction['token'])
488
+ // ->setAdditionalInformation('gateway_transaction_id', $platformTransaction['gateway_transaction_id'])
489
+ // ->setAdditionalInformation('transaction_type', $platformTransaction['type'])
490
+ ;
491
+ // Save AVS and CVV results when available
492
+ if ($payment instanceof Mage_Sales_Model_Order_Payment) {
493
+ if (isset($platformTransaction['avs_code'])) {
494
+ $payment->setCcAvsStatus($platformTransaction['avs_code']);
495
+ }
496
+ if (isset($platformTransaction['cvv_code'])) {
497
+ $payment->setCcCidStatus($platformTransaction['cvv_code']);
498
+ }
499
+ }
500
+ // Create transaction
501
+ $payment->addTransaction(Mage_Sales_Model_Order_Payment_Transaction::TYPE_CAPTURE);
502
+ }
503
+ else {
504
+ /*
505
+ * We are doing AuthCapture (also known as purchase) transaction here...
506
+ */
507
+
508
+ // Get order, etc from $payment
509
+ /** @var Mage_Sales_Model_Order $order */
510
+ $order = $payment->getOrder();
511
+ /** @var Mage_Customer_Model_Customer $customer */
512
+ $customer = $order->getCustomer();
513
+
514
+ // Set website / store for config on API helper
515
+ $store = Mage::app()->getWebsite($customer->getData('website_id'))->getDefaultStore();
516
+ $apiHelper->setConfigStore($store);
517
+ // Check if we should do profile transaction or one-time transaction
518
+ if ($payment->getAdditionalInformation('save_card') == '1' || $payment->getAdditionalInformation('is_new_card') != '1') {
519
+ // We are using existing pay profile or storing new one
520
+ // Get payment profile
521
+ $paymentProfile = $this->_createOrFetchPaymentProfile(
522
+ $payment,
523
+ $order->getBillingAddress(),
524
+ $payment->getData('cc_exp_month'),
525
+ $payment->getData('cc_exp_year'));
526
+ // Create transaction
527
+ if ($amount > 0) {
528
+ //Capture if positive amount
529
+ $platformTransaction = $vaultHelper->purchase(
530
+ $paymentProfile,
531
+ $amount,
532
+ $order->getData('base_currency_code'),
533
+ array(
534
+ 'email' => $order->getCustomerEmail(),
535
+ 'order_id' => $order->getIncrementId(),
536
+ 'ip' => $order->getRemoteIp(),
537
+ )
538
+ );
539
+ } else {
540
+ //Otherwise just verify the card
541
+ Mage::log('====== SFC_Autoship_Model_Payment_Method::capture called, but only verifying due to $0.00! ======', Zend_Log::INFO, SFC_Autoship_Helper_Data::LOG_FILE);
542
+ $platformTransaction = $vaultHelper->verify(
543
+ $paymentProfile,
544
+ $order->getData('base_currency_code'),
545
+ array(
546
+ 'email' => $order->getCustomerEmail(),
547
+ 'order_id' => $order->getIncrementId(),
548
+ 'ip' => $order->getRemoteIp(),
549
+ )
550
+ );
551
+ }
552
+ }
553
+ else {
554
+ if ($amount <= 0) {
555
+ //Don't allow $0.00 auth for one-time purchase, should use 'free' method
556
+ Mage::throwException(Mage::helper('autoship')->__('Invalid amount for capture.'));
557
+ }
558
+ // Create one-time purchase transaction
559
+ $platformTransaction = $vaultHelper->purchaseOneTime(
560
+ $payment->getAdditionalInformation('payment_token'),
561
+ $amount,
562
+ $order->getData('base_currency_code'),
563
+ array(
564
+ 'email' => $order->getCustomerEmail(),
565
+ 'order_id' => $order->getIncrementId(),
566
+ 'ip' => $order->getRemoteIp(),
567
+ ),
568
+ $order->getBillingAddress(),
569
+ $payment->getData('cc_exp_month'),
570
+ $payment->getData('cc_exp_year')
571
+ );
572
+ // Save cc type in $payment
573
+ $ccType = $vaultHelper->mapSubscribeProCardTypeToMagento($platformTransaction['creditcard_type'], false);
574
+ if (strlen($ccType)) {
575
+ $payment->setCcType($ccType);
576
+ }
577
+ }
578
+
579
+ // Save transaction details in $payment
580
+ $payment
581
+ ->setIsTransactionClosed(0)
582
+ ->setCcTransId($platformTransaction['id'])
583
+ ->setTransactionId($platformTransaction['id'])
584
+ ->setAdditionalInformation('transaction_token', $platformTransaction['token'])
585
+ ->setAdditionalInformation('gateway_transaction_id', $platformTransaction['gateway_transaction_id'])
586
+ ->setAdditionalInformation('transaction_type', $platformTransaction['type'])
587
+ ;
588
+ // Save AVS and CVV results when available
589
+ if ($payment instanceof Mage_Sales_Model_Order_Payment) {
590
+ if (isset($platformTransaction['avs_code'])) {
591
+ $payment->setCcAvsStatus($platformTransaction['avs_code']);
592
+ }
593
+ if (isset($platformTransaction['cvv_code'])) {
594
+ $payment->setCcCidStatus($platformTransaction['cvv_code']);
595
+ }
596
+ }
597
+ // Create transaction
598
+ $payment->addTransaction(Mage_Sales_Model_Order_Payment_Transaction::TYPE_CAPTURE);
599
+
600
+ }
601
+
602
+ return $this;
603
+ }
604
+
605
+ /**
606
+ * Void the payment through gateway
607
+ *
608
+ * @param Mage_Payment_Model_Info|\Varien_Object $payment
609
+ * @return $this
610
+ */
611
+ public function void(Varien_Object $payment)
612
+ {
613
+ // Log
614
+ Mage::log('====== SFC_Autoship_Model_Payment_Method::void called ======', Zend_Log::INFO, SFC_Autoship_Helper_Data::LOG_FILE);
615
+
616
+ /** @var SFC_Autoship_Helper_Vault $vaultHelper */
617
+ $vaultHelper = Mage::helper('autoship/vault');
618
+ /** @var SFC_Autoship_Helper_Api $apiHelper */
619
+ $apiHelper = Mage::helper('autoship/api');
620
+
621
+ // Set website / store for config on API helper
622
+ $store = Mage::app()->getStore($payment->getOrder()->getStoreId());
623
+ $apiHelper->setConfigStore($store);
624
+
625
+ // Use API to create a new prior auth-capture transaction
626
+ $platformTransaction = $vaultHelper->void($payment->getCcTransId());
627
+
628
+ // Save transaction details in $payment
629
+ // Field cc_trans_id in payment should hold the single authorize trans id and then the single capture trans id
630
+ // (or just the single auth n capture trans id)
631
+ $payment
632
+ ->setIsTransactionClosed(1)
633
+ ->setShouldCloseParentTransaction(1)
634
+ ->setParentTransactionId($payment->getData('cc_trans_id'))
635
+ ->setTransactionId($platformTransaction['id']);
636
+ // Create transaction
637
+ $payment->addTransaction(Mage_Sales_Model_Order_Payment_Transaction::TYPE_VOID);
638
+ // This seems to be necessary to keep 1.5.1.x and 1.10.1.x from duplicating the void transaction
639
+ $payment->setSkipTransactionCreation(true);
640
+
641
+ return $this;
642
+ }
643
+
644
+ /**
645
+ * Cancel the payment through gateway
646
+ *
647
+ * @param Mage_Payment_Model_Info|\Varien_Object $payment
648
+ * @return $this
649
+ */
650
+ public function cancel(Varien_Object $payment)
651
+ {
652
+ // Log
653
+ Mage::log('====== SFC_Autoship_Model_Payment_Method::cancel called ======', Zend_Log::INFO, SFC_Autoship_Helper_Data::LOG_FILE);
654
+
655
+ return $this->void($payment);
656
+ }
657
+
658
+ /**
659
+ * Refund the amount with transaction id
660
+ *
661
+ * @param Mage_Payment_Model_Info|\Varien_Object $payment
662
+ * @param float $requestedAmount
663
+ * @return $this
664
+ */
665
+ public function refund(Varien_Object $payment, $requestedAmount)
666
+ {
667
+ // Log
668
+ Mage::log('====== SFC_Autoship_Model_Payment_Method::refund called ======', Zend_Log::INFO, SFC_Autoship_Helper_Data::LOG_FILE);
669
+
670
+ /** @var SFC_Autoship_Helper_Vault $vaultHelper */
671
+ $vaultHelper = Mage::helper('autoship/vault');
672
+ /** @var SFC_Autoship_Helper_Api $apiHelper */
673
+ $apiHelper = Mage::helper('autoship/api');
674
+
675
+ // Set website / store for config on API helper
676
+ $store = Mage::app()->getStore($payment->getOrder()->getStoreId());
677
+ $apiHelper->setConfigStore($store);
678
+
679
+ // Get order, etc from $payment
680
+ /** @var Mage_Sales_Model_Order $order */
681
+ $order = $payment->getOrder();
682
+
683
+ // Use API to create a new prior auth-capture transaction
684
+ $platformTransaction = $vaultHelper->credit($payment->getCcTransId(), $requestedAmount, $order->getData('base_currency_code'));
685
+
686
+ /**
687
+ * Duplicate logic from standard Authorize.net payment method:
688
+ * This means that we should close the parent transaction if we have refunded the full amount of original transaction
689
+ */
690
+ $shouldCloseRefundTransaction = 0;
691
+ if ($this->_formatAmount($payment->getAmountPaid() - $payment->getAmountRefunded()) == $this->_formatAmount($requestedAmount)) {
692
+ $shouldCloseRefundTransaction = 1;
693
+ }
694
+
695
+ // Save transaction details in $payment
696
+ // Field cc_trans_id in payment should hold the single original (purchase or capture) trans id
697
+ // (or just the single auth n capture trans id)
698
+ $payment
699
+ ->setIsTransactionClosed(1)
700
+ ->setShouldCloseParentTransaction($shouldCloseRefundTransaction)
701
+ ->setParentTransactionId($payment->getData('cc_trans_id'))
702
+ ->setTransactionId($platformTransaction['id']);
703
+ // This seems to be necessary to keep 1.5.1.x and 1.10.1.x from causing "transaction already closed" error on 1.5.1.x and 1.10.1.x
704
+ $payment->setSkipTransactionCreation(true);
705
+ // Create transaction
706
+ $payment->addTransaction(Mage_Sales_Model_Order_Payment_Transaction::TYPE_REFUND);
707
+
708
+ return $this;
709
+ }
710
+
711
+
712
+ protected function createNewPaymentToken(Mage_Sales_Model_Quote $quote, $data)
713
+ {
714
+
715
+ /** @var SFC_Autoship_Helper_Vault $vaultHelper */
716
+ $vaultHelper = Mage::helper('autoship/vault');
717
+ /** @var SFC_Autoship_Helper_Api $apiHelper */
718
+ $apiHelper = Mage::helper('autoship/api');
719
+ // Set website / store for config on API helper
720
+ $apiHelper->setConfigStore($quote->getStore());
721
+ // Call api to create new payment token
722
+ $paymentToken = $vaultHelper->createPaymentToken(
723
+ $quote->getBillingAddress(),
724
+ $data['cc_number'],
725
+ $data['cc_exp_month'],
726
+ $data['cc_exp_year'],
727
+ $data['cc_cid']
728
+ );
729
+ // Now obfuscate card number and store token
730
+ $data['cc_number'] = $paymentToken['first_six_digits'] . 'XXXXXX' . $paymentToken['last_four_digits'];
731
+ $data['cc_cid'] = 'XXX';
732
+ $data['payment_token'] = $paymentToken['token'];
733
+ }
734
+
735
+ /**
736
+ * @param Varien_Object $payment
737
+ * @param \Mage_Customer_Model_Address_Abstract $billingAddress
738
+ * @param $expMonth
739
+ * @param $expYear
740
+ * @return array|SFC_Autoship_Model_Payment_Profile
741
+ * @throws Exception
742
+ * @throws Mage_Core_Exception
743
+ * @throws SFC_Autoship_Helper_PaymentError_Exception
744
+ */
745
+ protected function _createOrFetchPaymentProfile(Varien_Object $payment, Mage_Customer_Model_Address_Abstract $billingAddress, $expMonth, $expYear)
746
+ {
747
+ // Log
748
+ Mage::log('_createOrFetchPaymentProfile()', Zend_Log::INFO, SFC_Autoship_Helper_Data::LOG_FILE);
749
+
750
+ /** @var SFC_Autoship_Helper_Vault $vaultHelper */
751
+ $vaultHelper = Mage::helper('autoship/vault');
752
+ /** @var SFC_Autoship_Helper_Platform $platformHelper */
753
+ $platformHelper = Mage::helper('autoship/platform');
754
+
755
+ // Get order, etc from $payment
756
+ /** @var Mage_Sales_Model_Order $order */
757
+ $order = $payment->getOrder();
758
+ /** @var Mage_Customer_Model_Customer $customer */
759
+ $customer = $order->getCustomer();
760
+
761
+ try {
762
+ // Get payment token
763
+ $paymentToken = $payment->getAdditionalInformation('payment_token');
764
+ // Check if this is a new card
765
+ $isNewCard = $payment->getAdditionalInformation('is_new_card') == '1';
766
+ // Get token details
767
+ $paymentTokenDetails = $vaultHelper->getPaymentTokenDetails($paymentToken);
768
+ $paymentTokenStatus = $paymentTokenDetails['storage_state'];
769
+ // Check status of token and new card flag
770
+ if ($isNewCard) {
771
+ // This is a new card
772
+ if ($paymentTokenStatus == 'cached') {
773
+ // This is a new card, its only cache at this point, store it
774
+ // Create or update customer on platform
775
+ $platformHelper->createOrUpdateCustomer($customer);
776
+ // Store token as new pay profile
777
+ $paymentProfile = $vaultHelper->storeToken($customer->getId(), $paymentToken, $billingAddress, $expMonth, $expYear);
778
+ }
779
+ else if ($paymentTokenStatus = 'retained') {
780
+ // This is a new card, must have already been stored in a failed checkout type
781
+ // Just try to fetch it
782
+ /** @var SFC_Autoship_Model_Payment_Profile $paymentProfile */
783
+ $paymentProfile = $vaultHelper->getPaymentProfileByToken($paymentToken);
784
+ // Now update billing address & exp date
785
+ $this->updatePaymentProfile($paymentProfile, $billingAddress, $expMonth, $expYear);
786
+ }
787
+ else {
788
+ throw new SFC_Autoship_Helper_PaymentError_Exception(Mage::helper('autoship')->__('Credit card information has expired! Please reenter card details.'));
789
+ }
790
+ }
791
+ else {
792
+ // This is an existing card, just fetch it
793
+ // Just try to fetch it
794
+ $paymentProfile = $vaultHelper->getPaymentProfileByToken($paymentToken);
795
+ if (!$paymentProfile->isThirdParty()) {
796
+ // Third party profiles can't be updated
797
+ // Now update billing address & exp date
798
+ $this->updatePaymentProfile($paymentProfile, $billingAddress, $expMonth, $expYear);
799
+ }
800
+ }
801
+ if (!$paymentProfile->isThirdParty()) {
802
+ // Third party profiles won't necessarily have the card type set
803
+ // Update CC card type on payment record
804
+ // Save cc type in $payment
805
+ $ccType = $vaultHelper->mapSubscribeProCardTypeToMagento($paymentProfile->getData('creditcard_type'), false);
806
+ if (strlen($ccType)) {
807
+ $payment->setCcType($ccType);
808
+ }
809
+ }
810
+
811
+ // Save payment profile id in additional info
812
+ $payment->setAdditionalInformation('payment_profile_id', $paymentProfile->getId());
813
+
814
+ // Finally return the profile
815
+ return $paymentProfile;
816
+ }
817
+ catch (SFC_Autoship_Helper_PaymentError_Exception $e) {
818
+ // Rethrow these exceptions as the message will be customer friendly
819
+ throw $e;
820
+ }
821
+ catch (Exception $e) {
822
+ // Throw new exception with generic message
823
+ Mage::throwException(Mage::helper('autoship')->__('Failed to store credit card for payment transaction!'));
824
+ }
825
+ }
826
+
827
+ protected function updatePaymentProfile(SFC_Autoship_Model_Payment_Profile $paymentProfile, Mage_Customer_Model_Address_Abstract $billingAddress, $expMonth, $expYear)
828
+ {
829
+ /** @var SFC_Autoship_Helper_Vault $vaultHelper */
830
+ $vaultHelper = Mage::helper('autoship/vault');
831
+
832
+ // Now update billing address & exp date
833
+ /** @var SFC_Autoship_Model_Payment_Profile_Address $paymentProfileBillingAddress */
834
+ $paymentProfileBillingAddress = $paymentProfile->getData('billing_address');
835
+ $paymentProfileBillingAddress->updateFromCustomerAddress($billingAddress);
836
+ $paymentProfile->setData('creditcard_month', $expMonth);
837
+ $paymentProfile->setData('creditcard_year', $expYear);
838
+ $vaultHelper->updatePaymentProfile($paymentProfile);
839
+ }
840
+
841
+ /**
842
+ * Round up and cast specified amount to float or string
843
+ *
844
+ * @param string|float $amount
845
+ * @param bool $asFloat
846
+ * @return string|float
847
+ */
848
+ protected function _formatAmount($amount, $asFloat = false)
849
+ {
850
+ $amount = sprintf('%.2F', $amount); // 'f' depends on locale, 'F' doesn't
851
+ return $asFloat ? (float)$amount : $amount;
852
+ }
853
+
854
+ }
app/code/local/SFC/Autoship/Model/Payment/Profile.php CHANGED
@@ -1,4 +1,4 @@
1
- <?php //00612
2
  /**
3
  * Subscribe Pro - Subscriptions Management Extension
4
  *
@@ -15,74 +15,105 @@
15
  *
16
  */
17
 
18
- if(!extension_loaded('ionCube Loader')){$__oc=strtolower(substr(php_uname(),0,3));$__ln='/ioncube/ioncube_loader_'.$__oc.'_'.substr(phpversion(),0,3).(($__oc=='win')?'.dll':'.so');$__oid=$__id=realpath(ini_get('extension_dir'));$__here=dirname(__FILE__);if((@$__id[1])==':'){$__id=str_replace('\\','/',substr($__id,2));$__here=str_replace('\\','/',substr($__here,2));}$__rd=str_repeat('/..',substr_count($__id,'/')).$__here.'/';$__i=strlen($__rd);while($__i--){if($__rd[$__i]=='/'){$__lp=substr($__rd,0,$__i).$__ln;if(file_exists($__oid.$__lp)){$__ln=$__lp;break;}}}@dl($__ln);}else{die('The file '.__FILE__." is corrupted. Ensure that you use binary mode when transferring files with FTP and disable the 'TAR smart cr/lf feature' if using WinZIP\n");}if(function_exists('_il_exec')){return _il_exec();}die('The file <b>'.__FILE__.'</b> has been encoded with the <a href="http://www.ioncube.com">ionCube PHP Encoder</a> and requires the free '.basename($__ln).' <a href="http://www.ioncube.com/loader_download/">ionCube PHP Loader</a> to be installed.');
 
 
19
 
20
- ?>
21
- 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
- 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
- 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
- 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
- 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
- bPm96W/9Jy0VztNacX+lUr48/Y0kk9E9dNQJiyurjWAZ70cEmBfIPMduGG6OlXtPro6a5MdZDMBO
27
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- RRxpsbXCb6o3WCU7s2VscdeZY7tFtHBUZfbcjcTqQYCcjs9G/nlv6FpdxqAoAxHcPz6B5ye4fqGO
47
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- et8k/AG23Ez/3aCfVKSEIAnUy10UGB2ZyGxHMTZItiyYwfZf/jf/nyhNlLwyOyj2NRceecXFvMPa
56
- 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
- 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
- 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
- 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
- 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
- tAQG2zeRixmYfbu+tu4ILGlVeWqqBaBjBFjOzWv1Lyt9FehokQVn2Faew4FG8CZ7lH3pByqqkaEs
62
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- SWi3N7rBsBa2D14BErtfvDWSYm9V+5G79Xd6B+36E0mDhM9R/CpG7XPzwZ096K/ZxsQqjGMQ0CUd
86
- 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
- 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
88
- qu+fJwTkXFd3mfEm1VK3L0==
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
  /**
3
  * Subscribe Pro - Subscriptions Management Extension
4
  *
15
  *
16
  */
17
 
18
+ class SFC_Autoship_Model_Payment_Profile extends Mage_Core_Model_Abstract
19
+ {
20
+ const PAYMENT_TYPE_THIRDPARTY = 'third_party_token';
21
 
22
+ public function getCollection()
23
+ {
24
+ return Mage::getModel('autoship/payment_profile_collection');
25
+ }
26
+
27
+ public function getId()
28
+ {
29
+ return $this->getData('id');
30
+ }
31
+
32
+ /**
33
+ * Init profile with customer data from customer record
34
+ */
35
+ public function initProfileWithCustomerDefault($customer)
36
+ {
37
+ // Load customer
38
+ if (!$customer instanceof Mage_Customer_Model_Customer) {
39
+ /** @var Mage_Customer_Model_Customer $model */
40
+ $customer = Mage::getModel('customer/customer')->load($customer);
41
+ }
42
+ $this->setData('customer_email', $customer->getData('email'));
43
+ $this->setData('magento_customer_id', $customer->getId());
44
+ $this->setData('billing_first_name', $customer->getData('firstname'));
45
+ $this->setData('billing_last_name', $customer->getData('lastname'));
46
+ // Grab default billing addy id
47
+ $addressId = $customer->getData('default_billing');
48
+ // Add address data if default billing addy exists
49
+ if ($addressId) {
50
+ // Get address
51
+ $address = Mage::getModel('customer/address')->load($addressId);
52
+ // Create billing address from customer address
53
+ $billingAddress = Mage::getModel('autoship/payment_profile_address')
54
+ ->updateFromCustomerAddress($address);
55
+ $this->setData('billing_address', $billingAddress);
56
+ }
57
+ else {
58
+ $billingAddress = Mage::getModel('autoship/payment_profile_address');
59
+ $this->setData('billing_address', $billingAddress);
60
+ }
61
+
62
+ $this->mapFlatFields();
63
+ }
64
+
65
+ public function updatePaymentProfileFromVaultData(array $vaultPaymentProfile)
66
+ {
67
+ $vaultPaymentProfileMinusBillingAddress = $vaultPaymentProfile;
68
+ unset($vaultPaymentProfileMinusBillingAddress['billing_address']);
69
+ $this->addData($vaultPaymentProfileMinusBillingAddress);
70
+ $this->getData('billing_address')->addData($vaultPaymentProfile['billing_address']);
71
+ // Map extra fields
72
+ $this->mapFlatFields();
73
+ }
74
+
75
+ public static function makePaymentProfileFromVaultData(array $vaultPaymentProfile)
76
+ {
77
+ // New object
78
+ $paymentProfile = Mage::getModel('autoship/payment_profile');
79
+ $billingAddress = Mage::getModel('autoship/payment_profile_address');
80
+ $paymentProfile->setData('billing_address', $billingAddress);
81
+ $paymentProfile->updatePaymentProfileFromVaultData($vaultPaymentProfile);
82
+
83
+ return $paymentProfile;
84
+ }
85
+
86
+ public function mapFlatFields()
87
+ {
88
+ $billingAddress = $this->getData('billing_address');
89
+ foreach ($billingAddress->getData() as $billingField => $billingValue) {
90
+ $this->setData('billing_' . $billingField, $billingValue);
91
+ }
92
+
93
+ $this->setData('billing_name', $this->getData('billing_first_name') . ' ' . $this->getData('billing_last_name'));
94
+
95
+ $this->setData('creditcard_number', $this->getData('creditcard_first_digits') . 'XXXXXX' . $this->getData('creditcard_last_digits'));
96
+
97
+ $this->setData('creditcard_exp_date', sprintf("%02d", $this->getData('creditcard_month')) . ' / ' . $this->getData('creditcard_year'));
98
+ }
99
+
100
+ public function unmapFlatFields()
101
+ {
102
+ // Un-map billing address flat fields
103
+ $billingAddress = $this->getData('billing_address');
104
+ foreach ($this->getData() as $field => $value) {
105
+ if (strpos($field, 'billing_') === 0 && $field != 'billing_address') {
106
+ $billingAddress->setData(substr($field, strlen('billing_')), $value);
107
+ }
108
+ }
109
+ }
110
+
111
+ /**
112
+ * @return bool
113
+ */
114
+ public function isThirdParty()
115
+ {
116
+ return $this->getData('payment_method_type') == self::PAYMENT_TYPE_THIRDPARTY;
117
+ }
118
+
119
+ }
app/code/local/SFC/Autoship/Model/Payment/Profile/Address.php CHANGED
@@ -1,4 +1,4 @@
1
- <?php //00612
2
  /**
3
  * Subscribe Pro - Subscriptions Management Extension
4
  *
@@ -15,44 +15,42 @@
15
  *
16
  */
17
 
18
- if(!extension_loaded('ionCube Loader')){$__oc=strtolower(substr(php_uname(),0,3));$__ln='/ioncube/ioncube_loader_'.$__oc.'_'.substr(phpversion(),0,3).(($__oc=='win')?'.dll':'.so');$__oid=$__id=realpath(ini_get('extension_dir'));$__here=dirname(__FILE__);if((@$__id[1])==':'){$__id=str_replace('\\','/',substr($__id,2));$__here=str_replace('\\','/',substr($__here,2));}$__rd=str_repeat('/..',substr_count($__id,'/')).$__here.'/';$__i=strlen($__rd);while($__i--){if($__rd[$__i]=='/'){$__lp=substr($__rd,0,$__i).$__ln;if(file_exists($__oid.$__lp)){$__ln=$__lp;break;}}}@dl($__ln);}else{die('The file '.__FILE__." is corrupted. Ensure that you use binary mode when transferring files with FTP and disable the 'TAR smart cr/lf feature' if using WinZIP\n");}if(function_exists('_il_exec')){return _il_exec();}die('The file <b>'.__FILE__.'</b> has been encoded with the <a href="http://www.ioncube.com">ionCube PHP Encoder</a> and requires the free '.basename($__ln).' <a href="http://www.ioncube.com/loader_download/">ionCube PHP Loader</a> to be installed.');
 
19
 
20
- ?>
21
- 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
- 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
- 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
- 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
- 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
- DfItizNB1NA5rzd3d6GB/NkTRP8KfeRAZWVrwoty9mOB3evma2gN/GpBE2pYnkEnCsRexsKbIYPX
27
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- I5uQi7AHKtQ0cVDTrjDJFxST3qtTmfEPTGEB/sDU1nvvSQnR/6VQvsupdcuX0gIOtuE/WEHmgp9+
55
- 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
- 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
- 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
58
- LziHlTQhcMW=
1
+ <?php
2
  /**
3
  * Subscribe Pro - Subscriptions Management Extension
4
  *
15
  *
16
  */
17
 
18
+ class SFC_Autoship_Model_Payment_Profile_Address extends Mage_Core_Model_Abstract
19
+ {
20
 
21
+ /**
22
+ * Construct
23
+ */
24
+ protected function _construct()
25
+ {
26
+ }
27
+
28
+ public function getId()
29
+ {
30
+ return $this->getData('id');
31
+ }
32
+
33
+ /**
34
+ * Set billing address fields on payment profile from a Magento customer address
35
+ *
36
+ * @param Mage_Customer_Model_Address_Abstract $billingAddress
37
+ * @return SFC_Autoship_Model_Payment_Profile_Address
38
+ */
39
+ public function updateFromCustomerAddress(Mage_Customer_Model_Address_Abstract $billingAddress)
40
+ {
41
+ $this->setData('first_name', $billingAddress->getData('firstname'));
42
+ $this->setData('last_name', $billingAddress->getData('lastname'));
43
+ $this->setData('company', $billingAddress->getData('company'));
44
+ $this->setData('street1', (string) $billingAddress->getStreet(1));
45
+ if(strlen($billingAddress->getStreet(2)))
46
+ $this->setData('street2', (string) $billingAddress->getStreet(2));
47
+ $this->setData('city', $billingAddress->getData('city'));
48
+ $this->setData('region', $billingAddress->getRegionCode());
49
+ $this->setData('postcode', $billingAddress->getData('postcode'));
50
+ $this->setData('country', $billingAddress->getData('country_id'));
51
+ $this->setData('phone', $billingAddress->getData('telephone'));
52
+
53
+ return $this;
54
+ }
55
+
56
+ }
 
 
 
app/code/local/SFC/Autoship/Model/Payment/Profile/Collection.php CHANGED
@@ -1,4 +1,4 @@
1
- <?php //00612
2
  /**
3
  * Subscribe Pro - Subscriptions Management Extension
4
  *
@@ -15,52 +15,83 @@
15
  *
16
  */
17
 
18
- if(!extension_loaded('ionCube Loader')){$__oc=strtolower(substr(php_uname(),0,3));$__ln='/ioncube/ioncube_loader_'.$__oc.'_'.substr(phpversion(),0,3).(($__oc=='win')?'.dll':'.so');$__oid=$__id=realpath(ini_get('extension_dir'));$__here=dirname(__FILE__);if((@$__id[1])==':'){$__id=str_replace('\\','/',substr($__id,2));$__here=str_replace('\\','/',substr($__here,2));}$__rd=str_repeat('/..',substr_count($__id,'/')).$__here.'/';$__i=strlen($__rd);while($__i--){if($__rd[$__i]=='/'){$__lp=substr($__rd,0,$__i).$__ln;if(file_exists($__oid.$__lp)){$__ln=$__lp;break;}}}@dl($__ln);}else{die('The file '.__FILE__." is corrupted. Ensure that you use binary mode when transferring files with FTP and disable the 'TAR smart cr/lf feature' if using WinZIP\n");}if(function_exists('_il_exec')){return _il_exec();}die('The file <b>'.__FILE__.'</b> has been encoded with the <a href="http://www.ioncube.com">ionCube PHP Encoder</a> and requires the free '.basename($__ln).' <a href="http://www.ioncube.com/loader_download/">ionCube PHP Loader</a> to be installed.');
 
19
 
20
- ?>
21
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- p0gjES6mvm1aWTkt7HeYQ66p5KXaf96PMQ5V+OmJyf/GhKpU/M3CAwclQjoEjxcQ7EaFSoj+1bbg
60
- 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
- 77o2uM4SMVrwMevZg23ZiYinUEpv8VyOQPs+gcXALA2lR2P8mEhf+BWjzvkvgrZOtm3Dh1m5iLFt
62
- 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
- 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
- 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
- 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
66
- 7dPdsiQjKUn8VxDKUyyBePAVrUi=
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
  /**
3
  * Subscribe Pro - Subscriptions Management Extension
4
  *
15
  *
16
  */
17
 
18
+ class SFC_Autoship_Model_Payment_Profile_Collection extends Varien_Data_Collection
19
+ {
20
 
21
+ public function _construct()
22
+ {
23
+ $this->setItemObjectClass(Mage::getConfig()->getModelClassName('autoship/payment_profile'));
24
+ }
25
+
26
+ /**
27
+ * Load data
28
+ *
29
+ * @param bool $printQuery
30
+ * @param bool $logQuery
31
+ * @throws Exception
32
+ * @return Varien_Data_Collection
33
+ */
34
+ public function loadData($printQuery = false, $logQuery = false)
35
+ {
36
+ if ($this->isLoaded()) {
37
+ return $this;
38
+ }
39
+
40
+ /** @var SFC_Autoship_Helper_Vault $vaultHelper */
41
+ $vaultHelper = Mage::helper('autoship/vault');
42
+
43
+ // Get customer email filter
44
+ $emailFilter = $this->getFilter('customer_email');
45
+ // This collection only usable when filtered by customer email address
46
+ if ($emailFilter != null) {
47
+ // Retrieve profiles from SP Vault API
48
+ $profiles = $vaultHelper->getPaymentProfilesForCustomer($emailFilter['value']);
49
+
50
+ // Sort profiles
51
+ $this->sortProfiles($profiles);
52
+
53
+ // Add profiles to collection
54
+ foreach ($profiles as $profile) {
55
+ $this->addItem($profile);
56
+ }
57
+ }
58
+
59
+
60
+ $this->_setIsLoaded();
61
+
62
+ return $this;
63
+ }
64
+
65
+ protected function sortProfiles(array &$profiles)
66
+ {
67
+ // Get orders in local
68
+ $orders = $this->_orders;
69
+ // Do sort, with closure sort function
70
+ usort(
71
+ $profiles,
72
+ function(Mage_Core_Model_Abstract $a, Mage_Core_Model_Abstract $b) use($orders) {
73
+ foreach ($orders as $field => $dir) {
74
+ if ($a->getData($field) < $b->getData($field)) {
75
+ if ($dir == 'ASC') {
76
+ return -1;
77
+ }
78
+ else {
79
+ return 1;
80
+ }
81
+ }
82
+ else if ($a->getData($field) > $b->getData($field)) {
83
+ if ($dir == 'ASC') {
84
+ return 1;
85
+ }
86
+ else {
87
+ return -1;
88
+ }
89
+ }
90
+ }
91
+
92
+ return 0;
93
+ }
94
+ );
95
+ }
96
+
97
+ }
app/code/local/SFC/Autoship/Model/Paypal/Express.php CHANGED
@@ -1,4 +1,4 @@
1
- <?php //00612
2
  /**
3
  * Subscribe Pro - Subscriptions Management Extension
4
  *
@@ -15,33 +15,39 @@
15
  *
16
  */
17
 
18
- if(!extension_loaded('ionCube Loader')){$__oc=strtolower(substr(php_uname(),0,3));$__ln='/ioncube/ioncube_loader_'.$__oc.'_'.substr(phpversion(),0,3).(($__oc=='win')?'.dll':'.so');$__oid=$__id=realpath(ini_get('extension_dir'));$__here=dirname(__FILE__);if((@$__id[1])==':'){$__id=str_replace('\\','/',substr($__id,2));$__here=str_replace('\\','/',substr($__here,2));}$__rd=str_repeat('/..',substr_count($__id,'/')).$__here.'/';$__i=strlen($__rd);while($__i--){if($__rd[$__i]=='/'){$__lp=substr($__rd,0,$__i).$__ln;if(file_exists($__oid.$__lp)){$__ln=$__lp;break;}}}@dl($__ln);}else{die('The file '.__FILE__." is corrupted. Ensure that you use binary mode when transferring files with FTP and disable the 'TAR smart cr/lf feature' if using WinZIP\n");}if(function_exists('_il_exec')){return _il_exec();}die('The file <b>'.__FILE__.'</b> has been encoded with the <a href="http://www.ioncube.com">ionCube PHP Encoder</a> and requires the free '.basename($__ln).' <a href="http://www.ioncube.com/loader_download/">ionCube PHP Loader</a> to be installed.');
 
19
 
20
- ?>
21
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 2Ephomg3i4j/k4tVeWa+EUZjafdZALP9Qawa8iwoUVD238oqlLWovIz07D807alouEsuTnhKGcxd
30
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
47
- g7E1XV+SPfUXGdpW/G==
 
 
 
 
 
1
+ <?php
2
  /**
3
  * Subscribe Pro - Subscriptions Management Extension
4
  *
15
  *
16
  */
17
 
18
+ class SFC_Autoship_Model_Paypal_Express extends Mage_Paypal_Model_Express
19
+ {
20
 
21
+ /**
22
+ * Check whether payment method can be used
23
+ * @param Mage_Sales_Model_Quote
24
+ * @return bool
25
+ */
26
+ public function isAvailable($quote = null)
27
+ {
28
+ // Check config to see if extension functionality is enabled
29
+ if ($quote != null) {
30
+ $store = $quote->getStore();
31
+ }
32
+ else {
33
+ $store = null;
34
+ }
35
+ if (Mage::getStoreConfig('autoship_general/general/enabled', $store) != '1') {
36
+ return parent::isAvailable($quote);
37
+ }
38
+
39
+ // If quote present and subscription products in quote, don't allow paypal
40
+ if ($quote instanceof Mage_Sales_Model_Quote) {
41
+ // Get quote helper
42
+ /** @var SFC_Autoship_Helper_Quote $quoteHelper */
43
+ $quoteHelper = Mage::helper('autoship/quote');
44
+ // Check if quote has subscription products, if yes disallow paypal express
45
+ if ($quoteHelper->hasProductsToCreateNewSubscription($quote)) {
46
+ return false;
47
+ }
48
+ }
49
+
50
+ return parent::isAvailable($quote);
51
+ }
52
+
53
+ }
app/code/local/SFC/Autoship/Model/Platform/Product.php CHANGED
@@ -1,4 +1,4 @@
1
- <?php //00612
2
  /**
3
  * Subscribe Pro - Subscriptions Management Extension
4
  *
@@ -15,18 +15,14 @@
15
  *
16
  */
17
 
18
- if(!extension_loaded('ionCube Loader')){$__oc=strtolower(substr(php_uname(),0,3));$__ln='/ioncube/ioncube_loader_'.$__oc.'_'.substr(phpversion(),0,3).(($__oc=='win')?'.dll':'.so');$__oid=$__id=realpath(ini_get('extension_dir'));$__here=dirname(__FILE__);if((@$__id[1])==':'){$__id=str_replace('\\','/',substr($__id,2));$__here=str_replace('\\','/',substr($__here,2));}$__rd=str_repeat('/..',substr_count($__id,'/')).$__here.'/';$__i=strlen($__rd);while($__i--){if($__rd[$__i]=='/'){$__lp=substr($__rd,0,$__i).$__ln;if(file_exists($__oid.$__lp)){$__ln=$__lp;break;}}}@dl($__ln);}else{die('The file '.__FILE__." is corrupted. Ensure that you use binary mode when transferring files with FTP and disable the 'TAR smart cr/lf feature' if using WinZIP\n");}if(function_exists('_il_exec')){return _il_exec();}die('The file <b>'.__FILE__.'</b> has been encoded with the <a href="http://www.ioncube.com">ionCube PHP Encoder</a> and requires the free '.basename($__ln).' <a href="http://www.ioncube.com/loader_download/">ionCube PHP Loader</a> to be installed.');
 
 
 
 
 
 
 
 
19
 
20
- ?>
21
- HR+cPmAJuhbvUzU+02Ttca5mhqwQOyInPnFw0v2yu9lM+DUIAV4h8WOogCIwMMZL6Mn8u05dxZgr
22
- PUx4jkFp/X5NZR2CXka43gFv3srQrijOFdW6TkxNxNqfbdwLrfdtoRGbeew1BLAhOFhzzHd2PFbB
23
- OAgaIz8+zZAN+AM6WYUU4gO+KXDC+Nn4X3FJxf8OjUi3iEtYp4SSjPKFawuuvF5OFYdfZ1gc80Mt
24
- nHx1pKXyZDnxPfgi3WgkdqglXdeXfpip43b00DhZnOpwYA0ifxPfd9hj0FoIa0HBR/1lMPU5Guoa
25
- ov0nSMMl5NLZJlmgiDaaP4ZXQKRXQzVE4GbHjmSi7tnE99bqAtPu5eA1zjeA03ZE6PVsJdkT2efT
26
- 79e192FOl+bdMeJgJoJQ0g5ArLC6SKNUp1bDAjWfUxAb9URYpjBBYdB8Xopq4jr26RJ4ZRLVV7VA
27
- 5zNcRhPsedTb+PkLjcg91t8CgNP+ApxpBiK7tbv04ResylSjfrI0HYSn0/XIUzjPEh8YuApVYeJZ
28
- 5iitluxy+IR7+3tGsI0QvUDiNod6KFAnjNrOSau3SjdhJUJNca8mJsm/7KzTQux07hCuB45j5opJ
29
- 6/XNeytl0iRyo7jH05Isoc59Ep3VGp0SRscEvSYR5lMy7QlQLXGrRG/CSnhr8OmDI0o3RSiUFOtQ
30
- USjeJGOMvxPXXCnM+PNYNCmL6aiQm2n/sNE1xhKFl2Z53PH2wyb7ml38wcms6P+aKrYDn9nMvUml
31
- Fzchm689wWhYKzHAtETVs0iPB5EMyEqwJ5l12srL0utOidkL0MOq6n1ghweNJ3yW1c2R11phvQSh
32
- pBglovi7UpULRazooALHrRfJWoDf5J5nKxSaOwNxse3pouRlUWSjXEZffh2uiVpJGhq=
1
+ <?php
2
  /**
3
  * Subscribe Pro - Subscriptions Management Extension
4
  *
15
  *
16
  */
17
 
18
+ /**
19
+ * Platform Product Model Class
20
+ *
21
+ * This model represents a single product in the platform API / DB.
22
+ * This model is not persisted to the Magento DB, but instead is persisted to the platform API.
23
+ *
24
+ */
25
+ class SFC_Autoship_Model_Platform_Product extends Mage_Core_Model_Abstract
26
+ {
27
 
28
+ }
 
 
 
 
 
 
 
 
 
 
 
 
app/code/local/SFC/Autoship/Model/Quote/Address.php CHANGED
@@ -1,4 +1,4 @@
1
- <?php //00612
2
  /**
3
  * Subscribe Pro - Subscriptions Management Extension
4
  *
@@ -15,54 +15,80 @@
15
  *
16
  */
17
 
18
- if(!extension_loaded('ionCube Loader')){$__oc=strtolower(substr(php_uname(),0,3));$__ln='/ioncube/ioncube_loader_'.$__oc.'_'.substr(phpversion(),0,3).(($__oc=='win')?'.dll':'.so');$__oid=$__id=realpath(ini_get('extension_dir'));$__here=dirname(__FILE__);if((@$__id[1])==':'){$__id=str_replace('\\','/',substr($__id,2));$__here=str_replace('\\','/',substr($__here,2));}$__rd=str_repeat('/..',substr_count($__id,'/')).$__here.'/';$__i=strlen($__rd);while($__i--){if($__rd[$__i]=='/'){$__lp=substr($__rd,0,$__i).$__ln;if(file_exists($__oid.$__lp)){$__ln=$__lp;break;}}}@dl($__ln);}else{die('The file '.__FILE__." is corrupted. Ensure that you use binary mode when transferring files with FTP and disable the 'TAR smart cr/lf feature' if using WinZIP\n");}if(function_exists('_il_exec')){return _il_exec();}die('The file <b>'.__FILE__.'</b> has been encoded with the <a href="http://www.ioncube.com">ionCube PHP Encoder</a> and requires the free '.basename($__ln).' <a href="http://www.ioncube.com/loader_download/">ionCube PHP Loader</a> to be installed.');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
19
 
20
- ?>
21
- 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
- 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
- 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
- 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
- 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
- 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
- ue3DZEP4DzbMLzHQeMIhzPdSGrzxusJUeBTJ0wtUexoV7GGnZLiaRHkvej4fGEMjerUwdZJ1M/po
28
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- +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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 2tZDfbqiTkcH4tWmmMgKotahP+4SN9WnU8oYz4NzEkCWcfpSUBqNUV/GEw3NObrWeucm33AvrOEC
57
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- +/JPMjro3P7WxfUY4UyXHJtSJFZNLg3gb9ViyJCmH7avjhkQeXrY7Nx3nep03NNRVHClfeuLyLTz
66
- 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
- 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
- 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
 
 
1
+ <?php
2
  /**
3
  * Subscribe Pro - Subscriptions Management Extension
4
  *
15
  *
16
  */
17
 
18
+ class SFC_Autoship_Model_Quote_Address extends Mage_Sales_Model_Quote_Address
19
+ {
20
+ /**
21
+ * Mage override : filters shipping rate collection.
22
+ */
23
+ public function getShippingRatesCollection()
24
+ {
25
+ // Check if extension enabled
26
+ if (Mage::getStoreConfig('autoship_general/general/enabled', $this->getQuote()->getStore()) != '1') {
27
+ return parent::getShippingRatesCollection();
28
+ }
29
+ // Call parent method to collect rates
30
+ parent::getShippingRatesCollection();
31
+ // Now filter out the subscription shipping method if appropriate
32
+ if (!$this->allowSubscriptionShippingMethod()) {
33
+ $subscriptionShippingMethod = Mage::getStoreConfig('autoship_subscription/subscription/shipping_method', $this->getQuote()->getStore());
34
+ // Iterate rates and look for one matching our subscription method
35
+ foreach ($this->_rates as $key => $rate) {
36
+ $rateData = $rate->getData();
37
+ if (isset($rateData['code']) && $rateData['code'] == $subscriptionShippingMethod) {
38
+ // If we find a rate matching our subscription method, remove it, making it unavailable
39
+ $this->_rates->removeItemByKey($key);
40
+ }
41
+ }
42
+ }
43
 
44
+ return $this->_rates;
45
+ }
46
+
47
+ /**
48
+ * Method to determine if shipping method configured for subscriptions should be allowed in current context
49
+ * Detect if code is running inside frontend of site
50
+ * If Autoship extension is disabled, method should be allowed
51
+ * If New Sub Page is disabled, method should be allowed
52
+ * If shipping_method_onetime_enabled is set to Enabled, method should be allowed
53
+ * If code is called from admin panel, or from API, method should be allowed
54
+ * If code is run from New Subscription page, method should be allowed
55
+ * Otherwise, if this is a normal customer check from the frontend and the Disable setting is set, method should be disallowed
56
+ *
57
+ * @return bool Is this the admin panel?
58
+ */
59
+ protected function allowSubscriptionShippingMethod()
60
+ {
61
+ // Check if extension enabled
62
+ if (Mage::getStoreConfig('autoship_general/general/enabled', $this->getQuote()->getStore()) != '1') {
63
+ return true;
64
+ }
65
+ // Check if New Sub page disabled
66
+ if (Mage::getStoreConfig('autoship_subscription/subscription/use_new_subscription_page', $this->getQuote()->getStore()) != '1') {
67
+ return true;
68
+ }
69
+ // Check shipping_method_onetime_enabled setting
70
+ if (Mage::getStoreConfig('autoship_subscription/subscription/shipping_method_onetime_enabled', $this->getQuote()->getStore()) == '1') {
71
+ return true;
72
+ }
73
+ // Check if admin store is set as current store
74
+ if (Mage::app()->getStore()->isAdmin()) {
75
+ return true;
76
+ }
77
+ // Check if admin theme area is in effect
78
+ if (Mage::getDesign()->getArea() == 'adminhtml') {
79
+ return true;
80
+ }
81
+ // Check if API call session is active
82
+ if (Mage::getModel('api/session')->isLoggedIn()) {
83
+ return true;
84
+ }
85
+ // Now we know we're on the frontend, but if we're on the new subscriptions page, we need to allow the shipping method
86
+ // Allow use of shipping method from new subscription controller
87
+ if (Mage::app()->getRequest()->getControllerName() == 'newsubscription') {
88
+ return true;
89
+ }
90
+
91
+ return false;
92
+ }
93
+
94
+ }
app/code/local/SFC/Autoship/Model/Sales/Quote/Item.php ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * @author Alan Barber <alan@cadence-labs.com>
4
+ */
5
+ class SFC_Autoship_Model_Sales_Quote_Item extends Mage_Sales_Model_Quote_Item
6
+ {
7
+ /**
8
+ * Checking if there children calculated or parent item
9
+ * when we have parent quote item and its children
10
+ *
11
+ * @return bool
12
+ */
13
+ public function isChildrenCalculated()
14
+ {
15
+ //If this item has children, and has a custom price set, we are in a trial scenario
16
+ //In that case, do not allow Magento to collect subtotal, tax, and discount based off the child items
17
+ //Magento should work this way automatically, as it doesn't fully honor custom prices
18
+ if ($this->getHasChildren() && !is_null($this->getCustomPrice())) {
19
+ return false;
20
+ }
21
+ return parent::isChildrenCalculated();
22
+ }
23
+ }
app/code/local/SFC/Autoship/Model/SalesRule/Rule/Condition/Product.php CHANGED
@@ -1,4 +1,4 @@
1
- <?php //00612
2
  /**
3
  * Subscribe Pro - Subscriptions Management Extension
4
  *
@@ -15,61 +15,134 @@
15
  *
16
  */
17
 
18
- if(!extension_loaded('ionCube Loader')){$__oc=strtolower(substr(php_uname(),0,3));$__ln='/ioncube/ioncube_loader_'.$__oc.'_'.substr(phpversion(),0,3).(($__oc=='win')?'.dll':'.so');$__oid=$__id=realpath(ini_get('extension_dir'));$__here=dirname(__FILE__);if((@$__id[1])==':'){$__id=str_replace('\\','/',substr($__id,2));$__here=str_replace('\\','/',substr($__here,2));}$__rd=str_repeat('/..',substr_count($__id,'/')).$__here.'/';$__i=strlen($__rd);while($__i--){if($__rd[$__i]=='/'){$__lp=substr($__rd,0,$__i).$__ln;if(file_exists($__oid.$__lp)){$__ln=$__lp;break;}}}@dl($__ln);}else{die('The file '.__FILE__." is corrupted. Ensure that you use binary mode when transferring files with FTP and disable the 'TAR smart cr/lf feature' if using WinZIP\n");}if(function_exists('_il_exec')){return _il_exec();}die('The file <b>'.__FILE__.'</b> has been encoded with the <a href="http://www.ioncube.com">ionCube PHP Encoder</a> and requires the free '.basename($__ln).' <a href="http://www.ioncube.com/loader_download/">ionCube PHP Loader</a> to be installed.');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
19
 
20
- ?>
21
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- +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
- 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
- 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
- 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
- ZgAPWTjkCPAkhn/Z9Zh0A+cKewT4Iso1TJUBoHbq9MOSrPwLntCDvDaK8kgvxr4arryN2AmpM+cp
47
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- +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
- 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
- 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
- 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
- fXRI+NfA6vu5k5qdIVyFoJzq4mBL7cvN3UGItMjjEZUtgC/XBsxRjet2CFNiK+nM9+zHf5stegK/
67
- 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
- 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
- LnpbXCagab94ONKsRFFc4vfvEBlv+cZrdQCZTMkJCJ+cz6lvZfEL84z2HBsbr9UNG7rtZ04KvsfC
70
- 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
- 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
- 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
- 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
- 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
75
- 0rzZKwH/c1lrAgzLZvpP
1
+ <?php
2
  /**
3
  * Subscribe Pro - Subscriptions Management Extension
4
  *
15
  *
16
  */
17
 
18
+ /**
19
+ * Special code to make us compatible with Fooman_AdvancedPromotions module
20
+ */
21
+ if (file_exists(realpath(dirname(__FILE__)) . '/../../../../community/Fooman/AdvancedPromotions/Model/SalesRule/Rule/Condition/Product.php') &&
22
+ class_exists('Fooman_AdvancedPromotions_Model_SalesRule_Rule_Condition_Product'))
23
+ {
24
+ class SFC_Autoship_Model_SalesRule_Rule_Condition_Product_Base extends Fooman_AdvancedPromotions_Model_SalesRule_Rule_Condition_Product
25
+ {
26
+ }
27
+ }
28
+ else
29
+ {
30
+ class SFC_Autoship_Model_SalesRule_Rule_Condition_Product_Base extends Mage_SalesRule_Model_Rule_Condition_Product
31
+ {
32
+ }
33
+ }
34
+
35
+ /**
36
+ * Product rule condition data model
37
+ *
38
+ */
39
+ class SFC_Autoship_Model_SalesRule_Rule_Condition_Product extends SFC_Autoship_Model_SalesRule_Rule_Condition_Product_Base
40
+ {
41
+
42
+ // Subscription status constants
43
+ const SUBSCRIPTION_STATUS_ANY = 1;
44
+ const SUBSCRIPTION_STATUS_NEW = 2;
45
+ const SUBSCRIPTION_STATUS_REORDER = 3;
46
+
47
+ /**
48
+ * Add special attributes
49
+ *
50
+ * @param array $attributes
51
+ */
52
+ protected function _addSpecialAttributes(array &$attributes)
53
+ {
54
+ parent::_addSpecialAttributes($attributes);
55
+ $attributes['quote_item_part_of_subscription'] = Mage::helper('salesrule')->__('Subscription Status');
56
+ }
57
+
58
+ /**
59
+ * Validate Product Rule Condition
60
+ *
61
+ * @param Varien_Object $object
62
+ *
63
+ * @return bool
64
+ */
65
+ public function validate(Varien_Object $object)
66
+ {
67
+ if ($this->getAttribute() == 'quote_item_part_of_subscription') {
68
+ // Check quote item attributes
69
+ $itemFulfilsSubscription = $object->getData('item_fulfils_subscription');
70
+ $itemCreatesNewSubscription = $object->getData('create_new_subscription_at_checkout');
71
+ // Get value set on rule condition
72
+ $conditionValue = $this->getValueParsed();
73
+ // Get operator set on rule condition
74
+ $op = $this->getOperatorForValidate();
75
+ // Handle different status types
76
+ switch ($conditionValue) {
77
+ case self::SUBSCRIPTION_STATUS_ANY:
78
+ $matchResult = (bool) ($itemFulfilsSubscription || $itemCreatesNewSubscription);
79
+ break;
80
+ case self::SUBSCRIPTION_STATUS_NEW:
81
+ $matchResult = (bool) $itemCreatesNewSubscription;
82
+ break;
83
+ case self::SUBSCRIPTION_STATUS_REORDER:
84
+ $matchResult = (bool) ($itemFulfilsSubscription && !$itemCreatesNewSubscription);
85
+ break;
86
+ default:
87
+ $matchResult = false;
88
+ break;
89
+ }
90
+ // Only == or != operators supported
91
+ // In case of !=, do invert $matchResult
92
+ if($op != '==') {
93
+ $matchResult = !$matchResult;
94
+ }
95
+
96
+ // Return our result
97
+ return $matchResult;
98
+ }
99
+ else {
100
+ return parent::validate($object);
101
+ }
102
+ }
103
+
104
+ /**
105
+ * Retrieve input type
106
+ *
107
+ * @return string
108
+ */
109
+ public function getInputType()
110
+ {
111
+ if ($this->getAttribute()=='quote_item_part_of_subscription') {
112
+ return 'select';
113
+ }
114
+ else {
115
+ return parent::getInputType();
116
+ }
117
+ }
118
+
119
+ /**
120
+ * Retrieve value element type
121
+ *
122
+ * @return string
123
+ */
124
+ public function getValueElementType()
125
+ {
126
+ if ($this->getAttribute()=='quote_item_part_of_subscription') {
127
+ return 'select';
128
+ }
129
+ else {
130
+ return parent::getValueElementType();
131
+ }
132
+ }
133
+
134
+ public function getValueSelectOptions()
135
+ {
136
+ if ($this->getAttribute()=='quote_item_part_of_subscription') {
137
+ return array(
138
+ array('value' => self::SUBSCRIPTION_STATUS_ANY, 'label' => Mage::helper('autoship')->__('Part of Subscription (New or Re-order)')),
139
+ array('value' => self::SUBSCRIPTION_STATUS_NEW, 'label' => Mage::helper('autoship')->__('Part of New Subscription Order')),
140
+ array('value' => self::SUBSCRIPTION_STATUS_REORDER, 'label' => Mage::helper('autoship')->__('Part of Subscription Re-order')),
141
+ );
142
+ }
143
+ else {
144
+ return parent::getValueSelectOptions();
145
+ }
146
+ }
147
 
148
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/code/local/SFC/Autoship/Model/SalesRule/Validator.php CHANGED
@@ -1,4 +1,4 @@
1
- <?php //00612
2
  /**
3
  * Subscribe Pro - Subscriptions Management Extension
4
  *
@@ -15,93 +15,227 @@
15
  *
16
  */
17
 
18
- if(!extension_loaded('ionCube Loader')){$__oc=strtolower(substr(php_uname(),0,3));$__ln='/ioncube/ioncube_loader_'.$__oc.'_'.substr(phpversion(),0,3).(($__oc=='win')?'.dll':'.so');$__oid=$__id=realpath(ini_get('extension_dir'));$__here=dirname(__FILE__);if((@$__id[1])==':'){$__id=str_replace('\\','/',substr($__id,2));$__here=str_replace('\\','/',substr($__here,2));}$__rd=str_repeat('/..',substr_count($__id,'/')).$__here.'/';$__i=strlen($__rd);while($__i--){if($__rd[$__i]=='/'){$__lp=substr($__rd,0,$__i).$__ln;if(file_exists($__oid.$__lp)){$__ln=$__lp;break;}}}@dl($__ln);}else{die('The file '.__FILE__." is corrupted. Ensure that you use binary mode when transferring files with FTP and disable the 'TAR smart cr/lf feature' if using WinZIP\n");}if(function_exists('_il_exec')){return _il_exec();}die('The file <b>'.__FILE__.'</b> has been encoded with the <a href="http://www.ioncube.com">ionCube PHP Encoder</a> and requires the free '.basename($__ln).' <a href="http://www.ioncube.com/loader_download/">ionCube PHP Loader</a> to be installed.');
19
-
20
- ?>
21
- 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
- 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
- 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
- VcqgWCD9khLcwG+fa7IQNyYrCC8v0o1xo/i9QuMF4L2C+eYWBAUsQPoQxG3yaf04Ssoyf61Xd/xf
25
- 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
- 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
- e2c8IsxsQgYY2ckdbANxlAoJ7q9WvuHvQsvLsvWxBZeiMRSUnvjs6Uc6gfqNhIge3rX0htCFvc5e
28
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- +mDKiwu5n384a1jYp9LvwkLdEyHD27RxvxClMj9MALi9X/gVqwp4WIGCDrQqsuSrCs5DBiQBEy/c
36
- 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
- 0XUoZWC+SngE8gH1GmdU0X0MAUngXn/+C5RJFUtEr1tC613G3PR73j1aFvB5VbBUVfi6FHaSztsP
38
- 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
- iixlZHROnttkM2LAtEUJWsNzBqIC+xWfCbO8+idc00z7SMWOYtaxOMz4y0EvMhkmoCNRNLkvL8NW
40
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- gcdSZqc8wBnb89ekGuK0nNEbc2QswueQ8KN/J8jbnGlU67NNGNBt4Pe2RWhh7AHv4AesE5DS1VNY
53
- 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
- +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
- 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
- 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
- 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
- CEjsk9jvfx48w9zNIHI1sJq2OiXSJjy4OtYYOazqxxkTCWMv2GoGOZZgR5kz7SOPHM9Za6N8iIbV
59
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- jKwNGGKjOM4OHJFGaqEIeW0RD2QIE05TpCR9xTz1+vODKRrwqne493jM/AeDrsziUUsY77YSV7B6
70
- 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
- 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
- 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
- OYd1TVKdOzl7zebRPbxgNwM9SZ8T5RNmM7wgyN6A8aIbrafEZcbXWJQa2ZNphSyJOKEdbD1tGzNw
74
- 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
- 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
- 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
- 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
- WDchgPTgv/1YuM2DjwM+1ruxVpeqYU6TBtI0QeS34SiUJlI4tyn8KQ184p5NhmeGfhK7YnXtXzUV
79
- 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
- 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
- 7oXN+QP0I2j0CEUGQdFR/ABvo3DmoVSjg1PcQ1++HHg4/+MBz2lSpB2NJBV1Nr+mosbKt4xaQr+c
82
- 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
- 3sVehvH7Kya61wNjKXXsCbzUrmup5nOc1hSnwjduzaZapJSmZHdFXdhZk3LG9nXTeMYxJgycQ6CP
84
- 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
- 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
- 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
- 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
- wpC+W80e0Ww+PgnaMvpvnxn8nDsXSu9PRGbAoThRVCbsnEIDhs49rKkUlKIUt0ZE3a5fl+2h7rwC
89
- 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
- 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
- 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
- +ow8nwPVP27AvgD9B8UJGmDgjEkVQxVwnGx8Zzcc2XslJzzpCWPkbk6AChrQ1Rjsbg+QPFkpGq6n
93
- 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
- SrLXVzOtZu1D2+/GToZQ6Ui3Hrj6QjviD3NdGjw7yIF1DHxQM7zIimQLkLIoefouHM8/b+SjMa78
95
- NrDwlivhOgtp9tgcnvgeHuEdOUWDHNpqU9yKH34dEaQ5BMjH+87lkfcHKrMiSnxqEHgfGCIPyNtT
96
- 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
- 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
- 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
- 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
- 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
- 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
- fTqULDIC7qKLGWalCtLVdvHIcVZjYRwFD1WfC1clzvI+y3R1Tdj3Obmfu95DwnsljYW+goJra4Cu
103
- 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
- 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
- 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
- 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
107
- HXRTcW==
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
  /**
3
  * Subscribe Pro - Subscriptions Management Extension
4
  *
15
  *
16
  */
17
 
18
+ /**
19
+ * Special code to make us compatible with Mexbs_Tieredcoupon module
20
+ */
21
+ if (file_exists(realpath(dirname(__FILE__)) . '/../../../Mexbs/Tieredcoupon/Model/SalesRule/Validator.php') &&
22
+ class_exists('Mexbs_Tieredcoupon_Model_SalesRule_Validator'))
23
+ {
24
+ class SFC_Autoship_Model_SalesRule_Validator_Base extends Mexbs_Tieredcoupon_Model_SalesRule_Validator
25
+ {
26
+ }
27
+ }
28
+ else
29
+ {
30
+ class SFC_Autoship_Model_SalesRule_Validator_Base extends Mage_SalesRule_Model_Validator
31
+ {
32
+ }
33
+ }
34
+
35
+ class SFC_Autoship_Model_SalesRule_Validator extends SFC_Autoship_Model_SalesRule_Validator_Base
36
+ {
37
+ /**
38
+ * Quote item discount calculation process
39
+ *
40
+ * @param Mage_Sales_Model_Quote_Item_Abstract $quoteItem
41
+ * @return Mage_SalesRule_Model_Validator
42
+ */
43
+ public function process(Mage_Sales_Model_Quote_Item_Abstract $quoteItem)
44
+ {
45
+ // Get quote & address & Store
46
+ $quote = $quoteItem->getQuote();
47
+ $address = $this->_getAddress($quoteItem);
48
+ $store = $quoteItem->getStore();
49
+
50
+ // Check config to see if extension functionality is enabled
51
+ if (Mage::getStoreConfig('autoship_general/general/enabled', $store) != '1') {
52
+ return parent::process($quoteItem);
53
+ }
54
+
55
+ // Save appliedRuleIds before calling parent method
56
+ $appliedRuleIds = array(
57
+ 'quoteItem' => $quoteItem->getAppliedRuleIds(),
58
+ 'quote' => $quote->getAppliedRuleIds(),
59
+ 'address' => $address->getAppliedRuleIds(),
60
+ );
61
+ // Save discountDescriptionArray
62
+ $discountDescriptionArray = $address->getDiscountDescriptionArray();
63
+
64
+ // Call parent method to process shopping cart price rules
65
+ parent::process($quoteItem);
66
+
67
+ // Check if item is part of a subscription or a subscription that is about to be created
68
+ $partOfSubscription = $this->_isItemPartOfSubscription($quoteItem, $store);
69
+
70
+ if($partOfSubscription) {
71
+
72
+ // Get platform helper
73
+ /** @var SFC_Autoship_Helper_Platform $platformHelper */
74
+ $platformHelper = Mage::helper('autoship/platform');
75
+ /** @var SFC_Autoship_Helper_Api $apiHelper */
76
+ $apiHelper = Mage::helper('autoship/api');
77
+ $apiHelper->setConfigStore($store);
78
+
79
+ // Lookup product profile, including current settings and discount
80
+ $product = Mage::helper('autoship/quote')->getRelevantProductFromQuoteItem($quoteItem);
81
+ $platformProduct = $platformHelper->getPlatformProduct($product);
82
+
83
+ // Get configuration setting for apply_discount_to_catalog_price
84
+ $applyDiscountToCatalogPrice = Mage::getStoreConfig('autoship_subscription/discount/apply_discount_to_catalog_price', $store);
85
+
86
+ // Get item price for comparison with product price
87
+ $itemPrice = $this->_getComparableItemPrice($quoteItem);
88
+ // Calculate subscription discount for item
89
+ if($platformProduct->getData('is_discount_percentage')) {
90
+ // Percent discount
91
+ // Call _getDiscountableItemPrice so we factor in tax if necessary
92
+ $subscriptionDiscount = $platformProduct->getData('discount') * $this->_getDiscountableItemPrice($quoteItem) * $quoteItem->getQty();
93
+ }
94
+ else {
95
+ // Fixed price discount
96
+ $subscriptionDiscount = $platformProduct->getData('discount') * $quoteItem->getQty();
97
+ }
98
+
99
+ $productPrice = $product->getPrice();
100
+ // Check to see if product price is discounted (by catalog price rules or special price)
101
+ $catalogDiscountApplied = ($itemPrice < $productPrice);
102
+ // Get already applied discount
103
+ $alreadyAppliedDiscount = $quoteItem->getDiscountAmount();
104
+
105
+ // Apply our subscription discount if all our biz logic is satisfied
106
+ // Flag to check if any biz logic matched
107
+ $applyOnlySubscriptionDiscount = false;
108
+ $combineSubscriptionDiscount = false;
109
+ // Check if catalog price already discounted and check config setting
110
+ if(!$catalogDiscountApplied || $applyDiscountToCatalogPrice) {
111
+ // Check the cart rule combine type config setting
112
+ switch(Mage::getStoreConfig('autoship_subscription/discount/cartrule_combine_type', $store)) {
113
+ case SFC_Autoship_Model_System_Config_Source_Cartrulediscountcombinetype::TYPE_APPLY_GREATEST:
114
+ // Check which is greater
115
+ if($subscriptionDiscount >= $alreadyAppliedDiscount) {
116
+ $applyOnlySubscriptionDiscount = true;
117
+ }
118
+ break;
119
+ case SFC_Autoship_Model_System_Config_Source_Cartrulediscountcombinetype::TYPE_APPLY_LEAST:
120
+ // Check which is less
121
+ if($subscriptionDiscount <= $alreadyAppliedDiscount) {
122
+ $applyOnlySubscriptionDiscount = true;
123
+ }
124
+ break;
125
+ case SFC_Autoship_Model_System_Config_Source_Cartrulediscountcombinetype::TYPE_APPLY_CART_DISCOUNT:
126
+ // Check if any cart rules were applied
127
+ // If any cart rules applied, go with cart rules, otherwise go with subscription discount
128
+ if($alreadyAppliedDiscount == 0) {
129
+ // Apply sub discount only if no other rules matched
130
+ $applyOnlySubscriptionDiscount = true;
131
+ }
132
+ break;
133
+ case SFC_Autoship_Model_System_Config_Source_Cartrulediscountcombinetype::TYPE_APPLY_SUBSCRIPTION:
134
+ $applyOnlySubscriptionDiscount = true;
135
+ break;
136
+ case SFC_Autoship_Model_System_Config_Source_Cartrulediscountcombinetype::TYPE_COMBINE_SUBSCRIPTION:
137
+ $combineSubscriptionDiscount = true;
138
+ break;
139
+ }
140
+ }
141
+
142
+ // Apply only subscription discount
143
+ if ($applyOnlySubscriptionDiscount) {
144
+ // Now lets apply subscription discount
145
+ $quoteItem->setDiscountAmount($subscriptionDiscount);
146
+ $quoteItem->setBaseDiscountAmount($subscriptionDiscount);
147
+
148
+ // If we are applying subscription discount, wipe out "appliedRuleIds" and descriptions added by shopping cart price rules
149
+ $quoteItem->setAppliedRuleIds($appliedRuleIds['quoteItem']);
150
+ $address->setAppliedRuleIds($appliedRuleIds['address']);
151
+ $quote->setAppliedRuleIds($appliedRuleIds['quote']);
152
+
153
+ // Since we applied subscription discount, wipe out any discount descriptions from shopping cart price rules and add in our own
154
+ $discountDescriptionArray['subscription'] = Mage::helper('autoship')->__('Subscription');
155
+ $address->setDiscountDescriptionArray($discountDescriptionArray);
156
+ }
157
+ // Combine subscription discount with already applied discounts
158
+ else if ($combineSubscriptionDiscount) {
159
+ $newDiscountAmount = $quoteItem->getDiscountAmount() + $subscriptionDiscount;
160
+ $newBaseDiscountAmount = $quoteItem->getBaseDiscountAmount() + $subscriptionDiscount;
161
+ $quoteItem->setDiscountAmount($newDiscountAmount);
162
+ $quoteItem->setBaseDiscountAmount($newBaseDiscountAmount);
163
+
164
+ // Since we applied subscription discount, add in our discount description
165
+ $discountDescriptionArray = $address->getDiscountDescriptionArray();
166
+ $discountDescriptionArray['subscription'] = Mage::helper('autoship')->__('Subscription');
167
+ $address->setDiscountDescriptionArray($discountDescriptionArray);
168
+ }
169
+ }
170
+
171
+ return $this;
172
+ }
173
+
174
+ /**
175
+ * Determine if an item is part of a subscription purchase
176
+ * @param Mage_Sales_Model_Quote_Item_Abstract $baseItem
177
+ * @param $store
178
+ * @return bool
179
+ */
180
+ protected function _isItemPartOfSubscription(Mage_Sales_Model_Quote_Item_Abstract $baseItem, $store)
181
+ {
182
+ if ($baseItem->getParentItem() && $baseItem->getParentItem()->isChildrenCalculated()) {
183
+ $quoteItem = $baseItem->getParentItem();
184
+ } else {
185
+ $quoteItem = $baseItem;
186
+ }
187
+ return ($quoteItem->getData('item_fulfils_subscription')
188
+ ||
189
+ (
190
+ $quoteItem->getData('create_new_subscription_at_checkout')
191
+ &&
192
+ (Mage::getStoreConfig('autoship_subscription/subscription/use_new_subscription_page', $store) != '1')
193
+ )
194
+ );
195
+ }
196
+
197
+ /**
198
+ * Return the total item price on which the discount can be applied.
199
+ * If the config setting allows for it, take the item price including tax, versus w/o tax
200
+ * @param Mage_Sales_Model_Quote_Item_Abstract $quoteItem
201
+ * @return float
202
+ */
203
+ protected function _getDiscountableItemPrice(Mage_Sales_Model_Quote_Item_Abstract $quoteItem)
204
+ {
205
+ if (Mage::helper("tax")->priceIncludesTax() && Mage::helper("tax")->discountTax()) {
206
+ /**
207
+ * If the settings are such that item prices include tax,
208
+ * magento doesn't factor tax into _getItemPrice.
209
+ *
210
+ * However, if item prices DON'T include tax but Apply Discounts to Taxes is set to yes,
211
+ * _getItemPrice appears to return the value with tax
212
+ */
213
+ return Mage::app()->getStore()->convertPrice($quoteItem->getPriceInclTax());
214
+ }
215
+ return $this->_getItemPrice($quoteItem);
216
+ }
217
+
218
+ /**
219
+ * Get the item price for comparison with the product
220
+ * @param Mage_Sales_Model_Quote_Item_Abstract $quoteItem
221
+ * @return float
222
+ */
223
+ protected function _getComparableItemPrice(Mage_Sales_Model_Quote_Item_Abstract $quoteItem)
224
+ {
225
+ if (Mage::helper("tax")->priceIncludesTax()) {
226
+ /**
227
+ * If Magento is set such that product prices include tax,
228
+ * _getItemPrice returns the item *without* tax
229
+ */
230
+ return Mage::app()->getStore()->convertPrice($quoteItem->getPriceInclTax());
231
+ } elseif (Mage::helper("tax")->discountTax()) {
232
+ /**
233
+ * If product price doesn't include tax but we've set Magento to apply discounts to tax,
234
+ * the result of _getItemPrice actually *includes* the tax - but for comparison to the product we remove it
235
+ */
236
+ return Mage::app()->getStore()->convertPrice($quoteItem->getCalculationPrice());
237
+ }
238
+ return $this->_getItemPrice($quoteItem);
239
+ }
240
+
241
+ }
app/code/local/SFC/Autoship/Model/Subscription.php CHANGED
@@ -21,7 +21,7 @@
21
  * This model is not persisted to the Magento DB, but instead is persisted to the platform API
22
  *
23
  */
24
- class SFC_Autoship_Model_Subscription extends Mage_Core_Model_Abstract
25
  {
26
  /**
27
  * Constants
@@ -36,6 +36,13 @@ class SFC_Autoship_Model_Subscription extends Mage_Core_Model_Abstract
36
  private $_platformProduct = null;
37
  private $_paymentProfile = null;
38
 
 
 
 
 
 
 
 
39
  protected function _construct()
40
  {
41
  parent::_construct();
@@ -64,6 +71,9 @@ class SFC_Autoship_Model_Subscription extends Mage_Core_Model_Abstract
64
  return $address;
65
  }
66
 
 
 
 
67
  public function getPaymentProfile()
68
  {
69
  if($this->_paymentProfile == null || $this->_paymentProfile->getData('cim_payment_profile_id') != $this->getData('cim_payment_profile_id')) {
@@ -110,5 +120,4 @@ class SFC_Autoship_Model_Subscription extends Mage_Core_Model_Abstract
110
 
111
  return date_format($date, 'm/d/y');
112
  }
113
-
114
  }
21
  * This model is not persisted to the Magento DB, but instead is persisted to the platform API
22
  *
23
  */
24
+ class SFC_Autoship_Model_Subscription extends Varien_Object
25
  {
26
  /**
27
  * Constants
36
  private $_platformProduct = null;
37
  private $_paymentProfile = null;
38
 
39
+ /**
40
+ * Name of object id field
41
+ *
42
+ * @var string
43
+ */
44
+ protected $_idFieldName = 'subscription_id';
45
+
46
  protected function _construct()
47
  {
48
  parent::_construct();
71
  return $address;
72
  }
73
 
74
+ /**
75
+ * @return SFC_Autoship_Model_Payment_Profile
76
+ */
77
  public function getPaymentProfile()
78
  {
79
  if($this->_paymentProfile == null || $this->_paymentProfile->getData('cim_payment_profile_id') != $this->getData('cim_payment_profile_id')) {
120
 
121
  return date_format($date, 'm/d/y');
122
  }
 
123
  }
app/code/local/SFC/Autoship/controllers/Adminhtml/{PaymentprofileController.php → SppaymentprofileController.php} RENAMED
@@ -15,7 +15,7 @@
15
  *
16
  */
17
 
18
- class SFC_Autoship_Adminhtml_PaymentprofileController extends Mage_Adminhtml_Controller_Action
19
  {
20
 
21
  /**
@@ -189,7 +189,7 @@ class SFC_Autoship_Adminhtml_PaymentprofileController extends Mage_Adminhtml_Con
189
  $vaultHelper->createPaymentProfile($profile);
190
  }
191
 
192
- Mage::getSingleton('adminhtml/session')->addSuccess(Mage::helper('adminhtml')->__('Saved credit card.'));
193
  Mage::getSingleton('adminhtml/session')->setCustomerData(false);
194
 
195
  if ($this->getRequest()->getParam('back')) {
@@ -199,7 +199,7 @@ class SFC_Autoship_Adminhtml_PaymentprofileController extends Mage_Adminhtml_Con
199
  }
200
  }
201
  catch (Exception $e) {
202
- Mage::getSingleton('adminhtml/session')->addError('Failed to save credit card!');
203
  }
204
  }
205
 
@@ -242,13 +242,13 @@ class SFC_Autoship_Adminhtml_PaymentprofileController extends Mage_Adminhtml_Con
242
  catch (\Exception $e) {
243
  $message =
244
  'Failed to delete payment profile ID #' . $profileId;
245
- Mage::getSingleton('adminhtml/session')->addError($message);
246
  }
247
  }
248
  Mage::getSingleton('adminhtml/session')->addSuccess(Mage::helper('autoship')->__('Deleted saved credit card(s).'));
249
  }
250
  catch (Exception $e) {
251
- Mage::getSingleton('adminhtml/session')->addError('Failed to delete saved credit card!');
252
  }
253
 
254
  $this->_redirect('adminhtml/customer/edit/tab/customer_info_tabs_paymentprofile', array('id' => $customerId));
15
  *
16
  */
17
 
18
+ class SFC_Autoship_Adminhtml_SppaymentprofileController extends Mage_Adminhtml_Controller_Action
19
  {
20
 
21
  /**
189
  $vaultHelper->createPaymentProfile($profile);
190
  }
191
 
192
+ Mage::getSingleton('adminhtml/session')->addSuccess(Mage::helper('autoship')->__('Saved credit card.'));
193
  Mage::getSingleton('adminhtml/session')->setCustomerData(false);
194
 
195
  if ($this->getRequest()->getParam('back')) {
199
  }
200
  }
201
  catch (Exception $e) {
202
+ Mage::getSingleton('adminhtml/session')->addError(Mage::helper('autoship')->__('Failed to save credit card!'));
203
  }
204
  }
205
 
242
  catch (\Exception $e) {
243
  $message =
244
  'Failed to delete payment profile ID #' . $profileId;
245
+ Mage::getSingleton('adminhtml/session')->addError(Mage::helper('autoship')->__($message));
246
  }
247
  }
248
  Mage::getSingleton('adminhtml/session')->addSuccess(Mage::helper('autoship')->__('Deleted saved credit card(s).'));
249
  }
250
  catch (Exception $e) {
251
+ Mage::getSingleton('adminhtml/session')->addError(Mage::helper('autoship')->__('Failed to delete saved credit card!'));
252
  }
253
 
254
  $this->_redirect('adminhtml/customer/edit/tab/customer_info_tabs_paymentprofile', array('id' => $customerId));
app/code/local/SFC/Autoship/controllers/Adminhtml/{TestconnectionbuttonController.php → SptestconnectionbuttonController.php} RENAMED
@@ -15,7 +15,7 @@
15
  *
16
  */
17
 
18
- class SFC_Autoship_Adminhtml_TestconnectionbuttonController extends Mage_Adminhtml_Controller_Action
19
  {
20
 
21
  public function testAction()
15
  *
16
  */
17
 
18
+ class SFC_Autoship_Adminhtml_SptestconnectionbuttonController extends Mage_Adminhtml_Controller_Action
19
  {
20
 
21
  public function testAction()
app/code/local/SFC/Autoship/controllers/MycreditcardsController.php CHANGED
@@ -48,7 +48,7 @@ class SFC_Autoship_MycreditcardsController extends Mage_Core_Controller_Front_Ac
48
  $customerSession = Mage::getSingleton('customer/session');
49
  // Authorize customer for this profile - in other words profile must belong to this customer
50
  if ($customerSession->getCustomerId() != $paymentProfile->getData('customer_id')) {
51
- throw new SFC_CyberSource_Helper_Gateway_Exception('Customer not authorized to edit this profile!');
52
  }
53
  }
54
 
@@ -100,7 +100,7 @@ class SFC_Autoship_MycreditcardsController extends Mage_Core_Controller_Front_Ac
100
  $this->getLayout()->getBlock('payment_profile_edit')->setData('cim_profile', $paymentProfile);
101
  }
102
  catch (Exception $e) {
103
- $coreSession->addError('Failed to load new credit credit card page!');
104
  // Send customer back to grid
105
  $this->_redirect('creditcards/*/');
106
 
@@ -139,7 +139,7 @@ class SFC_Autoship_MycreditcardsController extends Mage_Core_Controller_Front_Ac
139
  }
140
  catch (Exception $e) {
141
  Mage::log('Error: ' . $e->getMessage(), Zend_Log::ERR, SFC_Autoship_Helper_Data::LOG_FILE);
142
- $coreSession->addError('Failed to retrieve credit card for edit!');
143
  // Send customer back to grid
144
  $this->_redirect('subscriptions/mycreditcards/');
145
 
@@ -172,7 +172,7 @@ class SFC_Autoship_MycreditcardsController extends Mage_Core_Controller_Front_Ac
172
  }
173
  catch (Exception $e) {
174
  Mage::log('Error: ' . $e->getMessage(), Zend_Log::ERR, SFC_Autoship_Helper_Data::LOG_FILE);
175
- $coreSession->addError('Failed to store credit card!');
176
  }
177
 
178
  // Send customer back to grid
@@ -203,11 +203,11 @@ class SFC_Autoship_MycreditcardsController extends Mage_Core_Controller_Front_Ac
203
  // Update profile in vault
204
  $vaultHelper->updatePaymentProfile($paymentProfile);
205
 
206
- $coreSession->addSuccess('Credit card was successfully updated!');
207
  }
208
  catch (Exception $e) {
209
  Mage::log('Error: ' . $e->getMessage(), Zend_Log::ERR, SFC_Autoship_Helper_Data::LOG_FILE);
210
- $coreSession->addError('Failed to save credit card!');
211
  }
212
 
213
  // Send customer back to grid
@@ -233,10 +233,10 @@ class SFC_Autoship_MycreditcardsController extends Mage_Core_Controller_Front_Ac
233
  // Redact profile in vault
234
  $vaultHelper->redactPaymentProfile($paymentProfile);
235
 
236
- $coreSession->addSuccess('Your credit card was deleted.');
237
  }
238
  catch (Exception $e) {
239
- $coreSession->addError('Failed to delete saved credit card!');
240
  }
241
 
242
  // Send customer back to grid
48
  $customerSession = Mage::getSingleton('customer/session');
49
  // Authorize customer for this profile - in other words profile must belong to this customer
50
  if ($customerSession->getCustomerId() != $paymentProfile->getData('customer_id')) {
51
+ throw new SFC_CyberSource_Helper_Gateway_Exception($this->__('Customer not authorized to edit this profile!'));
52
  }
53
  }
54
 
100
  $this->getLayout()->getBlock('payment_profile_edit')->setData('cim_profile', $paymentProfile);
101
  }
102
  catch (Exception $e) {
103
+ $coreSession->addError($this->__('Failed to load new credit credit card page!'));
104
  // Send customer back to grid
105
  $this->_redirect('creditcards/*/');
106
 
139
  }
140
  catch (Exception $e) {
141
  Mage::log('Error: ' . $e->getMessage(), Zend_Log::ERR, SFC_Autoship_Helper_Data::LOG_FILE);
142
+ $coreSession->addError($this->__('Failed to retrieve credit card for edit!'));
143
  // Send customer back to grid
144
  $this->_redirect('subscriptions/mycreditcards/');
145
 
172
  }
173
  catch (Exception $e) {
174
  Mage::log('Error: ' . $e->getMessage(), Zend_Log::ERR, SFC_Autoship_Helper_Data::LOG_FILE);
175
+ $coreSession->addError($this->__('Failed to store credit card!'));
176
  }
177
 
178
  // Send customer back to grid
203
  // Update profile in vault
204
  $vaultHelper->updatePaymentProfile($paymentProfile);
205
 
206
+ $coreSession->addSuccess($this->__('Credit card was successfully updated!'));
207
  }
208
  catch (Exception $e) {
209
  Mage::log('Error: ' . $e->getMessage(), Zend_Log::ERR, SFC_Autoship_Helper_Data::LOG_FILE);
210
+ $coreSession->addError($this->__('Failed to save credit card!'));
211
  }
212
 
213
  // Send customer back to grid
233
  // Redact profile in vault
234
  $vaultHelper->redactPaymentProfile($paymentProfile);
235
 
236
+ $coreSession->addSuccess($this->__('Your credit card was deleted.'));
237
  }
238
  catch (Exception $e) {
239
+ $coreSession->addError($this->__('Failed to delete saved credit card!'));
240
  }
241
 
242
  // Send customer back to grid
app/code/local/SFC/Autoship/controllers/MysubscriptionsController.php CHANGED
@@ -114,6 +114,48 @@ class SFC_Autoship_MysubscriptionsController extends Mage_Core_Controller_Front_
114
  }
115
  }
116
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
117
  /**
118
  * Retrieve post data for changeAction and validate it
119
  */
@@ -378,13 +420,15 @@ class SFC_Autoship_MysubscriptionsController extends Mage_Core_Controller_Front_
378
  */
379
  public function skipAction()
380
  {
 
 
381
  try {
382
  // Get subscription id from request
383
  $subscriptionId = $this->getRequest()->getParam('id');
384
  // Call API to delete subscription
385
- Mage::helper('autoship/platform')->skipSubscription($subscriptionId);
386
  // Now call platform to get subscription again
387
- $subscription = Mage::helper('autoship/platform')->getSubscription($subscriptionId);
388
  // Return the rendered html for this new subscription state
389
  echo $this->getLayout()->createBlock('autoship/mysubscriptions_subscription')
390
  ->setTemplate('autoship/mysubscriptions/subscription.phtml')
@@ -402,13 +446,41 @@ class SFC_Autoship_MysubscriptionsController extends Mage_Core_Controller_Front_
402
  */
403
  public function cancelAction()
404
  {
 
 
405
  try {
406
  // Get subscription id from request
407
  $subscriptionId = $this->getRequest()->getParam('id');
408
  // Call API to delete subscription
409
- Mage::helper('autoship/platform')->cancelSubscription($subscriptionId);
410
  // Now call platform to get subscription again
411
- $subscription = Mage::helper('autoship/platform')->getSubscription($subscriptionId);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
412
  // Return the rendered html for this new subscription state
413
  echo $this->getLayout()->createBlock('autoship/mysubscriptions_subscription')
414
  ->setTemplate('autoship/mysubscriptions/subscription.phtml')
@@ -426,13 +498,15 @@ class SFC_Autoship_MysubscriptionsController extends Mage_Core_Controller_Front_
426
  */
427
  public function restartAction()
428
  {
 
 
429
  try {
430
  // Get subscription id from request
431
  $subscriptionId = $this->getRequest()->getParam('id');
432
  // Call API to delete subscription
433
- Mage::helper('autoship/platform')->restartSubscription($subscriptionId);
434
  // Now call platform to get subscription again
435
- $subscription = Mage::helper('autoship/platform')->getSubscription($subscriptionId);
436
  // Return the rendered html for this new subscription state
437
  echo $this->getLayout()->createBlock('autoship/mysubscriptions_subscription')
438
  ->setTemplate('autoship/mysubscriptions/subscription.phtml')
@@ -492,7 +566,7 @@ class SFC_Autoship_MysubscriptionsController extends Mage_Core_Controller_Front_
492
  $model->save();
493
  }
494
  catch (Exception $e) {
495
- Mage::throwException('Failed to save credit card!');
496
  }
497
 
498
  // Return new model
@@ -524,7 +598,7 @@ class SFC_Autoship_MysubscriptionsController extends Mage_Core_Controller_Front_
524
  $model->save();
525
  }
526
  catch (Exception $e) {
527
- Mage::throwException('Failed to save credit card!');
528
  }
529
 
530
  // Return new model
@@ -562,7 +636,7 @@ class SFC_Autoship_MysubscriptionsController extends Mage_Core_Controller_Front_
562
  $model->save();
563
  }
564
  catch (Exception $e) {
565
- Mage::throwException('Failed to save credit card!');
566
  }
567
 
568
  // Return new model
@@ -570,36 +644,6 @@ class SFC_Autoship_MysubscriptionsController extends Mage_Core_Controller_Front_
570
  'payment_token' => $model->getData('payment_token'),
571
  'creditcard_last_digits' => $model->getData('customer_cardnumber'),
572
  );
573
-
574
- case SFC_Autoship_Helper_Platform::PAY_METHOD_CODE_PARADOX_TRANSARMOR:
575
- // Create payment using paradox ext
576
- $payment = array(
577
- 'firstname' => $customer->getData('firstname'),
578
- 'lastname' => $customer->getData('lastname'),
579
- 'cc_type' => $data['cc_type'],
580
- 'cc_type' => $data['cc_type'],
581
- 'cc_number' => $data['cc_number'],
582
- 'cc_exp_month' => $data['cc_exp_month'],
583
- 'cc_exp_year' => $data['cc_exp_year'],
584
- );
585
- // If customer has selected billing address, add billing address data to new CIM profile
586
- if (strlen($subscription->getBillingAddressId())) {
587
- $billingAddress = Mage::getModel('customer/address')->load($subscription->getBillingAddressId());
588
- $payment['address1'] = $billingAddress->getStreet(1);
589
- $payment['city'] = $billingAddress->getData('city');
590
- $payment['state'] = $billingAddress->getData('region');
591
- $payment['zip'] = $billingAddress->getData('postcode');
592
- $payment['country'] = $billingAddress->getData('country_id');
593
- }
594
- $paymentId = Mage::getModel('transarmor/payment')->createCustomerPaymentProfile( $payment, $customer );
595
- $paymentProfile = Mage::getModel('transarmor/payment')->getPaymentInfoById($paymentId);
596
-
597
- // Return new model
598
- return array(
599
- 'payment_token' => $paymentProfile->getData('trans_id'),
600
- 'creditcard_last_digits' => $paymentProfile->getData('last4'),
601
- );
602
-
603
  }
604
  }
605
 
@@ -645,7 +689,7 @@ class SFC_Autoship_MysubscriptionsController extends Mage_Core_Controller_Front_
645
  else {
646
  $html = '';
647
  foreach ($errors as $error) {
648
- $html .= '<li class="error">' . $error . '</li>';
649
  }
650
 
651
  return $html;
@@ -663,7 +707,7 @@ class SFC_Autoship_MysubscriptionsController extends Mage_Core_Controller_Front_
663
  Mage::log($e->getMessage() . "\n" . $e->getTraceAsString());
664
  Mage::logException($e);
665
  // Output error message formatted for display
666
- echo '<li class="error">' . $e->getMessage() . '</li>';
667
  }
668
 
669
  /**
@@ -673,16 +717,16 @@ class SFC_Autoship_MysubscriptionsController extends Mage_Core_Controller_Front_
673
  {
674
  switch ($eCim->getResponse()->getMessageCode()) {
675
  case 'E00014':
676
- return ('A required field was not entered for credit card!');
677
  break;
678
  case 'E00039':
679
- return ('Credit card number is already saved in your account!');
680
  break;
681
  case 'E00042':
682
- return ('You have already saved the maximum number of credit cards!');
683
  break;
684
  default:
685
- return ('Failed to save credit card with gateway!');
686
  break;
687
  }
688
  }
114
  }
115
  }
116
 
117
+ public function changeSkuAction()
118
+ {
119
+ try {
120
+ $data = $this->getRequest()->getPost();
121
+
122
+ if (isset($data['product_sku']) && strlen($data['product_sku'])) {
123
+ //Ensure we have a valid product that is active for subscriptions
124
+ $product = Mage::getModel("catalog/product")->loadByAttribute('sku', $data['product_sku']);
125
+ if ($product->getId() && $product->getData('subscription_enabled')) {
126
+ $data['product_id'] = $product->getId();
127
+ } else {
128
+ Mage::throwException($this->__("Please supply a valid product sku enabled for subscriptions."));
129
+ }
130
+ }
131
+
132
+ if (isset($data['id'])) {
133
+ $data['subscription_id'] = $data['id'];
134
+ }
135
+
136
+ if (!isset($data['subscription_id'])) {
137
+ Mage::throwException($this->__("Please supply a valid subscription id."));
138
+ }
139
+ $subscription = Mage::helper("autoship/platform")->getSubscription($data['subscription_id']);
140
+
141
+ //Update the SKU data
142
+ $subscription
143
+ ->setProductSku($data['product_sku'])
144
+ ->setProductId($data['product_id']);
145
+
146
+ //Update the subscription
147
+ Mage::helper('autoship/platform')->updateSubscription($subscription->getSubscriptionId(), $subscription);
148
+
149
+ echo $this->getLayout()->createBlock('autoship/mysubscriptions_subscription')
150
+ ->setTemplate('autoship/mysubscriptions/subscription.phtml')
151
+ ->setSubscription($subscription)
152
+ ->toHtml();
153
+ } Catch (Exception $e) {
154
+ $this->handleAjaxException($e);
155
+ }
156
+ }
157
+
158
+
159
  /**
160
  * Retrieve post data for changeAction and validate it
161
  */
420
  */
421
  public function skipAction()
422
  {
423
+ /** @var SFC_Autoship_Helper_Platform $platformHelper */
424
+ $platformHelper = Mage::helper('autoship/platform');
425
  try {
426
  // Get subscription id from request
427
  $subscriptionId = $this->getRequest()->getParam('id');
428
  // Call API to delete subscription
429
+ $platformHelper->skipSubscription($subscriptionId);
430
  // Now call platform to get subscription again
431
+ $subscription = $platformHelper->getSubscription($subscriptionId);
432
  // Return the rendered html for this new subscription state
433
  echo $this->getLayout()->createBlock('autoship/mysubscriptions_subscription')
434
  ->setTemplate('autoship/mysubscriptions/subscription.phtml')
446
  */
447
  public function cancelAction()
448
  {
449
+ /** @var SFC_Autoship_Helper_Platform $platformHelper */
450
+ $platformHelper = Mage::helper('autoship/platform');
451
  try {
452
  // Get subscription id from request
453
  $subscriptionId = $this->getRequest()->getParam('id');
454
  // Call API to delete subscription
455
+ $platformHelper->cancelSubscription($subscriptionId);
456
  // Now call platform to get subscription again
457
+ $subscription = $platformHelper->getSubscription($subscriptionId);
458
+ // Return the rendered html for this new subscription state
459
+ echo $this->getLayout()->createBlock('autoship/mysubscriptions_subscription')
460
+ ->setTemplate('autoship/mysubscriptions/subscription.phtml')
461
+ ->setSubscription($subscription)
462
+ ->toHtml();
463
+ }
464
+ catch (Exception $e) {
465
+ $this->handleAjaxException($e);
466
+ }
467
+ }
468
+
469
+ /**
470
+ * Pause subscription action
471
+ *
472
+ */
473
+ public function pauseAction()
474
+ {
475
+ /** @var SFC_Autoship_Helper_Platform $platformHelper */
476
+ $platformHelper = Mage::helper('autoship/platform');
477
+ try {
478
+ // Get subscription id from request
479
+ $subscriptionId = $this->getRequest()->getParam('id');
480
+ // Call API to delete subscription
481
+ $platformHelper->pauseSubscription($subscriptionId);
482
+ // Now call platform to get subscription again
483
+ $subscription = $platformHelper->getSubscription($subscriptionId);
484
  // Return the rendered html for this new subscription state
485
  echo $this->getLayout()->createBlock('autoship/mysubscriptions_subscription')
486
  ->setTemplate('autoship/mysubscriptions/subscription.phtml')
498
  */
499
  public function restartAction()
500
  {
501
+ /** @var SFC_Autoship_Helper_Platform $platformHelper */
502
+ $platformHelper = Mage::helper('autoship/platform');
503
  try {
504
  // Get subscription id from request
505
  $subscriptionId = $this->getRequest()->getParam('id');
506
  // Call API to delete subscription
507
+ $platformHelper->restartSubscription($subscriptionId);
508
  // Now call platform to get subscription again
509
+ $subscription = $platformHelper->getSubscription($subscriptionId);
510
  // Return the rendered html for this new subscription state
511
  echo $this->getLayout()->createBlock('autoship/mysubscriptions_subscription')
512
  ->setTemplate('autoship/mysubscriptions/subscription.phtml')
566
  $model->save();
567
  }
568
  catch (Exception $e) {
569
+ Mage::throwException($this->__('Failed to save credit card!'));
570
  }
571
 
572
  // Return new model
598
  $model->save();
599
  }
600
  catch (Exception $e) {
601
+ Mage::throwException($this->__('Failed to save credit card!'));
602
  }
603
 
604
  // Return new model
636
  $model->save();
637
  }
638
  catch (Exception $e) {
639
+ Mage::throwException($this->__('Failed to save credit card!'));
640
  }
641
 
642
  // Return new model
644
  'payment_token' => $model->getData('payment_token'),
645
  'creditcard_last_digits' => $model->getData('customer_cardnumber'),
646
  );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
647
  }
648
  }
649
 
689
  else {
690
  $html = '';
691
  foreach ($errors as $error) {
692
+ $html .= '<li class="error">' . $this->__($error) . '</li>';
693
  }
694
 
695
  return $html;
707
  Mage::log($e->getMessage() . "\n" . $e->getTraceAsString());
708
  Mage::logException($e);
709
  // Output error message formatted for display
710
+ echo '<li class="error">' . $this->__($e->getMessage()) . '</li>';
711
  }
712
 
713
  /**
717
  {
718
  switch ($eCim->getResponse()->getMessageCode()) {
719
  case 'E00014':
720
+ return $this->__('A required field was not entered for credit card!');
721
  break;
722
  case 'E00039':
723
+ return $this->__('Credit card number is already saved in your account!');
724
  break;
725
  case 'E00042':
726
+ return $this->__('You have already saved the maximum number of credit cards!');
727
  break;
728
  default:
729
+ return $this->__('Failed to save credit card with gateway!');
730
  break;
731
  }
732
  }
app/code/local/SFC/Autoship/controllers/NewsubscriptionController.php CHANGED
@@ -112,12 +112,12 @@ class SFC_Autoship_NewsubscriptionController extends Mage_Core_Controller_Front_
112
  }
113
  else {
114
  // No product identifying parameter passed
115
- Mage::throwException('No product_id or product_sku parameter passed!');
116
  }
117
  }
118
  // If there is no valid product, error out
119
  if (!strlen($product->getId())) {
120
- Mage::throwException('Invalid product requested!');
121
  }
122
  $processedParameters['product'] = $product;
123
  $processedParameters['product_id'] = $product->getId();
@@ -181,11 +181,11 @@ class SFC_Autoship_NewsubscriptionController extends Mage_Core_Controller_Front_
181
  $platformProduct = Mage::helper('autoship/platform')->getPlatformProduct($product);
182
  if($subscription->getData('qty') < $platformProduct->getData('min_qty')) {
183
  $subscription->setData('qty', $platformProduct->getData('min_qty'));
184
- Mage::getSingleton('customer/session')->addError('Minimum quantity for subscription is ' . $platformProduct->getData('min_qty'));
185
  }
186
  if($subscription->getData('qty') > $platformProduct->getData('max_qty')) {
187
  $subscription->setData('qty', $platformProduct->getData('max_qty'));
188
- Mage::getSingleton('customer/session')->addError('Maximum quantity for subscription is ' . $platformProduct->getData('max_qty'));
189
  }
190
 
191
  // Return the new subscription model
@@ -225,7 +225,7 @@ class SFC_Autoship_NewsubscriptionController extends Mage_Core_Controller_Front_
225
  catch (Exception $e) {
226
  Mage::log($e->getMessage());
227
  Mage::logException($e);
228
- echo '<li class="error">' . $e->getMessage() . '</li>';
229
 
230
  return;
231
  }
@@ -267,7 +267,7 @@ class SFC_Autoship_NewsubscriptionController extends Mage_Core_Controller_Front_
267
  Mage::throwException($this->addErrorFromCimException($eCim));
268
  }
269
  catch (Exception $e) {
270
- Mage::throwException('Failed to save credit card!');
271
  }
272
 
273
  // Return new model
@@ -316,7 +316,7 @@ class SFC_Autoship_NewsubscriptionController extends Mage_Core_Controller_Front_
316
  $addressId = $this->saveAddress($data['billing']);
317
  }
318
  if (!is_numeric($addressId)) {
319
- Mage::throwException('Failed to save address!');
320
  }
321
  // Set billing address on subscription
322
  $subscription->setBillingAddressId($addressId);
@@ -343,7 +343,7 @@ class SFC_Autoship_NewsubscriptionController extends Mage_Core_Controller_Front_
343
  catch (Exception $e) {
344
  Mage::log($e->getMessage());
345
  Mage::logException($e);
346
- echo '<li class="error">' . $e->getMessage() . '</li>';
347
 
348
  return;
349
  }
@@ -372,7 +372,7 @@ class SFC_Autoship_NewsubscriptionController extends Mage_Core_Controller_Front_
372
  $addressId = $this->saveAddress($data['shipping']);
373
  }
374
  if (!is_numeric($addressId)) {
375
- Mage::throwException('Failed to save address!');
376
  }
377
  // Set shipping address on subscription
378
  $subscription->setShippingAddressId($addressId);
@@ -399,7 +399,7 @@ class SFC_Autoship_NewsubscriptionController extends Mage_Core_Controller_Front_
399
  catch (Exception $e) {
400
  Mage::log($e->getMessage());
401
  Mage::logException($e);
402
- echo '<li class="error">' . $e->getMessage() . '</li>';
403
 
404
  return;
405
  }
@@ -425,7 +425,7 @@ class SFC_Autoship_NewsubscriptionController extends Mage_Core_Controller_Front_
425
  }
426
  catch (Exception $e) {
427
  Mage::log($e->getMessage() . '\n' . $e->getTraceAsString());
428
- echo '<li class="error">' . $e->getMessage() . '</li>';
429
  }
430
  // Load and render layout
431
  $this->loadLayout(false);
@@ -475,10 +475,10 @@ class SFC_Autoship_NewsubscriptionController extends Mage_Core_Controller_Front_
475
  Mage::log($e->getMessage());
476
  Mage::logException($e);
477
  if (strpos($e->getMessage(), '1062 Duplicate entry')) {
478
- echo '<li class="error">You already have a subscription to this product.</li>';
479
  }
480
  else {
481
- echo '<li class="error">' . $e->getMessage() . '</li>';
482
  }
483
  }
484
 
@@ -526,7 +526,7 @@ class SFC_Autoship_NewsubscriptionController extends Mage_Core_Controller_Front_
526
  else {
527
  $html = '';
528
  foreach ($errors as $error) {
529
- $html .= '<li class="error">' . $error . '</li>';
530
  }
531
 
532
  return $html;
@@ -541,16 +541,16 @@ class SFC_Autoship_NewsubscriptionController extends Mage_Core_Controller_Front_
541
  {
542
  switch ($eCim->getResponse()->getMessageCode()) {
543
  case 'E00014':
544
- return ('A required field was not entered for credit card!');
545
  break;
546
  case 'E00039':
547
- return ('Credit card number is already saved in your account!');
548
  break;
549
  case 'E00042':
550
- return ('You have already saved the maximum number of credit cards!');
551
  break;
552
  default:
553
- return ('Failed to save credit card with gateway!');
554
  break;
555
  }
556
  }
112
  }
113
  else {
114
  // No product identifying parameter passed
115
+ Mage::throwException($this->__('No product_id or product_sku parameter passed!'));
116
  }
117
  }
118
  // If there is no valid product, error out
119
  if (!strlen($product->getId())) {
120
+ Mage::throwException($this->__('Invalid product requested!'));
121
  }
122
  $processedParameters['product'] = $product;
123
  $processedParameters['product_id'] = $product->getId();
181
  $platformProduct = Mage::helper('autoship/platform')->getPlatformProduct($product);
182
  if($subscription->getData('qty') < $platformProduct->getData('min_qty')) {
183
  $subscription->setData('qty', $platformProduct->getData('min_qty'));
184
+ Mage::getSingleton('customer/session')->addError($this->__('Minimum quantity for subscription is %s', $platformProduct->getData('min_qty')));
185
  }
186
  if($subscription->getData('qty') > $platformProduct->getData('max_qty')) {
187
  $subscription->setData('qty', $platformProduct->getData('max_qty'));
188
+ Mage::getSingleton('customer/session')->addError($this->__('Maximum quantity for subscription is %s', $platformProduct->getData('max_qty')));
189
  }
190
 
191
  // Return the new subscription model
225
  catch (Exception $e) {
226
  Mage::log($e->getMessage());
227
  Mage::logException($e);
228
+ echo '<li class="error">' . $this->__($e->getMessage()) . '</li>';
229
 
230
  return;
231
  }
267
  Mage::throwException($this->addErrorFromCimException($eCim));
268
  }
269
  catch (Exception $e) {
270
+ Mage::throwException($this->__('Failed to save credit card!'));
271
  }
272
 
273
  // Return new model
316
  $addressId = $this->saveAddress($data['billing']);
317
  }
318
  if (!is_numeric($addressId)) {
319
+ Mage::throwException($this->__('Failed to save address!'));
320
  }
321
  // Set billing address on subscription
322
  $subscription->setBillingAddressId($addressId);
343
  catch (Exception $e) {
344
  Mage::log($e->getMessage());
345
  Mage::logException($e);
346
+ echo '<li class="error">' . $this->__($e->getMessage()) . '</li>';
347
 
348
  return;
349
  }
372
  $addressId = $this->saveAddress($data['shipping']);
373
  }
374
  if (!is_numeric($addressId)) {
375
+ Mage::throwException($this->__('Failed to save address!'));
376
  }
377
  // Set shipping address on subscription
378
  $subscription->setShippingAddressId($addressId);
399
  catch (Exception $e) {
400
  Mage::log($e->getMessage());
401
  Mage::logException($e);
402
+ echo '<li class="error">' . $this->__($e->getMessage()) . '</li>';
403
 
404
  return;
405
  }
425
  }
426
  catch (Exception $e) {
427
  Mage::log($e->getMessage() . '\n' . $e->getTraceAsString());
428
+ echo '<li class="error">' . $this->__($e->getMessage()) . '</li>';
429
  }
430
  // Load and render layout
431
  $this->loadLayout(false);
475
  Mage::log($e->getMessage());
476
  Mage::logException($e);
477
  if (strpos($e->getMessage(), '1062 Duplicate entry')) {
478
+ echo '<li class="error">' . $this->__("You already have a subscription to this product.") . '</li>';
479
  }
480
  else {
481
+ echo '<li class="error">' . $this->__($e->getMessage()) . '</li>';
482
  }
483
  }
484
 
526
  else {
527
  $html = '';
528
  foreach ($errors as $error) {
529
+ $html .= '<li class="error">' . $this->__($error) . '</li>';
530
  }
531
 
532
  return $html;
541
  {
542
  switch ($eCim->getResponse()->getMessageCode()) {
543
  case 'E00014':
544
+ return $this->__('A required field was not entered for credit card!');
545
  break;
546
  case 'E00039':
547
+ return $this->__('Credit card number is already saved in your account!');
548
  break;
549
  case 'E00042':
550
+ return $this->__('You have already saved the maximum number of credit cards!');
551
  break;
552
  default:
553
+ return $this->__('Failed to save credit card with gateway!');
554
  break;
555
  }
556
  }
app/code/local/SFC/Autoship/etc/adminhtml.xml CHANGED
@@ -37,6 +37,14 @@
37
  </config>
38
  </children>
39
  </system>
 
 
 
 
 
 
 
 
40
  </children>
41
  </admin>
42
  </resources>
37
  </config>
38
  </children>
39
  </system>
40
+ <customer>
41
+ <children>
42
+ <paymentprofiles translate="title" module="autoship">
43
+ <title>Credit Cards (Subscribe Pro Vault)</title>
44
+ <sort_order>1000</sort_order>
45
+ </paymentprofiles>
46
+ </children>
47
+ </customer>
48
  </children>
49
  </admin>
50
  </resources>
app/code/local/SFC/Autoship/etc/api.xml ADDED
@@ -0,0 +1,76 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <config>
3
+ <api>
4
+ <resources>
5
+ <sp_cart translate="title" module="autoship">
6
+ <title>autoship</title>
7
+ <model>autoship/api_cart_api</model>
8
+ <acl>autoship/sp_cart</acl>
9
+ <methods>
10
+ <set_addresses translate="title" module="autoship">
11
+ <title>Set Addresses</title>
12
+ <method>setAddresses</method>
13
+ <acl>autoship/sp_cart/set_addresses</acl>
14
+ </set_addresses>
15
+ <set_customer translate="title" module="autoship">
16
+ <title>Set Customer</title>
17
+ <method>setCustomer</method>
18
+ <acl>autoship/sp_cart/set_customer</acl>
19
+ </set_customer>
20
+ </methods>
21
+ <faults module="autoship">
22
+ <sp_cart_address_format>
23
+ <code>94101</code >
24
+ <message>Address data was not formatted properly.</message>
25
+ </sp_cart_address_format>
26
+ <sp_cart_address_mode>
27
+ <code>94102</code >
28
+ <message>Address mode is not valid.</message>
29
+ </sp_cart_address_mode>
30
+ <sp_cart_address_save>
31
+ <code>94103</code >
32
+ <message>There was an error saving addresses for the quote.</message>
33
+ </sp_cart_address_save>
34
+ <sp_cart_address_country_code>
35
+ <code>94104</code >
36
+ <message>Country code didn't match a known 2 or 3 digit ISO country code.</message>
37
+ </sp_cart_address_country_code>
38
+ <sp_cart_address_validation>
39
+ <code>94105</code>
40
+ <message>Address didn't pass Magento validation.</message>
41
+ </sp_cart_address_validation>
42
+ <sp_cart_customer_format>
43
+ <code>95101</code >
44
+ <message>Customer data was not formatted properly.</message>
45
+ </sp_cart_customer_format>
46
+ <sp_cart_customer_not_found>
47
+ <code>95102</code >
48
+ <message>Customer was not found.</message>
49
+ </sp_cart_customer_not_found>
50
+ <sp_cart_customer_not_set>
51
+ <code>95103</code >
52
+ <message>Failed to set customer on quote.</message>
53
+ </sp_cart_customer_not_set>
54
+ </faults>
55
+ </sp_cart>
56
+ </resources>
57
+ <acl>
58
+ <resources>
59
+ <autoship translate="title" module="autoship">
60
+ <title>autoship</title>
61
+ <sort_order>1</sort_order>
62
+ <sp_cart translate="title" module="autoship">
63
+ <title>Subscribe Pro Cart</title>
64
+ <sort_order>2000</sort_order>
65
+ <set_addresses translate="title" module="autoship">
66
+ <title>Set Addresses</title>
67
+ </set_addresses>
68
+ <set_customer translate="title" module="autoship">
69
+ <title>Set Customer</title>
70
+ </set_customer>
71
+ </sp_cart>
72
+ </autoship>
73
+ </resources>
74
+ </acl>
75
+ </api>
76
+ </config>
app/code/local/SFC/Autoship/etc/config.xml CHANGED
@@ -19,7 +19,7 @@
19
  <config>
20
  <modules>
21
  <SFC_Autoship>
22
- <version>1.3.1.14</version>
23
  </SFC_Autoship>
24
  </modules>
25
  <global>
@@ -49,8 +49,12 @@
49
  <onepage_payment_methods>SFC_Autoship_Block_Checkout_Onepage_Payment_Methods</onepage_payment_methods>
50
  </rewrite>
51
  </checkout>
52
-
53
-
 
 
 
 
54
  </blocks>
55
  <models>
56
  <autoship>
@@ -89,9 +93,6 @@
89
  <rewrite>
90
  <cart_product_api>SFC_Autoship_Model_Checkout_Cart_Product_Api</cart_product_api>
91
  </rewrite>
92
- <rewrite>
93
- <cart_payment_api>SFC_Autoship_Model_Checkout_Cart_Payment_Api</cart_payment_api>
94
- </rewrite>
95
  <rewrite>
96
  <cart_api>SFC_Autoship_Model_Checkout_Cart_Api</cart_api>
97
  </rewrite>
@@ -99,6 +100,7 @@
99
  <sales>
100
  <rewrite>
101
  <quote_address>SFC_Autoship_Model_Quote_Address</quote_address>
 
102
  </rewrite>
103
  </sales>
104
  <salesrule>
@@ -170,6 +172,24 @@
170
  </subscription_checkout_cart_update_items_after>
171
  </observers>
172
  </checkout_cart_update_items_after>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
173
  <sales_convert_quote_item_to_order_item>
174
  <observers>
175
  <subscription_sales_convert_quote_item_to_order_item>
@@ -214,6 +234,15 @@
214
  </checkout_allow_guest>
215
  </observers>
216
  </checkout_allow_guest>
 
 
 
 
 
 
 
 
 
217
  </events>
218
 
219
  </global>
@@ -245,13 +274,13 @@
245
  <!-- Admin panel routers -->
246
  <admin>
247
  <routers>
248
- <autoship_admin>
249
- <use>admin</use>
250
  <args>
251
- <module>SFC_Autoship</module>
252
- <frontName>subscriptions_admin</frontName>
 
253
  </args>
254
- </autoship_admin>
255
  </routers>
256
  </admin>
257
  <!-- Admin panel html changes -->
19
  <config>
20
  <modules>
21
  <SFC_Autoship>
22
+ <version>1.3.2.6</version>
23
  </SFC_Autoship>
24
  </modules>
25
  <global>
49
  <onepage_payment_methods>SFC_Autoship_Block_Checkout_Onepage_Payment_Methods</onepage_payment_methods>
50
  </rewrite>
51
  </checkout>
52
+ <adminhtml>
53
+ <rewrite>
54
+ <sales_order_create_billing_method_form>SFC_Autoship_Block_Adminhtml_Sales_Order_Create_Billing_Method_Form</sales_order_create_billing_method_form>
55
+ <customer_edit_tabs>SFC_Autoship_Block_Adminhtml_Customer_Edit_Tabs</customer_edit_tabs>
56
+ </rewrite>
57
+ </adminhtml>
58
  </blocks>
59
  <models>
60
  <autoship>
93
  <rewrite>
94
  <cart_product_api>SFC_Autoship_Model_Checkout_Cart_Product_Api</cart_product_api>
95
  </rewrite>
 
 
 
96
  <rewrite>
97
  <cart_api>SFC_Autoship_Model_Checkout_Cart_Api</cart_api>
98
  </rewrite>
100
  <sales>
101
  <rewrite>
102
  <quote_address>SFC_Autoship_Model_Quote_Address</quote_address>
103
+ <quote_item>SFC_Autoship_Model_Sales_Quote_Item</quote_item>
104
  </rewrite>
105
  </sales>
106
  <salesrule>
172
  </subscription_checkout_cart_update_items_after>
173
  </observers>
174
  </checkout_cart_update_items_after>
175
+ <adminhtml_sales_order_create_process_data>
176
+ <observers>
177
+ <subscription_adminhtml_sales_order_create_process_data>
178
+ <type>singleton</type>
179
+ <class>autoship/observer</class>
180
+ <method>onAdminhtmlSalesOrderCreateProcessData</method>
181
+ </subscription_adminhtml_sales_order_create_process_data>
182
+ </observers>
183
+ </adminhtml_sales_order_create_process_data>
184
+ <sales_convert_order_item_to_quote_item>
185
+ <observers>
186
+ <subscription_sales_convert_order_item_to_quote_item>
187
+ <type>singleton</type>
188
+ <class>autoship/observer</class>
189
+ <method>onSalesConvertOrderItemToQuoteItem</method>
190
+ </subscription_sales_convert_order_item_to_quote_item>
191
+ </observers>
192
+ </sales_convert_order_item_to_quote_item>
193
  <sales_convert_quote_item_to_order_item>
194
  <observers>
195
  <subscription_sales_convert_quote_item_to_order_item>
234
  </checkout_allow_guest>
235
  </observers>
236
  </checkout_allow_guest>
237
+ <customer_save_after>
238
+ <observers>
239
+ <subscription_customer_save_after>
240
+ <type>singleton</type>
241
+ <class>autoship/observer</class>
242
+ <method>onCustomerSave</method>
243
+ </subscription_customer_save_after>
244
+ </observers>
245
+ </customer_save_after>
246
  </events>
247
 
248
  </global>
274
  <!-- Admin panel routers -->
275
  <admin>
276
  <routers>
277
+ <adminhtml>
 
278
  <args>
279
+ <modules>
280
+ <SFC_Autoship after="Mage_Adminhtml">SFC_Autoship_Adminhtml</SFC_Autoship>
281
+ </modules>
282
  </args>
283
+ </adminhtml>
284
  </routers>
285
  </admin>
286
  <!-- Admin panel html changes -->
app/code/local/SFC/Autoship/etc/system.xml CHANGED
@@ -325,7 +325,7 @@
325
  <show_in_default>1</show_in_default>
326
  <show_in_website>1</show_in_website>
327
  <show_in_store>0</show_in_store>
328
- <comment>NOTE: CVV field is always shown in Admin panel ordering interface. This configuration setting turns the CVV field on and off for the customer-facing frontend features.</comment>
329
  </useccv>
330
  <currency translate="label">
331
  <label>Accepted Currency</label>
325
  <show_in_default>1</show_in_default>
326
  <show_in_website>1</show_in_website>
327
  <show_in_store>0</show_in_store>
328
+ <comment>NOTE: CVV field is always shown in Admin panel ordering interface. This configuration setting turns the CVV field on and off for the customer-facing frontend features. Also, please note the CVV field will never be shown for third-party payment profiles.</comment>
329
  </useccv>
330
  <currency translate="label">
331
  <label>Accepted Currency</label>
app/code/local/SFC/Autoship/sql/sfc_autoship_setup/mysql4-install-1.3.1.8.php CHANGED
@@ -38,7 +38,7 @@ if (!$installer->getAttributeId('catalog_product', 'subscription_enabled')) {
38
  'global' => Mage_Catalog_Model_Resource_Eav_Attribute::SCOPE_WEBSITE,
39
  'visible' => true,
40
  'required' => false,
41
- 'apply_to' => 'simple,bundle,configurable',
42
  'user_defined' => false,
43
  'searchable' => false,
44
  'filterable' => false,
38
  'global' => Mage_Catalog_Model_Resource_Eav_Attribute::SCOPE_WEBSITE,
39
  'visible' => true,
40
  'required' => false,
41
+ 'apply_to' => 'simple,bundle,configurable,virtual,downloadable',
42
  'user_defined' => false,
43
  'searchable' => false,
44
  'filterable' => false,
app/code/local/SFC/Autoship/sql/sfc_autoship_setup/mysql4-upgrade-1.3.1.15-1.3.1.16.php ADDED
@@ -0,0 +1,35 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Subscribe Pro - Subscriptions Management Extension
4
+ *
5
+ * PHP version 5
6
+ *
7
+ * LICENSE: This source file is subject to commercial source code license of SUBSCRIBE PRO INC.
8
+ *
9
+ * @category SFC
10
+ * @package SFC_Autoship
11
+ * @author Garth Brantley <garth@subscribepro.com>
12
+ * @copyright 2009-2014 SUBSCRIBE PRO INC. All Rights Reserved.
13
+ * @license http://www.subscribepro.com/terms-of-service/ Subscribe Pro Terms of Service
14
+ * @link http://www.subscribepro.com/
15
+ *
16
+ */
17
+
18
+ /**
19
+ * Installer
20
+ */
21
+ $installer = $this;
22
+ $installer->startSetup();
23
+
24
+ // Update subscription_enabled product attribute to have apply to all product types except grouped
25
+ $installer->updateAttribute(
26
+ 'catalog_product',
27
+ 'subscription_enabled',
28
+ 'apply_to',
29
+ 'simple,configurable,bundle,virtual,downloadable'
30
+ );
31
+
32
+ /**
33
+ * Clean up installer
34
+ */
35
+ $installer->endSetup();
app/code/local/SFC/Autoship/sql/sfc_autoship_setup/mysql4-upgrade-1.3.1.3-1.3.1.4.php CHANGED
@@ -21,12 +21,12 @@
21
  $installer = $this;
22
  $installer->startSetup();
23
 
24
- // Update subscription_enabled product attribute to have it only apply to simple, config and bundle products
25
  $installer->updateAttribute(
26
  'catalog_product',
27
  'subscription_enabled',
28
  'apply_to',
29
- 'simple,configurable,bundle'
30
  );
31
 
32
  $sql = <<<SQL
21
  $installer = $this;
22
  $installer->startSetup();
23
 
24
+ // Update subscription_enabled product attribute to have apply to all product types except grouped
25
  $installer->updateAttribute(
26
  'catalog_product',
27
  'subscription_enabled',
28
  'apply_to',
29
+ 'simple,configurable,bundle,virtual,downloadable'
30
  );
31
 
32
  $sql = <<<SQL
app/design/adminhtml/default/default/layout/autoship.xml CHANGED
@@ -28,15 +28,23 @@
28
  <reference name="js">
29
  <block type="autoship/adminhtml_sales_order_create_jsonp" name="jsonp" template="autoship/sales/create_order/jsonp.phtml" after="-"/>
30
  </reference>
 
 
 
 
31
  </adminhtml_sales_order_create_index>
32
 
 
 
 
 
 
 
 
33
  <!-- Saved Credit Cards tab in ADMIN > CUSTOMER > EDIT > GRID -->
34
  <adminhtml_customer_edit>
35
  <reference name="customer_edit_tabs">
36
- <action method="addTab">
37
- <name>paymentprofile</name>
38
- <block>autoship/adminhtml_customer_paymentprofiles_paymentprofile</block>
39
- </action>
40
  </reference>
41
  </adminhtml_customer_edit>
42
 
28
  <reference name="js">
29
  <block type="autoship/adminhtml_sales_order_create_jsonp" name="jsonp" template="autoship/sales/create_order/jsonp.phtml" after="-"/>
30
  </reference>
31
+ <reference name="order_item_extra_info">
32
+ <block type="autoship/adminhtml_sales_order_create_product_subscription" name="autoship_subscribe_widget"
33
+ template="autoship/sales/create_order/product/subscription.phtml" />
34
+ </reference>
35
  </adminhtml_sales_order_create_index>
36
 
37
+ <adminhtml_sales_order_create_load_block_items>
38
+ <reference name="order_item_extra_info">
39
+ <block type="autoship/adminhtml_sales_order_create_product_subscription" name="autoship_subscribe_widget"
40
+ template="autoship/sales/create_order/product/subscription.phtml" />
41
+ </reference>
42
+ </adminhtml_sales_order_create_load_block_items>
43
+
44
  <!-- Saved Credit Cards tab in ADMIN > CUSTOMER > EDIT > GRID -->
45
  <adminhtml_customer_edit>
46
  <reference name="customer_edit_tabs">
47
+ <action method="addPaymentProfilesTab" />
 
 
 
48
  </reference>
49
  </adminhtml_customer_edit>
50
 
app/design/adminhtml/default/default/template/autoship/payment/form/cc.phtml CHANGED
@@ -14,6 +14,7 @@
14
  * @link http://www.subscribepro.com/
15
  *
16
  */
 
17
  ?>
18
  <?php $_code = $this->getMethodCode() ?>
19
  <ul class="form-list" id="payment_form_<?php echo $_code ?>" style="display:none;">
@@ -53,7 +54,7 @@
53
  <input type="text" title="<?php echo $this->__('Card Verification Number') ?>"
54
  class="input-text"
55
  id="<?php echo $_code ?>_cc_cid"
56
- name="payment[cc_cid]" />
57
  </div>
58
  </div>
59
  </li>
@@ -65,7 +66,7 @@
65
  <input type='hidden' value='0' name='payment[save_card]'/>
66
  <input type="checkbox" title="<?php echo $this->__('Save Card') ?>" class="checkbox"
67
  id="<?php echo $_code ?>_save_card" name="payment[save_card]"
68
- value="1" <?php if($this->getAdditionalInfo('save_card')): ?>checked<?php endif; ?> />
69
  </div>
70
  </div>
71
  </li>
14
  * @link http://www.subscribepro.com/
15
  *
16
  */
17
+ /** @var SFC_Autoship_Block_Payment_Form_CC $this */
18
  ?>
19
  <?php $_code = $this->getMethodCode() ?>
20
  <ul class="form-list" id="payment_form_<?php echo $_code ?>" style="display:none;">
54
  <input type="text" title="<?php echo $this->__('Card Verification Number') ?>"
55
  class="input-text"
56
  id="<?php echo $_code ?>_cc_cid"
57
+ name="payment[cc_cid]" value="<?php echo $this->getCvv() ?>" />
58
  </div>
59
  </div>
60
  </li>
66
  <input type='hidden' value='0' name='payment[save_card]'/>
67
  <input type="checkbox" title="<?php echo $this->__('Save Card') ?>" class="checkbox"
68
  id="<?php echo $_code ?>_save_card" name="payment[save_card]"
69
+ value="1" <?php if($this->getSaveCard()): ?>checked<?php endif; ?> />
70
  </div>
71
  </div>
72
  </li>
app/design/adminhtml/default/default/template/autoship/payment/form/cc_saved.phtml CHANGED
@@ -14,9 +14,11 @@
14
  * @link http://www.subscribepro.com/
15
  *
16
  */
 
17
  ?>
18
  <?php $_code = $this->getMethodCode() ?>
19
- <?php $_paymentProfile = $this->getMethod()->getSavedPaymentProfile() ?>
 
20
  <?php echo $this->getChildHtml() ?>
21
  <ul id="payment_form_<?php echo $_code ?>" style="display:none;">
22
  <input type="hidden" id="<?php echo $_code ?>_payment_token" name="payment[payment_token]"
@@ -27,32 +29,37 @@
27
  title="<?php echo $this->__('Obscured Card Number') ?>" value="<?php echo $this->getObscuredCardNumber() ?>"/>
28
  <input type="hidden" id="<?php echo $_code ?>_cc_type" name="payment[cc_type]" title="<?php echo $this->__('Card Type') ?>"
29
  value="<?php echo $this->getMagentoCardType() ?>"/>
30
- <li id="<?php echo $_code ?>_cc_type_exp_div">
31
- <div class="input-box">
32
- <label for="<?php echo $_code ?>_expiration"><?php echo Mage::helper('payment')->__('Expiration Date') ?> <span class="required">*</span></label><br/>
33
- <select id="<?php echo $_code ?>_expiration" style="width:140px;" name="payment[cc_exp_month]" class="validate-cc-exp required-entry">
34
- <?php $_ccExpMonth = $_paymentProfile->getData('creditcard_month') ?>
35
- <?php foreach ($this->getCcMonths() as $k=>$v): ?>
36
- <option value="<?php echo $k ?>" <?php if($k==$_ccExpMonth): ?>selected="selected"<?php endif ?>><?php echo $v ?></option>
37
- <?php endforeach ?>
38
- </select>
39
- <?php $_ccExpYear = $_paymentProfile->getData('creditcard_year') ?>
40
- <select id="<?php echo $_code ?>_expiration_yr" style="width:103px;" name="payment[cc_exp_year]" class="required-entry">
41
- <?php foreach ($this->getCcYears() as $k=>$v): ?>
42
- <option value="<?php echo $k ? $k : '' ?>" <?php if($k==$_ccExpYear): ?>selected="selected"<?php endif ?>><?php echo $v ?></option>
43
- <?php endforeach ?>
44
- </select>
45
- </div>
46
- </li>
47
- <li id="<?php echo $_code ?>_cc_type_cvv_div">
48
- <label for="<?php echo $_code ?>_cc_cid"><?php echo $this->__('Card Verification Number') ?>
49
- </label>
 
50
 
51
- <div class="input-box">
52
- <div class="v-fix">
53
- <input type="text" title="<?php echo $this->__('Card Verification Number') ?>" class="input-text"
54
- id="<?php echo $_code ?>_cc_cid" name="payment[cc_cid]" value=""/>
 
55
  </div>
56
- </div>
57
- </li>
 
 
58
  </ul>
 
14
  * @link http://www.subscribepro.com/
15
  *
16
  */
17
+ /** @var SFC_Autoship_Block_Payment_Form_CC_Saved $this */
18
  ?>
19
  <?php $_code = $this->getMethodCode() ?>
20
+ <?php /** @var SFC_Autoship_Model_Payment_Profile $_paymentProfile */
21
+ $_paymentProfile = $this->getMethod()->getSavedPaymentProfile() ?>
22
  <?php echo $this->getChildHtml() ?>
23
  <ul id="payment_form_<?php echo $_code ?>" style="display:none;">
24
  <input type="hidden" id="<?php echo $_code ?>_payment_token" name="payment[payment_token]"
29
  title="<?php echo $this->__('Obscured Card Number') ?>" value="<?php echo $this->getObscuredCardNumber() ?>"/>
30
  <input type="hidden" id="<?php echo $_code ?>_cc_type" name="payment[cc_type]" title="<?php echo $this->__('Card Type') ?>"
31
  value="<?php echo $this->getMagentoCardType() ?>"/>
32
+ <?php if (!$_paymentProfile->isThirdParty()): ?>
33
+ <li id="<?php echo $_code ?>_cc_type_exp_div">
34
+ <div class="input-box">
35
+ <label for="<?php echo $_code ?>_expiration"><?php echo Mage::helper('payment')->__('Expiration Date') ?> <span class="required">*</span></label><br/>
36
+ <select id="<?php echo $_code ?>_expiration" style="width:140px;" name="payment[cc_exp_month]" class="validate-cc-exp required-entry">
37
+ <?php $_ccExpMonth = $_paymentProfile->getData('creditcard_month') ?>
38
+ <?php foreach ($this->getCcMonths() as $k=>$v): ?>
39
+ <option value="<?php echo $k ?>" <?php if($k==$_ccExpMonth): ?>selected="selected"<?php endif ?>><?php echo $v ?></option>
40
+ <?php endforeach ?>
41
+ </select>
42
+ <?php $_ccExpYear = $_paymentProfile->getData('creditcard_year') ?>
43
+ <select id="<?php echo $_code ?>_expiration_yr" style="width:103px;" name="payment[cc_exp_year]" class="required-entry">
44
+ <?php foreach ($this->getCcYears() as $k=>$v): ?>
45
+ <option value="<?php echo $k ? $k : '' ?>" <?php if($k==$_ccExpYear): ?>selected="selected"<?php endif ?>><?php echo $v ?></option>
46
+ <?php endforeach ?>
47
+ </select>
48
+ </div>
49
+ </li>
50
+ <li id="<?php echo $_code ?>_cc_type_cvv_div">
51
+ <label for="<?php echo $_code ?>_cc_cid"><?php echo $this->__('Card Verification Number') ?>
52
+ </label>
53
 
54
+ <div class="input-box">
55
+ <div class="v-fix">
56
+ <input type="text" title="<?php echo $this->__('Card Verification Number') ?>" class="input-text"
57
+ id="<?php echo $_code ?>_cc_cid" name="payment[cc_cid]" value="<?php echo $this->getCvv() ?>" />
58
+ </div>
59
  </div>
60
+ </li>
61
+ <?php else: ?>
62
+ <input type="hidden" name="payment[third_party_token]" value="1" />
63
+ <?php endif; ?>
64
  </ul>
65
+
app/design/adminhtml/default/default/template/autoship/sales/create_order/product/subscription.phtml ADDED
@@ -0,0 +1,102 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Subscribe Pro - Subscriptions Management Extension
4
+ *
5
+ * PHP version 5
6
+ *
7
+ * LICENSE: This source file is subject to commercial source code license of SUBSCRIBE PRO INC.
8
+ *
9
+ * @category SFC
10
+ * @package SFC_Autoship
11
+ * @author Garth Brantley <garth@subscribepro.com>
12
+ * @author Dennis Rogers <dennis@storefrontconsulting.com>
13
+ * @copyright 2009-2014 SUBSCRIBE PRO INC. All Rights Reserved.
14
+ * @license http://www.subscribepro.com/terms-of-service/ Subscribe Pro Terms of Service
15
+ * @link http://www.subscribepro.com/
16
+ *
17
+ */
18
+ /** @var $this SFC_Autoship_Block_Adminhtml_Sales_Order_Create_Product_Subscription */
19
+ ?>
20
+ <?php
21
+ if (!$this->isItemSubscriptionEligible()) {
22
+ return;
23
+ }
24
+ /** @var $_item Mage_Sales_Model_Quote_Item */
25
+ $quoteItem = $this->getItem();
26
+ ?>
27
+ <tr class="border">
28
+ <td class="first">
29
+
30
+ <div class="subscription-product product-options" data-subscription="<?php echo $quoteItem->getId() ?>">
31
+ <?php if ($this->isTrialProduct() || $this->getSubscriptionOptionMode() == 'subscription_only'): ?>
32
+ <p><?php echo $this->getDiscountText() ?></p>
33
+ <?php else: ?>
34
+ <p><?php echo $this->__('Would you like to receive regular shipments of this item?') ?></p>
35
+ <?php endif; ?>
36
+ <ul class="options-list">
37
+ <?php if ($this->isTrialProduct() || $this->getSubscriptionOptionMode() == 'subscription_only'): ?>
38
+ <input type="hidden" onclick="" class="" data-subscription="<?php echo $quoteItem->getId() ?>"
39
+ id="<?php echo $quoteItem->getId() ?>-delivery-option-subscribe"
40
+ name="item[<?php echo $quoteItem->getId() ?>][delivery-option]" value="subscribe"/>
41
+ <label for="delivery-interval" style="display:block; margin-top:12px;"><?php echo $this->__("Delivery every:") ?>
42
+ <select
43
+ id="<?php echo $quoteItem->getId() ?>-delivery-interval" data-subscription="<?php echo $quoteItem->getId() ?>"
44
+ name="item[<?php echo $quoteItem->getId() ?>][delivery-interval]"
45
+ class="">
46
+ <?php foreach ($this->getIntervals() as $interval): ?>
47
+ <option value="<?php echo $interval ?>" <?php if($interval == $this->getNewSubscriptionInterval()): ?>selected="selected"<?php endif; ?>>
48
+ <?php echo $interval ?>
49
+ </option>
50
+ <?php endforeach; ?>
51
+ </select>
52
+ </label>
53
+ <?php else: ?>
54
+ <li>
55
+ <input type="radio" onclick="" class="radio" data-subscription="<?php echo $quoteItem->getId() ?>"
56
+ id="<?php echo $quoteItem->getId() ?>-delivery-option-one-time"
57
+ name="item[<?php echo $quoteItem->getId() ?>][delivery-option]"
58
+ value="one-time-delivery"
59
+ <?php if (!$this->isItemFlaggedToCreateNewSubscription()): ?>checked="checked"<?php endif; ?>
60
+ />
61
+ <span class="label">
62
+ <label for="<?php echo $quoteItem->getId() ?>-delivery-option-one-time"><?php echo $this->__("One Time Delivery") ?></label>
63
+ </span>
64
+ </li>
65
+ <li>
66
+ <input type="radio" onclick="" class="radio" data-subscription="<?php echo $quoteItem->getId() ?>"
67
+ id="<?php echo $quoteItem->getId() ?>-delivery-option-subscribe"
68
+ name="item[<?php echo $quoteItem->getId() ?>][delivery-option]" value="subscribe"
69
+ <?php if ($this->isItemFlaggedToCreateNewSubscription()): ?>checked="checked"<?php endif; ?>
70
+ />
71
+ <span class="label">
72
+ <label for="<?php echo $quoteItem->getId() ?>-delivery-option-subscribe"><?php echo $this->__("Regular Delivery") ?>
73
+ (<?php echo $this->getDiscountText() ?>)</label>
74
+ </span>
75
+
76
+ <label for="delivery-interval" style="display:block; margin-top:12px;"><?php echo $this->__("Delivery every:") ?>
77
+ <select
78
+ id="<?php echo $quoteItem->getId() ?>-delivery-interval" data-subscription="<?php echo $quoteItem->getId() ?>"
79
+ name="item[<?php echo $quoteItem->getId() ?>][delivery-interval]"
80
+ class="">
81
+ <?php foreach ($this->getIntervals() as $interval): ?>
82
+ <option value="<?php echo $interval ?>" <?php if($interval == $this->getNewSubscriptionInterval()): ?>selected="selected"<?php endif; ?>>
83
+ <?php echo $interval ?>
84
+ </option>
85
+ <?php endforeach; ?>
86
+ </select>
87
+ </label>
88
+ </li>
89
+ <?php endif; ?>
90
+ </ul>
91
+ </div>
92
+
93
+ </td>
94
+
95
+ <td></td>
96
+ <td></td>
97
+ <td></td>
98
+ <td></td>
99
+ <td></td>
100
+ <td></td>
101
+ <td class="last"></td>
102
+ </tr>
app/design/frontend/base/default/layout/autoship.xml CHANGED
@@ -25,7 +25,6 @@
25
 
26
  <reference name="head">
27
  <action method="addCss"><stylesheet>css/autoship.css</stylesheet></action>
28
- <action method="addItem"><type>skin_js</type><name>js/autoship/jquery/jquery-1.10.1.min.js</name></action>
29
  <action method="addItem"><type>skin_js</type><name>js/autoship/jquery/ui/jquery.ui.core.min.js</name></action>
30
  <action method="addItem"><type>skin_js</type><name>js/autoship/jquery/ui/jquery.ui.datepicker.min.js</name></action>
31
  <action method="addItem"><type>skin_css</type><name>js/autoship/jquery/ui/theme/jquery-ui.css</name></action>
@@ -251,4 +250,10 @@ Product view
251
  </reference>
252
  </checkout_onepage_index>
253
 
 
 
 
 
 
 
254
  </layout>
25
 
26
  <reference name="head">
27
  <action method="addCss"><stylesheet>css/autoship.css</stylesheet></action>
 
28
  <action method="addItem"><type>skin_js</type><name>js/autoship/jquery/ui/jquery.ui.core.min.js</name></action>
29
  <action method="addItem"><type>skin_js</type><name>js/autoship/jquery/ui/jquery.ui.datepicker.min.js</name></action>
30
  <action method="addItem"><type>skin_css</type><name>js/autoship/jquery/ui/theme/jquery-ui.css</name></action>
250
  </reference>
251
  </checkout_onepage_index>
252
 
253
+ <!-- EE Only, ensure the gift card function is not hiding subscribe pro -->
254
+ <checkout_onepage_paymentmethod>
255
+ <reference name="giftcardaccount_scripts">
256
+ <action method="setTemplate"><template>autoship/giftcardaccount/onepage/payment/scripts.phtml</template></action>
257
+ </reference>
258
+ </checkout_onepage_paymentmethod>
259
  </layout>
app/design/frontend/base/default/template/autoship/cart/product/subscription.phtml CHANGED
@@ -20,8 +20,35 @@
20
  <?php if(Mage::getStoreConfig('autoship_subscription/subscription/use_new_subscription_page') != '1'): ?>
21
  <?php $quoteItem = $this->getQuoteItem(); ?>
22
  <?php if ($this->isItemSubscriptionEligible()): ?>
23
- <div class="subscription-product">
24
- <p><?php echo $this->__('Would you like to receive regular shipments of this item?') ?></p>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
25
  <ul class="options-list">
26
  <li>
27
  <input type="radio" onclick="" class="radio"
@@ -31,13 +58,9 @@
31
  value="one-time-delivery"
32
  <?php if (!$this->isItemFlaggedToCreateNewSubscription()): ?>checked="checked"<?php endif; ?>
33
  />
34
-
35
- <div class="radio-text">
36
- <span class=label>
37
- <label for="delivery-option-one-time">One Time Delivery</label>
38
- </span>
39
- </div>
40
- <div class="clearer"></div>
41
  </li>
42
  <li>
43
  <input type="radio" onclick="" class="radio"
@@ -46,30 +69,27 @@
46
  name="cart[<?php echo $quoteItem->getId() ?>][delivery-option]" value="subscribe"
47
  <?php if ($this->isItemFlaggedToCreateNewSubscription()): ?>checked="checked"<?php endif; ?>
48
  />
 
 
 
49
 
50
- <div class="radio-text">
51
- <span class=label>
52
- <label for="delivery-option-subscribe">Regular Delivery</label>
53
- </span>
54
-
55
- <p>
56
- <label for="delivery-interval">Delivery every:</label><br/>
57
- <select onchange=""
58
- id="<?php echo $quoteItem->getId() ?>-delivery-interval"
59
- name="cart[<?php echo $quoteItem->getId() ?>][delivery-interval]"
60
- class="">
61
- <?php foreach ($this->getIntervals() as $interval): ?>
62
- <option value="<?php echo $interval ?>" <?php if($interval == $this->getNewSubscriptionInterval()): ?>selected="selected"<?php endif; ?>>
63
- <?php echo $interval ?>
64
- </option>
65
- <?php endforeach; ?>
66
- </select>
67
- </p>
68
- </div>
69
- <div class="clearer"></div>
70
  </li>
71
  </ul>
72
  </div>
73
  <?php endif; ?>
74
  <?php endif; ?>
 
75
  <?php endif; ?>
20
  <?php if(Mage::getStoreConfig('autoship_subscription/subscription/use_new_subscription_page') != '1'): ?>
21
  <?php $quoteItem = $this->getQuoteItem(); ?>
22
  <?php if ($this->isItemSubscriptionEligible()): ?>
23
+ <?php if($this->isTrialProduct() || $this->getSubscriptionOptionMode() == 'subscription_only'): // Subscription Only Mode or Trial Product - Only Subscription Option Allowed ?>
24
+ <div class="subscription-product product-options">
25
+ <?php if ($this->isTrialProduct()): ?><p><?php echo $this->__('Trial Subscription') ?></p><?php endif; ?>
26
+ <ul class="options-list">
27
+ <li>
28
+ <input type="hidden"
29
+ id="<?php echo $quoteItem->getId() ?>-delivery-option-subscribe"
30
+ name="cart[<?php echo $quoteItem->getId() ?>][delivery-option]" value="subscribe"
31
+ />
32
+
33
+ <label for="delivery-interval">Delivery every:
34
+ <select
35
+ onchange="this.form.submit();"
36
+ id="<?php echo $quoteItem->getId() ?>-delivery-interval"
37
+ name="cart[<?php echo $quoteItem->getId() ?>][delivery-interval]"
38
+ class="">
39
+ <?php foreach ($this->getIntervals() as $interval): ?>
40
+ <option value="<?php echo $interval ?>" <?php if($interval == $this->getNewSubscriptionInterval()): ?>selected="selected"<?php endif; ?>>
41
+ <?php echo $interval ?>
42
+ </option>
43
+ <?php endforeach; ?>
44
+ </select>
45
+ </label>
46
+ </li>
47
+ </ul>
48
+ </div>
49
+ <?php else: // Standard version ?>
50
+ <div class="subscription-product product-options">
51
+ <p><?php echo $this->__('Would you like to receive regular shipments of this item?') ?></p>
52
  <ul class="options-list">
53
  <li>
54
  <input type="radio" onclick="" class="radio"
58
  value="one-time-delivery"
59
  <?php if (!$this->isItemFlaggedToCreateNewSubscription()): ?>checked="checked"<?php endif; ?>
60
  />
61
+ <span class="label">
62
+ <label for="delivery-option-one-time"><?php echo $this->__("One Time Delivery") ?></label>
63
+ </span>
 
 
 
 
64
  </li>
65
  <li>
66
  <input type="radio" onclick="" class="radio"
69
  name="cart[<?php echo $quoteItem->getId() ?>][delivery-option]" value="subscribe"
70
  <?php if ($this->isItemFlaggedToCreateNewSubscription()): ?>checked="checked"<?php endif; ?>
71
  />
72
+ <span class="label">
73
+ <label for="delivery-option-subscribe"><?php echo $this->__("Regular Delivery") ?></label>
74
+ </span>
75
 
76
+ <label for="delivery-interval"><?php echo $this->__("Delivery every:") ?>
77
+ <select
78
+ onchange="this.form.submit();"
79
+ id="<?php echo $quoteItem->getId() ?>-delivery-interval"
80
+ name="cart[<?php echo $quoteItem->getId() ?>][delivery-interval]"
81
+ class="">
82
+ <?php foreach ($this->getIntervals() as $interval): ?>
83
+ <option value="<?php echo $interval ?>" <?php if($interval == $this->getNewSubscriptionInterval()): ?>selected="selected"<?php endif; ?>>
84
+ <?php echo $interval ?>
85
+ </option>
86
+ <?php endforeach; ?>
87
+ </select>
88
+ </label>
 
 
 
 
 
 
 
89
  </li>
90
  </ul>
91
  </div>
92
  <?php endif; ?>
93
  <?php endif; ?>
94
+ <?php endif; ?>
95
  <?php endif; ?>
app/design/frontend/base/default/template/autoship/checkout/success.phtml CHANGED
@@ -21,11 +21,11 @@
21
  <?php $createdSubscriptionIds = $this->getCreatedSubscriptionIds(); ?>
22
  <?php if ($this->getFailedSubscriptionCount()): ?>
23
  <?php // Output error message ?>
24
- <p>Failed to create some of your product subscriptions! Please contact support for assistance.</p>
25
  <?php endif; ?>
26
  <?php if (is_array($createdSubscriptionIds) && count($createdSubscriptionIds)): ?>
27
- <p>You will receive a separate email confirmation for your product subscription(s). Click here to <a
28
- href="<?php echo $this->getUrl('autoship/mysubscriptions') ?>">manage your product subscriptions</a>.
29
  </p>
30
  <?php endif; ?>
31
  <?php endif; ?>
21
  <?php $createdSubscriptionIds = $this->getCreatedSubscriptionIds(); ?>
22
  <?php if ($this->getFailedSubscriptionCount()): ?>
23
  <?php // Output error message ?>
24
+ <p><?php echo $this->__("Failed to create some of your product subscriptions! Please contact support for assistance.") ?></p>
25
  <?php endif; ?>
26
  <?php if (is_array($createdSubscriptionIds) && count($createdSubscriptionIds)): ?>
27
+ <p><?php echo $this->__('You will receive a separate email confirmation for your product subscription(s). Click here to <a
28
+ href="%s">manage your product subscriptions</a>.', $this->getUrl('autoship/mysubscriptions')) ?>
29
  </p>
30
  <?php endif; ?>
31
  <?php endif; ?>
app/design/frontend/base/default/template/autoship/giftcardaccount/onepage/payment/scripts.phtml ADDED
@@ -0,0 +1,59 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Magento Enterprise Edition
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Magento Enterprise Edition License
8
+ * that is bundled with this package in the file LICENSE_EE.txt.
9
+ * It is also available through the world-wide-web at this URL:
10
+ * http://www.magentocommerce.com/license/enterprise-edition
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 enterprise_default
23
+ * @copyright Copyright (c) 2011 Magento Inc. (http://www.magentocommerce.com)
24
+ * @license http://www.magentocommerce.com/license/enterprise-edition
25
+ */
26
+ ?>
27
+ quoteBaseGrandTotal = <?php echo (float)$this->_getQuote()->getBaseGrandTotal(); ?>;
28
+ var isGiftCardApplied = <?php if($this->isFullyPaidAfterApplication()): ?>true<?php else: ?>false<?php endif; ?>;
29
+ var epsilon = 0.0001;
30
+ function enablePaymentMethods(free) {
31
+ Payment.prototype.init = function () {
32
+ var elements = Form.getElements(this.form);
33
+ for (var i=0; i < elements.length; i++) {
34
+ if (elements[i].name == 'payment[method]'
35
+ || elements[i].name == 'payment[use_customer_balance]'
36
+ || elements[i].name == 'payment[use_reward_points]'
37
+ ) {
38
+ <?php //@mod Update this to still show the subscribe_pro method even if it's free ?>
39
+ var isSubscribepro = (-1 !== elements[i].value.search(/subscribe_pro/));
40
+ if ((free && (elements[i].value == 'free' || isSubscribepro)) || (!free && elements[i].value != 'free')) {
41
+ $((elements[i]).parentNode).show();
42
+ if (free && !isSubscribepro) {
43
+ this.switchMethod('free');
44
+ elements[i].checked = true;
45
+ }
46
+ } else {
47
+ $((elements[i]).parentNode).hide();
48
+ }
49
+ } else {
50
+ elements[i].disabled = true;
51
+ }
52
+ }
53
+ };
54
+ }
55
+ if (quoteBaseGrandTotal < epsilon && isGiftCardApplied) {
56
+ enablePaymentMethods(true);
57
+ } else if (quoteBaseGrandTotal >= epsilon) {
58
+ enablePaymentMethods(false);
59
+ }
app/design/frontend/base/default/template/autoship/mysubscriptions.phtml CHANGED
@@ -17,7 +17,7 @@
17
  */
18
  ?>
19
  <div class="page-title">
20
- <h1>My Product Subscriptions</h1>
21
  </div>
22
 
23
  <div id="mysubscriptions">
@@ -33,7 +33,7 @@ if($this->getNextOrderDateMode() != SFC_Autoship_Model_System_Config_Source_Next
33
  <form id="all-subscriptions-date-form" class="all-subscriptions-date-form" action="<?php echo Mage::getUrl('autoship/mysubscriptions/change', array('_secure' => true)) ?>">
34
  <input type="hidden" name="id" id="subscription_id"
35
  value="all_active"/>
36
- <p>Next Ship Date:</p>
37
  <div class="input-box">
38
  <input type="text" id="delivery_date"
39
  name="delivery_date"
@@ -88,7 +88,7 @@ if($this->getNextOrderDateMode() != SFC_Autoship_Model_System_Config_Source_Next
88
  <img src="<?php echo $this->getSkinUrl('images/opc-ajax-loader.gif') ?>" alt="<?php echo $this->__('Updating...') ?>" title="<?php echo $this->__('Updating...') ?>" class="v-middle" /> <?php echo $this->__('Updating...') ?>
89
  </span>
90
  <div class="buttons-set">
91
- <p class="back-link"><a href="<?php echo Mage::getUrl('customer/account/'); ?>"><small>&#171;</small> Back</a></p>
92
  </div>
93
 
94
  <script type="text/javascript">
17
  */
18
  ?>
19
  <div class="page-title">
20
+ <h1><?php echo $this->__("My Product Subscriptions") ?></h1>
21
  </div>
22
 
23
  <div id="mysubscriptions">
33
  <form id="all-subscriptions-date-form" class="all-subscriptions-date-form" action="<?php echo Mage::getUrl('autoship/mysubscriptions/change', array('_secure' => true)) ?>">
34
  <input type="hidden" name="id" id="subscription_id"
35
  value="all_active"/>
36
+ <p><?php echo $this->__("Next Ship Date:") ?></p>
37
  <div class="input-box">
38
  <input type="text" id="delivery_date"
39
  name="delivery_date"
88
  <img src="<?php echo $this->getSkinUrl('images/opc-ajax-loader.gif') ?>" alt="<?php echo $this->__('Updating...') ?>" title="<?php echo $this->__('Updating...') ?>" class="v-middle" /> <?php echo $this->__('Updating...') ?>
89
  </span>
90
  <div class="buttons-set">
91
+ <p class="back-link"><a href="<?php echo Mage::getUrl('customer/account/'); ?>"><small>&#171;</small> <?php echo $this->__("Back") ?></a></p>
92
  </div>
93
 
94
  <script type="text/javascript">
app/design/frontend/base/default/template/autoship/mysubscriptions/subscription/actions.phtml CHANGED
@@ -23,20 +23,20 @@ $product = $this->getProduct();
23
  <div class="subscription-actions">
24
  <?php if ($subscription->getStatus() == 'Active'): ?>
25
  <?php if ($this->getNextOrderDateMode() == SFC_Autoship_Model_System_Config_Source_Nextorderdatemode::MODE_MULTIPLE_DATES): ?>
26
- <button type="button" title="<?php echo $this->__('Skip Next Delivery') ?>" class="button change skip">
27
  <span><span><?php echo $this->__('Skip Next Delivery') ?></span></span></button>
28
  <?php endif; ?>
29
  <div>
30
  <p><a href="<?php echo $this->getUrl('autoship/mysubscriptions/cancel/id/' . $subscription->getSubscriptionId(),
31
- array('_secure' => true)) ?>" class="change cancel"><?php echo $this->__('Cancel Subscription') ?></a></p>
32
 
33
- <p><a href="<?php echo $product->getProductUrl() ?>">Need more immediately?</a></p>
34
 
35
  <p>&nbsp;</p>
36
 
37
  <?php if ($this->getNextOrderDateMode() == SFC_Autoship_Model_System_Config_Source_Nextorderdatemode::MODE_MULTIPLE_DATES): ?>
38
  <p><a href="<?php echo $subscription->getSubscriptionId() ?>-more-details-div"
39
- class="link more details">More Details...</a></p>
40
  <?php endif; ?>
41
  </div>
42
  <?php elseif ($subscription->getStatus() == 'Failed' || $subscription->getStatus() == 'Retry'): ?>
@@ -44,13 +44,13 @@ $product = $this->getProduct();
44
  <p><span class="status"><strong><?php echo $subscription->getStatus() ?></strong></span></p>
45
  <div>
46
  <p><a href="<?php echo $this->getUrl('autoship/mysubscriptions/restart/id/' . $subscription->getSubscriptionId(),
47
- array('_secure' => true)) ?>" class="change restart"><?php echo $this->__('Restart Subscription') ?></a></p>
48
 
49
  <p>&nbsp;</p>
50
 
51
  <?php if ($this->getNextOrderDateMode() == SFC_Autoship_Model_System_Config_Source_Nextorderdatemode::MODE_MULTIPLE_DATES): ?>
52
  <p><a href="<?php echo $subscription->getSubscriptionId() ?>-more-details-div"
53
- class="link more details">More Details...</a></p>
54
  <?php endif; ?>
55
  </div>
56
  <?php else: ?>
@@ -58,9 +58,9 @@ $product = $this->getProduct();
58
  <p><span class="status"><strong><?php echo $subscription->getStatus() ?></strong></span></p>
59
  <?php endif; ?>
60
  </div>
61
- <div class="change skip-delivery" style="display:none;">
62
  <div class="block-title">
63
- <h2>Skip Delivery?</h2>
64
  </div>
65
  <div class="block-content">
66
  <p>Skipping delivery on <?php echo $subscription->getNextOrderDateText() ?>.</p>
@@ -76,12 +76,12 @@ $product = $this->getProduct();
76
  </div>
77
  </div>
78
  </div>
79
- <div class="change cancel" style="display:none;">
80
  <div class="block-title">
81
- <h2>Cancel Subscription?</h2>
82
  </div>
83
  <div class="block-content">
84
- <p>Are you sure you want to cancel your subscription?</p>
85
 
86
  <div class="buttons-set">
87
  <button type="button" title="<?php echo $this->__('Yes') ?>"
@@ -94,12 +94,12 @@ $product = $this->getProduct();
94
  </div>
95
  </div>
96
  </div>
97
- <div class="change restart" style="display:none;">
98
  <div class="block-title">
99
- <h2>Restart Subscription?</h2>
100
  </div>
101
  <div class="block-content">
102
- <p>Are you sure you want to restart your subscription?</p>
103
 
104
  <div class="buttons-set">
105
  <button type="button" title="<?php echo $this->__('Yes') ?>"
23
  <div class="subscription-actions">
24
  <?php if ($subscription->getStatus() == 'Active'): ?>
25
  <?php if ($this->getNextOrderDateMode() == SFC_Autoship_Model_System_Config_Source_Nextorderdatemode::MODE_MULTIPLE_DATES): ?>
26
+ <button type="button" title="<?php echo $this->__('Skip Next Delivery') ?>" class="button adjust skip">
27
  <span><span><?php echo $this->__('Skip Next Delivery') ?></span></span></button>
28
  <?php endif; ?>
29
  <div>
30
  <p><a href="<?php echo $this->getUrl('autoship/mysubscriptions/cancel/id/' . $subscription->getSubscriptionId(),
31
+ array('_secure' => true)) ?>" class="adjust cancel"><?php echo $this->__('Cancel Subscription') ?></a></p>
32
 
33
+ <p><a href="<?php echo $product->getProductUrl() ?>"><?php echo $this->__("Need more immediately?") ?></a></p>
34
 
35
  <p>&nbsp;</p>
36
 
37
  <?php if ($this->getNextOrderDateMode() == SFC_Autoship_Model_System_Config_Source_Nextorderdatemode::MODE_MULTIPLE_DATES): ?>
38
  <p><a href="<?php echo $subscription->getSubscriptionId() ?>-more-details-div"
39
+ class="link more details"><?php echo $this->__("More Details...") ?></a></p>
40
  <?php endif; ?>
41
  </div>
42
  <?php elseif ($subscription->getStatus() == 'Failed' || $subscription->getStatus() == 'Retry'): ?>
44
  <p><span class="status"><strong><?php echo $subscription->getStatus() ?></strong></span></p>
45
  <div>
46
  <p><a href="<?php echo $this->getUrl('autoship/mysubscriptions/restart/id/' . $subscription->getSubscriptionId(),
47
+ array('_secure' => true)) ?>" class="adjust restart"><?php echo $this->__('Restart Subscription') ?></a></p>
48
 
49
  <p>&nbsp;</p>
50
 
51
  <?php if ($this->getNextOrderDateMode() == SFC_Autoship_Model_System_Config_Source_Nextorderdatemode::MODE_MULTIPLE_DATES): ?>
52
  <p><a href="<?php echo $subscription->getSubscriptionId() ?>-more-details-div"
53
+ class="link more details"><?php echo $this->__("More Details...") ?></a></p>
54
  <?php endif; ?>
55
  </div>
56
  <?php else: ?>
58
  <p><span class="status"><strong><?php echo $subscription->getStatus() ?></strong></span></p>
59
  <?php endif; ?>
60
  </div>
61
+ <div class="adjust skip-delivery" style="display:none;">
62
  <div class="block-title">
63
+ <h2><?php echo $this->__("Skip Delivery?") ?></h2>
64
  </div>
65
  <div class="block-content">
66
  <p>Skipping delivery on <?php echo $subscription->getNextOrderDateText() ?>.</p>
76
  </div>
77
  </div>
78
  </div>
79
+ <div class="adjust cancel" style="display:none;">
80
  <div class="block-title">
81
+ <h2><?php echo $this->__("Cancel Subscription?") ?></h2>
82
  </div>
83
  <div class="block-content">
84
+ <p><?php echo $this->__("Are you sure you want to cancel your subscription?") ?></p>
85
 
86
  <div class="buttons-set">
87
  <button type="button" title="<?php echo $this->__('Yes') ?>"
94
  </div>
95
  </div>
96
  </div>
97
+ <div class="adjust restart" style="display:none;">
98
  <div class="block-title">
99
+ <h2><?php echo $this->__("Restart Subscription?") ?></h2>
100
  </div>
101
  <div class="block-content">
102
+ <p><?php echo $this->__("Are you sure you want to restart your subscription?") ?></p>
103
 
104
  <div class="buttons-set">
105
  <button type="button" title="<?php echo $this->__('Yes') ?>"
app/design/frontend/base/default/template/autoship/mysubscriptions/subscription/billing_address.phtml CHANGED
@@ -20,7 +20,7 @@ $subscription = $this->getSubscription();
20
  $billingAddress = $subscription->getBillingAddress();
21
  ?>
22
  <div class="block subscription-billing-address">
23
- <p><strong>Billing address:</strong> <a class="change" href="">(Change)</a></p>
24
  <address>
25
  <?php echo $billingAddress->getFirstname() ?> <?php echo $billingAddress->getLastname() ?><br/>
26
  <?php if (strlen($billingAddress->getCompany())): ?>
@@ -36,9 +36,9 @@ $billingAddress = $subscription->getBillingAddress();
36
  <input type="text" id="billing_address_id" name="billing_address_id" value="<?php echo $billingAddress->getId() ?>"
37
  class="input-text" style="display:none;"/>
38
 
39
- <div class="change" style="display: none;">
40
  <div class="block-title">
41
- <h2>Change Billing Address</h2>
42
  </div>
43
  <div class="block-content">
44
  <?php
20
  $billingAddress = $subscription->getBillingAddress();
21
  ?>
22
  <div class="block subscription-billing-address">
23
+ <p><strong><?php echo $this->__("Billing address:") ?></strong> <a class="adjust" href=""><?php echo $this->__("(Change)") ?></a></p>
24
  <address>
25
  <?php echo $billingAddress->getFirstname() ?> <?php echo $billingAddress->getLastname() ?><br/>
26
  <?php if (strlen($billingAddress->getCompany())): ?>
36
  <input type="text" id="billing_address_id" name="billing_address_id" value="<?php echo $billingAddress->getId() ?>"
37
  class="input-text" style="display:none;"/>
38
 
39
+ <div class="adjust" style="display: none;">
40
  <div class="block-title">
41
+ <h2><?php echo $this->__("Change Billing Address") ?></h2>
42
  </div>
43
  <div class="block-content">
44
  <?php
app/design/frontend/base/default/template/autoship/mysubscriptions/subscription/payment.phtml CHANGED
@@ -22,18 +22,20 @@ $subscription = $this->getSubscription();
22
  <div class="block subscription-payment">
23
  <p><strong>Payment Information:</strong></p>
24
  <?php if (strlen($subscription->getData('payment_token'))): ?>
25
- <p>Credit card ending in <?php echo $subscription->getData('creditcard_last_digits') ?> <a class="change" href="">(Change)</a></p>
26
  <p><a href="<?php echo $this->getNewCardUrl() ?>">Add a new credit card</a></p>
27
  <?php else: ?>
28
- <p>Haven't saved a credit card yet? <a href="<?php echo $this->getNewCardUrl() ?>">Add one now</a>.</p>
 
 
29
  <?php endif; ?>
30
 
31
  <input type="text" id="payment_token" name="payment_token" value="<?php echo $subscription->getData('payment_token') ?>"
32
  class="input-text" style="display:none;"/>
33
 
34
- <div class="change" style="display:none;">
35
  <div class="block-title">
36
- <h2>Change Payment Method</h2>
37
  </div>
38
  <div class="block-content">
39
  <?php
22
  <div class="block subscription-payment">
23
  <p><strong>Payment Information:</strong></p>
24
  <?php if (strlen($subscription->getData('payment_token'))): ?>
25
+ <p><?php echo $this->__("Credit card ending in") ?> <?php echo $subscription->getData('creditcard_last_digits') ?> <a class="adjust" href=""><?php echo $this->__("(Change)") ?></a></p>
26
  <p><a href="<?php echo $this->getNewCardUrl() ?>">Add a new credit card</a></p>
27
  <?php else: ?>
28
+ <p><?php
29
+ echo $this->__('Haven\'t saved a credit card yet? <a href="%s">Add one now</a>.', $this->getNewCardUrl());
30
+ ?></p>
31
  <?php endif; ?>
32
 
33
  <input type="text" id="payment_token" name="payment_token" value="<?php echo $subscription->getData('payment_token') ?>"
34
  class="input-text" style="display:none;"/>
35
 
36
+ <div class="adjust" style="display:none;">
37
  <div class="block-title">
38
+ <h2><?php echo $this->__("Change Payment Method") ?></h2>
39
  </div>
40
  <div class="block-content">
41
  <?php
app/design/frontend/base/default/template/autoship/mysubscriptions/subscription/product_info.phtml CHANGED
@@ -31,9 +31,9 @@ $product = $this->getProduct();
31
  <h2 class="product-name"><a href="<?php echo $product->getProductUrl() ?>"
32
  title="<?php echo $_productNameStripped; ?>"><?php echo $product->getName() ?></a></h2>
33
 
34
- <p><span class="product-original-price">One-Time Purchase Price: <?php echo $this->getOneTimePurchasePrice(true) ?></span><br/>
35
  <span class="product-price"><?php echo $this->getSubscriptionPriceText() ?></span></p>
36
  <?php if (strlen($subscription->getCouponCode())): ?>
37
- <p>Applied coupon code: <?php echo $subscription->getCouponCode() ?></p>
38
  <?php endif; ?>
39
  </div>
31
  <h2 class="product-name"><a href="<?php echo $product->getProductUrl() ?>"
32
  title="<?php echo $_productNameStripped; ?>"><?php echo $product->getName() ?></a></h2>
33
 
34
+ <p><span class="product-original-price"><?php echo $this->__("One-Time Purchase Price:") ?> <?php echo $this->getOneTimePurchasePrice(true) ?></span><br/>
35
  <span class="product-price"><?php echo $this->getSubscriptionPriceText() ?></span></p>
36
  <?php if (strlen($subscription->getCouponCode())): ?>
37
+ <p><?php echo $this->__("Applied coupon code:") ?> <?php echo $subscription->getCouponCode() ?></p>
38
  <?php endif; ?>
39
  </div>
app/design/frontend/base/default/template/autoship/mysubscriptions/subscription/shipping_address.phtml CHANGED
@@ -20,7 +20,7 @@ $subscription = $this->getSubscription();
20
  $shippingAddress = $subscription->getShippingAddress();
21
  ?>
22
  <div class="block subscription-shipping-address">
23
- <p><strong>Delivery address:</strong> <a class="change" href="">(Change)</a></p>
24
  <address>
25
  <?php echo $shippingAddress->getFirstname() ?> <?php echo $shippingAddress->getLastname() ?><br/>
26
  <?php if (strlen($shippingAddress->getCompany())): ?>
@@ -36,9 +36,9 @@ $shippingAddress = $subscription->getShippingAddress();
36
  <input type="text" id="shipping_address_id" name="shipping_address_id" value="<?php echo $shippingAddress->getId() ?>"
37
  class="input-text" style="display:none;"/>
38
 
39
- <div class="change" style="display: none;">
40
  <div class="block-title">
41
- <h2>Change Shipping Address</h2>
42
  </div>
43
  <div class="block-content">
44
  <?php
20
  $shippingAddress = $subscription->getShippingAddress();
21
  ?>
22
  <div class="block subscription-shipping-address">
23
+ <p><strong><?php echo $this->__("Delivery address:") ?></strong> <a class="adjust" href=""><?php echo $this->__("(Change)") ?></a></p>
24
  <address>
25
  <?php echo $shippingAddress->getFirstname() ?> <?php echo $shippingAddress->getLastname() ?><br/>
26
  <?php if (strlen($shippingAddress->getCompany())): ?>
36
  <input type="text" id="shipping_address_id" name="shipping_address_id" value="<?php echo $shippingAddress->getId() ?>"
37
  class="input-text" style="display:none;"/>
38
 
39
+ <div class="adjust" style="display: none;">
40
  <div class="block-title">
41
+ <h2><?php echo $this->__("Change Shipping Address") ?></h2>
42
  </div>
43
  <div class="block-content">
44
  <?php
app/design/frontend/base/default/template/autoship/mysubscriptions/subscription/subscription_info.phtml CHANGED
@@ -25,7 +25,7 @@ $intervals = $this->getIntervals();
25
  <div class="subscription-info">
26
  <form class="interval" action="<?php echo Mage::getUrl('autoship/mysubscriptions/change', array('_secure' => true)) ?>">
27
  <?php if ($this->getNextOrderDateMode() == SFC_Autoship_Model_System_Config_Source_Nextorderdatemode::MODE_MULTIPLE_DATES): ?>
28
- <p>Next Ship Date:</p>
29
  <?php if ($subscription->getStatus() == 'Active' && $subscription->getNextOrderDate() >= date('Y-m-d', strtotime('+2 days'))
30
  ): ?>
31
  <?php // Only allow change of next ship date if its more than 2 days in the future ?>
@@ -41,7 +41,7 @@ $intervals = $this->getIntervals();
41
  <p><span class="next-order-date"><strong><?php echo $subscription->getNextOrderDateText() ?></strong></span></p>
42
  <?php
43
  else: ?>
44
- <p><span class="next-order-date"><strong><?php echo 'n/a' ?></strong></span></p>
45
  <?php endif; ?>
46
  <?php endif; ?>
47
  <?php if ($subscription->getStatus() == 'Active' || $subscription->getStatus() == 'Failed' || $subscription->getStatus() == 'Retry'): ?>
@@ -61,7 +61,7 @@ $intervals = $this->getIntervals();
61
  <option value="<?php echo $qty ?>" selected="selected"><?php echo $qty ?></option>
62
  <?php endif; ?>
63
  </select>
64
- unit(s) every
65
  <select id="delivery_interval_<?php echo $subscription->getSubscriptionId() ?>"
66
  name="delivery_interval" class="delivery_interval" title="Delivery Interval">
67
  <?php foreach ($intervals as $interval): ?>
@@ -76,8 +76,8 @@ $intervals = $this->getIntervals();
76
  <?php if ($this->getNextOrderDateMode() == SFC_Autoship_Model_System_Config_Source_Nextorderdatemode::MODE_MULTIPLE_DATES): ?>
77
  <script type="text/javascript">
78
  //<![CDATA[
79
- $j(function () {
80
- $j("#delivery_date_<?php echo $subscription->getSubscriptionId() ?>").datepicker({
81
  minDate: 2,
82
  showOn: "button",
83
  buttonImage: "<?php echo $this->getSkinUrl('images/autoship/calendar_icon.png')?>",
@@ -85,7 +85,7 @@ $intervals = $this->getIntervals();
85
  buttonText: "Click to change date.",
86
  dateFormat: "mm/dd/y",
87
  onSelect: function () {
88
- var form = $j(this).closest("form");
89
  updateMySubscription(form);
90
  }
91
  })
25
  <div class="subscription-info">
26
  <form class="interval" action="<?php echo Mage::getUrl('autoship/mysubscriptions/change', array('_secure' => true)) ?>">
27
  <?php if ($this->getNextOrderDateMode() == SFC_Autoship_Model_System_Config_Source_Nextorderdatemode::MODE_MULTIPLE_DATES): ?>
28
+ <p><?php echo $this->__("Next Ship Date:") ?></p>
29
  <?php if ($subscription->getStatus() == 'Active' && $subscription->getNextOrderDate() >= date('Y-m-d', strtotime('+2 days'))
30
  ): ?>
31
  <?php // Only allow change of next ship date if its more than 2 days in the future ?>
41
  <p><span class="next-order-date"><strong><?php echo $subscription->getNextOrderDateText() ?></strong></span></p>
42
  <?php
43
  else: ?>
44
+ <p><span class="next-order-date"><strong><?php echo $this->__('n/a') ?></strong></span></p>
45
  <?php endif; ?>
46
  <?php endif; ?>
47
  <?php if ($subscription->getStatus() == 'Active' || $subscription->getStatus() == 'Failed' || $subscription->getStatus() == 'Retry'): ?>
61
  <option value="<?php echo $qty ?>" selected="selected"><?php echo $qty ?></option>
62
  <?php endif; ?>
63
  </select>
64
+ <?php echo $this->__("unit(s) every") ?>
65
  <select id="delivery_interval_<?php echo $subscription->getSubscriptionId() ?>"
66
  name="delivery_interval" class="delivery_interval" title="Delivery Interval">
67
  <?php foreach ($intervals as $interval): ?>
76
  <?php if ($this->getNextOrderDateMode() == SFC_Autoship_Model_System_Config_Source_Nextorderdatemode::MODE_MULTIPLE_DATES): ?>
77
  <script type="text/javascript">
78
  //<![CDATA[
79
+ jQuery(function () {
80
+ jQuery("#delivery_date_<?php echo $subscription->getSubscriptionId() ?>").datepicker({
81
  minDate: 2,
82
  showOn: "button",
83
  buttonImage: "<?php echo $this->getSkinUrl('images/autoship/calendar_icon.png')?>",
85
  buttonText: "Click to change date.",
86
  dateFormat: "mm/dd/y",
87
  onSelect: function () {
88
+ var form = jQuery(this).closest("form");
89
  updateMySubscription(form);
90
  }
91
  })
app/design/frontend/base/default/template/autoship/newsubscription.phtml CHANGED
@@ -17,7 +17,7 @@
17
  ?>
18
 
19
  <div class="page-title">
20
- <h1>Create New Product Subscription</h1>
21
  </div>
22
 
23
  <div class="new-subscription subscription">
17
  ?>
18
 
19
  <div class="page-title">
20
+ <h1><?php echo $this->__("Create New Product Subscription") ?></h1>
21
  </div>
22
 
23
  <div class="new-subscription subscription">
app/design/frontend/base/default/template/autoship/newsubscription/billing_address.phtml CHANGED
@@ -21,11 +21,11 @@ $billingAddress = $subscription->getBillingAddress();
21
  ?>
22
 
23
  <div class="block-title">
24
- <h2>Billing Address</h2>
25
  </div>
26
 
27
  <div class="box-padding">
28
- <p>Please select the address associated with your payment method: <a class="change" href="">(Change)</a></p>
29
 
30
  <address>
31
  <?php echo $billingAddress->getFirstname() ?> <?php echo $billingAddress->getLastname() ?><br/>
@@ -42,7 +42,7 @@ $billingAddress = $subscription->getBillingAddress();
42
 
43
  <div class="change">
44
  <div class="block-title">
45
- <h2>Change Billing Address</h2>
46
  </div>
47
  <div class="block-content">
48
  <?php echo $this->getChildHtml("billing_address_select") ?>
21
  ?>
22
 
23
  <div class="block-title">
24
+ <h2><?php echo $this->__("Billing Address") ?></h2>
25
  </div>
26
 
27
  <div class="box-padding">
28
+ <p><?php echo $this->__("Please select the address associated with your payment method:") ?> <a class="change" href=""><?php echo $this->__("(Change)") ?></a></p>
29
 
30
  <address>
31
  <?php echo $billingAddress->getFirstname() ?> <?php echo $billingAddress->getLastname() ?><br/>
42
 
43
  <div class="change">
44
  <div class="block-title">
45
+ <h2><?php echo $this->__("Change Billing Address") ?></h2>
46
  </div>
47
  <div class="block-content">
48
  <?php echo $this->getChildHtml("billing_address_select") ?>
app/design/frontend/base/default/template/autoship/newsubscription/delivery_frequency.phtml CHANGED
@@ -23,7 +23,7 @@ $platformProduct = $this->getPlatformProduct();
23
  ?>
24
 
25
  <div class="block-title">
26
- <h2>Delivery Frequency</h2>
27
  </div>
28
 
29
  <div class="box-padding">
@@ -34,7 +34,7 @@ $platformProduct = $this->getPlatformProduct();
34
  <option value="<?php echo $i ?>" <?php if($qty == $i): ?>selected="selected"<?php endif; ?>><?php echo $i ?></option>
35
  <?php endfor; ?>
36
  </select>
37
- unit(s) every
38
  <select id="delivery_interval" name="delivery_interval" class="" title="Delivery Interval">
39
  <?php foreach($intervals as $interval): ?>
40
  <option value="<?php echo $interval ?>" <?php if($interval == $subscription->getInterval()): ?>selected="selected"<?php endif; ?>><?php echo $interval ?></option>
23
  ?>
24
 
25
  <div class="block-title">
26
+ <h2><?php echo $this->__("Delivery Frequency") ?></h2>
27
  </div>
28
 
29
  <div class="box-padding">
34
  <option value="<?php echo $i ?>" <?php if($qty == $i): ?>selected="selected"<?php endif; ?>><?php echo $i ?></option>
35
  <?php endfor; ?>
36
  </select>
37
+ <?php echo $this->__("unit(s) every") ?>
38
  <select id="delivery_interval" name="delivery_interval" class="" title="Delivery Interval">
39
  <?php foreach($intervals as $interval): ?>
40
  <option value="<?php echo $interval ?>" <?php if($interval == $subscription->getInterval()): ?>selected="selected"<?php endif; ?>><?php echo $interval ?></option>
app/design/frontend/base/default/template/autoship/newsubscription/payment.phtml CHANGED
@@ -22,14 +22,17 @@ $paymentProfile = $subscription->getPaymentProfile();
22
  ?>
23
 
24
  <div class="block-title">
25
- <h2>Payment Method</h2>
26
  </div>
27
 
28
  <div class="box-padding">
29
  <?php if($paymentProfile->getCustomerCardnumber()): ?>
30
- <p>Credit card ending in <?php echo $paymentProfile->getCustomerCardnumber() ?>. <a class="change" href="">(Change)</a></p>
31
  <?php else: ?>
32
  <p>Haven't saved a credit card yet? <a class="change" href="">Add one now</a>.</p>
 
 
 
33
  <?php endif; ?>
34
 
35
  <?php if ($this->useCouponCode()): ?>
@@ -48,7 +51,7 @@ $paymentProfile = $subscription->getPaymentProfile();
48
 
49
  <div class="change" style="display:none;">
50
  <div class="block-title">
51
- <h2>Change Payment Method</h2>
52
  </div>
53
  <div class="block-content">
54
  <?php echo $this->getChildHtml("payment") ?>
22
  ?>
23
 
24
  <div class="block-title">
25
+ <h2><?php echo $this->__("Payment Method") ?></h2>
26
  </div>
27
 
28
  <div class="box-padding">
29
  <?php if($paymentProfile->getCustomerCardnumber()): ?>
30
+ <p><?php echo $this->__("Credit card ending in") ?> <?php echo $paymentProfile->getCustomerCardnumber() ?>. <a class="change" href=""><?php echo $this->__("(Change)") ?></a></p>
31
  <?php else: ?>
32
  <p>Haven't saved a credit card yet? <a class="change" href="">Add one now</a>.</p>
33
+ <p><?php
34
+ echo $this->__('Haven\'t saved a credit card yet? <a class="change" href="">Add one now</a>.');
35
+ ?></p>
36
  <?php endif; ?>
37
 
38
  <?php if ($this->useCouponCode()): ?>
51
 
52
  <div class="change" style="display:none;">
53
  <div class="block-title">
54
+ <h2><?php echo $this->__("Change Payment Method") ?></h2>
55
  </div>
56
  <div class="block-content">
57
  <?php echo $this->getChildHtml("payment") ?>
app/design/frontend/base/default/template/autoship/newsubscription/shipping_address.phtml CHANGED
@@ -21,11 +21,11 @@ $shippingAddress = $subscription->getShippingAddress();
21
  ?>
22
 
23
  <div class="block-title">
24
- <h2>Shipping Address</h2>
25
  </div>
26
 
27
  <div class="box-padding">
28
- <p>Please select the address where your orders should be delivered: <a class="change" href="">(Change)</a></p>
29
 
30
  <address>
31
  <?php echo $shippingAddress->getFirstname() ?> <?php echo $shippingAddress->getLastname() ?><br/>
@@ -42,7 +42,7 @@ $shippingAddress = $subscription->getShippingAddress();
42
 
43
  <div class="change">
44
  <div class="block-title">
45
- <h2>Change Shipping Address</h2>
46
  </div>
47
  <div class="block-content">
48
  <?php echo $this->getChildHtml("shipping_address_select") ?>
21
  ?>
22
 
23
  <div class="block-title">
24
+ <h2><?php echo $this->__("Shipping Address") ?></h2>
25
  </div>
26
 
27
  <div class="box-padding">
28
+ <p><?php echo $this->__("Please select the address where your orders should be delivered:") ?> <a class="change" href=""><?php echo $this->__("(Change)") ?></a></p>
29
 
30
  <address>
31
  <?php echo $shippingAddress->getFirstname() ?> <?php echo $shippingAddress->getLastname() ?><br/>
42
 
43
  <div class="change">
44
  <div class="block-title">
45
+ <h2><?php echo $this->__("Change Shipping Address") ?></h2>
46
  </div>
47
  <div class="block-content">
48
  <?php echo $this->getChildHtml("shipping_address_select") ?>
app/design/frontend/base/default/template/autoship/newsubscription/summary.phtml CHANGED
@@ -22,36 +22,36 @@ $coreHelper = $this->helper('core');
22
  ?>
23
 
24
  <div class="block-title">
25
- <h2>Estimated Order Summary</h2>
26
  </div>
27
  <ul class="messages"></ul>
28
  <div class="box-padding">
29
  <?php // If $summary is an array, it has totals, otherwise it's a string with error message ?>
30
  <?php if (is_array($summary)): ?>
31
- <p>The following are the estimated costs for each of your shipments:</p>
32
  <div class="subscription-summary-table">
33
  <table>
34
  <tbody>
35
  <tr>
36
- <td class="a-right">Product Total</td>
37
  <td class="a-right"><?php echo $coreHelper->currency($summary['product_total'], true, false); ?></td>
38
  </tr>
39
  <tr>
40
- <td class="a-right">Subscription Discount</td>
41
  <td class="a-right"><?php echo $coreHelper->currency($summary['discount'], true, false); ?></td>
42
  </tr>
43
  <tr>
44
- <td class="a-right">Shipping</td>
45
  <td class="a-right"><?php echo $coreHelper->currency($summary['shipping'], true, false); ?></td>
46
  </tr>
47
  <tr>
48
- <td class="a-right">Tax</td>
49
  <td class="a-right"><?php echo $coreHelper->currency($summary['tax'], true, false); ?></td>
50
  </tr>
51
  </tbody>
52
  <tfoot>
53
  <tr>
54
- <td class="a-right"><strong>Estimated Order Total</strong></td>
55
  <td class="a-right"><strong><span class="price"><?php echo $coreHelper->currency($summary['total'], true, false); ?></span></strong></td>
56
  </tr>
57
  </tfoot>
22
  ?>
23
 
24
  <div class="block-title">
25
+ <h2><?php echo $this->__("Estimated Order Summary") ?></h2>
26
  </div>
27
  <ul class="messages"></ul>
28
  <div class="box-padding">
29
  <?php // If $summary is an array, it has totals, otherwise it's a string with error message ?>
30
  <?php if (is_array($summary)): ?>
31
+ <p><?php echo $this->__("The following are the estimated costs for each of your shipments:") ?></p>
32
  <div class="subscription-summary-table">
33
  <table>
34
  <tbody>
35
  <tr>
36
+ <td class="a-right"><?php echo $this->__("Product Total") ?></td>
37
  <td class="a-right"><?php echo $coreHelper->currency($summary['product_total'], true, false); ?></td>
38
  </tr>
39
  <tr>
40
+ <td class="a-right"><?php echo $this->__("Subscription Discount") ?></td>
41
  <td class="a-right"><?php echo $coreHelper->currency($summary['discount'], true, false); ?></td>
42
  </tr>
43
  <tr>
44
+ <td class="a-right"><?php echo $this->__("Shipping") ?></td>
45
  <td class="a-right"><?php echo $coreHelper->currency($summary['shipping'], true, false); ?></td>
46
  </tr>
47
  <tr>
48
+ <td class="a-right"><?php echo $this->__("Tax") ?></td>
49
  <td class="a-right"><?php echo $coreHelper->currency($summary['tax'], true, false); ?></td>
50
  </tr>
51
  </tbody>
52
  <tfoot>
53
  <tr>
54
+ <td class="a-right"><strong><?php echo $this->__("Estimated Order Total") ?></strong></td>
55
  <td class="a-right"><strong><span class="price"><?php echo $coreHelper->currency($summary['total'], true, false); ?></span></strong></td>
56
  </tr>
57
  </tfoot>
app/design/frontend/base/default/template/autoship/payment/form/cc_saved.phtml CHANGED
@@ -16,7 +16,8 @@
16
  */
17
  ?>
18
  <?php $_code = $this->getMethodCode() ?>
19
- <?php $_paymentProfile = $this->getMethod()->getSavedPaymentProfile() ?>
 
20
  <?php echo $this->getChildHtml() ?>
21
  <ul class="form-list" id="payment_form_<?php echo $_code ?>" style="display:none;">
22
  <input type="hidden" id="<?php echo $_code ?>_payment_token" name="payment[payment_token]"
@@ -27,42 +28,50 @@
27
  title="<?php echo $this->__('Obscured Card Number') ?>" value="<?php echo $this->getObscuredCardNumber() ?>"/>
28
  <input type="hidden" id="<?php echo $_code ?>_cc_type" name="payment[cc_type]" title="<?php echo $this->__('Card Type') ?>"
29
  value="<?php echo $this->getMagentoCardType() ?>"/>
30
- <li id="<?php echo $_code ?>_cc_type_exp_div">
31
- <label for="<?php echo $_code ?>_expiration" class="required"><em>*</em><?php echo $this->__('Expiration Date') ?></label>
32
-
33
- <div class="input-box">
34
- <div class="v-fix">
35
- <select id="<?php echo $_code ?>_expiration" name="payment[cc_exp_month]" class="month validate-cc-exp required-entry">
36
- <?php $_ccExpMonth = $_paymentProfile->getData('creditcard_month') ?>
37
- <?php foreach ($this->getCcMonths() as $k => $v): ?>
38
- <option value="<?php echo $k ? $k : '' ?>"<?php if ($k == $_ccExpMonth
39
- ): ?> selected="selected"<?php endif ?>><?php echo $v ?></option>
40
- <?php endforeach ?>
41
- </select>
42
- </div>
43
- <div class="v-fix">
44
- <?php $_ccExpYear = $_paymentProfile->getData('creditcard_year') ?>
45
- <select id="<?php echo $_code ?>_expiration_yr" name="payment[cc_exp_year]" class="year required-entry">
46
- <?php foreach ($this->getCcYears() as $k => $v): ?>
47
- <option value="<?php echo $k ? $k : '' ?>"<?php if ($k == $_ccExpYear
48
- ): ?> selected="selected"<?php endif ?>><?php echo $v ?></option>
49
- <?php endforeach ?>
50
- </select>
51
- </div>
52
- </div>
53
- </li>
54
- <?php if ($this->hasVerification()): ?>
55
- <li id="<?php echo $_code ?>_cc_type_cvv_div">
56
- <label for="<?php echo $_code ?>_cc_cid" class="required"><em>*</em><?php echo $this->__('Card Verification Number') ?>
57
- </label>
58
 
59
  <div class="input-box">
60
  <div class="v-fix">
61
- <input type="text" title="<?php echo $this->__('Card Verification Number') ?>" class="input-text cvv required-entry"
62
- id="<?php echo $_code ?>_cc_cid" name="payment[cc_cid]" value=""/>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
63
  </div>
64
- <a href="#" class="cvv-what-is-this"><?php echo $this->__('What is this?') ?></a>
65
  </div>
66
  </li>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
67
  <?php endif; ?>
68
  </ul>
16
  */
17
  ?>
18
  <?php $_code = $this->getMethodCode() ?>
19
+ <?php /** @var SFC_Autoship_Model_Payment_Profile $_paymentProfile */
20
+ $_paymentProfile = $this->getMethod()->getSavedPaymentProfile() ?>
21
  <?php echo $this->getChildHtml() ?>
22
  <ul class="form-list" id="payment_form_<?php echo $_code ?>" style="display:none;">
23
  <input type="hidden" id="<?php echo $_code ?>_payment_token" name="payment[payment_token]"
28
  title="<?php echo $this->__('Obscured Card Number') ?>" value="<?php echo $this->getObscuredCardNumber() ?>"/>
29
  <input type="hidden" id="<?php echo $_code ?>_cc_type" name="payment[cc_type]" title="<?php echo $this->__('Card Type') ?>"
30
  value="<?php echo $this->getMagentoCardType() ?>"/>
31
+ <?php if (!$_paymentProfile->isThirdParty()) : ?>
32
+ <li id="<?php echo $_code ?>_cc_type_exp_div">
33
+ <label for="<?php echo $_code ?>_expiration" class="required"><em>*</em><?php echo $this->__('Expiration Date') ?></label>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
34
 
35
  <div class="input-box">
36
  <div class="v-fix">
37
+ <?php if ($_paymentProfile->isThirdParty()): ?>
38
+
39
+ <?php else: ?>
40
+ <select id="<?php echo $_code ?>_expiration" name="payment[cc_exp_month]" class="month validate-cc-exp required-entry">
41
+ <?php $_ccExpMonth = $_paymentProfile->getData('creditcard_month') ?>
42
+ <?php foreach ($this->getCcMonths() as $k => $v): ?>
43
+ <option value="<?php echo $k ? $k : '' ?>"<?php if ($k == $_ccExpMonth
44
+ ): ?> selected="selected"<?php endif ?>><?php echo $v ?></option>
45
+ <?php endforeach ?>
46
+ </select>
47
+ <?php endif; ?>
48
+ </div>
49
+ <div class="v-fix">
50
+ <?php $_ccExpYear = $_paymentProfile->getData('creditcard_year') ?>
51
+ <select id="<?php echo $_code ?>_expiration_yr" name="payment[cc_exp_year]" class="year required-entry">
52
+ <?php foreach ($this->getCcYears() as $k => $v): ?>
53
+ <option value="<?php echo $k ? $k : '' ?>"<?php if ($k == $_ccExpYear
54
+ ): ?> selected="selected"<?php endif ?>><?php echo $v ?></option>
55
+ <?php endforeach ?>
56
+ </select>
57
  </div>
 
58
  </div>
59
  </li>
60
+ <?php if ($this->hasVerification($_paymentProfile)): ?>
61
+ <li id="<?php echo $_code ?>_cc_type_cvv_div">
62
+ <label for="<?php echo $_code ?>_cc_cid" class="required"><em>*</em><?php echo $this->__('Card Verification Number') ?>
63
+ </label>
64
+
65
+ <div class="input-box">
66
+ <div class="v-fix">
67
+ <input type="text" title="<?php echo $this->__('Card Verification Number') ?>" class="input-text cvv required-entry"
68
+ id="<?php echo $_code ?>_cc_cid" name="payment[cc_cid]" value=""/>
69
+ </div>
70
+ <a href="#" class="cvv-what-is-this"><?php echo $this->__('What is this?') ?></a>
71
+ </div>
72
+ </li>
73
+ <?php endif; ?>
74
+ <?php else: ?>
75
+ <input type="hidden" name="payment[third_party_token]" value="1" />
76
  <?php endif; ?>
77
  </ul>
app/design/frontend/base/default/template/autoship/payment/profile/edit.phtml CHANGED
@@ -27,11 +27,11 @@
27
  <input name="payment_profile_id" type="hidden" value="<?php echo $paymentProfile->getId() ?>" />
28
 
29
  <div class="fieldset">
30
- <h2 class="legend">Cardholder Information</h2>
31
  <ul class="form-list">
32
  <li class="fields">
33
  <div class="field name-firstname">
34
- <label for="bill_to_forename" class="required"><em>*</em>First Name</label>
35
 
36
  <div class="input-box">
37
  <input type="text" id="bill_to_forename" name="billing_address[first_name]"
@@ -40,7 +40,7 @@
40
  </div>
41
  </div>
42
  <div class="field name-lastname">
43
- <label for="bill_to_surname" class="required"><em>*</em>Last Name</label>
44
 
45
  <div class="input-box">
46
  <input type="text" id="bill_to_surname" name="billing_address[last_name]"
@@ -53,11 +53,11 @@
53
  </div>
54
 
55
  <div class="fieldset">
56
- <h2 class="legend">Billing Address</h2>
57
  <ul class="form-list">
58
  <li class="wide">
59
  <div class="address">
60
- <label for="bill_to_address_line1" class="required">Street Address</label>
61
 
62
  <div class="input-box">
63
  <input type="text" id="bill_to_address_line1" name="billing_address[street1]"
@@ -79,7 +79,7 @@
79
  </li>
80
  <li class="fields">
81
  <div class="field name-firstname">
82
- <label for="bill_to_address_city" class="required">City</label>
83
 
84
  <div class="input-box">
85
  <input type="text" id="bill_to_address_city" name="billing_address[city]" value="<?php echo $this->escapeHtml($billingAddress->getData('city')) ?>"
@@ -87,7 +87,7 @@
87
  </div>
88
  </div>
89
  <div class="field name-lastname">
90
- <label for="bill_to_address_state" class="required">State/Province</label>
91
 
92
  <div class="input-box">
93
  <input type="text" id="bill_to_address_state" name="billing_address[region]"
@@ -98,7 +98,7 @@
98
  </li>
99
  <li class="fields">
100
  <div class="field name-firstname">
101
- <label for="bill_to_address_postal_code" class="required">Zip/Postal Code</label>
102
 
103
  <div class="input-box">
104
  <input type="text" id="bill_to_address_postal_code" name="billing_address[postcode]"
@@ -109,7 +109,7 @@
109
  </li>
110
  <li class="wide">
111
  <div class="country">
112
- <label for="bill_to_address_country" class="required">Country</label>
113
 
114
  <div class="input-box">
115
  <select id="bill_to_address_country" name="billing_address[country]" title="Country" class="input-text">
@@ -126,7 +126,7 @@
126
  </li>
127
  <li class="fields">
128
  <div class="field name-firstname">
129
- <label for="bill_to_phone" class="required">Telephone</label>
130
 
131
  <div class="input-box">
132
  <input type="text" id="bill_to_phone" name="billing_address[phone]"
@@ -139,7 +139,7 @@
139
  </div>
140
 
141
  <div class="fieldset">
142
- <h2 class="legend">Payment Information</h2>
143
  <ul class="form-list">
144
  <li>
145
  <label for="card_type" class="required"><em>*</em><?php echo $this->__('Credit Card Type') ?></label>
@@ -156,7 +156,7 @@
156
  </li>
157
  <li class="wide">
158
  <div class="">
159
- <label for="card_number" class="required"><em>*</em>Card Number</label>
160
 
161
  <div class="input-box">
162
  <input type="text" id="card_number" name="credit_card[number]" disabled="disabled"
@@ -199,9 +199,11 @@
199
  <div class="buttons-set form-buttons">
200
  <p class="back-link"><a href="<?php echo $this->getBackUrl() ?>">
201
  <small>&#171;</small>
202
- Back</a></p>
 
203
  <button type="submit" class="button" title="Save">
204
- <span><span>Save Credit Card</span></span>
205
  </button>
 
206
  </div>
207
  </form>
27
  <input name="payment_profile_id" type="hidden" value="<?php echo $paymentProfile->getId() ?>" />
28
 
29
  <div class="fieldset">
30
+ <h2 class="legend"><?php echo $this->__("Cardholder Information") ?></h2>
31
  <ul class="form-list">
32
  <li class="fields">
33
  <div class="field name-firstname">
34
+ <label for="bill_to_forename" class="required"><em>*</em><?php echo $this->__("First Name") ?></label>
35
 
36
  <div class="input-box">
37
  <input type="text" id="bill_to_forename" name="billing_address[first_name]"
40
  </div>
41
  </div>
42
  <div class="field name-lastname">
43
+ <label for="bill_to_surname" class="required"><em>*</em><?php echo $this->__("Last Name") ?></label>
44
 
45
  <div class="input-box">
46
  <input type="text" id="bill_to_surname" name="billing_address[last_name]"
53
  </div>
54
 
55
  <div class="fieldset">
56
+ <h2 class="legend"><?php echo $this->__("Billing Address") ?></h2>
57
  <ul class="form-list">
58
  <li class="wide">
59
  <div class="address">
60
+ <label for="bill_to_address_line1" class="required"><?php echo $this->__("Street Address") ?></label>
61
 
62
  <div class="input-box">
63
  <input type="text" id="bill_to_address_line1" name="billing_address[street1]"
79
  </li>
80
  <li class="fields">
81
  <div class="field name-firstname">
82
+ <label for="bill_to_address_city" class="required"><?php echo $this->__("City") ?></label>
83
 
84
  <div class="input-box">
85
  <input type="text" id="bill_to_address_city" name="billing_address[city]" value="<?php echo $this->escapeHtml($billingAddress->getData('city')) ?>"
87
  </div>
88
  </div>
89
  <div class="field name-lastname">
90
+ <label for="bill_to_address_state" class="required"><?php echo $this->__("State/Province") ?></label>
91
 
92
  <div class="input-box">
93
  <input type="text" id="bill_to_address_state" name="billing_address[region]"
98
  </li>
99
  <li class="fields">
100
  <div class="field name-firstname">
101
+ <label for="bill_to_address_postal_code" class="required"><?php echo $this->__("Zip/Postal Code") ?></label>
102
 
103
  <div class="input-box">
104
  <input type="text" id="bill_to_address_postal_code" name="billing_address[postcode]"
109
  </li>
110
  <li class="wide">
111
  <div class="country">
112
+ <label for="bill_to_address_country" class="required"><?php echo $this->__("Country") ?></label>
113
 
114
  <div class="input-box">
115
  <select id="bill_to_address_country" name="billing_address[country]" title="Country" class="input-text">
126
  </li>
127
  <li class="fields">
128
  <div class="field name-firstname">
129
+ <label for="bill_to_phone" class="required"><?php echo $this->__("Telephone") ?></label>
130
 
131
  <div class="input-box">
132
  <input type="text" id="bill_to_phone" name="billing_address[phone]"
139
  </div>
140
 
141
  <div class="fieldset">
142
+ <h2 class="legend"><?php echo $this->__("Payment Information") ?></h2>
143
  <ul class="form-list">
144
  <li>
145
  <label for="card_type" class="required"><em>*</em><?php echo $this->__('Credit Card Type') ?></label>
156
  </li>
157
  <li class="wide">
158
  <div class="">
159
+ <label for="card_number" class="required"><em>*</em><?php echo $this->__("Card Number") ?></label>
160
 
161
  <div class="input-box">
162
  <input type="text" id="card_number" name="credit_card[number]" disabled="disabled"
199
  <div class="buttons-set form-buttons">
200
  <p class="back-link"><a href="<?php echo $this->getBackUrl() ?>">
201
  <small>&#171;</small>
202
+ <?php echo $this->__("Back") ?></a></p>
203
+ <?php if (!$paymentProfile->isThirdParty()): ?>
204
  <button type="submit" class="button" title="Save">
205
+ <span><span><?php echo $this->__("Save Credit Card") ?></span></span>
206
  </button>
207
+ <?php endif; ?>
208
  </div>
209
  </form>
app/design/frontend/base/default/template/autoship/payment/profile/grid.phtml CHANGED
@@ -17,21 +17,21 @@
17
  ?>
18
  <?php $paymentProfiles = $this->getPaymentProfiles() ?>
19
  <div class="page-title">
20
- <h1>My Credit Cards</h1>
21
  </div>
22
 
23
  <fieldset>
24
  <div class="pager">
25
  <p class="amount">
26
- <?php echo count($paymentProfiles); ?> Item(s)
27
  </p>
28
  </div>
29
  <table class="data-table" id="cc-table">
30
  <thead>
31
  <tr class="first last">
32
- <th>Card Number</th>
33
- <th>Billing Customer Name</th>
34
- <th>Edit / Delete</th>
35
  </tr>
36
  </thead>
37
  <tbody>
@@ -48,7 +48,7 @@
48
  <?php echo $billingAddress->getData('first_name') . ' ' . $billingAddress->getData('last_name'); ?>
49
  </td>
50
  <td>
51
- <span><a href="<?php echo Mage::getUrl('subscriptions/mycreditcards/edit'); ?>id/<?php echo $profile->getId() ?>"><b>Edit</b></a></span> |
52
  <span><a href="#" class="link-reorder" onclick="confirmDelete(<?php echo $profile->getId() ?>)"> Delete</a></span>
53
  </td>
54
  </tr>
@@ -58,7 +58,7 @@
58
  </table>
59
  <div class="pager">
60
  <p class="amount">
61
- <?php echo count($paymentProfiles); ?> Item(s)
62
  </p>
63
  </div>
64
  </fieldset>
@@ -75,7 +75,7 @@
75
  function confirmDelete(id)
76
  {
77
  var x;
78
- var r=confirm("Are you sure you want to delete this credit card?");
79
  if (r==true)
80
  {
81
  window.location="<?php echo Mage::getUrl('subscriptions/mycreditcards/delete'); ?>id/" + id;
17
  ?>
18
  <?php $paymentProfiles = $this->getPaymentProfiles() ?>
19
  <div class="page-title">
20
+ <h1><?php echo $this->__("My Credit Cards") ?></h1>
21
  </div>
22
 
23
  <fieldset>
24
  <div class="pager">
25
  <p class="amount">
26
+ <?php echo count($paymentProfiles); ?> <?php echo $this->__("Item(s)") ?>
27
  </p>
28
  </div>
29
  <table class="data-table" id="cc-table">
30
  <thead>
31
  <tr class="first last">
32
+ <th><?php echo $this->__("Card Number") ?></th>
33
+ <th><?php echo $this->__("Billing Customer Name") ?></th>
34
+ <th><?php echo $this->__("Edit / Delete") ?></th>
35
  </tr>
36
  </thead>
37
  <tbody>
48
  <?php echo $billingAddress->getData('first_name') . ' ' . $billingAddress->getData('last_name'); ?>
49
  </td>
50
  <td>
51
+ <?php if (!$profile->isThirdParty()) :?><span><a href="<?php echo Mage::getUrl('subscriptions/mycreditcards/edit'); ?>id/<?php echo $profile->getId() ?>"><b>Edit</b></a></span> |<?php endif; ?>
52
  <span><a href="#" class="link-reorder" onclick="confirmDelete(<?php echo $profile->getId() ?>)"> Delete</a></span>
53
  </td>
54
  </tr>
58
  </table>
59
  <div class="pager">
60
  <p class="amount">
61
+ <?php echo count($paymentProfiles); ?> <?php echo $this->__("Item(s)") ?>
62
  </p>
63
  </div>
64
  </fieldset>
75
  function confirmDelete(id)
76
  {
77
  var x;
78
+ var r=confirm("<?php echo $this->__("Are you sure you want to delete this credit card?")?>");
79
  if (r==true)
80
  {
81
  window.location="<?php echo Mage::getUrl('subscriptions/mycreditcards/delete'); ?>id/" + id;
app/design/frontend/base/default/template/autoship/payment/profile/new.phtml CHANGED
@@ -29,11 +29,11 @@
29
  <input name="utf8" type="hidden" value="✓" />
30
 
31
  <div class="fieldset">
32
- <h2 class="legend">Cardholder Information</h2>
33
  <ul class="form-list">
34
  <li class="fields">
35
  <div class="field name-firstname">
36
- <label for="bill_to_forename" class="required"><em>*</em>First Name</label>
37
 
38
  <div class="input-box">
39
  <input type="text" id="bill_to_forename" name="credit_card[first_name]"
@@ -42,7 +42,7 @@
42
  </div>
43
  </div>
44
  <div class="field name-lastname">
45
- <label for="bill_to_surname" class="required"><em>*</em>Last Name</label>
46
 
47
  <div class="input-box">
48
  <input type="text" id="bill_to_surname" name="credit_card[last_name]"
@@ -55,11 +55,11 @@
55
  </div>
56
 
57
  <div class="fieldset">
58
- <h2 class="legend">Billing Address</h2>
59
  <ul class="form-list">
60
  <li class="wide">
61
  <div class="address">
62
- <label for="bill_to_address_line1" class="required">Street Address</label>
63
 
64
  <div class="input-box">
65
  <input type="text" id="bill_to_address_line1" name="credit_card[address1]"
@@ -81,7 +81,7 @@
81
  </li>
82
  <li class="fields">
83
  <div class="field name-firstname">
84
- <label for="bill_to_address_city" class="required">City</label>
85
 
86
  <div class="input-box">
87
  <input type="text" id="bill_to_address_city" name="credit_card[city]" value="<?php echo $this->escapeHtml($billingAddress->getData('city')) ?>"
@@ -89,7 +89,7 @@
89
  </div>
90
  </div>
91
  <div class="field name-lastname">
92
- <label for="bill_to_address_state" class="required">State/Province</label>
93
 
94
  <div class="input-box">
95
  <input type="text" id="bill_to_address_state" name="credit_card[state]"
@@ -100,7 +100,7 @@
100
  </li>
101
  <li class="fields">
102
  <div class="field name-firstname">
103
- <label for="bill_to_address_postal_code" class="required">Zip/Postal Code</label>
104
 
105
  <div class="input-box">
106
  <input type="text" id="bill_to_address_postal_code" name="credit_card[zip]"
@@ -111,7 +111,7 @@
111
  </li>
112
  <li class="wide">
113
  <div class="country">
114
- <label for="bill_to_address_country" class="required">Country</label>
115
 
116
  <div class="input-box">
117
  <select id="bill_to_address_country" name="credit_card[country]" title="Country" class="input-text">
@@ -128,7 +128,7 @@
128
  </li>
129
  <li class="fields">
130
  <div class="field name-firstname">
131
- <label for="bill_to_phone" class="required">Telephone</label>
132
 
133
  <div class="input-box">
134
  <input type="text" id="bill_to_phone" name="credit_card[phone_number]"
@@ -141,7 +141,7 @@
141
  </div>
142
 
143
  <div class="fieldset">
144
- <h2 class="legend">Payment Information</h2>
145
  <ul class="form-list">
146
  <li>
147
  <label for="card_type" class="required"><em>*</em><?php echo $this->__('Credit Card Type') ?></label>
@@ -158,7 +158,7 @@
158
  </li>
159
  <li class="wide">
160
  <div class="">
161
- <label for="card_number" class="required"><em>*</em>Card Number</label>
162
 
163
  <div class="input-box">
164
  <input type="text" id="card_number" name="credit_card[number]"
@@ -210,9 +210,9 @@
210
  <div class="buttons-set form-buttons">
211
  <p class="back-link"><a href="<?php echo $this->getBackUrl() ?>">
212
  <small>&#171;</small>
213
- Back</a></p>
214
  <button type="submit" class="button" title="Save">
215
- <span><span>Save Credit Card</span></span>
216
  </button>
217
  </div>
218
  </form>
29
  <input name="utf8" type="hidden" value="✓" />
30
 
31
  <div class="fieldset">
32
+ <h2 class="legend"><?php echo $this->__("Cardholder Information") ?></h2>
33
  <ul class="form-list">
34
  <li class="fields">
35
  <div class="field name-firstname">
36
+ <label for="bill_to_forename" class="required"><em>*</em><?php echo $this->__("First Name") ?></label>
37
 
38
  <div class="input-box">
39
  <input type="text" id="bill_to_forename" name="credit_card[first_name]"
42
  </div>
43
  </div>
44
  <div class="field name-lastname">
45
+ <label for="bill_to_surname" class="required"><em>*</em><?php echo $this->__("Last Name") ?></label>
46
 
47
  <div class="input-box">
48
  <input type="text" id="bill_to_surname" name="credit_card[last_name]"
55
  </div>
56
 
57
  <div class="fieldset">
58
+ <h2 class="legend"><?php echo $this->__("Billing Address") ?></h2>
59
  <ul class="form-list">
60
  <li class="wide">
61
  <div class="address">
62
+ <label for="bill_to_address_line1" class="required"><?php echo $this->__("Street Address") ?></label>
63
 
64
  <div class="input-box">
65
  <input type="text" id="bill_to_address_line1" name="credit_card[address1]"
81
  </li>
82
  <li class="fields">
83
  <div class="field name-firstname">
84
+ <label for="bill_to_address_city" class="required"><?php echo $this->__("City") ?></label>
85
 
86
  <div class="input-box">
87
  <input type="text" id="bill_to_address_city" name="credit_card[city]" value="<?php echo $this->escapeHtml($billingAddress->getData('city')) ?>"
89
  </div>
90
  </div>
91
  <div class="field name-lastname">
92
+ <label for="bill_to_address_state" class="required"><?php echo $this->__("State/Province") ?></label>
93
 
94
  <div class="input-box">
95
  <input type="text" id="bill_to_address_state" name="credit_card[state]"
100
  </li>
101
  <li class="fields">
102
  <div class="field name-firstname">
103
+ <label for="bill_to_address_postal_code" class="required"><?php echo $this->__("Zip/Postal Code") ?></label>
104
 
105
  <div class="input-box">
106
  <input type="text" id="bill_to_address_postal_code" name="credit_card[zip]"
111
  </li>
112
  <li class="wide">
113
  <div class="country">
114
+ <label for="bill_to_address_country" class="required"><?php echo $this->__("Country") ?></label>
115
 
116
  <div class="input-box">
117
  <select id="bill_to_address_country" name="credit_card[country]" title="Country" class="input-text">
128
  </li>
129
  <li class="fields">
130
  <div class="field name-firstname">
131
+ <label for="bill_to_phone" class="required"><?php echo $this->__("Telephone") ?></label>
132
 
133
  <div class="input-box">
134
  <input type="text" id="bill_to_phone" name="credit_card[phone_number]"
141
  </div>
142
 
143
  <div class="fieldset">
144
+ <h2 class="legend"><?php echo $this->__("Payment Information") ?></h2>
145
  <ul class="form-list">
146
  <li>
147
  <label for="card_type" class="required"><em>*</em><?php echo $this->__('Credit Card Type') ?></label>
158
  </li>
159
  <li class="wide">
160
  <div class="">
161
+ <label for="card_number" class="required"><em>*</em><?php echo $this->__("Card Number") ?></label>
162
 
163
  <div class="input-box">
164
  <input type="text" id="card_number" name="credit_card[number]"
210
  <div class="buttons-set form-buttons">
211
  <p class="back-link"><a href="<?php echo $this->getBackUrl() ?>">
212
  <small>&#171;</small>
213
+ <?php echo $this->__("Back") ?></a></p>
214
  <button type="submit" class="button" title="Save">
215
+ <span><span><?php echo $this->__("Save Credit Card") ?></span></span>
216
  </button>
217
  </div>
218
  </form>
app/design/frontend/base/default/template/autoship/product/subscribe.phtml CHANGED
@@ -18,38 +18,56 @@
18
  ?>
19
  <?php if(Mage::getStoreConfig('autoship_general/general/enabled') == '1'): ?>
20
  <?php if($this->isProductAutoshipEligible()): ?>
21
- <div class="subscription-product">
 
22
  <ul class="options-list">
23
  <li>
24
- <input type="radio" onclick="" class="radio" id="delivery-option-one-time" name="delivery-option" value="one-time-delivery"/>
25
- <div class="radio-text">
26
- <span class=label>
27
- <label for="delivery-option-one-time">One Time Delivery</label>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
28
  </span>
29
- <p><span class="price">Price: <?php echo $this->getOneTimePurchasePrice(true) ?></span></p>
30
- </div>
31
- <div class="clearer"></div>
32
  </li>
33
  <li>
34
- <input type="radio" onclick="" class="radio" id="delivery-option-subscribe" name="delivery-option" value="subscribe" checked="checked"/>
35
- <span class=label>
36
- <div class="radio-text">
37
- <label for="delivery-option-subscribe">Regular Delivery</label>
 
 
 
38
  </span>
39
- <p><span class="product-price"><?php echo $this->getDiscountText() ?></span></p>
40
- <p>
41
- <label for="delivery-interval">Delivery every:</label><br />
42
- <select onchange="" id="delivery-interval" name="delivery-interval" class="">
43
- <?php foreach($this->getIntervals() as $interval): ?>
44
- <option value="<?php echo $interval ?>"><?php echo $interval ?></option>
45
- <?php endforeach; ?>
46
- </select>
47
- </p>
48
- </div>
49
- <div class="clearer"></div>
50
  </li>
51
  </ul>
52
  </div>
 
53
  <?php if(Mage::getStoreConfig('autoship_subscription/subscription/use_new_subscription_page') == '1'): ?>
54
  <script type="text/javascript">
55
  //<![CDATA[
18
  ?>
19
  <?php if(Mage::getStoreConfig('autoship_general/general/enabled') == '1'): ?>
20
  <?php if($this->isProductAutoshipEligible()): ?>
21
+ <?php if($this->isTrialProduct() || $this->getSubscriptionOptionMode() == 'subscription_only'): // Subscription Only Mode or Trial Product - Only Subscription Option Allowed ?>
22
+ <div class="subscription-product product-options">
23
  <ul class="options-list">
24
  <li>
25
+ <input type="hidden" onclick="" class="radio" id="delivery-option-subscribe" name="delivery-option" value="subscribe" checked="checked"/>
26
+ <p><span class="product-price"><?php echo $this->getDiscountText() ?></span></p>
27
+ <label for="delivery-interval">Delivery every:
28
+ <select onchange="" id="delivery-interval" name="delivery-interval" class="">
29
+ <?php foreach($this->getIntervals() as $interval): ?>
30
+ <option value="<?php echo $interval ?>" <?php if($interval == $this->getDefaultInterval()): ?> selected="selected"<?php endif; ?>><?php echo $interval ?></option>
31
+ <?php endforeach; ?>
32
+ </select>
33
+ </label>
34
+ <div class="clearer"></div>
35
+ </li>
36
+ </ul>
37
+ </div>
38
+ <?php else: // Standard mode - subscription or one-time purchase allowed ?>
39
+ <div class="subscription-product product-options">
40
+ <ul class="options-list">
41
+ <li>
42
+ <input type="radio" onclick="" class="radio validate-one-required-by-name change-container-classname" id="delivery-option-one-time" name="delivery-option" value="one-time-delivery"
43
+ <?php if ($this->getDefaultSubscriptionOption() == 'onetime_purchase'): ?> checked="checked"<?php endif; ?>
44
+ />
45
+ <span class="label">
46
+ <label for="delivery-option-one-time">One Time Delivery&nbsp;&mdash;&nbsp;
47
+ <span class="price-notice"><?php echo $this->getOneTimePurchasePrice(true) ?></span>
48
+ </label>
49
  </span>
 
 
 
50
  </li>
51
  <li>
52
+ <input type="radio" onclick="" class="radio validate-one-required-by-name change-container-classname" id="delivery-option-subscribe" name="delivery-option" value="subscribe"
53
+ <?php if ($this->getDefaultSubscriptionOption() != 'onetime_purchase'): ?> checked="checked"<?php endif; ?>
54
+ />
55
+ <span class="label">
56
+ <label for="delivery-option-subscribe">Regular Delivery&nbsp;&mdash;&nbsp;
57
+ <span class="price-notice"><?php echo $this->getDiscountText() ?></span>
58
+ </label>
59
  </span>
60
+ <label for="delivery-interval">Delivery every:
61
+ <select onchange="" id="delivery-interval" name="delivery-interval" class="">
62
+ <?php foreach($this->getIntervals() as $interval): ?>
63
+ <option value="<?php echo $interval ?>" <?php if($interval == $this->getDefaultInterval()): ?> selected="selected"<?php endif; ?>><?php echo $interval ?></option>
64
+ <?php endforeach; ?>
65
+ </select>
66
+ </label>
 
 
 
 
67
  </li>
68
  </ul>
69
  </div>
70
+ <?php endif; ?>
71
  <?php if(Mage::getStoreConfig('autoship_subscription/subscription/use_new_subscription_page') == '1'): ?>
72
  <script type="text/javascript">
73
  //<![CDATA[
app/design/frontend/base/default/template/autoship/product/view/type/grouped/subscribe.phtml CHANGED
@@ -30,7 +30,7 @@ $productId = $this->getProduct()->getId();
30
 
31
  <div class="radio-text">
32
  <span class=label>
33
- <label for="delivery-option-one-time">One Time Delivery</label>
34
  </span>
35
 
36
  <p><span class="price">Price: <?php echo $this->getOneTimePurchasePrice(true) ?></span></p>
@@ -42,16 +42,16 @@ $productId = $this->getProduct()->getId();
42
  <input type="radio" onclick="" class="radio" id="delivery-option-subscribe" name="delivery-option[<?php echo $productId ?>]"
43
  value="subscribe" checked="checked"/>
44
  <span class=label>
45
- <label for="delivery-option-subscribe">Regular Delivery</label>
46
  </span>
47
 
48
  <p><span class="product-price"><?php echo $this->getDiscountText() ?></span></p>
49
 
50
  <p>
51
- <label for="delivery-interval">Delivery every:</label><br/>
52
  <select onchange="" id="delivery-interval" name="delivery-interval[<?php echo $productId ?>]" class="">
53
  <?php foreach ($this->getIntervals() as $interval): ?>
54
- <option value="<?php echo $interval ?>"><?php echo $interval ?></option>
55
  <?php endforeach; ?>
56
  </select>
57
  </p>
30
 
31
  <div class="radio-text">
32
  <span class=label>
33
+ <label for="delivery-option-one-time"><?php echo $this->__("One Time Delivery") ?></label>
34
  </span>
35
 
36
  <p><span class="price">Price: <?php echo $this->getOneTimePurchasePrice(true) ?></span></p>
42
  <input type="radio" onclick="" class="radio" id="delivery-option-subscribe" name="delivery-option[<?php echo $productId ?>]"
43
  value="subscribe" checked="checked"/>
44
  <span class=label>
45
+ <label for="delivery-option-subscribe"><?php echo $this->__("Regular Delivery") ?></label>
46
  </span>
47
 
48
  <p><span class="product-price"><?php echo $this->getDiscountText() ?></span></p>
49
 
50
  <p>
51
+ <label for="delivery-interval"><?php echo $this->__("Delivery every:") ?></label><br/>
52
  <select onchange="" id="delivery-interval" name="delivery-interval[<?php echo $productId ?>]" class="">
53
  <?php foreach ($this->getIntervals() as $interval): ?>
54
+ <option value="<?php echo $interval ?>" <?php if($interval == $this->getDefaultInterval()): ?> selected="selected"<?php endif; ?>><?php echo $interval ?></option>
55
  <?php endforeach; ?>
56
  </select>
57
  </p>
app/design/frontend/base/default/template/autoship/subscription/form/payment.phtml CHANGED
@@ -30,7 +30,7 @@
30
  ?>
31
  <?php foreach ($savedCards as $card): ?>
32
  <dt>
33
- <?php $curMethodName = 'Use my Saved Card Ending in ' . $card['creditcard_last_digits']; ?>
34
  <input
35
  id="payment_token_<?php echo $card['payment_token'] ?>"
36
  value="<?php echo $card['payment_token'] ?>"
@@ -40,7 +40,7 @@
40
  class="radio"
41
  <?php if($card['payment_token'] == $selectedCard['payment_token']): ?>checked="checked"<?php endif; ?> />
42
  <label for="payment_token_<?php echo $card['payment_token'] ?>">
43
- <?php echo $this->escapeHtml($curMethodName) ?><?php if (strlen($card['edit_url'])): ?> <a href="<?php echo $card['edit_url'] ?>">(Edit)</a><?php endif; ?>
44
  </label>
45
  </dt>
46
  <dd>
30
  ?>
31
  <?php foreach ($savedCards as $card): ?>
32
  <dt>
33
+ <?php $curMethodName = $this->__('Use my Saved Card Ending in %s', $card['creditcard_last_digits']); ?>
34
  <input
35
  id="payment_token_<?php echo $card['payment_token'] ?>"
36
  value="<?php echo $card['payment_token'] ?>"
40
  class="radio"
41
  <?php if($card['payment_token'] == $selectedCard['payment_token']): ?>checked="checked"<?php endif; ?> />
42
  <label for="payment_token_<?php echo $card['payment_token'] ?>">
43
+ <?php echo $this->escapeHtml($curMethodName) ?><?php if (strlen($card['edit_url']) && (!isset($card['is_third_party']) || !$card['is_third_party'])): ?> <a href="<?php echo $card['edit_url'] ?>"><?php echo $this->__("(Edit)") ?></a><?php endif; ?>
44
  </label>
45
  </dt>
46
  <dd>
app/design/frontend/base/default/template/autoship/subscription/form/shipping.phtml CHANGED
@@ -152,8 +152,8 @@ $subscription = $this->getSubscription();
152
  </fieldset>
153
  </li>
154
  </ul>
 
155
  <div class="buttons-set" id="shipping-buttons-container-<?php echo $subscription->getSubscriptionId() ?>">
156
- <p class="required"><?php echo $this->__('* Required Fields') ?></p>
157
  <button type="submit" title="<?php echo $this->__('Continue') ?>" class="button">
158
  <span><span><?php echo $this->__('Continue') ?></span></span></button>
159
  </div>
152
  </fieldset>
153
  </li>
154
  </ul>
155
+ <p class="required"><?php echo $this->__('* Required Fields') ?></p>
156
  <div class="buttons-set" id="shipping-buttons-container-<?php echo $subscription->getSubscriptionId() ?>">
 
157
  <button type="submit" title="<?php echo $this->__('Continue') ?>" class="button">
158
  <span><span><?php echo $this->__('Continue') ?></span></span></button>
159
  </div>
app/design/frontend/enterprise/default/layout/autoship.xml CHANGED
@@ -251,4 +251,10 @@ Product view
251
  </reference>
252
  </checkout_onepage_index>
253
 
 
 
 
 
 
 
254
  </layout>
251
  </reference>
252
  </checkout_onepage_index>
253
 
254
+ <!-- EE Only, ensure the gift card function is not hiding subscribe pro -->
255
+ <checkout_onepage_paymentmethod>
256
+ <reference name="giftcardaccount_scripts">
257
+ <action method="setTemplate"><template>autoship/giftcardaccount/onepage/payment/scripts.phtml</template></action>
258
+ </reference>
259
+ </checkout_onepage_paymentmethod>
260
  </layout>
package.xml CHANGED
@@ -1,18 +1,18 @@
1
  <?xml version="1.0"?>
2
  <package>
3
  <name>SFC_Autoship</name>
4
- <version>1.3.1.14</version>
5
  <stability>stable</stability>
6
- <license uri="http://www.subscribepro.com/terms-of-service/">SFC Commercial Software License</license>
7
  <channel>community</channel>
8
  <extends/>
9
  <summary>Manage your auto-ship program, customer subscription payments and recurring billing transactions to optimize customer retention and recurring revenue.</summary>
10
  <description>Manage your auto-ship program, customer subscription payments and recurring billing transactions to optimize customer retention and recurring revenue. The Subscribe Pro Extension for Magento allows you to easily implement subscriptions and recurring billing on your Magento website. Our extension is fully integrated into Magento and allows you to acquire and manage subscription customers directly in the Magento admin panel.</description>
11
  <notes>Subscribe Pro Extension Release</notes>
12
  <authors><author><name>Subscribe Pro</name><user>SF_Consulting</user><email>support@subscribepro.com</email></author></authors>
13
- <date>2015-03-16</date>
14
- <time>12:57:34</time>
15
- <contents><target name="magelocal"><dir name="SFC"><dir name="Autoship"><dir name="Block"><dir name="Adminhtml"><dir name="Customer"><dir name="Paymentprofiles"><dir name="Edit"><file name="Form.php" hash="c64c65b46cc2a3d8b11c5632dc3b169c"/><dir name="Tab"><file name="Form.php" hash="808488ab5e15da6d0461b7d61f687a78"/></dir><file name="Tabs.php" hash="e6dd26321da4e4bd5ab3614ed6c21478"/></dir><file name="Edit.php" hash="bd3f2cda0476d7ce51021e065c990588"/><file name="Paymentprofile.php" hash="20962c72c68599247da372120ed532de"/></dir></dir><dir name="Sales"><dir name="Order"><dir name="Create"><file name="Jsonp.php" hash="ffe4ba6b40a53fee4a9fafe775d58858"/></dir></dir></dir><dir name="System"><dir name="Config"><dir name="Form"><file name="TestConnectionButton.php" hash="50eb2f3f1938cdda0d50ae88aece3318"/></dir></dir></dir></dir><dir name="Cart"><dir name="Product"><file name="Subscription.php" hash="7717c4a4f95b8fa453cdf9b36f0a297b"/></dir></dir><dir name="Checkout"><file name="Jsonp.php" hash="9e061e2c21f8cfab1aad9993239d5f8e"/><dir name="Onepage"><dir name="Payment"><file name="Methods.php" hash="3ca6cf9fe1eee61f520d629682870e9c"/></dir></dir></dir><dir name="Mysubscriptions"><dir name="Subscription"><dir name="Form"><file name="Billing.php" hash="b5a13e45b069412c6b3f17f5fa0b92c0"/><file name="Payment.php" hash="3b04e1aafd85089add3c88ce78687825"/><file name="Shipping.php" hash="0bf4cd339016a265dc33344158d05858"/></dir></dir><file name="Subscription.php" hash="d1e46fae138f348622b90836a77d2110"/></dir><file name="Mysubscriptions.php" hash="14430c0eaa005a77af7baaab6611303f"/><dir name="Newsubscription"><dir name="Form"><file name="Billing.php" hash="5f6215847e07dcf70a72804b4e8d351c"/><file name="Payment.php" hash="dac0b8db0bd401f2a57ba81af7d0150d"/><file name="Shipping.php" hash="6fde0265466e927309a9085239c5f817"/></dir></dir><file name="Newsubscription.php" hash="6377f729e6df8c5485b32e042a2abb5c"/><dir name="Payment"><dir name="Form"><dir name="Cc"><file name="Saved.php" hash="316e6954dfabbc6d141cf16c49459cc6"/></dir><file name="Cc.php" hash="6ab5676c3419b474efb9723a5712cea2"/></dir><dir name="Info"><file name="Cc.php" hash="69d3cb6b421e60534797ddde9335d542"/></dir><dir name="Profile"><file name="Edit.php" hash="edd5ed6b9b8b3435406e4fbeb37fd0ae"/><file name="Grid.php" hash="5da491d7db12b5ccbe7a3bbcee33d057"/></dir></dir><dir name="Product"><file name="Subscribe.php" hash="19c516250680f6fe59e5e04270c02a6a"/><dir name="View"><dir name="Type"><dir name="Grouped"><file name="Subscribe.php" hash="8a2d2308b3f762a2b2921a6d19a413ab"/></dir></dir></dir><file name="View.php" hash="8e1a840a51f260ada0a2910abd425d70"/></dir><dir name="Subscription"><file name="Abstract.php" hash="1dc9227bf03ea0475da81e51965d6188"/><dir name="Form"><file name="Address.php" hash="644c0f94434001f8bd228ed0d80bfff9"/><file name="Payment.php" hash="48e9ab07da4c18d5322a839217a42d2f"/></dir></dir></dir><dir name="Helper"><file name="Adminorder.php" hash="5517124d31b890466cb4d97f04e1c2ce"/><file name="Api.php" hash="9e99b7fc579075b1701c2d99e6223ec1"/><file name="Data.php" hash="d13d83754c73ce649d4d069218a0e5a8"/><file name="Payment.php" hash="1ba8a44a7b2b9d73e3a6e306aac73f6c"/><dir name="PaymentError"><file name="Exception.php" hash="2e180a089c0b515541e5cb474d09287d"/></dir><file name="PaymentError.php" hash="4c41a5364947465f9aa49068dbb7914a"/><file name="Platform.php" hash="8dd3d61e2eedc80e76d25db2d57ec315"/><file name="Product.php" hash="6938f12f5819c8657b9fcc799fabd092"/><file name="Quote.php" hash="6d6659c4f88be2531e933d843b50a67b"/><file name="Schedule.php" hash="3e0deaad918d79faaf680f2bed5747a3"/><file name="Subscription.php" hash="584657fecca929b441cd7ba00207ed60"/><file name="Vault.php" hash="aa84e073ffd3d41894f3ec81cc61e579"/></dir><dir name="Model"><dir name="Checkout"><dir name="Cart"><file name="Api.php" hash="f9795a0c99c2280ab221966829b71fa4"/><dir name="Payment"><file name="Api.php" hash="acafac3a776ae2005c41cb0f2ca20d08"/></dir><dir name="Product"><file name="Api.php" hash="9a79b630a2775740abbf2e633fbae8f7"/></dir></dir></dir><dir name="Mysql4"><dir name="Subscription"><file name="Collection.php" hash="e566798b4e8e7326709653ff538b8ee7"/></dir><file name="Subscription.php" hash="65e44a52dd1d6aff8b6acd2675f07ec0"/></dir><file name="Observer.php" hash="b1f4414bf08bffde8e72f052f41bd39a"/><dir name="Payment"><file name="Method.php" hash="262483defd5f7d237d2a700c6d0176e0"/><dir name="Profile"><file name="Address.php" hash="e912f0fdc9708b6b0811f0f85ffe7074"/><file name="Collection.php" hash="b0a5b730b83d5f36eaf29e3a98a99451"/></dir><file name="Profile.php" hash="b7ee1d8e70c2d2f917c8c180837ce3e1"/></dir><dir name="Paypal"><file name="Express.php" hash="eaa56b097a3123966c4a79efb9c9d802"/></dir><dir name="Platform"><file name="Product.php" hash="f7a56c3d4ddef27f9b60509d045295b0"/></dir><dir name="Quote"><file name="Address.php" hash="d00635f5ace4229a8f05417d45c9dad7"/></dir><dir name="SalesRule"><dir name="Rule"><dir name="Condition"><file name="Product.php" hash="d02ad2a5f3048a2e032154a093e568a4"/></dir></dir><file name="Validator.php" hash="6339bb28a3605b724cf3f4b35c0fd471"/></dir><file name="Subscription.php" hash="398ff49ffa9db6b2f10c4eaa150f0f47"/><dir name="System"><dir name="Config"><dir name="Source"><file name="Cartrulediscountcombinetype.php" hash="9cb608bce8527a96c84013b93eec08e9"/><file name="Cctype.php" hash="d6a6e9850f528b87a3195d857a101f88"/><file name="Month.php" hash="4e4a684bea68d309ffab906eb48be98b"/><file name="Nextorderdatemode.php" hash="0150cb3b0a67d81ccaf25e8c59aab91e"/><file name="Shippingmethods.php" hash="3db5dc237d86fdca4a81521aec0685d0"/><file name="Year.php" hash="f33a16ad0a463c89e260570b55bec4b5"/></dir></dir></dir></dir><dir name="controllers"><dir name="Adminhtml"><file name="PaymentprofileController.php" hash="7e91286582d52b2d1f2cd9cc7fb8512a"/><file name="TestconnectionbuttonController.php" hash="03825956ea5572502d0b7a55b89364a2"/></dir><file name="MycreditcardsController.php" hash="a6eb9bd3f26e6a3307fe68880e587eee"/><file name="MysubscriptionsController.php" hash="2f33c17252abc1f67397c0d5295ac6e9"/><file name="NewsubscriptionController.php" hash="7c086583a232d25005715bc3dc98bae9"/></dir><dir name="etc"><file name="adminhtml.xml" hash="c3d897eeddef7b2f04c8d35888b44f2a"/><file name="config.xml" hash="facbee8bf371decf9f3dc7545b641933"/><file name="system.xml" hash="dc040748842b21f3a283d82a223d0c8c"/></dir><dir name="sql"><dir name="sfc_autoship_setup"><file name="mysql4-install-1.3.1.8.php" hash="2b48c8075b4888b04251c98bb78ec002"/><file name="mysql4-uninstall-1.3.1.4.php" hash="1e00347d1040b76a65f34158bcc17874"/><file name="mysql4-upgrade-1.1.0-1.1.1.php" hash="975d72d3c954cd635e9ed71852eb604c"/><file name="mysql4-upgrade-1.1.2-1.2.0.php" hash="2a9f3c6d8043a7fd230fea8bb6e14f47"/><file name="mysql4-upgrade-1.2.2.1-1.2.2.2.php" hash="f1332f7a473196b790fb6a15b60801cd"/><file name="mysql4-upgrade-1.2.3-1.2.4.php" hash="86ab8f0f0ea4830dcc0c6f20cbece8b7"/><file name="mysql4-upgrade-1.2.4.6-1.2.4.7.php" hash="5ad183dfc8a53b84650e27701b296716"/><file name="mysql4-upgrade-1.3.0.1-1.3.0.2.php" hash="457a5611a2f927a376dfed3a3d5e40be"/><file name="mysql4-upgrade-1.3.0.5-1.3.1.0.php" hash="d21a249dd1986a61bd8198fe3dd9545d"/><file name="mysql4-upgrade-1.3.1.3-1.3.1.4.php" hash="a55cc5b8b023cb2f9fae602c7a087421"/><file name="mysql4-upgrade-1.3.1.4-1.3.1.5.php" hash="bd54231d4bff0371503799f1012926f9"/><file name="mysql4-upgrade-1.3.1.7-1.3.1.8.php" hash="d89e730e526d2667d7d18b3b1cb6ca5a"/></dir></dir></dir></dir></target><target name="mageetc"><dir name="modules"><file name="SFC_Autoship.xml" hash="35cd3f244a2b3249057c4c1790538f35"/></dir></target><target name="magedesign"><dir name="frontend"><dir name="base"><dir name="default"><dir name="layout"><file name="autoship.xml" hash="1a90fee16782ba0cd90fc7afbfaa0823"/></dir><dir name="template"><dir name="autoship"><dir name="cart"><dir name="product"><file name="subscription.phtml" hash="af3ccb36effdaf3915724fc37bf21f1e"/></dir></dir><dir name="checkout"><file name="jsonp.phtml" hash="4b4b0bcb1383e6a19079d8ed7b3e5461"/><file name="serversideapi.phtml" hash="ee841b58e10d5bad42f11086df8f1c21"/><file name="success.phtml" hash="3dcb75efb73cc6c60016489517e6e6bb"/></dir><dir name="mysubscriptions"><dir name="subscription"><file name="actions.phtml" hash="40b91f8fe968cc28bb4d3b7b8bc76806"/><file name="billing_address.phtml" hash="c73fb08c44aac3d1518f26fa91489697"/><file name="payment.phtml" hash="2ac49da7dff23c54e4bbc8d2deee48f2"/><file name="product_info.phtml" hash="d036cbd12a4e754131ca25ea17ca1bb3"/><file name="shipping_address.phtml" hash="00c06e51b6c2317113bfdffb020be80b"/><file name="subscription_info.phtml" hash="1779ef3bebcbb955779acd78d0254991"/></dir><file name="subscription.phtml" hash="fc4379c5da4ed70fae9610cbd9e971c0"/></dir><file name="mysubscriptions.phtml" hash="b91d072e75eadaa033b19922dafbb047"/><dir name="newsubscription"><file name="ajax_update.phtml" hash="6165fe63bfd32e11319fba40f23fd6cf"/><file name="billing_address.phtml" hash="2fe25de0e084f4e850a2cdaa9ab64fee"/><file name="delivery_date.phtml" hash="a937bb32c4900b9650cc903662ecc5a9"/><file name="delivery_frequency.phtml" hash="53090ce31858558232f50e052bbd7028"/><file name="payment.phtml" hash="add40caa322b065b60c18a0754280b64"/><file name="product_info.phtml" hash="46b2419447f9ec7cc67c110f932e7f8b"/><file name="shipping_address.phtml" hash="4df7ce0979941cb358f479096f2598cb"/><file name="summary.phtml" hash="14e00d67a4e97df262a9c676eb699602"/></dir><file name="newsubscription.phtml" hash="9c81b0c8b8cc205bb33b83ba774c2bd2"/><dir name="payment"><dir name="form"><file name="cc.phtml" hash="51f946cc57fa877385d6792fa023407f"/><file name="cc_saved.phtml" hash="fa85460bc2bef4e00760cfeb52cf8386"/></dir><dir name="profile"><file name="edit.phtml" hash="e539648eaa66efe56ea5ef8fc1f74e92"/><file name="grid.phtml" hash="d77360eeb0c769d09a58deebbf87869f"/><file name="new.phtml" hash="0c99c60c7ff9929f104d2cfc855ad620"/></dir></dir><dir name="product"><file name="subscribe.phtml" hash="eb1d185006a9b16af96ccf99492dd0b6"/><dir name="view"><file name="addtocart.phtml" hash="90cc1bc0fabf84eafd7ee948710139e1"/><dir name="type"><dir name="grouped"><file name="subscribe.phtml" hash="db5b9d3c84808e0120636c6b6d1235b3"/></dir></dir></dir></dir><dir name="subscription"><dir name="form"><file name="billing.phtml" hash="e381ce871a7fb1ee1ad685c780abf5d8"/><file name="payment.phtml" hash="e958ddd4a6dd15008c4a1d8a4d8d439d"/><file name="shipping.phtml" hash="51db842d7a7ed560a27aa1cc188ea179"/></dir></dir></dir></dir></dir></dir><dir name="enterprise"><dir name="default"><dir name="layout"><file name="autoship.xml" hash="1a90fee16782ba0cd90fc7afbfaa0823"/></dir></dir></dir></dir><dir name="adminhtml"><dir name="default"><dir name="default"><dir name="layout"><file name="autoship.xml" hash="f02dedf9c2e9de305528fcc9fc3307fc"/></dir><dir name="template"><dir name="autoship"><dir name="payment"><dir name="form"><file name="cc.phtml" hash="5c8c404c91a83252bffb40e7788323c9"/><file name="cc_saved.phtml" hash="72ef34ae9fd9be0314c8dfe351654d01"/></dir></dir><dir name="sales"><dir name="create_order"><file name="jsonp.phtml" hash="b507e2f4d74312f7f8a3ea220634f49e"/></dir></dir><dir name="system"><dir name="config"><file name="test_connection_button.phtml" hash="1ab886afca2bca69d25f543e28482fc9"/></dir></dir></dir></dir></dir></dir></dir></target><target name="mageskin"><dir name="frontend"><dir name="base"><dir name="default"><dir name="css"><file name="autoship.css" hash="960e1ea27d6dd97e44afa47563e3e84f"/></dir><dir name="images"><dir name="autoship"><file name="bkg_active-step.gif" hash="01d803ca8f4d7c7fb96c96694d233810"/><file name="bkg_block.gif" hash="df355007ee78db8a33c4e542594fe3f2"/><file name="bkg_btn-co.gif" hash="45547679e3ba34e4fd2a69750bbad05d"/><file name="bkg_thead.gif" hash="9957f9c2b564965d4d1a0ef1edcb1349"/><file name="calendar_icon.png" hash="f7073fc49641344b880a0b3218f2b261"/><file name="white_trans.png" hash="118606bdffc3e99bf15c6544cfdff1c2"/></dir></dir><dir name="js"><dir name="autoship"><file name="checkout.js" hash="cb92f1cc9bac34057843e6dcd5a38290"/><dir name="jquery"><file name="jquery-1.10.1.min.js" hash="33d85132f0154466fc017dd05111873d"/><file name="noconflict.js" hash="d8cc6cf5baad45a3ff03f75649f8ee41"/><dir name="ui"><file name="jquery.ui.core.min.js" hash="739cf68f21c10e04cde3ad13fcff9063"/><file name="jquery.ui.datepicker.min.js" hash="4eac58ed8deb3189c8d05bab9187f1ce"/><dir name="theme"><dir name="images"><file name="animated-overlay.gif" hash="2b912f7c0653008ca28ebacda49025e7"/><file name="ui-bg_flat_0_aaaaaa_40x100.png" hash="2a44fbdb7360c60122bcf6dcef0387d8"/><file name="ui-bg_flat_75_ffffff_40x100.png" hash="8692e6efddf882acbff144c38ea7dfdf"/><file name="ui-bg_glass_55_fbf9ee_1x400.png" hash="f8f4558e0b92ff2cd6136781533902ec"/><file name="ui-bg_glass_65_ffffff_1x400.png" hash="e5a8f32e28fd5c27bf0fed33c8a8b9b5"/><file name="ui-bg_glass_75_dadada_1x400.png" hash="c12c6510dad3ebfa64c8a30e959a2469"/><file name="ui-bg_glass_75_e6e6e6_1x400.png" hash="f4254356c2a8c9a383205ef2c4de22c4"/><file name="ui-bg_glass_95_fef1ec_1x400.png" hash="5a3be2d8fff8324d59aec3df7b0a0c83"/><file name="ui-bg_highlight-soft_75_cccccc_1x100.png" hash="72c593d16e998952cd8d798fee33c6f3"/><file name="ui-icons_222222_256x240.png" hash="9129e086dc488d8bcaf808510bc646ba"/><file name="ui-icons_2e83ff_256x240.png" hash="25162bf857a8eb83ea932a58436e1049"/><file name="ui-icons_454545_256x240.png" hash="771099482bdc1571ece41073b1752596"/><file name="ui-icons_888888_256x240.png" hash="faf6f5dc44e713178784c1fb053990aa"/><file name="ui-icons_cd0a0a_256x240.png" hash="5d8808d43cefca6f6781a5316d176632"/></dir><file name="jquery-ui.css" hash="dfcf2d9b984ec33bc6bb11e755ca0931"/></dir></dir></dir><file name="mysubscription.js" hash="38493104f99d9b50dccaae7267cef8d5"/><file name="newsubscription.js" hash="d89ad52dc30a5e3b50fec5d1cbc87308"/></dir></dir></dir></dir></dir><dir name="adminhtml"><dir name="default"><dir name="default"><dir name="js"><dir name="autoship"><dir name="jquery"><file name="jquery-1.10.1.min.js" hash="33d85132f0154466fc017dd05111873d"/><file name="noconflict.js" hash="d8cc6cf5baad45a3ff03f75649f8ee41"/></dir><file name="sales_create_order.js" hash="07f17495a2d1ba171d35798478fe0616"/></dir></dir></dir></dir></dir></target><target name="magelib"><dir name="OAuth2"><file name="Client.php" hash="fa9439393ed6483bd7d07af87df09b7e"/><dir name="GrantType"><file name="AuthorizationCode.php" hash="a1ff324a733fc33dbf938153c4c1667c"/><file name="ClientCredentials.php" hash="21b30fbb06d4b67263499d687316ae8b"/><file name="IGrantType.php" hash="ee03d4c5bc20f518716fc2c616b4d38d"/><file name="Password.php" hash="2e938e60c4af8bad71b5c4f0f1a40969"/><file name="RefreshToken.php" hash="a773f48348ad7aa510955099ba18d3ad"/></dir><file name="README" hash="8ef3bf723c93b6e091b707a546df2804"/></dir></target><target name="mage"><dir name="shell"><file name="autoship_prod_sync.php" hash="631910ac8ed6d0825bbd41f397934572"/></dir></target></contents>
16
  <compatible/>
17
- <dependencies><required><php><min>5.2.0</min><max>6.2.0</max></php><extension><name>ionCube Loader</name><min/><max/></extension></required></dependencies>
18
  </package>
1
  <?xml version="1.0"?>
2
  <package>
3
  <name>SFC_Autoship</name>
4
+ <version>1.3.2.6</version>
5
  <stability>stable</stability>
6
+ <license uri="http://www.subscribepro.com/terms-of-service/">Subscribe Pro Commercial Software License</license>
7
  <channel>community</channel>
8
  <extends/>
9
  <summary>Manage your auto-ship program, customer subscription payments and recurring billing transactions to optimize customer retention and recurring revenue.</summary>
10
  <description>Manage your auto-ship program, customer subscription payments and recurring billing transactions to optimize customer retention and recurring revenue. The Subscribe Pro Extension for Magento allows you to easily implement subscriptions and recurring billing on your Magento website. Our extension is fully integrated into Magento and allows you to acquire and manage subscription customers directly in the Magento admin panel.</description>
11
  <notes>Subscribe Pro Extension Release</notes>
12
  <authors><author><name>Subscribe Pro</name><user>SF_Consulting</user><email>support@subscribepro.com</email></author></authors>
13
+ <date>2015-11-06</date>
14
+ <time>16:14:13</time>
15
+ <contents><target name="magelocal"><dir name="SFC"><dir name="Autoship"><dir name="Block"><dir name="Adminhtml"><dir name="Customer"><dir name="Edit"><file name="Tabs.php" hash="324faebed3f1933a3dd46ff949257c12"/></dir><dir name="Paymentprofiles"><dir name="Edit"><file name="Form.php" hash="c64c65b46cc2a3d8b11c5632dc3b169c"/><dir name="Tab"><file name="Form.php" hash="808488ab5e15da6d0461b7d61f687a78"/></dir><file name="Tabs.php" hash="e6dd26321da4e4bd5ab3614ed6c21478"/></dir><file name="Edit.php" hash="1b816b790aef0bc0f2190b255fa38036"/><file name="Paymentprofile.php" hash="34a5aade9d3a5e7c8f2488a80842b320"/></dir></dir><dir name="Sales"><dir name="Order"><dir name="Create"><dir name="Billing"><dir name="Method"><file name="Form.php" hash="2cc22fddd456dcc5e6ff9c4ae7ff0bab"/></dir></dir><file name="Jsonp.php" hash="ffe4ba6b40a53fee4a9fafe775d58858"/><dir name="Product"><file name="Subscription.php" hash="13c3d8310779448571fba86109e2a750"/></dir></dir></dir></dir><dir name="System"><dir name="Config"><dir name="Form"><file name="TestConnectionButton.php" hash="be1efaaef2ec91e300d68d1537414863"/></dir></dir></dir></dir><dir name="Cart"><dir name="Product"><file name="Subscription.php" hash="2c63c67560ef4d4f5f512cf82af49aaf"/></dir></dir><dir name="Checkout"><file name="Jsonp.php" hash="9e061e2c21f8cfab1aad9993239d5f8e"/><dir name="Onepage"><dir name="Payment"><file name="Methods.php" hash="78d4a0061b477ba2e7ffdd97341c71f9"/></dir></dir></dir><dir name="Mysubscriptions"><dir name="Subscription"><dir name="Form"><file name="Billing.php" hash="b5a13e45b069412c6b3f17f5fa0b92c0"/><file name="Payment.php" hash="3b04e1aafd85089add3c88ce78687825"/><file name="Shipping.php" hash="0bf4cd339016a265dc33344158d05858"/></dir></dir><file name="Subscription.php" hash="c79ba864e41331a7508b99742c1a8ca1"/></dir><file name="Mysubscriptions.php" hash="14430c0eaa005a77af7baaab6611303f"/><dir name="Newsubscription"><dir name="Form"><file name="Billing.php" hash="5f6215847e07dcf70a72804b4e8d351c"/><file name="Payment.php" hash="dac0b8db0bd401f2a57ba81af7d0150d"/><file name="Shipping.php" hash="6fde0265466e927309a9085239c5f817"/></dir></dir><file name="Newsubscription.php" hash="6377f729e6df8c5485b32e042a2abb5c"/><dir name="Payment"><dir name="Form"><dir name="Cc"><file name="Saved.php" hash="99d9ec0ef623087958a4ed28fea79fcf"/></dir><file name="Cc.php" hash="0a2866b79a4daf1da35d5678b90b2891"/></dir><dir name="Info"><file name="Cc.php" hash="69d3cb6b421e60534797ddde9335d542"/></dir><dir name="Profile"><file name="Edit.php" hash="f0d71e58c22056e5e6f9ab59602ea37e"/><file name="Grid.php" hash="5da491d7db12b5ccbe7a3bbcee33d057"/></dir></dir><dir name="Product"><file name="Subscribe.php" hash="7c1c31a83888ff3598347e1dfcf7e2ce"/><dir name="View"><dir name="Type"><dir name="Grouped"><file name="Subscribe.php" hash="8a2d2308b3f762a2b2921a6d19a413ab"/></dir></dir></dir><file name="View.php" hash="8d1ead602bc46f38cf20de6e75cda7e2"/></dir><dir name="Subscription"><file name="Abstract.php" hash="ed4cd4c14c6acc43eafd265188b080b1"/><dir name="Form"><file name="Address.php" hash="644c0f94434001f8bd228ed0d80bfff9"/><file name="Payment.php" hash="ad817a1ca4eb7a7d96eb095b77fe8843"/></dir></dir></dir><dir name="Helper"><file name="Adminorder.php" hash="db2c3e8e518efd447c79823d7bbfa177"/><file name="Api.php" hash="0fea4f2c707bc990393e57c66290aa5f"/><file name="Data.php" hash="d13d83754c73ce649d4d069218a0e5a8"/><file name="Payment.php" hash="1f950fa0a89f826944466b8448cc850c"/><dir name="PaymentError"><file name="Exception.php" hash="2e180a089c0b515541e5cb474d09287d"/></dir><file name="PaymentError.php" hash="d34ccca09d2fb290205e78c80b665056"/><file name="Platform.php" hash="5a54a9260fa7efce4f067c36896374f8"/><file name="Product.php" hash="f691000a9cdcdf10e170251543bfe792"/><file name="Quote.php" hash="ac16c8f86a594ab5560ee481052bf8cc"/><file name="Schedule.php" hash="ea730420e600385df3c4308f0436f207"/><file name="Subscription.php" hash="cd6b9d8bb2b798ba245ea7813cfea834"/><file name="Vault.php" hash="b560032231392d70bb4bb015bd7a8203"/></dir><dir name="Model"><dir name="Api"><dir name="Cart"><file name="Api.php" hash="c10f821ab839d2d95965046fbffbc127"/></dir></dir><dir name="Checkout"><dir name="Cart"><file name="Api.php" hash="49f30c4ec5c2fc18ac33d40f6be12a41"/><dir name="Product"><file name="Api.php" hash="53552e01afe3b52b6808ab2792f40f2f"/></dir></dir></dir><dir name="Mysql4"><dir name="Subscription"><file name="Collection.php" hash="e566798b4e8e7326709653ff538b8ee7"/></dir><file name="Subscription.php" hash="65e44a52dd1d6aff8b6acd2675f07ec0"/></dir><file name="Observer.php" hash="18c663c2d621d3d6285590a02207c78d"/><dir name="Payment"><file name="Method.php" hash="309f76767974006b2539721cf169c0b2"/><dir name="Profile"><file name="Address.php" hash="916aefe0ad78e4280445d52245c78e73"/><file name="Collection.php" hash="94c6a7079d179f065f8a1f1c450bf20a"/></dir><file name="Profile.php" hash="ee74c488d2acf4bee5b1a474286ab182"/></dir><dir name="Paypal"><file name="Express.php" hash="74e9dae334a36a7742d8f7bcd617c995"/></dir><dir name="Platform"><file name="Product.php" hash="4b5ee034dbdb3c247640902db6a8fd9f"/></dir><dir name="Quote"><file name="Address.php" hash="ff29d531b5cbc80550a8e4652e44d19e"/></dir><dir name="Sales"><dir name="Quote"><file name="Item.php" hash="f4ecd49673b9a8f586977aaf3002158e"/></dir></dir><dir name="SalesRule"><dir name="Rule"><dir name="Condition"><file name="Product.php" hash="e1a2c3e996108b470d1b43cd165b6709"/></dir></dir><file name="Validator.php" hash="d6fd6a6d6b1eac7d286e25f31ceb0a13"/></dir><file name="Subscription.php" hash="666e1faf4a125e591cc67965c8e8fbb3"/><dir name="System"><dir name="Config"><dir name="Source"><file name="Cartrulediscountcombinetype.php" hash="9cb608bce8527a96c84013b93eec08e9"/><file name="Cctype.php" hash="d6a6e9850f528b87a3195d857a101f88"/><file name="Month.php" hash="4e4a684bea68d309ffab906eb48be98b"/><file name="Nextorderdatemode.php" hash="0150cb3b0a67d81ccaf25e8c59aab91e"/><file name="Shippingmethods.php" hash="3db5dc237d86fdca4a81521aec0685d0"/><file name="Year.php" hash="f33a16ad0a463c89e260570b55bec4b5"/></dir></dir></dir></dir><dir name="controllers"><dir name="Adminhtml"><file name="SppaymentprofileController.php" hash="e0c8d3419d7a4ae4692062fcca83e8ec"/><file name="SptestconnectionbuttonController.php" hash="fecdd079e1f89acf5d3a2e135d284c85"/></dir><file name="MycreditcardsController.php" hash="f9ea234e349ff859b781143b0bb0e48c"/><file name="MysubscriptionsController.php" hash="342edd6fcfdc93ed6e323123d153ad43"/><file name="NewsubscriptionController.php" hash="62f58c7dd06044a80cca1ff0c0b96e65"/></dir><dir name="etc"><file name="adminhtml.xml" hash="24fb76c426527354a34ec6c9be73c80b"/><file name="api.xml" hash="92dcea5b6884b1dc952b8f719409948d"/><file name="config.xml" hash="2de0963291a226f2328c7def72aa7d95"/><file name="system.xml" hash="cfd18e496c19dcbe16daed14d59c355d"/></dir><dir name="sql"><dir name="sfc_autoship_setup"><file name="mysql4-install-1.3.1.8.php" hash="4a93b674b9b7dcfdaa955878e09e3fc7"/><file name="mysql4-uninstall-1.3.1.4.php" hash="1e00347d1040b76a65f34158bcc17874"/><file name="mysql4-upgrade-1.1.0-1.1.1.php" hash="975d72d3c954cd635e9ed71852eb604c"/><file name="mysql4-upgrade-1.1.2-1.2.0.php" hash="2a9f3c6d8043a7fd230fea8bb6e14f47"/><file name="mysql4-upgrade-1.2.2.1-1.2.2.2.php" hash="f1332f7a473196b790fb6a15b60801cd"/><file name="mysql4-upgrade-1.2.3-1.2.4.php" hash="86ab8f0f0ea4830dcc0c6f20cbece8b7"/><file name="mysql4-upgrade-1.2.4.6-1.2.4.7.php" hash="5ad183dfc8a53b84650e27701b296716"/><file name="mysql4-upgrade-1.3.0.1-1.3.0.2.php" hash="457a5611a2f927a376dfed3a3d5e40be"/><file name="mysql4-upgrade-1.3.0.5-1.3.1.0.php" hash="d21a249dd1986a61bd8198fe3dd9545d"/><file name="mysql4-upgrade-1.3.1.15-1.3.1.16.php" hash="0b52f100fcea31b33b7035d13a44b79b"/><file name="mysql4-upgrade-1.3.1.3-1.3.1.4.php" hash="669964df8638c3cd42bc39849604614f"/><file name="mysql4-upgrade-1.3.1.4-1.3.1.5.php" hash="bd54231d4bff0371503799f1012926f9"/><file name="mysql4-upgrade-1.3.1.7-1.3.1.8.php" hash="d89e730e526d2667d7d18b3b1cb6ca5a"/></dir></dir></dir></dir></target><target name="mageetc"><dir name="modules"><file name="SFC_Autoship.xml" hash="35cd3f244a2b3249057c4c1790538f35"/></dir></target><target name="magedesign"><dir name="frontend"><dir name="base"><dir name="default"><dir name="layout"><file name="autoship.xml" hash="b4f25c12857e5cd066167d492d2f9d49"/></dir><dir name="template"><dir name="autoship"><dir name="cart"><dir name="product"><file name="subscription.phtml" hash="f1f3457613fb0f03eaf677f1564af3d9"/></dir></dir><dir name="checkout"><file name="jsonp.phtml" hash="4b4b0bcb1383e6a19079d8ed7b3e5461"/><file name="serversideapi.phtml" hash="ee841b58e10d5bad42f11086df8f1c21"/><file name="success.phtml" hash="d4fdb9ec6e72752f356c98efb889d7da"/></dir><dir name="giftcardaccount"><dir name="onepage"><dir name="payment"><file name="scripts.phtml" hash="2236cb498a9f60c401ce05300397d653"/></dir></dir></dir><dir name="mysubscriptions"><dir name="subscription"><file name="actions.phtml" hash="bde0af6567a53c286769bb248fe161fe"/><file name="billing_address.phtml" hash="ea40cacd90e77d712f3aa635b7f3da0f"/><file name="payment.phtml" hash="77e5644fee717246fa9554a6764d1b56"/><file name="product_info.phtml" hash="ad10c223fbd31fbb90144f501feb9f00"/><file name="shipping_address.phtml" hash="679153e1e6d60a04146f8fa6337c9198"/><file name="subscription_info.phtml" hash="b5333a7583c4b84da2414d560e9ad02a"/></dir><file name="subscription.phtml" hash="fc4379c5da4ed70fae9610cbd9e971c0"/></dir><file name="mysubscriptions.phtml" hash="b480674c647155f170a890f3ab1d3fcf"/><dir name="newsubscription"><file name="ajax_update.phtml" hash="6165fe63bfd32e11319fba40f23fd6cf"/><file name="billing_address.phtml" hash="3902047a5904e7cf6d3a33085a898ddd"/><file name="delivery_date.phtml" hash="a937bb32c4900b9650cc903662ecc5a9"/><file name="delivery_frequency.phtml" hash="318a1a5987a3fb1e397a8f53df3e8936"/><file name="payment.phtml" hash="e87e497b5451a2ee7745728f1ba5c154"/><file name="product_info.phtml" hash="46b2419447f9ec7cc67c110f932e7f8b"/><file name="shipping_address.phtml" hash="7a087557d24e0d79d0291d622a7e9c6b"/><file name="summary.phtml" hash="860a8f068f5c721b56d95db0e689429a"/></dir><file name="newsubscription.phtml" hash="25d7bf862ef9746fe2dd4c9bcea2d744"/><dir name="payment"><dir name="form"><file name="cc.phtml" hash="51f946cc57fa877385d6792fa023407f"/><file name="cc_saved.phtml" hash="e63b2a0188c8eeae918e1ef38afe0da5"/></dir><dir name="profile"><file name="edit.phtml" hash="f5704ec37e6908711d7393b544b0d3e8"/><file name="grid.phtml" hash="963f14a165181036d77a2e814a003838"/><file name="new.phtml" hash="ae585d2c2f0beac4bdc6068221e1310c"/></dir></dir><dir name="product"><file name="subscribe.phtml" hash="7c40d18f160351a3e02eb60a85679197"/><dir name="view"><file name="addtocart.phtml" hash="90cc1bc0fabf84eafd7ee948710139e1"/><dir name="type"><dir name="grouped"><file name="subscribe.phtml" hash="475e9feb164d640109fd053e2c98a92e"/></dir></dir></dir></dir><dir name="subscription"><dir name="form"><file name="billing.phtml" hash="e381ce871a7fb1ee1ad685c780abf5d8"/><file name="payment.phtml" hash="7bff7ba34f6f7747951bc3c217a79209"/><file name="shipping.phtml" hash="e1e2fdaf910cf6228aa5c783e1695596"/></dir></dir></dir></dir></dir></dir><dir name="enterprise"><dir name="default"><dir name="layout"><file name="autoship.xml" hash="de3be9da9f6b76342698a61e9363c50d"/></dir></dir></dir></dir><dir name="adminhtml"><dir name="default"><dir name="default"><dir name="layout"><file name="autoship.xml" hash="f5f2d6e16e2adb4bf9a01a8cc3e4db8c"/></dir><dir name="template"><dir name="autoship"><dir name="payment"><dir name="form"><file name="cc.phtml" hash="9c8725873d2ef50748982a3677ba86b4"/><file name="cc_saved.phtml" hash="450b1184ce1968149a5be8896e95e05a"/></dir></dir><dir name="sales"><dir name="create_order"><file name="jsonp.phtml" hash="b507e2f4d74312f7f8a3ea220634f49e"/><dir name="product"><file name="subscription.phtml" hash="0f6fc9663d6846270610c529f00d7e37"/></dir></dir></dir><dir name="system"><dir name="config"><file name="test_connection_button.phtml" hash="1ab886afca2bca69d25f543e28482fc9"/></dir></dir></dir></dir></dir></dir></dir></target><target name="mageskin"><dir name="frontend"><dir name="base"><dir name="default"><dir name="css"><file name="autoship.css" hash="1f3740432347441ec94de69878a1d159"/></dir><dir name="images"><dir name="autoship"><file name="bkg_active-step.gif" hash="01d803ca8f4d7c7fb96c96694d233810"/><file name="bkg_block.gif" hash="df355007ee78db8a33c4e542594fe3f2"/><file name="bkg_btn-co.gif" hash="45547679e3ba34e4fd2a69750bbad05d"/><file name="bkg_thead.gif" hash="9957f9c2b564965d4d1a0ef1edcb1349"/><file name="calendar_icon.png" hash="f7073fc49641344b880a0b3218f2b261"/><file name="white_trans.png" hash="118606bdffc3e99bf15c6544cfdff1c2"/></dir></dir><dir name="js"><dir name="autoship"><file name="checkout.js" hash="cb92f1cc9bac34057843e6dcd5a38290"/><dir name="jquery"><file name="jquery-1.10.1.min.js" hash="33d85132f0154466fc017dd05111873d"/><file name="noconflict.js" hash="d8cc6cf5baad45a3ff03f75649f8ee41"/><dir name="ui"><file name="jquery.ui.core.min.js" hash="739cf68f21c10e04cde3ad13fcff9063"/><file name="jquery.ui.datepicker.min.js" hash="4eac58ed8deb3189c8d05bab9187f1ce"/><dir name="theme"><dir name="images"><file name="animated-overlay.gif" hash="2b912f7c0653008ca28ebacda49025e7"/><file name="ui-bg_flat_0_aaaaaa_40x100.png" hash="2a44fbdb7360c60122bcf6dcef0387d8"/><file name="ui-bg_flat_75_ffffff_40x100.png" hash="8692e6efddf882acbff144c38ea7dfdf"/><file name="ui-bg_glass_55_fbf9ee_1x400.png" hash="f8f4558e0b92ff2cd6136781533902ec"/><file name="ui-bg_glass_65_ffffff_1x400.png" hash="e5a8f32e28fd5c27bf0fed33c8a8b9b5"/><file name="ui-bg_glass_75_dadada_1x400.png" hash="c12c6510dad3ebfa64c8a30e959a2469"/><file name="ui-bg_glass_75_e6e6e6_1x400.png" hash="f4254356c2a8c9a383205ef2c4de22c4"/><file name="ui-bg_glass_95_fef1ec_1x400.png" hash="5a3be2d8fff8324d59aec3df7b0a0c83"/><file name="ui-bg_highlight-soft_75_cccccc_1x100.png" hash="72c593d16e998952cd8d798fee33c6f3"/><file name="ui-icons_222222_256x240.png" hash="9129e086dc488d8bcaf808510bc646ba"/><file name="ui-icons_2e83ff_256x240.png" hash="25162bf857a8eb83ea932a58436e1049"/><file name="ui-icons_454545_256x240.png" hash="771099482bdc1571ece41073b1752596"/><file name="ui-icons_888888_256x240.png" hash="faf6f5dc44e713178784c1fb053990aa"/><file name="ui-icons_cd0a0a_256x240.png" hash="5d8808d43cefca6f6781a5316d176632"/></dir><file name="jquery-ui.css" hash="dfcf2d9b984ec33bc6bb11e755ca0931"/></dir></dir></dir><file name="mysubscription.js" hash="2f1cb810774eb6d42601c579584a4d1b"/><file name="newsubscription.js" hash="12a8a54a2b47408e7268325c095aa271"/></dir></dir></dir></dir></dir><dir name="adminhtml"><dir name="default"><dir name="default"><dir name="js"><dir name="autoship"><dir name="jquery"><file name="jquery-1.10.1.min.js" hash="33d85132f0154466fc017dd05111873d"/><file name="noconflict.js" hash="d8cc6cf5baad45a3ff03f75649f8ee41"/></dir><file name="sales_create_order.js" hash="07f17495a2d1ba171d35798478fe0616"/></dir></dir></dir></dir></dir></target><target name="magelib"><dir name="OAuth2"><file name="Client.php" hash="fa9439393ed6483bd7d07af87df09b7e"/><dir name="GrantType"><file name="AuthorizationCode.php" hash="a1ff324a733fc33dbf938153c4c1667c"/><file name="ClientCredentials.php" hash="21b30fbb06d4b67263499d687316ae8b"/><file name="IGrantType.php" hash="ee03d4c5bc20f518716fc2c616b4d38d"/><file name="Password.php" hash="2e938e60c4af8bad71b5c4f0f1a40969"/><file name="RefreshToken.php" hash="a773f48348ad7aa510955099ba18d3ad"/></dir><file name="README" hash="8ef3bf723c93b6e091b707a546df2804"/></dir></target><target name="mage"><dir name="shell"><file name="autoship_prod_sync.php" hash="631910ac8ed6d0825bbd41f397934572"/><file name="autoship_report_dl.php" hash="99eeb37784720ef5bc5aed2db81da4d0"/><file name="autoship_customer_sync.php" hash="af19184a593d841fd187946952e34c79"/></dir></target></contents>
16
  <compatible/>
17
+ <dependencies><required><php><min>5.2.0</min><max>6.2.0</max></php></required></dependencies>
18
  </package>
shell/autoship_customer_sync.php ADDED
@@ -0,0 +1,75 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Subscribe Pro - Subscriptions Management Extension
4
+ *
5
+ * PHP version 5
6
+ *
7
+ * LICENSE: This source file is subject to commercial source code license of SUBSCRIBE PRO INC.
8
+ *
9
+ * @category SFC
10
+ * @package SFC_Autoship
11
+ * @author Dennis Rogers <dennis@storefrontconsulting.com>
12
+ * @author Garth Brantley <garth@subscribepro.com>
13
+ * @copyright 2009-2014 SUBSCRIBE PRO INC. All Rights Reserved.
14
+ * @license http://www.subscribepro.com/terms-of-service/ Subscribe Pro Terms of Service
15
+ * @link http://www.subscribepro.com/
16
+ *
17
+ */
18
+
19
+ define('MAGENTO_ROOT', dirname(dirname(__FILE__)));
20
+
21
+ require (MAGENTO_ROOT . '/app/Mage.php');
22
+
23
+ if (!Mage::isInstalled()) {
24
+ die("Application is not installed yet, please complete install wizard first.\n");
25
+ }
26
+
27
+ // Only for urls
28
+ // Don't remove this
29
+ $_SERVER['SCRIPT_NAME'] = str_replace(basename(__FILE__), 'index.php', $_SERVER['SCRIPT_NAME']);
30
+ $_SERVER['SCRIPT_FILENAME'] = str_replace(basename(__FILE__), 'index.php', $_SERVER['SCRIPT_FILENAME']);
31
+
32
+ Mage::app('admin')->setUseSessionInUrl(false);
33
+
34
+ umask(0);
35
+
36
+ /** @var SFC_Autoship_Helper_Platform $platformHelper */
37
+ $platformHelper = Mage::helper('autoship/platform');
38
+ /** @var SFC_Autoship_Helper_Api $apiHelper */
39
+ $apiHelper = Mage::helper('autoship/api');
40
+
41
+ eLog("Syncing all Magento customers to Subscribe Pro.");
42
+
43
+ // Get and iterate collection of all customers
44
+ $mageCustomers = Mage::getModel('customer/customer')->getCollection();
45
+ /** @var Mage_Customer_Model_Customer $customerRow */
46
+ foreach ($mageCustomers as $customerRow) {
47
+ try {
48
+ //We must load the storeId through this method
49
+ //Otherwise customers created in admin will always read the default setting for subscription enabled
50
+ $storeId = Mage::app()->getWebsite($customerRow->getWebsiteId())->getDefaultGroup()->getDefaultStoreId();
51
+ if (!Mage::getStoreConfig('autoship_general/general/enabled', $storeId) == '1') {
52
+ continue;
53
+ }
54
+ // Load the full customer model
55
+ $customer = Mage::getModel('customer/customer')->load($customerRow->getId());
56
+ // Set config store / website
57
+ $apiHelper->setConfigStore($storeId);
58
+ // Sync customer to SP
59
+ $spCustomer = $platformHelper->createOrUpdateCustomer($customer);
60
+ eLog("Processed Customer ID {$customer->getId()}");
61
+ }
62
+ catch (Exception $e) {
63
+ eLog("Failed to process Customer ({$customer->getId()}) with error: " . $e->getMessage());
64
+ }
65
+ }
66
+
67
+ function eLog($message)
68
+ {
69
+ if (is_string($message)) {
70
+ echo $message . "\n";
71
+ }
72
+ else {
73
+ print_r($message);
74
+ }
75
+ }
shell/autoship_report_dl.php ADDED
@@ -0,0 +1,99 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Subscribe Pro - Subscriptions Management Extension
4
+ *
5
+ * PHP version 5
6
+ *
7
+ * LICENSE: This source file is subject to commercial source code license of SUBSCRIBE PRO INC.
8
+ *
9
+ * @category SFC
10
+ * @package SFC_Autoship
11
+ * @author Dennis Rogers <dennis@storefrontconsulting.com>
12
+ * @author Garth Brantley <garth@subscribepro.com>
13
+ * @copyright 2009-2014 SUBSCRIBE PRO INC. All Rights Reserved.
14
+ * @license http://www.subscribepro.com/terms-of-service/ Subscribe Pro Terms of Service
15
+ * @link http://www.subscribepro.com/
16
+ *
17
+ */
18
+
19
+ define('MAGENTO_ROOT', dirname(dirname(__FILE__)));
20
+
21
+ require (MAGENTO_ROOT . '/app/Mage.php');
22
+
23
+ if (!Mage::isInstalled()) {
24
+ die("Application is not installed yet, please complete install wizard first.\n");
25
+ }
26
+
27
+
28
+
29
+ // Only for urls
30
+ // Don't remove this
31
+ $_SERVER['SCRIPT_NAME'] = str_replace(basename(__FILE__), 'index.php', $_SERVER['SCRIPT_NAME']);
32
+ $_SERVER['SCRIPT_FILENAME'] = str_replace(basename(__FILE__), 'index.php', $_SERVER['SCRIPT_FILENAME']);
33
+
34
+ Mage::app('admin')->setUseSessionInUrl(false);
35
+
36
+ umask(0);
37
+
38
+ $valid_codes = array('daily_subscriptions',
39
+ 'complete_subscriptions',
40
+ 'subscription_history',
41
+ 'expired_credit_card',
42
+ 'customer_activity',
43
+ 'failed_subscriptions',
44
+ 'subscription_order_history',
45
+ 'complete_sales_orders',
46
+ 'complete_transaction',
47
+ 'products'
48
+ );
49
+
50
+ $args = getopt("", array("code:"));
51
+
52
+ if (!sizeof($args) || !isset($args['code'])) {
53
+ eLog("No code provided, please provide a valid report code, code options are:");
54
+ eLog($valid_codes);
55
+ exit;
56
+ }
57
+
58
+ $code = $args['code'];
59
+
60
+ if (!in_array($code, $valid_codes)) {
61
+ eLog("Invalid code provided, code options are:");
62
+ eLog($valid_codes);
63
+ exit;
64
+ }
65
+
66
+ $report_dir = MAGENTO_ROOT . '/var/autoship_report_archive/' . $code;
67
+
68
+ if (!file_exists(($report_dir))) {
69
+ //0775 in case apache/php is running as a different user in same group
70
+ mkdir($report_dir, 0775, true);
71
+ }
72
+
73
+ $file_name = $report_dir . '/' . $code . '_' . date("Y-m-d_H:i:s") . '.csv';
74
+
75
+ if (!is_writeable($report_dir)) {
76
+ eLog("Unable to write to report archive: " . $file_name);
77
+ exit;
78
+ }
79
+
80
+ /** @var SFC_Autoship_Helper_Platform $platformHelper */
81
+ $platformHelper = Mage::helper('autoship/platform');
82
+
83
+ $report = $platformHelper->getReport($code);
84
+
85
+ file_put_contents($file_name, $report);
86
+
87
+ eLog("Success!");
88
+ eLog("Downloaded report to: " . $file_name);
89
+
90
+
91
+ function eLog($message)
92
+ {
93
+ if (is_string($message)) {
94
+ echo $message . "\n";
95
+ }
96
+ else {
97
+ print_r($message);
98
+ }
99
+ }
skin/frontend/base/default/css/autoship.css CHANGED
@@ -102,7 +102,7 @@
102
  margin: 0 !important;
103
  }
104
 
105
- .subscription div.change { padding: 20px; background-color: #ffffff; }
106
 
107
 
108
  /* My Subscriptions page */
@@ -110,38 +110,52 @@
110
  #all-subscriptions-details .delivery_date { margin: 2px 0 12px -6px; border: none; padding: 0; background: none; font-size: 22px; font-weight: bold; text-align: center; width: 96px; }
111
  #all-subscriptions-details .input-box .ui-datepicker-trigger { margin-top: 6px; cursor: pointer; }
112
 
 
113
  .active-subscriptions-links { padding-bottom: 18px; }
114
 
115
  .subscription-block:first-child { margin-top: 0px; border-top: none; padding-top: 0px; }
116
- .subscription-block { margin-top: 18px; border-bottom: 1px solid #cfcfcf; padding-bottom: 18px; }
117
  .subscription-block p, .subscription-block h2 { padding-bottom: 6px; }
118
 
119
- .subscription-info { float: left; width: 200px; padding-right: 10px; }
120
- .subscription-product { float: left; width: 340px; padding-right: 10px; }
121
- .subscription-actions { float: right; width: 144px; }
122
  .subscription-more-details { padding-top: 10px; }
123
  .subscription-shipping-address { float: left; padding-right: 40px; }
124
  .subscription-billing-address { float: left; padding-right: 40px; }
125
  .subscription-payment { float: left; padding-right: 40px; }
126
 
 
 
 
 
 
 
 
 
 
 
127
  .subscription-info .next-order-date { font-size: 22px; }
128
  .subscription-actions .status { font-size: 18px; }
129
 
130
- .subscription-product .product-image img { float: left; margin-right: 12px; border: 1px solid #cfcfcf; padding: 6px; background: #ffffff; }
131
- .subscription-product .product-name a { color: #c73615; text-decoration: none; }
132
  .subscription-product .product-original-price { font-size: 11px; color: #989696; text-decoration: line-through; }
133
- .subscription-product .product-price { font-size: 14px; color: #c73615; font-weight: bold; }
134
 
135
- .subscription-actions .button { padding-bottom: 6px; }
136
  .subscription-actions .button span span { width: 116px; }
137
 
138
- .subscription-block .input-box input.delivery_date { margin: 2px 0 12px -6px; border: none; padding: 0; background: none; font-size: 22px; font-weight: bold; text-align: center; width: 96px; }
139
- .subscription-block .input-box .ui-datepicker-trigger { margin-top: 6px; cursor: pointer; }
140
 
141
- .subscription-block .change .buttons-set button.button { float: none; margin-left: 0; }
142
 
143
  /* Subscription Product page */
144
- .subscription-product .options-list li { padding-bottom: 18px; }
 
 
 
145
  .subscription-product .options-list .radio { font-size: 14px !important; }
146
  .subscription-product .options-list .radio, .subscription-product .options-list .radio-text { float: left; margin-right: 9px; }
147
  .subscription-product .options-list .price { font-weight: bold; }
@@ -204,7 +218,7 @@
204
  .new-subscription .change .new-cc-form-list input.input-text, .subscription-lightbox-background .change .new-cc-form-list textarea { width: auto; }
205
  .new-subscription .change .new-cc-form-list .input-box { float: left; }
206
 
207
- .active-subscriptions div.change {
208
  position: absolute;
209
  z-index: 999;
210
  display: none;
@@ -213,36 +227,36 @@
213
  box-shadow: 0px 5px 20px 0px #e6e6e6;
214
  background: #ffffff url(../images/autoship/bkg_block.gif) repeat-x center bottom;
215
  }
216
- .active-subscriptions .change .block-title {
217
  padding: 5px 12px;
218
  border-bottom: 1px solid #d9d9d9;
219
  background: url(../images/autoship/bkg_thead.gif) repeat-x;
220
  }
221
- .active-subscriptions .change .block-title h2 {
222
  text-transform: uppercase;
223
  font-size: 11px;
224
  padding-bottom: 0;
225
  }
226
- .active-subscriptions .change .block-content { padding: 20px; }
227
 
228
- .active-subscriptions .change .next-order-date { font-size: 22px; }
229
 
230
  .active-subscriptions .change .form-list select { width: 300px; }
231
- .active-subscriptions .change .form-list input.input-text, .subscription-lightbox-background .change .form-list textarea { width: 294px }
232
- .active-subscriptions .change .buttons-set { padding: 0 15px 0 0 }
233
- .active-subscriptions .change .form-list .input-box { float: right; margin-right: 3px; padding-right: 20px; }
234
- .active-subscriptions .change p.required { width: auto; }
235
 
236
- .active-subscriptions .change .messages { margin-top: 0; }
237
- .active-subscriptions .change label { font-size: 12px; font-weight: bold; }
238
- .active-subscriptions .change dt { padding-bottom: 6px; }
239
 
240
- .active-subscriptions .change .new-cc-form-list label { width: 160px; }
241
- .active-subscriptions .change .new-cc-form-list select { width: auto; margin-right: 4px; }
242
- .active-subscriptions .change .new-cc-form-list input.input-text, .subscription-lightbox-background .change .new-cc-form-list textarea { width: auto; }
243
- .active-subscriptions .change .new-cc-form-list .input-box { float: left; }
244
 
245
- #all-subscriptions-details div.change {
246
  position: absolute;
247
  z-index: 999;
248
  display: none;
@@ -251,34 +265,34 @@
251
  box-shadow: 0px 5px 20px 0px #e6e6e6;
252
  background: #ffffff url(../images/autoship/bkg_block.gif) repeat-x center bottom;
253
  }
254
- #all-subscriptions-details .change .block-title {
255
  padding: 5px 12px;
256
  border-bottom: 1px solid #d9d9d9;
257
  background: url(../images/autoship/bkg_thead.gif) repeat-x;
258
  }
259
- #all-subscriptions-details .change .block-title h2 {
260
  text-transform: uppercase;
261
  font-size: 11px;
262
  padding-bottom: 0;
263
  }
264
- #all-subscriptions-details .change .block-content { padding: 20px; }
265
 
266
- #all-subscriptions-details .change .next-order-date { font-size: 22px; }
267
 
268
- #all-subscriptions-details .change .form-list select { width: 300px; }
269
- #all-subscriptions-details .change .form-list input.input-text, .subscription-lightbox-background .change .form-list textarea { width: 294px }
270
- #all-subscriptions-details .change .buttons-set { padding: 0 15px 0 0 }
271
- #all-subscriptions-details .change .form-list .input-box { float: right; margin-right: 3px; padding-right: 20px; }
272
- #all-subscriptions-details .change p.required { width: auto; }
273
 
274
- #all-subscriptions-details .change .messages { margin-top: 0; }
275
- #all-subscriptions-details .change label { font-size: 12px; font-weight: bold; }
276
- #all-subscriptions-details .change dt { padding-bottom: 6px; }
277
 
278
- #all-subscriptions-details .change .new-cc-form-list label { width: 160px; }
279
- #all-subscriptions-details .change .new-cc-form-list select { width: auto; margin-right: 4px; }
280
- #all-subscriptions-details .change .new-cc-form-list input.input-text, .subscription-lightbox-background .change .new-cc-form-list textarea { width: auto; }
281
- #all-subscriptions-details .change .new-cc-form-list .input-box { float: left; }
282
 
283
  /* Cart page */
284
 
@@ -288,3 +302,5 @@
288
  .cart .subscription-product .options-list .radio, .cart .subscription-product .options-list .radio-text { line-height: 18px; }
289
  .cart .subscription-product .options-list .radio { cursor: pointer; }
290
  .cart .subscription-product .options-list p { margin: 0; }
 
 
102
  margin: 0 !important;
103
  }
104
 
105
+ .subscription div.adjust { padding: 20px; background-color: #ffffff; }
106
 
107
 
108
  /* My Subscriptions page */
110
  #all-subscriptions-details .delivery_date { margin: 2px 0 12px -6px; border: none; padding: 0; background: none; font-size: 22px; font-weight: bold; text-align: center; width: 96px; }
111
  #all-subscriptions-details .input-box .ui-datepicker-trigger { margin-top: 6px; cursor: pointer; }
112
 
113
+ #mysubscriptions .clearer {clear:both;}
114
  .active-subscriptions-links { padding-bottom: 18px; }
115
 
116
  .subscription-block:first-child { margin-top: 0px; border-top: none; padding-top: 0px; }
117
+ .subscription-block { margin-top: 18px; border-bottom: 1px solid #cfcfcf; padding-bottom: 18px; overflow: auto;}
118
  .subscription-block p, .subscription-block h2 { padding-bottom: 6px; }
119
 
120
+ .subscription-info { float: left; width: 30%; padding-right: 10px; }
121
+ .subscription-product { float: left; width: 48%; padding-right: 10px; }
122
+ .subscription-actions { float: left; width: 22%; }
123
  .subscription-more-details { padding-top: 10px; }
124
  .subscription-shipping-address { float: left; padding-right: 40px; }
125
  .subscription-billing-address { float: left; padding-right: 40px; }
126
  .subscription-payment { float: left; padding-right: 40px; }
127
 
128
+ @media only screen and (max-width: 480px) {
129
+ .subscription-info,.subscription-product,.subscription-actions {
130
+ float:none;
131
+ width:100%;
132
+ padding: 10px;
133
+ background:#eee;
134
+ overflow:auto;
135
+ }
136
+ }
137
+
138
  .subscription-info .next-order-date { font-size: 22px; }
139
  .subscription-actions .status { font-size: 18px; }
140
 
141
+ .subscription-product .product-image { float: left; margin-right: 12px; border: 1px solid #cfcfcf; padding: 6px; background: #ffffff; }
142
+ .subscription-product .product-name a { color: #3399cc; text-decoration: none; }
143
  .subscription-product .product-original-price { font-size: 11px; color: #989696; text-decoration: line-through; }
144
+ .subscription-product .product-price { font-size: 14px; color: #3399cc; font-weight: bold; }
145
 
146
+ .subscription-actions .button { padding-bottom: 6px; white-space: normal; }
147
  .subscription-actions .button span span { width: 116px; }
148
 
149
+ .subscription-block .input-box input.delivery_date { margin: 2px 0 12px -6px; border: none; padding: 0; background: none; font-size: 22px; font-weight: bold; text-align: center; width: 105px; }
150
+ .subscription-block .input-box .ui-datepicker-trigger { margin: 5px 0 1px 6px; cursor: pointer; display: inline;}
151
 
152
+ .subscription-block .adjust .buttons-set button.button { float: none; margin-left: 0; }
153
 
154
  /* Subscription Product page */
155
+ .subscription-product.product-options { padding:0; border:none; margin: 0 0 15px;}
156
+ .subscription-product .price-notice {color: #3399cc;}
157
+ .subscription-product.product-options ul.options-list label {width:auto;}
158
+ .subscription-product .options-list li { padding-bottom: 10px; }
159
  .subscription-product .options-list .radio { font-size: 14px !important; }
160
  .subscription-product .options-list .radio, .subscription-product .options-list .radio-text { float: left; margin-right: 9px; }
161
  .subscription-product .options-list .price { font-weight: bold; }
218
  .new-subscription .change .new-cc-form-list input.input-text, .subscription-lightbox-background .change .new-cc-form-list textarea { width: auto; }
219
  .new-subscription .change .new-cc-form-list .input-box { float: left; }
220
 
221
+ .active-subscriptions div.adjust {
222
  position: absolute;
223
  z-index: 999;
224
  display: none;
227
  box-shadow: 0px 5px 20px 0px #e6e6e6;
228
  background: #ffffff url(../images/autoship/bkg_block.gif) repeat-x center bottom;
229
  }
230
+ .active-subscriptions .adjust .block-title {
231
  padding: 5px 12px;
232
  border-bottom: 1px solid #d9d9d9;
233
  background: url(../images/autoship/bkg_thead.gif) repeat-x;
234
  }
235
+ .active-subscriptions .adjust .block-title h2 {
236
  text-transform: uppercase;
237
  font-size: 11px;
238
  padding-bottom: 0;
239
  }
240
+ .active-subscriptions .adjust .block-content { padding: 20px; }
241
 
242
+ .active-subscriptions .adjust .next-order-date { font-size: 22px; }
243
 
244
  .active-subscriptions .change .form-list select { width: 300px; }
245
+ .active-subscriptions .adjust .form-list input.input-text, .subscription-lightbox-background .adjust .form-list textarea { }
246
+ .active-subscriptions .adjust .buttons-set { padding: 0 15px 0 0 }
247
+ .active-subscriptions .adjust .form-list .input-box { }
248
+ .active-subscriptions .adjust p.required { width: auto; }
249
 
250
+ .active-subscriptions .adjust .messages { margin-top: 0; }
251
+ .active-subscriptions .adjust label { font-size: 12px; font-weight: bold; }
252
+ .active-subscriptions .adjust dt { padding-bottom: 6px; }
253
 
254
+ .active-subscriptions .adjust .new-cc-form-list label { width: 160px; }
255
+ .active-subscriptions .adjust .new-cc-form-list select { width: auto; margin-right: 4px; }
256
+ .active-subscriptions .adjust .new-cc-form-list input.input-text, .subscription-lightbox-background .adjust .new-cc-form-list textarea { width: auto; }
257
+ .active-subscriptions .adjust .new-cc-form-list .input-box { float: left; }
258
 
259
+ #all-subscriptions-details div.adjust {
260
  position: absolute;
261
  z-index: 999;
262
  display: none;
265
  box-shadow: 0px 5px 20px 0px #e6e6e6;
266
  background: #ffffff url(../images/autoship/bkg_block.gif) repeat-x center bottom;
267
  }
268
+ #all-subscriptions-details .adjust .block-title {
269
  padding: 5px 12px;
270
  border-bottom: 1px solid #d9d9d9;
271
  background: url(../images/autoship/bkg_thead.gif) repeat-x;
272
  }
273
+ #all-subscriptions-details .adjust .block-title h2 {
274
  text-transform: uppercase;
275
  font-size: 11px;
276
  padding-bottom: 0;
277
  }
278
+ #all-subscriptions-details .adjust .block-content { padding: 20px; }
279
 
280
+ #all-subscriptions-details .adjust .next-order-date { font-size: 22px; }
281
 
282
+ #all-subscriptions-details .adjust .form-list select { width: 300px; }
283
+ #all-subscriptions-details .adjust .form-list input.input-text, .subscription-lightbox-background .adjust .form-list textarea { width: 294px }
284
+ #all-subscriptions-details .adjust .buttons-set { padding: 0 15px 0 0 }
285
+ #all-subscriptions-details .adjust .form-list .input-box { float: right; margin-right: 3px; padding-right: 20px; }
286
+ #all-subscriptions-details .adjust p.required { width: auto; }
287
 
288
+ #all-subscriptions-details .adjust .messages { margin-top: 0; }
289
+ #all-subscriptions-details .adjust label { font-size: 12px; font-weight: bold; }
290
+ #all-subscriptions-details .adjust dt { padding-bottom: 6px; }
291
 
292
+ #all-subscriptions-details .adjust .new-cc-form-list label { width: 160px; }
293
+ #all-subscriptions-details .adjust .new-cc-form-list select { width: auto; margin-right: 4px; }
294
+ #all-subscriptions-details .adjust .new-cc-form-list input.input-text, .subscription-lightbox-background .adjust .new-cc-form-list textarea { width: auto; }
295
+ #all-subscriptions-details .adjust .new-cc-form-list .input-box { float: left; }
296
 
297
  /* Cart page */
298
 
302
  .cart .subscription-product .options-list .radio, .cart .subscription-product .options-list .radio-text { line-height: 18px; }
303
  .cart .subscription-product .options-list .radio { cursor: pointer; }
304
  .cart .subscription-product .options-list p { margin: 0; }
305
+ .cart .subscription-product .options-list label { background-color: transparent; }
306
+ .cart .subscription-product .options-list { background-color: #f4f4f4; }
skin/frontend/base/default/js/autoship/mysubscription.js CHANGED
@@ -16,69 +16,51 @@
16
  */
17
 
18
  function updateMySubscription(form) {
19
- $j("div.change,#modal_overlay").hide();
20
- $j("#please-wait").show();
21
- $j(".subscription-block .messages").html("");
22
- $j.ajax({
23
- url: form.attr('action'),
24
- data: form.serialize(),
25
- method: "post",
26
- success: function(transport){
27
- $j("#please-wait").hide();
28
- if(transport.match("error")){
29
- form.parents(".subscription-block").find(".messages").html(transport);
30
- } else {
31
- form.parents(".subscription-block").html(transport).highlight();
32
- }
33
  }
34
  });
35
  }
36
 
37
  function updateAllSubscriptions(form) {
38
- $j("div.change,#modal_overlay").hide();
39
- $j("#please-wait").show();
40
- $j(".subscription-block .messages").html("");
41
- $j.ajax({
42
- url: form.attr('action'),
43
- data: form.serialize(),
44
- method: "post",
45
- success: function(transport){
46
- $j("#please-wait").hide();
47
- if(transport.match("error")){
48
- form.parents(".my-account").find(".messages").html(transport);
49
- } else {
50
- form.parents(".my-account").html(transport).highlight();
51
- }
52
  }
53
  });
54
  }
55
 
56
- $j(document).ready(function(){
57
 
58
- $j(".wrapper").after("<div id='modal_overlay'></div>");
59
- $j('#modal_overlay').css({
60
  position: "absolute",
61
  top: 0,
62
  left: 0,
63
- height: $j(document).height(),
64
  width: "100%",
65
  zIndex: 900
66
  }).bind('click', function(){
67
- $j('div.change').hide();
68
- $j(this).hide();
69
  }).hide();
70
 
71
- $j(".my-account").on('click', "a.change", function(e){
72
- e.preventDefault();
73
- var box = $j(this).parents(".block").find("div.change");
74
- box.css({
75
- "top": $j(window).scrollTop() + 50,
76
- "left": ($j(window).width() / 2) - (box.width() / 2)
77
- }).show();
78
- $j('#modal_overlay').show();
79
- }).on('submit', 'form.payment-form', function(e){
80
  e.preventDefault();
81
- var form = $j(this);
82
  if(editMultipleSubscriptions == true) {
83
  updateAllSubscriptions(form);
84
  }
@@ -86,14 +68,14 @@ $j(document).ready(function(){
86
  updateMySubscription(form);
87
  }
88
  }).on('change', '.shipping-address-select', function(){
89
- if($j(this).val() == ""){
90
- $j(this).closest('.co-shipping-form').find('.shipping-new-address-form').show();
91
  } else {
92
- $j(this).closest('.co-shipping-form').find('.shipping-new-address-form').hide();
93
  }
94
  }).on('submit', 'form.co-shipping-form', function(e){
95
  e.preventDefault();
96
- var form = $j(this);
97
  if(editMultipleSubscriptions == true) {
98
  updateAllSubscriptions(form);
99
  }
@@ -101,14 +83,14 @@ $j(document).ready(function(){
101
  updateMySubscription(form);
102
  }
103
  }).on('change', '.billing-address-select', function(){
104
- if($j(this).val() == ""){
105
- $j(this).closest('.co-billing-form').find('.billing-new-address-form').show();
106
  } else {
107
- $j(this).closest('.co-billing-form').find('.billing-new-address-form').hide();
108
  }
109
  }).on('submit', 'form.co-billing-form', function(e){
110
  e.preventDefault();
111
- var form = $j(this);
112
  if(editMultipleSubscriptions == true) {
113
  updateAllSubscriptions(form);
114
  }
@@ -117,53 +99,53 @@ $j(document).ready(function(){
117
  }
118
  }).on("click", "a.link.more.details", function(e){
119
  e.preventDefault();
120
- var link = $j(this);
121
- $j('#'+link.attr('href')).toggle();
122
  }).on("change", "select.delivery_qty", function(e){
123
  e.preventDefault();
124
- var form = $j(this).closest("form");
125
  updateMySubscription(form);
126
  }).on("change", "select.delivery_interval", function(e){
127
  e.preventDefault();
128
- var form = $j(this).closest("form");
129
  updateMySubscription(form);
130
- }).on("click", "button.change.skip", function(e){
131
  e.preventDefault();
132
- var box = $j(this).parents(".subscription-block").find("div.change.skip-delivery");
133
  box.css({
134
- "top": $j(window).scrollTop() + 50,
135
- "left": ($j(window).width() / 2) - (box.width() / 2)
136
  }).show();
137
- $j('#modal_overlay').show();
138
- }).on("click", "a.change.cancel", function(e){
139
  e.preventDefault();
140
- var box = $j(this).parents(".subscription-block").find("div.change.cancel");
141
  box.css({
142
- "top": $j(window).scrollTop() + 50,
143
- "left": ($j(window).width() / 2) - (box.width() / 2)
144
  }).show();
145
- $j('#modal_overlay').show();
146
- }).on("click", "a.change.restart", function(e){
147
  e.preventDefault();
148
- var box = $j(this).parents(".subscription-block").find("div.change.restart");
149
  box.css({
150
- "top": $j(window).scrollTop() + 50,
151
- "left": ($j(window).width() / 2) - (box.width() / 2)
152
  }).show();
153
- $j('#modal_overlay').show();
154
  }).on("click", "button.no", function(e){
155
- $j("div.change,#modal_overlay").hide();
156
  }).on("click", "button.skip_yes", function(e){
157
  e.preventDefault();
158
- var form = $j(this);
159
- $j("div.change,#modal_overlay").hide();
160
- $j("#please-wait").show();
161
- $j(".subscription-block .messages").html("");
162
- $j.ajax({
163
  url: form.attr('href'),
164
  method: "get",
165
  success: function(transport){
166
- $j("#please-wait").hide();
167
  if(transport.match("error")){
168
  form.parents(".subscription-block").find(".messages").html(transport);
169
  } else {
@@ -173,34 +155,34 @@ $j(document).ready(function(){
173
  });
174
  }).on("click", "button.cancel_yes", function(e){
175
  e.preventDefault();
176
- var form = $j(this);
177
- $j("div.change,#modal_overlay").hide();
178
- $j("#please-wait").show();
179
- $j(".subscription-block .messages").html("");
180
- $j.ajax({
181
  url: form.attr('href'),
182
  method: "get",
183
  success: function(transport){
184
- $j("#please-wait").hide();
185
  if(transport.match("error")){
186
  form.parents(".subscription-block").find(".messages").html(transport);
187
  } else {
188
  form.parents(".subscription-block").fadeOut(1000);
189
- $j(".inactive-subscriptions").prepend('<div class="subscription-block">' + transport + '</div>');
190
  }
191
  }
192
  });
193
  }).on("click", "button.restart_yes", function(e){
194
  e.preventDefault();
195
- var form = $j(this);
196
- $j("div.change,#modal_overlay").hide();
197
- $j("#please-wait").show();
198
- $j(".subscription-block .messages").html("");
199
- $j.ajax({
200
  url: form.attr('href'),
201
  method: "get",
202
  success: function(transport){
203
- $j("#please-wait").hide();
204
  if(transport.match("error")){
205
  form.parents(".subscription-block").find(".messages").html(transport);
206
  } else {
@@ -208,6 +190,14 @@ $j(document).ready(function(){
208
  }
209
  }
210
  });
 
 
 
 
 
 
 
 
211
  });
212
 
213
  });
16
  */
17
 
18
  function updateMySubscription(form) {
19
+ jQuery("div.change,#modal_overlay").hide();
20
+ jQuery("#please-wait").show();
21
+ jQuery(".subscription-block .messages").html("");
22
+ jQuery.post(form.attr('action'), form.serialize(), function(transport){
23
+ jQuery("#please-wait").hide();
24
+ if(transport.match("error")){
25
+ form.parents(".subscription-block").find(".messages").html(transport);
26
+ } else {
27
+ form.parents(".subscription-block").html(transport).highlight();
 
 
 
 
 
28
  }
29
  });
30
  }
31
 
32
  function updateAllSubscriptions(form) {
33
+ jQuery("div.change,#modal_overlay").hide();
34
+ jQuery("#please-wait").show();
35
+ jQuery(".subscription-block .messages").html("");
36
+ jQuery.post(form.attr('action'), form.serialize(), function(transport){
37
+ $j("#please-wait").hide();
38
+ if(transport.match("error")){
39
+ form.parents(".my-account").find(".messages").html(transport);
40
+ } else {
41
+ form.parents(".my-account").html(transport).highlight();
 
 
 
 
 
42
  }
43
  });
44
  }
45
 
46
+ jQuery(document).ready(function(){
47
 
48
+ jQuery(".wrapper").after("<div id='modal_overlay'></div>");
49
+ jQuery('#modal_overlay').css({
50
  position: "absolute",
51
  top: 0,
52
  left: 0,
53
+ height: jQuery(document).height(),
54
  width: "100%",
55
  zIndex: 900
56
  }).bind('click', function(){
57
+ jQuery('div.adjust').hide();
58
+ jQuery(this).hide();
59
  }).hide();
60
 
61
+ jQuery(document).on('submit', 'form.payment-form', function(e){
 
 
 
 
 
 
 
 
62
  e.preventDefault();
63
+ var form = jQuery(this);
64
  if(editMultipleSubscriptions == true) {
65
  updateAllSubscriptions(form);
66
  }
68
  updateMySubscription(form);
69
  }
70
  }).on('change', '.shipping-address-select', function(){
71
+ if(jQuery(this).val() == ""){
72
+ jQuery(this).closest('.co-shipping-form').find('.shipping-new-address-form').show();
73
  } else {
74
+ jQuery(this).closest('.co-shipping-form').find('.shipping-new-address-form').hide();
75
  }
76
  }).on('submit', 'form.co-shipping-form', function(e){
77
  e.preventDefault();
78
+ var form = jQuery(this);
79
  if(editMultipleSubscriptions == true) {
80
  updateAllSubscriptions(form);
81
  }
83
  updateMySubscription(form);
84
  }
85
  }).on('change', '.billing-address-select', function(){
86
+ if(jQuery(this).val() == ""){
87
+ jQuery(this).closest('.co-billing-form').find('.billing-new-address-form').show();
88
  } else {
89
+ jQuery(this).closest('.co-billing-form').find('.billing-new-address-form').hide();
90
  }
91
  }).on('submit', 'form.co-billing-form', function(e){
92
  e.preventDefault();
93
+ var form = jQuery(this);
94
  if(editMultipleSubscriptions == true) {
95
  updateAllSubscriptions(form);
96
  }
99
  }
100
  }).on("click", "a.link.more.details", function(e){
101
  e.preventDefault();
102
+ var link = jQuery(this);
103
+ jQuery('#'+link.attr('href')).toggle();
104
  }).on("change", "select.delivery_qty", function(e){
105
  e.preventDefault();
106
+ var form = jQuery(this).closest("form");
107
  updateMySubscription(form);
108
  }).on("change", "select.delivery_interval", function(e){
109
  e.preventDefault();
110
+ var form = jQuery(this).closest("form");
111
  updateMySubscription(form);
112
+ }).on("click", "button.adjust.skip", function(e){
113
  e.preventDefault();
114
+ var box = jQuery(this).parents(".subscription-block").find("div.adjust.skip-delivery");
115
  box.css({
116
+ "top": jQuery(window).scrollTop() + 50,
117
+ "left": (jQuery(window).width() / 2) - (box.width() / 2)
118
  }).show();
119
+ jQuery('#modal_overlay').show();
120
+ }).on("click", "a.adjust.cancel", function(e){
121
  e.preventDefault();
122
+ var box = jQuery(this).parents(".subscription-block").find("div.adjust.cancel");
123
  box.css({
124
+ "top": jQuery(window).scrollTop() + 50,
125
+ "left": (jQuery(window).width() / 2) - (box.width() / 2)
126
  }).show();
127
+ jQuery('#modal_overlay').show();
128
+ }).on("click", "a.adjust.restart", function(e){
129
  e.preventDefault();
130
+ var box = jQuery(this).parents(".subscription-block").find("div.adjust.restart");
131
  box.css({
132
+ "top": jQuery(window).scrollTop() + 50,
133
+ "left": (jQuery(window).width() / 2) - (box.width() / 2)
134
  }).show();
135
+ jQuery('#modal_overlay').show();
136
  }).on("click", "button.no", function(e){
137
+ jQuery("div.adjust,#modal_overlay").hide();
138
  }).on("click", "button.skip_yes", function(e){
139
  e.preventDefault();
140
+ var form = jQuery(this);
141
+ jQuery("div.adjust,#modal_overlay").hide();
142
+ jQuery("#please-wait").show();
143
+ jQuery(".subscription-block .messages").html("");
144
+ jQuery.ajax({
145
  url: form.attr('href'),
146
  method: "get",
147
  success: function(transport){
148
+ jQuery("#please-wait").hide();
149
  if(transport.match("error")){
150
  form.parents(".subscription-block").find(".messages").html(transport);
151
  } else {
155
  });
156
  }).on("click", "button.cancel_yes", function(e){
157
  e.preventDefault();
158
+ var form = jQuery(this);
159
+ jQuery("div.adjust,#modal_overlay").hide();
160
+ jQuery("#please-wait").show();
161
+ jQuery(".subscription-block .messages").html("");
162
+ jQuery.ajax({
163
  url: form.attr('href'),
164
  method: "get",
165
  success: function(transport){
166
+ jQuery("#please-wait").hide();
167
  if(transport.match("error")){
168
  form.parents(".subscription-block").find(".messages").html(transport);
169
  } else {
170
  form.parents(".subscription-block").fadeOut(1000);
171
+ jQuery(".inactive-subscriptions").prepend('<div class="subscription-block">' + transport + '</div>');
172
  }
173
  }
174
  });
175
  }).on("click", "button.restart_yes", function(e){
176
  e.preventDefault();
177
+ var form = jQuery(this);
178
+ jQuery("div.adjust,#modal_overlay").hide();
179
+ jQuery("#please-wait").show();
180
+ jQuery(".subscription-block .messages").html("");
181
+ jQuery.ajax({
182
  url: form.attr('href'),
183
  method: "get",
184
  success: function(transport){
185
+ jQuery("#please-wait").hide();
186
  if(transport.match("error")){
187
  form.parents(".subscription-block").find(".messages").html(transport);
188
  } else {
190
  }
191
  }
192
  });
193
+ }).on('click', ".subscription-more-details a.adjust", function(e){
194
+ e.preventDefault();
195
+ var box = jQuery(this).parents(".block").find("div.adjust");
196
+ box.css({
197
+ "top": jQuery(window).scrollTop() + 50,
198
+ "left": (jQuery(window).width() / 2) - (box.width() / 2)
199
+ }).show();
200
+ jQuery('#modal_overlay').show();
201
  });
202
 
203
  });
skin/frontend/base/default/js/autoship/newsubscription.js CHANGED
@@ -68,18 +68,13 @@ $j(document).ready(function(){
68
  var form = $j(this);
69
  $j("#please-wait").show();
70
  $j('.billing-address-block .messages').html("");
71
- $j.ajax({
72
- url: form.attr('action'),
73
- data: form.serialize(),
74
- method: "post",
75
- success: function(transport){
76
- $j("#please-wait").hide();
77
- if(transport.match("error")){
78
- $j('.billing-address-block .messages').html(transport);
79
- } else {
80
- updateSubscriptionData(transport);
81
- $j('div.change,#modal_overlay').hide();
82
- }
83
  }
84
  });
85
  }).on('submit', '#co-payment-form', function(e){
@@ -87,18 +82,13 @@ $j(document).ready(function(){
87
  var form = $j(this);
88
  $j("#please-wait").show();
89
  $j('.payment-block .messages').html("");
90
- $j.ajax({
91
- url: form.attr('action'),
92
- data: form.serialize(),
93
- method: "post",
94
- success: function(transport){
95
- $j("#please-wait").hide();
96
- if(transport.match("error")){
97
- $j('.payment-block .messages').html(transport);
98
- } else {
99
- updateSubscriptionData(transport);
100
- $j('div.change,#modal_overlay').hide();
101
- }
102
  }
103
  });
104
  }).on('change', '.shipping-address-select', function(){
@@ -112,18 +102,13 @@ $j(document).ready(function(){
112
  var form = $j(this);
113
  $j("#please-wait").show();
114
  $j('.shipping-address-block .messages').html("");
115
- $j.ajax({
116
- url: form.attr('action'),
117
- data: form.serialize(),
118
- method: "post",
119
- success: function(transport){
120
- $j("#please-wait").hide();
121
- if(transport.match("error")){
122
- $j('.shipping-address-block .messages').html(transport);
123
- } else {
124
- updateSubscriptionData(transport);
125
- $j('div.change,#modal_overlay').hide();
126
- }
127
  }
128
  });
129
  }).on('click', '#subscribe', function(e){
@@ -131,36 +116,29 @@ $j(document).ready(function(){
131
  var form = $j(this);
132
  $j("#please-wait").show();
133
  $j('.summary-block .messages').html("");
134
- $j.ajax({
135
- url: form.attr('href'),
136
- data: {"delivery_date":$j("#delivery_date").val(), "coupon_code":$j("#coupon_code").val()},
137
- method: "post",
138
- success: function(transport){
139
- $j("#please-wait").hide();
140
- if(transport.match("error")){
141
- $j('.summary-block .messages').html(transport);
142
- } else {
143
- window.location = transport;
144
- }
145
  }
146
  });
147
  });
148
-
149
  $j("#delivery_qty,#delivery_interval").bind('change', function(e){
150
  $j("#please-wait").show();
151
  var form = $j("#frequency_form"); // fake form
152
- $j.ajax({
153
- url: form.val(),
154
- data: {
155
- "qty": $j("#delivery_qty").val(),
156
- "interval": $j("#delivery_interval").val()
157
- },
158
- method: "post",
159
- success: function(transport){
160
- $j("#please-wait").hide();
161
- updateSubscriptionData(transport);
162
- }
163
- });
164
  });
165
 
166
  });
68
  var form = $j(this);
69
  $j("#please-wait").show();
70
  $j('.billing-address-block .messages').html("");
71
+ $j.post(form.attr('action'), form.serialize(), function(transport){
72
+ $j("#please-wait").hide();
73
+ if(transport.match("error")){
74
+ $j('.billing-address-block .messages').html(transport);
75
+ } else {
76
+ updateSubscriptionData(transport);
77
+ $j('div.change,#modal_overlay').hide();
 
 
 
 
 
78
  }
79
  });
80
  }).on('submit', '#co-payment-form', function(e){
82
  var form = $j(this);
83
  $j("#please-wait").show();
84
  $j('.payment-block .messages').html("");
85
+ $j.post(form.attr('action'), form.serialize(), function(transport){
86
+ $j("#please-wait").hide();
87
+ if(transport.match("error")){
88
+ $j('.payment-block .messages').html(transport);
89
+ } else {
90
+ updateSubscriptionData(transport);
91
+ $j('div.change,#modal_overlay').hide();
 
 
 
 
 
92
  }
93
  });
94
  }).on('change', '.shipping-address-select', function(){
102
  var form = $j(this);
103
  $j("#please-wait").show();
104
  $j('.shipping-address-block .messages').html("");
105
+ $j.post(form.attr('action'), form.serialize(), function(transport){
106
+ $j("#please-wait").hide();
107
+ if(transport.match("error")){
108
+ $j('.shipping-address-block .messages').html(transport);
109
+ } else {
110
+ updateSubscriptionData(transport);
111
+ $j('div.change,#modal_overlay').hide();
 
 
 
 
 
112
  }
113
  });
114
  }).on('click', '#subscribe', function(e){
116
  var form = $j(this);
117
  $j("#please-wait").show();
118
  $j('.summary-block .messages').html("");
119
+ $j.post(form.attr('href'), {
120
+ "delivery_date": $j("#delivery_date").val(),
121
+ "coupon_code": $j("#coupon_code").val()
122
+ }, function(transport){
123
+ $j("#please-wait").hide();
124
+ if(transport.match("error")){
125
+ $j('.summary-block .messages').html(transport);
126
+ } else {
127
+ window.location = transport;
 
 
128
  }
129
  });
130
  });
131
+
132
  $j("#delivery_qty,#delivery_interval").bind('change', function(e){
133
  $j("#please-wait").show();
134
  var form = $j("#frequency_form"); // fake form
135
+ $j.post(form.val(), {
136
+ "qty": $j("#delivery_qty").val(),
137
+ "interval": $j("#delivery_interval").val()
138
+ }, function(transport){
139
+ $j("#please-wait").hide();
140
+ updateSubscriptionData(transport);
141
+ });
 
 
 
 
 
142
  });
143
 
144
  });