1: <?php
2: namespace Opencart\Catalog\Controller\Account;
3: /**
4: * Class Order
5: *
6: * @package Opencart\Catalog\Controller\Account
7: */
8: class Order extends \Opencart\System\Engine\Controller {
9: /**
10: * @return void
11: */
12: public function index(): void {
13: $this->load->language('account/order');
14:
15: if (isset($this->request->get['page'])) {
16: $page = (int)$this->request->get['page'];
17: } else {
18: $page = 1;
19: }
20:
21: if (!$this->customer->isLogged() || (!isset($this->request->get['customer_token']) || !isset($this->session->data['customer_token']) || ($this->request->get['customer_token'] != $this->session->data['customer_token']))) {
22: $this->session->data['redirect'] = $this->url->link('account/order', 'language=' . $this->config->get('config_language'));
23:
24: $this->response->redirect($this->url->link('account/login', 'language=' . $this->config->get('config_language'), true));
25: }
26:
27: $this->document->setTitle($this->language->get('heading_title'));
28:
29: $url = '';
30:
31: if (isset($this->request->get['page'])) {
32: $url .= '&page=' . $this->request->get['page'];
33: }
34:
35: $data['breadcrumbs'] = [];
36:
37: $data['breadcrumbs'][] = [
38: 'text' => $this->language->get('text_home'),
39: 'href' => $this->url->link('common/home', 'language=' . $this->config->get('config_language'))
40: ];
41:
42: $data['breadcrumbs'][] = [
43: 'text' => $this->language->get('text_account'),
44: 'href' => $this->url->link('account/account', 'language=' . $this->config->get('config_language') . '&customer_token=' . $this->session->data['customer_token'])
45: ];
46:
47: $data['breadcrumbs'][] = [
48: 'text' => $this->language->get('heading_title'),
49: 'href' => $this->url->link('account/order', 'language=' . $this->config->get('config_language') . '&customer_token=' . $this->session->data['customer_token'] . $url)
50: ];
51:
52: $limit = 10;
53:
54: $data['orders'] = [];
55:
56: $this->load->model('account/order');
57: $this->load->model('localisation/order_status');
58:
59: $results = $this->model_account_order->getOrders(($page - 1) * $limit, $limit);
60:
61: foreach ($results as $result) {
62: $order_status_info = $this->model_localisation_order_status->getOrderStatus($result['order_status_id']);
63:
64: if ($order_status_info) {
65: $order_status = $order_status_info['name'];
66: } else {
67: $order_status = '';
68: }
69:
70: $product_total = $this->model_account_order->getTotalProductsByOrderId($result['order_id']);
71: $voucher_total = $this->model_account_order->getTotalVouchersByOrderId($result['order_id']);
72:
73: $data['orders'][] = [
74: 'order_id' => $result['order_id'],
75: 'name' => $result['firstname'] . ' ' . $result['lastname'],
76: 'status' => $order_status,
77: 'date_added' => date($this->language->get('date_format_short'), strtotime($result['date_added'])),
78: 'products' => ($product_total + $voucher_total),
79: 'total' => $this->currency->format($result['total'], $result['currency_code'], $result['currency_value']),
80: 'view' => $this->url->link('account/order.info', 'language=' . $this->config->get('config_language') . '&customer_token=' . $this->session->data['customer_token'] . '&order_id=' . $result['order_id']),
81: ];
82: }
83:
84: $order_total = $this->model_account_order->getTotalOrders();
85:
86: $data['pagination'] = $this->load->controller('common/pagination', [
87: 'total' => $order_total,
88: 'page' => $page,
89: 'limit' => $limit,
90: 'url' => $this->url->link('account/order', 'language=' . $this->config->get('config_language') . '&customer_token=' . $this->session->data['customer_token'] . '&page={page}')
91: ]);
92:
93: $data['results'] = sprintf($this->language->get('text_pagination'), ($order_total) ? (($page - 1) * $limit) + 1 : 0, ((($page - 1) * $limit) > ($order_total - $limit)) ? $order_total : ((($page - 1) * $limit) + $limit), $order_total, ceil($order_total / $limit));
94:
95: $data['continue'] = $this->url->link('account/account', 'language=' . $this->config->get('config_language') . '&customer_token=' . $this->session->data['customer_token']);
96:
97: $data['column_left'] = $this->load->controller('common/column_left');
98: $data['column_right'] = $this->load->controller('common/column_right');
99: $data['content_top'] = $this->load->controller('common/content_top');
100: $data['content_bottom'] = $this->load->controller('common/content_bottom');
101: $data['footer'] = $this->load->controller('common/footer');
102: $data['header'] = $this->load->controller('common/header');
103:
104: $this->response->setOutput($this->load->view('account/order_list', $data));
105: }
106:
107: /**
108: * Info
109: *
110: * @return \Opencart\System\Engine\Action|null
111: */
112: public function info(): ?\Opencart\System\Engine\Action {
113: $this->load->language('account/order');
114:
115: if (isset($this->request->get['order_id'])) {
116: $order_id = (int)$this->request->get['order_id'];
117: } else {
118: $order_id = 0;
119: }
120:
121: if (!$this->customer->isLogged() || (!isset($this->request->get['customer_token']) || !isset($this->session->data['customer_token']) || ($this->request->get['customer_token'] != $this->session->data['customer_token']))) {
122: $this->session->data['redirect'] = $this->url->link('account/order', 'language=' . $this->config->get('config_language'));
123:
124: $this->response->redirect($this->url->link('account/login', 'language=' . $this->config->get('config_language'), true));
125: }
126:
127: $this->load->model('account/order');
128:
129: $order_info = $this->model_account_order->getOrder($order_id);
130:
131: if ($order_info) {
132: $heading_title = sprintf($this->language->get('text_order'), $order_info['order_id']);
133:
134: $this->document->setTitle($heading_title);
135:
136: $data['heading_title'] = $heading_title;
137:
138: $url = '';
139:
140: if (isset($this->request->get['page'])) {
141: $url .= '&page=' . $this->request->get['page'];
142: }
143:
144: $data['breadcrumbs'] = [];
145:
146: $data['breadcrumbs'][] = [
147: 'text' => $this->language->get('text_home'),
148: 'href' => $this->url->link('common/home', 'language=' . $this->config->get('config_language'))
149: ];
150:
151: $data['breadcrumbs'][] = [
152: 'text' => $this->language->get('text_account'),
153: 'href' => $this->url->link('account/account', 'language=' . $this->config->get('config_language') . '&customer_token=' . $this->session->data['customer_token'])
154: ];
155:
156: $data['breadcrumbs'][] = [
157: 'text' => $this->language->get('heading_title'),
158: 'href' => $this->url->link('account/order', 'language=' . $this->config->get('config_language') . '&customer_token=' . $this->session->data['customer_token'] . $url)
159: ];
160:
161: $data['breadcrumbs'][] = [
162: 'text' => $heading_title,
163: 'href' => $this->url->link('account/order.info', 'language=' . $this->config->get('config_language') . '&customer_token=' . $this->session->data['customer_token'] . '&order_id=' . $order_id . $url)
164: ];
165:
166: if ($order_info['invoice_no']) {
167: $data['invoice_no'] = $order_info['invoice_prefix'] . $order_info['invoice_no'];
168: } else {
169: $data['invoice_no'] = '';
170: }
171:
172: $data['order_id'] = $order_id;
173:
174: $this->load->model('localisation/order_status');
175:
176: $order_status_info = $this->model_localisation_order_status->getOrderStatus($order_info['order_status_id']);
177:
178: if ($order_status_info) {
179: $data['order_status'] = $order_status_info['name'];
180: } else {
181: $data['order_status'] = '';
182: }
183:
184: $data['date_added'] = date($this->language->get('date_format_short'), strtotime($order_info['date_added']));
185:
186: // Payment Address
187: if ($order_info['payment_address_format']) {
188: $format = $order_info['payment_address_format'];
189: } else {
190: $format = '{firstname} {lastname}' . "\n" . '{company}' . "\n" . '{address_1}' . "\n" . '{address_2}' . "\n" . '{city} {postcode}' . "\n" . '{zone}' . "\n" . '{country}';
191: }
192:
193: $find = [
194: '{firstname}',
195: '{lastname}',
196: '{company}',
197: '{address_1}',
198: '{address_2}',
199: '{city}',
200: '{postcode}',
201: '{zone}',
202: '{zone_code}',
203: '{country}'
204: ];
205:
206: $replace = [
207: 'firstname' => $order_info['payment_firstname'],
208: 'lastname' => $order_info['payment_lastname'],
209: 'company' => $order_info['payment_company'],
210: 'address_1' => $order_info['payment_address_1'],
211: 'address_2' => $order_info['payment_address_2'],
212: 'city' => $order_info['payment_city'],
213: 'postcode' => $order_info['payment_postcode'],
214: 'zone' => $order_info['payment_zone'],
215: 'zone_code' => $order_info['payment_zone_code'],
216: 'country' => $order_info['payment_country']
217: ];
218:
219: $pattern_1 = [
220: "\r\n",
221: "\r",
222: "\n"
223: ];
224:
225: $pattern_2 = [
226: "/\\s\\s+/",
227: "/\r\r+/",
228: "/\n\n+/"
229: ];
230:
231: $data['payment_address'] = str_replace($pattern_1, '<br/>', preg_replace($pattern_2, '<br/>', trim(str_replace($find, $replace, $format))));
232:
233: $data['payment_method'] = $order_info['payment_method']['name'];
234:
235: // Shipping Address
236: if ($order_info['shipping_method']) {
237: if ($order_info['shipping_address_format']) {
238: $format = $order_info['shipping_address_format'];
239: } else {
240: $format = '{firstname} {lastname}' . "\n" . '{company}' . "\n" . '{address_1}' . "\n" . '{address_2}' . "\n" . '{city} {postcode}' . "\n" . '{zone}' . "\n" . '{country}';
241: }
242:
243: $find = [
244: '{firstname}',
245: '{lastname}',
246: '{company}',
247: '{address_1}',
248: '{address_2}',
249: '{city}',
250: '{postcode}',
251: '{zone}',
252: '{zone_code}',
253: '{country}'
254: ];
255:
256: $replace = [
257: 'firstname' => $order_info['shipping_firstname'],
258: 'lastname' => $order_info['shipping_lastname'],
259: 'company' => $order_info['shipping_company'],
260: 'address_1' => $order_info['shipping_address_1'],
261: 'address_2' => $order_info['shipping_address_2'],
262: 'city' => $order_info['shipping_city'],
263: 'postcode' => $order_info['shipping_postcode'],
264: 'zone' => $order_info['shipping_zone'],
265: 'zone_code' => $order_info['shipping_zone_code'],
266: 'country' => $order_info['shipping_country']
267: ];
268:
269: $data['shipping_address'] = str_replace($pattern_1, '<br/>', preg_replace($pattern_2, '<br/>', trim(str_replace($find, $replace, $format))));
270:
271: $data['shipping_method'] = $order_info['shipping_method']['name'];
272: } else {
273: $data['shipping_address'] = '';
274: $data['shipping_method'] = '';
275: }
276:
277: $this->load->model('account/subscription');
278: $this->load->model('catalog/product');
279: $this->load->model('tool/upload');
280:
281: // Products
282: $data['products'] = [];
283:
284: $products = $this->model_account_order->getProducts($order_id);
285:
286: foreach ($products as $product) {
287: $option_data = [];
288:
289: $options = $this->model_account_order->getOptions($order_id, $product['order_product_id']);
290:
291: foreach ($options as $option) {
292: if ($option['type'] != 'file') {
293: $value = $option['value'];
294: } else {
295: $upload_info = $this->model_tool_upload->getUploadByCode($option['value']);
296:
297: if ($upload_info) {
298: $value = $upload_info['name'];
299: } else {
300: $value = '';
301: }
302: }
303:
304: $option_data[] = [
305: 'name' => $option['name'],
306: 'value' => (oc_strlen($value) > 20 ? oc_substr($value, 0, 20) . '..' : $value)
307: ];
308: }
309:
310: $description = '';
311:
312: $subscription_info = $this->model_account_order->getSubscription($order_id, $product['order_product_id']);
313:
314: if ($subscription_info) {
315: if ($subscription_info['trial_status']) {
316: $trial_price = $this->currency->format($subscription_info['trial_price'] + ($this->config->get('config_tax') ? $subscription_info['trial_tax'] : 0), $order_info['currency_code'], $order_info['currency_value']);
317: $trial_cycle = $subscription_info['trial_cycle'];
318: $trial_frequency = $this->language->get('text_' . $subscription_info['trial_frequency']);
319: $trial_duration = $subscription_info['trial_duration'];
320:
321: $description .= sprintf($this->language->get('text_subscription_trial'), $trial_price, $trial_cycle, $trial_frequency, $trial_duration);
322: }
323:
324: $price = $this->currency->format($subscription_info['price'] + ($this->config->get('config_tax') ? $subscription_info['tax'] : 0), $order_info['currency_code'], $order_info['currency_value']);
325: $cycle = $subscription_info['cycle'];
326: $frequency = $this->language->get('text_' . $subscription_info['frequency']);
327: $duration = $subscription_info['duration'];
328:
329: if ($subscription_info['duration']) {
330: $description .= sprintf($this->language->get('text_subscription_duration'), $price, $cycle, $frequency, $duration);
331: } else {
332: $description .= sprintf($this->language->get('text_subscription_cancel'), $price, $cycle, $frequency);
333: }
334: }
335:
336: $subscription_info = $this->model_account_subscription->getSubscriptionByOrderProductId($order_id, $product['order_product_id']);
337:
338: if ($subscription_info) {
339: $subscription = $this->url->link('account/subscription.info', 'language=' . $this->config->get('config_language') . '&customer_token=' . $this->session->data['customer_token'] . '&subscription_id=' . $subscription_info['subscription_id']);
340: } else {
341: $subscription = '';
342: }
343:
344: $product_info = $this->model_catalog_product->getProduct($product['product_id']);
345:
346: if ($product_info) {
347: $reorder = $this->url->link('account/order.reorder', 'language=' . $this->config->get('config_language') . '&customer_token=' . $this->session->data['customer_token'] . '&order_id=' . $order_id . '&order_product_id=' . $product['order_product_id']);
348: } else {
349: $reorder = '';
350: }
351:
352: $data['products'][] = [
353: 'name' => $product['name'],
354: 'model' => $product['model'],
355: 'option' => $option_data,
356: 'subscription' => $subscription,
357: 'subscription_description' => $description,
358: 'quantity' => $product['quantity'],
359: 'price' => $this->currency->format($product['price'] + ($this->config->get('config_tax') ? $product['tax'] : 0), $order_info['currency_code'], $order_info['currency_value']),
360: 'total' => $this->currency->format($product['total'] + ($this->config->get('config_tax') ? ($product['tax'] * $product['quantity']) : 0), $order_info['currency_code'], $order_info['currency_value']),
361: 'href' => $this->url->link('product/product', 'language=' . $this->config->get('config_language') . '&product_id=' . $product['product_id']),
362: 'reorder' => $reorder,
363: 'return' => $this->url->link('account/returns.add', 'language=' . $this->config->get('config_language') . '&order_id=' . $order_info['order_id'] . '&product_id=' . $product['product_id'])
364: ];
365: }
366:
367: // Voucher
368: $data['vouchers'] = [];
369:
370: $vouchers = $this->model_account_order->getVouchers($order_id);
371:
372: foreach ($vouchers as $voucher) {
373: $data['vouchers'][] = [
374: 'description' => $voucher['description'],
375: 'amount' => $this->currency->format($voucher['amount'], $order_info['currency_code'], $order_info['currency_value'])
376: ];
377: }
378:
379: // Totals
380: $data['totals'] = [];
381:
382: $totals = $this->model_account_order->getTotals($order_id);
383:
384: foreach ($totals as $total) {
385: $data['totals'][] = [
386: 'title' => $total['title'],
387: 'text' => $this->currency->format($total['value'], $order_info['currency_code'], $order_info['currency_value']),
388: ];
389: }
390:
391: $data['comment'] = nl2br($order_info['comment']);
392:
393: // History
394: $data['history'] = $this->getHistory();
395:
396: $data['continue'] = $this->url->link('account/order', 'language=' . $this->config->get('config_language') . '&customer_token=' . $this->session->data['customer_token']);
397:
398: $data['column_left'] = $this->load->controller('common/column_left');
399: $data['column_right'] = $this->load->controller('common/column_right');
400: $data['content_top'] = $this->load->controller('common/content_top');
401: $data['content_bottom'] = $this->load->controller('common/content_bottom');
402: $data['footer'] = $this->load->controller('common/footer');
403: $data['header'] = $this->load->controller('common/header');
404:
405: $this->response->setOutput($this->load->view('account/order_info', $data));
406:
407: return null;
408: } else {
409: return new \Opencart\System\Engine\Action('error/not_found');
410: }
411: }
412:
413: /**
414: * History
415: *
416: * @return void
417: */
418: public function history(): void {
419: $this->load->language('account/order');
420:
421: $this->response->setOutput($this->getHistory());
422: }
423:
424: /**
425: * Get History
426: *
427: * @return string
428: */
429: public function getHistory(): string {
430: if (isset($this->request->get['order_id'])) {
431: $order_id = (int)$this->request->get['order_id'];
432: } else {
433: $order_id = 0;
434: }
435:
436: if (isset($this->request->get['page']) && $this->request->get['route'] == 'account/order.history') {
437: $page = (int)$this->request->get['page'];
438: } else {
439: $page = 1;
440: }
441:
442: $limit = 10;
443:
444: $data['histories'] = [];
445:
446: $this->load->model('account/order');
447:
448: $results = $this->model_account_order->getHistories($order_id);
449:
450: foreach ($results as $result) {
451: $data['histories'][] = [
452: 'status' => $result['status'],
453: 'comment' => nl2br($result['comment']),
454: 'date_added' => date($this->language->get('date_format_short'), strtotime($result['date_added']))
455: ];
456: }
457:
458: $history_total = $this->model_account_order->getTotalHistories($order_id);
459:
460: $data['pagination'] = $this->load->controller('common/pagination', [
461: 'total' => $history_total,
462: 'page' => $page,
463: 'limit' => $limit,
464: 'url' => $this->url->link('account/order.history', 'customer_token=' . $this->session->data['customer_token'] . '&order_id=' . $order_id . '&page={page}')
465: ]);
466:
467: $data['results'] = sprintf($this->language->get('text_pagination'), ($history_total) ? (($page - 1) * $limit) + 1 : 0, ((($page - 1) * $limit) > ($history_total - $limit)) ? $history_total : ((($page - 1) * $limit) + $limit), $history_total, ceil($history_total / $limit));
468:
469: return $this->load->view('account/order_history', $data);
470: }
471:
472: /**
473: * Reorder
474: *
475: * @return void
476: */
477: public function reorder(): void {
478: $this->load->language('account/order');
479:
480: if (isset($this->request->get['order_id'])) {
481: $order_id = (int)$this->request->get['order_id'];
482: } else {
483: $order_id = 0;
484: }
485:
486: if (isset($this->request->get['order_product_id'])) {
487: $order_product_id = (int)$this->request->get['order_product_id'];
488: } else {
489: $order_product_id = 0;
490: }
491:
492: if (!$this->customer->isLogged() || (!isset($this->request->get['customer_token']) || !isset($this->session->data['customer_token']) || ($this->request->get['customer_token'] != $this->session->data['customer_token']))) {
493: $this->session->data['redirect'] = $this->url->link('account/order', 'language=' . $this->config->get('config_language'));
494:
495: $this->response->redirect($this->url->link('account/login', 'language=' . $this->config->get('config_language'), true));
496: }
497:
498: $this->load->model('account/order');
499:
500: $order_info = $this->model_account_order->getOrder($order_id);
501:
502: if ($order_info) {
503: $order_product_info = $this->model_account_order->getProduct($order_id, $order_product_id);
504:
505: if ($order_product_info) {
506: $this->load->model('catalog/product');
507:
508: $product_info = $this->model_catalog_product->getProduct($order_product_info['product_id']);
509:
510: if ($product_info) {
511: $option_data = [];
512:
513: $order_options = $this->model_account_order->getOptions($order_product_info['order_id'], $order_product_id);
514:
515: foreach ($order_options as $order_option) {
516: if ($order_option['type'] == 'select' || $order_option['type'] == 'radio' || $order_option['type'] == 'image') {
517: $option_data[$order_option['product_option_id']] = $order_option['product_option_value_id'];
518: } elseif ($order_option['type'] == 'checkbox') {
519: $option_data[$order_option['product_option_id']][] = $order_option['product_option_value_id'];
520: } elseif ($order_option['type'] == 'text' || $order_option['type'] == 'textarea' || $order_option['type'] == 'date' || $order_option['type'] == 'datetime' || $order_option['type'] == 'time') {
521: $option_data[$order_option['product_option_id']] = $order_option['value'];
522: } elseif ($order_option['type'] == 'file') {
523: $option_data[$order_option['product_option_id']] = $order_option['value'];
524: }
525: }
526:
527: $subscription_info = $this->model_account_order->getSubscription($order_product_info['order_id'], $order_product_id);
528:
529: if ($subscription_info) {
530: $subscription_id = $subscription_info['subscription_id'];
531: } else {
532: $subscription_id = 0;
533: }
534:
535: $this->cart->add($order_product_info['product_id'], $order_product_info['quantity'], $option_data, $subscription_id);
536:
537: $this->session->data['success'] = sprintf($this->language->get('text_success'), $this->url->link('product/product', 'language=' . $this->config->get('config_language') . '&product_id=' . $product_info['product_id']), $product_info['name'], $this->url->link('checkout/cart', 'language=' . $this->config->get('config_language')));
538:
539: unset($this->session->data['shipping_method']);
540: unset($this->session->data['shipping_methods']);
541: unset($this->session->data['payment_method']);
542: unset($this->session->data['payment_methods']);
543: } else {
544: $this->session->data['error'] = sprintf($this->language->get('error_reorder'), $order_product_info['name']);
545: }
546: }
547: }
548:
549: $this->response->redirect($this->url->link('account/order.info', 'language=' . $this->config->get('config_language') . '&customer_token=' . $this->session->data['customer_token'] . '&order_id=' . $order_id, true));
550: }
551: }
552: