load->model('checkout/subscription'); * * @package Opencart\Catalog\Model\Checkout */ class Subscription extends \Opencart\System\Engine\Model { /** * Add Subscription * * Create a new subscription record in the database. * * @param array $data array of data * * @return int returns the primary key of the new subscription record * * @example * * $subscription_data = [ * 'order_id' => 1, * 'store_id' => 1, * 'customer_id' => 1, * 'payment_address_id' => 1, * 'payment_method' => [ * 'name' => 'Payment Name', * 'code' => 'Payment Code' * ], * 'shipping_address_id' => 1, * 'shipping_method' => [ * 'name' => 'Shipping Name', * 'code' => 'Shipping Code' * ], * 'subscription_plan_id' => 1, * 'trial_price' => 0.0000, * 'trial_frequency' => 'month', * 'trial_cycle' => 5, * 'trial_duration' => 1, * 'trial_status' => 1, * 'price' => 0.0000, * 'frequency' => 'month', * 'cycle' => 5, * 'duration' => 1, * 'comment' => '', * 'affiliate_id' => 1, * 'marketing_id' => 1, * 'tracking' => '', * 'language_id' => 1, * 'currency_id' => 1 * ]; * * $this->load->model('checkout/subscription'); * * $subscription_id = $this->model_checkout_subscription->addSubscription($subscription_data); */ public function addSubscription(array $data): int { if ($data['trial_status'] && $data['trial_duration']) { $trial_remaining = $data['trial_duration'] - 1; $remaining = $data['duration']; } elseif ($data['duration']) { $trial_remaining = 0; $remaining = $data['duration'] - 1; } else { $trial_remaining = 0; $remaining = 0; } if ($data['trial_status'] && $data['trial_duration']) { $date_next = date('Y-m-d', strtotime('+' . $data['trial_cycle'] . ' ' . $data['trial_frequency'])); } else { $date_next = date('Y-m-d', strtotime('+' . $data['cycle'] . ' ' . $data['frequency'])); } $this->db->query("INSERT INTO `" . DB_PREFIX . "subscription` SET `order_id` = '" . (isset($data['order_id']) ? (int)$data['order_id'] : 0) . "', `store_id` = '" . (int)$data['store_id'] . "', `customer_id` = '" . (int)$data['customer_id'] . "', `payment_address_id` = '" . (int)$data['payment_address_id'] . "', `payment_method` = '" . $this->db->escape($data['payment_method'] ? json_encode($data['payment_method']) : '') . "', `shipping_address_id` = '" . (int)$data['shipping_address_id'] . "', `shipping_method` = '" . $this->db->escape($data['shipping_method'] ? json_encode($data['shipping_method']) : '') . "', `subscription_plan_id` = '" . (int)$data['subscription_plan_id'] . "', `trial_price` = '" . (float)$data['trial_price'] . "', `trial_tax` = '" . (float)$data['trial_tax'] . "', `trial_frequency` = '" . $this->db->escape($data['trial_frequency']) . "', `trial_cycle` = '" . (int)$data['trial_cycle'] . "', `trial_duration` = '" . (int)$data['trial_duration'] . "', `trial_remaining` = '" . (int)$trial_remaining . "', `trial_status` = '" . (int)$data['trial_status'] . "', `price` = '" . (float)$data['price'] . "', `tax` = '" . (float)$data['tax'] . "', `frequency` = '" . $this->db->escape($data['frequency']) . "', `cycle` = '" . (int)$data['cycle'] . "', `duration` = '" . (int)$data['duration'] . "', `remaining` = '" . (int)$remaining . "', `date_next` = '" . $this->db->escape($date_next) . "', `comment` = '" . $this->db->escape($data['comment']) . "', `language` = '" . $this->db->escape($data['language']) . "', `currency` = '" . $this->db->escape($data['currency']) . "', `date_added` = NOW(), `date_modified` = NOW()"); $subscription_id = $this->db->getLastId(); foreach ($data['subscription_product'] as $subscription_product) { $this->addProduct($subscription_id, $subscription_product); } return $subscription_id; } /** * Edit Subscription * * Edit subscription record in the database. * * @param int $subscription_id primary key of the subscription record * @param array $data array of data * * @return void * * @example * * $subscription_data = [ * 'order_id' => 1, * 'store_id' => 1, * 'customer_id' => 1, * 'payment_address_id' => 1, * 'payment_method' => [ * 'name' => 'Payment Name', * 'code' => 'Payment Code' * ], * 'shipping_address_id' => 1, * 'shipping_method' => [ * 'name' => 'Shipping Name', * 'code' => 'Shipping Code' * ], * 'subscription_plan_id' => 1, * 'trial_price' => 0.0000, * 'trial_frequency' => 'month', * 'trial_cycle' => 5, * 'trial_duration' => 1, * 'trial_status' => 1, * 'price' => 0.0000, * 'frequency' => 'month', * 'cycle' => 5, * 'duration' => 1, * 'comment' => '', * 'affiliate_id' => 1, * 'marketing_id' => 1, * 'tracking' => '', * 'language_id' => 1, * 'currency_id' => 1 * ]; * * $this->load->model('checkout/subscription'); * * $this->model_checkout_subscription->addSubscription($subscription_id, $subscription_data); */ public function editSubscription(int $subscription_id, array $data): void { if ($data['trial_status'] && $data['trial_duration']) { $trial_remaining = $data['trial_duration'] - 1; $remaining = $data['duration']; } elseif ($data['duration']) { $trial_remaining = 0; $remaining = $data['duration'] - 1; } else { $trial_remaining = 0; $remaining = 0; } if ($data['trial_status'] && $data['trial_duration']) { $date_next = date('Y-m-d', strtotime('+' . $data['trial_cycle'] . ' ' . $data['trial_frequency'])); } else { $date_next = date('Y-m-d', strtotime('+' . $data['cycle'] . ' ' . $data['frequency'])); } $this->db->query("UPDATE `" . DB_PREFIX . "subscription` SET `order_id` = '" . (isset($data['order_id']) ? (int)$data['order_id'] : 0) . "', `store_id` = '" . (int)$data['store_id'] . "', `customer_id` = '" . (int)$data['customer_id'] . "', `payment_address_id` = '" . (int)$data['payment_address_id'] . "', `payment_method` = '" . $this->db->escape($data['payment_method'] ? json_encode($data['payment_method']) : '') . "', `shipping_address_id` = '" . (int)$data['shipping_address_id'] . "', `shipping_method` = '" . $this->db->escape($data['shipping_method'] ? json_encode($data['shipping_method']) : '') . "', `subscription_plan_id` = '" . (int)$data['subscription_plan_id'] . "', `trial_price` = '" . (float)$data['trial_price'] . "', `trial_tax` = '" . (float)$data['trial_tax'] . "', `trial_frequency` = '" . $this->db->escape($data['trial_frequency']) . "', `trial_cycle` = '" . (int)$data['trial_cycle'] . "', `trial_duration` = '" . (int)$data['trial_duration'] . "', `trial_remaining` = '" . (int)$trial_remaining . "',`trial_status` = '" . (int)$data['trial_status'] . "', `price` = '" . (float)$data['price'] . "', `tax` = '" . (float)$data['tax'] . "', `frequency` = '" . $this->db->escape($data['frequency']) . "', `cycle` = '" . (int)$data['cycle'] . "', `duration` = '" . (int)$data['duration'] . "', `remaining` = '" . (int)$remaining . "', `date_next` = '" . $this->db->escape($date_next) . "', `comment` = '" . $this->db->escape($data['comment']) . "', `language` = '" . $this->db->escape($data['language']) . "', `currency` = '" . $this->db->escape($data['currency']) . "', `date_modified` = NOW() WHERE `subscription_id` = '" . (int)$subscription_id . "'"); $this->deleteProducts($subscription_id); foreach ($data['subscription_product'] as $subscription_product) { $this->addProduct($subscription_id, $subscription_product); } } /** * Edit Subscription Status * * Edit subscription status record in the database. * * @param int $subscription_id primary key of the subscription record * @param bool $subscription_status_id primary key of the subscription status record * * @return void * * @example * * $this->load->model('checkout/subscription'); * * $this->model_checkout_subscription->editSubscriptionStatus($subscription_id, $subscription_status_id); */ public function editSubscriptionStatus(int $subscription_id, bool $subscription_status_id): void { $this->db->query("UPDATE `" . DB_PREFIX . "subscription` SET `subscription_status_id` = '" . (int)$subscription_status_id . "' WHERE `subscription_id` = '" . (int)$subscription_id . "'"); } /** * Edit Remaining * * Edit subscription remaining record in the database. * * @param int $subscription_id primary key of the subscription record * @param int $remaining * * @return void * * @example * * $this->load->model('checkout/subscription'); * * $this->model_checkout_subscription->editRemaining($subscription_id, $remaining); */ public function editRemaining(int $subscription_id, int $remaining): void { $this->db->query("UPDATE `" . DB_PREFIX . "subscription` SET `remaining` = '" . (int)$remaining . "' WHERE `subscription_id` = '" . (int)$subscription_id . "'"); } /** * Edit Trial Remaining * * Edit subscription trial remaining record in the database. * * @param int $subscription_id primary key of the subscription record * @param int $trial_remaining * * @return void * * @example * * $this->load->model('checkout/subscription'); * * $this->model_checkout_subscription->editTrialRemaining($subscription_id, $trial_remaining); */ public function editTrialRemaining(int $subscription_id, int $trial_remaining): void { $this->db->query("UPDATE `" . DB_PREFIX . "subscription` SET `trial_remaining` = '" . (int)$trial_remaining . "' WHERE `subscription_id` = '" . (int)$subscription_id . "'"); } /** * Edit Date Next * * Edit date next record in the database. * * @param int $subscription_id primary key of the subscription record * @param string $date_next * * @return void * * @example * * $this->load->model('checkout/subscription'); * * $this->model_checkout_subscription->editDateNext($subscription_id, $date_next); */ public function editDateNext(int $subscription_id, string $date_next): void { $this->db->query("UPDATE `" . DB_PREFIX . "subscription` SET `date_next` = '" . $this->db->escape($date_next) . "' WHERE `subscription_id` = '" . (int)$subscription_id . "'"); } /** * Delete Subscription By Order ID * * Delete subscription by order record in the database. * * @param int $order_id primary key of the order record * * @return void * * @example * * $this->load->model('checkout/subscription'); * * $this->model_checkout_subscription->deleteSubscriptionByOrderId($order_id); */ public function deleteSubscriptionByOrderId(int $order_id): void { $this->db->query("DELETE FROM `" . DB_PREFIX . "subscription` WHERE `order_id` = '" . (int)$order_id . "'"); } /** * Get Subscription * * Get the record of the subscription record in the database. * * @param int $subscription_id primary key of the subscription record * * @return array subscription record that has subscription ID * * @example * * $this->load->model('checkout/subscription'); * * $subscription_info = $this->model_checkout_subscription->getSubscription($subscription_id); */ public function getSubscription(int $subscription_id): array { $query = $this->db->query("SELECT * FROM `" . DB_PREFIX . "subscription` WHERE `subscription_id` = '" . (int)$subscription_id . "'"); if ($query->num_rows) { return [ 'payment_method' => $query->row['payment_method'] ? json_decode($query->row['payment_method'], true) : [], 'shipping_method' => $query->row['shipping_method'] ? json_decode($query->row['shipping_method'], true) : [] ] + $query->row; } return []; } /** * Get Subscriptions * * Get the record of the subscription records in the database. * * @param array $data array of filters * * @return array> subscription records * * @example * * $this->load->model('checkout/subscription'); * * $subscriptions = $this->model_checkout_subscription->getSubscriptions(); */ public function getSubscriptions(array $data): array { $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`)"; $implode = []; if (!empty($data['filter_subscription_id'])) { $implode[] = "`s`.`subscription_id` = '" . (int)$data['filter_subscription_id'] . "'"; } if (!empty($data['filter_order_id'])) { $implode[] = "`s`.`order_id` = '" . (int)$data['filter_order_id'] . "'"; } if (!empty($data['filter_order_product_id'])) { $implode[] = "`s`.`order_product_id` = '" . (int)$data['filter_order_product_id'] . "'"; } if (!empty($data['filter_customer'])) { $implode[] = "CONCAT(`o`.`firstname`, ' ', `o`.`lastname`) LIKE '" . $this->db->escape($data['filter_customer'] . '%') . "'"; } if (!empty($data['filter_date_next'])) { $implode[] = "DATE(`s`.`date_next`) = DATE('" . $this->db->escape($data['filter_date_next']) . "')"; } if (!empty($data['filter_subscription_status_id'])) { $implode[] = "`s`.`subscription_status_id` = '" . (int)$data['filter_subscription_status_id'] . "'"; } if (!empty($data['filter_date_from'])) { $implode[] = "DATE(`s`.`date_added`) >= DATE('" . $this->db->escape($data['filter_date_from']) . "')"; } if (!empty($data['filter_date_to'])) { $implode[] = "DATE(`s`.`date_added`) <= DATE('" . $this->db->escape($data['filter_date_to']) . "')"; } if ($implode) { $sql .= " WHERE " . implode(" AND ", $implode); } $sort_data = [ 's.subscription_id', 's.order_id', 's.reference', 'customer', 's.subscription_status', 's.date_added' ]; if (isset($data['sort']) && in_array($data['sort'], $sort_data)) { $sql .= " ORDER BY " . $data['sort']; } else { $sql .= " ORDER BY `s`.`subscription_id`"; } if (isset($data['order']) && ($data['order'] == 'DESC')) { $sql .= " DESC"; } else { $sql .= " ASC"; } if (isset($data['start']) || isset($data['limit'])) { if ($data['start'] < 0) { $data['start'] = 0; } if ($data['limit'] < 1) { $data['limit'] = 20; } $sql .= " LIMIT " . (int)$data['start'] . "," . (int)$data['limit']; } $order_data = []; $query = $this->db->query($sql); foreach ($query->rows as $key => $result) { $order_data[$key] = [ 'payment_method' => $result['payment_method'] ? json_decode($result['payment_method'], true) : [], 'shipping_method' => $result['shipping_method'] ? json_decode($result['shipping_method'], true) : [] ] + $result; } return $order_data; } /** * Add Product * * Create a new subscription product record in the database. * * @param int $subscription_id primary key of the subscription record * @param array $data array of data * * @return int returns the primary key of the new subscription product record * * @example * * $subscription_product_data = [ * 'order_id' => 1, * 'order_product_id' => 1, * 'product_id' => 1, * 'name' => 'Product Name', * 'model' => 'Product Model', * 'quantity' => 1, * 'trial_price' => 0.0000, * 'price' => 0.0000 * ]; * * $this->load->model('checkout/subscription'); * * $this->model_checkout_subscription->addProduct($subscription_id, $subscription_product_data); */ public function addProduct(int $subscription_id, array $data): int { $this->db->query("INSERT INTO `" . DB_PREFIX . "subscription_product` SET `subscription_id` = '" . (int)$subscription_id . "', `order_id` = '" . (int)$data['order_id'] . "', `order_product_id` = '" . (int)$data['order_product_id'] . "', `product_id` = '" . (int)$data['product_id'] . "', `name` = '" . $this->db->escape($data['name']) . "', `model` = '" . $this->db->escape($data['model']) . "', `quantity` = '" . (int)$data['quantity'] . "', `trial_price` = '" . (float)$data['trial_price'] . "', `price` = '" . (float)$data['price'] . "'"); $subscription_product_id = $this->db->getLastId(); if ($data['option']) { foreach ($data['option'] as $option) { $this->model_checkout_subscription->addOption($subscription_id, $subscription_product_id, $option); } } return $subscription_product_id; } /** * Delete Subscription Products * * Delete subscription product records in the database. * * @param int $subscription_id primary key of the subscription record * * @return void * * @example * * $this->load->model('checkout/subscription'); * * $this->model_checkout_subscription->deleteProducts($subscription_id); */ public function deleteProducts(int $subscription_id): void { $this->db->query("DELETE FROM `" . DB_PREFIX . "subscription_product` WHERE `subscription_id` = '" . (int)$subscription_id . "'"); $this->deleteOptions($subscription_id); } /** * Get Products * * Get the record of the subscription product records in the database. * * @param int $subscription_id primary key of the subscription record * * @return array product records that have subscription ID * * @example * * $this->load->model('checkout/subscription'); * * $products = $this->model_checkout_subscription->getProducts($subscription_id); */ public function getProducts(int $subscription_id): array { $query = $this->db->query("SELECT * FROM `" . DB_PREFIX . "subscription_product` WHERE `subscription_id` = '" . (int)$subscription_id . "'"); return $query->rows; } /** * Get Product By Order Product ID * * Get the record of the subscription products by order product records in the database. * * @param int $order_id primary key of the order record * @param int $order_product_id primary key of the order product record * * @return array product record that has order ID, order product ID * * @example * * $this->load->model('checkout/subscription'); * * $subscription_product_info = $this->model_checkout_subscription->getProductByOrderProductId($order_id, $order_product_id); */ public function getProductByOrderProductId(int $order_id, int $order_product_id): array { $query = $this->db->query("SELECT * FROM `" . DB_PREFIX . "subscription_product` WHERE `order_id` = '" . (int)$order_id . "' AND `order_product_id` = '" . (int)$order_product_id . "'"); return $query->row; } /** * Add Option * * Create a new subscription option record in the database. * * @param int $subscription_id primary key of the subscription record * @param int $subscription_product_id primary key of the subscription product record * @param array $data array of data * * @return void * * @example * * $subscription_option_data = [ * 'product_option_id' => 1, * 'product_option_value_id' => 1, * 'name' => 'Option Name', * 'value' => 'Option Value', * 'type' => 'radio' * ]; * * $this->load->model('checkout/subscription'); * * $this->model_checkout_subscription->addOtion($subscription_id, $subscription_product_id, $subscription_option_data); */ public function addOption(int $subscription_id, int $subscription_product_id, array $data): void { $this->db->query("INSERT INTO `" . DB_PREFIX . "subscription_option` SET `subscription_id` = '" . (int)$subscription_id . "', `subscription_product_id` = '" . (int)$subscription_product_id . "', `product_option_id` = '" . (int)$data['product_option_id'] . "', `product_option_value_id` = '" . (int)$data['product_option_value_id'] . "', `name` = '" . $this->db->escape($data['name']) . "', `value` = '" . $this->db->escape($data['value']) . "', `type` = '" . $this->db->escape($data['type']) . "'"); } /** * Delete Options * * Delete subscription option records in the database. * * @param int $subscription_id primary key of the subscription record * * @return void * * @example * * $this->load->model('checkout/subscription'); * * $this->model_checkout_subscription->deleteOptions($subscription_id); */ public function deleteOptions(int $subscription_id): void { $this->db->query("DELETE FROM `" . DB_PREFIX . "subscription_option` WHERE `subscription_id` = '" . (int)$subscription_id . "'"); } /** * Get Option * * Get the record of the subscription option record in the database. * * @param int $subscription_id primary key of the subscription record * @param int $subscription_product_id primary key of the subscription product record * @param int $product_option_id primary key of the product option record * * @return array option record that has subscription ID, subscription product ID, product option ID * * @example * * $this->load->model('checkout/subscription'); * * $option = $this->model_checkout_subscription->getOption($subscription_id, $subscription_product_id, $product_option_id); */ public function getOption(int $subscription_id, int $subscription_product_id, int $product_option_id): array { $query = $this->db->query("SELECT * FROM `" . DB_PREFIX . "subscription_option` WHERE `subscription_id` = '" . (int)$subscription_id . "' AND `subscription_product_id` = '" . (int)$subscription_product_id . "' AND `product_option_id` = '" . (int)$product_option_id . "'"); return $query->row; } /** * Get Options * * Get the record of the subscription option records in the database. * * @param int $subscription_id primary key of the subscription record * @param int $subscription_product_id primary key of the subscription product record * * @return array> option records that have subscription ID, subscription product ID * * @example * * $this->load->model('checkout/subscription'); * * $options = $this->model_checkout_subscription->getOptions($subscription_id, $subscription_product_id); */ public function getOptions(int $subscription_id, int $subscription_product_id): array { $query = $this->db->query("SELECT * FROM `" . DB_PREFIX . "subscription_option` WHERE `subscription_id` = '" . (int)$subscription_id . "' AND `subscription_product_id` = '" . (int)$subscription_product_id . "'"); return $query->rows; } /** * Add History * * Create a new subscription history record in the database. * * @param int $subscription_id primary key of the subscription record * @param int $subscription_status_id primary key of the subscription status record * @param string $comment * @param bool $notify * * @return void * * @example * * $this->load->model('checkout/subscription'); * * $this->model_checkout_subscription->addHistory($subscription_id, $subscription_status_id, $comment, $notify); */ public function addHistory(int $subscription_id, int $subscription_status_id, string $comment = '', bool $notify = false): void { $this->db->query("UPDATE `" . DB_PREFIX . "subscription` SET `subscription_status_id` = '" . (int)$subscription_status_id . "' WHERE `subscription_id` = '" . (int)$subscription_id . "'"); $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()"); } /** * Add Log * * Create a new subscription log record in the database. * * @param int $subscription_id primary key of the subscription record * @param string $code * @param string $description * @param bool $status * * @return void * * @example * * $this->load->model('checkout/subscription'); * * $this->model_checkout_subscription->addLog($subscription_id, $code, $description, $status); */ public function addLog(int $subscription_id, string $code, string $description, bool $status = false): void { $this->db->query("INSERT INTO `" . DB_PREFIX . "subscription_log` SET `subscription_id` = '" . (int)$subscription_id . "', `code` = '" . $this->db->escape($code) . "', `description` = '" . $this->db->escape($description) . "', `status` = '" . (int)$status . "', `date_added` = NOW()"); } }