1: | <?php
2: | namespace Opencart\Catalog\Controller\Cron;
3: | /**
4: | * Class Subscription
5: | *
6: | * @package Opencart\Catalog\Controller\Cron
7: | */
8: | class Subscription extends \Opencart\System\Engine\Controller {
9: | /**
10: | * Index
11: | *
12: | * @param int $cron_id
13: | * @param string $code
14: | * @param string $cycle
15: | * @param string $date_added
16: | * @param string $date_modified
17: | *
18: | * @return void
19: | */
20: | public function index(int $cron_id, string $code, string $cycle, string $date_added, string $date_modified): void {
21: | $this->load->language('cron/subscription');
22: |
23: | // Check if there is an order, the order status is complete and subscription status is active
24: | $filter_data = [
25: | 'filter_date_next' => date('Y-m-d H:i:s'),
26: | 'filter_subscription_status_id' => $this->config->get('config_subscription_active_status_id'),
27: | 'start' => 0,
28: | 'limit' => 10
29: | ];
30: |
31: | // Get all
32: | $this->load->model('checkout/subscription');
33: | $this->load->model('checkout/order');
34: |
35: | $results = $this->model_checkout_subscription->getSubscriptions($filter_data);
36: |
37: | foreach ($results as $result) {
38: | $order_info = $this->model_checkout_order->getOrder($result['order_id']);
39: |
40: | if (($result['trial_status'] && $result['trial_remaining']) || ($result['duration'] && $result['remaining'])) {
41: | $error = '';
42: |
43: | // 1. Language
44: | $this->load->model('localisation/language');
45: |
46: | $language_info = $this->model_localisation_language->getLanguage($result['language_id']);
47: |
48: | if (!$language_info) {
49: | $error = $this->language->get('error_language');
50: | }
51: |
52: | // 2. Currency
53: | $this->load->model('localisation/currency');
54: |
55: | $currency_info = $this->model_localisation_currency->getCurrency($result['currency_id']);
56: |
57: | if (!$currency_info) {
58: | $error = $this->language->get('error_currency');
59: | }
60: |
61: | // 3. Create new instance of a store
62: | if (!$error) {
63: | $this->load->model('setting/store');
64: |
65: | $store = $this->model_setting_store->createStoreInstance($result['store_id'], $language_info['code']);
66: |
67: | // Login
68: | $this->load->model('account/customer');
69: |
70: | $customer_info = $this->model_account_customer->getCustomer($result['customer_id']);
71: |
72: | if ($customer_info && $this->customer->login($customer_info['email'], '', true)) {
73: | // Add customer details into session
74: | $store->session->data['customer'] = $customer_info;
75: | } else {
76: | $error = $this->language->get('error_customer');
77: | }
78: | }
79: |
80: | // 4. Add product
81: | if (!$error) {
82: | $this->load->model('catalog/product');
83: |
84: | $product_info = $this->model_catalog_product->getProduct($result['product_id']);
85: |
86: | if ($product_info) {
87: | $price = $result['price'];
88: |
89: | if ($result['trial_status'] && (!$result['trial_duration'] || $result['trial_remaining'])) {
90: | $price = $result['trial_price'];
91: | }
92: |
93: | $store->cart->add($result['product_id'], $result['quantity'], $result['option'], $result['subscription_plan_id'], true, $price);
94: | } else {
95: | $error = $this->language->get('error_product');
96: | }
97: | }
98: |
99: | // 5. Add Shipping Address
100: | if (!$error && $store->cart->hasShipping()) {
101: | $this->load->model('account/address');
102: |
103: | $shipping_address_info = $this->model_account_address->getAddress($result['customer_id'], $result['shipping_address_id']);
104: |
105: | if ($shipping_address_info) {
106: | $store->session->data['shipping_address'] = $shipping_address_info;
107: | } else {
108: | $error = $this->language->get('error_shipping_address');
109: | }
110: |
111: | // 5. Shipping Methods
112: | if (!$error) {
113: | $this->load->model('checkout/shipping_method');
114: |
115: | $shipping_methods = $this->model_checkout_shipping_method->getMethods($shipping_address_info);
116: |
117: | // Validate shipping method
118: | if (isset($order_info['shipping_method']['code']) && $shipping_methods) {
119: | $shipping = explode('.', $order_info['shipping_method']['code']);
120: |
121: | if (isset($shipping[0]) && isset($shipping[1]) && isset($shipping_methods[$shipping[0]]['quote'][$shipping[1]])) {
122: | $store->session->data['shipping_method'] = $shipping_methods[$shipping[0]]['quote'][$shipping[1]];
123: | } else {
124: | $error = $this->language->get('error_shipping_method');
125: | }
126: | } else {
127: | $error = $this->language->get('error_shipping_method');
128: | }
129: | }
130: | }
131: |
132: | // 6. Payment Address
133: | if (!$error) {
134: | if ($this->config->get('config_checkout_payment_address')) {
135: | $this->load->model('account/address');
136: |
137: | $payment_address_info = $this->model_account_address->getAddress($order_info['customer_id'], $result['payment_address_id']);
138: |
139: | if ($payment_address_info) {
140: | $store->session->data['payment_address'] = $payment_address_info;
141: | } else {
142: | $error = $this->language->get('error_payment_address');
143: | }
144: | } else {
145: | $payment_address_info = [];
146: | }
147: | }
148: |
149: | // 7. Payment Methods
150: | if (!$error) {
151: | $this->load->model('checkout/payment_method');
152: |
153: | $payment_methods = $this->model_checkout_payment_method->getMethods($store->session->data['payment_address']);
154: |
155: | // Validate payment methods
156: | if (isset($order_info['payment_method']['code']) && $payment_methods) {
157: | $payment = explode('.', $order_info['payment_method']['code']);
158: |
159: | if (isset($payment[0]) && isset($payment[1]) && isset($payment_methods[$payment[0]]['option'][$payment[1]])) {
160: | $store->session->data['payment_method'] = $payment_methods[$payment[0]]['option'][$payment[1]];
161: | } else {
162: | $error = $this->language->get('error_payment_method');
163: | }
164: | } else {
165: | $error = $this->language->get('error_payment_method');
166: | }
167: | }
168: |
169: | if (!$error) {
170: | // Subscription
171: | $order_data = [];
172: |
173: | $order_data['subscription_id'] = $order_info['subscription_id'];
174: |
175: | // Store Details
176: | $order_data['invoice_prefix'] = $order_info['invoice_prefix'];
177: | $order_data['store_id'] = $order_info['store_id'];
178: | $order_data['store_name'] = $order_info['store_name'];
179: | $order_data['store_url'] = $order_info['store_url'];
180: |
181: | // Customer Details
182: | $order_data['customer_id'] = $customer_info['customer_id'];
183: | $order_data['customer_group_id'] = $customer_info['customer_group_id'];
184: | $order_data['firstname'] = $customer_info['firstname'];
185: | $order_data['lastname'] = $customer_info['lastname'];
186: | $order_data['email'] = $customer_info['email'];
187: | $order_data['telephone'] = $customer_info['telephone'];
188: | $order_data['custom_field'] = $customer_info['custom_field'];
189: |
190: | // Payment Details
191: | if ($payment_address_info) {
192: | $order_data['payment_address_id'] = $payment_address_info['address_id'];
193: | $order_data['payment_firstname'] = $payment_address_info['firstname'];
194: | $order_data['payment_lastname'] = $payment_address_info['lastname'];
195: | $order_data['payment_company'] = $payment_address_info['company'];
196: | $order_data['payment_address_1'] = $payment_address_info['address_1'];
197: | $order_data['payment_address_2'] = $payment_address_info['address_2'];
198: | $order_data['payment_city'] = $payment_address_info['city'];
199: | $order_data['payment_postcode'] = $payment_address_info['postcode'];
200: | $order_data['payment_zone'] = $payment_address_info['zone'];
201: | $order_data['payment_zone_id'] = $payment_address_info['zone_id'];
202: | $order_data['payment_country'] = $payment_address_info['country'];
203: | $order_data['payment_country_id'] = $payment_address_info['country_id'];
204: | $order_data['payment_address_format'] = $payment_address_info['address_format'];
205: | $order_data['payment_custom_field'] = $payment_address_info['custom_field'];
206: | } else {
207: | $order_data['payment_address_id'] = 0;
208: | $order_data['payment_firstname'] = '';
209: | $order_data['payment_lastname'] = '';
210: | $order_data['payment_company'] = '';
211: | $order_data['payment_address_1'] = '';
212: | $order_data['payment_address_2'] = '';
213: | $order_data['payment_city'] = '';
214: | $order_data['payment_postcode'] = '';
215: | $order_data['payment_zone'] = '';
216: | $order_data['payment_zone_id'] = 0;
217: | $order_data['payment_country'] = '';
218: | $order_data['payment_country_id'] = 0;
219: | $order_data['payment_address_format'] = '';
220: | $order_data['payment_custom_field'] = [];
221: | }
222: |
223: | $order_data['payment_method'] = $store->session->data['payment_method'];
224: |
225: | // Shipping Details
226: | if ($store->cart->hasShipping()) {
227: | $order_data['shipping_address_id'] = $shipping_address_info['address_id'];
228: | $order_data['shipping_firstname'] = $shipping_address_info['firstname'];
229: | $order_data['shipping_lastname'] = $shipping_address_info['lastname'];
230: | $order_data['shipping_company'] = $shipping_address_info['company'];
231: | $order_data['shipping_address_1'] = $shipping_address_info['address_1'];
232: | $order_data['shipping_address_2'] = $shipping_address_info['address_2'];
233: | $order_data['shipping_city'] = $shipping_address_info['city'];
234: | $order_data['shipping_postcode'] = $shipping_address_info['postcode'];
235: | $order_data['shipping_zone'] = $shipping_address_info['zone'];
236: | $order_data['shipping_zone_id'] = $shipping_address_info['zone_id'];
237: | $order_data['shipping_country'] = $shipping_address_info['country'];
238: | $order_data['shipping_country_id'] = $shipping_address_info['country_id'];
239: | $order_data['shipping_address_format'] = $shipping_address_info['address_format'];
240: | $order_data['shipping_custom_field'] = $shipping_address_info['custom_field'];
241: |
242: | $order_data['shipping_method'] = $store->session->data['shipping_method'];
243: | } else {
244: | $order_data['shipping_address_id'] = 0;
245: | $order_data['shipping_firstname'] = '';
246: | $order_data['shipping_lastname'] = '';
247: | $order_data['shipping_company'] = '';
248: | $order_data['shipping_address_1'] = '';
249: | $order_data['shipping_address_2'] = '';
250: | $order_data['shipping_city'] = '';
251: | $order_data['shipping_postcode'] = '';
252: | $order_data['shipping_zone'] = '';
253: | $order_data['shipping_zone_id'] = 0;
254: | $order_data['shipping_country'] = '';
255: | $order_data['shipping_country_id'] = 0;
256: | $order_data['shipping_address_format'] = '';
257: | $order_data['shipping_custom_field'] = [];
258: |
259: | $order_data['shipping_method'] = [];
260: | }
261: |
262: | // Products
263: | $order_data['products'] = [];
264: |
265: | $products = $store->model_checkout_cart->getProducts();
266: |
267: | foreach ($products as $product) {
268: | $order_data['products'][] = [
269: | 'product_id' => $product['product_id'],
270: | 'master_id' => $product['master_id'],
271: | 'name' => $product['name'],
272: | 'model' => $product['model'],
273: | 'option' => $product['option'],
274: | 'subscription' => [],
275: | 'download' => $product['download'],
276: | 'quantity' => $product['quantity'],
277: | 'subtract' => $product['subtract'],
278: | 'price' => $product['price'],
279: | 'total' => $product['total'],
280: | 'tax' => $this->tax->getTax($price, $product['tax_class_id']),
281: | 'reward' => $product['reward']
282: | ];
283: | }
284: |
285: | // Vouchers can not be in subscriptions
286: | $order_data['vouchers'] = [];
287: |
288: | // Order Totals
289: | $totals = [];
290: | $taxes = $store->cart->getTaxes();
291: | $total = 0;
292: |
293: | $store->load->model('checkout/cart');
294: |
295: | ($store->model_checkout_cart->getTotals)($totals, $taxes, $total);
296: |
297: | $total_data = [
298: | 'totals' => $totals,
299: | 'taxes' => $taxes,
300: | 'total' => $total
301: | ];
302: |
303: | $order_data = array_merge($order_data, $total_data);
304: |
305: | $order_data['affiliate_id'] = 0;
306: | $order_data['commission'] = 0;
307: | $order_data['marketing_id'] = 0;
308: | $order_data['tracking'] = '';
309: |
310: | if (isset($this->session->data['tracking'])) {
311: | $subtotal = $this->cart->getSubTotal();
312: |
313: | // Affiliate
314: | if ($this->config->get('config_affiliate_status')) {
315: | $this->load->model('account/affiliate');
316: |
317: | $affiliate_info = $this->model_account_affiliate->getAffiliateByTracking($this->session->data['tracking']);
318: |
319: | if ($affiliate_info) {
320: | $order_data['affiliate_id'] = $affiliate_info['customer_id'];
321: | $order_data['commission'] = ($subtotal / 100) * $affiliate_info['commission'];
322: | $order_data['tracking'] = $this->session->data['tracking'];
323: | }
324: | }
325: |
326: | $this->load->model('marketing/marketing');
327: |
328: | $marketing_info = $this->model_marketing_marketing->getMarketingByCode($this->session->data['tracking']);
329: |
330: | if ($marketing_info) {
331: | $order_data['marketing_id'] = $marketing_info['marketing_id'];
332: | }
333: | }
334: |
335: | // Language
336: | $order_data['language_id'] = $language_info['language_id'];
337: | $order_data['language_code'] = $language_info['code'];
338: |
339: | // Currency
340: | $order_data['currency_id'] = $currency_info['currency_id'];
341: | $order_data['currency_code'] = $currency_info['code'];
342: | $order_data['currency_value'] = $currency_info['value'];
343: |
344: | $order_data['ip'] = $result['ip'];
345: | $order_data['forwarded_ip'] = $result['forwarded_ip'];
346: | $order_data['user_agent'] = $result['user_agent'];
347: | $order_data['accept_language'] = $result['accept_language'];
348: |
349: | $this->load->model('checkout/order');
350: |
351: | $store->session->data['order_id'] = $this->model_checkout_order->addOrder($order_data);
352: |
353: | // Validate if payment extension installed
354: | $this->load->model('setting/extension');
355: |
356: | $extension_info = $this->model_setting_extension->getExtensionByCode('payment', $payment[0]);
357: |
358: | // Load payment method used by the subscription
359: | $this->load->model('extension/' . $extension_info['extension'] . '/payment/' . $extension_info['code']);
360: |
361: | $callable = [$this->{'model_extension_' . $extension_info['extension'] . '_payment_' . $extension_info['code']}, 'charge'];
362: |
363: | if (is_callable($callable)) {
364: | // Process payment
365: | $response_info = $this->{'model_extension_' . $order_data['payment_method']['extension'] . '_payment_' . $order_data['payment_method']['code']}->charge($this->customer->getId(), $this->session->data['order_id'], $order_info['total'], $order_data['payment_method']['code']);
366: |
367: | if (isset($response_info['order_status_id'])) {
368: | $order_status_id = $response_info['order_status_id'];
369: | } else {
370: | $order_status_id = 0;
371: | }
372: |
373: | if ($response_info['message']) {
374: | $message = $response_info['message'];
375: | } else {
376: | $message = '';
377: | }
378: |
379: | $this->model_checkout_order->addHistory($store->session->data['order_id'], $order_status_id, $message, false);
380: | $this->model_checkout_order->addHistory($store->session->data['order_id'], $order_status_id);
381: |
382: | // If payment order status is active or processing
383: | if (!in_array($order_status_id, (array)$this->config->get('config_processing_status') + (array)$this->config->get('config_complete_status'))) {
384: | $remaining = 0;
385: | $date_next = '';
386: |
387: | if ($result['trial_status'] && $result['trial_remaining'] > 1) {
388: | $remaining = $result['trial_remaining'] - 1;
389: | $date_next = date('Y-m-d', strtotime('+' . $result['trial_cycle'] . ' ' . $result['trial_frequency']));
390: |
391: | $this->model_account_subscription->editTrialRemaining($result['subscription_id'], $remaining);
392: | } elseif ($result['duration'] && $result['remaining']) {
393: | $remaining = $result['remaining'] - 1;
394: | $date_next = date('Y-m-d', strtotime('+' . $result['cycle'] . ' ' . $result['frequency']));
395: |
396: | // If duration make sure there is remaining
397: | $this->model_account_subscription->editRemaining($result['subscription_id'], $remaining);
398: | } elseif (!$result['duration']) {
399: | // If duration is unlimited
400: | $date_next = date('Y-m-d', strtotime('+' . $result['cycle'] . ' ' . $result['frequency']));
401: | }
402: |
403: | if ($date_next) {
404: | $this->load->model('checkout/subscription');
405: | $this->model_checkout_subscription->editDateNext($result['subscription_id'], $date_next);
406: | }
407: |
408: | $this->model_checkout_subscription->addHistory($result['subscription_id'], $this->config->get('config_subscription_active_status_id'), $this->language->get('text_success'), true);
409: | } else {
410: | // If payment failed change subscription history to failed
411: | $this->model_checkout_subscription->addHistory($result['subscription_id'], $this->config->get('config_subscription_failed_status_id'), $message, true);
412: | }
413: | } else {
414: | // Add subscription history failed if no charge method
415: | $this->model_checkout_subscription->addHistory($result['subscription_id'], $this->config->get('config_subscription_failed_status_id'), $this->language->get('error_payment_method'), true);
416: | }
417: | } else {
418: | // Errors add to
419: | $this->model_checkout_subscription->addHistory($result['subscription_id'], $this->config->get('config_subscription_failed_status_id'), $error, true);
420: | }
421: | }
422: | }
423: | }
424: | }
425: |

OpenCart API API documentation generated by ApiGen dev-master