1: <?php
2: namespace Opencart\Catalog\Model\Checkout;
3: /**
4: * Class Subscription
5: *
6: * @package Opencart\Catalog\Model\Checkout
7: */
8: class Subscription extends \Opencart\System\Engine\Model {
9: /**
10: * Add Subscription
11: *
12: * @param array<string, mixed> $data
13: *
14: * @return int
15: */
16: public function addSubscription(array $data): int {
17: if ($data['trial_status'] && $data['trial_duration']) {
18: $trial_remaining = $data['trial_duration'] - 1;
19: $remaining = $data['duration'];
20: } elseif ($data['duration']) {
21: $trial_remaining = $data['trial_duration'];
22: $remaining = $data['duration'] - 1;
23: } else {
24: $trial_remaining = $data['trial_duration'];
25: $remaining = $data['duration'];
26: }
27:
28: if ($data['trial_status'] && $data['trial_duration']) {
29: $date_next = date('Y-m-d', strtotime('+' . $data['trial_cycle'] . ' ' . $data['trial_frequency']));
30: } else {
31: $date_next = date('Y-m-d', strtotime('+' . $data['cycle'] . ' ' . $data['frequency']));
32: }
33:
34: $this->db->query("INSERT INTO `" . DB_PREFIX . "subscription` SET
35: `order_product_id` = '" . (int)$data['order_product_id'] . "',
36: `order_id` = '" . (int)$data['order_id'] . "',
37: `store_id` = '" . (int)$data['store_id'] . "',
38: `customer_id` = '" . (int)$data['customer_id'] . "',
39: `payment_address_id` = '" . (int)$data['payment_address_id'] . "',
40: `payment_method` = '" . $this->db->escape($data['payment_method'] ? json_encode($data['payment_method']) : '') . "',
41: `shipping_address_id` = '" . (int)$data['shipping_address_id'] . "',
42: `shipping_method` = '" . $this->db->escape($data['shipping_method'] ? json_encode($data['shipping_method']) : '') . "',
43: `product_id` = '" . (int)$data['product_id'] . "',
44: `option` = '" . $this->db->escape($data['option'] ? json_encode($data['option']) : '') . "',
45: `quantity` = '" . (int)$data['quantity'] . "',
46: `subscription_plan_id` = '" . (int)$data['subscription_plan_id'] . "',
47: `trial_price` = '" . (float)$data['trial_price'] . "',
48: `trial_frequency` = '" . $this->db->escape($data['trial_frequency']) . "',
49: `trial_cycle` = '" . (int)$data['trial_cycle'] . "',
50: `trial_duration` = '" . (int)$data['trial_duration'] . "',
51: `trial_remaining` = '" . (int)$trial_remaining . "',
52: `trial_status` = '" . (int)$data['trial_status'] . "',
53: `price` = '" . (float)$data['price'] . "',
54: `frequency` = '" . $this->db->escape($data['frequency']) . "',
55: `cycle` = '" . (int)$data['cycle'] . "',
56: `duration` = '" . (int)$data['duration'] . "',
57: `remaining` = '" . (int)$trial_remaining . "',
58: `date_next` = '" . $this->db->escape($date_next) . "',
59: `comment` = '" . $this->db->escape($data['comment']) . "',
60: `affiliate_id` = '" . (int)$data['affiliate_id'] . "',
61: `marketing_id` = '" . (int)$data['marketing_id'] . "',
62: `tracking` = '" . $this->db->escape($data['tracking']) . "',
63: `language_id` = '" . (int)$data['language_id'] . "',
64: `currency_id` = '" . (int)$data['currency_id'] . "',
65: `ip` = '" . $this->db->escape($data['ip']) . "',
66: `forwarded_ip` = '" . $this->db->escape($data['forwarded_ip']) . "',
67: `user_agent` = '" . $this->db->escape($data['user_agent']) . "',
68: `accept_language` = '" . $this->db->escape($data['accept_language']) . "',
69: `date_added` = NOW(),
70: `date_modified` = NOW()
71: ");
72:
73: return $this->db->getLastId();
74: }
75:
76: /**
77: * Edit Subscription
78: *
79: * @param int $subscription_id
80: * @param array<string, mixed> $data
81: *
82: * @return void
83: */
84: public function editSubscription(int $subscription_id, array $data): void {
85: if ($data['trial_status'] && $data['trial_duration']) {
86: $trial_remaining = $data['trial_duration'] - 1;
87: $remaining = $data['duration'];
88: } elseif ($data['duration']) {
89: $trial_remaining = $data['trial_duration'];
90: $remaining = $data['duration'] - 1;
91: } else {
92: $trial_remaining = $data['trial_duration'];
93: $remaining = $data['duration'];
94: }
95:
96: if ($data['trial_status'] && $data['trial_duration']) {
97: $date_next = date('Y-m-d', strtotime('+' . $data['trial_cycle'] . ' ' . $data['trial_frequency']));
98: } else {
99: $date_next = date('Y-m-d', strtotime('+' . $data['cycle'] . ' ' . $data['frequency']));
100: }
101:
102: $this->db->query("UPDATE `" . DB_PREFIX . "subscription` SET
103: `order_id` = '" . (int)$data['order_id'] . "',
104: `order_product_id` = '" . (int)$data['order_product_id'] . "',
105: `store_id` = '" . (int)$data['store_id'] . "',
106: `customer_id` = '" . (int)$data['customer_id'] . "',
107: `payment_address_id` = '" . (int)$data['payment_address_id'] . "',
108: `payment_method` = '" . $this->db->escape($data['payment_method'] ? json_encode($data['payment_method']) : '') . "',
109: `shipping_address_id` = '" . (int)$data['shipping_address_id'] . "',
110: `shipping_method` = '" . $this->db->escape($data['shipping_method'] ? json_encode($data['shipping_method']) : '') . "',
111: `product_id` = '" . (int)$data['product_id'] . "',
112: `option` = '" . $this->db->escape($data['option'] ? json_encode($data['option']) : '') . "',
113: `quantity` = '" . (int)$data['quantity'] . "',
114: `subscription_plan_id` = '" . (int)$data['subscription_plan_id'] . "',
115: `trial_price` = '" . (float)$data['trial_price'] . "',
116: `trial_frequency` = '" . $this->db->escape($data['trial_frequency']) . "',
117: `trial_cycle` = '" . (int)$data['trial_cycle'] . "',
118: `trial_duration` = '" . (int)$data['trial_duration'] . "',
119: `trial_remaining` = '" . (int)$trial_remaining . "',
120: `trial_status` = '" . (int)$data['trial_status'] . "',
121: `price` = '" . (float)$data['price'] . "',
122: `frequency` = '" . $this->db->escape($data['frequency']) . "',
123: `cycle` = '" . (int)$data['cycle'] . "',
124: `duration` = '" . (int)$data['duration'] . "',
125: `remaining` = '" . (int)$remaining . "',
126: `date_next` = '" . $this->db->escape($date_next) . "',
127: `comment` = '" . $this->db->escape($data['comment']) . "',
128: `affiliate_id` = '" . (int)$data['affiliate_id'] . "',
129: `marketing_id` = '" . (int)$data['marketing_id'] . "',
130: `tracking` = '" . $this->db->escape($data['tracking']) . "',
131: `language_id` = '" . (int)$data['language_id'] . "',
132: `currency_id` = '" . (int)$data['currency_id'] . "',
133: `ip` = '" . $this->db->escape($data['ip']) . "',
134: `forwarded_ip` = '" . $this->db->escape($data['forwarded_ip']) . "',
135: `user_agent` = '" . $this->db->escape($data['user_agent']) . "',
136: `accept_language` = '" . $this->db->escape($data['accept_language']) . "',
137: `date_modified` = NOW()
138: WHERE `subscription_id` = '" . (int)$subscription_id . "'
139: ");
140: }
141:
142: /**
143: * Delete Subscription By Order ID
144: *
145: * @param int $order_id
146: *
147: * @return void
148: */
149: public function deleteSubscriptionByOrderId(int $order_id): void {
150: $this->db->query("DELETE FROM `" . DB_PREFIX . "subscription` WHERE `order_id` = '" . (int)$order_id . "'");
151: }
152:
153: /**
154: * Get Subscription By Order Product ID
155: *
156: * @param int $order_id
157: * @param int $order_product_id
158: *
159: * @return array<string, mixed>
160: */
161: public function getSubscriptionByOrderProductId(int $order_id, int $order_product_id): array {
162: $subscription_data = [];
163:
164: $query = $this->db->query("SELECT * FROM `" . DB_PREFIX . "subscription` WHERE `order_id` = '" . (int)$order_id . "' AND `order_product_id` = '" . (int)$order_product_id . "'");
165:
166: if ($query->num_rows) {
167: $subscription_data = $query->row;
168:
169: $subscription_data['option'] = ($query->row['option'] ? json_decode($query->row['option'], true) : '');
170: $subscription_data['payment_method'] = ($query->row['payment_method'] ? json_decode($query->row['payment_method'], true) : '');
171: $subscription_data['shipping_method'] = ($query->row['shipping_method'] ? json_decode($query->row['shipping_method'], true) : '');
172: }
173:
174: return $subscription_data;
175: }
176:
177: /**
178: * Add History
179: *
180: * @param int $subscription_id
181: * @param int $subscription_status_id
182: * @param string $comment
183: * @param bool $notify
184: *
185: * @return void
186: */
187: public function addHistory(int $subscription_id, int $subscription_status_id, string $comment = '', bool $notify = false): void {
188: $this->db->query("INSERT INTO `" . DB_PREFIX . "subscription_history` SET `subscription_id` = '" . (int)$subscription_id . "', `subscription_status_id` = '" . (int)$subscription_status_id . "', `comment` = '" . $this->db->escape($comment) . "', `notify` = '" . (int)$notify . "', `date_added` = NOW()");
189:
190: $this->db->query("UPDATE `" . DB_PREFIX . "subscription` SET `subscription_status_id` = '" . (int)$subscription_status_id . "' WHERE `subscription_id` = '" . (int)$subscription_id . "'");
191: }
192:
193: /**
194: * Edit Subscription Status
195: *
196: * @param int $subscription_id
197: * @param bool $subscription_status_id
198: *
199: * @return void
200: */
201: public function editSubscriptionStatus(int $subscription_id, bool $subscription_status_id): void {
202: $this->db->query("UPDATE `" . DB_PREFIX . "subscription` SET `subscription_status_id` = '" . (int)$subscription_status_id . "' WHERE `subscription_id` = '" . (int)$subscription_id . "'");
203: }
204:
205: /**
206: * Edit Trial Remaining
207: *
208: * @param int $subscription_id
209: * @param int $trial_remaining
210: *
211: * @return void
212: */
213: public function editTrialRemaining(int $subscription_id, int $trial_remaining): void {
214: $this->db->query("UPDATE `" . DB_PREFIX . "subscription` SET `trial_remaining` = '" . (int)$trial_remaining . "' WHERE `subscription_id` = '" . (int)$subscription_id . "'");
215: }
216:
217: /**
218: * Edit Date Next
219: *
220: * @param int $subscription_id
221: * @param string $date_next
222: *
223: * @return void
224: */
225: public function editDateNext(int $subscription_id, string $date_next): void {
226: $this->db->query("UPDATE `" . DB_PREFIX . "subscription` SET `date_next` = '" . $this->db->escape($date_next) . "' WHERE `subscription_id` = '" . (int)$subscription_id . "'");
227: }
228:
229: /**
230: * Get Subscriptions
231: *
232: * @param array<string, mixed> $data
233: *
234: * @return array<int, array<string, mixed>>
235: */
236: public function getSubscriptions(array $data): array {
237: $sql = "SELECT `s`.`subscription_id`, `s`.*, CONCAT(`o`.`firstname`, ' ', `o`.`lastname`) AS `customer`, (SELECT `ss`.`name` FROM `" . DB_PREFIX . "subscription_status` `ss` WHERE `ss`.`subscription_status_id` = `s`.`subscription_status_id` AND `ss`.`language_id` = '" . (int)$this->config->get('config_language_id') . "') AS `subscription_status` FROM `" . DB_PREFIX . "subscription` `s` LEFT JOIN `" . DB_PREFIX . "order` `o` ON (`s`.`order_id` = `o`.`order_id`)";
238:
239: $implode = [];
240:
241: if (!empty($data['filter_subscription_id'])) {
242: $implode[] = "`s`.`subscription_id` = '" . (int)$data['filter_subscription_id'] . "'";
243: }
244:
245: if (!empty($data['filter_order_id'])) {
246: $implode[] = "`s`.`order_id` = '" . (int)$data['filter_order_id'] . "'";
247: }
248:
249: if (!empty($data['filter_order_product_id'])) {
250: $implode[] = "`s`.`order_product_id` = '" . (int)$data['filter_order_product_id'] . "'";
251: }
252:
253: if (!empty($data['filter_customer'])) {
254: $implode[] = "CONCAT(`o`.`firstname`, ' ', `o`.`lastname`) LIKE '" . $this->db->escape($data['filter_customer'] . '%') . "'";
255: }
256:
257: if (!empty($data['filter_date_next'])) {
258: $implode[] = "DATE(`s`.`date_next`) = DATE('" . $this->db->escape($data['filter_date_next']) . "')";
259: }
260:
261: if (!empty($data['filter_subscription_status_id'])) {
262: $implode[] = "`s`.`subscription_status_id` = '" . (int)$data['filter_subscription_status_id'] . "'";
263: }
264:
265: if (!empty($data['filter_date_from'])) {
266: $implode[] = "DATE(`s`.`date_added`) >= DATE('" . $this->db->escape($data['filter_date_from']) . "')";
267: }
268:
269: if (!empty($data['filter_date_to'])) {
270: $implode[] = "DATE(`s`.`date_added`) <= DATE('" . $this->db->escape($data['filter_date_to']) . "')";
271: }
272:
273: if ($implode) {
274: $sql .= " WHERE " . implode(" AND ", $implode);
275: }
276:
277: $sort_data = [
278: 's.subscription_id',
279: 's.order_id',
280: 's.reference',
281: 'customer',
282: 's.subscription_status',
283: 's.date_added'
284: ];
285:
286: if (isset($data['sort']) && in_array($data['sort'], $sort_data)) {
287: $sql .= " ORDER BY " . $data['sort'];
288: } else {
289: $sql .= " ORDER BY `s`.`subscription_id`";
290: }
291:
292: if (isset($data['order']) && ($data['order'] == 'DESC')) {
293: $sql .= " DESC";
294: } else {
295: $sql .= " ASC";
296: }
297:
298: if (isset($data['start']) || isset($data['limit'])) {
299: if ($data['start'] < 0) {
300: $data['start'] = 0;
301: }
302:
303: if ($data['limit'] < 1) {
304: $data['limit'] = 20;
305: }
306:
307: $sql .= " LIMIT " . (int)$data['start'] . "," . (int)$data['limit'];
308: }
309:
310: $query = $this->db->query($sql);
311:
312: return $query->rows;
313: }
314: }
315: