1: <?php
2: namespace Opencart\Catalog\Model\Extension\Opencart\Total;
3: /**
4: * Class Coupon
5: *
6: * @package Opencart\Catalog\Model\Extension\Opencart\Total
7: */
8: class Coupon extends \Opencart\System\Engine\Model {
9: /**
10: * Get Total
11: *
12: * @param array<int, array<string, mixed>> $totals
13: * @param array<int, float> $taxes
14: * @param float $total
15: *
16: * @return void
17: */
18: public function getTotal(array &$totals, array &$taxes, float &$total): void {
19: if (isset($this->session->data['coupon'])) {
20: $this->load->language('extension/opencart/total/coupon', 'coupon');
21:
22: $this->load->model('marketing/coupon');
23:
24: $coupon_info = $this->model_marketing_coupon->getCoupon($this->session->data['coupon']);
25:
26: if ($coupon_info) {
27: $discount_total = 0;
28:
29: $products = $this->cart->getProducts();
30:
31: if (!$coupon_info['product']) {
32: $sub_total = $this->cart->getSubTotal();
33: } else {
34: $sub_total = 0;
35:
36: foreach ($products as $product) {
37: if (in_array($product['product_id'], $coupon_info['product'])) {
38: $sub_total += $product['total'];
39: }
40: }
41: }
42:
43: if ($coupon_info['type'] == 'F') {
44: $coupon_info['discount'] = min($coupon_info['discount'], $sub_total);
45: }
46:
47: foreach ($products as $product) {
48: $discount = 0;
49:
50: if (!$coupon_info['product']) {
51: $status = true;
52: } else {
53: $status = in_array($product['product_id'], $coupon_info['product']);
54: }
55:
56: if ($status) {
57: if ($coupon_info['type'] == 'F') {
58: $discount = $coupon_info['discount'] * ($product['total'] / $sub_total);
59: } elseif ($coupon_info['type'] == 'P') {
60: $discount = $product['total'] / 100 * $coupon_info['discount'];
61: }
62:
63: if ($product['tax_class_id']) {
64: $tax_rates = $this->tax->getRates($product['total'] - ($product['total'] - $discount), $product['tax_class_id']);
65:
66: foreach ($tax_rates as $tax_rate) {
67: if ($tax_rate['type'] == 'P') {
68: $taxes[$tax_rate['tax_rate_id']] -= $tax_rate['amount'];
69: }
70: }
71: }
72: }
73:
74: $discount_total += $discount;
75: }
76:
77: if ($coupon_info['shipping'] && isset($this->session->data['shipping_method']['cost']) && isset($this->session->data['shipping_method']['tax_class_id'])) {
78: if (!empty($this->session->data['shipping_method']['tax_class_id'])) {
79: $tax_rates = $this->tax->getRates($this->session->data['shipping_method']['cost'], $this->session->data['shipping_method']['tax_class_id']);
80:
81: foreach ($tax_rates as $tax_rate) {
82: if ($tax_rate['type'] == 'P') {
83: $taxes[$tax_rate['tax_rate_id']] -= $tax_rate['amount'];
84: }
85: }
86: }
87:
88: $discount_total += $this->session->data['shipping_method']['cost'];
89: }
90:
91: // If discount greater than total
92: if ($discount_total > $total) {
93: $discount_total = $total;
94: }
95:
96: if ($discount_total > 0) {
97: $totals[] = [
98: 'extension' => 'opencart',
99: 'code' => 'coupon',
100: 'title' => sprintf($this->language->get('coupon_text_coupon'), $this->session->data['coupon']),
101: 'value' => -$discount_total,
102: 'sort_order' => (int)$this->config->get('total_coupon_sort_order')
103: ];
104:
105: $total -= $discount_total;
106: }
107: }
108: }
109: }
110:
111: /**
112: * Confirm
113: *
114: * @param array<string, mixed> $order_info
115: * @param array<string, mixed> $order_total
116: *
117: * @return int
118: */
119: public function confirm(array $order_info, array $order_total): int {
120: $code = '';
121:
122: $start = strpos($order_total['title'], '(');
123: $end = strrpos($order_total['title'], ')');
124:
125: if ($start !== false && $end !== false) {
126: $code = substr($order_total['title'], $start + 1, $end - ($start + 1));
127: }
128:
129: if ($code) {
130: $this->load->model('marketing/coupon');
131:
132: $status = true;
133:
134: $coupon_info = $this->model_marketing_coupon->getCouponByCode($code);
135:
136: if ($coupon_info) {
137: $coupon_total = $this->model_marketing_coupon->getTotalHistories($coupon_info['coupon_id']);
138:
139: if ($coupon_info['uses_total'] > 0 && ($coupon_total >= $coupon_info['uses_total'])) {
140: $status = false;
141: }
142:
143: if ($order_info['customer_id']) {
144: $customer_total = $this->model_marketing_coupon->getTotalHistoriesByCustomerId($coupon_info['coupon_id'], $order_info['customer_id']);
145:
146: if ($coupon_info['uses_customer'] > 0 && ($customer_total >= $coupon_info['uses_customer'])) {
147: $status = false;
148: }
149: }
150: } else {
151: $status = false;
152: }
153:
154: if ($status) {
155: $this->model_marketing_coupon->addHistory($coupon_info['coupon_id'], $order_info['order_id'], $order_info['customer_id'], $order_total['value']);
156: } else {
157: return $this->config->get('config_fraud_status_id');
158: }
159: }
160:
161: return 0;
162: }
163:
164: /**
165: * Unconfirm
166: *
167: * @param array<string, mixed> $order_info
168: *
169: * @return void
170: */
171: public function unconfirm(array $order_info): void {
172: $this->load->model('marketing/coupon');
173:
174: $this->model_marketing_coupon->deleteHistoryByOrderId($order_info['order_id']);
175: }
176: }
177: