aboutsummaryrefslogtreecommitdiffstats
path: root/public/admin/model
diff options
context:
space:
mode:
Diffstat (limited to 'public/admin/model')
-rw-r--r--public/admin/model/catalog/attribute.php105
-rw-r--r--public/admin/model/catalog/attribute_group.php90
-rw-r--r--public/admin/model/catalog/category.php344
-rw-r--r--public/admin/model/catalog/download.php94
-rw-r--r--public/admin/model/catalog/filter.php179
-rw-r--r--public/admin/model/catalog/information.php212
-rw-r--r--public/admin/model/catalog/manufacturer.php148
-rw-r--r--public/admin/model/catalog/option.php177
-rw-r--r--public/admin/model/catalog/product.php723
-rw-r--r--public/admin/model/catalog/recurring.php108
-rw-r--r--public/admin/model/catalog/review.php116
-rw-r--r--public/admin/model/customer/custom_field.php208
-rw-r--r--public/admin/model/customer/customer.php486
-rw-r--r--public/admin/model/customer/customer_approval.php102
-rw-r--r--public/admin/model/customer/customer_group.php97
-rw-r--r--public/admin/model/design/banner.php103
-rw-r--r--public/admin/model/design/layout.php109
-rw-r--r--public/admin/model/design/seo_url.php123
-rw-r--r--public/admin/model/design/theme.php38
-rw-r--r--public/admin/model/design/translation.php66
-rw-r--r--public/admin/model/extension/advertise/google.php697
-rw-r--r--public/admin/model/extension/dashboard/activity.php8
-rw-r--r--public/admin/model/extension/dashboard/chart.php214
-rw-r--r--public/admin/model/extension/dashboard/map.php20
-rw-r--r--public/admin/model/extension/dashboard/online.php24
-rw-r--r--public/admin/model/extension/dashboard/sale.php438
-rw-r--r--public/admin/model/extension/feed/google_base.php97
-rw-r--r--public/admin/model/extension/fraud/fraudlabspro.php125
-rw-r--r--public/admin/model/extension/fraud/ip.php50
-rw-r--r--public/admin/model/extension/fraud/maxmind.php73
-rw-r--r--public/admin/model/extension/openbay/amazon.php741
-rw-r--r--public/admin/model/extension/openbay/amazon_listing.php231
-rw-r--r--public/admin/model/extension/openbay/amazonus.php720
-rw-r--r--public/admin/model/extension/openbay/amazonus_listing.php197
-rw-r--r--public/admin/model/extension/openbay/ebay.php832
-rw-r--r--public/admin/model/extension/openbay/ebay_product.php101
-rw-r--r--public/admin/model/extension/openbay/ebay_profile.php106
-rw-r--r--public/admin/model/extension/openbay/ebay_template.php51
-rw-r--r--public/admin/model/extension/openbay/etsy.php73
-rw-r--r--public/admin/model/extension/openbay/etsy_product.php75
-rw-r--r--public/admin/model/extension/openbay/fba.php65
-rw-r--r--public/admin/model/extension/openbay/openbay.php761
-rw-r--r--public/admin/model/extension/openbay/order.php228
-rw-r--r--public/admin/model/extension/openbay/version.php7
-rw-r--r--public/admin/model/extension/payment/amazon_login_pay.php452
-rw-r--r--public/admin/model/extension/payment/bluepay_hosted.php235
-rw-r--r--public/admin/model/extension/payment/bluepay_redirect.php228
-rw-r--r--public/admin/model/extension/payment/cardconnect.php328
-rw-r--r--public/admin/model/extension/payment/cardinity.php98
-rw-r--r--public/admin/model/extension/payment/divido.php81
-rw-r--r--public/admin/model/extension/payment/eway.php227
-rw-r--r--public/admin/model/extension/payment/firstdata.php222
-rw-r--r--public/admin/model/extension/payment/firstdata_remote.php278
-rw-r--r--public/admin/model/extension/payment/g2apay.php145
-rw-r--r--public/admin/model/extension/payment/globalpay.php265
-rw-r--r--public/admin/model/extension/payment/globalpay_remote.php260
-rw-r--r--public/admin/model/extension/payment/klarna_checkout.php226
-rw-r--r--public/admin/model/extension/payment/laybuy.php362
-rw-r--r--public/admin/model/extension/payment/pilibaba.php165
-rw-r--r--public/admin/model/extension/payment/pp_braintree.php168
-rw-r--r--public/admin/model/extension/payment/pp_express.php376
-rw-r--r--public/admin/model/extension/payment/pp_payflow_iframe.php136
-rw-r--r--public/admin/model/extension/payment/pp_pro_iframe.php261
-rw-r--r--public/admin/model/extension/payment/realex.php265
-rw-r--r--public/admin/model/extension/payment/realex_remote.php260
-rw-r--r--public/admin/model/extension/payment/sagepay_direct.php265
-rw-r--r--public/admin/model/extension/payment/sagepay_server.php266
-rw-r--r--public/admin/model/extension/payment/securetrading_pp.php208
-rw-r--r--public/admin/model/extension/payment/securetrading_ws.php351
-rw-r--r--public/admin/model/extension/payment/squareup.php117
-rw-r--r--public/admin/model/extension/payment/worldpay.php175
-rw-r--r--public/admin/model/extension/report/activity.php8
-rw-r--r--public/admin/model/extension/report/coupon.php60
-rw-r--r--public/admin/model/extension/report/customer.php380
-rw-r--r--public/admin/model/extension/report/customer_transaction.php62
-rw-r--r--public/admin/model/extension/report/marketing.php60
-rw-r--r--public/admin/model/extension/report/product.php96
-rw-r--r--public/admin/model/extension/report/return.php100
-rw-r--r--public/admin/model/extension/report/sale.php438
-rw-r--r--public/admin/model/localisation/country.php86
-rw-r--r--public/admin/model/localisation/currency.php159
-rw-r--r--public/admin/model/localisation/geo_zone.php130
-rw-r--r--public/admin/model/localisation/language.php313
-rw-r--r--public/admin/model/localisation/length_class.php120
-rw-r--r--public/admin/model/localisation/location.php65
-rw-r--r--public/admin/model/localisation/order_status.php100
-rw-r--r--public/admin/model/localisation/return_action.php100
-rw-r--r--public/admin/model/localisation/return_reason.php100
-rw-r--r--public/admin/model/localisation/return_status.php100
-rw-r--r--public/admin/model/localisation/stock_status.php100
-rw-r--r--public/admin/model/localisation/tax_class.php105
-rw-r--r--public/admin/model/localisation/tax_rate.php104
-rw-r--r--public/admin/model/localisation/weight_class.php120
-rw-r--r--public/admin/model/localisation/zone.php92
-rw-r--r--public/admin/model/marketing/coupon.php152
-rw-r--r--public/admin/model/marketing/marketing.php118
-rw-r--r--public/admin/model/report/online.php60
-rw-r--r--public/admin/model/report/statistics.php30
-rw-r--r--public/admin/model/sale/order.php478
-rw-r--r--public/admin/model/sale/recurring.php197
-rw-r--r--public/admin/model/sale/return.php199
-rw-r--r--public/admin/model/sale/voucher.php103
-rw-r--r--public/admin/model/sale/voucher_theme.php99
-rw-r--r--public/admin/model/setting/event.php88
-rw-r--r--public/admin/model/setting/extension.php77
-rw-r--r--public/admin/model/setting/modification.php80
-rw-r--r--public/admin/model/setting/module.php42
-rw-r--r--public/admin/model/setting/setting.php54
-rw-r--r--public/admin/model/setting/store.php108
-rw-r--r--public/admin/model/tool/backup.php68
-rw-r--r--public/admin/model/tool/image.php47
-rw-r--r--public/admin/model/tool/upload.php108
-rw-r--r--public/admin/model/user/api.php123
-rw-r--r--public/admin/model/user/user.php108
-rw-r--r--public/admin/model/user/user_group.php85
115 files changed, 21404 insertions, 0 deletions
diff --git a/public/admin/model/catalog/attribute.php b/public/admin/model/catalog/attribute.php
new file mode 100644
index 0000000..a4a35c6
--- /dev/null
+++ b/public/admin/model/catalog/attribute.php
@@ -0,0 +1,105 @@
+<?php
+class ModelCatalogAttribute extends Model {
+ public function addAttribute($data) {
+ $this->db->query("INSERT INTO " . DB_PREFIX . "attribute SET attribute_group_id = '" . (int)$data['attribute_group_id'] . "', sort_order = '" . (int)$data['sort_order'] . "'");
+
+ $attribute_id = $this->db->getLastId();
+
+ foreach ($data['attribute_description'] as $language_id => $value) {
+ $this->db->query("INSERT INTO " . DB_PREFIX . "attribute_description SET attribute_id = '" . (int)$attribute_id . "', language_id = '" . (int)$language_id . "', name = '" . $this->db->escape($value['name']) . "'");
+ }
+
+ return $attribute_id;
+ }
+
+ public function editAttribute($attribute_id, $data) {
+ $this->db->query("UPDATE " . DB_PREFIX . "attribute SET attribute_group_id = '" . (int)$data['attribute_group_id'] . "', sort_order = '" . (int)$data['sort_order'] . "' WHERE attribute_id = '" . (int)$attribute_id . "'");
+
+ $this->db->query("DELETE FROM " . DB_PREFIX . "attribute_description WHERE attribute_id = '" . (int)$attribute_id . "'");
+
+ foreach ($data['attribute_description'] as $language_id => $value) {
+ $this->db->query("INSERT INTO " . DB_PREFIX . "attribute_description SET attribute_id = '" . (int)$attribute_id . "', language_id = '" . (int)$language_id . "', name = '" . $this->db->escape($value['name']) . "'");
+ }
+ }
+
+ public function deleteAttribute($attribute_id) {
+ $this->db->query("DELETE FROM " . DB_PREFIX . "attribute WHERE attribute_id = '" . (int)$attribute_id . "'");
+ $this->db->query("DELETE FROM " . DB_PREFIX . "attribute_description WHERE attribute_id = '" . (int)$attribute_id . "'");
+ }
+
+ public function getAttribute($attribute_id) {
+ $query = $this->db->query("SELECT * FROM " . DB_PREFIX . "attribute a LEFT JOIN " . DB_PREFIX . "attribute_description ad ON (a.attribute_id = ad.attribute_id) WHERE a.attribute_id = '" . (int)$attribute_id . "' AND ad.language_id = '" . (int)$this->config->get('config_language_id') . "'");
+
+ return $query->row;
+ }
+
+ public function getAttributes($data = array()) {
+ $sql = "SELECT *, (SELECT agd.name FROM " . DB_PREFIX . "attribute_group_description agd WHERE agd.attribute_group_id = a.attribute_group_id AND agd.language_id = '" . (int)$this->config->get('config_language_id') . "') AS attribute_group FROM " . DB_PREFIX . "attribute a LEFT JOIN " . DB_PREFIX . "attribute_description ad ON (a.attribute_id = ad.attribute_id) WHERE ad.language_id = '" . (int)$this->config->get('config_language_id') . "'";
+
+ if (!empty($data['filter_name'])) {
+ $sql .= " AND ad.name LIKE '" . $this->db->escape($data['filter_name']) . "%'";
+ }
+
+ if (!empty($data['filter_attribute_group_id'])) {
+ $sql .= " AND a.attribute_group_id = '" . $this->db->escape($data['filter_attribute_group_id']) . "'";
+ }
+
+ $sort_data = array(
+ 'ad.name',
+ 'attribute_group',
+ 'a.sort_order'
+ );
+
+ if (isset($data['sort']) && in_array($data['sort'], $sort_data)) {
+ $sql .= " ORDER BY " . $data['sort'];
+ } else {
+ $sql .= " ORDER BY attribute_group, ad.name";
+ }
+
+ 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'];
+ }
+
+ $query = $this->db->query($sql);
+
+ return $query->rows;
+ }
+
+ public function getAttributeDescriptions($attribute_id) {
+ $attribute_data = array();
+
+ $query = $this->db->query("SELECT * FROM " . DB_PREFIX . "attribute_description WHERE attribute_id = '" . (int)$attribute_id . "'");
+
+ foreach ($query->rows as $result) {
+ $attribute_data[$result['language_id']] = array('name' => $result['name']);
+ }
+
+ return $attribute_data;
+ }
+
+ public function getTotalAttributes() {
+ $query = $this->db->query("SELECT COUNT(*) AS total FROM " . DB_PREFIX . "attribute");
+
+ return $query->row['total'];
+ }
+
+ public function getTotalAttributesByAttributeGroupId($attribute_group_id) {
+ $query = $this->db->query("SELECT COUNT(*) AS total FROM " . DB_PREFIX . "attribute WHERE attribute_group_id = '" . (int)$attribute_group_id . "'");
+
+ return $query->row['total'];
+ }
+}
diff --git a/public/admin/model/catalog/attribute_group.php b/public/admin/model/catalog/attribute_group.php
new file mode 100644
index 0000000..12a5591
--- /dev/null
+++ b/public/admin/model/catalog/attribute_group.php
@@ -0,0 +1,90 @@
+<?php
+class ModelCatalogAttributeGroup extends Model {
+ public function addAttributeGroup($data) {
+ $this->db->query("INSERT INTO " . DB_PREFIX . "attribute_group SET sort_order = '" . (int)$data['sort_order'] . "'");
+
+ $attribute_group_id = $this->db->getLastId();
+
+ foreach ($data['attribute_group_description'] as $language_id => $value) {
+ $this->db->query("INSERT INTO " . DB_PREFIX . "attribute_group_description SET attribute_group_id = '" . (int)$attribute_group_id . "', language_id = '" . (int)$language_id . "', name = '" . $this->db->escape($value['name']) . "'");
+ }
+
+ return $attribute_group_id;
+ }
+
+ public function editAttributeGroup($attribute_group_id, $data) {
+ $this->db->query("UPDATE " . DB_PREFIX . "attribute_group SET sort_order = '" . (int)$data['sort_order'] . "' WHERE attribute_group_id = '" . (int)$attribute_group_id . "'");
+
+ $this->db->query("DELETE FROM " . DB_PREFIX . "attribute_group_description WHERE attribute_group_id = '" . (int)$attribute_group_id . "'");
+
+ foreach ($data['attribute_group_description'] as $language_id => $value) {
+ $this->db->query("INSERT INTO " . DB_PREFIX . "attribute_group_description SET attribute_group_id = '" . (int)$attribute_group_id . "', language_id = '" . (int)$language_id . "', name = '" . $this->db->escape($value['name']) . "'");
+ }
+ }
+
+ public function deleteAttributeGroup($attribute_group_id) {
+ $this->db->query("DELETE FROM " . DB_PREFIX . "attribute_group WHERE attribute_group_id = '" . (int)$attribute_group_id . "'");
+ $this->db->query("DELETE FROM " . DB_PREFIX . "attribute_group_description WHERE attribute_group_id = '" . (int)$attribute_group_id . "'");
+ }
+
+ public function getAttributeGroup($attribute_group_id) {
+ $query = $this->db->query("SELECT * FROM " . DB_PREFIX . "attribute_group WHERE attribute_group_id = '" . (int)$attribute_group_id . "'");
+
+ return $query->row;
+ }
+
+ public function getAttributeGroups($data = array()) {
+ $sql = "SELECT * FROM " . DB_PREFIX . "attribute_group ag LEFT JOIN " . DB_PREFIX . "attribute_group_description agd ON (ag.attribute_group_id = agd.attribute_group_id) WHERE agd.language_id = '" . (int)$this->config->get('config_language_id') . "'";
+
+ $sort_data = array(
+ 'agd.name',
+ 'ag.sort_order'
+ );
+
+ if (isset($data['sort']) && in_array($data['sort'], $sort_data)) {
+ $sql .= " ORDER BY " . $data['sort'];
+ } else {
+ $sql .= " ORDER BY agd.name";
+ }
+
+ 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'];
+ }
+
+ $query = $this->db->query($sql);
+
+ return $query->rows;
+ }
+
+ public function getAttributeGroupDescriptions($attribute_group_id) {
+ $attribute_group_data = array();
+
+ $query = $this->db->query("SELECT * FROM " . DB_PREFIX . "attribute_group_description WHERE attribute_group_id = '" . (int)$attribute_group_id . "'");
+
+ foreach ($query->rows as $result) {
+ $attribute_group_data[$result['language_id']] = array('name' => $result['name']);
+ }
+
+ return $attribute_group_data;
+ }
+
+ public function getTotalAttributeGroups() {
+ $query = $this->db->query("SELECT COUNT(*) AS total FROM " . DB_PREFIX . "attribute_group");
+
+ return $query->row['total'];
+ }
+} \ No newline at end of file
diff --git a/public/admin/model/catalog/category.php b/public/admin/model/catalog/category.php
new file mode 100644
index 0000000..74e5b5d
--- /dev/null
+++ b/public/admin/model/catalog/category.php
@@ -0,0 +1,344 @@
+<?php
+class ModelCatalogCategory extends Model {
+ public function addCategory($data) {
+ $this->db->query("INSERT INTO " . DB_PREFIX . "category SET parent_id = '" . (int)$data['parent_id'] . "', `top` = '" . (isset($data['top']) ? (int)$data['top'] : 0) . "', `column` = '" . (int)$data['column'] . "', sort_order = '" . (int)$data['sort_order'] . "', status = '" . (int)$data['status'] . "', date_modified = NOW(), date_added = NOW()");
+
+ $category_id = $this->db->getLastId();
+
+ if (isset($data['image'])) {
+ $this->db->query("UPDATE " . DB_PREFIX . "category SET image = '" . $this->db->escape($data['image']) . "' WHERE category_id = '" . (int)$category_id . "'");
+ }
+
+ foreach ($data['category_description'] as $language_id => $value) {
+ $this->db->query("INSERT INTO " . DB_PREFIX . "category_description SET category_id = '" . (int)$category_id . "', language_id = '" . (int)$language_id . "', name = '" . $this->db->escape($value['name']) . "', description = '" . $this->db->escape($value['description']) . "', meta_title = '" . $this->db->escape($value['meta_title']) . "', meta_description = '" . $this->db->escape($value['meta_description']) . "', meta_keyword = '" . $this->db->escape($value['meta_keyword']) . "'");
+ }
+
+ // MySQL Hierarchical Data Closure Table Pattern
+ $level = 0;
+
+ $query = $this->db->query("SELECT * FROM `" . DB_PREFIX . "category_path` WHERE category_id = '" . (int)$data['parent_id'] . "' ORDER BY `level` ASC");
+
+ foreach ($query->rows as $result) {
+ $this->db->query("INSERT INTO `" . DB_PREFIX . "category_path` SET `category_id` = '" . (int)$category_id . "', `path_id` = '" . (int)$result['path_id'] . "', `level` = '" . (int)$level . "'");
+
+ $level++;
+ }
+
+ $this->db->query("INSERT INTO `" . DB_PREFIX . "category_path` SET `category_id` = '" . (int)$category_id . "', `path_id` = '" . (int)$category_id . "', `level` = '" . (int)$level . "'");
+
+ if (isset($data['category_filter'])) {
+ foreach ($data['category_filter'] as $filter_id) {
+ $this->db->query("INSERT INTO " . DB_PREFIX . "category_filter SET category_id = '" . (int)$category_id . "', filter_id = '" . (int)$filter_id . "'");
+ }
+ }
+
+ if (isset($data['category_store'])) {
+ foreach ($data['category_store'] as $store_id) {
+ $this->db->query("INSERT INTO " . DB_PREFIX . "category_to_store SET category_id = '" . (int)$category_id . "', store_id = '" . (int)$store_id . "'");
+ }
+ }
+
+ if (isset($data['category_seo_url'])) {
+ foreach ($data['category_seo_url'] as $store_id => $language) {
+ foreach ($language as $language_id => $keyword) {
+ if (!empty($keyword)) {
+ $this->db->query("INSERT INTO " . DB_PREFIX . "seo_url SET store_id = '" . (int)$store_id . "', language_id = '" . (int)$language_id . "', query = 'category_id=" . (int)$category_id . "', keyword = '" . $this->db->escape($keyword) . "'");
+ }
+ }
+ }
+ }
+
+ // Set which layout to use with this category
+ if (isset($data['category_layout'])) {
+ foreach ($data['category_layout'] as $store_id => $layout_id) {
+ $this->db->query("INSERT INTO " . DB_PREFIX . "category_to_layout SET category_id = '" . (int)$category_id . "', store_id = '" . (int)$store_id . "', layout_id = '" . (int)$layout_id . "'");
+ }
+ }
+
+ $this->cache->delete('category');
+
+ return $category_id;
+ }
+
+ public function editCategory($category_id, $data) {
+ $this->db->query("UPDATE " . DB_PREFIX . "category SET parent_id = '" . (int)$data['parent_id'] . "', `top` = '" . (isset($data['top']) ? (int)$data['top'] : 0) . "', `column` = '" . (int)$data['column'] . "', sort_order = '" . (int)$data['sort_order'] . "', status = '" . (int)$data['status'] . "', date_modified = NOW() WHERE category_id = '" . (int)$category_id . "'");
+
+ if (isset($data['image'])) {
+ $this->db->query("UPDATE " . DB_PREFIX . "category SET image = '" . $this->db->escape($data['image']) . "' WHERE category_id = '" . (int)$category_id . "'");
+ }
+
+ $this->db->query("DELETE FROM " . DB_PREFIX . "category_description WHERE category_id = '" . (int)$category_id . "'");
+
+ foreach ($data['category_description'] as $language_id => $value) {
+ $this->db->query("INSERT INTO " . DB_PREFIX . "category_description SET category_id = '" . (int)$category_id . "', language_id = '" . (int)$language_id . "', name = '" . $this->db->escape($value['name']) . "', description = '" . $this->db->escape($value['description']) . "', meta_title = '" . $this->db->escape($value['meta_title']) . "', meta_description = '" . $this->db->escape($value['meta_description']) . "', meta_keyword = '" . $this->db->escape($value['meta_keyword']) . "'");
+ }
+
+ // MySQL Hierarchical Data Closure Table Pattern
+ $query = $this->db->query("SELECT * FROM `" . DB_PREFIX . "category_path` WHERE path_id = '" . (int)$category_id . "' ORDER BY level ASC");
+
+ if ($query->rows) {
+ foreach ($query->rows as $category_path) {
+ // Delete the path below the current one
+ $this->db->query("DELETE FROM `" . DB_PREFIX . "category_path` WHERE category_id = '" . (int)$category_path['category_id'] . "' AND level < '" . (int)$category_path['level'] . "'");
+
+ $path = array();
+
+ // Get the nodes new parents
+ $query = $this->db->query("SELECT * FROM `" . DB_PREFIX . "category_path` WHERE category_id = '" . (int)$data['parent_id'] . "' ORDER BY level ASC");
+
+ foreach ($query->rows as $result) {
+ $path[] = $result['path_id'];
+ }
+
+ // Get whats left of the nodes current path
+ $query = $this->db->query("SELECT * FROM `" . DB_PREFIX . "category_path` WHERE category_id = '" . (int)$category_path['category_id'] . "' ORDER BY level ASC");
+
+ foreach ($query->rows as $result) {
+ $path[] = $result['path_id'];
+ }
+
+ // Combine the paths with a new level
+ $level = 0;
+
+ foreach ($path as $path_id) {
+ $this->db->query("REPLACE INTO `" . DB_PREFIX . "category_path` SET category_id = '" . (int)$category_path['category_id'] . "', `path_id` = '" . (int)$path_id . "', level = '" . (int)$level . "'");
+
+ $level++;
+ }
+ }
+ } else {
+ // Delete the path below the current one
+ $this->db->query("DELETE FROM `" . DB_PREFIX . "category_path` WHERE category_id = '" . (int)$category_id . "'");
+
+ // Fix for records with no paths
+ $level = 0;
+
+ $query = $this->db->query("SELECT * FROM `" . DB_PREFIX . "category_path` WHERE category_id = '" . (int)$data['parent_id'] . "' ORDER BY level ASC");
+
+ foreach ($query->rows as $result) {
+ $this->db->query("INSERT INTO `" . DB_PREFIX . "category_path` SET category_id = '" . (int)$category_id . "', `path_id` = '" . (int)$result['path_id'] . "', level = '" . (int)$level . "'");
+
+ $level++;
+ }
+
+ $this->db->query("REPLACE INTO `" . DB_PREFIX . "category_path` SET category_id = '" . (int)$category_id . "', `path_id` = '" . (int)$category_id . "', level = '" . (int)$level . "'");
+ }
+
+ $this->db->query("DELETE FROM " . DB_PREFIX . "category_filter WHERE category_id = '" . (int)$category_id . "'");
+
+ if (isset($data['category_filter'])) {
+ foreach ($data['category_filter'] as $filter_id) {
+ $this->db->query("INSERT INTO " . DB_PREFIX . "category_filter SET category_id = '" . (int)$category_id . "', filter_id = '" . (int)$filter_id . "'");
+ }
+ }
+
+ $this->db->query("DELETE FROM " . DB_PREFIX . "category_to_store WHERE category_id = '" . (int)$category_id . "'");
+
+ if (isset($data['category_store'])) {
+ foreach ($data['category_store'] as $store_id) {
+ $this->db->query("INSERT INTO " . DB_PREFIX . "category_to_store SET category_id = '" . (int)$category_id . "', store_id = '" . (int)$store_id . "'");
+ }
+ }
+
+ // SEO URL
+ $this->db->query("DELETE FROM `" . DB_PREFIX . "seo_url` WHERE query = 'category_id=" . (int)$category_id . "'");
+
+ if (isset($data['category_seo_url'])) {
+ foreach ($data['category_seo_url'] as $store_id => $language) {
+ foreach ($language as $language_id => $keyword) {
+ if (!empty($keyword)) {
+ $this->db->query("INSERT INTO " . DB_PREFIX . "seo_url SET store_id = '" . (int)$store_id . "', language_id = '" . (int)$language_id . "', query = 'category_id=" . (int)$category_id . "', keyword = '" . $this->db->escape($keyword) . "'");
+ }
+ }
+ }
+ }
+
+ $this->db->query("DELETE FROM " . DB_PREFIX . "category_to_layout WHERE category_id = '" . (int)$category_id . "'");
+
+ if (isset($data['category_layout'])) {
+ foreach ($data['category_layout'] as $store_id => $layout_id) {
+ $this->db->query("INSERT INTO " . DB_PREFIX . "category_to_layout SET category_id = '" . (int)$category_id . "', store_id = '" . (int)$store_id . "', layout_id = '" . (int)$layout_id . "'");
+ }
+ }
+
+ $this->cache->delete('category');
+ }
+
+ public function deleteCategory($category_id) {
+ $this->db->query("DELETE FROM " . DB_PREFIX . "category_path WHERE category_id = '" . (int)$category_id . "'");
+
+ $query = $this->db->query("SELECT * FROM " . DB_PREFIX . "category_path WHERE path_id = '" . (int)$category_id . "'");
+
+ foreach ($query->rows as $result) {
+ $this->deleteCategory($result['category_id']);
+ }
+
+ $this->db->query("DELETE FROM " . DB_PREFIX . "category WHERE category_id = '" . (int)$category_id . "'");
+ $this->db->query("DELETE FROM " . DB_PREFIX . "category_description WHERE category_id = '" . (int)$category_id . "'");
+ $this->db->query("DELETE FROM " . DB_PREFIX . "category_filter WHERE category_id = '" . (int)$category_id . "'");
+ $this->db->query("DELETE FROM " . DB_PREFIX . "category_to_store WHERE category_id = '" . (int)$category_id . "'");
+ $this->db->query("DELETE FROM " . DB_PREFIX . "category_to_layout WHERE category_id = '" . (int)$category_id . "'");
+ $this->db->query("DELETE FROM " . DB_PREFIX . "product_to_category WHERE category_id = '" . (int)$category_id . "'");
+ $this->db->query("DELETE FROM " . DB_PREFIX . "seo_url WHERE query = 'category_id=" . (int)$category_id . "'");
+ $this->db->query("DELETE FROM " . DB_PREFIX . "coupon_category WHERE category_id = '" . (int)$category_id . "'");
+
+ $this->cache->delete('category');
+ }
+
+ public function repairCategories($parent_id = 0) {
+ $query = $this->db->query("SELECT * FROM " . DB_PREFIX . "category WHERE parent_id = '" . (int)$parent_id . "'");
+
+ foreach ($query->rows as $category) {
+ // Delete the path below the current one
+ $this->db->query("DELETE FROM `" . DB_PREFIX . "category_path` WHERE category_id = '" . (int)$category['category_id'] . "'");
+
+ // Fix for records with no paths
+ $level = 0;
+
+ $query = $this->db->query("SELECT * FROM `" . DB_PREFIX . "category_path` WHERE category_id = '" . (int)$parent_id . "' ORDER BY level ASC");
+
+ foreach ($query->rows as $result) {
+ $this->db->query("INSERT INTO `" . DB_PREFIX . "category_path` SET category_id = '" . (int)$category['category_id'] . "', `path_id` = '" . (int)$result['path_id'] . "', level = '" . (int)$level . "'");
+
+ $level++;
+ }
+
+ $this->db->query("REPLACE INTO `" . DB_PREFIX . "category_path` SET category_id = '" . (int)$category['category_id'] . "', `path_id` = '" . (int)$category['category_id'] . "', level = '" . (int)$level . "'");
+
+ $this->repairCategories($category['category_id']);
+ }
+ }
+
+ public function getCategory($category_id) {
+ $query = $this->db->query("SELECT DISTINCT *, (SELECT GROUP_CONCAT(cd1.name ORDER BY level SEPARATOR '&nbsp;&nbsp;&gt;&nbsp;&nbsp;') FROM " . DB_PREFIX . "category_path cp LEFT JOIN " . DB_PREFIX . "category_description cd1 ON (cp.path_id = cd1.category_id AND cp.category_id != cp.path_id) WHERE cp.category_id = c.category_id AND cd1.language_id = '" . (int)$this->config->get('config_language_id') . "' GROUP BY cp.category_id) AS path FROM " . DB_PREFIX . "category c LEFT JOIN " . DB_PREFIX . "category_description cd2 ON (c.category_id = cd2.category_id) WHERE c.category_id = '" . (int)$category_id . "' AND cd2.language_id = '" . (int)$this->config->get('config_language_id') . "'");
+
+ return $query->row;
+ }
+
+ public function getCategories($data = array()) {
+ $sql = "SELECT cp.category_id AS category_id, GROUP_CONCAT(cd1.name ORDER BY cp.level SEPARATOR '&nbsp;&nbsp;&gt;&nbsp;&nbsp;') AS name, c1.parent_id, c1.sort_order FROM " . DB_PREFIX . "category_path cp LEFT JOIN " . DB_PREFIX . "category c1 ON (cp.category_id = c1.category_id) LEFT JOIN " . DB_PREFIX . "category c2 ON (cp.path_id = c2.category_id) LEFT JOIN " . DB_PREFIX . "category_description cd1 ON (cp.path_id = cd1.category_id) LEFT JOIN " . DB_PREFIX . "category_description cd2 ON (cp.category_id = cd2.category_id) WHERE cd1.language_id = '" . (int)$this->config->get('config_language_id') . "' AND cd2.language_id = '" . (int)$this->config->get('config_language_id') . "'";
+
+ if (!empty($data['filter_name'])) {
+ $sql .= " AND cd2.name LIKE '%" . $this->db->escape($data['filter_name']) . "%'";
+ }
+
+ $sql .= " GROUP BY cp.category_id";
+
+ $sort_data = array(
+ 'name',
+ 'sort_order'
+ );
+
+ if (isset($data['sort']) && in_array($data['sort'], $sort_data)) {
+ $sql .= " ORDER BY " . $data['sort'];
+ } else {
+ $sql .= " ORDER BY sort_order";
+ }
+
+ 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'];
+ }
+
+ $query = $this->db->query($sql);
+
+ return $query->rows;
+ }
+
+ public function getCategoryDescriptions($category_id) {
+ $category_description_data = array();
+
+ $query = $this->db->query("SELECT * FROM " . DB_PREFIX . "category_description WHERE category_id = '" . (int)$category_id . "'");
+
+ foreach ($query->rows as $result) {
+ $category_description_data[$result['language_id']] = array(
+ 'name' => $result['name'],
+ 'meta_title' => $result['meta_title'],
+ 'meta_description' => $result['meta_description'],
+ 'meta_keyword' => $result['meta_keyword'],
+ 'description' => $result['description']
+ );
+ }
+
+ return $category_description_data;
+ }
+
+ public function getCategoryPath($category_id) {
+ $query = $this->db->query("SELECT category_id, path_id, level FROM " . DB_PREFIX . "category_path WHERE category_id = '" . (int)$category_id . "'");
+
+ return $query->rows;
+ }
+
+ public function getCategoryFilters($category_id) {
+ $category_filter_data = array();
+
+ $query = $this->db->query("SELECT * FROM " . DB_PREFIX . "category_filter WHERE category_id = '" . (int)$category_id . "'");
+
+ foreach ($query->rows as $result) {
+ $category_filter_data[] = $result['filter_id'];
+ }
+
+ return $category_filter_data;
+ }
+
+ public function getCategoryStores($category_id) {
+ $category_store_data = array();
+
+ $query = $this->db->query("SELECT * FROM " . DB_PREFIX . "category_to_store WHERE category_id = '" . (int)$category_id . "'");
+
+ foreach ($query->rows as $result) {
+ $category_store_data[] = $result['store_id'];
+ }
+
+ return $category_store_data;
+ }
+
+ public function getCategorySeoUrls($category_id) {
+ $category_seo_url_data = array();
+
+ $query = $this->db->query("SELECT * FROM " . DB_PREFIX . "seo_url WHERE query = 'category_id=" . (int)$category_id . "'");
+
+ foreach ($query->rows as $result) {
+ $category_seo_url_data[$result['store_id']][$result['language_id']] = $result['keyword'];
+ }
+
+ return $category_seo_url_data;
+ }
+
+ public function getCategoryLayouts($category_id) {
+ $category_layout_data = array();
+
+ $query = $this->db->query("SELECT * FROM " . DB_PREFIX . "category_to_layout WHERE category_id = '" . (int)$category_id . "'");
+
+ foreach ($query->rows as $result) {
+ $category_layout_data[$result['store_id']] = $result['layout_id'];
+ }
+
+ return $category_layout_data;
+ }
+
+ public function getTotalCategories() {
+ $query = $this->db->query("SELECT COUNT(*) AS total FROM " . DB_PREFIX . "category");
+
+ return $query->row['total'];
+ }
+
+ public function getTotalCategoriesByLayoutId($layout_id) {
+ $query = $this->db->query("SELECT COUNT(*) AS total FROM " . DB_PREFIX . "category_to_layout WHERE layout_id = '" . (int)$layout_id . "'");
+
+ return $query->row['total'];
+ }
+} \ No newline at end of file
diff --git a/public/admin/model/catalog/download.php b/public/admin/model/catalog/download.php
new file mode 100644
index 0000000..1849d2a
--- /dev/null
+++ b/public/admin/model/catalog/download.php
@@ -0,0 +1,94 @@
+<?php
+class ModelCatalogDownload extends Model {
+ public function addDownload($data) {
+ $this->db->query("INSERT INTO " . DB_PREFIX . "download SET filename = '" . $this->db->escape($data['filename']) . "', mask = '" . $this->db->escape($data['mask']) . "', date_added = NOW()");
+
+ $download_id = $this->db->getLastId();
+
+ foreach ($data['download_description'] as $language_id => $value) {
+ $this->db->query("INSERT INTO " . DB_PREFIX . "download_description SET download_id = '" . (int)$download_id . "', language_id = '" . (int)$language_id . "', name = '" . $this->db->escape($value['name']) . "'");
+ }
+
+ return $download_id;
+ }
+
+ public function editDownload($download_id, $data) {
+ $this->db->query("UPDATE " . DB_PREFIX . "download SET filename = '" . $this->db->escape($data['filename']) . "', mask = '" . $this->db->escape($data['mask']) . "' WHERE download_id = '" . (int)$download_id . "'");
+
+ $this->db->query("DELETE FROM " . DB_PREFIX . "download_description WHERE download_id = '" . (int)$download_id . "'");
+
+ foreach ($data['download_description'] as $language_id => $value) {
+ $this->db->query("INSERT INTO " . DB_PREFIX . "download_description SET download_id = '" . (int)$download_id . "', language_id = '" . (int)$language_id . "', name = '" . $this->db->escape($value['name']) . "'");
+ }
+ }
+
+ public function deleteDownload($download_id) {
+ $this->db->query("DELETE FROM " . DB_PREFIX . "download WHERE download_id = '" . (int)$download_id . "'");
+ $this->db->query("DELETE FROM " . DB_PREFIX . "download_description WHERE download_id = '" . (int)$download_id . "'");
+ }
+
+ public function getDownload($download_id) {
+ $query = $this->db->query("SELECT DISTINCT * FROM " . DB_PREFIX . "download d LEFT JOIN " . DB_PREFIX . "download_description dd ON (d.download_id = dd.download_id) WHERE d.download_id = '" . (int)$download_id . "' AND dd.language_id = '" . (int)$this->config->get('config_language_id') . "'");
+
+ return $query->row;
+ }
+
+ public function getDownloads($data = array()) {
+ $sql = "SELECT * FROM " . DB_PREFIX . "download d LEFT JOIN " . DB_PREFIX . "download_description dd ON (d.download_id = dd.download_id) WHERE dd.language_id = '" . (int)$this->config->get('config_language_id') . "'";
+
+ if (!empty($data['filter_name'])) {
+ $sql .= " AND dd.name LIKE '" . $this->db->escape($data['filter_name']) . "%'";
+ }
+
+ $sort_data = array(
+ 'dd.name',
+ 'd.date_added'
+ );
+
+ if (isset($data['sort']) && in_array($data['sort'], $sort_data)) {
+ $sql .= " ORDER BY " . $data['sort'];
+ } else {
+ $sql .= " ORDER BY dd.name";
+ }
+
+ 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'];
+ }
+
+ $query = $this->db->query($sql);
+
+ return $query->rows;
+ }
+
+ public function getDownloadDescriptions($download_id) {
+ $download_description_data = array();
+
+ $query = $this->db->query("SELECT * FROM " . DB_PREFIX . "download_description WHERE download_id = '" . (int)$download_id . "'");
+
+ foreach ($query->rows as $result) {
+ $download_description_data[$result['language_id']] = array('name' => $result['name']);
+ }
+
+ return $download_description_data;
+ }
+
+ public function getTotalDownloads() {
+ $query = $this->db->query("SELECT COUNT(*) AS total FROM " . DB_PREFIX . "download");
+
+ return $query->row['total'];
+ }
+} \ No newline at end of file
diff --git a/public/admin/model/catalog/filter.php b/public/admin/model/catalog/filter.php
new file mode 100644
index 0000000..830e1f6
--- /dev/null
+++ b/public/admin/model/catalog/filter.php
@@ -0,0 +1,179 @@
+<?php
+class ModelCatalogFilter extends Model {
+ public function addFilter($data) {
+ $this->db->query("INSERT INTO `" . DB_PREFIX . "filter_group` SET sort_order = '" . (int)$data['sort_order'] . "'");
+
+ $filter_group_id = $this->db->getLastId();
+
+ foreach ($data['filter_group_description'] as $language_id => $value) {
+ $this->db->query("INSERT INTO " . DB_PREFIX . "filter_group_description SET filter_group_id = '" . (int)$filter_group_id . "', language_id = '" . (int)$language_id . "', name = '" . $this->db->escape($value['name']) . "'");
+ }
+
+ if (isset($data['filter'])) {
+ foreach ($data['filter'] as $filter) {
+ $this->db->query("INSERT INTO " . DB_PREFIX . "filter SET filter_group_id = '" . (int)$filter_group_id . "', sort_order = '" . (int)$filter['sort_order'] . "'");
+
+ $filter_id = $this->db->getLastId();
+
+ foreach ($filter['filter_description'] as $language_id => $filter_description) {
+ $this->db->query("INSERT INTO " . DB_PREFIX . "filter_description SET filter_id = '" . (int)$filter_id . "', language_id = '" . (int)$language_id . "', filter_group_id = '" . (int)$filter_group_id . "', name = '" . $this->db->escape($filter_description['name']) . "'");
+ }
+ }
+ }
+
+ return $filter_group_id;
+ }
+
+ public function editFilter($filter_group_id, $data) {
+ $this->db->query("UPDATE `" . DB_PREFIX . "filter_group` SET sort_order = '" . (int)$data['sort_order'] . "' WHERE filter_group_id = '" . (int)$filter_group_id . "'");
+
+ $this->db->query("DELETE FROM " . DB_PREFIX . "filter_group_description WHERE filter_group_id = '" . (int)$filter_group_id . "'");
+
+ foreach ($data['filter_group_description'] as $language_id => $value) {
+ $this->db->query("INSERT INTO " . DB_PREFIX . "filter_group_description SET filter_group_id = '" . (int)$filter_group_id . "', language_id = '" . (int)$language_id . "', name = '" . $this->db->escape($value['name']) . "'");
+ }
+
+ $this->db->query("DELETE FROM " . DB_PREFIX . "filter WHERE filter_group_id = '" . (int)$filter_group_id . "'");
+ $this->db->query("DELETE FROM " . DB_PREFIX . "filter_description WHERE filter_group_id = '" . (int)$filter_group_id . "'");
+
+ if (isset($data['filter'])) {
+ foreach ($data['filter'] as $filter) {
+ if ($filter['filter_id']) {
+ $this->db->query("INSERT INTO " . DB_PREFIX . "filter SET filter_id = '" . (int)$filter['filter_id'] . "', filter_group_id = '" . (int)$filter_group_id . "', sort_order = '" . (int)$filter['sort_order'] . "'");
+ } else {
+ $this->db->query("INSERT INTO " . DB_PREFIX . "filter SET filter_group_id = '" . (int)$filter_group_id . "', sort_order = '" . (int)$filter['sort_order'] . "'");
+ }
+
+ $filter_id = $this->db->getLastId();
+
+ foreach ($filter['filter_description'] as $language_id => $filter_description) {
+ $this->db->query("INSERT INTO " . DB_PREFIX . "filter_description SET filter_id = '" . (int)$filter_id . "', language_id = '" . (int)$language_id . "', filter_group_id = '" . (int)$filter_group_id . "', name = '" . $this->db->escape($filter_description['name']) . "'");
+ }
+ }
+ }
+ }
+
+ public function deleteFilter($filter_group_id) {
+ $this->db->query("DELETE FROM `" . DB_PREFIX . "filter_group` WHERE filter_group_id = '" . (int)$filter_group_id . "'");
+ $this->db->query("DELETE FROM `" . DB_PREFIX . "filter_group_description` WHERE filter_group_id = '" . (int)$filter_group_id . "'");
+ $this->db->query("DELETE FROM `" . DB_PREFIX . "filter` WHERE filter_group_id = '" . (int)$filter_group_id . "'");
+ $this->db->query("DELETE FROM `" . DB_PREFIX . "filter_description` WHERE filter_group_id = '" . (int)$filter_group_id . "'");
+ }
+
+ public function getFilterGroup($filter_group_id) {
+ $query = $this->db->query("SELECT * FROM `" . DB_PREFIX . "filter_group` fg LEFT JOIN " . DB_PREFIX . "filter_group_description fgd ON (fg.filter_group_id = fgd.filter_group_id) WHERE fg.filter_group_id = '" . (int)$filter_group_id . "' AND fgd.language_id = '" . (int)$this->config->get('config_language_id') . "'");
+
+ return $query->row;
+ }
+
+ public function getFilterGroups($data = array()) {
+ $sql = "SELECT * FROM `" . DB_PREFIX . "filter_group` fg LEFT JOIN " . DB_PREFIX . "filter_group_description fgd ON (fg.filter_group_id = fgd.filter_group_id) WHERE fgd.language_id = '" . (int)$this->config->get('config_language_id') . "'";
+
+ $sort_data = array(
+ 'fgd.name',
+ 'fg.sort_order'
+ );
+
+ if (isset($data['sort']) && in_array($data['sort'], $sort_data)) {
+ $sql .= " ORDER BY " . $data['sort'];
+ } else {
+ $sql .= " ORDER BY fgd.name";
+ }
+
+ 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'];
+ }
+
+ $query = $this->db->query($sql);
+
+ return $query->rows;
+ }
+
+ public function getFilterGroupDescriptions($filter_group_id) {
+ $filter_group_data = array();
+
+ $query = $this->db->query("SELECT * FROM " . DB_PREFIX . "filter_group_description WHERE filter_group_id = '" . (int)$filter_group_id . "'");
+
+ foreach ($query->rows as $result) {
+ $filter_group_data[$result['language_id']] = array('name' => $result['name']);
+ }
+
+ return $filter_group_data;
+ }
+
+ public function getFilter($filter_id) {
+ $query = $this->db->query("SELECT *, (SELECT name FROM " . DB_PREFIX . "filter_group_description fgd WHERE f.filter_group_id = fgd.filter_group_id AND fgd.language_id = '" . (int)$this->config->get('config_language_id') . "') AS `group` FROM " . DB_PREFIX . "filter f LEFT JOIN " . DB_PREFIX . "filter_description fd ON (f.filter_id = fd.filter_id) WHERE f.filter_id = '" . (int)$filter_id . "' AND fd.language_id = '" . (int)$this->config->get('config_language_id') . "'");
+
+ return $query->row;
+ }
+
+ public function getFilters($data) {
+ $sql = "SELECT *, (SELECT name FROM " . DB_PREFIX . "filter_group_description fgd WHERE f.filter_group_id = fgd.filter_group_id AND fgd.language_id = '" . (int)$this->config->get('config_language_id') . "') AS `group` FROM " . DB_PREFIX . "filter f LEFT JOIN " . DB_PREFIX . "filter_description fd ON (f.filter_id = fd.filter_id) WHERE fd.language_id = '" . (int)$this->config->get('config_language_id') . "'";
+
+ if (!empty($data['filter_name'])) {
+ $sql .= " AND fd.name LIKE '" . $this->db->escape($data['filter_name']) . "%'";
+ }
+
+ $sql .= " ORDER BY f.sort_order 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'];
+ }
+
+ $query = $this->db->query($sql);
+
+ return $query->rows;
+ }
+
+ public function getFilterDescriptions($filter_group_id) {
+ $filter_data = array();
+
+ $filter_query = $this->db->query("SELECT * FROM " . DB_PREFIX . "filter WHERE filter_group_id = '" . (int)$filter_group_id . "'");
+
+ foreach ($filter_query->rows as $filter) {
+ $filter_description_data = array();
+
+ $filter_description_query = $this->db->query("SELECT * FROM " . DB_PREFIX . "filter_description WHERE filter_id = '" . (int)$filter['filter_id'] . "'");
+
+ foreach ($filter_description_query->rows as $filter_description) {
+ $filter_description_data[$filter_description['language_id']] = array('name' => $filter_description['name']);
+ }
+
+ $filter_data[] = array(
+ 'filter_id' => $filter['filter_id'],
+ 'filter_description' => $filter_description_data,
+ 'sort_order' => $filter['sort_order']
+ );
+ }
+
+ return $filter_data;
+ }
+
+ public function getTotalFilterGroups() {
+ $query = $this->db->query("SELECT COUNT(*) AS total FROM `" . DB_PREFIX . "filter_group`");
+
+ return $query->row['total'];
+ }
+}
diff --git a/public/admin/model/catalog/information.php b/public/admin/model/catalog/information.php
new file mode 100644
index 0000000..1b212de
--- /dev/null
+++ b/public/admin/model/catalog/information.php
@@ -0,0 +1,212 @@
+<?php
+class ModelCatalogInformation extends Model {
+ public function addInformation($data) {
+ $this->db->query("INSERT INTO " . DB_PREFIX . "information SET sort_order = '" . (int)$data['sort_order'] . "', bottom = '" . (isset($data['bottom']) ? (int)$data['bottom'] : 0) . "', status = '" . (int)$data['status'] . "'");
+
+ $information_id = $this->db->getLastId();
+
+ foreach ($data['information_description'] as $language_id => $value) {
+ $this->db->query("INSERT INTO " . DB_PREFIX . "information_description SET information_id = '" . (int)$information_id . "', language_id = '" . (int)$language_id . "', title = '" . $this->db->escape($value['title']) . "', description = '" . $this->db->escape($value['description']) . "', meta_title = '" . $this->db->escape($value['meta_title']) . "', meta_description = '" . $this->db->escape($value['meta_description']) . "', meta_keyword = '" . $this->db->escape($value['meta_keyword']) . "'");
+ }
+
+ if (isset($data['information_store'])) {
+ foreach ($data['information_store'] as $store_id) {
+ $this->db->query("INSERT INTO " . DB_PREFIX . "information_to_store SET information_id = '" . (int)$information_id . "', store_id = '" . (int)$store_id . "'");
+ }
+ }
+
+ // SEO URL
+ if (isset($data['information_seo_url'])) {
+ foreach ($data['information_seo_url'] as $store_id => $language) {
+ foreach ($language as $language_id => $keyword) {
+ if (!empty($keyword)) {
+ $this->db->query("INSERT INTO " . DB_PREFIX . "seo_url SET store_id = '" . (int)$store_id . "', language_id = '" . (int)$language_id . "', query = 'information_id=" . (int)$information_id . "', keyword = '" . $this->db->escape($keyword) . "'");
+ }
+ }
+ }
+ }
+
+ if (isset($data['information_layout'])) {
+ foreach ($data['information_layout'] as $store_id => $layout_id) {
+ $this->db->query("INSERT INTO " . DB_PREFIX . "information_to_layout SET information_id = '" . (int)$information_id . "', store_id = '" . (int)$store_id . "', layout_id = '" . (int)$layout_id . "'");
+ }
+ }
+
+ $this->cache->delete('information');
+
+ return $information_id;
+ }
+
+ public function editInformation($information_id, $data) {
+ $this->db->query("UPDATE " . DB_PREFIX . "information SET sort_order = '" . (int)$data['sort_order'] . "', bottom = '" . (isset($data['bottom']) ? (int)$data['bottom'] : 0) . "', status = '" . (int)$data['status'] . "' WHERE information_id = '" . (int)$information_id . "'");
+
+ $this->db->query("DELETE FROM " . DB_PREFIX . "information_description WHERE information_id = '" . (int)$information_id . "'");
+
+ foreach ($data['information_description'] as $language_id => $value) {
+ $this->db->query("INSERT INTO " . DB_PREFIX . "information_description SET information_id = '" . (int)$information_id . "', language_id = '" . (int)$language_id . "', title = '" . $this->db->escape($value['title']) . "', description = '" . $this->db->escape($value['description']) . "', meta_title = '" . $this->db->escape($value['meta_title']) . "', meta_description = '" . $this->db->escape($value['meta_description']) . "', meta_keyword = '" . $this->db->escape($value['meta_keyword']) . "'");
+ }
+
+ $this->db->query("DELETE FROM " . DB_PREFIX . "information_to_store WHERE information_id = '" . (int)$information_id . "'");
+
+ if (isset($data['information_store'])) {
+ foreach ($data['information_store'] as $store_id) {
+ $this->db->query("INSERT INTO " . DB_PREFIX . "information_to_store SET information_id = '" . (int)$information_id . "', store_id = '" . (int)$store_id . "'");
+ }
+ }
+
+ $this->db->query("DELETE FROM " . DB_PREFIX . "seo_url WHERE query = 'information_id=" . (int)$information_id . "'");
+
+ if (isset($data['information_seo_url'])) {
+ foreach ($data['information_seo_url'] as $store_id => $language) {
+ foreach ($language as $language_id => $keyword) {
+ if (trim($keyword)) {
+ $this->db->query("INSERT INTO `" . DB_PREFIX . "seo_url` SET store_id = '" . (int)$store_id . "', language_id = '" . (int)$language_id . "', query = 'information_id=" . (int)$information_id . "', keyword = '" . $this->db->escape($keyword) . "'");
+ }
+ }
+ }
+ }
+
+ $this->db->query("DELETE FROM `" . DB_PREFIX . "information_to_layout` WHERE information_id = '" . (int)$information_id . "'");
+
+ if (isset($data['information_layout'])) {
+ foreach ($data['information_layout'] as $store_id => $layout_id) {
+ $this->db->query("INSERT INTO `" . DB_PREFIX . "information_to_layout` SET information_id = '" . (int)$information_id . "', store_id = '" . (int)$store_id . "', layout_id = '" . (int)$layout_id . "'");
+ }
+ }
+
+ $this->cache->delete('information');
+ }
+
+ public function deleteInformation($information_id) {
+ $this->db->query("DELETE FROM `" . DB_PREFIX . "information` WHERE information_id = '" . (int)$information_id . "'");
+ $this->db->query("DELETE FROM `" . DB_PREFIX . "information_description` WHERE information_id = '" . (int)$information_id . "'");
+ $this->db->query("DELETE FROM `" . DB_PREFIX . "information_to_store` WHERE information_id = '" . (int)$information_id . "'");
+ $this->db->query("DELETE FROM `" . DB_PREFIX . "information_to_layout` WHERE information_id = '" . (int)$information_id . "'");
+ $this->db->query("DELETE FROM `" . DB_PREFIX . "seo_url` WHERE query = 'information_id=" . (int)$information_id . "'");
+
+ $this->cache->delete('information');
+ }
+
+ public function getInformation($information_id) {
+ $query = $this->db->query("SELECT DISTINCT * FROM " . DB_PREFIX . "information WHERE information_id = '" . (int)$information_id . "'");
+
+ return $query->row;
+ }
+
+ public function getInformations($data = array()) {
+ if ($data) {
+ $sql = "SELECT * FROM " . DB_PREFIX . "information i LEFT JOIN " . DB_PREFIX . "information_description id ON (i.information_id = id.information_id) WHERE id.language_id = '" . (int)$this->config->get('config_language_id') . "'";
+
+ $sort_data = array(
+ 'id.title',
+ 'i.sort_order'
+ );
+
+ if (isset($data['sort']) && in_array($data['sort'], $sort_data)) {
+ $sql .= " ORDER BY " . $data['sort'];
+ } else {
+ $sql .= " ORDER BY id.title";
+ }
+
+ 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'];
+ }
+
+ $query = $this->db->query($sql);
+
+ return $query->rows;
+ } else {
+ $information_data = $this->cache->get('information.' . (int)$this->config->get('config_language_id'));
+
+ if (!$information_data) {
+ $query = $this->db->query("SELECT * FROM " . DB_PREFIX . "information i LEFT JOIN " . DB_PREFIX . "information_description id ON (i.information_id = id.information_id) WHERE id.language_id = '" . (int)$this->config->get('config_language_id') . "' ORDER BY id.title");
+
+ $information_data = $query->rows;
+
+ $this->cache->set('information.' . (int)$this->config->get('config_language_id'), $information_data);
+ }
+
+ return $information_data;
+ }
+ }
+
+ public function getInformationDescriptions($information_id) {
+ $information_description_data = array();
+
+ $query = $this->db->query("SELECT * FROM " . DB_PREFIX . "information_description WHERE information_id = '" . (int)$information_id . "'");
+
+ foreach ($query->rows as $result) {
+ $information_description_data[$result['language_id']] = array(
+ 'title' => $result['title'],
+ 'description' => $result['description'],
+ 'meta_title' => $result['meta_title'],
+ 'meta_description' => $result['meta_description'],
+ 'meta_keyword' => $result['meta_keyword']
+ );
+ }
+
+ return $information_description_data;
+ }
+
+ public function getInformationStores($information_id) {
+ $information_store_data = array();
+
+ $query = $this->db->query("SELECT * FROM " . DB_PREFIX . "information_to_store WHERE information_id = '" . (int)$information_id . "'");
+
+ foreach ($query->rows as $result) {
+ $information_store_data[] = $result['store_id'];
+ }
+
+ return $information_store_data;
+ }
+
+ public function getInformationSeoUrls($information_id) {
+ $information_seo_url_data = array();
+
+ $query = $this->db->query("SELECT * FROM " . DB_PREFIX . "seo_url WHERE query = 'information_id=" . (int)$information_id . "'");
+
+ foreach ($query->rows as $result) {
+ $information_seo_url_data[$result['store_id']][$result['language_id']] = $result['keyword'];
+ }
+
+ return $information_seo_url_data;
+ }
+
+ public function getInformationLayouts($information_id) {
+ $information_layout_data = array();
+
+ $query = $this->db->query("SELECT * FROM " . DB_PREFIX . "information_to_layout WHERE information_id = '" . (int)$information_id . "'");
+
+ foreach ($query->rows as $result) {
+ $information_layout_data[$result['store_id']] = $result['layout_id'];
+ }
+
+ return $information_layout_data;
+ }
+
+ public function getTotalInformations() {
+ $query = $this->db->query("SELECT COUNT(*) AS total FROM " . DB_PREFIX . "information");
+
+ return $query->row['total'];
+ }
+
+ public function getTotalInformationsByLayoutId($layout_id) {
+ $query = $this->db->query("SELECT COUNT(*) AS total FROM " . DB_PREFIX . "information_to_layout WHERE layout_id = '" . (int)$layout_id . "'");
+
+ return $query->row['total'];
+ }
+} \ No newline at end of file
diff --git a/public/admin/model/catalog/manufacturer.php b/public/admin/model/catalog/manufacturer.php
new file mode 100644
index 0000000..7115694
--- /dev/null
+++ b/public/admin/model/catalog/manufacturer.php
@@ -0,0 +1,148 @@
+<?php
+class ModelCatalogManufacturer extends Model {
+ public function addManufacturer($data) {
+ $this->db->query("INSERT INTO " . DB_PREFIX . "manufacturer SET name = '" . $this->db->escape($data['name']) . "', sort_order = '" . (int)$data['sort_order'] . "'");
+
+ $manufacturer_id = $this->db->getLastId();
+
+ if (isset($data['image'])) {
+ $this->db->query("UPDATE " . DB_PREFIX . "manufacturer SET image = '" . $this->db->escape($data['image']) . "' WHERE manufacturer_id = '" . (int)$manufacturer_id . "'");
+ }
+
+ if (isset($data['manufacturer_store'])) {
+ foreach ($data['manufacturer_store'] as $store_id) {
+ $this->db->query("INSERT INTO " . DB_PREFIX . "manufacturer_to_store SET manufacturer_id = '" . (int)$manufacturer_id . "', store_id = '" . (int)$store_id . "'");
+ }
+ }
+
+ // SEO URL
+ if (isset($data['manufacturer_seo_url'])) {
+ foreach ($data['manufacturer_seo_url'] as $store_id => $language) {
+ foreach ($language as $language_id => $keyword) {
+ if (!empty($keyword)) {
+ $this->db->query("INSERT INTO " . DB_PREFIX . "seo_url SET store_id = '" . (int)$store_id . "', language_id = '" . (int)$language_id . "', query = 'manufacturer_id=" . (int)$manufacturer_id . "', keyword = '" . $this->db->escape($keyword) . "'");
+ }
+ }
+ }
+ }
+
+ $this->cache->delete('manufacturer');
+
+ return $manufacturer_id;
+ }
+
+ public function editManufacturer($manufacturer_id, $data) {
+ $this->db->query("UPDATE " . DB_PREFIX . "manufacturer SET name = '" . $this->db->escape($data['name']) . "', sort_order = '" . (int)$data['sort_order'] . "' WHERE manufacturer_id = '" . (int)$manufacturer_id . "'");
+
+ if (isset($data['image'])) {
+ $this->db->query("UPDATE " . DB_PREFIX . "manufacturer SET image = '" . $this->db->escape($data['image']) . "' WHERE manufacturer_id = '" . (int)$manufacturer_id . "'");
+ }
+
+ $this->db->query("DELETE FROM " . DB_PREFIX . "manufacturer_to_store WHERE manufacturer_id = '" . (int)$manufacturer_id . "'");
+
+ if (isset($data['manufacturer_store'])) {
+ foreach ($data['manufacturer_store'] as $store_id) {
+ $this->db->query("INSERT INTO " . DB_PREFIX . "manufacturer_to_store SET manufacturer_id = '" . (int)$manufacturer_id . "', store_id = '" . (int)$store_id . "'");
+ }
+ }
+
+ $this->db->query("DELETE FROM `" . DB_PREFIX . "seo_url` WHERE query = 'manufacturer_id=" . (int)$manufacturer_id . "'");
+
+ if (isset($data['manufacturer_seo_url'])) {
+ foreach ($data['manufacturer_seo_url'] as $store_id => $language) {
+ foreach ($language as $language_id => $keyword) {
+ if (!empty($keyword)) {
+ $this->db->query("INSERT INTO `" . DB_PREFIX . "seo_url` SET store_id = '" . (int)$store_id . "', language_id = '" . (int)$language_id . "', query = 'manufacturer_id=" . (int)$manufacturer_id . "', keyword = '" . $this->db->escape($keyword) . "'");
+ }
+ }
+ }
+ }
+
+ $this->cache->delete('manufacturer');
+ }
+
+ public function deleteManufacturer($manufacturer_id) {
+ $this->db->query("DELETE FROM `" . DB_PREFIX . "manufacturer` WHERE manufacturer_id = '" . (int)$manufacturer_id . "'");
+ $this->db->query("DELETE FROM `" . DB_PREFIX . "manufacturer_to_store` WHERE manufacturer_id = '" . (int)$manufacturer_id . "'");
+ $this->db->query("DELETE FROM `" . DB_PREFIX . "seo_url` WHERE query = 'manufacturer_id=" . (int)$manufacturer_id . "'");
+
+ $this->cache->delete('manufacturer');
+ }
+
+ public function getManufacturer($manufacturer_id) {
+ $query = $this->db->query("SELECT DISTINCT * FROM " . DB_PREFIX . "manufacturer WHERE manufacturer_id = '" . (int)$manufacturer_id . "'");
+
+ return $query->row;
+ }
+
+ public function getManufacturers($data = array()) {
+ $sql = "SELECT * FROM " . DB_PREFIX . "manufacturer";
+
+ if (!empty($data['filter_name'])) {
+ $sql .= " WHERE name LIKE '" . $this->db->escape($data['filter_name']) . "%'";
+ }
+
+ $sort_data = array(
+ 'name',
+ 'sort_order'
+ );
+
+ if (isset($data['sort']) && in_array($data['sort'], $sort_data)) {
+ $sql .= " ORDER BY " . $data['sort'];
+ } else {
+ $sql .= " ORDER BY name";
+ }
+
+ 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'];
+ }
+
+ $query = $this->db->query($sql);
+
+ return $query->rows;
+ }
+
+ public function getManufacturerStores($manufacturer_id) {
+ $manufacturer_store_data = array();
+
+ $query = $this->db->query("SELECT * FROM " . DB_PREFIX . "manufacturer_to_store WHERE manufacturer_id = '" . (int)$manufacturer_id . "'");
+
+ foreach ($query->rows as $result) {
+ $manufacturer_store_data[] = $result['store_id'];
+ }
+
+ return $manufacturer_store_data;
+ }
+
+ public function getManufacturerSeoUrls($manufacturer_id) {
+ $manufacturer_seo_url_data = array();
+
+ $query = $this->db->query("SELECT * FROM " . DB_PREFIX . "seo_url WHERE query = 'manufacturer_id=" . (int)$manufacturer_id . "'");
+
+ foreach ($query->rows as $result) {
+ $manufacturer_seo_url_data[$result['store_id']][$result['language_id']] = $result['keyword'];
+ }
+
+ return $manufacturer_seo_url_data;
+ }
+
+ public function getTotalManufacturers() {
+ $query = $this->db->query("SELECT COUNT(*) AS total FROM " . DB_PREFIX . "manufacturer");
+
+ return $query->row['total'];
+ }
+}
diff --git a/public/admin/model/catalog/option.php b/public/admin/model/catalog/option.php
new file mode 100644
index 0000000..dd8c17f
--- /dev/null
+++ b/public/admin/model/catalog/option.php
@@ -0,0 +1,177 @@
+<?php
+class ModelCatalogOption extends Model {
+ public function addOption($data) {
+ $this->db->query("INSERT INTO `" . DB_PREFIX . "option` SET type = '" . $this->db->escape($data['type']) . "', sort_order = '" . (int)$data['sort_order'] . "'");
+
+ $option_id = $this->db->getLastId();
+
+ foreach ($data['option_description'] as $language_id => $value) {
+ $this->db->query("INSERT INTO " . DB_PREFIX . "option_description SET option_id = '" . (int)$option_id . "', language_id = '" . (int)$language_id . "', name = '" . $this->db->escape($value['name']) . "'");
+ }
+
+ if (isset($data['option_value'])) {
+ foreach ($data['option_value'] as $option_value) {
+ $this->db->query("INSERT INTO " . DB_PREFIX . "option_value SET option_id = '" . (int)$option_id . "', image = '" . $this->db->escape(html_entity_decode($option_value['image'], ENT_QUOTES, 'UTF-8')) . "', sort_order = '" . (int)$option_value['sort_order'] . "'");
+
+ $option_value_id = $this->db->getLastId();
+
+ foreach ($option_value['option_value_description'] as $language_id => $option_value_description) {
+ $this->db->query("INSERT INTO " . DB_PREFIX . "option_value_description SET option_value_id = '" . (int)$option_value_id . "', language_id = '" . (int)$language_id . "', option_id = '" . (int)$option_id . "', name = '" . $this->db->escape($option_value_description['name']) . "'");
+ }
+ }
+ }
+
+ return $option_id;
+ }
+
+ public function editOption($option_id, $data) {
+ $this->db->query("UPDATE `" . DB_PREFIX . "option` SET type = '" . $this->db->escape($data['type']) . "', sort_order = '" . (int)$data['sort_order'] . "' WHERE option_id = '" . (int)$option_id . "'");
+
+ $this->db->query("DELETE FROM " . DB_PREFIX . "option_description WHERE option_id = '" . (int)$option_id . "'");
+
+ foreach ($data['option_description'] as $language_id => $value) {
+ $this->db->query("INSERT INTO " . DB_PREFIX . "option_description SET option_id = '" . (int)$option_id . "', language_id = '" . (int)$language_id . "', name = '" . $this->db->escape($value['name']) . "'");
+ }
+
+ $this->db->query("DELETE FROM " . DB_PREFIX . "option_value WHERE option_id = '" . (int)$option_id . "'");
+ $this->db->query("DELETE FROM " . DB_PREFIX . "option_value_description WHERE option_id = '" . (int)$option_id . "'");
+
+ if (isset($data['option_value'])) {
+ foreach ($data['option_value'] as $option_value) {
+ if ($option_value['option_value_id']) {
+ $this->db->query("INSERT INTO " . DB_PREFIX . "option_value SET option_value_id = '" . (int)$option_value['option_value_id'] . "', option_id = '" . (int)$option_id . "', image = '" . $this->db->escape(html_entity_decode($option_value['image'], ENT_QUOTES, 'UTF-8')) . "', sort_order = '" . (int)$option_value['sort_order'] . "'");
+ } else {
+ $this->db->query("INSERT INTO " . DB_PREFIX . "option_value SET option_id = '" . (int)$option_id . "', image = '" . $this->db->escape(html_entity_decode($option_value['image'], ENT_QUOTES, 'UTF-8')) . "', sort_order = '" . (int)$option_value['sort_order'] . "'");
+ }
+
+ $option_value_id = $this->db->getLastId();
+
+ foreach ($option_value['option_value_description'] as $language_id => $option_value_description) {
+ $this->db->query("INSERT INTO " . DB_PREFIX . "option_value_description SET option_value_id = '" . (int)$option_value_id . "', language_id = '" . (int)$language_id . "', option_id = '" . (int)$option_id . "', name = '" . $this->db->escape($option_value_description['name']) . "'");
+ }
+ }
+
+ }
+ }
+
+ public function deleteOption($option_id) {
+ $this->db->query("DELETE FROM `" . DB_PREFIX . "option` WHERE option_id = '" . (int)$option_id . "'");
+ $this->db->query("DELETE FROM " . DB_PREFIX . "option_description WHERE option_id = '" . (int)$option_id . "'");
+ $this->db->query("DELETE FROM " . DB_PREFIX . "option_value WHERE option_id = '" . (int)$option_id . "'");
+ $this->db->query("DELETE FROM " . DB_PREFIX . "option_value_description WHERE option_id = '" . (int)$option_id . "'");
+ }
+
+ public function getOption($option_id) {
+ $query = $this->db->query("SELECT * FROM `" . DB_PREFIX . "option` o LEFT JOIN " . DB_PREFIX . "option_description od ON (o.option_id = od.option_id) WHERE o.option_id = '" . (int)$option_id . "' AND od.language_id = '" . (int)$this->config->get('config_language_id') . "'");
+
+ return $query->row;
+ }
+
+ public function getOptions($data = array()) {
+ $sql = "SELECT * FROM `" . DB_PREFIX . "option` o LEFT JOIN " . DB_PREFIX . "option_description od ON (o.option_id = od.option_id) WHERE od.language_id = '" . (int)$this->config->get('config_language_id') . "'";
+
+ if (!empty($data['filter_name'])) {
+ $sql .= " AND od.name LIKE '" . $this->db->escape($data['filter_name']) . "%'";
+ }
+
+ $sort_data = array(
+ 'od.name',
+ 'o.type',
+ 'o.sort_order'
+ );
+
+ if (isset($data['sort']) && in_array($data['sort'], $sort_data)) {
+ $sql .= " ORDER BY " . $data['sort'];
+ } else {
+ $sql .= " ORDER BY od.name";
+ }
+
+ 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'];
+ }
+
+ $query = $this->db->query($sql);
+
+ return $query->rows;
+ }
+
+ public function getOptionDescriptions($option_id) {
+ $option_data = array();
+
+ $query = $this->db->query("SELECT * FROM " . DB_PREFIX . "option_description WHERE option_id = '" . (int)$option_id . "'");
+
+ foreach ($query->rows as $result) {
+ $option_data[$result['language_id']] = array('name' => $result['name']);
+ }
+
+ return $option_data;
+ }
+
+ public function getOptionValue($option_value_id) {
+ $query = $this->db->query("SELECT * FROM " . DB_PREFIX . "option_value ov LEFT JOIN " . DB_PREFIX . "option_value_description ovd ON (ov.option_value_id = ovd.option_value_id) WHERE ov.option_value_id = '" . (int)$option_value_id . "' AND ovd.language_id = '" . (int)$this->config->get('config_language_id') . "'");
+
+ return $query->row;
+ }
+
+ public function getOptionValues($option_id) {
+ $option_value_data = array();
+
+ $option_value_query = $this->db->query("SELECT * FROM " . DB_PREFIX . "option_value ov LEFT JOIN " . DB_PREFIX . "option_value_description ovd ON (ov.option_value_id = ovd.option_value_id) WHERE ov.option_id = '" . (int)$option_id . "' AND ovd.language_id = '" . (int)$this->config->get('config_language_id') . "' ORDER BY ov.sort_order, ovd.name");
+
+ foreach ($option_value_query->rows as $option_value) {
+ $option_value_data[] = array(
+ 'option_value_id' => $option_value['option_value_id'],
+ 'name' => $option_value['name'],
+ 'image' => $option_value['image'],
+ 'sort_order' => $option_value['sort_order']
+ );
+ }
+
+ return $option_value_data;
+ }
+
+ public function getOptionValueDescriptions($option_id) {
+ $option_value_data = array();
+
+ $option_value_query = $this->db->query("SELECT * FROM " . DB_PREFIX . "option_value WHERE option_id = '" . (int)$option_id . "' ORDER BY sort_order");
+
+ foreach ($option_value_query->rows as $option_value) {
+ $option_value_description_data = array();
+
+ $option_value_description_query = $this->db->query("SELECT * FROM " . DB_PREFIX . "option_value_description WHERE option_value_id = '" . (int)$option_value['option_value_id'] . "'");
+
+ foreach ($option_value_description_query->rows as $option_value_description) {
+ $option_value_description_data[$option_value_description['language_id']] = array('name' => $option_value_description['name']);
+ }
+
+ $option_value_data[] = array(
+ 'option_value_id' => $option_value['option_value_id'],
+ 'option_value_description' => $option_value_description_data,
+ 'image' => $option_value['image'],
+ 'sort_order' => $option_value['sort_order']
+ );
+ }
+
+ return $option_value_data;
+ }
+
+ public function getTotalOptions() {
+ $query = $this->db->query("SELECT COUNT(*) AS total FROM `" . DB_PREFIX . "option`");
+
+ return $query->row['total'];
+ }
+} \ No newline at end of file
diff --git a/public/admin/model/catalog/product.php b/public/admin/model/catalog/product.php
new file mode 100644
index 0000000..7d3c0be
--- /dev/null
+++ b/public/admin/model/catalog/product.php
@@ -0,0 +1,723 @@
+<?php
+class ModelCatalogProduct extends Model {
+ public function addProduct($data) {
+ $this->db->query("INSERT INTO " . DB_PREFIX . "product SET model = '" . $this->db->escape($data['model']) . "', sku = '" . $this->db->escape($data['sku']) . "', upc = '" . $this->db->escape($data['upc']) . "', ean = '" . $this->db->escape($data['ean']) . "', jan = '" . $this->db->escape($data['jan']) . "', isbn = '" . $this->db->escape($data['isbn']) . "', mpn = '" . $this->db->escape($data['mpn']) . "', location = '" . $this->db->escape($data['location']) . "', quantity = '" . (int)$data['quantity'] . "', minimum = '" . (int)$data['minimum'] . "', subtract = '" . (int)$data['subtract'] . "', stock_status_id = '" . (int)$data['stock_status_id'] . "', date_available = '" . $this->db->escape($data['date_available']) . "', manufacturer_id = '" . (int)$data['manufacturer_id'] . "', shipping = '" . (int)$data['shipping'] . "', price = '" . (float)$data['price'] . "', points = '" . (int)$data['points'] . "', weight = '" . (float)$data['weight'] . "', weight_class_id = '" . (int)$data['weight_class_id'] . "', length = '" . (float)$data['length'] . "', width = '" . (float)$data['width'] . "', height = '" . (float)$data['height'] . "', length_class_id = '" . (int)$data['length_class_id'] . "', status = '" . (int)$data['status'] . "', tax_class_id = '" . (int)$data['tax_class_id'] . "', sort_order = '" . (int)$data['sort_order'] . "', date_added = NOW(), date_modified = NOW()");
+
+ $product_id = $this->db->getLastId();
+
+ if (isset($data['image'])) {
+ $this->db->query("UPDATE " . DB_PREFIX . "product SET image = '" . $this->db->escape($data['image']) . "' WHERE product_id = '" . (int)$product_id . "'");
+ }
+
+ foreach ($data['product_description'] as $language_id => $value) {
+ $this->db->query("INSERT INTO " . DB_PREFIX . "product_description SET product_id = '" . (int)$product_id . "', language_id = '" . (int)$language_id . "', name = '" . $this->db->escape($value['name']) . "', description = '" . $this->db->escape($value['description']) . "', tag = '" . $this->db->escape($value['tag']) . "', meta_title = '" . $this->db->escape($value['meta_title']) . "', meta_description = '" . $this->db->escape($value['meta_description']) . "', meta_keyword = '" . $this->db->escape($value['meta_keyword']) . "'");
+ }
+
+ if (isset($data['product_store'])) {
+ foreach ($data['product_store'] as $store_id) {
+ $this->db->query("INSERT INTO " . DB_PREFIX . "product_to_store SET product_id = '" . (int)$product_id . "', store_id = '" . (int)$store_id . "'");
+ }
+ }
+
+ if (isset($data['product_attribute'])) {
+ foreach ($data['product_attribute'] as $product_attribute) {
+ if ($product_attribute['attribute_id']) {
+ // Removes duplicates
+ $this->db->query("DELETE FROM " . DB_PREFIX . "product_attribute WHERE product_id = '" . (int)$product_id . "' AND attribute_id = '" . (int)$product_attribute['attribute_id'] . "'");
+
+ foreach ($product_attribute['product_attribute_description'] as $language_id => $product_attribute_description) {
+ $this->db->query("DELETE FROM " . DB_PREFIX . "product_attribute WHERE product_id = '" . (int)$product_id . "' AND attribute_id = '" . (int)$product_attribute['attribute_id'] . "' AND language_id = '" . (int)$language_id . "'");
+
+ $this->db->query("INSERT INTO " . DB_PREFIX . "product_attribute SET product_id = '" . (int)$product_id . "', attribute_id = '" . (int)$product_attribute['attribute_id'] . "', language_id = '" . (int)$language_id . "', text = '" . $this->db->escape($product_attribute_description['text']) . "'");
+ }
+ }
+ }
+ }
+
+ if (isset($data['product_option'])) {
+ foreach ($data['product_option'] as $product_option) {
+ if ($product_option['type'] == 'select' || $product_option['type'] == 'radio' || $product_option['type'] == 'checkbox' || $product_option['type'] == 'image') {
+ if (isset($product_option['product_option_value'])) {
+ $this->db->query("INSERT INTO " . DB_PREFIX . "product_option SET product_id = '" . (int)$product_id . "', option_id = '" . (int)$product_option['option_id'] . "', required = '" . (int)$product_option['required'] . "'");
+
+ $product_option_id = $this->db->getLastId();
+
+ foreach ($product_option['product_option_value'] as $product_option_value) {
+ $this->db->query("INSERT INTO " . DB_PREFIX . "product_option_value SET product_option_id = '" . (int)$product_option_id . "', product_id = '" . (int)$product_id . "', option_id = '" . (int)$product_option['option_id'] . "', option_value_id = '" . (int)$product_option_value['option_value_id'] . "', quantity = '" . (int)$product_option_value['quantity'] . "', subtract = '" . (int)$product_option_value['subtract'] . "', price = '" . (float)$product_option_value['price'] . "', price_prefix = '" . $this->db->escape($product_option_value['price_prefix']) . "', points = '" . (int)$product_option_value['points'] . "', points_prefix = '" . $this->db->escape($product_option_value['points_prefix']) . "', weight = '" . (float)$product_option_value['weight'] . "', weight_prefix = '" . $this->db->escape($product_option_value['weight_prefix']) . "'");
+ }
+ }
+ } else {
+ $this->db->query("INSERT INTO " . DB_PREFIX . "product_option SET product_id = '" . (int)$product_id . "', option_id = '" . (int)$product_option['option_id'] . "', value = '" . $this->db->escape($product_option['value']) . "', required = '" . (int)$product_option['required'] . "'");
+ }
+ }
+ }
+
+ if (isset($data['product_recurring'])) {
+ foreach ($data['product_recurring'] as $recurring) {
+ $this->db->query("INSERT INTO `" . DB_PREFIX . "product_recurring` SET `product_id` = " . (int)$product_id . ", customer_group_id = " . (int)$recurring['customer_group_id'] . ", `recurring_id` = " . (int)$recurring['recurring_id']);
+ }
+ }
+
+ if (isset($data['product_discount'])) {
+ foreach ($data['product_discount'] as $product_discount) {
+ $this->db->query("INSERT INTO " . DB_PREFIX . "product_discount SET product_id = '" . (int)$product_id . "', customer_group_id = '" . (int)$product_discount['customer_group_id'] . "', quantity = '" . (int)$product_discount['quantity'] . "', priority = '" . (int)$product_discount['priority'] . "', price = '" . (float)$product_discount['price'] . "', date_start = '" . $this->db->escape($product_discount['date_start']) . "', date_end = '" . $this->db->escape($product_discount['date_end']) . "'");
+ }
+ }
+
+ if (isset($data['product_special'])) {
+ foreach ($data['product_special'] as $product_special) {
+ $this->db->query("INSERT INTO " . DB_PREFIX . "product_special SET product_id = '" . (int)$product_id . "', customer_group_id = '" . (int)$product_special['customer_group_id'] . "', priority = '" . (int)$product_special['priority'] . "', price = '" . (float)$product_special['price'] . "', date_start = '" . $this->db->escape($product_special['date_start']) . "', date_end = '" . $this->db->escape($product_special['date_end']) . "'");
+ }
+ }
+
+ if (isset($data['product_image'])) {
+ foreach ($data['product_image'] as $product_image) {
+ $this->db->query("INSERT INTO " . DB_PREFIX . "product_image SET product_id = '" . (int)$product_id . "', image = '" . $this->db->escape($product_image['image']) . "', sort_order = '" . (int)$product_image['sort_order'] . "'");
+ }
+ }
+
+ if (isset($data['product_download'])) {
+ foreach ($data['product_download'] as $download_id) {
+ $this->db->query("INSERT INTO " . DB_PREFIX . "product_to_download SET product_id = '" . (int)$product_id . "', download_id = '" . (int)$download_id . "'");
+ }
+ }
+
+ if (isset($data['product_category'])) {
+ foreach ($data['product_category'] as $category_id) {
+ $this->db->query("INSERT INTO " . DB_PREFIX . "product_to_category SET product_id = '" . (int)$product_id . "', category_id = '" . (int)$category_id . "'");
+ }
+ }
+
+ if (isset($data['product_filter'])) {
+ foreach ($data['product_filter'] as $filter_id) {
+ $this->db->query("INSERT INTO " . DB_PREFIX . "product_filter SET product_id = '" . (int)$product_id . "', filter_id = '" . (int)$filter_id . "'");
+ }
+ }
+
+ if (isset($data['product_related'])) {
+ foreach ($data['product_related'] as $related_id) {
+ $this->db->query("DELETE FROM " . DB_PREFIX . "product_related WHERE product_id = '" . (int)$product_id . "' AND related_id = '" . (int)$related_id . "'");
+ $this->db->query("INSERT INTO " . DB_PREFIX . "product_related SET product_id = '" . (int)$product_id . "', related_id = '" . (int)$related_id . "'");
+ $this->db->query("DELETE FROM " . DB_PREFIX . "product_related WHERE product_id = '" . (int)$related_id . "' AND related_id = '" . (int)$product_id . "'");
+ $this->db->query("INSERT INTO " . DB_PREFIX . "product_related SET product_id = '" . (int)$related_id . "', related_id = '" . (int)$product_id . "'");
+ }
+ }
+
+ if (isset($data['product_reward'])) {
+ foreach ($data['product_reward'] as $customer_group_id => $product_reward) {
+ if ((int)$product_reward['points'] > 0) {
+ $this->db->query("INSERT INTO " . DB_PREFIX . "product_reward SET product_id = '" . (int)$product_id . "', customer_group_id = '" . (int)$customer_group_id . "', points = '" . (int)$product_reward['points'] . "'");
+ }
+ }
+ }
+
+ // SEO URL
+ if (isset($data['product_seo_url'])) {
+ foreach ($data['product_seo_url'] as $store_id => $language) {
+ foreach ($language as $language_id => $keyword) {
+ if (!empty($keyword)) {
+ $this->db->query("INSERT INTO " . DB_PREFIX . "seo_url SET store_id = '" . (int)$store_id . "', language_id = '" . (int)$language_id . "', query = 'product_id=" . (int)$product_id . "', keyword = '" . $this->db->escape($keyword) . "'");
+ }
+ }
+ }
+ }
+
+ if (isset($data['product_layout'])) {
+ foreach ($data['product_layout'] as $store_id => $layout_id) {
+ $this->db->query("INSERT INTO " . DB_PREFIX . "product_to_layout SET product_id = '" . (int)$product_id . "', store_id = '" . (int)$store_id . "', layout_id = '" . (int)$layout_id . "'");
+ }
+ }
+
+
+ $this->cache->delete('product');
+
+ return $product_id;
+ }
+
+ public function editProduct($product_id, $data) {
+ $this->db->query("UPDATE " . DB_PREFIX . "product SET model = '" . $this->db->escape($data['model']) . "', sku = '" . $this->db->escape($data['sku']) . "', upc = '" . $this->db->escape($data['upc']) . "', ean = '" . $this->db->escape($data['ean']) . "', jan = '" . $this->db->escape($data['jan']) . "', isbn = '" . $this->db->escape($data['isbn']) . "', mpn = '" . $this->db->escape($data['mpn']) . "', location = '" . $this->db->escape($data['location']) . "', quantity = '" . (int)$data['quantity'] . "', minimum = '" . (int)$data['minimum'] . "', subtract = '" . (int)$data['subtract'] . "', stock_status_id = '" . (int)$data['stock_status_id'] . "', date_available = '" . $this->db->escape($data['date_available']) . "', manufacturer_id = '" . (int)$data['manufacturer_id'] . "', shipping = '" . (int)$data['shipping'] . "', price = '" . (float)$data['price'] . "', points = '" . (int)$data['points'] . "', weight = '" . (float)$data['weight'] . "', weight_class_id = '" . (int)$data['weight_class_id'] . "', length = '" . (float)$data['length'] . "', width = '" . (float)$data['width'] . "', height = '" . (float)$data['height'] . "', length_class_id = '" . (int)$data['length_class_id'] . "', status = '" . (int)$data['status'] . "', tax_class_id = '" . (int)$data['tax_class_id'] . "', sort_order = '" . (int)$data['sort_order'] . "', date_modified = NOW() WHERE product_id = '" . (int)$product_id . "'");
+
+ if (isset($data['image'])) {
+ $this->db->query("UPDATE " . DB_PREFIX . "product SET image = '" . $this->db->escape($data['image']) . "' WHERE product_id = '" . (int)$product_id . "'");
+ }
+
+ $this->db->query("DELETE FROM " . DB_PREFIX . "product_description WHERE product_id = '" . (int)$product_id . "'");
+
+ foreach ($data['product_description'] as $language_id => $value) {
+ $this->db->query("INSERT INTO " . DB_PREFIX . "product_description SET product_id = '" . (int)$product_id . "', language_id = '" . (int)$language_id . "', name = '" . $this->db->escape($value['name']) . "', description = '" . $this->db->escape($value['description']) . "', tag = '" . $this->db->escape($value['tag']) . "', meta_title = '" . $this->db->escape($value['meta_title']) . "', meta_description = '" . $this->db->escape($value['meta_description']) . "', meta_keyword = '" . $this->db->escape($value['meta_keyword']) . "'");
+ }
+
+ $this->db->query("DELETE FROM " . DB_PREFIX . "product_to_store WHERE product_id = '" . (int)$product_id . "'");
+
+ if (isset($data['product_store'])) {
+ foreach ($data['product_store'] as $store_id) {
+ $this->db->query("INSERT INTO " . DB_PREFIX . "product_to_store SET product_id = '" . (int)$product_id . "', store_id = '" . (int)$store_id . "'");
+ }
+ }
+
+ $this->db->query("DELETE FROM " . DB_PREFIX . "product_attribute WHERE product_id = '" . (int)$product_id . "'");
+
+ if (!empty($data['product_attribute'])) {
+ foreach ($data['product_attribute'] as $product_attribute) {
+ if ($product_attribute['attribute_id']) {
+ // Removes duplicates
+ $this->db->query("DELETE FROM " . DB_PREFIX . "product_attribute WHERE product_id = '" . (int)$product_id . "' AND attribute_id = '" . (int)$product_attribute['attribute_id'] . "'");
+
+ foreach ($product_attribute['product_attribute_description'] as $language_id => $product_attribute_description) {
+ $this->db->query("INSERT INTO " . DB_PREFIX . "product_attribute SET product_id = '" . (int)$product_id . "', attribute_id = '" . (int)$product_attribute['attribute_id'] . "', language_id = '" . (int)$language_id . "', text = '" . $this->db->escape($product_attribute_description['text']) . "'");
+ }
+ }
+ }
+ }
+
+ $this->db->query("DELETE FROM " . DB_PREFIX . "product_option WHERE product_id = '" . (int)$product_id . "'");
+ $this->db->query("DELETE FROM " . DB_PREFIX . "product_option_value WHERE product_id = '" . (int)$product_id . "'");
+
+ if (isset($data['product_option'])) {
+ foreach ($data['product_option'] as $product_option) {
+ if ($product_option['type'] == 'select' || $product_option['type'] == 'radio' || $product_option['type'] == 'checkbox' || $product_option['type'] == 'image') {
+ if (isset($product_option['product_option_value'])) {
+ $this->db->query("INSERT INTO " . DB_PREFIX . "product_option SET product_option_id = '" . (int)$product_option['product_option_id'] . "', product_id = '" . (int)$product_id . "', option_id = '" . (int)$product_option['option_id'] . "', required = '" . (int)$product_option['required'] . "'");
+
+ $product_option_id = $this->db->getLastId();
+
+ foreach ($product_option['product_option_value'] as $product_option_value) {
+ $this->db->query("INSERT INTO " . DB_PREFIX . "product_option_value SET product_option_value_id = '" . (int)$product_option_value['product_option_value_id'] . "', product_option_id = '" . (int)$product_option_id . "', product_id = '" . (int)$product_id . "', option_id = '" . (int)$product_option['option_id'] . "', option_value_id = '" . (int)$product_option_value['option_value_id'] . "', quantity = '" . (int)$product_option_value['quantity'] . "', subtract = '" . (int)$product_option_value['subtract'] . "', price = '" . (float)$product_option_value['price'] . "', price_prefix = '" . $this->db->escape($product_option_value['price_prefix']) . "', points = '" . (int)$product_option_value['points'] . "', points_prefix = '" . $this->db->escape($product_option_value['points_prefix']) . "', weight = '" . (float)$product_option_value['weight'] . "', weight_prefix = '" . $this->db->escape($product_option_value['weight_prefix']) . "'");
+ }
+ }
+ } else {
+ $this->db->query("INSERT INTO " . DB_PREFIX . "product_option SET product_option_id = '" . (int)$product_option['product_option_id'] . "', product_id = '" . (int)$product_id . "', option_id = '" . (int)$product_option['option_id'] . "', value = '" . $this->db->escape($product_option['value']) . "', required = '" . (int)$product_option['required'] . "'");
+ }
+ }
+ }
+
+ $this->db->query("DELETE FROM `" . DB_PREFIX . "product_recurring` WHERE product_id = " . (int)$product_id);
+
+ if (isset($data['product_recurring'])) {
+ foreach ($data['product_recurring'] as $product_recurring) {
+ $this->db->query("INSERT INTO `" . DB_PREFIX . "product_recurring` SET `product_id` = " . (int)$product_id . ", customer_group_id = " . (int)$product_recurring['customer_group_id'] . ", `recurring_id` = " . (int)$product_recurring['recurring_id']);
+ }
+ }
+
+ $this->db->query("DELETE FROM " . DB_PREFIX . "product_discount WHERE product_id = '" . (int)$product_id . "'");
+
+ if (isset($data['product_discount'])) {
+ foreach ($data['product_discount'] as $product_discount) {
+ $this->db->query("INSERT INTO " . DB_PREFIX . "product_discount SET product_id = '" . (int)$product_id . "', customer_group_id = '" . (int)$product_discount['customer_group_id'] . "', quantity = '" . (int)$product_discount['quantity'] . "', priority = '" . (int)$product_discount['priority'] . "', price = '" . (float)$product_discount['price'] . "', date_start = '" . $this->db->escape($product_discount['date_start']) . "', date_end = '" . $this->db->escape($product_discount['date_end']) . "'");
+ }
+ }
+
+ $this->db->query("DELETE FROM " . DB_PREFIX . "product_special WHERE product_id = '" . (int)$product_id . "'");
+
+ if (isset($data['product_special'])) {
+ foreach ($data['product_special'] as $product_special) {
+ $this->db->query("INSERT INTO " . DB_PREFIX . "product_special SET product_id = '" . (int)$product_id . "', customer_group_id = '" . (int)$product_special['customer_group_id'] . "', priority = '" . (int)$product_special['priority'] . "', price = '" . (float)$product_special['price'] . "', date_start = '" . $this->db->escape($product_special['date_start']) . "', date_end = '" . $this->db->escape($product_special['date_end']) . "'");
+ }
+ }
+
+ $this->db->query("DELETE FROM " . DB_PREFIX . "product_image WHERE product_id = '" . (int)$product_id . "'");
+
+ if (isset($data['product_image'])) {
+ foreach ($data['product_image'] as $product_image) {
+ $this->db->query("INSERT INTO " . DB_PREFIX . "product_image SET product_id = '" . (int)$product_id . "', image = '" . $this->db->escape($product_image['image']) . "', sort_order = '" . (int)$product_image['sort_order'] . "'");
+ }
+ }
+
+ $this->db->query("DELETE FROM " . DB_PREFIX . "product_to_download WHERE product_id = '" . (int)$product_id . "'");
+
+ if (isset($data['product_download'])) {
+ foreach ($data['product_download'] as $download_id) {
+ $this->db->query("INSERT INTO " . DB_PREFIX . "product_to_download SET product_id = '" . (int)$product_id . "', download_id = '" . (int)$download_id . "'");
+ }
+ }
+
+ $this->db->query("DELETE FROM " . DB_PREFIX . "product_to_category WHERE product_id = '" . (int)$product_id . "'");
+
+ if (isset($data['product_category'])) {
+ foreach ($data['product_category'] as $category_id) {
+ $this->db->query("INSERT INTO " . DB_PREFIX . "product_to_category SET product_id = '" . (int)$product_id . "', category_id = '" . (int)$category_id . "'");
+ }
+ }
+
+ $this->db->query("DELETE FROM " . DB_PREFIX . "product_filter WHERE product_id = '" . (int)$product_id . "'");
+
+ if (isset($data['product_filter'])) {
+ foreach ($data['product_filter'] as $filter_id) {
+ $this->db->query("INSERT INTO " . DB_PREFIX . "product_filter SET product_id = '" . (int)$product_id . "', filter_id = '" . (int)$filter_id . "'");
+ }
+ }
+
+ $this->db->query("DELETE FROM " . DB_PREFIX . "product_related WHERE product_id = '" . (int)$product_id . "'");
+ $this->db->query("DELETE FROM " . DB_PREFIX . "product_related WHERE related_id = '" . (int)$product_id . "'");
+
+ if (isset($data['product_related'])) {
+ foreach ($data['product_related'] as $related_id) {
+ $this->db->query("DELETE FROM " . DB_PREFIX . "product_related WHERE product_id = '" . (int)$product_id . "' AND related_id = '" . (int)$related_id . "'");
+ $this->db->query("INSERT INTO " . DB_PREFIX . "product_related SET product_id = '" . (int)$product_id . "', related_id = '" . (int)$related_id . "'");
+ $this->db->query("DELETE FROM " . DB_PREFIX . "product_related WHERE product_id = '" . (int)$related_id . "' AND related_id = '" . (int)$product_id . "'");
+ $this->db->query("INSERT INTO " . DB_PREFIX . "product_related SET product_id = '" . (int)$related_id . "', related_id = '" . (int)$product_id . "'");
+ }
+ }
+
+ $this->db->query("DELETE FROM " . DB_PREFIX . "product_reward WHERE product_id = '" . (int)$product_id . "'");
+
+ if (isset($data['product_reward'])) {
+ foreach ($data['product_reward'] as $customer_group_id => $value) {
+ if ((int)$value['points'] > 0) {
+ $this->db->query("INSERT INTO " . DB_PREFIX . "product_reward SET product_id = '" . (int)$product_id . "', customer_group_id = '" . (int)$customer_group_id . "', points = '" . (int)$value['points'] . "'");
+ }
+ }
+ }
+
+ // SEO URL
+ $this->db->query("DELETE FROM " . DB_PREFIX . "seo_url WHERE query = 'product_id=" . (int)$product_id . "'");
+
+ if (isset($data['product_seo_url'])) {
+ foreach ($data['product_seo_url']as $store_id => $language) {
+ foreach ($language as $language_id => $keyword) {
+ if (!empty($keyword)) {
+ $this->db->query("INSERT INTO " . DB_PREFIX . "seo_url SET store_id = '" . (int)$store_id . "', language_id = '" . (int)$language_id . "', query = 'product_id=" . (int)$product_id . "', keyword = '" . $this->db->escape($keyword) . "'");
+ }
+ }
+ }
+ }
+
+ $this->db->query("DELETE FROM " . DB_PREFIX . "product_to_layout WHERE product_id = '" . (int)$product_id . "'");
+
+ if (isset($data['product_layout'])) {
+ foreach ($data['product_layout'] as $store_id => $layout_id) {
+ $this->db->query("INSERT INTO " . DB_PREFIX . "product_to_layout SET product_id = '" . (int)$product_id . "', store_id = '" . (int)$store_id . "', layout_id = '" . (int)$layout_id . "'");
+ }
+ }
+
+ $this->cache->delete('product');
+ }
+
+ public function copyProduct($product_id) {
+ $query = $this->db->query("SELECT DISTINCT * FROM " . DB_PREFIX . "product p WHERE p.product_id = '" . (int)$product_id . "'");
+
+ if ($query->num_rows) {
+ $data = $query->row;
+
+ $data['sku'] = '';
+ $data['upc'] = '';
+ $data['viewed'] = '0';
+ $data['keyword'] = '';
+ $data['status'] = '0';
+
+ $data['product_attribute'] = $this->getProductAttributes($product_id);
+ $data['product_description'] = $this->getProductDescriptions($product_id);
+ $data['product_discount'] = $this->getProductDiscounts($product_id);
+ $data['product_filter'] = $this->getProductFilters($product_id);
+ $data['product_image'] = $this->getProductImages($product_id);
+ $data['product_option'] = $this->getProductOptions($product_id);
+ $data['product_related'] = $this->getProductRelated($product_id);
+ $data['product_reward'] = $this->getProductRewards($product_id);
+ $data['product_special'] = $this->getProductSpecials($product_id);
+ $data['product_category'] = $this->getProductCategories($product_id);
+ $data['product_download'] = $this->getProductDownloads($product_id);
+ $data['product_layout'] = $this->getProductLayouts($product_id);
+ $data['product_store'] = $this->getProductStores($product_id);
+ $data['product_recurrings'] = $this->getRecurrings($product_id);
+
+ $this->addProduct($data);
+ }
+ }
+
+ public function deleteProduct($product_id) {
+ $this->db->query("DELETE FROM " . DB_PREFIX . "product WHERE product_id = '" . (int)$product_id . "'");
+ $this->db->query("DELETE FROM " . DB_PREFIX . "product_attribute WHERE product_id = '" . (int)$product_id . "'");
+ $this->db->query("DELETE FROM " . DB_PREFIX . "product_description WHERE product_id = '" . (int)$product_id . "'");
+ $this->db->query("DELETE FROM " . DB_PREFIX . "product_discount WHERE product_id = '" . (int)$product_id . "'");
+ $this->db->query("DELETE FROM " . DB_PREFIX . "product_filter WHERE product_id = '" . (int)$product_id . "'");
+ $this->db->query("DELETE FROM " . DB_PREFIX . "product_image WHERE product_id = '" . (int)$product_id . "'");
+ $this->db->query("DELETE FROM " . DB_PREFIX . "product_option WHERE product_id = '" . (int)$product_id . "'");
+ $this->db->query("DELETE FROM " . DB_PREFIX . "product_option_value WHERE product_id = '" . (int)$product_id . "'");
+ $this->db->query("DELETE FROM " . DB_PREFIX . "product_related WHERE product_id = '" . (int)$product_id . "'");
+ $this->db->query("DELETE FROM " . DB_PREFIX . "product_related WHERE related_id = '" . (int)$product_id . "'");
+ $this->db->query("DELETE FROM " . DB_PREFIX . "product_reward WHERE product_id = '" . (int)$product_id . "'");
+ $this->db->query("DELETE FROM " . DB_PREFIX . "product_special WHERE product_id = '" . (int)$product_id . "'");
+ $this->db->query("DELETE FROM " . DB_PREFIX . "product_to_category WHERE product_id = '" . (int)$product_id . "'");
+ $this->db->query("DELETE FROM " . DB_PREFIX . "product_to_download WHERE product_id = '" . (int)$product_id . "'");
+ $this->db->query("DELETE FROM " . DB_PREFIX . "product_to_layout WHERE product_id = '" . (int)$product_id . "'");
+ $this->db->query("DELETE FROM " . DB_PREFIX . "product_to_store WHERE product_id = '" . (int)$product_id . "'");
+ $this->db->query("DELETE FROM " . DB_PREFIX . "product_recurring WHERE product_id = " . (int)$product_id);
+ $this->db->query("DELETE FROM " . DB_PREFIX . "review WHERE product_id = '" . (int)$product_id . "'");
+ $this->db->query("DELETE FROM " . DB_PREFIX . "seo_url WHERE query = 'product_id=" . (int)$product_id . "'");
+ $this->db->query("DELETE FROM " . DB_PREFIX . "coupon_product WHERE product_id = '" . (int)$product_id . "'");
+
+ $this->cache->delete('product');
+ }
+
+ public function getProduct($product_id) {
+ $query = $this->db->query("SELECT DISTINCT * FROM " . DB_PREFIX . "product p LEFT JOIN " . DB_PREFIX . "product_description pd ON (p.product_id = pd.product_id) WHERE p.product_id = '" . (int)$product_id . "' AND pd.language_id = '" . (int)$this->config->get('config_language_id') . "'");
+
+ return $query->row;
+ }
+
+ public function getProducts($data = array()) {
+ $sql = "SELECT * FROM " . DB_PREFIX . "product p LEFT JOIN " . DB_PREFIX . "product_description pd ON (p.product_id = pd.product_id) WHERE pd.language_id = '" . (int)$this->config->get('config_language_id') . "'";
+
+ if (!empty($data['filter_name'])) {
+ $sql .= " AND pd.name LIKE '" . $this->db->escape($data['filter_name']) . "%'";
+ }
+
+ if (!empty($data['filter_model'])) {
+ $sql .= " AND p.model LIKE '" . $this->db->escape($data['filter_model']) . "%'";
+ }
+
+ if (!empty($data['filter_price'])) {
+ $sql .= " AND p.price LIKE '" . $this->db->escape($data['filter_price']) . "%'";
+ }
+
+ if (isset($data['filter_quantity']) && $data['filter_quantity'] !== '') {
+ $sql .= " AND p.quantity = '" . (int)$data['filter_quantity'] . "'";
+ }
+
+ if (isset($data['filter_status']) && $data['filter_status'] !== '') {
+ $sql .= " AND p.status = '" . (int)$data['filter_status'] . "'";
+ }
+
+ $sql .= " GROUP BY p.product_id";
+
+ $sort_data = array(
+ 'pd.name',
+ 'p.model',
+ 'p.price',
+ 'p.quantity',
+ 'p.status',
+ 'p.sort_order'
+ );
+
+ if (isset($data['sort']) && in_array($data['sort'], $sort_data)) {
+ $sql .= " ORDER BY " . $data['sort'];
+ } else {
+ $sql .= " ORDER BY pd.name";
+ }
+
+ 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'];
+ }
+
+ $query = $this->db->query($sql);
+
+ return $query->rows;
+ }
+
+ public function getProductsByCategoryId($category_id) {
+ $query = $this->db->query("SELECT * FROM " . DB_PREFIX . "product p LEFT JOIN " . DB_PREFIX . "product_description pd ON (p.product_id = pd.product_id) LEFT JOIN " . DB_PREFIX . "product_to_category p2c ON (p.product_id = p2c.product_id) WHERE pd.language_id = '" . (int)$this->config->get('config_language_id') . "' AND p2c.category_id = '" . (int)$category_id . "' ORDER BY pd.name ASC");
+
+ return $query->rows;
+ }
+
+ public function getProductDescriptions($product_id) {
+ $product_description_data = array();
+
+ $query = $this->db->query("SELECT * FROM " . DB_PREFIX . "product_description WHERE product_id = '" . (int)$product_id . "'");
+
+ foreach ($query->rows as $result) {
+ $product_description_data[$result['language_id']] = array(
+ 'name' => $result['name'],
+ 'description' => $result['description'],
+ 'meta_title' => $result['meta_title'],
+ 'meta_description' => $result['meta_description'],
+ 'meta_keyword' => $result['meta_keyword'],
+ 'tag' => $result['tag']
+ );
+ }
+
+ return $product_description_data;
+ }
+
+ public function getProductCategories($product_id) {
+ $product_category_data = array();
+
+ $query = $this->db->query("SELECT * FROM " . DB_PREFIX . "product_to_category WHERE product_id = '" . (int)$product_id . "'");
+
+ foreach ($query->rows as $result) {
+ $product_category_data[] = $result['category_id'];
+ }
+
+ return $product_category_data;
+ }
+
+ public function getProductFilters($product_id) {
+ $product_filter_data = array();
+
+ $query = $this->db->query("SELECT * FROM " . DB_PREFIX . "product_filter WHERE product_id = '" . (int)$product_id . "'");
+
+ foreach ($query->rows as $result) {
+ $product_filter_data[] = $result['filter_id'];
+ }
+
+ return $product_filter_data;
+ }
+
+ public function getProductAttributes($product_id) {
+ $product_attribute_data = array();
+
+ $product_attribute_query = $this->db->query("SELECT attribute_id FROM " . DB_PREFIX . "product_attribute WHERE product_id = '" . (int)$product_id . "' GROUP BY attribute_id");
+
+ foreach ($product_attribute_query->rows as $product_attribute) {
+ $product_attribute_description_data = array();
+
+ $product_attribute_description_query = $this->db->query("SELECT * FROM " . DB_PREFIX . "product_attribute WHERE product_id = '" . (int)$product_id . "' AND attribute_id = '" . (int)$product_attribute['attribute_id'] . "'");
+
+ foreach ($product_attribute_description_query->rows as $product_attribute_description) {
+ $product_attribute_description_data[$product_attribute_description['language_id']] = array('text' => $product_attribute_description['text']);
+ }
+
+ $product_attribute_data[] = array(
+ 'attribute_id' => $product_attribute['attribute_id'],
+ 'product_attribute_description' => $product_attribute_description_data
+ );
+ }
+
+ return $product_attribute_data;
+ }
+
+ public function getProductOptions($product_id) {
+ $product_option_data = array();
+
+ $product_option_query = $this->db->query("SELECT * FROM `" . DB_PREFIX . "product_option` po LEFT JOIN `" . DB_PREFIX . "option` o ON (po.option_id = o.option_id) LEFT JOIN `" . DB_PREFIX . "option_description` od ON (o.option_id = od.option_id) WHERE po.product_id = '" . (int)$product_id . "' AND od.language_id = '" . (int)$this->config->get('config_language_id') . "'");
+
+ foreach ($product_option_query->rows as $product_option) {
+ $product_option_value_data = array();
+
+ $product_option_value_query = $this->db->query("SELECT * FROM " . DB_PREFIX . "product_option_value pov LEFT JOIN " . DB_PREFIX . "option_value ov ON(pov.option_value_id = ov.option_value_id) WHERE pov.product_option_id = '" . (int)$product_option['product_option_id'] . "' ORDER BY ov.sort_order ASC");
+
+ foreach ($product_option_value_query->rows as $product_option_value) {
+ $product_option_value_data[] = array(
+ 'product_option_value_id' => $product_option_value['product_option_value_id'],
+ 'option_value_id' => $product_option_value['option_value_id'],
+ 'quantity' => $product_option_value['quantity'],
+ 'subtract' => $product_option_value['subtract'],
+ 'price' => $product_option_value['price'],
+ 'price_prefix' => $product_option_value['price_prefix'],
+ 'points' => $product_option_value['points'],
+ 'points_prefix' => $product_option_value['points_prefix'],
+ 'weight' => $product_option_value['weight'],
+ 'weight_prefix' => $product_option_value['weight_prefix']
+ );
+ }
+
+ $product_option_data[] = array(
+ 'product_option_id' => $product_option['product_option_id'],
+ 'product_option_value' => $product_option_value_data,
+ 'option_id' => $product_option['option_id'],
+ 'name' => $product_option['name'],
+ 'type' => $product_option['type'],
+ 'value' => $product_option['value'],
+ 'required' => $product_option['required']
+ );
+ }
+
+ return $product_option_data;
+ }
+
+ public function getProductOptionValue($product_id, $product_option_value_id) {
+ $query = $this->db->query("SELECT pov.option_value_id, ovd.name, pov.quantity, pov.subtract, pov.price, pov.price_prefix, pov.points, pov.points_prefix, pov.weight, pov.weight_prefix FROM " . DB_PREFIX . "product_option_value pov LEFT JOIN " . DB_PREFIX . "option_value ov ON (pov.option_value_id = ov.option_value_id) LEFT JOIN " . DB_PREFIX . "option_value_description ovd ON (ov.option_value_id = ovd.option_value_id) WHERE pov.product_id = '" . (int)$product_id . "' AND pov.product_option_value_id = '" . (int)$product_option_value_id . "' AND ovd.language_id = '" . (int)$this->config->get('config_language_id') . "'");
+
+ return $query->row;
+ }
+
+ public function getProductImages($product_id) {
+ $query = $this->db->query("SELECT * FROM " . DB_PREFIX . "product_image WHERE product_id = '" . (int)$product_id . "' ORDER BY sort_order ASC");
+
+ return $query->rows;
+ }
+
+ public function getProductDiscounts($product_id) {
+ $query = $this->db->query("SELECT * FROM " . DB_PREFIX . "product_discount WHERE product_id = '" . (int)$product_id . "' ORDER BY quantity, priority, price");
+
+ return $query->rows;
+ }
+
+ public function getProductSpecials($product_id) {
+ $query = $this->db->query("SELECT * FROM " . DB_PREFIX . "product_special WHERE product_id = '" . (int)$product_id . "' ORDER BY priority, price");
+
+ return $query->rows;
+ }
+
+ public function getProductRewards($product_id) {
+ $product_reward_data = array();
+
+ $query = $this->db->query("SELECT * FROM " . DB_PREFIX . "product_reward WHERE product_id = '" . (int)$product_id . "'");
+
+ foreach ($query->rows as $result) {
+ $product_reward_data[$result['customer_group_id']] = array('points' => $result['points']);
+ }
+
+ return $product_reward_data;
+ }
+
+ public function getProductDownloads($product_id) {
+ $product_download_data = array();
+
+ $query = $this->db->query("SELECT * FROM " . DB_PREFIX . "product_to_download WHERE product_id = '" . (int)$product_id . "'");
+
+ foreach ($query->rows as $result) {
+ $product_download_data[] = $result['download_id'];
+ }
+
+ return $product_download_data;
+ }
+
+ public function getProductStores($product_id) {
+ $product_store_data = array();
+
+ $query = $this->db->query("SELECT * FROM " . DB_PREFIX . "product_to_store WHERE product_id = '" . (int)$product_id . "'");
+
+ foreach ($query->rows as $result) {
+ $product_store_data[] = $result['store_id'];
+ }
+
+ return $product_store_data;
+ }
+
+ public function getProductSeoUrls($product_id) {
+ $product_seo_url_data = array();
+
+ $query = $this->db->query("SELECT * FROM " . DB_PREFIX . "seo_url WHERE query = 'product_id=" . (int)$product_id . "'");
+
+ foreach ($query->rows as $result) {
+ $product_seo_url_data[$result['store_id']][$result['language_id']] = $result['keyword'];
+ }
+
+ return $product_seo_url_data;
+ }
+
+ public function getProductLayouts($product_id) {
+ $product_layout_data = array();
+
+ $query = $this->db->query("SELECT * FROM " . DB_PREFIX . "product_to_layout WHERE product_id = '" . (int)$product_id . "'");
+
+ foreach ($query->rows as $result) {
+ $product_layout_data[$result['store_id']] = $result['layout_id'];
+ }
+
+ return $product_layout_data;
+ }
+
+ public function getProductRelated($product_id) {
+ $product_related_data = array();
+
+ $query = $this->db->query("SELECT * FROM " . DB_PREFIX . "product_related WHERE product_id = '" . (int)$product_id . "'");
+
+ foreach ($query->rows as $result) {
+ $product_related_data[] = $result['related_id'];
+ }
+
+ return $product_related_data;
+ }
+
+ public function getRecurrings($product_id) {
+ $query = $this->db->query("SELECT * FROM `" . DB_PREFIX . "product_recurring` WHERE product_id = '" . (int)$product_id . "'");
+
+ return $query->rows;
+ }
+
+ public function getTotalProducts($data = array()) {
+ $sql = "SELECT COUNT(DISTINCT p.product_id) AS total FROM " . DB_PREFIX . "product p LEFT JOIN " . DB_PREFIX . "product_description pd ON (p.product_id = pd.product_id)";
+
+ $sql .= " WHERE pd.language_id = '" . (int)$this->config->get('config_language_id') . "'";
+
+ if (!empty($data['filter_name'])) {
+ $sql .= " AND pd.name LIKE '" . $this->db->escape($data['filter_name']) . "%'";
+ }
+
+ if (!empty($data['filter_model'])) {
+ $sql .= " AND p.model LIKE '" . $this->db->escape($data['filter_model']) . "%'";
+ }
+
+ if (isset($data['filter_price']) && !is_null($data['filter_price'])) {
+ $sql .= " AND p.price LIKE '" . $this->db->escape($data['filter_price']) . "%'";
+ }
+
+ if (isset($data['filter_quantity']) && $data['filter_quantity'] !== '') {
+ $sql .= " AND p.quantity = '" . (int)$data['filter_quantity'] . "'";
+ }
+
+ if (isset($data['filter_status']) && $data['filter_status'] !== '') {
+ $sql .= " AND p.status = '" . (int)$data['filter_status'] . "'";
+ }
+
+ $query = $this->db->query($sql);
+
+ return $query->row['total'];
+ }
+
+ public function getTotalProductsByTaxClassId($tax_class_id) {
+ $query = $this->db->query("SELECT COUNT(*) AS total FROM " . DB_PREFIX . "product WHERE tax_class_id = '" . (int)$tax_class_id . "'");
+
+ return $query->row['total'];
+ }
+
+ public function getTotalProductsByStockStatusId($stock_status_id) {
+ $query = $this->db->query("SELECT COUNT(*) AS total FROM " . DB_PREFIX . "product WHERE stock_status_id = '" . (int)$stock_status_id . "'");
+
+ return $query->row['total'];
+ }
+
+ public function getTotalProductsByWeightClassId($weight_class_id) {
+ $query = $this->db->query("SELECT COUNT(*) AS total FROM " . DB_PREFIX . "product WHERE weight_class_id = '" . (int)$weight_class_id . "'");
+
+ return $query->row['total'];
+ }
+
+ public function getTotalProductsByLengthClassId($length_class_id) {
+ $query = $this->db->query("SELECT COUNT(*) AS total FROM " . DB_PREFIX . "product WHERE length_class_id = '" . (int)$length_class_id . "'");
+
+ return $query->row['total'];
+ }
+
+ public function getTotalProductsByDownloadId($download_id) {
+ $query = $this->db->query("SELECT COUNT(*) AS total FROM " . DB_PREFIX . "product_to_download WHERE download_id = '" . (int)$download_id . "'");
+
+ return $query->row['total'];
+ }
+
+ public function getTotalProductsByManufacturerId($manufacturer_id) {
+ $query = $this->db->query("SELECT COUNT(*) AS total FROM " . DB_PREFIX . "product WHERE manufacturer_id = '" . (int)$manufacturer_id . "'");
+
+ return $query->row['total'];
+ }
+
+ public function getTotalProductsByAttributeId($attribute_id) {
+ $query = $this->db->query("SELECT COUNT(*) AS total FROM " . DB_PREFIX . "product_attribute WHERE attribute_id = '" . (int)$attribute_id . "'");
+
+ return $query->row['total'];
+ }
+
+ public function getTotalProductsByOptionId($option_id) {
+ $query = $this->db->query("SELECT COUNT(*) AS total FROM " . DB_PREFIX . "product_option WHERE option_id = '" . (int)$option_id . "'");
+
+ return $query->row['total'];
+ }
+
+ public function getTotalProductsByProfileId($recurring_id) {
+ $query = $this->db->query("SELECT COUNT(*) AS total FROM " . DB_PREFIX . "product_recurring WHERE recurring_id = '" . (int)$recurring_id . "'");
+
+ return $query->row['total'];
+ }
+
+ public function getTotalProductsByLayoutId($layout_id) {
+ $query = $this->db->query("SELECT COUNT(*) AS total FROM " . DB_PREFIX . "product_to_layout WHERE layout_id = '" . (int)$layout_id . "'");
+
+ return $query->row['total'];
+ }
+}
diff --git a/public/admin/model/catalog/recurring.php b/public/admin/model/catalog/recurring.php
new file mode 100644
index 0000000..8dbd655
--- /dev/null
+++ b/public/admin/model/catalog/recurring.php
@@ -0,0 +1,108 @@
+<?php
+class ModelCatalogRecurring extends Model {
+ public function addRecurring($data) {
+ $this->db->query("INSERT INTO `" . DB_PREFIX . "recurring` SET `sort_order` = " . (int)$data['sort_order'] . ", `status` = " . (int)$data['status'] . ", `price` = " . (float)$data['price'] . ", `frequency` = '" . $this->db->escape($data['frequency']) . "', `duration` = " . (int)$data['duration'] . ", `cycle` = " . (int)$data['cycle'] . ", `trial_status` = " . (int)$data['trial_status'] . ", `trial_price` = " . (float)$data['trial_price'] . ", `trial_frequency` = '" . $this->db->escape($data['trial_frequency']) . "', `trial_duration` = " . (int)$data['trial_duration'] . ", `trial_cycle` = '" . (int)$data['trial_cycle'] . "'");
+
+ $recurring_id = $this->db->getLastId();
+
+ foreach ($data['recurring_description'] as $language_id => $recurring_description) {
+ $this->db->query("INSERT INTO `" . DB_PREFIX . "recurring_description` (`recurring_id`, `language_id`, `name`) VALUES (" . (int)$recurring_id . ", " . (int)$language_id . ", '" . $this->db->escape($recurring_description['name']) . "')");
+ }
+
+ return $recurring_id;
+ }
+
+ public function editRecurring($recurring_id, $data) {
+ $this->db->query("DELETE FROM `" . DB_PREFIX . "recurring_description` WHERE recurring_id = '" . (int)$recurring_id . "'");
+
+ $this->db->query("UPDATE `" . DB_PREFIX . "recurring` SET `price` = '" . (float)$data['price'] . "', `frequency` = '" . $this->db->escape($data['frequency']) . "', `duration` = '" . (int)$data['duration'] . "', `cycle` = '" . (int)$data['cycle'] . "', `sort_order` = '" . (int)$data['sort_order'] . "', `status` = '" . (int)$data['status'] . "', `trial_price` = '" . (float)$data['trial_price'] . "', `trial_frequency` = '" . $this->db->escape($data['trial_frequency']) . "', `trial_duration` = '" . (int)$data['trial_duration'] . "', `trial_cycle` = '" . (int)$data['trial_cycle'] . "', `trial_status` = '" . (int)$data['trial_status'] . "' WHERE recurring_id = '" . (int)$recurring_id . "'");
+
+ foreach ($data['recurring_description'] as $language_id => $recurring_description) {
+ $this->db->query("INSERT INTO `" . DB_PREFIX . "recurring_description` (`recurring_id`, `language_id`, `name`) VALUES (" . (int)$recurring_id . ", " . (int)$language_id . ", '" . $this->db->escape($recurring_description['name']) . "')");
+ }
+ }
+
+ public function copyRecurring($recurring_id) {
+ $data = $this->getRecurring($recurring_id);
+
+ $data['recurring_description'] = $this->getRecurringDescription($recurring_id);
+
+ foreach ($data['recurring_description'] as &$recurring_description) {
+ $recurring_description['name'] .= ' - 2';
+ }
+
+ $this->addRecurring($data);
+ }
+
+ public function deleteRecurring($recurring_id) {
+ $this->db->query("DELETE FROM `" . DB_PREFIX . "recurring` WHERE recurring_id = " . (int)$recurring_id . "");
+ $this->db->query("DELETE FROM `" . DB_PREFIX . "recurring_description` WHERE recurring_id = " . (int)$recurring_id . "");
+ $this->db->query("DELETE FROM `" . DB_PREFIX . "product_recurring` WHERE recurring_id = " . (int)$recurring_id . "");
+ $this->db->query("UPDATE `" . DB_PREFIX . "order_recurring` SET `recurring_id` = 0 WHERE `recurring_id` = " . (int)$recurring_id . "");
+ }
+
+ public function getRecurring($recurring_id) {
+ $query = $this->db->query("SELECT * FROM `" . DB_PREFIX . "recurring` WHERE recurring_id = '" . (int)$recurring_id . "'");
+
+ return $query->row;
+ }
+
+ public function getRecurringDescription($recurring_id) {
+ $recurring_description_data = array();
+
+ $query = $this->db->query("SELECT * FROM `" . DB_PREFIX . "recurring_description` WHERE `recurring_id` = '" . (int)$recurring_id . "'");
+
+ foreach ($query->rows as $result) {
+ $recurring_description_data[$result['language_id']] = array('name' => $result['name']);
+ }
+
+ return $recurring_description_data;
+ }
+
+ public function getRecurrings($data = array()) {
+ $sql = "SELECT * FROM `" . DB_PREFIX . "recurring` r LEFT JOIN " . DB_PREFIX . "recurring_description rd ON (r.recurring_id = rd.recurring_id) WHERE rd.language_id = '" . (int)$this->config->get('config_language_id') . "'";
+
+ if (!empty($data['filter_name'])) {
+ $sql .= " AND rd.name LIKE '" . $this->db->escape($data['filter_name']) . "%'";
+ }
+
+ $sort_data = array(
+ 'rd.name',
+ 'r.sort_order'
+ );
+
+ if (isset($data['sort']) && in_array($data['sort'], $sort_data)) {
+ $sql .= " ORDER BY " . $data['sort'];
+ } else {
+ $sql .= " ORDER BY rd.name";
+ }
+
+ 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'];
+ }
+
+ $query = $this->db->query($sql);
+
+ return $query->rows;
+ }
+
+ public function getTotalRecurrings() {
+ $query = $this->db->query("SELECT COUNT(*) AS total FROM `" . DB_PREFIX . "recurring`");
+
+ return $query->row['total'];
+ }
+} \ No newline at end of file
diff --git a/public/admin/model/catalog/review.php b/public/admin/model/catalog/review.php
new file mode 100644
index 0000000..5cc059e
--- /dev/null
+++ b/public/admin/model/catalog/review.php
@@ -0,0 +1,116 @@
+<?php
+class ModelCatalogReview extends Model {
+ public function addReview($data) {
+ $this->db->query("INSERT INTO " . DB_PREFIX . "review SET author = '" . $this->db->escape($data['author']) . "', product_id = '" . (int)$data['product_id'] . "', text = '" . $this->db->escape(strip_tags($data['text'])) . "', rating = '" . (int)$data['rating'] . "', status = '" . (int)$data['status'] . "', date_added = '" . $this->db->escape($data['date_added']) . "'");
+
+ $review_id = $this->db->getLastId();
+
+ $this->cache->delete('product');
+
+ return $review_id;
+ }
+
+ public function editReview($review_id, $data) {
+ $this->db->query("UPDATE " . DB_PREFIX . "review SET author = '" . $this->db->escape($data['author']) . "', product_id = '" . (int)$data['product_id'] . "', text = '" . $this->db->escape(strip_tags($data['text'])) . "', rating = '" . (int)$data['rating'] . "', status = '" . (int)$data['status'] . "', date_added = '" . $this->db->escape($data['date_added']) . "', date_modified = NOW() WHERE review_id = '" . (int)$review_id . "'");
+
+ $this->cache->delete('product');
+ }
+
+ public function deleteReview($review_id) {
+ $this->db->query("DELETE FROM " . DB_PREFIX . "review WHERE review_id = '" . (int)$review_id . "'");
+
+ $this->cache->delete('product');
+ }
+
+ public function getReview($review_id) {
+ $query = $this->db->query("SELECT DISTINCT *, (SELECT pd.name FROM " . DB_PREFIX . "product_description pd WHERE pd.product_id = r.product_id AND pd.language_id = '" . (int)$this->config->get('config_language_id') . "') AS product FROM " . DB_PREFIX . "review r WHERE r.review_id = '" . (int)$review_id . "'");
+
+ return $query->row;
+ }
+
+ public function getReviews($data = array()) {
+ $sql = "SELECT r.review_id, pd.name, r.author, r.rating, r.status, r.date_added FROM " . DB_PREFIX . "review r LEFT JOIN " . DB_PREFIX . "product_description pd ON (r.product_id = pd.product_id) WHERE pd.language_id = '" . (int)$this->config->get('config_language_id') . "'";
+
+ if (!empty($data['filter_product'])) {
+ $sql .= " AND pd.name LIKE '" . $this->db->escape($data['filter_product']) . "%'";
+ }
+
+ if (!empty($data['filter_author'])) {
+ $sql .= " AND r.author LIKE '" . $this->db->escape($data['filter_author']) . "%'";
+ }
+
+ if (isset($data['filter_status']) && $data['filter_status'] !== '') {
+ $sql .= " AND r.status = '" . (int)$data['filter_status'] . "'";
+ }
+
+ if (!empty($data['filter_date_added'])) {
+ $sql .= " AND DATE(r.date_added) = DATE('" . $this->db->escape($data['filter_date_added']) . "')";
+ }
+
+ $sort_data = array(
+ 'pd.name',
+ 'r.author',
+ 'r.rating',
+ 'r.status',
+ 'r.date_added'
+ );
+
+ if (isset($data['sort']) && in_array($data['sort'], $sort_data)) {
+ $sql .= " ORDER BY " . $data['sort'];
+ } else {
+ $sql .= " ORDER BY r.date_added";
+ }
+
+ 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'];
+ }
+
+ $query = $this->db->query($sql);
+
+ return $query->rows;
+ }
+
+ public function getTotalReviews($data = array()) {
+ $sql = "SELECT COUNT(*) AS total FROM " . DB_PREFIX . "review r LEFT JOIN " . DB_PREFIX . "product_description pd ON (r.product_id = pd.product_id) WHERE pd.language_id = '" . (int)$this->config->get('config_language_id') . "'";
+
+ if (!empty($data['filter_product'])) {
+ $sql .= " AND pd.name LIKE '" . $this->db->escape($data['filter_product']) . "%'";
+ }
+
+ if (!empty($data['filter_author'])) {
+ $sql .= " AND r.author LIKE '" . $this->db->escape($data['filter_author']) . "%'";
+ }
+
+ if (isset($data['filter_status']) && $data['filter_status'] !== '') {
+ $sql .= " AND r.status = '" . (int)$data['filter_status'] . "'";
+ }
+
+ if (!empty($data['filter_date_added'])) {
+ $sql .= " AND DATE(r.date_added) = DATE('" . $this->db->escape($data['filter_date_added']) . "')";
+ }
+
+ $query = $this->db->query($sql);
+
+ return $query->row['total'];
+ }
+
+ public function getTotalReviewsAwaitingApproval() {
+ $query = $this->db->query("SELECT COUNT(*) AS total FROM " . DB_PREFIX . "review WHERE status = '0'");
+
+ return $query->row['total'];
+ }
+} \ No newline at end of file
diff --git a/public/admin/model/customer/custom_field.php b/public/admin/model/customer/custom_field.php
new file mode 100644
index 0000000..37267a7
--- /dev/null
+++ b/public/admin/model/customer/custom_field.php
@@ -0,0 +1,208 @@
+<?php
+class ModelCustomerCustomField extends Model {
+ public function addCustomField($data) {
+ $this->db->query("INSERT INTO `" . DB_PREFIX . "custom_field` SET type = '" . $this->db->escape($data['type']) . "', value = '" . $this->db->escape($data['value']) . "', validation = '" . $this->db->escape($data['validation']) . "', location = '" . $this->db->escape($data['location']) . "', status = '" . (int)$data['status'] . "', sort_order = '" . (int)$data['sort_order'] . "'");
+
+ $custom_field_id = $this->db->getLastId();
+
+ foreach ($data['custom_field_description'] as $language_id => $value) {
+ $this->db->query("INSERT INTO " . DB_PREFIX . "custom_field_description SET custom_field_id = '" . (int)$custom_field_id . "', language_id = '" . (int)$language_id . "', name = '" . $this->db->escape($value['name']) . "'");
+ }
+
+ if (isset($data['custom_field_customer_group'])) {
+ foreach ($data['custom_field_customer_group'] as $custom_field_customer_group) {
+ if (isset($custom_field_customer_group['customer_group_id'])) {
+ $this->db->query("INSERT INTO " . DB_PREFIX . "custom_field_customer_group SET custom_field_id = '" . (int)$custom_field_id . "', customer_group_id = '" . (int)$custom_field_customer_group['customer_group_id'] . "', required = '" . (int)(isset($custom_field_customer_group['required']) ? 1 : 0) . "'");
+ }
+ }
+ }
+
+ if (isset($data['custom_field_value'])) {
+ foreach ($data['custom_field_value'] as $custom_field_value) {
+ $this->db->query("INSERT INTO " . DB_PREFIX . "custom_field_value SET custom_field_id = '" . (int)$custom_field_id . "', sort_order = '" . (int)$custom_field_value['sort_order'] . "'");
+
+ $custom_field_value_id = $this->db->getLastId();
+
+ foreach ($custom_field_value['custom_field_value_description'] as $language_id => $custom_field_value_description) {
+ $this->db->query("INSERT INTO " . DB_PREFIX . "custom_field_value_description SET custom_field_value_id = '" . (int)$custom_field_value_id . "', language_id = '" . (int)$language_id . "', custom_field_id = '" . (int)$custom_field_id . "', name = '" . $this->db->escape($custom_field_value_description['name']) . "'");
+ }
+ }
+ }
+
+ return $custom_field_id;
+ }
+
+ public function editCustomField($custom_field_id, $data) {
+ $this->db->query("UPDATE `" . DB_PREFIX . "custom_field` SET type = '" . $this->db->escape($data['type']) . "', value = '" . $this->db->escape($data['value']) . "', validation = '" . $this->db->escape($data['validation']) . "', location = '" . $this->db->escape($data['location']) . "', status = '" . (int)$data['status'] . "', sort_order = '" . (int)$data['sort_order'] . "' WHERE custom_field_id = '" . (int)$custom_field_id . "'");
+
+ $this->db->query("DELETE FROM " . DB_PREFIX . "custom_field_description WHERE custom_field_id = '" . (int)$custom_field_id . "'");
+
+ foreach ($data['custom_field_description'] as $language_id => $value) {
+ $this->db->query("INSERT INTO " . DB_PREFIX . "custom_field_description SET custom_field_id = '" . (int)$custom_field_id . "', language_id = '" . (int)$language_id . "', name = '" . $this->db->escape($value['name']) . "'");
+ }
+
+ $this->db->query("DELETE FROM " . DB_PREFIX . "custom_field_customer_group WHERE custom_field_id = '" . (int)$custom_field_id . "'");
+
+ if (isset($data['custom_field_customer_group'])) {
+ foreach ($data['custom_field_customer_group'] as $custom_field_customer_group) {
+ if (isset($custom_field_customer_group['customer_group_id'])) {
+ $this->db->query("INSERT INTO " . DB_PREFIX . "custom_field_customer_group SET custom_field_id = '" . (int)$custom_field_id . "', customer_group_id = '" . (int)$custom_field_customer_group['customer_group_id'] . "', required = '" . (int)(isset($custom_field_customer_group['required']) ? 1 : 0) . "'");
+ }
+ }
+ }
+
+ $this->db->query("DELETE FROM " . DB_PREFIX . "custom_field_value WHERE custom_field_id = '" . (int)$custom_field_id . "'");
+ $this->db->query("DELETE FROM " . DB_PREFIX . "custom_field_value_description WHERE custom_field_id = '" . (int)$custom_field_id . "'");
+
+ if (isset($data['custom_field_value'])) {
+ foreach ($data['custom_field_value'] as $custom_field_value) {
+ if ($custom_field_value['custom_field_value_id']) {
+ $this->db->query("INSERT INTO " . DB_PREFIX . "custom_field_value SET custom_field_value_id = '" . (int)$custom_field_value['custom_field_value_id'] . "', custom_field_id = '" . (int)$custom_field_id . "', sort_order = '" . (int)$custom_field_value['sort_order'] . "'");
+ } else {
+ $this->db->query("INSERT INTO " . DB_PREFIX . "custom_field_value SET custom_field_id = '" . (int)$custom_field_id . "', sort_order = '" . (int)$custom_field_value['sort_order'] . "'");
+ }
+
+ $custom_field_value_id = $this->db->getLastId();
+
+ foreach ($custom_field_value['custom_field_value_description'] as $language_id => $custom_field_value_description) {
+ $this->db->query("INSERT INTO " . DB_PREFIX . "custom_field_value_description SET custom_field_value_id = '" . (int)$custom_field_value_id . "', language_id = '" . (int)$language_id . "', custom_field_id = '" . (int)$custom_field_id . "', name = '" . $this->db->escape($custom_field_value_description['name']) . "'");
+ }
+ }
+ }
+ }
+
+ public function deleteCustomField($custom_field_id) {
+ $this->db->query("DELETE FROM `" . DB_PREFIX . "custom_field` WHERE custom_field_id = '" . (int)$custom_field_id . "'");
+ $this->db->query("DELETE FROM `" . DB_PREFIX . "custom_field_description` WHERE custom_field_id = '" . (int)$custom_field_id . "'");
+ $this->db->query("DELETE FROM `" . DB_PREFIX . "custom_field_customer_group` WHERE custom_field_id = '" . (int)$custom_field_id . "'");
+ $this->db->query("DELETE FROM `" . DB_PREFIX . "custom_field_value` WHERE custom_field_id = '" . (int)$custom_field_id . "'");
+ $this->db->query("DELETE FROM `" . DB_PREFIX . "custom_field_value_description` WHERE custom_field_id = '" . (int)$custom_field_id . "'");
+ }
+
+ public function getCustomField($custom_field_id) {
+ $query = $this->db->query("SELECT * FROM `" . DB_PREFIX . "custom_field` cf LEFT JOIN " . DB_PREFIX . "custom_field_description cfd ON (cf.custom_field_id = cfd.custom_field_id) WHERE cf.custom_field_id = '" . (int)$custom_field_id . "' AND cfd.language_id = '" . (int)$this->config->get('config_language_id') . "'");
+
+ return $query->row;
+ }
+
+ public function getCustomFields($data = array()) {
+ if (empty($data['filter_customer_group_id'])) {
+ $sql = "SELECT * FROM `" . DB_PREFIX . "custom_field` cf LEFT JOIN " . DB_PREFIX . "custom_field_description cfd ON (cf.custom_field_id = cfd.custom_field_id) WHERE cfd.language_id = '" . (int)$this->config->get('config_language_id') . "'";
+ } else {
+ $sql = "SELECT * FROM " . DB_PREFIX . "custom_field_customer_group cfcg LEFT JOIN `" . DB_PREFIX . "custom_field` cf ON (cfcg.custom_field_id = cf.custom_field_id) LEFT JOIN " . DB_PREFIX . "custom_field_description cfd ON (cf.custom_field_id = cfd.custom_field_id) WHERE cfd.language_id = '" . (int)$this->config->get('config_language_id') . "'";
+ }
+
+ if (!empty($data['filter_name'])) {
+ $sql .= " AND cfd.name LIKE '" . $this->db->escape($data['filter_name']) . "%'";
+ }
+
+ if (!empty($data['filter_customer_group_id'])) {
+ $sql .= " AND cfcg.customer_group_id = '" . (int)$data['filter_customer_group_id'] . "'";
+ }
+
+ $sort_data = array(
+ 'cfd.name',
+ 'cf.type',
+ 'cf.location',
+ 'cf.status',
+ 'cf.sort_order'
+ );
+
+ if (isset($data['sort']) && in_array($data['sort'], $sort_data)) {
+ $sql .= " ORDER BY " . $data['sort'];
+ } else {
+ $sql .= " ORDER BY cfd.name";
+ }
+
+ 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'];
+ }
+
+ $query = $this->db->query($sql);
+
+ return $query->rows;
+ }
+
+ public function getCustomFieldDescriptions($custom_field_id) {
+ $custom_field_data = array();
+
+ $query = $this->db->query("SELECT * FROM " . DB_PREFIX . "custom_field_description WHERE custom_field_id = '" . (int)$custom_field_id . "'");
+
+ foreach ($query->rows as $result) {
+ $custom_field_data[$result['language_id']] = array('name' => $result['name']);
+ }
+
+ return $custom_field_data;
+ }
+
+ public function getCustomFieldValue($custom_field_value_id) {
+ $query = $this->db->query("SELECT * FROM " . DB_PREFIX . "custom_field_value cfv LEFT JOIN " . DB_PREFIX . "custom_field_value_description cfvd ON (cfv.custom_field_value_id = cfvd.custom_field_value_id) WHERE cfv.custom_field_value_id = '" . (int)$custom_field_value_id . "' AND cfvd.language_id = '" . (int)$this->config->get('config_language_id') . "'");
+
+ return $query->row;
+ }
+
+ public function getCustomFieldValues($custom_field_id) {
+ $custom_field_value_data = array();
+
+ $custom_field_value_query = $this->db->query("SELECT * FROM " . DB_PREFIX . "custom_field_value cfv LEFT JOIN " . DB_PREFIX . "custom_field_value_description cfvd ON (cfv.custom_field_value_id = cfvd.custom_field_value_id) WHERE cfv.custom_field_id = '" . (int)$custom_field_id . "' AND cfvd.language_id = '" . (int)$this->config->get('config_language_id') . "' ORDER BY cfv.sort_order ASC");
+
+ foreach ($custom_field_value_query->rows as $custom_field_value) {
+ $custom_field_value_data[$custom_field_value['custom_field_value_id']] = array(
+ 'custom_field_value_id' => $custom_field_value['custom_field_value_id'],
+ 'name' => $custom_field_value['name']
+ );
+ }
+
+ return $custom_field_value_data;
+ }
+
+ public function getCustomFieldCustomerGroups($custom_field_id) {
+ $query = $this->db->query("SELECT * FROM `" . DB_PREFIX . "custom_field_customer_group` WHERE custom_field_id = '" . (int)$custom_field_id . "'");
+
+ return $query->rows;
+ }
+
+ public function getCustomFieldValueDescriptions($custom_field_id) {
+ $custom_field_value_data = array();
+
+ $custom_field_value_query = $this->db->query("SELECT * FROM " . DB_PREFIX . "custom_field_value WHERE custom_field_id = '" . (int)$custom_field_id . "'");
+
+ foreach ($custom_field_value_query->rows as $custom_field_value) {
+ $custom_field_value_description_data = array();
+
+ $custom_field_value_description_query = $this->db->query("SELECT * FROM " . DB_PREFIX . "custom_field_value_description WHERE custom_field_value_id = '" . (int)$custom_field_value['custom_field_value_id'] . "'");
+
+ foreach ($custom_field_value_description_query->rows as $custom_field_value_description) {
+ $custom_field_value_description_data[$custom_field_value_description['language_id']] = array('name' => $custom_field_value_description['name']);
+ }
+
+ $custom_field_value_data[] = array(
+ 'custom_field_value_id' => $custom_field_value['custom_field_value_id'],
+ 'custom_field_value_description' => $custom_field_value_description_data,
+ 'sort_order' => $custom_field_value['sort_order']
+ );
+ }
+
+ return $custom_field_value_data;
+ }
+
+ public function getTotalCustomFields() {
+ $query = $this->db->query("SELECT COUNT(*) AS total FROM `" . DB_PREFIX . "custom_field`");
+
+ return $query->row['total'];
+ }
+} \ No newline at end of file
diff --git a/public/admin/model/customer/customer.php b/public/admin/model/customer/customer.php
new file mode 100644
index 0000000..f1eab7d
--- /dev/null
+++ b/public/admin/model/customer/customer.php
@@ -0,0 +1,486 @@
+<?php
+class ModelCustomerCustomer extends Model {
+ public function addCustomer($data) {
+ $this->db->query("INSERT INTO " . DB_PREFIX . "customer SET customer_group_id = '" . (int)$data['customer_group_id'] . "', firstname = '" . $this->db->escape($data['firstname']) . "', lastname = '" . $this->db->escape($data['lastname']) . "', email = '" . $this->db->escape($data['email']) . "', telephone = '" . $this->db->escape($data['telephone']) . "', custom_field = '" . $this->db->escape(isset($data['custom_field']) ? json_encode($data['custom_field']) : json_encode(array())) . "', newsletter = '" . (int)$data['newsletter'] . "', salt = '" . $this->db->escape($salt = token(9)) . "', password = '" . $this->db->escape(sha1($salt . sha1($salt . sha1($data['password'])))) . "', status = '" . (int)$data['status'] . "', safe = '" . (int)$data['safe'] . "', date_added = NOW()");
+
+ $customer_id = $this->db->getLastId();
+
+ if (isset($data['address'])) {
+ foreach ($data['address'] as $address) {
+ $this->db->query("INSERT INTO " . DB_PREFIX . "address SET customer_id = '" . (int)$customer_id . "', firstname = '" . $this->db->escape($address['firstname']) . "', lastname = '" . $this->db->escape($address['lastname']) . "', company = '" . $this->db->escape($address['company']) . "', address_1 = '" . $this->db->escape($address['address_1']) . "', address_2 = '" . $this->db->escape($address['address_2']) . "', city = '" . $this->db->escape($address['city']) . "', postcode = '" . $this->db->escape($address['postcode']) . "', country_id = '" . (int)$address['country_id'] . "', zone_id = '" . (int)$address['zone_id'] . "', custom_field = '" . $this->db->escape(isset($address['custom_field']) ? json_encode($address['custom_field']) : json_encode(array())) . "'");
+
+ if (isset($address['default'])) {
+ $address_id = $this->db->getLastId();
+
+ $this->db->query("UPDATE " . DB_PREFIX . "customer SET address_id = '" . (int)$address_id . "' WHERE customer_id = '" . (int)$customer_id . "'");
+ }
+ }
+ }
+
+ if ($data['affiliate']) {
+ $this->db->query("INSERT INTO " . DB_PREFIX . "customer_affiliate SET customer_id = '" . (int)$customer_id . "', company = '" . $this->db->escape($data['company']) . "', website = '" . $this->db->escape($data['website']) . "', tracking = '" . $this->db->escape($data['tracking']) . "', commission = '" . (float)$data['commission'] . "', tax = '" . $this->db->escape($data['tax']) . "', payment = '" . $this->db->escape($data['payment']) . "', cheque = '" . $this->db->escape($data['cheque']) . "', paypal = '" . $this->db->escape($data['paypal']) . "', bank_name = '" . $this->db->escape($data['bank_name']) . "', bank_branch_number = '" . $this->db->escape($data['bank_branch_number']) . "', bank_swift_code = '" . $this->db->escape($data['bank_swift_code']) . "', bank_account_name = '" . $this->db->escape($data['bank_account_name']) . "', bank_account_number = '" . $this->db->escape($data['bank_account_number']) . "', custom_field = '" . $this->db->escape(isset($data['custom_field']) ? json_encode($data['custom_field']) : json_encode(array())) . "', status = '" . (int)$data['affiliate'] . "', date_added = NOW()");
+ }
+
+ return $customer_id;
+ }
+
+ public function editCustomer($customer_id, $data) {
+ $this->db->query("UPDATE " . DB_PREFIX . "customer SET customer_group_id = '" . (int)$data['customer_group_id'] . "', firstname = '" . $this->db->escape($data['firstname']) . "', lastname = '" . $this->db->escape($data['lastname']) . "', email = '" . $this->db->escape($data['email']) . "', telephone = '" . $this->db->escape($data['telephone']) . "', custom_field = '" . $this->db->escape(isset($data['custom_field']) ? json_encode($data['custom_field']) : json_encode(array())) . "', newsletter = '" . (int)$data['newsletter'] . "', status = '" . (int)$data['status'] . "', safe = '" . (int)$data['safe'] . "' WHERE customer_id = '" . (int)$customer_id . "'");
+
+ if ($data['password']) {
+ $this->db->query("UPDATE " . DB_PREFIX . "customer SET salt = '" . $this->db->escape($salt = token(9)) . "', password = '" . $this->db->escape(sha1($salt . sha1($salt . sha1($data['password'])))) . "' WHERE customer_id = '" . (int)$customer_id . "'");
+ }
+
+ $this->db->query("DELETE FROM " . DB_PREFIX . "address WHERE customer_id = '" . (int)$customer_id . "'");
+
+ if (isset($data['address'])) {
+ foreach ($data['address'] as $address) {
+ $this->db->query("INSERT INTO " . DB_PREFIX . "address SET address_id = '" . (int)$address['address_id'] . "', customer_id = '" . (int)$customer_id . "', firstname = '" . $this->db->escape($address['firstname']) . "', lastname = '" . $this->db->escape($address['lastname']) . "', company = '" . $this->db->escape($address['company']) . "', address_1 = '" . $this->db->escape($address['address_1']) . "', address_2 = '" . $this->db->escape($address['address_2']) . "', city = '" . $this->db->escape($address['city']) . "', postcode = '" . $this->db->escape($address['postcode']) . "', country_id = '" . (int)$address['country_id'] . "', zone_id = '" . (int)$address['zone_id'] . "', custom_field = '" . $this->db->escape(isset($address['custom_field']) ? json_encode($address['custom_field']) : json_encode(array())) . "'");
+
+ if (isset($address['default'])) {
+ $address_id = $this->db->getLastId();
+
+ $this->db->query("UPDATE " . DB_PREFIX . "customer SET address_id = '" . (int)$address_id . "' WHERE customer_id = '" . (int)$customer_id . "'");
+ }
+ }
+ }
+
+ if ($data['affiliate']) {
+ $this->db->query("REPLACE INTO " . DB_PREFIX . "customer_affiliate SET customer_id = '" . (int)$customer_id . "', company = '" . $this->db->escape($data['company']) . "', website = '" . $this->db->escape($data['website']) . "', tracking = '" . $this->db->escape($data['tracking']) . "', commission = '" . (float)$data['commission'] . "', tax = '" . $this->db->escape($data['tax']) . "', payment = '" . $this->db->escape($data['payment']) . "', cheque = '" . $this->db->escape($data['cheque']) . "', paypal = '" . $this->db->escape($data['paypal']) . "', bank_name = '" . $this->db->escape($data['bank_name']) . "', bank_branch_number = '" . $this->db->escape($data['bank_branch_number']) . "', bank_swift_code = '" . $this->db->escape($data['bank_swift_code']) . "', bank_account_name = '" . $this->db->escape($data['bank_account_name']) . "', bank_account_number = '" . $this->db->escape($data['bank_account_number']) . "', status = '" . (int)$data['affiliate'] . "', date_added = NOW()");
+ }
+ }
+
+ public function editToken($customer_id, $token) {
+ $this->db->query("UPDATE " . DB_PREFIX . "customer SET token = '" . $this->db->escape($token) . "' WHERE customer_id = '" . (int)$customer_id . "'");
+ }
+
+ public function deleteCustomer($customer_id) {
+ $this->db->query("DELETE FROM " . DB_PREFIX . "customer WHERE customer_id = '" . (int)$customer_id . "'");
+ $this->db->query("DELETE FROM " . DB_PREFIX . "customer_activity WHERE customer_id = '" . (int)$customer_id . "'");
+ $this->db->query("DELETE FROM " . DB_PREFIX . "customer_affiliate WHERE customer_id = '" . (int)$customer_id . "'");
+ $this->db->query("DELETE FROM " . DB_PREFIX . "customer_approval WHERE customer_id = '" . (int)$customer_id . "'");
+ $this->db->query("DELETE FROM " . DB_PREFIX . "customer_reward WHERE customer_id = '" . (int)$customer_id . "'");
+ $this->db->query("DELETE FROM " . DB_PREFIX . "customer_transaction WHERE customer_id = '" . (int)$customer_id . "'");
+ $this->db->query("DELETE FROM " . DB_PREFIX . "customer_ip WHERE customer_id = '" . (int)$customer_id . "'");
+ $this->db->query("DELETE FROM " . DB_PREFIX . "address WHERE customer_id = '" . (int)$customer_id . "'");
+ }
+
+ public function getCustomer($customer_id) {
+ $query = $this->db->query("SELECT DISTINCT * FROM " . DB_PREFIX . "customer WHERE customer_id = '" . (int)$customer_id . "'");
+
+ return $query->row;
+ }
+
+ public function getCustomerByEmail($email) {
+ $query = $this->db->query("SELECT DISTINCT * FROM " . DB_PREFIX . "customer WHERE LCASE(email) = '" . $this->db->escape(utf8_strtolower($email)) . "'");
+
+ return $query->row;
+ }
+
+ public function getCustomers($data = array()) {
+ $sql = "SELECT *, CONCAT(c.firstname, ' ', c.lastname) AS name, cgd.name AS customer_group FROM " . DB_PREFIX . "customer c LEFT JOIN " . DB_PREFIX . "customer_group_description cgd ON (c.customer_group_id = cgd.customer_group_id)";
+
+ if (!empty($data['filter_affiliate'])) {
+ $sql .= " LEFT JOIN " . DB_PREFIX . "customer_affiliate ca ON (c.customer_id = ca.customer_id)";
+ }
+
+ $sql .= " WHERE cgd.language_id = '" . (int)$this->config->get('config_language_id') . "'";
+
+ $implode = array();
+
+ if (!empty($data['filter_name'])) {
+ $implode[] = "CONCAT(c.firstname, ' ', c.lastname) LIKE '%" . $this->db->escape($data['filter_name']) . "%'";
+ }
+
+ if (!empty($data['filter_email'])) {
+ $implode[] = "c.email LIKE '" . $this->db->escape($data['filter_email']) . "%'";
+ }
+
+ if (isset($data['filter_newsletter']) && !is_null($data['filter_newsletter'])) {
+ $implode[] = "c.newsletter = '" . (int)$data['filter_newsletter'] . "'";
+ }
+
+ if (!empty($data['filter_customer_group_id'])) {
+ $implode[] = "c.customer_group_id = '" . (int)$data['filter_customer_group_id'] . "'";
+ }
+
+ if (!empty($data['filter_affiliate'])) {
+ $implode[] = "ca.status = '" . (int)$data['filter_affiliate'] . "'";
+ }
+
+ if (!empty($data['filter_ip'])) {
+ $implode[] = "c.customer_id IN (SELECT customer_id FROM " . DB_PREFIX . "customer_ip WHERE ip = '" . $this->db->escape($data['filter_ip']) . "')";
+ }
+
+ if (isset($data['filter_status']) && $data['filter_status'] !== '') {
+ $implode[] = "c.status = '" . (int)$data['filter_status'] . "'";
+ }
+
+ if (!empty($data['filter_date_added'])) {
+ $implode[] = "DATE(c.date_added) = DATE('" . $this->db->escape($data['filter_date_added']) . "')";
+ }
+
+ if ($implode) {
+ $sql .= " AND " . implode(" AND ", $implode);
+ }
+
+ $sort_data = array(
+ 'name',
+ 'c.email',
+ 'customer_group',
+ 'c.status',
+ 'c.ip',
+ 'c.date_added'
+ );
+
+ if (isset($data['sort']) && in_array($data['sort'], $sort_data)) {
+ $sql .= " ORDER BY " . $data['sort'];
+ } else {
+ $sql .= " ORDER BY name";
+ }
+
+ 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'];
+ }
+
+ $query = $this->db->query($sql);
+
+ return $query->rows;
+ }
+
+ public function getAddress($address_id) {
+ $address_query = $this->db->query("SELECT * FROM " . DB_PREFIX . "address WHERE address_id = '" . (int)$address_id . "'");
+
+ if ($address_query->num_rows) {
+ $country_query = $this->db->query("SELECT * FROM `" . DB_PREFIX . "country` WHERE country_id = '" . (int)$address_query->row['country_id'] . "'");
+
+ if ($country_query->num_rows) {
+ $country = $country_query->row['name'];
+ $iso_code_2 = $country_query->row['iso_code_2'];
+ $iso_code_3 = $country_query->row['iso_code_3'];
+ $address_format = $country_query->row['address_format'];
+ } else {
+ $country = '';
+ $iso_code_2 = '';
+ $iso_code_3 = '';
+ $address_format = '';
+ }
+
+ $zone_query = $this->db->query("SELECT * FROM `" . DB_PREFIX . "zone` WHERE zone_id = '" . (int)$address_query->row['zone_id'] . "'");
+
+ if ($zone_query->num_rows) {
+ $zone = $zone_query->row['name'];
+ $zone_code = $zone_query->row['code'];
+ } else {
+ $zone = '';
+ $zone_code = '';
+ }
+
+ return array(
+ 'address_id' => $address_query->row['address_id'],
+ 'customer_id' => $address_query->row['customer_id'],
+ 'firstname' => $address_query->row['firstname'],
+ 'lastname' => $address_query->row['lastname'],
+ 'company' => $address_query->row['company'],
+ 'address_1' => $address_query->row['address_1'],
+ 'address_2' => $address_query->row['address_2'],
+ 'postcode' => $address_query->row['postcode'],
+ 'city' => $address_query->row['city'],
+ 'zone_id' => $address_query->row['zone_id'],
+ 'zone' => $zone,
+ 'zone_code' => $zone_code,
+ 'country_id' => $address_query->row['country_id'],
+ 'country' => $country,
+ 'iso_code_2' => $iso_code_2,
+ 'iso_code_3' => $iso_code_3,
+ 'address_format' => $address_format,
+ 'custom_field' => json_decode($address_query->row['custom_field'], true)
+ );
+ }
+ }
+
+ public function getAddresses($customer_id) {
+ $address_data = array();
+
+ $query = $this->db->query("SELECT address_id FROM " . DB_PREFIX . "address WHERE customer_id = '" . (int)$customer_id . "'");
+
+ foreach ($query->rows as $result) {
+ $address_info = $this->getAddress($result['address_id']);
+
+ if ($address_info) {
+ $address_data[$result['address_id']] = $address_info;
+ }
+ }
+
+ return $address_data;
+ }
+
+ public function getTotalCustomers($data = array()) {
+ $sql = "SELECT COUNT(*) AS total FROM " . DB_PREFIX . "customer";
+
+ $implode = array();
+
+ if (!empty($data['filter_name'])) {
+ $implode[] = "CONCAT(firstname, ' ', lastname) LIKE '%" . $this->db->escape($data['filter_name']) . "%'";
+ }
+
+ if (!empty($data['filter_email'])) {
+ $implode[] = "email LIKE '" . $this->db->escape($data['filter_email']) . "%'";
+ }
+
+ if (isset($data['filter_newsletter']) && !is_null($data['filter_newsletter'])) {
+ $implode[] = "newsletter = '" . (int)$data['filter_newsletter'] . "'";
+ }
+
+ if (!empty($data['filter_customer_group_id'])) {
+ $implode[] = "customer_group_id = '" . (int)$data['filter_customer_group_id'] . "'";
+ }
+
+ if (!empty($data['filter_ip'])) {
+ $implode[] = "customer_id IN (SELECT customer_id FROM " . DB_PREFIX . "customer_ip WHERE ip = '" . $this->db->escape($data['filter_ip']) . "')";
+ }
+
+ if (isset($data['filter_status']) && $data['filter_status'] !== '') {
+ $implode[] = "status = '" . (int)$data['filter_status'] . "'";
+ }
+
+ if (!empty($data['filter_date_added'])) {
+ $implode[] = "DATE(date_added) = DATE('" . $this->db->escape($data['filter_date_added']) . "')";
+ }
+
+ if ($implode) {
+ $sql .= " WHERE " . implode(" AND ", $implode);
+ }
+
+ $query = $this->db->query($sql);
+
+ return $query->row['total'];
+ }
+
+ public function getAffliateByTracking($tracking) {
+ $query = $this->db->query("SELECT * FROM " . DB_PREFIX . "customer_affiliate WHERE tracking = '" . $this->db->escape($tracking) . "'");
+
+ return $query->row;
+ }
+
+ public function getAffiliate($customer_id) {
+ $query = $this->db->query("SELECT * FROM " . DB_PREFIX . "customer_affiliate WHERE customer_id = '" . (int)$customer_id . "'");
+
+ return $query->row;
+ }
+
+ public function getAffiliates($data = array()) {
+ $sql = "SELECT DISTINCT *, CONCAT(c.firstname, ' ', c.lastname) AS name FROM " . DB_PREFIX . "customer_affiliate ca LEFT JOIN " . DB_PREFIX . "customer c ON (ca.customer_id = c.customer_id)";
+
+ $implode = array();
+
+ if (!empty($data['filter_name'])) {
+ $implode[] = "CONCAT(c.firstname, ' ', c.lastname) LIKE '%" . $this->db->escape($data['filter_name']) . "%'";
+ }
+
+ if ($implode) {
+ $sql .= " WHERE " . implode(" AND ", $implode);
+ }
+
+ 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'];
+ }
+
+ $query = $this->db->query($sql . "ORDER BY name");
+
+ return $query->rows;
+ }
+
+ public function getTotalAffiliates($data = array()) {
+ $sql = "SELECT DISTINCT COUNT(*) AS total FROM " . DB_PREFIX . "customer_affiliate ca LEFT JOIN " . DB_PREFIX . "customer c ON (ca.customer_id = c.customer_id)";
+
+ $implode = array();
+
+ if (!empty($data['filter_name'])) {
+ $implode[] = "CONCAT(c.firstname, ' ', c.lastname) LIKE '%" . $this->db->escape($data['filter_name']) . "%'";
+ }
+
+ if ($implode) {
+ $sql .= " WHERE " . implode(" AND ", $implode);
+ }
+
+ return $query->row['total'];
+ }
+
+ public function getTotalAddressesByCustomerId($customer_id) {
+ $query = $this->db->query("SELECT COUNT(*) AS total FROM " . DB_PREFIX . "address WHERE customer_id = '" . (int)$customer_id . "'");
+
+ return $query->row['total'];
+ }
+
+ public function getTotalAddressesByCountryId($country_id) {
+ $query = $this->db->query("SELECT COUNT(*) AS total FROM " . DB_PREFIX . "address WHERE country_id = '" . (int)$country_id . "'");
+
+ return $query->row['total'];
+ }
+
+ public function getTotalAddressesByZoneId($zone_id) {
+ $query = $this->db->query("SELECT COUNT(*) AS total FROM " . DB_PREFIX . "address WHERE zone_id = '" . (int)$zone_id . "'");
+
+ return $query->row['total'];
+ }
+
+ public function getTotalCustomersByCustomerGroupId($customer_group_id) {
+ $query = $this->db->query("SELECT COUNT(*) AS total FROM " . DB_PREFIX . "customer WHERE customer_group_id = '" . (int)$customer_group_id . "'");
+
+ return $query->row['total'];
+ }
+
+ public function addHistory($customer_id, $comment) {
+ $this->db->query("INSERT INTO " . DB_PREFIX . "customer_history SET customer_id = '" . (int)$customer_id . "', comment = '" . $this->db->escape(strip_tags($comment)) . "', date_added = NOW()");
+ }
+
+ public function getHistories($customer_id, $start = 0, $limit = 10) {
+ if ($start < 0) {
+ $start = 0;
+ }
+
+ if ($limit < 1) {
+ $limit = 10;
+ }
+
+ $query = $this->db->query("SELECT comment, date_added FROM " . DB_PREFIX . "customer_history WHERE customer_id = '" . (int)$customer_id . "' ORDER BY date_added DESC LIMIT " . (int)$start . "," . (int)$limit);
+
+ return $query->rows;
+ }
+
+ public function getTotalHistories($customer_id) {
+ $query = $this->db->query("SELECT COUNT(*) AS total FROM " . DB_PREFIX . "customer_history WHERE customer_id = '" . (int)$customer_id . "'");
+
+ return $query->row['total'];
+ }
+
+ public function addTransaction($customer_id, $description = '', $amount = '', $order_id = 0) {
+ $this->db->query("INSERT INTO " . DB_PREFIX . "customer_transaction SET customer_id = '" . (int)$customer_id . "', order_id = '" . (int)$order_id . "', description = '" . $this->db->escape($description) . "', amount = '" . (float)$amount . "', date_added = NOW()");
+ }
+
+ public function deleteTransactionByOrderId($order_id) {
+ $this->db->query("DELETE FROM " . DB_PREFIX . "customer_transaction WHERE order_id = '" . (int)$order_id . "'");
+ }
+
+ public function getTransactions($customer_id, $start = 0, $limit = 10) {
+ if ($start < 0) {
+ $start = 0;
+ }
+
+ if ($limit < 1) {
+ $limit = 10;
+ }
+
+ $query = $this->db->query("SELECT * FROM " . DB_PREFIX . "customer_transaction WHERE customer_id = '" . (int)$customer_id . "' ORDER BY date_added DESC LIMIT " . (int)$start . "," . (int)$limit);
+
+ return $query->rows;
+ }
+
+ public function getTotalTransactions($customer_id) {
+ $query = $this->db->query("SELECT COUNT(*) AS total FROM " . DB_PREFIX . "customer_transaction WHERE customer_id = '" . (int)$customer_id . "'");
+
+ return $query->row['total'];
+ }
+
+ public function getTransactionTotal($customer_id) {
+ $query = $this->db->query("SELECT SUM(amount) AS total FROM " . DB_PREFIX . "customer_transaction WHERE customer_id = '" . (int)$customer_id . "'");
+
+ return $query->row['total'];
+ }
+
+ public function getTotalTransactionsByOrderId($order_id) {
+ $query = $this->db->query("SELECT COUNT(*) AS total FROM " . DB_PREFIX . "customer_transaction WHERE order_id = '" . (int)$order_id . "'");
+
+ return $query->row['total'];
+ }
+
+ public function addReward($customer_id, $description = '', $points = '', $order_id = 0) {
+ $this->db->query("INSERT INTO " . DB_PREFIX . "customer_reward SET customer_id = '" . (int)$customer_id . "', order_id = '" . (int)$order_id . "', points = '" . (int)$points . "', description = '" . $this->db->escape($description) . "', date_added = NOW()");
+ }
+
+ public function deleteReward($order_id) {
+ $this->db->query("DELETE FROM " . DB_PREFIX . "customer_reward WHERE order_id = '" . (int)$order_id . "' AND points > 0");
+ }
+
+ public function getRewards($customer_id, $start = 0, $limit = 10) {
+ $query = $this->db->query("SELECT * FROM " . DB_PREFIX . "customer_reward WHERE customer_id = '" . (int)$customer_id . "' ORDER BY date_added DESC LIMIT " . (int)$start . "," . (int)$limit);
+
+ return $query->rows;
+ }
+
+ public function getTotalRewards($customer_id) {
+ $query = $this->db->query("SELECT COUNT(*) AS total FROM " . DB_PREFIX . "customer_reward WHERE customer_id = '" . (int)$customer_id . "'");
+
+ return $query->row['total'];
+ }
+
+ public function getRewardTotal($customer_id) {
+ $query = $this->db->query("SELECT SUM(points) AS total FROM " . DB_PREFIX . "customer_reward WHERE customer_id = '" . (int)$customer_id . "'");
+
+ return $query->row['total'];
+ }
+
+ public function getTotalCustomerRewardsByOrderId($order_id) {
+ $query = $this->db->query("SELECT COUNT(*) AS total FROM " . DB_PREFIX . "customer_reward WHERE order_id = '" . (int)$order_id . "' AND points > 0");
+
+ return $query->row['total'];
+ }
+
+ public function getIps($customer_id, $start = 0, $limit = 10) {
+ if ($start < 0) {
+ $start = 0;
+ }
+ if ($limit < 1) {
+ $limit = 10;
+ }
+
+ $query = $this->db->query("SELECT * FROM " . DB_PREFIX . "customer_ip WHERE customer_id = '" . (int)$customer_id . "' ORDER BY date_added DESC LIMIT " . (int)$start . "," . (int)$limit);
+
+ return $query->rows;
+ }
+
+ public function getTotalIps($customer_id) {
+ $query = $this->db->query("SELECT COUNT(*) AS total FROM " . DB_PREFIX . "customer_ip WHERE customer_id = '" . (int)$customer_id . "'");
+
+ return $query->row['total'];
+ }
+
+ public function getTotalCustomersByIp($ip) {
+ $query = $this->db->query("SELECT COUNT(*) AS total FROM " . DB_PREFIX . "customer_ip WHERE ip = '" . $this->db->escape($ip) . "'");
+
+ return $query->row['total'];
+ }
+
+ public function getTotalLoginAttempts($email) {
+ $query = $this->db->query("SELECT * FROM `" . DB_PREFIX . "customer_login` WHERE `email` = '" . $this->db->escape($email) . "'");
+
+ return $query->row;
+ }
+
+ public function deleteLoginAttempts($email) {
+ $this->db->query("DELETE FROM `" . DB_PREFIX . "customer_login` WHERE `email` = '" . $this->db->escape($email) . "'");
+ }
+}
diff --git a/public/admin/model/customer/customer_approval.php b/public/admin/model/customer/customer_approval.php
new file mode 100644
index 0000000..f75a3c7
--- /dev/null
+++ b/public/admin/model/customer/customer_approval.php
@@ -0,0 +1,102 @@
+<?php
+class ModelCustomerCustomerApproval extends Model {
+ public function getCustomerApprovals($data = array()) {
+ $sql = "SELECT *, CONCAT(c.`firstname`, ' ', c.`lastname`) AS name, cgd.`name` AS customer_group, ca.`type` FROM `" . DB_PREFIX . "customer_approval` ca LEFT JOIN `" . DB_PREFIX . "customer` c ON (ca.`customer_id` = c.`customer_id`) LEFT JOIN `" . DB_PREFIX . "customer_group_description` cgd ON (c.`customer_group_id` = cgd.`customer_group_id`) WHERE cgd.`language_id` = '" . (int)$this->config->get('config_language_id') . "'";
+
+ if (!empty($data['filter_name'])) {
+ $sql .= " AND CONCAT(c.`firstname`, ' ', c.`lastname`) LIKE '%" . $this->db->escape($data['filter_name']) . "%'";
+ }
+
+ if (!empty($data['filter_email'])) {
+ $sql .= " AND c.`email` LIKE '" . $this->db->escape($data['filter_email']) . "%'";
+ }
+
+ if (!empty($data['filter_customer_group_id'])) {
+ $sql .= " AND c.`customer_group_id` = '" . (int)$data['filter_customer_group_id'] . "'";
+ }
+
+ if (!empty($data['filter_type'])) {
+ $sql .= " AND ca.`type` = '" . $this->db->escape($data['filter_type']) . "'";
+ }
+
+ if (!empty($data['filter_date_added'])) {
+ $sql .= " AND DATE(c.`date_added`) = DATE('" . $this->db->escape($data['filter_date_added']) . "')";
+ }
+
+ $sql .= " ORDER BY c.`date_added` DESC";
+
+ 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'];
+ }
+
+ $query = $this->db->query($sql);
+
+ return $query->rows;
+ }
+
+ public function getCustomerApproval($customer_approval_id) {
+ $query = $this->db->query("SELECT * FROM `" . DB_PREFIX . "customer_approval` WHERE `customer_approval_id` = '" . (int)$customer_approval_id . "'");
+
+ return $query->row;
+ }
+
+ public function getTotalCustomerApprovals($data = array()) {
+ $sql = "SELECT COUNT(*) AS total FROM `" . DB_PREFIX . "customer_approval` ca LEFT JOIN `" . DB_PREFIX . "customer` c ON (ca.`customer_id` = c.`customer_id`)";
+
+ $implode = array();
+
+ if (!empty($data['filter_name'])) {
+ $implode[] = "CONCAT(c.`firstname`, ' ', c.`lastname`) LIKE '%" . $this->db->escape($data['filter_name']) . "%'";
+ }
+
+ if (!empty($data['filter_email'])) {
+ $implode[] = "c.`email` LIKE '" . $this->db->escape($data['filter_email']) . "%'";
+ }
+
+ if (!empty($data['filter_customer_group_id'])) {
+ $implode[] = "c.`customer_group_id` = '" . (int)$data['filter_customer_group_id'] . "'";
+ }
+
+ if (!empty($data['filter_type'])) {
+ $implode[] = "ca.`type` = '" . $this->db->escape($data['filter_type']) . "'";
+ }
+
+ if (!empty($data['filter_date_added'])) {
+ $implode[] = "DATE(ca.`date_added`) = DATE('" . $this->db->escape($data['filter_date_added']) . "')";
+ }
+
+ if ($implode) {
+ $sql .= " WHERE " . implode(" AND ", $implode);
+ }
+
+ $query = $this->db->query($sql);
+
+ return $query->row['total'];
+ }
+
+ public function approveCustomer($customer_id) {
+ $this->db->query("UPDATE `" . DB_PREFIX . "customer` SET status = '1' WHERE customer_id = '" . (int)$customer_id . "'");
+ $this->db->query("DELETE FROM `" . DB_PREFIX . "customer_approval` WHERE customer_id = '" . (int)$customer_id . "' AND `type` = 'customer'");
+ }
+
+ public function denyCustomer($customer_id) {
+ $this->db->query("DELETE FROM `" . DB_PREFIX . "customer_approval` WHERE customer_id = '" . (int)$customer_id . "' AND `type` = 'customer'");
+ }
+
+ public function approveAffiliate($customer_id) {
+ $this->db->query("UPDATE `" . DB_PREFIX . "customer_affiliate` SET status = '1' WHERE customer_id = '" . (int)$customer_id . "'");
+ $this->db->query("DELETE FROM `" . DB_PREFIX . "customer_approval` WHERE customer_id = '" . (int)$customer_id . "' AND `type` = 'affiliate'");
+ }
+
+ public function denyAffiliate($customer_id) {
+ $this->db->query("DELETE FROM `" . DB_PREFIX . "customer_approval` WHERE customer_id = '" . (int)$customer_id . "' AND `type` = 'affiliate'");
+ }
+} \ No newline at end of file
diff --git a/public/admin/model/customer/customer_group.php b/public/admin/model/customer/customer_group.php
new file mode 100644
index 0000000..f93b4c9
--- /dev/null
+++ b/public/admin/model/customer/customer_group.php
@@ -0,0 +1,97 @@
+<?php
+class ModelCustomerCustomerGroup extends Model {
+ public function addCustomerGroup($data) {
+ $this->db->query("INSERT INTO " . DB_PREFIX . "customer_group SET approval = '" . (int)$data['approval'] . "', sort_order = '" . (int)$data['sort_order'] . "'");
+
+ $customer_group_id = $this->db->getLastId();
+
+ foreach ($data['customer_group_description'] as $language_id => $value) {
+ $this->db->query("INSERT INTO " . DB_PREFIX . "customer_group_description SET customer_group_id = '" . (int)$customer_group_id . "', language_id = '" . (int)$language_id . "', name = '" . $this->db->escape($value['name']) . "', description = '" . $this->db->escape($value['description']) . "'");
+ }
+
+ return $customer_group_id;
+ }
+
+ public function editCustomerGroup($customer_group_id, $data) {
+ $this->db->query("UPDATE " . DB_PREFIX . "customer_group SET approval = '" . (int)$data['approval'] . "', sort_order = '" . (int)$data['sort_order'] . "' WHERE customer_group_id = '" . (int)$customer_group_id . "'");
+
+ $this->db->query("DELETE FROM " . DB_PREFIX . "customer_group_description WHERE customer_group_id = '" . (int)$customer_group_id . "'");
+
+ foreach ($data['customer_group_description'] as $language_id => $value) {
+ $this->db->query("INSERT INTO " . DB_PREFIX . "customer_group_description SET customer_group_id = '" . (int)$customer_group_id . "', language_id = '" . (int)$language_id . "', name = '" . $this->db->escape($value['name']) . "', description = '" . $this->db->escape($value['description']) . "'");
+ }
+ }
+
+ public function deleteCustomerGroup($customer_group_id) {
+ $this->db->query("DELETE FROM " . DB_PREFIX . "customer_group WHERE customer_group_id = '" . (int)$customer_group_id . "'");
+ $this->db->query("DELETE FROM " . DB_PREFIX . "customer_group_description WHERE customer_group_id = '" . (int)$customer_group_id . "'");
+ $this->db->query("DELETE FROM " . DB_PREFIX . "product_discount WHERE customer_group_id = '" . (int)$customer_group_id . "'");
+ $this->db->query("DELETE FROM " . DB_PREFIX . "product_special WHERE customer_group_id = '" . (int)$customer_group_id . "'");
+ $this->db->query("DELETE FROM " . DB_PREFIX . "product_reward WHERE customer_group_id = '" . (int)$customer_group_id . "'");
+ $this->db->query("DELETE FROM " . DB_PREFIX . "tax_rate_to_customer_group WHERE customer_group_id = '" . (int)$customer_group_id . "'");
+ }
+
+ public function getCustomerGroup($customer_group_id) {
+ $query = $this->db->query("SELECT DISTINCT * FROM " . DB_PREFIX . "customer_group cg LEFT JOIN " . DB_PREFIX . "customer_group_description cgd ON (cg.customer_group_id = cgd.customer_group_id) WHERE cg.customer_group_id = '" . (int)$customer_group_id . "' AND cgd.language_id = '" . (int)$this->config->get('config_language_id') . "'");
+
+ return $query->row;
+ }
+
+ public function getCustomerGroups($data = array()) {
+ $sql = "SELECT * FROM " . DB_PREFIX . "customer_group cg LEFT JOIN " . DB_PREFIX . "customer_group_description cgd ON (cg.customer_group_id = cgd.customer_group_id) WHERE cgd.language_id = '" . (int)$this->config->get('config_language_id') . "'";
+
+ $sort_data = array(
+ 'cgd.name',
+ 'cg.sort_order'
+ );
+
+ if (isset($data['sort']) && in_array($data['sort'], $sort_data)) {
+ $sql .= " ORDER BY " . $data['sort'];
+ } else {
+ $sql .= " ORDER BY cgd.name";
+ }
+
+ 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'];
+ }
+
+ $query = $this->db->query($sql);
+
+ return $query->rows;
+ }
+
+ public function getCustomerGroupDescriptions($customer_group_id) {
+ $customer_group_data = array();
+
+ $query = $this->db->query("SELECT * FROM " . DB_PREFIX . "customer_group_description WHERE customer_group_id = '" . (int)$customer_group_id . "'");
+
+ foreach ($query->rows as $result) {
+ $customer_group_data[$result['language_id']] = array(
+ 'name' => $result['name'],
+ 'description' => $result['description']
+ );
+ }
+
+ return $customer_group_data;
+ }
+
+ public function getTotalCustomerGroups() {
+ $query = $this->db->query("SELECT COUNT(*) AS total FROM " . DB_PREFIX . "customer_group");
+
+ return $query->row['total'];
+ }
+}
diff --git a/public/admin/model/design/banner.php b/public/admin/model/design/banner.php
new file mode 100644
index 0000000..e39464e
--- /dev/null
+++ b/public/admin/model/design/banner.php
@@ -0,0 +1,103 @@
+<?php
+class ModelDesignBanner extends Model {
+ public function addBanner($data) {
+ $this->db->query("INSERT INTO " . DB_PREFIX . "banner SET name = '" . $this->db->escape($data['name']) . "', status = '" . (int)$data['status'] . "'");
+
+ $banner_id = $this->db->getLastId();
+
+ if (isset($data['banner_image'])) {
+ foreach ($data['banner_image'] as $language_id => $value) {
+ foreach ($value as $banner_image) {
+ $this->db->query("INSERT INTO " . DB_PREFIX . "banner_image SET banner_id = '" . (int)$banner_id . "', language_id = '" . (int)$language_id . "', title = '" . $this->db->escape($banner_image['title']) . "', link = '" . $this->db->escape($banner_image['link']) . "', image = '" . $this->db->escape($banner_image['image']) . "', sort_order = '" . (int)$banner_image['sort_order'] . "'");
+ }
+ }
+ }
+
+ return $banner_id;
+ }
+
+ public function editBanner($banner_id, $data) {
+ $this->db->query("UPDATE " . DB_PREFIX . "banner SET name = '" . $this->db->escape($data['name']) . "', status = '" . (int)$data['status'] . "' WHERE banner_id = '" . (int)$banner_id . "'");
+
+ $this->db->query("DELETE FROM " . DB_PREFIX . "banner_image WHERE banner_id = '" . (int)$banner_id . "'");
+
+ if (isset($data['banner_image'])) {
+ foreach ($data['banner_image'] as $language_id => $value) {
+ foreach ($value as $banner_image) {
+ $this->db->query("INSERT INTO " . DB_PREFIX . "banner_image SET banner_id = '" . (int)$banner_id . "', language_id = '" . (int)$language_id . "', title = '" . $this->db->escape($banner_image['title']) . "', link = '" . $this->db->escape($banner_image['link']) . "', image = '" . $this->db->escape($banner_image['image']) . "', sort_order = '" . (int)$banner_image['sort_order'] . "'");
+ }
+ }
+ }
+ }
+
+ public function deleteBanner($banner_id) {
+ $this->db->query("DELETE FROM " . DB_PREFIX . "banner WHERE banner_id = '" . (int)$banner_id . "'");
+ $this->db->query("DELETE FROM " . DB_PREFIX . "banner_image WHERE banner_id = '" . (int)$banner_id . "'");
+ }
+
+ public function getBanner($banner_id) {
+ $query = $this->db->query("SELECT DISTINCT * FROM " . DB_PREFIX . "banner WHERE banner_id = '" . (int)$banner_id . "'");
+
+ return $query->row;
+ }
+
+ public function getBanners($data = array()) {
+ $sql = "SELECT * FROM " . DB_PREFIX . "banner";
+
+ $sort_data = array(
+ 'name',
+ 'status'
+ );
+
+ if (isset($data['sort']) && in_array($data['sort'], $sort_data)) {
+ $sql .= " ORDER BY " . $data['sort'];
+ } else {
+ $sql .= " ORDER BY name";
+ }
+
+ 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'];
+ }
+
+ $query = $this->db->query($sql);
+
+ return $query->rows;
+ }
+
+ public function getBannerImages($banner_id) {
+ $banner_image_data = array();
+
+ $banner_image_query = $this->db->query("SELECT * FROM " . DB_PREFIX . "banner_image WHERE banner_id = '" . (int)$banner_id . "' ORDER BY sort_order ASC");
+
+ foreach ($banner_image_query->rows as $banner_image) {
+ $banner_image_data[$banner_image['language_id']][] = array(
+ 'title' => $banner_image['title'],
+ 'link' => $banner_image['link'],
+ 'image' => $banner_image['image'],
+ 'sort_order' => $banner_image['sort_order']
+ );
+ }
+
+ return $banner_image_data;
+ }
+
+ public function getTotalBanners() {
+ $query = $this->db->query("SELECT COUNT(*) AS total FROM " . DB_PREFIX . "banner");
+
+ return $query->row['total'];
+ }
+}
diff --git a/public/admin/model/design/layout.php b/public/admin/model/design/layout.php
new file mode 100644
index 0000000..1cd3bff
--- /dev/null
+++ b/public/admin/model/design/layout.php
@@ -0,0 +1,109 @@
+<?php
+class ModelDesignLayout extends Model {
+ public function addLayout($data) {
+ $this->db->query("INSERT INTO " . DB_PREFIX . "layout SET name = '" . $this->db->escape($data['name']) . "'");
+
+ $layout_id = $this->db->getLastId();
+
+ if (isset($data['layout_route'])) {
+ foreach ($data['layout_route'] as $layout_route) {
+ $this->db->query("INSERT INTO " . DB_PREFIX . "layout_route SET layout_id = '" . (int)$layout_id . "', store_id = '" . (int)$layout_route['store_id'] . "', route = '" . $this->db->escape($layout_route['route']) . "'");
+ }
+ }
+
+ if (isset($data['layout_module'])) {
+ foreach ($data['layout_module'] as $layout_module) {
+ $this->db->query("INSERT INTO " . DB_PREFIX . "layout_module SET layout_id = '" . (int)$layout_id . "', code = '" . $this->db->escape($layout_module['code']) . "', position = '" . $this->db->escape($layout_module['position']) . "', sort_order = '" . (int)$layout_module['sort_order'] . "'");
+ }
+ }
+
+ return $layout_id;
+ }
+
+ public function editLayout($layout_id, $data) {
+ $this->db->query("UPDATE " . DB_PREFIX . "layout SET name = '" . $this->db->escape($data['name']) . "' WHERE layout_id = '" . (int)$layout_id . "'");
+
+ $this->db->query("DELETE FROM " . DB_PREFIX . "layout_route WHERE layout_id = '" . (int)$layout_id . "'");
+
+ if (isset($data['layout_route'])) {
+ foreach ($data['layout_route'] as $layout_route) {
+ $this->db->query("INSERT INTO " . DB_PREFIX . "layout_route SET layout_id = '" . (int)$layout_id . "', store_id = '" . (int)$layout_route['store_id'] . "', route = '" . $this->db->escape($layout_route['route']) . "'");
+ }
+ }
+
+ $this->db->query("DELETE FROM " . DB_PREFIX . "layout_module WHERE layout_id = '" . (int)$layout_id . "'");
+
+ if (isset($data['layout_module'])) {
+ foreach ($data['layout_module'] as $layout_module) {
+ $this->db->query("INSERT INTO " . DB_PREFIX . "layout_module SET layout_id = '" . (int)$layout_id . "', code = '" . $this->db->escape($layout_module['code']) . "', position = '" . $this->db->escape($layout_module['position']) . "', sort_order = '" . (int)$layout_module['sort_order'] . "'");
+ }
+ }
+ }
+
+ public function deleteLayout($layout_id) {
+ $this->db->query("DELETE FROM " . DB_PREFIX . "layout WHERE layout_id = '" . (int)$layout_id . "'");
+ $this->db->query("DELETE FROM " . DB_PREFIX . "layout_route WHERE layout_id = '" . (int)$layout_id . "'");
+ $this->db->query("DELETE FROM " . DB_PREFIX . "layout_module WHERE layout_id = '" . (int)$layout_id . "'");
+ $this->db->query("DELETE FROM " . DB_PREFIX . "category_to_layout WHERE layout_id = '" . (int)$layout_id . "'");
+ $this->db->query("DELETE FROM " . DB_PREFIX . "product_to_layout WHERE layout_id = '" . (int)$layout_id . "'");
+ $this->db->query("DELETE FROM " . DB_PREFIX . "information_to_layout WHERE layout_id = '" . (int)$layout_id . "'");
+ }
+
+ public function getLayout($layout_id) {
+ $query = $this->db->query("SELECT DISTINCT * FROM " . DB_PREFIX . "layout WHERE layout_id = '" . (int)$layout_id . "'");
+
+ return $query->row;
+ }
+
+ public function getLayouts($data = array()) {
+ $sql = "SELECT * FROM " . DB_PREFIX . "layout";
+
+ $sort_data = array('name');
+
+ if (isset($data['sort']) && in_array($data['sort'], $sort_data)) {
+ $sql .= " ORDER BY " . $data['sort'];
+ } else {
+ $sql .= " ORDER BY name";
+ }
+
+ 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'];
+ }
+
+ $query = $this->db->query($sql);
+
+ return $query->rows;
+ }
+
+ public function getLayoutRoutes($layout_id) {
+ $query = $this->db->query("SELECT * FROM " . DB_PREFIX . "layout_route WHERE layout_id = '" . (int)$layout_id . "'");
+
+ return $query->rows;
+ }
+
+ public function getLayoutModules($layout_id) {
+ $query = $this->db->query("SELECT * FROM " . DB_PREFIX . "layout_module WHERE layout_id = '" . (int)$layout_id . "' ORDER BY position ASC, sort_order ASC");
+
+ return $query->rows;
+ }
+
+ public function getTotalLayouts() {
+ $query = $this->db->query("SELECT COUNT(*) AS total FROM " . DB_PREFIX . "layout");
+
+ return $query->row['total'];
+ }
+} \ No newline at end of file
diff --git a/public/admin/model/design/seo_url.php b/public/admin/model/design/seo_url.php
new file mode 100644
index 0000000..093b28c
--- /dev/null
+++ b/public/admin/model/design/seo_url.php
@@ -0,0 +1,123 @@
+<?php
+class ModelDesignSeoUrl extends Model {
+ public function addSeoUrl($data) {
+ $this->db->query("INSERT INTO `" . DB_PREFIX . "seo_url` SET store_id = '" . (int)$data['store_id'] . "', language_id = '" . (int)$data['language_id'] . "', query = '" . $this->db->escape($data['query']) . "', keyword = '" . $this->db->escape($data['keyword']) . "'");
+ }
+
+ public function editSeoUrl($seo_url_id, $data) {
+ $this->db->query("UPDATE `" . DB_PREFIX . "seo_url` SET store_id = '" . (int)$data['store_id'] . "', language_id = '" . (int)$data['language_id'] . "', query = '" . $this->db->escape($data['query']) . "', keyword = '" . $this->db->escape($data['keyword']) . "' WHERE seo_url_id = '" . (int)$seo_url_id . "'");
+ }
+
+ public function deleteSeoUrl($seo_url_id) {
+ $this->db->query("DELETE FROM `" . DB_PREFIX . "seo_url` WHERE seo_url_id = '" . (int)$seo_url_id . "'");
+ }
+
+ public function getSeoUrl($seo_url_id) {
+ $query = $this->db->query("SELECT * FROM `" . DB_PREFIX . "seo_url` WHERE seo_url_id = '" . (int)$seo_url_id . "'");
+
+ return $query->row;
+ }
+
+ public function getSeoUrls($data = array()) {
+ $sql = "SELECT *, (SELECT `name` FROM `" . DB_PREFIX . "store` s WHERE s.store_id = su.store_id) AS store, (SELECT `name` FROM `" . DB_PREFIX . "language` l WHERE l.language_id = su.language_id) AS language FROM `" . DB_PREFIX . "seo_url` su";
+
+ $implode = array();
+
+ if (!empty($data['filter_query'])) {
+ $implode[] = "`query` LIKE '" . $this->db->escape($data['filter_query']) . "'";
+ }
+
+ if (!empty($data['filter_keyword'])) {
+ $implode[] = "`keyword` LIKE '" . $this->db->escape($data['filter_keyword']) . "'";
+ }
+
+ if (isset($data['filter_store_id']) && $data['filter_store_id'] !== '') {
+ $implode[] = "`store_id` = '" . (int)$data['filter_store_id'] . "'";
+ }
+
+ if (!empty($data['filter_language_id']) && $data['filter_language_id'] !== '') {
+ $implode[] = "`language_id` = '" . (int)$data['filter_language_id'] . "'";
+ }
+
+ if ($implode) {
+ $sql .= " WHERE " . implode(" AND ", $implode);
+ }
+
+ $sort_data = array(
+ 'query',
+ 'keyword',
+ 'language_id',
+ 'store_id'
+ );
+
+ if (isset($data['sort']) && in_array($data['sort'], $sort_data)) {
+ $sql .= " ORDER BY " . $data['sort'];
+ } else {
+ $sql .= " ORDER BY query";
+ }
+
+ 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'];
+ }
+
+ $query = $this->db->query($sql);
+
+ return $query->rows;
+ }
+
+ public function getTotalSeoUrls($data = array()) {
+ $sql = "SELECT COUNT(*) AS total FROM `" . DB_PREFIX . "seo_url`";
+
+ $implode = array();
+
+ if (!empty($data['filter_query'])) {
+ $implode[] = "query LIKE '" . $this->db->escape($data['filter_query']) . "'";
+ }
+
+ if (!empty($data['filter_keyword'])) {
+ $implode[] = "keyword LIKE '" . $this->db->escape($data['filter_keyword']) . "'";
+ }
+
+ if (!empty($data['filter_store_id']) && $data['filter_store_id'] !== '') {
+ $implode[] = "store_id = '" . (int)$data['filter_store_id'] . "'";
+ }
+
+ if (!empty($data['filter_language_id']) && $data['filter_language_id'] !== '') {
+ $implode[] = "language_id = '" . (int)$data['filter_language_id'] . "'";
+ }
+
+ if ($implode) {
+ $sql .= " WHERE " . implode(" AND ", $implode);
+ }
+
+ $query = $this->db->query($sql);
+
+ return $query->row['total'];
+ }
+
+ public function getSeoUrlsByKeyword($keyword) {
+ $query = $this->db->query("SELECT * FROM `" . DB_PREFIX . "seo_url` WHERE keyword = '" . $this->db->escape($keyword) . "'");
+
+ return $query->rows;
+ }
+
+ public function getSeoUrlsByQuery($keyword) {
+ $query = $this->db->query("SELECT * FROM `" . DB_PREFIX . "seo_url` WHERE keyword = '" . $this->db->escape($keyword) . "'");
+
+ return $query->rows;
+ }
+} \ No newline at end of file
diff --git a/public/admin/model/design/theme.php b/public/admin/model/design/theme.php
new file mode 100644
index 0000000..966adcd
--- /dev/null
+++ b/public/admin/model/design/theme.php
@@ -0,0 +1,38 @@
+<?php
+class ModelDesignTheme extends Model {
+ public function editTheme($store_id, $theme, $route, $code) {
+ $this->db->query("DELETE FROM `" . DB_PREFIX . "theme` WHERE store_id = '" . (int)$store_id . "' AND theme = '" . $this->db->escape($theme) . "' AND route = '" . $this->db->escape($route) . "'");
+
+ $this->db->query("INSERT INTO `" . DB_PREFIX . "theme` SET store_id = '" . (int)$store_id . "', theme = '" . $this->db->escape($theme) . "', route = '" . $this->db->escape($route) . "', code = '" . $this->db->escape($code) . "', date_added = NOW()");
+ }
+
+ public function deleteTheme($theme_id) {
+ $this->db->query("DELETE FROM `" . DB_PREFIX . "theme` WHERE theme_id = '" . (int)$theme_id . "'");
+ }
+
+ public function getTheme($store_id, $theme, $route) {
+ $query = $this->db->query("SELECT * FROM `" . DB_PREFIX . "theme` WHERE store_id = '" . (int)$store_id . "' AND theme = '" . $this->db->escape($theme) . "' AND route = '" . $this->db->escape($route) . "'");
+
+ return $query->row;
+ }
+
+ public function getThemes($start = 0, $limit = 10) {
+ if ($start < 0) {
+ $start = 0;
+ }
+
+ if ($limit < 1) {
+ $limit = 10;
+ }
+
+ $query = $this->db->query("SELECT *, (SELECT name FROM `" . DB_PREFIX . "store` s WHERE s.store_id = t.store_id) AS store FROM `" . DB_PREFIX . "theme` t ORDER BY t.date_added DESC LIMIT " . (int)$start . "," . (int)$limit);
+
+ return $query->rows;
+ }
+
+ public function getTotalThemes() {
+ $query = $this->db->query("SELECT COUNT(*) AS total FROM `" . DB_PREFIX . "theme`");
+
+ return $query->row['total'];
+ }
+} \ No newline at end of file
diff --git a/public/admin/model/design/translation.php b/public/admin/model/design/translation.php
new file mode 100644
index 0000000..b85e220
--- /dev/null
+++ b/public/admin/model/design/translation.php
@@ -0,0 +1,66 @@
+<?php
+class ModelDesignTranslation extends Model {
+ public function addTranslation($data) {
+ $this->db->query("INSERT INTO `" . DB_PREFIX . "translation` SET `store_id` = '" . (int)$data['store_id'] . "', `language_id` = '" . (int)$data['language_id'] . "', `route` = '" . $this->db->escape($data['route']) . "', `key` = '" . $this->db->escape($data['key']) . "', `value` = '" . $this->db->escape($data['value']) . "', `date_added` = NOW()");
+ }
+
+ public function editTranslation($translation_id, $data) {
+ $this->db->query("UPDATE `" . DB_PREFIX . "translation` SET `store_id` = '" . (int)$data['store_id'] . "', `language_id` = '" . (int)$data['language_id'] . "', `route` = '" . $this->db->escape($data['route']) . "', `key` = '" . $this->db->escape($data['key']) . "', `value` = '" . $this->db->escape($data['value']) . "' WHERE `translation_id` = '" . (int)$translation_id . "'");
+ }
+
+ public function deleteTranslation($translation_id) {
+ $this->db->query("DELETE FROM `" . DB_PREFIX . "translation` WHERE `translation_id` = '" . (int)$translation_id . "'");
+ }
+
+ public function getTranslation($translation_id) {
+ $query = $this->db->query("SELECT DISTINCT * FROM `" . DB_PREFIX . "translation` WHERE `translation_id` = '" . (int)$translation_id . "'");
+
+ return $query->row;
+ }
+
+ public function getTranslations($data = array()) {
+ $sql = "SELECT *, (SELECT s.name FROM `" . DB_PREFIX . "store` s WHERE s.store_id = t.store_id) AS store, (SELECT l.name FROM `" . DB_PREFIX . "language` l WHERE l.language_id = t.language_id) AS language FROM `" . DB_PREFIX . "translation` t";
+
+ $sort_data = array(
+ 'store',
+ 'language',
+ 'route',
+ 'key',
+ 'value'
+ );
+
+ if (isset($data['sort']) && in_array($data['sort'], $sort_data)) {
+ $sql .= " ORDER BY `" . $data['sort'] . "`";
+ } else {
+ $sql .= " ORDER BY store";
+ }
+
+ 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'];
+ }
+
+ $query = $this->db->query($sql);
+
+ return $query->rows;
+ }
+
+ public function getTotalTranslations() {
+ $query = $this->db->query("SELECT COUNT(*) AS total FROM `" . DB_PREFIX . "translation`");
+
+ return $query->row['total'];
+ }
+}
diff --git a/public/admin/model/extension/advertise/google.php b/public/admin/model/extension/advertise/google.php
new file mode 100644
index 0000000..467e90b
--- /dev/null
+++ b/public/admin/model/extension/advertise/google.php
@@ -0,0 +1,697 @@
+<?php
+
+use \googleshopping\exception\Connection as ConnectionException;
+use \googleshopping\Googleshopping;
+
+class ModelExtensionAdvertiseGoogle extends Model {
+ private $events = array(
+ 'admin/view/common/column_left/before' => array(
+ 'extension/advertise/google/admin_link',
+ ),
+ 'admin/model/catalog/product/addProduct/after' => array(
+ 'extension/advertise/google/addProduct',
+ ),
+ 'admin/model/catalog/product/copyProduct/after' => array(
+ 'extension/advertise/google/copyProduct',
+ ),
+ 'admin/model/catalog/product/deleteProduct/after' => array(
+ 'extension/advertise/google/deleteProduct',
+ ),
+ 'catalog/controller/checkout/success/before' => array(
+ 'extension/advertise/google/before_checkout_success'
+ ),
+ 'catalog/view/common/header/after' => array(
+ 'extension/advertise/google/google_global_site_tag'
+ ),
+ 'catalog/view/common/success/after' => array(
+ 'extension/advertise/google/google_dynamic_remarketing_purchase'
+ ),
+ 'catalog/view/product/product/after' => array(
+ 'extension/advertise/google/google_dynamic_remarketing_product'
+ ),
+ 'catalog/view/product/search/after' => array(
+ 'extension/advertise/google/google_dynamic_remarketing_searchresults'
+ ),
+ 'catalog/view/product/category/after' => array(
+ 'extension/advertise/google/google_dynamic_remarketing_category'
+ ),
+ 'catalog/view/common/home/after' => array(
+ 'extension/advertise/google/google_dynamic_remarketing_home'
+ ),
+ 'catalog/view/checkout/cart/after' => array(
+ 'extension/advertise/google/google_dynamic_remarketing_cart'
+ )
+ );
+
+ private $rename_tables = array(
+ 'advertise_google_target' => 'googleshopping_target',
+ 'category_to_google_product_category' => 'googleshopping_category',
+ 'product_advertise_google_status' => 'googleshopping_product_status',
+ 'product_advertise_google_target' => 'googleshopping_product_target',
+ 'product_advertise_google' => 'googleshopping_product'
+ );
+
+ private $table_columns = array(
+ 'googleshopping_target' => array(
+ 'advertise_google_target_id',
+ 'store_id',
+ 'campaign_name',
+ 'country',
+ 'budget',
+ 'feeds',
+ 'status'
+ ),
+ 'googleshopping_category' => array(
+ 'google_product_category',
+ 'store_id',
+ 'category_id'
+ ),
+ 'googleshopping_product_status' => array(
+ 'product_id',
+ 'store_id',
+ 'product_variation_id',
+ 'destination_statuses',
+ 'data_quality_issues',
+ 'item_level_issues',
+ 'google_expiration_date'
+ ),
+ 'googleshopping_product_target' => array(
+ 'product_id',
+ 'store_id',
+ 'advertise_google_target_id'
+ ),
+ 'googleshopping_product' => array(
+ 'product_advertise_google_id',
+ 'product_id',
+ 'store_id',
+ 'has_issues',
+ 'destination_status',
+ 'impressions',
+ 'clicks',
+ 'conversions',
+ 'cost',
+ 'conversion_value',
+ 'google_product_category',
+ 'condition',
+ 'adult',
+ 'multipack',
+ 'is_bundle',
+ 'age_group',
+ 'color',
+ 'gender',
+ 'size_type',
+ 'size_system',
+ 'size',
+ 'is_modified'
+ )
+ );
+
+ public function isAppIdUsed($app_id, $store_id) {
+ $sql = "SELECT `store_id` FROM `" . DB_PREFIX . "setting` WHERE `key`='advertise_google_app_id' AND `value`='" . $this->db->escape($store_id) . "' AND `store_id`!=" . (int)$store_id . " LIMIT 1";
+
+ $result = $this->db->query($sql);
+
+ if ($result->num_rows > 0) {
+ try {
+ $googleshopping = new Googleshopping($this->registry, (int)$result->row['store_id']);
+
+ return $googleshopping->isConnected();
+ } catch (\RuntimeException $e) {
+ return false;
+ }
+ }
+
+ return false;
+ }
+
+ public function getFinalProductId() {
+ $sql = "SELECT product_id FROM `" . DB_PREFIX . "product` ORDER BY product_id DESC LIMIT 1";
+
+ $result = $this->db->query($sql);
+
+ if ($result->num_rows > 0) {
+ return (int)$result->row['product_id'];
+ }
+
+ return null;
+ }
+
+ public function isAnyProductCategoryModified($store_id) {
+ $sql = "SELECT pag.is_modified FROM `" . DB_PREFIX . "googleshopping_product` pag WHERE pag.google_product_category IS NOT NULL AND pag.store_id=" . (int)$store_id . " LIMIT 0,1";
+
+ return $this->db->query($sql)->num_rows > 0;
+ }
+
+ public function getAdvertisedCount($store_id) {
+ $result = $this->db->query("SELECT COUNT(product_id) as total FROM `" . DB_PREFIX . "googleshopping_product_target` WHERE store_id=" . (int)$store_id . " GROUP BY `product_id`");
+
+ return $result->num_rows > 0 ? (int)$result->row['total'] : 0;
+ }
+
+ public function getMapping($store_id) {
+ $sql = "SELECT * FROM `" . DB_PREFIX . "googleshopping_category` WHERE store_id=" . (int)$store_id;
+
+ return $this->db->query($sql)->rows;
+ }
+
+ public function setCategoryMapping($google_product_category, $store_id, $category_id) {
+ $sql = "INSERT INTO `" . DB_PREFIX . "googleshopping_category` SET `google_product_category`='" . $this->db->escape($google_product_category) . "', `store_id`=" . (int)$store_id . ", `category_id`=" . (int)$category_id . " ON DUPLICATE KEY UPDATE `category_id`=" . (int)$category_id;
+
+ $this->db->query($sql);
+ }
+
+ public function getMappedCategory($google_product_category, $store_id) {
+ $sql = "SELECT GROUP_CONCAT(cd.name ORDER BY cp.level SEPARATOR '&nbsp;&nbsp;&gt;&nbsp;&nbsp;') AS name, cp.category_id FROM " . DB_PREFIX . "category_path cp LEFT JOIN " . DB_PREFIX . "category_description cd ON (cp.path_id = cd.category_id) LEFT JOIN `" . DB_PREFIX . "googleshopping_category` c2gpc ON (c2gpc.category_id = cp.category_id) WHERE cd.language_id=" . (int)$this->config->get('config_language_id') . " AND c2gpc.google_product_category='" . $this->db->escape($google_product_category) . "' AND c2gpc.store_id=" . (int)$store_id;
+
+ $result = $this->db->query($sql);
+
+ if ($result->num_rows > 0) {
+ return $result->row;
+ }
+
+ return null;
+ }
+
+ public function getProductByProductAdvertiseGoogleId($product_advertise_google_id) {
+ $sql = "SELECT pag.product_id FROM `" . DB_PREFIX . "googleshopping_product` pag WHERE pag.product_advertise_google_id=" . (int)$product_advertise_google_id;
+
+ $result = $this->db->query($sql);
+
+ if ($result->num_rows) {
+ $this->load->model('catalog/product');
+
+ return $this->model_catalog_product->getProduct($result->row['product_id']);
+ }
+ }
+
+ public function getProductAdvertiseGoogle($product_advertise_google_id) {
+ $sql = "SELECT pag.* FROM `" . DB_PREFIX . "googleshopping_product` pag WHERE pag.product_advertise_google_id=" . (int)$product_advertise_google_id;
+
+ return $this->db->query($sql)->row;
+ }
+
+ public function hasActiveTarget($store_id) {
+ $sql = "SELECT agt.advertise_google_target_id FROM `" . DB_PREFIX . "googleshopping_target` agt WHERE agt.store_id=" . (int)$store_id . " AND agt.status='active' LIMIT 1";
+
+ return $this->db->query($sql)->num_rows > 0;
+ }
+
+ public function getRequiredFieldsByProductIds($product_ids, $store_id) {
+ $this->load->config('googleshopping/googleshopping');
+
+ $result = array();
+ $countries = $this->getTargetCountriesByProductIds($product_ids, $store_id);
+
+ foreach ($countries as $country) {
+ foreach ($this->config->get('advertise_google_country_required_fields') as $field => $requirements) {
+ if (
+ (!empty($requirements['countries']) && in_array($country, $requirements['countries']))
+ ||
+ (is_array($requirements['countries']) && empty($requirements['countries']))
+ ) {
+ $result[$field] = $requirements;
+ }
+ }
+ }
+
+ return $result;
+ }
+
+ public function getRequiredFieldsByFilter($data, $store_id) {
+ $this->load->config('googleshopping/googleshopping');
+
+ $result = array();
+ $countries = $this->getTargetCountriesByFilter($data, $store_id);
+
+ foreach ($countries as $country) {
+ foreach ($this->config->get('advertise_google_country_required_fields') as $field => $requirements) {
+ if (
+ (!empty($requirements['countries']) && in_array($country, $requirements['countries']))
+ ||
+ (is_array($requirements['countries']) && empty($requirements['countries']))
+ ) {
+ $result[$field] = $requirements;
+ }
+ }
+ }
+
+ return $result;
+ }
+
+ public function getTargetCountriesByProductIds($product_ids, $store_id) {
+ $sql = "SELECT DISTINCT agt.country FROM `" . DB_PREFIX . "googleshopping_product_target` pagt LEFT JOIN `" . DB_PREFIX . "googleshopping_target` agt ON (agt.advertise_google_target_id = pagt.advertise_google_target_id AND agt.store_id = pagt.store_id) WHERE pagt.product_id IN (" . $this->googleshopping->productIdsToIntegerExpression($product_ids) . ") AND pagt.store_id=" . (int)$store_id;
+
+ return array_map(array($this, 'country'), $this->db->query($sql)->rows);
+ }
+
+ public function getTargetCountriesByFilter($data, $store_id) {
+ $sql = "SELECT DISTINCT agt.country FROM `" . DB_PREFIX . "googleshopping_product_target` pagt LEFT JOIN `" . DB_PREFIX . "googleshopping_target` agt ON (agt.advertise_google_target_id = pagt.advertise_google_target_id AND agt.store_id = pagt.store_id) LEFT JOIN `" . DB_PREFIX . "product` p ON (pagt.product_id = p.product_id) LEFT JOIN `" . DB_PREFIX . "product_description` pd ON (pd.product_id = pagt.product_id) WHERE pagt.store_id=" . (int)$store_id . " AND pd.language_id=" . (int)$this->config->get('config_language_id');
+
+ $this->googleshopping->applyFilter($sql, $data);
+
+ return array_map(array($this, 'country'), $this->db->query($sql)->rows);
+ }
+
+ public function getProductOptionsByProductIds($product_ids) {
+ $sql = "SELECT po.option_id, od.name FROM `" . DB_PREFIX . "product_option` po LEFT JOIN `" . DB_PREFIX . "option_description` od ON (od.option_id=po.option_id AND od.language_id=" . (int)$this->config->get('config_language_id') . ") LEFT JOIN `" . DB_PREFIX . "option` o ON (o.option_id = po.option_id) WHERE o.type IN ('select', 'radio') AND po.product_id IN (" . $this->googleshopping->productIdsToIntegerExpression($product_ids) . ")";
+
+ return $this->db->query($sql)->rows;
+ }
+
+ public function getProductOptionsByFilter($data) {
+ $sql = "SELECT DISTINCT po.option_id, od.name FROM `" . DB_PREFIX . "product_option` po LEFT JOIN `" . DB_PREFIX . "option_description` od ON (od.option_id=po.option_id AND od.language_id=" . (int)$this->config->get('config_language_id') . ") LEFT JOIN `" . DB_PREFIX . "option` o ON (o.option_id = po.option_id) LEFT JOIN `" . DB_PREFIX . "product` p ON (po.product_id = p.product_id) LEFT JOIN `" . DB_PREFIX . "product_description` pd ON (pd.product_id = po.product_id) WHERE o.type IN ('select', 'radio') AND pd.language_id=" . (int)$this->config->get('config_language_id');
+
+ $this->googleshopping->applyFilter($sql, $data);
+
+ return $this->db->query($sql)->rows;
+ }
+
+ public function addTarget($target, $store_id) {
+ $sql = "INSERT INTO `" . DB_PREFIX . "googleshopping_target` SET `store_id`=" . (int)$store_id . ", `campaign_name`='" . $this->db->escape($target['campaign_name']) . "', `country`='" . $this->db->escape($target['country']) . "', `budget`='" . (float)$target['budget'] . "', `feeds`='" . $this->db->escape(json_encode($target['feeds'])) . "', `date_added`=NOW(), `roas`=" . (int)$target['roas'] . " , `status`='" . $this->db->escape($target['status']) . "'";
+
+ $this->db->query($sql);
+
+ return $this->db->getLastId();
+ }
+
+ public function deleteProducts($product_ids) {
+ $sql = "DELETE FROM `" . DB_PREFIX . "googleshopping_product` WHERE `product_id` IN (" . $this->googleshopping->productIdsToIntegerExpression($product_ids) . ")";
+
+ $this->db->query($sql);
+
+ $sql = "DELETE FROM `" . DB_PREFIX . "googleshopping_product_target` WHERE `product_id` IN (" . $this->googleshopping->productIdsToIntegerExpression($product_ids) . ")";
+
+ $this->db->query($sql);
+
+ $sql = "DELETE FROM `" . DB_PREFIX . "googleshopping_product_status` WHERE `product_id` IN (" . $this->googleshopping->productIdsToIntegerExpression($product_ids) . ")";
+
+ $this->db->query($sql);
+
+ return true;
+ }
+
+ public function setAdvertisingBySelect($post_product_ids, $post_target_ids, $store_id) {
+ if (!empty($post_product_ids)) {
+ $product_ids = array_map(array($this->googleshopping, 'integer'), $post_product_ids);
+
+ $product_ids_expression = implode(',', $product_ids);
+
+ $this->db->query("DELETE FROM `" . DB_PREFIX . "googleshopping_product_target` WHERE product_id IN (" . $product_ids_expression . ") AND store_id=" . (int)$store_id);
+
+ if (!empty($post_target_ids)) {
+ $target_ids = array_map(array($this->googleshopping, 'integer'), $post_target_ids);
+
+ $values = array();
+
+ foreach ($product_ids as $product_id) {
+ foreach ($target_ids as $target_id) {
+ $values[] = '(' . $product_id . ',' . $store_id . ',' . $target_id . ')';
+ }
+ }
+
+ $sql = "INSERT INTO `" . DB_PREFIX . "googleshopping_product_target` (`product_id`, `store_id`, `advertise_google_target_id`) VALUES " . implode(',', $values);
+
+ $this->db->query($sql);
+ }
+ }
+ }
+
+ public function setAdvertisingByFilter($data, $post_target_ids, $store_id) {
+ $sql = "DELETE pagt FROM `" . DB_PREFIX . "googleshopping_product_target` pagt LEFT JOIN `" . DB_PREFIX . "product` p ON (pagt.product_id = p.product_id) LEFT JOIN `" . DB_PREFIX . "product_description` pd ON (pd.product_id = p.product_id) WHERE pd.language_id=" . (int)$this->config->get('config_language_id');
+
+ $this->googleshopping->applyFilter($sql, $data);
+
+ $this->db->query($sql);
+
+ if (!empty($post_target_ids)) {
+ $target_ids = array_map(array($this->googleshopping, 'integer'), $post_target_ids);
+
+ $insert_sql = "SELECT p.product_id, " . (int)$store_id . " as store_id, '{TARGET_ID}' as advertise_google_target_id FROM `" . DB_PREFIX . "product` p LEFT JOIN `" . DB_PREFIX . "product_description` pd ON (pd.product_id = p.product_id) WHERE pd.language_id=" . (int)$this->config->get('config_language_id');
+
+ $this->googleshopping->applyFilter($insert_sql, $data);
+
+ foreach ($target_ids as $target_id) {
+ $sql = "INSERT INTO `" . DB_PREFIX . "googleshopping_product_target` (`product_id`, `store_id`, `advertise_google_target_id`) " . str_replace('{TARGET_ID}', (string)$target_id, $insert_sql);
+
+ $this->db->query($sql);
+ }
+ }
+ }
+
+ public function insertNewProducts($product_ids = array(), $store_id) {
+ $sql = "INSERT INTO `" . DB_PREFIX . "googleshopping_product` (`product_id`, `store_id`, `google_product_category`) SELECT p.product_id, p2s.store_id, (SELECT c2gpc.google_product_category FROM `" . DB_PREFIX . "product_to_category` p2c LEFT JOIN `" . DB_PREFIX . "category_path` cp ON (p2c.category_id = cp.category_id) LEFT JOIN `" . DB_PREFIX . "googleshopping_category` c2gpc ON (c2gpc.category_id = cp.path_id AND c2gpc.store_id = " . (int)$store_id . ") WHERE p2c.product_id = p.product_id AND c2gpc.google_product_category IS NOT NULL ORDER BY cp.level DESC LIMIT 0,1) as `google_product_category` FROM `" . DB_PREFIX . "product` p LEFT JOIN `" . DB_PREFIX . "product_to_store` p2s ON (p2s.product_id = p.product_id AND p2s.store_id = " . (int)$store_id . ") LEFT JOIN `" . DB_PREFIX . "googleshopping_product` pag ON (pag.product_id = p.product_id AND pag.store_id=p2s.store_id) WHERE pag.product_id IS NULL AND p2s.store_id IS NOT NULL";
+
+ if (!empty($product_ids)) {
+ $sql .= " AND p.product_id IN (" . $this->googleshopping->productIdsToIntegerExpression($product_ids) . ")";
+ }
+
+ $this->db->query($sql);
+ }
+
+ public function updateGoogleProductCategoryMapping($store_id) {
+ $sql = "INSERT INTO `" . DB_PREFIX . "googleshopping_product` (`product_id`, `store_id`, `google_product_category`) SELECT p.product_id, " . (int)$store_id . " as store_id, (SELECT c2gpc.google_product_category FROM `" . DB_PREFIX . "product_to_category` p2c LEFT JOIN `" . DB_PREFIX . "category_path` cp ON (p2c.category_id = cp.category_id) LEFT JOIN `" . DB_PREFIX . "googleshopping_category` c2gpc ON (c2gpc.category_id = cp.path_id AND c2gpc.store_id = " . (int)$store_id . ") WHERE p2c.product_id = p.product_id AND c2gpc.google_product_category IS NOT NULL ORDER BY cp.level DESC LIMIT 0,1) as `google_product_category` FROM `" . DB_PREFIX . "product` p LEFT JOIN `" . DB_PREFIX . "googleshopping_product` pag ON (pag.product_id = p.product_id) WHERE pag.product_id IS NOT NULL ON DUPLICATE KEY UPDATE `google_product_category`=VALUES(`google_product_category`)";
+
+ $this->db->query($sql);
+ }
+
+ public function updateSingleProductFields($data) {
+ $values = array();
+
+ $entry = array();
+ $entry['product_id'] = (int)$data['product_id'];
+ $entry = array_merge($entry, $this->makeInsertData($data));
+
+ $values[] = "(" . implode(",", $entry) . ")";
+
+ $sql = "INSERT INTO `" . DB_PREFIX . "googleshopping_product` (`product_id`, `store_id`, `google_product_category`, `condition`, `adult`, `multipack`, `is_bundle`, `age_group`, `color`, `gender`, `size_type`, `size_system`, `size`, `is_modified`) VALUES " . implode(',', $values) . " ON DUPLICATE KEY UPDATE " . $this->makeOnDuplicateKeyData();
+
+ $this->db->query($sql);
+ }
+
+ public function updateMultipleProductFields($filter_data, $data) {
+ $insert_sql = "SELECT p.product_id, {INSERT_DATA} FROM `" . DB_PREFIX . "product` p LEFT JOIN `" . DB_PREFIX . "product_description` pd ON (pd.product_id = p.product_id) WHERE pd.language_id=" . (int)$this->config->get('config_language_id');
+
+ $this->googleshopping->applyFilter($insert_sql, $filter_data);
+
+ $insert_data = array();
+ $keys[] = "`product_id`";
+
+ foreach ($this->makeInsertData($data) as $key => $value) {
+ $insert_data[] = $value . " as `" . $key . "`";
+ $keys[] = "`" . $key . "`";
+ }
+
+ $sql = "INSERT INTO `" . DB_PREFIX . "googleshopping_product` (" . implode(", ", $keys) . ") " . str_replace('{INSERT_DATA}', implode(", ", $insert_data), $insert_sql) . " ON DUPLICATE KEY UPDATE " . $this->makeOnDuplicateKeyData();
+
+ $this->db->query($sql);
+ }
+
+ protected function makeInsertData($data) {
+ $insert_data = array();
+
+ $insert_data['store_id'] = (int)$data['store_id'];
+ $insert_data['google_product_category'] = "'" . $this->db->escape($data['google_product_category']) . "'";
+ $insert_data['condition'] = "'" . $this->db->escape($data['condition']) . "'";
+ $insert_data['adult'] = (int)$data['adult'];
+ $insert_data['multipack'] = (int)$data['multipack'];
+ $insert_data['is_bundle'] = (int)$data['is_bundle'];
+ $insert_data['age_group'] = "'" . $this->db->escape($data['age_group']) . "'";
+ $insert_data['color'] = (int)$data['color'];
+ $insert_data['gender'] = "'" . $this->db->escape($data['gender']) . "'";
+ $insert_data['size_type'] = "'" . $this->db->escape($data['size_type']) . "'";
+ $insert_data['size_system'] = "'" . $this->db->escape($data['size_system']) . "'";
+ $insert_data['size'] = (int)$data['size'];
+ $insert_data['is_modified'] = 1;
+
+ return $insert_data;
+ }
+
+ protected function makeOnDuplicateKeyData() {
+ return "`google_product_category`=VALUES(`google_product_category`), `condition`=VALUES(`condition`), `adult`=VALUES(`adult`), `multipack`=VALUES(`multipack`), `is_bundle`=VALUES(`is_bundle`), `age_group`=VALUES(`age_group`), `color`=VALUES(`color`), `gender`=VALUES(`gender`), `size_type`=VALUES(`size_type`), `size_system`=VALUES(`size_system`), `size`=VALUES(`size`), `is_modified`=VALUES(`is_modified`)";
+ }
+
+ public function getCategories($data = array(), $store_id) {
+ $sql = "SELECT cp.category_id AS category_id, GROUP_CONCAT(cd1.name ORDER BY cp.level SEPARATOR '&nbsp;&nbsp;&gt;&nbsp;&nbsp;') AS name, c1.parent_id, c1.sort_order FROM " . DB_PREFIX . "category_path cp LEFT JOIN `" . DB_PREFIX . "category_to_store` c2s ON (c2s.category_id = cp.category_id AND c2s.store_id=" . (int)$store_id . ") LEFT JOIN " . DB_PREFIX . "category c1 ON (cp.category_id = c1.category_id) LEFT JOIN " . DB_PREFIX . "category c2 ON (cp.path_id = c2.category_id) LEFT JOIN " . DB_PREFIX . "category_description cd1 ON (cp.path_id = cd1.category_id) LEFT JOIN " . DB_PREFIX . "category_description cd2 ON (cp.category_id = cd2.category_id) WHERE c2s.store_id IS NOT NULL AND cd1.language_id = '" . (int)$this->config->get('config_language_id') . "' AND cd2.language_id = '" . (int)$this->config->get('config_language_id') . "'";
+
+ if (!empty($data['filter_name'])) {
+ $sql .= " AND cd2.name LIKE '%" . $this->db->escape($data['filter_name']) . "%'";
+ }
+
+ $sql .= " GROUP BY cp.category_id";
+
+ $sort_data = array(
+ 'name',
+ 'sort_order'
+ );
+
+ if (isset($data['sort']) && in_array($data['sort'], $sort_data)) {
+ $sql .= " ORDER BY " . $data['sort'];
+ } else {
+ $sql .= " ORDER BY sort_order";
+ }
+
+ 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'];
+ }
+
+ $query = $this->db->query($sql);
+
+ return $query->rows;
+ }
+
+ public function getProductCampaigns($product_id, $store_id) {
+ $sql = "SELECT agt.advertise_google_target_id, agt.campaign_name FROM `" . DB_PREFIX . "googleshopping_product_target` pagt LEFT JOIN `" . DB_PREFIX . "googleshopping_target` agt ON (pagt.advertise_google_target_id = agt.advertise_google_target_id) WHERE pagt.product_id=" . (int)$product_id . " AND pagt.store_id=" . (int)$store_id;
+
+ return $this->db->query($sql)->rows;
+ }
+
+ public function getProductIssues($product_id, $store_id) {
+ $this->load->model('localisation/language');
+
+ $sql = "SELECT pag.color, pag.size, pd.name, p.model FROM `" . DB_PREFIX . "googleshopping_product` pag LEFT JOIN `" . DB_PREFIX . "product` p ON (p.product_id = pag.product_id) LEFT JOIN `" . DB_PREFIX . "product_description` pd ON (pd.product_id = pag.product_id AND pd.language_id=" . (int)$this->config->get('config_language_id') . ") WHERE pag.product_id=" . (int)$product_id . " AND pag.store_id=" . (int)$store_id;
+
+ $product_info = $this->db->query($sql)->row;
+
+ if (!empty($product_info)) {
+ $result = array();
+ $result['name'] = $product_info['name'];
+ $result['model'] = $product_info['model'];
+ $result['entries'] = array();
+
+ foreach ($this->model_localisation_language->getLanguages() as $language) {
+ $language_id = $language['language_id'];
+ $groups = $this->googleshopping->getGroups($product_id, $language_id, $product_info['color'], $product_info['size']);
+
+ $result['entries'][$language_id] = array(
+ 'language_name' => $language['name'],
+ 'issues' => array()
+ );
+
+ foreach ($groups as $id => $group) {
+ $issues = $this->db->query("SELECT * FROM `" . DB_PREFIX . "googleshopping_product_status` WHERE product_id=" . (int)$product_id . " AND store_id=" . (int)$store_id . " AND product_variation_id='" . $this->db->escape($id) . "'")->row;
+
+ $destination_statuses = !empty($issues['destination_statuses']) ? json_decode($issues['destination_statuses'], true) : array();
+ $data_quality_issues = !empty($issues['data_quality_issues']) ? json_decode($issues['data_quality_issues'], true) : array();
+ $item_level_issues = !empty($issues['item_level_issues']) ? json_decode($issues['item_level_issues'], true) : array();
+ $google_expiration_date = !empty($issues['google_expiration_date']) ? date($this->language->get('datetime_format'), $issues['google_expiration_date']) : $this->language->get('text_na');
+
+ $result['entries'][$language_id]['issues'][] = array(
+ 'color' => $group['color'] != "" ? $group['color'] : $this->language->get('text_na'),
+ 'size' => $group['size'] != "" ? $group['size'] : $this->language->get('text_na'),
+ 'destination_statuses' => $destination_statuses,
+ 'data_quality_issues' => $data_quality_issues,
+ 'item_level_issues' => $item_level_issues,
+ 'google_expiration_date' => $google_expiration_date
+ );
+ }
+ }
+
+ return $result;
+ }
+
+ return null;
+ }
+
+ /*
+ * Shortly after releasing the extension,
+ * we learned that the table names are actually
+ * clashing with third-party extensions.
+ * Hence, this renaming script was created.
+ */
+ public function renameTables() {
+ foreach ($this->rename_tables as $old_table => $new_table) {
+ $new_table_name = DB_PREFIX . $new_table;
+ $old_table_name = DB_PREFIX . $old_table;
+
+ if ($this->tableExists($old_table_name) && !$this->tableExists($new_table_name) && $this->tableColumnsMatch($old_table_name, $this->table_columns[$new_table])) {
+ $this->db->query("RENAME TABLE `" . $old_table_name . "` TO `" . $new_table_name . "`");
+ }
+ }
+ }
+
+ private function tableExists($table) {
+ return $this->db->query("SHOW TABLES LIKE '" . $table . "'")->num_rows > 0;
+ }
+
+ private function tableColumnsMatch($table, $columns) {
+ $num_columns = $this->db->query("SHOW COLUMNS FROM `" . $table . "` WHERE Field IN (" . implode(',', $this->wrap($columns, '"')) . ")")->num_rows;
+
+ return $num_columns == count($columns);
+ }
+
+ private function wrap($text, $char) {
+ if (is_array($text)) {
+ foreach ($text as &$string) {
+ $string = $char . $string . $char;
+ }
+
+ return $text;
+ } else {
+ return $char . $text . $char;
+ }
+ }
+
+ public function createTables() {
+ $this->db->query("CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "googleshopping_product` (
+ `product_advertise_google_id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
+ `product_id` INT(11),
+ `store_id` INT(11) NOT NULL DEFAULT '0',
+ `has_issues` TINYINT(1),
+ `destination_status` ENUM('pending','approved','disapproved') NOT NULL DEFAULT 'pending',
+ `impressions` INT(11) NOT NULL DEFAULT '0',
+ `clicks` INT(11) NOT NULL DEFAULT '0',
+ `conversions` INT(11) NOT NULL DEFAULT '0.0000',
+ `cost` decimal(15,4) NOT NULL DEFAULT '0.0000',
+ `conversion_value` decimal(15,4) NOT NULL DEFAULT '0.0000',
+ `google_product_category` VARCHAR(10),
+ `condition` ENUM('new','refurbished','used'),
+ `adult` TINYINT(1),
+ `multipack` INT(11),
+ `is_bundle` TINYINT(1),
+ `age_group` ENUM('newborn','infant','toddler','kids','adult'),
+ `color` INT(11),
+ `gender` ENUM('male','female','unisex'),
+ `size_type` ENUM('regular','petite','plus','big and tall','maternity'),
+ `size_system` ENUM('AU','BR','CN','DE','EU','FR','IT','JP','MEX','UK','US'),
+ `size` INT(11),
+ `is_modified` TINYINT(1) NOT NULL DEFAULT '0',
+ PRIMARY KEY (`product_advertise_google_id`),
+ UNIQUE `product_id_store_id` (`product_id`, `store_id`)
+ ) ENGINE=MyISAM DEFAULT CHARSET=utf8");
+
+ $this->db->query("CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "googleshopping_product_status` (
+ `product_id` INT(11),
+ `store_id` INT(11) NOT NULL DEFAULT '0',
+ `product_variation_id` varchar(64),
+ `destination_statuses` TEXT NOT NULL,
+ `data_quality_issues` TEXT NOT NULL,
+ `item_level_issues` TEXT NOT NULL,
+ `google_expiration_date` INT(11) NOT NULL DEFAULT '0',
+ PRIMARY KEY (`product_id`, `store_id`, `product_variation_id`)
+ ) ENGINE=MyISAM DEFAULT CHARSET=utf8");
+
+ $this->db->query("CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "googleshopping_product_target` (
+ `product_id` INT(11) NOT NULL,
+ `store_id` INT(11) NOT NULL DEFAULT '0',
+ `advertise_google_target_id` INT(11) UNSIGNED NOT NULL,
+ PRIMARY KEY (`product_id`, `advertise_google_target_id`)
+ ) ENGINE=MyISAM DEFAULT CHARSET=utf8");
+
+ $this->db->query("CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "googleshopping_category` (
+ `google_product_category` VARCHAR(10) NOT NULL,
+ `store_id` INT(11) NOT NULL DEFAULT '0',
+ `category_id` INT(11) NOT NULL,
+ INDEX `category_id_store_id` (`category_id`, `store_id`),
+ PRIMARY KEY (`google_product_category`, `store_id`)
+ ) ENGINE=MyISAM DEFAULT CHARSET=utf8");
+
+ $this->db->query("CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "googleshopping_target` (
+ `advertise_google_target_id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
+ `store_id` INT(11) NOT NULL DEFAULT '0',
+ `campaign_name` varchar(255) NOT NULL DEFAULT '',
+ `country` varchar(2) NOT NULL DEFAULT '',
+ `budget` decimal(15,4) NOT NULL DEFAULT '0.0000',
+ `feeds` text NOT NULL,
+ `date_added` DATE,
+ `roas` INT(11) NOT NULL DEFAULT '0',
+ `status` ENUM('paused','active') NOT NULL DEFAULT 'paused',
+ INDEX `store_id` (`store_id`),
+ PRIMARY KEY (`advertise_google_target_id`)
+ ) ENGINE=MyISAM DEFAULT CHARSET=utf8");
+ }
+
+ public function fixColumns() {
+ $has_auto_increment = $this->db->query("SHOW COLUMNS FROM `" . DB_PREFIX . "googleshopping_product` WHERE Field='product_advertise_google_id' AND Extra LIKE '%auto_increment%'")->num_rows > 0;
+
+ if (!$has_auto_increment) {
+ $this->db->query("ALTER TABLE " . DB_PREFIX . "googleshopping_product MODIFY COLUMN product_advertise_google_id INT(11) UNSIGNED NOT NULL AUTO_INCREMENT");
+ }
+
+ $has_unique_key = $this->db->query("SHOW INDEX FROM `" . DB_PREFIX . "googleshopping_product` WHERE Key_name='product_id_store_id' AND Non_unique=0")->num_rows == 2;
+
+ if (!$has_unique_key) {
+ $index_exists = $this->db->query("SHOW INDEX FROM `" . DB_PREFIX . "googleshopping_product` WHERE Key_name='product_id_store_id'")->num_rows > 0;
+
+ if ($index_exists) {
+ $this->db->query("ALTER TABLE `" . DB_PREFIX . "googleshopping_product` DROP INDEX product_id_store_id;");
+ }
+
+ $this->db->query("CREATE UNIQUE INDEX product_id_store_id ON `" . DB_PREFIX . "googleshopping_product` (product_id, store_id)");
+ }
+
+ $has_date_added_column = $this->db->query("SHOW COLUMNS FROM `" . DB_PREFIX . "googleshopping_target` WHERE Field='date_added'")->num_rows > 0;
+
+ if (!$has_date_added_column) {
+ $this->db->query("ALTER TABLE " . DB_PREFIX . "googleshopping_target ADD COLUMN date_added DATE");
+
+ $this->db->query("UPDATE " . DB_PREFIX . "googleshopping_target SET date_added = NOW() WHERE date_added IS NULL");
+ }
+
+ $has_roas_column = $this->db->query("SHOW COLUMNS FROM `" . DB_PREFIX . "googleshopping_target` WHERE Field='roas'")->num_rows > 0;
+
+ if (!$has_roas_column) {
+ $this->db->query("ALTER TABLE " . DB_PREFIX . "googleshopping_target ADD COLUMN roas INT(11) NOT NULL DEFAULT '0'");
+ }
+ }
+
+ public function dropTables() {
+ $this->db->query("DROP TABLE IF EXISTS `" . DB_PREFIX . "googleshopping_target`");
+ $this->db->query("DROP TABLE IF EXISTS `" . DB_PREFIX . "googleshopping_category`");
+ $this->db->query("DROP TABLE IF EXISTS `" . DB_PREFIX . "googleshopping_product_status`");
+ $this->db->query("DROP TABLE IF EXISTS `" . DB_PREFIX . "googleshopping_product_target`");
+ $this->db->query("DROP TABLE IF EXISTS `" . DB_PREFIX . "googleshopping_product`");
+ }
+
+ public function deleteEvents() {
+ $this->load->model('setting/event');
+
+ $this->model_setting_event->deleteEventByCode('advertise_google');
+ }
+
+ public function createEvents() {
+ $this->load->model('setting/event');
+
+ foreach ($this->events as $trigger => $actions) {
+ foreach ($actions as $action) {
+ $this->model_setting_event->addEvent('advertise_google', $trigger, $action, 1, 0);
+ }
+ }
+ }
+
+ public function getAllowedTargets() {
+ $this->load->config('googleshopping/googleshopping');
+
+ $result = array();
+
+ foreach ($this->config->get('advertise_google_targets') as $target) {
+ $result[] = array(
+ 'country' => array(
+ 'code' => $target['country'],
+ 'name' => $this->googleshopping->getCountryName($target['country'])
+ ),
+ 'languages' => $this->googleshopping->getLanguages($target['languages']),
+ 'currencies' => $this->googleshopping->getCurrencies($target['currencies'])
+ );
+ }
+
+ return $result;
+ }
+
+ protected function country($row) {
+ return $row['country'];
+ }
+}
diff --git a/public/admin/model/extension/dashboard/activity.php b/public/admin/model/extension/dashboard/activity.php
new file mode 100644
index 0000000..2ed8cc9
--- /dev/null
+++ b/public/admin/model/extension/dashboard/activity.php
@@ -0,0 +1,8 @@
+<?php
+class ModelExtensionDashboardActivity extends Model {
+ public function getActivities() {
+ $query = $this->db->query("SELECT `key`, `data`, `date_added` FROM `" . DB_PREFIX . "customer_activity` ORDER BY `date_added` DESC LIMIT 0,5");
+
+ return $query->rows;
+ }
+} \ No newline at end of file
diff --git a/public/admin/model/extension/dashboard/chart.php b/public/admin/model/extension/dashboard/chart.php
new file mode 100644
index 0000000..6e3f495
--- /dev/null
+++ b/public/admin/model/extension/dashboard/chart.php
@@ -0,0 +1,214 @@
+<?php
+class ModelExtensionDashboardChart extends Model {
+ public function getTotalOrdersByDay() {
+ $implode = array();
+
+ foreach ($this->config->get('config_complete_status') as $order_status_id) {
+ $implode[] = "'" . (int)$order_status_id . "'";
+ }
+
+ $order_data = array();
+
+ for ($i = 0; $i < 24; $i++) {
+ $order_data[$i] = array(
+ 'hour' => $i,
+ 'total' => 0
+ );
+ }
+
+ $query = $this->db->query("SELECT COUNT(*) AS total, HOUR(date_added) AS hour FROM `" . DB_PREFIX . "order` WHERE order_status_id IN(" . implode(",", $implode) . ") AND DATE(date_added) = DATE(NOW()) GROUP BY HOUR(date_added) ORDER BY date_added ASC");
+
+ foreach ($query->rows as $result) {
+ $order_data[$result['hour']] = array(
+ 'hour' => $result['hour'],
+ 'total' => $result['total']
+ );
+ }
+
+ return $order_data;
+ }
+
+ public function getTotalOrdersByWeek() {
+ $implode = array();
+
+ foreach ($this->config->get('config_complete_status') as $order_status_id) {
+ $implode[] = "'" . (int)$order_status_id . "'";
+ }
+
+ $order_data = array();
+
+ $date_start = strtotime('-' . date('w') . ' days');
+
+ for ($i = 0; $i < 7; $i++) {
+ $date = date('Y-m-d', $date_start + ($i * 86400));
+
+ $order_data[date('w', strtotime($date))] = array(
+ 'day' => date('D', strtotime($date)),
+ 'total' => 0
+ );
+ }
+
+ $query = $this->db->query("SELECT COUNT(*) AS total, date_added FROM `" . DB_PREFIX . "order` WHERE order_status_id IN(" . implode(",", $implode) . ") AND DATE(date_added) >= DATE('" . $this->db->escape(date('Y-m-d', $date_start)) . "') GROUP BY DAYNAME(date_added)");
+
+ foreach ($query->rows as $result) {
+ $order_data[date('w', strtotime($result['date_added']))] = array(
+ 'day' => date('D', strtotime($result['date_added'])),
+ 'total' => $result['total']
+ );
+ }
+
+ return $order_data;
+ }
+
+ public function getTotalOrdersByMonth() {
+ $implode = array();
+
+ foreach ($this->config->get('config_complete_status') as $order_status_id) {
+ $implode[] = "'" . (int)$order_status_id . "'";
+ }
+
+ $order_data = array();
+
+ for ($i = 1; $i <= date('t'); $i++) {
+ $date = date('Y') . '-' . date('m') . '-' . $i;
+
+ $order_data[date('j', strtotime($date))] = array(
+ 'day' => date('d', strtotime($date)),
+ 'total' => 0
+ );
+ }
+
+ $query = $this->db->query("SELECT COUNT(*) AS total, date_added FROM `" . DB_PREFIX . "order` WHERE order_status_id IN(" . implode(",", $implode) . ") AND DATE(date_added) >= '" . $this->db->escape(date('Y') . '-' . date('m') . '-1') . "' GROUP BY DATE(date_added)");
+
+ foreach ($query->rows as $result) {
+ $order_data[date('j', strtotime($result['date_added']))] = array(
+ 'day' => date('d', strtotime($result['date_added'])),
+ 'total' => $result['total']
+ );
+ }
+
+ return $order_data;
+ }
+
+ public function getTotalOrdersByYear() {
+ $implode = array();
+
+ foreach ($this->config->get('config_complete_status') as $order_status_id) {
+ $implode[] = "'" . (int)$order_status_id . "'";
+ }
+
+ $order_data = array();
+
+ for ($i = 1; $i <= 12; $i++) {
+ $order_data[$i] = array(
+ 'month' => date('M', mktime(0, 0, 0, $i)),
+ 'total' => 0
+ );
+ }
+
+ $query = $this->db->query("SELECT COUNT(*) AS total, date_added FROM `" . DB_PREFIX . "order` WHERE order_status_id IN(" . implode(",", $implode) . ") AND YEAR(date_added) = YEAR(NOW()) GROUP BY MONTH(date_added)");
+
+ foreach ($query->rows as $result) {
+ $order_data[date('n', strtotime($result['date_added']))] = array(
+ 'month' => date('M', strtotime($result['date_added'])),
+ 'total' => $result['total']
+ );
+ }
+
+ return $order_data;
+ }
+
+ public function getTotalCustomersByDay() {
+ $customer_data = array();
+
+ for ($i = 0; $i < 24; $i++) {
+ $customer_data[$i] = array(
+ 'hour' => $i,
+ 'total' => 0
+ );
+ }
+
+ $query = $this->db->query("SELECT COUNT(*) AS total, HOUR(date_added) AS hour FROM `" . DB_PREFIX . "customer` WHERE DATE(date_added) = DATE(NOW()) GROUP BY HOUR(date_added) ORDER BY date_added ASC");
+
+ foreach ($query->rows as $result) {
+ $customer_data[$result['hour']] = array(
+ 'hour' => $result['hour'],
+ 'total' => $result['total']
+ );
+ }
+
+ return $customer_data;
+ }
+
+ public function getTotalCustomersByWeek() {
+ $customer_data = array();
+
+ $date_start = strtotime('-' . date('w') . ' days');
+
+ for ($i = 0; $i < 7; $i++) {
+ $date = date('Y-m-d', $date_start + ($i * 86400));
+
+ $customer_data[date('w', strtotime($date))] = array(
+ 'day' => date('D', strtotime($date)),
+ 'total' => 0
+ );
+ }
+
+ $query = $this->db->query("SELECT COUNT(*) AS total, date_added FROM `" . DB_PREFIX . "customer` WHERE DATE(date_added) >= DATE('" . $this->db->escape(date('Y-m-d', $date_start)) . "') GROUP BY DAYNAME(date_added)");
+
+ foreach ($query->rows as $result) {
+ $customer_data[date('w', strtotime($result['date_added']))] = array(
+ 'day' => date('D', strtotime($result['date_added'])),
+ 'total' => $result['total']
+ );
+ }
+
+ return $customer_data;
+ }
+
+ public function getTotalCustomersByMonth() {
+ $customer_data = array();
+
+ for ($i = 1; $i <= date('t'); $i++) {
+ $date = date('Y') . '-' . date('m') . '-' . $i;
+
+ $customer_data[date('j', strtotime($date))] = array(
+ 'day' => date('d', strtotime($date)),
+ 'total' => 0
+ );
+ }
+
+ $query = $this->db->query("SELECT COUNT(*) AS total, date_added FROM `" . DB_PREFIX . "customer` WHERE DATE(date_added) >= '" . $this->db->escape(date('Y') . '-' . date('m') . '-1') . "' GROUP BY DATE(date_added)");
+
+ foreach ($query->rows as $result) {
+ $customer_data[date('j', strtotime($result['date_added']))] = array(
+ 'day' => date('d', strtotime($result['date_added'])),
+ 'total' => $result['total']
+ );
+ }
+
+ return $customer_data;
+ }
+
+ public function getTotalCustomersByYear() {
+ $customer_data = array();
+
+ for ($i = 1; $i <= 12; $i++) {
+ $customer_data[$i] = array(
+ 'month' => date('M', mktime(0, 0, 0, $i)),
+ 'total' => 0
+ );
+ }
+
+ $query = $this->db->query("SELECT COUNT(*) AS total, date_added FROM `" . DB_PREFIX . "customer` WHERE YEAR(date_added) = YEAR(NOW()) GROUP BY MONTH(date_added)");
+
+ foreach ($query->rows as $result) {
+ $customer_data[date('n', strtotime($result['date_added']))] = array(
+ 'month' => date('M', strtotime($result['date_added'])),
+ 'total' => $result['total']
+ );
+ }
+
+ return $customer_data;
+ }
+} \ No newline at end of file
diff --git a/public/admin/model/extension/dashboard/map.php b/public/admin/model/extension/dashboard/map.php
new file mode 100644
index 0000000..b108156
--- /dev/null
+++ b/public/admin/model/extension/dashboard/map.php
@@ -0,0 +1,20 @@
+<?php
+class ModelExtensionDashboardMap extends Model {
+ public function getTotalOrdersByCountry() {
+ $implode = array();
+
+ if (is_array($this->config->get('config_complete_status'))) {
+ foreach ($this->config->get('config_complete_status') as $order_status_id) {
+ $implode[] = (int)$order_status_id;
+ }
+ }
+
+ if ($implode) {
+ $query = $this->db->query("SELECT COUNT(*) AS total, SUM(o.total) AS amount, c.iso_code_2 FROM `" . DB_PREFIX . "order` o LEFT JOIN `" . DB_PREFIX . "country` c ON (o.payment_country_id = c.country_id) WHERE o.order_status_id IN('" . (int)implode(',', $implode) . "') GROUP BY o.payment_country_id");
+
+ return $query->rows;
+ } else {
+ return array();
+ }
+ }
+} \ No newline at end of file
diff --git a/public/admin/model/extension/dashboard/online.php b/public/admin/model/extension/dashboard/online.php
new file mode 100644
index 0000000..6cf7415
--- /dev/null
+++ b/public/admin/model/extension/dashboard/online.php
@@ -0,0 +1,24 @@
+<?php
+class ModelExtensionDashboardOnline extends Model {
+ public function getTotalOnline($data = array()) {
+ $sql = "SELECT COUNT(*) AS total FROM `" . DB_PREFIX . "customer_online` co LEFT JOIN " . DB_PREFIX . "customer c ON (co.customer_id = c.customer_id)";
+
+ $implode = array();
+
+ if (!empty($data['filter_ip'])) {
+ $implode[] = "co.ip LIKE '" . $this->db->escape($data['filter_ip']) . "'";
+ }
+
+ if (!empty($data['filter_customer'])) {
+ $implode[] = "co.customer_id > 0 AND CONCAT(c.firstname, ' ', c.lastname) LIKE '" . $this->db->escape($data['filter_customer']) . "'";
+ }
+
+ if ($implode) {
+ $sql .= " WHERE " . implode(" AND ", $implode);
+ }
+
+ $query = $this->db->query($sql);
+
+ return $query->row['total'];
+ }
+} \ No newline at end of file
diff --git a/public/admin/model/extension/dashboard/sale.php b/public/admin/model/extension/dashboard/sale.php
new file mode 100644
index 0000000..8732ba9
--- /dev/null
+++ b/public/admin/model/extension/dashboard/sale.php
@@ -0,0 +1,438 @@
+<?php
+class ModelExtensionDashboardSale extends Model {
+ public function getTotalSales($data = array()) {
+ $sql = "SELECT SUM(total) AS total FROM `" . DB_PREFIX . "order` WHERE order_status_id > '0'";
+
+ if (!empty($data['filter_date_added'])) {
+ $sql .= " AND DATE(date_added) = DATE('" . $this->db->escape($data['filter_date_added']) . "')";
+ }
+
+ $query = $this->db->query($sql);
+
+ return $query->row['total'];
+ }
+
+ public function getTotalOrdersByCountry() {
+ $query = $this->db->query("SELECT COUNT(*) AS total, SUM(o.total) AS amount, c.iso_code_2 FROM `" . DB_PREFIX . "order` o LEFT JOIN `" . DB_PREFIX . "country` c ON (o.payment_country_id = c.country_id) WHERE o.order_status_id > '0' GROUP BY o.payment_country_id");
+
+ return $query->rows;
+ }
+
+ public function getTotalOrdersByDay() {
+ $implode = array();
+
+ foreach ($this->config->get('config_complete_status') as $order_status_id) {
+ $implode[] = "'" . (int)$order_status_id . "'";
+ }
+
+ $order_data = array();
+
+ for ($i = 0; $i < 24; $i++) {
+ $order_data[$i] = array(
+ 'hour' => $i,
+ 'total' => 0
+ );
+ }
+
+ $query = $this->db->query("SELECT COUNT(*) AS total, HOUR(date_added) AS hour FROM `" . DB_PREFIX . "order` WHERE order_status_id IN(" . implode(",", $implode) . ") AND DATE(date_added) = DATE(NOW()) GROUP BY HOUR(date_added) ORDER BY date_added ASC");
+
+ foreach ($query->rows as $result) {
+ $order_data[$result['hour']] = array(
+ 'hour' => $result['hour'],
+ 'total' => $result['total']
+ );
+ }
+
+ return $order_data;
+ }
+
+ public function getTotalOrdersByWeek() {
+ $implode = array();
+
+ foreach ($this->config->get('config_complete_status') as $order_status_id) {
+ $implode[] = "'" . (int)$order_status_id . "'";
+ }
+
+ $order_data = array();
+
+ $date_start = strtotime('-' . date('w') . ' days');
+
+ for ($i = 0; $i < 7; $i++) {
+ $date = date('Y-m-d', $date_start + ($i * 86400));
+
+ $order_data[date('w', strtotime($date))] = array(
+ 'day' => date('D', strtotime($date)),
+ 'total' => 0
+ );
+ }
+
+ $query = $this->db->query("SELECT COUNT(*) AS total, date_added FROM `" . DB_PREFIX . "order` WHERE order_status_id IN(" . implode(",", $implode) . ") AND DATE(date_added) >= DATE('" . $this->db->escape(date('Y-m-d', $date_start)) . "') GROUP BY DAYNAME(date_added)");
+
+ foreach ($query->rows as $result) {
+ $order_data[date('w', strtotime($result['date_added']))] = array(
+ 'day' => date('D', strtotime($result['date_added'])),
+ 'total' => $result['total']
+ );
+ }
+
+ return $order_data;
+ }
+
+ public function getTotalOrdersByMonth() {
+ $implode = array();
+
+ foreach ($this->config->get('config_complete_status') as $order_status_id) {
+ $implode[] = "'" . (int)$order_status_id . "'";
+ }
+
+ $order_data = array();
+
+ for ($i = 1; $i <= date('t'); $i++) {
+ $date = date('Y') . '-' . date('m') . '-' . $i;
+
+ $order_data[date('j', strtotime($date))] = array(
+ 'day' => date('d', strtotime($date)),
+ 'total' => 0
+ );
+ }
+
+ $query = $this->db->query("SELECT COUNT(*) AS total, date_added FROM `" . DB_PREFIX . "order` WHERE order_status_id IN(" . implode(",", $implode) . ") AND DATE(date_added) >= '" . $this->db->escape(date('Y') . '-' . date('m') . '-1') . "' GROUP BY DATE(date_added)");
+
+ foreach ($query->rows as $result) {
+ $order_data[date('j', strtotime($result['date_added']))] = array(
+ 'day' => date('d', strtotime($result['date_added'])),
+ 'total' => $result['total']
+ );
+ }
+
+ return $order_data;
+ }
+
+ public function getTotalOrdersByYear() {
+ $implode = array();
+
+ foreach ($this->config->get('config_complete_status') as $order_status_id) {
+ $implode[] = "'" . (int)$order_status_id . "'";
+ }
+
+ $order_data = array();
+
+ for ($i = 1; $i <= 12; $i++) {
+ $order_data[$i] = array(
+ 'month' => date('M', mktime(0, 0, 0, $i)),
+ 'total' => 0
+ );
+ }
+
+ $query = $this->db->query("SELECT COUNT(*) AS total, date_added FROM `" . DB_PREFIX . "order` WHERE order_status_id IN(" . implode(",", $implode) . ") AND YEAR(date_added) = YEAR(NOW()) GROUP BY MONTH(date_added)");
+
+ foreach ($query->rows as $result) {
+ $order_data[date('n', strtotime($result['date_added']))] = array(
+ 'month' => date('M', strtotime($result['date_added'])),
+ 'total' => $result['total']
+ );
+ }
+
+ return $order_data;
+ }
+
+ public function getOrders($data = array()) {
+ $sql = "SELECT MIN(o.date_added) AS date_start, MAX(o.date_added) AS date_end, COUNT(*) AS `orders`, SUM((SELECT SUM(op.quantity) FROM `" . DB_PREFIX . "order_product` op WHERE op.order_id = o.order_id GROUP BY op.order_id)) AS products, SUM((SELECT SUM(ot.value) FROM `" . DB_PREFIX . "order_total` ot WHERE ot.order_id = o.order_id AND ot.code = 'tax' GROUP BY ot.order_id)) AS tax, SUM(o.total) AS `total` FROM `" . DB_PREFIX . "order` o";
+
+ if (!empty($data['filter_order_status_id'])) {
+ $sql .= " WHERE o.order_status_id = '" . (int)$data['filter_order_status_id'] . "'";
+ } else {
+ $sql .= " WHERE o.order_status_id > '0'";
+ }
+
+ if (!empty($data['filter_date_start'])) {
+ $sql .= " AND DATE(o.date_added) >= '" . $this->db->escape($data['filter_date_start']) . "'";
+ }
+
+ if (!empty($data['filter_date_end'])) {
+ $sql .= " AND DATE(o.date_added) <= '" . $this->db->escape($data['filter_date_end']) . "'";
+ }
+
+ if (!empty($data['filter_group'])) {
+ $group = $data['filter_group'];
+ } else {
+ $group = 'week';
+ }
+
+ switch($group) {
+ case 'day';
+ $sql .= " GROUP BY YEAR(o.date_added), MONTH(o.date_added), DAY(o.date_added)";
+ break;
+ default:
+ case 'week':
+ $sql .= " GROUP BY YEAR(o.date_added), WEEK(o.date_added)";
+ break;
+ case 'month':
+ $sql .= " GROUP BY YEAR(o.date_added), MONTH(o.date_added)";
+ break;
+ case 'year':
+ $sql .= " GROUP BY YEAR(o.date_added)";
+ break;
+ }
+
+ $sql .= " ORDER BY o.date_added DESC";
+
+ 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'];
+ }
+
+ $query = $this->db->query($sql);
+
+ return $query->rows;
+ }
+
+ public function getTotalOrders($data = array()) {
+ if (!empty($data['filter_group'])) {
+ $group = $data['filter_group'];
+ } else {
+ $group = 'week';
+ }
+
+ switch($group) {
+ case 'day';
+ $sql = "SELECT COUNT(DISTINCT YEAR(date_added), MONTH(date_added), DAY(date_added)) AS total FROM `" . DB_PREFIX . "order`";
+ break;
+ default:
+ case 'week':
+ $sql = "SELECT COUNT(DISTINCT YEAR(date_added), WEEK(date_added)) AS total FROM `" . DB_PREFIX . "order`";
+ break;
+ case 'month':
+ $sql = "SELECT COUNT(DISTINCT YEAR(date_added), MONTH(date_added)) AS total FROM `" . DB_PREFIX . "order`";
+ break;
+ case 'year':
+ $sql = "SELECT COUNT(DISTINCT YEAR(date_added)) AS total FROM `" . DB_PREFIX . "order`";
+ break;
+ }
+
+ if (!empty($data['filter_order_status_id'])) {
+ $sql .= " WHERE order_status_id = '" . (int)$data['filter_order_status_id'] . "'";
+ } else {
+ $sql .= " WHERE order_status_id > '0'";
+ }
+
+ if (!empty($data['filter_date_start'])) {
+ $sql .= " AND DATE(date_added) >= '" . $this->db->escape($data['filter_date_start']) . "'";
+ }
+
+ if (!empty($data['filter_date_end'])) {
+ $sql .= " AND DATE(date_added) <= '" . $this->db->escape($data['filter_date_end']) . "'";
+ }
+
+ $query = $this->db->query($sql);
+
+ return $query->row['total'];
+ }
+
+ public function getTaxes($data = array()) {
+ $sql = "SELECT MIN(o.date_added) AS date_start, MAX(o.date_added) AS date_end, ot.title, SUM(ot.value) AS total, COUNT(o.order_id) AS `orders` FROM `" . DB_PREFIX . "order` o LEFT JOIN `" . DB_PREFIX . "order_total` ot ON (ot.order_id = o.order_id) WHERE ot.code = 'tax'";
+
+ if (!empty($data['filter_order_status_id'])) {
+ $sql .= " AND o.order_status_id = '" . (int)$data['filter_order_status_id'] . "'";
+ } else {
+ $sql .= " AND o.order_status_id > '0'";
+ }
+
+ if (!empty($data['filter_date_start'])) {
+ $sql .= " AND DATE(o.date_added) >= '" . $this->db->escape($data['filter_date_start']) . "'";
+ }
+
+ if (!empty($data['filter_date_end'])) {
+ $sql .= " AND DATE(o.date_added) <= '" . $this->db->escape($data['filter_date_end']) . "'";
+ }
+
+ if (!empty($data['filter_group'])) {
+ $group = $data['filter_group'];
+ } else {
+ $group = 'week';
+ }
+
+ switch($group) {
+ case 'day';
+ $sql .= " GROUP BY YEAR(o.date_added), MONTH(o.date_added), DAY(o.date_added), ot.title";
+ break;
+ default:
+ case 'week':
+ $sql .= " GROUP BY YEAR(o.date_added), WEEK(o.date_added), ot.title";
+ break;
+ case 'month':
+ $sql .= " GROUP BY YEAR(o.date_added), MONTH(o.date_added), ot.title";
+ break;
+ case 'year':
+ $sql .= " GROUP BY YEAR(o.date_added), ot.title";
+ break;
+ }
+
+ 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'];
+ }
+
+ $query = $this->db->query($sql);
+
+ return $query->rows;
+ }
+
+ public function getTotalTaxes($data = array()) {
+ if (!empty($data['filter_group'])) {
+ $group = $data['filter_group'];
+ } else {
+ $group = 'week';
+ }
+
+ switch($group) {
+ case 'day';
+ $sql = "SELECT COUNT(DISTINCT YEAR(o.date_added), MONTH(o.date_added), DAY(o.date_added), ot.title) AS total FROM `" . DB_PREFIX . "order` o";
+ break;
+ default:
+ case 'week':
+ $sql = "SELECT COUNT(DISTINCT YEAR(o.date_added), WEEK(o.date_added), ot.title) AS total FROM `" . DB_PREFIX . "order` o";
+ break;
+ case 'month':
+ $sql = "SELECT COUNT(DISTINCT YEAR(o.date_added), MONTH(o.date_added), ot.title) AS total FROM `" . DB_PREFIX . "order` o";
+ break;
+ case 'year':
+ $sql = "SELECT COUNT(DISTINCT YEAR(o.date_added), ot.title) AS total FROM `" . DB_PREFIX . "order` o";
+ break;
+ }
+
+ $sql .= " LEFT JOIN `" . DB_PREFIX . "order_total` ot ON (o.order_id = ot.order_id) WHERE ot.code = 'tax'";
+
+ if (!empty($data['filter_order_status_id'])) {
+ $sql .= " AND o.order_status_id = '" . (int)$data['filter_order_status_id'] . "'";
+ } else {
+ $sql .= " AND o.order_status_id > '0'";
+ }
+
+ if (!empty($data['filter_date_start'])) {
+ $sql .= " AND DATE(o.date_added) >= '" . $this->db->escape($data['filter_date_start']) . "'";
+ }
+
+ if (!empty($data['filter_date_end'])) {
+ $sql .= " AND DATE(o.date_added) <= '" . $this->db->escape($data['filter_date_end']) . "'";
+ }
+
+ $query = $this->db->query($sql);
+
+ return $query->row['total'];
+ }
+
+ public function getShipping($data = array()) {
+ $sql = "SELECT MIN(o.date_added) AS date_start, MAX(o.date_added) AS date_end, ot.title, SUM(ot.value) AS total, COUNT(o.order_id) AS `orders` FROM `" . DB_PREFIX . "order` o LEFT JOIN `" . DB_PREFIX . "order_total` ot ON (o.order_id = ot.order_id) WHERE ot.code = 'shipping'";
+
+ if (!empty($data['filter_order_status_id'])) {
+ $sql .= " AND o.order_status_id = '" . (int)$data['filter_order_status_id'] . "'";
+ } else {
+ $sql .= " AND o.order_status_id > '0'";
+ }
+
+ if (!empty($data['filter_date_start'])) {
+ $sql .= " AND DATE(o.date_added) >= '" . $this->db->escape($data['filter_date_start']) . "'";
+ }
+
+ if (!empty($data['filter_date_end'])) {
+ $sql .= " AND DATE(o.date_added) <= '" . $this->db->escape($data['filter_date_end']) . "'";
+ }
+
+ if (!empty($data['filter_group'])) {
+ $group = $data['filter_group'];
+ } else {
+ $group = 'week';
+ }
+
+ switch($group) {
+ case 'day';
+ $sql .= " GROUP BY YEAR(o.date_added), MONTH(o.date_added), DAY(o.date_added), ot.title";
+ break;
+ default:
+ case 'week':
+ $sql .= " GROUP BY YEAR(o.date_added), WEEK(o.date_added), ot.title";
+ break;
+ case 'month':
+ $sql .= " GROUP BY YEAR(o.date_added), MONTH(o.date_added), ot.title";
+ break;
+ case 'year':
+ $sql .= " GROUP BY YEAR(o.date_added), ot.title";
+ break;
+ }
+
+ 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'];
+ }
+
+ $query = $this->db->query($sql);
+
+ return $query->rows;
+ }
+
+ public function getTotalShipping($data = array()) {
+ if (!empty($data['filter_group'])) {
+ $group = $data['filter_group'];
+ } else {
+ $group = 'week';
+ }
+
+ switch($group) {
+ case 'day';
+ $sql = "SELECT COUNT(DISTINCT YEAR(o.date_added), MONTH(o.date_added), DAY(o.date_added), ot.title) AS total FROM `" . DB_PREFIX . "order` o";
+ break;
+ default:
+ case 'week':
+ $sql = "SELECT COUNT(DISTINCT YEAR(o.date_added), WEEK(o.date_added), ot.title) AS total FROM `" . DB_PREFIX . "order` o";
+ break;
+ case 'month':
+ $sql = "SELECT COUNT(DISTINCT YEAR(o.date_added), MONTH(o.date_added), ot.title) AS total FROM `" . DB_PREFIX . "order` o";
+ break;
+ case 'year':
+ $sql = "SELECT COUNT(DISTINCT YEAR(o.date_added), ot.title) AS total FROM `" . DB_PREFIX . "order` o";
+ break;
+ }
+
+ $sql .= " LEFT JOIN `" . DB_PREFIX . "order_total` ot ON (o.order_id = ot.order_id) WHERE ot.code = 'shipping'";
+
+ if (!empty($data['filter_order_status_id'])) {
+ $sql .= " AND order_status_id = '" . (int)$data['filter_order_status_id'] . "'";
+ } else {
+ $sql .= " AND order_status_id > '0'";
+ }
+
+ if (!empty($data['filter_date_start'])) {
+ $sql .= " AND DATE(o.date_added) >= '" . $this->db->escape($data['filter_date_start']) . "'";
+ }
+
+ if (!empty($data['filter_date_end'])) {
+ $sql .= " AND DATE(o.date_added) <= '" . $this->db->escape($data['filter_date_end']) . "'";
+ }
+
+ $query = $this->db->query($sql);
+
+ return $query->row['total'];
+ }
+} \ No newline at end of file
diff --git a/public/admin/model/extension/feed/google_base.php b/public/admin/model/extension/feed/google_base.php
new file mode 100644
index 0000000..b54f1b1
--- /dev/null
+++ b/public/admin/model/extension/feed/google_base.php
@@ -0,0 +1,97 @@
+<?php
+class ModelExtensionFeedGoogleBase extends Model {
+ public function install() {
+ $this->db->query("
+ CREATE TABLE `" . DB_PREFIX . "google_base_category` (
+ `google_base_category_id` INT(11) NOT NULL AUTO_INCREMENT,
+ `name` varchar(255) NOT NULL,
+ PRIMARY KEY (`google_base_category_id`)
+ ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci;
+ ");
+
+ $this->db->query("
+ CREATE TABLE `" . DB_PREFIX . "google_base_category_to_category` (
+ `google_base_category_id` INT(11) NOT NULL,
+ `category_id` INT(11) NOT NULL,
+ PRIMARY KEY (`google_base_category_id`, `category_id`)
+ ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci;
+ ");
+ }
+
+ public function uninstall() {
+ $this->db->query("DROP TABLE IF EXISTS `" . DB_PREFIX . "google_base_category`");
+ $this->db->query("DROP TABLE IF EXISTS `" . DB_PREFIX . "google_base_category_to_category`");
+ }
+
+ public function import($string) {
+ $this->db->query("DELETE FROM " . DB_PREFIX . "google_base_category");
+
+ $lines = explode("\n", $string);
+
+ foreach ($lines as $line) {
+ if (substr($line, 0, 1) != '#') {
+ $part = explode(' - ', $line, 2);
+
+ if (isset($part[1])) {
+ $this->db->query("INSERT INTO " . DB_PREFIX . "google_base_category SET google_base_category_id = '" . (int)$part[0] . "', name = '" . $this->db->escape($part[1]) . "'");
+ }
+ }
+ }
+ }
+
+ public function getGoogleBaseCategories($data = array()) {
+ $sql = "SELECT * FROM `" . DB_PREFIX . "google_base_category` WHERE name LIKE '%" . $this->db->escape($data['filter_name']) . "%' ORDER BY name 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'];
+ }
+
+ $query = $this->db->query($sql);
+
+ return $query->rows;
+ }
+
+ public function addCategory($data) {
+ $this->db->query("DELETE FROM " . DB_PREFIX . "google_base_category_to_category WHERE category_id = '" . (int)$data['category_id'] . "'");
+
+ $this->db->query("INSERT INTO " . DB_PREFIX . "google_base_category_to_category SET google_base_category_id = '" . (int)$data['google_base_category_id'] . "', category_id = '" . (int)$data['category_id'] . "'");
+ }
+
+ public function deleteCategory($category_id) {
+ $this->db->query("DELETE FROM " . DB_PREFIX . "google_base_category_to_category WHERE category_id = '" . (int)$category_id . "'");
+ }
+
+ public function getCategories($data = array()) {
+ $sql = "SELECT google_base_category_id, (SELECT name FROM `" . DB_PREFIX . "google_base_category` gbc WHERE gbc.google_base_category_id = gbc2c.google_base_category_id) AS google_base_category, category_id, (SELECT name FROM `" . DB_PREFIX . "category_description` cd WHERE cd.category_id = gbc2c.category_id AND cd.language_id = '" . (int)$this->config->get('config_language_id') . "') AS category FROM `" . DB_PREFIX . "google_base_category_to_category` gbc2c ORDER BY google_base_category 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'];
+ }
+
+ $query = $this->db->query($sql);
+
+ return $query->rows;
+ }
+
+ public function getTotalCategories() {
+ $query = $this->db->query("SELECT COUNT(*) AS total FROM `" . DB_PREFIX . "google_base_category_to_category`");
+
+ return $query->row['total'];
+ }
+}
diff --git a/public/admin/model/extension/fraud/fraudlabspro.php b/public/admin/model/extension/fraud/fraudlabspro.php
new file mode 100644
index 0000000..b7a80b2
--- /dev/null
+++ b/public/admin/model/extension/fraud/fraudlabspro.php
@@ -0,0 +1,125 @@
+<?php
+class ModelExtensionFraudFraudLabsPro extends Model {
+ public function install() {
+ $this->db->query("
+ CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "fraudlabspro` (
+ `order_id` VARCHAR(11) NOT NULL,
+ `is_country_match` CHAR(2) NOT NULL,
+ `is_high_risk_country` CHAR(2) NOT NULL,
+ `distance_in_km` VARCHAR(10) NOT NULL,
+ `distance_in_mile` VARCHAR(10) NOT NULL,
+ `ip_address` VARCHAR(15) NOT NULL,
+ `ip_country` VARCHAR(2) NOT NULL,
+ `ip_continent` VARCHAR(20) NOT NULL,
+ `ip_region` VARCHAR(21) NOT NULL,
+ `ip_city` VARCHAR(21) NOT NULL,
+ `ip_latitude` VARCHAR(21) NOT NULL,
+ `ip_longitude` VARCHAR(21) NOT NULL,
+ `ip_timezone` VARCHAR(10) NOT NULL,
+ `ip_elevation` VARCHAR(10) NOT NULL,
+ `ip_domain` VARCHAR(50) NOT NULL,
+ `ip_mobile_mnc` VARCHAR(100) NOT NULL,
+ `ip_mobile_mcc` VARCHAR(100) NOT NULL,
+ `ip_mobile_brand` VARCHAR(100) NOT NULL,
+ `ip_netspeed` VARCHAR(10) NOT NULL,
+ `ip_isp_name` VARCHAR(50) NOT NULL,
+ `ip_usage_type` VARCHAR(30) NOT NULL,
+ `is_free_email` CHAR(2) NOT NULL,
+ `is_new_domain_name` CHAR(2) NOT NULL,
+ `is_proxy_ip_address` CHAR(2) NOT NULL,
+ `is_bin_found` CHAR(2) NOT NULL,
+ `is_bin_country_match` CHAR(2) NOT NULL,
+ `is_bin_name_match` CHAR(2) NOT NULL,
+ `is_bin_phone_match` CHAR(2) NOT NULL,
+ `is_bin_prepaid` CHAR(2) NOT NULL,
+ `is_address_ship_forward` CHAR(2) NOT NULL,
+ `is_bill_ship_city_match` CHAR(2) NOT NULL,
+ `is_bill_ship_state_match` CHAR(2) NOT NULL,
+ `is_bill_ship_country_match` CHAR(2) NOT NULL,
+ `is_bill_ship_postal_match` CHAR(2) NOT NULL,
+ `is_ip_blacklist` CHAR(2) NOT NULL,
+ `is_email_blacklist` CHAR(2) NOT NULL,
+ `is_credit_card_blacklist` CHAR(2) NOT NULL,
+ `is_device_blacklist` CHAR(2) NOT NULL,
+ `is_user_blacklist` CHAR(2) NOT NULL,
+ `fraudlabspro_score` CHAR(3) NOT NULL,
+ `fraudlabspro_distribution` CHAR(3) NOT NULL,
+ `fraudlabspro_status` CHAR(10) NOT NULL,
+ `fraudlabspro_id` CHAR(15) NOT NULL,
+ `fraudlabspro_error` CHAR(3) NOT NULL,
+ `fraudlabspro_message` VARCHAR(50) NOT NULL,
+ `fraudlabspro_credits` VARCHAR(10) NOT NULL,
+ `api_key` CHAR(32) NOT NULL,
+ PRIMARY KEY (`order_id`)
+ ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci;
+ ");
+
+ $this->db->query("INSERT INTO `" . DB_PREFIX . "order_status` (`language_id`, `name`) VALUES (1, 'Fraud');");
+ $status_fraud_id = $this->db->getLastId();
+
+ $this->db->query("INSERT INTO `" . DB_PREFIX . "order_status` (`language_id`, `name`) VALUES (1, 'Fraud Review');");
+
+ $status_fraud_review_id = $this->db->getLastId();
+
+ $this->db->query("INSERT INTO `" . DB_PREFIX . "setting` (`code`, `key`, `value`, `serialized`) VALUES ('fraudlabspro', 'fraud_fraudlabspro_score', '80', '0');");
+ $this->db->query("INSERT INTO `" . DB_PREFIX . "setting` (`code`, `key`, `value`, `serialized`) VALUES ('fraudlabspro', 'fraud_fraudlabspro_order_status_id', '" . (int)$status_fraud_id . "', '0');");
+ $this->db->query("INSERT INTO `" . DB_PREFIX . "setting` (`code`, `key`, `value`, `serialized`) VALUES ('fraudlabspro', 'fraud_fraudlabspro_review_status_id', '" . (int)$status_fraud_review_id . "', '0');");
+ $this->db->query("INSERT INTO `" . DB_PREFIX . "setting` (`code`, `key`, `value`, `serialized`) VALUES ('fraudlabspro', 'fraud_fraudlabspro_approve_status_id', '2', '0');");
+ $this->db->query("INSERT INTO `" . DB_PREFIX . "setting` (`code`, `key`, `value`, `serialized`) VALUES ('fraudlabspro', 'fraud_fraudlabspro_reject_status_id', '8', '0');");
+
+ $this->cache->delete('order_status.' . (int)$this->config->get('config_language_id'));
+ }
+
+ public function uninstall() {
+ //$this->db->query("DROP TABLE IF EXISTS `" . DB_PREFIX . "fraudlabspro`");
+ $this->db->query("DELETE FROM `" . DB_PREFIX . "order_status` WHERE `name` = 'Fraud'");
+ $this->db->query("DELETE FROM `" . DB_PREFIX . "order_status` WHERE `name` = 'Fraud Review'");
+ }
+
+ public function getOrder($order_id) {
+ $query = $this->db->query("SELECT * FROM `" . DB_PREFIX . "fraudlabspro` WHERE order_id = '" . (int)$order_id . "'");
+
+ return $query->row;
+ }
+
+ public function addOrderHistory($order_id, $data, $store_id = 0) {
+ $json = array();
+
+ $this->load->model('setting/store');
+
+ $store_info = $this->model_setting_store->getStore($store_id);
+
+ if ($store_info) {
+ $url = $store_info['ssl'];
+ } else {
+ $url = HTTPS_CATALOG;
+ }
+
+ if (isset($this->session->data['cookie'])) {
+ $curl = curl_init();
+
+ // Set SSL if required
+ if (substr($url, 0, 5) == 'https') {
+ curl_setopt($curl, CURLOPT_PORT, 443);
+ }
+
+ curl_setopt($curl, CURLOPT_HEADER, false);
+ curl_setopt($curl, CURLINFO_HEADER_OUT, true);
+ curl_setopt($curl, CURLOPT_USERAGENT, $this->request->server['HTTP_USER_AGENT']);
+ curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
+ curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
+ curl_setopt($curl, CURLOPT_FORBID_REUSE, false);
+ curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
+ curl_setopt($curl, CURLOPT_URL, $url . 'index.php?route=api/order/history&order_id=' . $order_id);
+ curl_setopt($curl, CURLOPT_POST, true);
+ curl_setopt($curl, CURLOPT_POSTFIELDS, http_build_query($data));
+ curl_setopt($curl, CURLOPT_COOKIE, session_name() . '=' . $this->session->data['cookie'] . ';');
+
+ $json = curl_exec($curl);
+
+ curl_close($curl);
+ }
+
+ return $json;
+ }
+} \ No newline at end of file
diff --git a/public/admin/model/extension/fraud/ip.php b/public/admin/model/extension/fraud/ip.php
new file mode 100644
index 0000000..3e01bdf
--- /dev/null
+++ b/public/admin/model/extension/fraud/ip.php
@@ -0,0 +1,50 @@
+<?php
+class ModelExtensionFraudIp extends Model {
+ public function install() {
+ $this->db->query("
+ CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "fraud_ip` (
+ `ip` varchar(40) NOT NULL,
+ `date_added` datetime NOT NULL,
+ PRIMARY KEY (`ip`)
+ ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci;
+ ");
+ }
+
+ public function uninstall() {
+ $this->db->query("DROP TABLE IF EXISTS `" . DB_PREFIX . "ip`");
+ }
+
+ public function addIp($ip) {
+ $this->db->query("INSERT INTO `" . DB_PREFIX . "fraud_ip` SET `ip` = '" . $this->db->escape($ip) . "', date_added = NOW()");
+ }
+
+ public function removeIp($ip) {
+ $this->db->query("DELETE FROM `" . DB_PREFIX . "fraud_ip` WHERE `ip` = '" . $this->db->escape($ip) . "'");
+ }
+
+ public function getIps($start = 0, $limit = 10) {
+ if ($start < 0) {
+ $start = 0;
+ }
+
+ if ($limit < 1) {
+ $limit = 10;
+ }
+
+ $query = $this->db->query("SELECT * FROM `" . DB_PREFIX . "fraud_ip` ORDER BY `ip` ASC LIMIT " . (int)$start . "," . (int)$limit);
+
+ return $query->rows;
+ }
+
+ public function getTotalIps() {
+ $query = $this->db->query("SELECT COUNT(*) AS total FROM `" . DB_PREFIX . "fraud_ip`");
+
+ return $query->row['total'];
+ }
+
+ public function getTotalIpsByIp($ip) {
+ $query = $this->db->query("SELECT COUNT(*) AS total FROM `" . DB_PREFIX . "fraud_ip` WHERE ip = '" . $this->db->escape($ip) . "'");
+
+ return $query->row['total'];
+ }
+}
diff --git a/public/admin/model/extension/fraud/maxmind.php b/public/admin/model/extension/fraud/maxmind.php
new file mode 100644
index 0000000..ad2134f
--- /dev/null
+++ b/public/admin/model/extension/fraud/maxmind.php
@@ -0,0 +1,73 @@
+<?php
+class ModelExtensionFraudMaxMind extends Model {
+ public function install() {
+ $this->db->query("
+ CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "maxmind` (
+ `order_id` int(11) NOT NULL,
+ `customer_id` int(11) NOT NULL,
+ `country_match` varchar(3) NOT NULL,
+ `country_code` varchar(2) NOT NULL,
+ `high_risk_country` varchar(3) NOT NULL,
+ `distance` int(11) NOT NULL,
+ `ip_region` varchar(255) NOT NULL,
+ `ip_city` varchar(255) NOT NULL,
+ `ip_latitude` decimal(10,6) NOT NULL,
+ `ip_longitude` decimal(10,6) NOT NULL,
+ `ip_isp` varchar(255) NOT NULL,
+ `ip_org` varchar(255) NOT NULL,
+ `ip_asnum` int(11) NOT NULL,
+ `ip_user_type` varchar(255) NOT NULL,
+ `ip_country_confidence` varchar(3) NOT NULL,
+ `ip_region_confidence` varchar(3) NOT NULL,
+ `ip_city_confidence` varchar(3) NOT NULL,
+ `ip_postal_confidence` varchar(3) NOT NULL,
+ `ip_postal_code` varchar(10) NOT NULL,
+ `ip_accuracy_radius` int(11) NOT NULL,
+ `ip_net_speed_cell` varchar(255) NOT NULL,
+ `ip_metro_code` int(3) NOT NULL,
+ `ip_area_code` int(3) NOT NULL,
+ `ip_time_zone` varchar(255) NOT NULL,
+ `ip_region_name` varchar(255) NOT NULL,
+ `ip_domain` varchar(255) NOT NULL,
+ `ip_country_name` varchar(255) NOT NULL,
+ `ip_continent_code` varchar(2) NOT NULL,
+ `ip_corporate_proxy` varchar(3) NOT NULL,
+ `anonymous_proxy` varchar(3) NOT NULL,
+ `proxy_score` int(3) NOT NULL,
+ `is_trans_proxy` varchar(3) NOT NULL,
+ `free_mail` varchar(3) NOT NULL,
+ `carder_email` varchar(3) NOT NULL,
+ `high_risk_username` varchar(3) NOT NULL,
+ `high_risk_password` varchar(3) NOT NULL,
+ `bin_match` varchar(10) NOT NULL,
+ `bin_country` varchar(2) NOT NULL,
+ `bin_name_match` varchar(3) NOT NULL,
+ `bin_name` varchar(255) NOT NULL,
+ `bin_phone_match` varchar(3) NOT NULL,
+ `bin_phone` varchar(32) NOT NULL,
+ `customer_phone_in_billing_location` varchar(8) NOT NULL,
+ `ship_forward` varchar(3) NOT NULL,
+ `city_postal_match` varchar(3) NOT NULL,
+ `ship_city_postal_match` varchar(3) NOT NULL,
+ `score` decimal(10,5) NOT NULL,
+ `explanation` text NOT NULL,
+ `risk_score` decimal(10,5) NOT NULL,
+ `queries_remaining` int(11) NOT NULL,
+ `maxmind_id` varchar(8) NOT NULL,
+ `error` text NOT NULL,
+ `date_added` datetime NOT NULL,
+ PRIMARY KEY (`order_id`)
+ ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci;
+ ");
+ }
+
+ public function uninstall() {
+ $this->db->query("DROP TABLE IF EXISTS `" . DB_PREFIX . "maxmind`");
+ }
+
+ public function getOrder($order_id) {
+ $query = $this->db->query("SELECT * FROM `" . DB_PREFIX . "maxmind` WHERE order_id = '" . (int)$order_id . "'");
+
+ return $query->row;
+ }
+} \ No newline at end of file
diff --git a/public/admin/model/extension/openbay/amazon.php b/public/admin/model/extension/openbay/amazon.php
new file mode 100644
index 0000000..a323ab9
--- /dev/null
+++ b/public/admin/model/extension/openbay/amazon.php
@@ -0,0 +1,741 @@
+<?php
+class ModelExtensionOpenBayAmazon extends Model {
+ public function install() {
+ $this->load->model('setting/event');
+
+ $this->model_setting_event->addEvent('openbay_amazon_add_order', 'catalog/model/checkout/order/addOrderHistory/after', 'extension/openbay/amazon/eventAddOrderHistory');
+
+ $this->db->query("
+ CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "amazon_order` (
+ `order_id` int(11) NOT NULL ,
+ `amazon_order_id` char(19) NOT NULL ,
+ `courier_id` varchar(255) NOT NULL ,
+ `courier_other` tinyint(1) NOT NULL,
+ `tracking_no` varchar(255) NOT NULL ,
+ PRIMARY KEY (`order_id`, `amazon_order_id`)
+ ) DEFAULT COLLATE=utf8_general_ci;");
+
+ $this->db->query("
+ CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "amazon_order_product` (
+ `order_product_id` int(11) NOT NULL ,
+ `amazon_order_item_id` varchar(255) NOT NULL,
+ PRIMARY KEY(`order_product_id`, `amazon_order_item_id`)
+ );");
+
+ $this->db->query("
+ CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "amazon_product_unshipped` (
+ `order_id` int(11) NOT NULL,
+ `product_id` int(11) NOT NULL,
+ `quantity` int(11) NOT NULL DEFAULT '0',
+ PRIMARY KEY (`order_id`,`product_id`)
+ ) DEFAULT COLLATE=utf8_general_ci;");
+
+ $this->db->query("
+ CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "amazon_product` (
+ `version` int(11) NOT NULL DEFAULT 2,
+ `product_id` int(11) NOT NULL ,
+ `category` varchar(255) NOT NULL ,
+ `sku` varchar(255) NOT NULL ,
+ `insertion_id` varchar(255) NOT NULL ,
+ `data` text NOT NULL ,
+ `status` enum('saved','uploaded','ok','error') NOT NULL ,
+ `price` decimal(15,4) NOT NULL COMMENT 'Price on Amazon' ,
+ `var` char(100) NOT NULL DEFAULT '',
+ `marketplaces` text NOT NULL ,
+ `messages` text NOT NULL,
+ PRIMARY KEY (`product_id`, `var`)
+ );");
+
+ $this->db->query("
+ CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "amazon_product_error` (
+ `error_id` int(11) NOT NULL AUTO_INCREMENT,
+ `sku` varchar(255) NOT NULL ,
+ `insertion_id` varchar(255) NOT NULL ,
+ `error_code` int(11) NOT NULL ,
+ `message` text NOT NULL ,
+ PRIMARY KEY (`error_id`)
+ );");
+
+ $this->db->query("
+ CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "amazon_product_link` (
+ `id` int(11) NOT NULL AUTO_INCREMENT,
+ `amazon_sku` varchar(255) NOT NULL,
+ `var` char(100) NOT NULL DEFAULT '',
+ `product_id` int(11) NOT NULL,
+ PRIMARY KEY (`id`)
+ ) DEFAULT COLLATE=utf8_general_ci;");
+
+ $this->db->query("
+ CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "amazon_product_search` (
+ `product_id` int(11) NOT NULL,
+ `marketplace` enum('uk','de','es','it','fr') NOT NULL,
+ `status` enum('searching','finished') NOT NULL,
+ `matches` int(11) DEFAULT NULL,
+ `data` text,
+ PRIMARY KEY (`product_id`,`marketplace`)
+ ) DEFAULT COLLATE=utf8_general_ci;");
+
+ $this->db->query("
+ CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "amazon_listing_report` (
+ `marketplace` enum('uk','de','fr','es','it') NOT NULL,
+ `sku` varchar(255) NOT NULL,
+ `quantity` int(10) unsigned NOT NULL,
+ `asin` varchar(255) NOT NULL,
+ `price` decimal(10,4) NOT NULL,
+ PRIMARY KEY (`marketplace`,`sku`)
+ ) DEFAULT COLLATE=utf8_general_ci;");
+ }
+
+ public function uninstall() {
+ $this->db->query("DROP TABLE IF EXISTS `" . DB_PREFIX . "amazon_order`");
+ $this->db->query("DROP TABLE IF EXISTS `" . DB_PREFIX . "amazon_order_product`");
+ $this->db->query("DROP TABLE IF EXISTS `" . DB_PREFIX . "amazon_product2`");
+ $this->db->query("DROP TABLE IF EXISTS `" . DB_PREFIX . "amazon_product`");
+ $this->db->query("DROP TABLE IF EXISTS `" . DB_PREFIX . "amazon_product_link`");
+ $this->db->query("DROP TABLE IF EXISTS `" . DB_PREFIX . "amazon_product_unshipped`");
+ $this->db->query("DROP TABLE IF EXISTS `" . DB_PREFIX . "amazon_product_error`");
+ $this->db->query("DROP TABLE IF EXISTS `" . DB_PREFIX . "amazon_process`");
+ $this->db->query("DROP TABLE IF EXISTS `" . DB_PREFIX . "amazon_product_unshipped`");
+ $this->db->query("DROP TABLE IF EXISTS `" . DB_PREFIX . "amazon_product_search`");
+ $this->db->query("DROP TABLE IF EXISTS `" . DB_PREFIX . "amazon_listing_report`");
+
+ $this->db->query("DELETE FROM `" . DB_PREFIX . "setting` WHERE `code` = 'openbay_amazon'");
+
+ $this->load->model('setting/event');
+ $this->model_setting_event->deleteEventByCode('openbay_amazon_add_order');
+ }
+
+ public function patch() {
+ if ($this->config->get('openbay_amazon_status') == 1) {
+
+ }
+ }
+
+ public function verifyConfig($data) {
+ $log = new Log('amazon.log');
+
+ $request_xml = new SimpleXMLElement("<Request></Request>");
+ $request_xml->addChild("ResponseURL", HTTP_CATALOG . 'index.php?route=extension/openbay/amazon/order');
+
+ $marketplace_ids = $request_xml->addChild("MarketplaceIDs");
+
+ foreach ($data['openbay_amazon_orders_marketplace_ids'] as $marketplace_id) {
+ $marketplace_ids->addChild("MarketplaceID", $marketplace_id);
+ }
+
+ $response = $this->openbay->amazon->call('order/scheduleOrders', $request_xml->asXML(), false);
+
+ libxml_use_internal_errors(true);
+ $response_xml = simplexml_load_string($response);
+ libxml_use_internal_errors(false);
+
+ if ($response_xml && $response_xml->Status == '0') {
+ $log->write('Scheduling orders call was successful');
+ return true;
+ }
+
+ $log->write('Failed to schedule orders. Response: ' . $response);
+
+ return false;
+ }
+
+ public function saveProduct($product_id, $data_array) {
+ if (isset($data_array['fields']['item-price'])) {
+ $price = $data_array['fields']['item-price'];
+ } else if (isset($data_array['fields']['price'])) {
+ $price = $data_array['fields']['price'];
+ } else if (isset($data_array['fields']['StandardPrice'])) {
+ $price = $data_array['fields']['StandardPrice'];
+ } else {
+ $price = 0;
+ }
+
+ $category = (isset($data_array['category'])) ? $data_array['category'] : "";
+ $sku = (isset($data_array['fields']['sku'])) ? $data_array['fields']['sku'] : "";
+ if (isset($data_array['fields']['sku'])) {
+ $sku = $data_array['fields']['sku'];
+ } else if (isset($data_array['fields']['SKU'])) {
+ $sku = $data_array['fields']['SKU'];
+ }
+
+ $var = isset($data_array['optionVar']) ? $data_array['optionVar'] : '';
+
+ $marketplaces = isset($data_array['marketplace_ids']) ? serialize($data_array['marketplace_ids']) : serialize(array());
+
+ $data_encoded = json_encode(array('fields' => $data_array['fields']));
+
+ $this->db->query("
+ REPLACE INTO `" . DB_PREFIX . "amazon_product`
+ SET `product_id` = '" . (int)$product_id . "',
+ `sku` = '" . $this->db->escape($sku) . "',
+ `category` = '" . $this->db->escape($category) . "',
+ `data` = '" . $this->db->escape($data_encoded) . "',
+ `status` = 'saved',
+ `insertion_id` = '',
+ `price` = '" . $price . "',
+ `var` = '" . $this->db->escape($var) . "',
+ `marketplaces` = '" . $this->db->escape($marketplaces) . "'");
+ }
+
+ public function deleteSaved($product_id, $var = '') {
+ $this->db->query("DELETE FROM `" . DB_PREFIX . "amazon_product`
+ WHERE `product_id` = '" . (int)$product_id . "' AND `var` = '" . $this->db->escape($var) . "'");
+ }
+
+ public function getSavedProducts() {
+ return $this->db->query("
+ SELECT `ap`.`status`, `ap`.`product_id`, `ap`.`sku` as `amazon_sku`, `pd`.`name` as `product_name`, `p`.`model` as `product_model`, `p`.`sku` as `product_sku`, `ap`.`var` as `var`
+ FROM `" . DB_PREFIX . "amazon_product` as `ap`
+ LEFT JOIN `" . DB_PREFIX . "product_description` as `pd`
+ ON `ap`.`product_id` = `pd`.`product_id`
+ LEFT JOIN `" . DB_PREFIX . "product` as `p`
+ ON `ap`.`product_id` = `p`.`product_id`
+ WHERE `ap`.`status` = 'saved'
+ AND `pd`.`language_id` = '" . (int)$this->config->get('config_language_id') . "'")->rows;
+ }
+
+ public function getSavedProductsData() {
+ return $this->db->query("
+ SELECT * FROM `" . DB_PREFIX . "amazon_product`
+ WHERE `status` = 'saved' AND `version` = 2")->rows;
+ }
+
+ public function getProduct($product_id, $var = '') {
+ return $this->db->query("
+ SELECT * FROM `" . DB_PREFIX . "amazon_product`
+ WHERE `product_id` = '" . (int)$product_id . "' AND `var` = '" . $this->db->escape($var) . "' AND `version` = 2")->row;
+ }
+
+ public function getProductCategory($product_id, $var = '') {
+ $row = $this->db->query("
+ SELECT `category` FROM `" . DB_PREFIX . "amazon_product`
+ WHERE `product_id` = '" . (int)$product_id . "' AND `var` = '" . $this->db->escape($var) . "' AND `version` = 2")->row;
+ if (isset($row['category'])) {
+ return $row['category'];
+ } else {
+ return "";
+ }
+ }
+
+ public function setProductUploaded($product_id, $insertion_id, $var = '') {
+ $this->db->query(
+ "UPDATE `" . DB_PREFIX . "amazon_product`
+ SET `status` = 'uploaded', `insertion_id` = '" . $this->db->escape($insertion_id) . "'
+ WHERE `product_id` = '" . (int)$product_id . "' AND `var` = '" . $this->db->escape($var) . "' AND `version` = 2");
+ }
+
+ public function resetUploaded($insertion_id) {
+ $this->db->query(
+ "UPDATE `" . DB_PREFIX . "amazon_product`
+ SET `status` = 'saved', `insertion_id` = ''
+ WHERE `insertion_id` = '" . $this->db->escape($insertion_id) . "' AND `version` = 2");
+ }
+
+ public function getProductStatus($product_id) {
+
+ $rows_uploaded = $this->db->query("
+ SELECT COUNT(*) count
+ FROM `" . DB_PREFIX . "amazon_product`
+ WHERE `product_id` = '" . (int)$product_id . "' AND status = 'uploaded'")->row;
+ $rows_uploaded = $rows_uploaded['count'];
+
+ $rows_ok = $this->db->query("
+ SELECT COUNT(*) count
+ FROM `" . DB_PREFIX . "amazon_product`
+ WHERE `product_id` = '" . (int)$product_id . "' AND status = 'ok'")->row;
+ $rows_ok = $rows_ok['count'];
+
+ $rows_error = $this->db->query("
+ SELECT COUNT(*) count
+ FROM `" . DB_PREFIX . "amazon_product`
+ WHERE `product_id` = '" . (int)$product_id . "' AND status = 'error'")->row;
+ $rows_error = $rows_error['count'];
+
+ $rows_saved = $this->db->query("
+ SELECT COUNT(*) count
+ FROM `" . DB_PREFIX . "amazon_product`
+ WHERE `product_id` = '" . (int)$product_id . "' AND status = 'saved'")->row;
+ $rows_saved = $rows_saved['count'];
+
+ $rows_total = $rows_uploaded + $rows_ok + $rows_error + $rows_saved;
+
+ $links = $this->db->query("
+ SELECT COUNT(*) as count
+ FROM `" . DB_PREFIX . "amazon_product_link`
+ WHERE `product_id` = '" . (int)$product_id . "'")->row;
+ $links = $links['count'];
+
+ if ($rows_total === 0 && $links > 0) {
+ return 'linked';
+ } else if ($rows_total == 0) {
+ return false;
+ }
+
+ if ($rows_uploaded > 0) {
+ return 'processing';
+ }
+
+ if ($rows_uploaded == 0 && $rows_ok > 0 && $rows_error == 0) {
+ return 'ok';
+ }
+
+ if ($rows_saved > 0) {
+ return 'saved';
+ }
+
+ if ($rows_uploaded == 0 && $rows_error > 0 && $rows_ok == 0) {
+ $quick = $this->db->query("SELECT * FROM `" . DB_PREFIX . "amazon_product` WHERE `product_id` = " . (int)$product_id . " AND `version` = 3")->row;
+
+ if ($quick) {
+ return 'error_quick';
+ } else {
+ return 'error_advanced';
+ }
+ } else {
+ return 'error_few';
+ }
+
+ return false;
+ }
+
+ public function getProductErrors($product_id, $version = 2) {
+ if ($version == 3) {
+ $message_row = $this->db->query("SELECT `messages` FROM `" . DB_PREFIX . "amazon_product` WHERE `product_id` = '" . (int)$product_id . "' AND `version` = 3")->row;
+
+ return json_decode($message_row['messages']);
+ }
+
+ $result = array();
+
+ $insertion_rows = $this->db->query("SELECT `sku`, `insertion_id` FROM `" . DB_PREFIX . "amazon_product` WHERE `product_id` = '" . (int)$product_id . "' AND `version` = 2")->rows;
+
+ if (!empty($insertion_rows)) {
+ foreach($insertion_rows as $insertion_row) {
+ $error_rows = $this->db->query("SELECT * FROM `" . DB_PREFIX . "amazon_product_error` WHERE `sku` = '" . $this->db->escape($insertion_row['sku']) . "' AND `insertion_id` = '" . $this->db->escape($insertion_row['insertion_id']) . "'")->rows;
+
+ foreach($error_rows as $error_row) {
+ $result[] = $error_row;
+ }
+ }
+ }
+ return $result;
+ }
+
+ public function getProductsWithErrors() {
+ return $this->db->query("
+ SELECT `product_id`, `sku` FROM `" . DB_PREFIX . "amazon_product`
+ WHERE `status` = 'error' AND `version` = 2")->rows;
+ }
+
+ public function deleteProduct($product_id) {
+ $this->db->query(
+ "DELETE FROM `" . DB_PREFIX . "amazon_product`
+ WHERE `product_id` = '" . (int)$product_id . "'");
+ }
+
+ public function linkProduct($amazon_sku, $product_id, $var = '') {
+ $count = $this->db->query("SELECT COUNT(*) as `count` FROM `" . DB_PREFIX . "amazon_product_link` WHERE `product_id` = '" . (int)$product_id . "' AND `amazon_sku` = '" . $this->db->escape($amazon_sku) . "' AND `var` = '" . $this->db->escape($var) . "' LIMIT 1")->row;
+
+ if ($count['count'] == 0) {
+ $this->db->query("INSERT INTO `" . DB_PREFIX . "amazon_product_link` SET `product_id` = '" . (int)$product_id . "', `amazon_sku` = '" . $this->db->escape($amazon_sku) . "', `var` = '" . $this->db->escape($var) . "'");
+ }
+ }
+
+ public function removeProductLink($amazon_sku) {
+ $this->db->query(
+ "DELETE FROM `" . DB_PREFIX . "amazon_product_link`
+ WHERE `amazon_sku` = '" . $this->db->escape($amazon_sku) . "'");
+ }
+
+ public function removeAdvancedErrors($product_id) {
+ $product_rows = $this->db->query("
+ SELECT `insertion_id` FROM `" . DB_PREFIX . "amazon_product`
+ WHERE `product_id` = '" . (int)$product_id . "' AND `version` = 2")->rows;
+
+ foreach ($product_rows as $product) {
+ $this->db->query(
+ "DELETE FROM `" . DB_PREFIX . "amazon_product_error`
+ WHERE `insertion_id` = '" . $this->db->escape($product['insertion_id']) . "'");
+ }
+
+ $this->db->query(
+ "UPDATE `" . DB_PREFIX . "amazon_product`
+ SET `status` = 'saved', `insertion_id` = ''
+ WHERE `product_id` = '" . (int)$product_id . "' AND `status` = 'error' AND `version` = 2");
+ }
+
+ public function getProductLinks($product_id = 'all') {
+ $query = "
+ SELECT `apl`.`product_id`, `pd`.`name` as `product_name`, `p`.`model`, `apl`.`amazon_sku`, `p`.`sku`, `apl`.`var`, '' as `combination`
+ FROM `" . DB_PREFIX . "amazon_product_link` as `apl`
+ LEFT JOIN `" . DB_PREFIX . "product_description` as `pd`
+ ON `apl`.`product_id` = `pd`.`product_id`
+ LEFT JOIN `" . DB_PREFIX . "product` as `p`
+ ON `apl`.`product_id` = `p`.`product_id`";
+
+ if ($product_id != 'all') {
+ $query .= " WHERE `apl`.`product_id` = '" . (int)$product_id . "' AND `pd`.`language_id` = '" . (int)$this->config->get('config_language_id') . "'";
+ } else {
+ $query .= "WHERE `pd`.`language_id` = '" . (int)$this->config->get('config_language_id') . "'";
+ }
+
+ $product_links = $this->db->query($query)->rows;
+
+ if ($this->openbay->addonLoad('openstock')) {
+ $this->load->model('extension/module/openstock');
+ $this->load->model('tool/image');
+
+ foreach ($product_links as $key => $product_link) {
+ $variants = $this->model_setting_module_openstock->getVariants($product_link['product_id']);
+
+ if (!empty($variants)) {
+ foreach($variants as $variant) {
+ if ($variant['sku'] == $product_link['var']) {
+ $product_links[$key]['combination'] = $variant['combination'];
+ break;
+ }
+ }
+ }
+ }
+
+ return $product_links;
+ } else {
+ return $product_links;
+ }
+ }
+
+ public function getUnlinkedProducts() {
+ if ($this->openbay->addonLoad('openstock')) {
+ $rows = $this->db->query("
+ SELECT `p`.`product_id`, `p`.`model`, `p`.`sku`, `pd`.`name` as `product_name`, '' as `var`, '' as `combination`, `p`.`has_option`
+ FROM `" . DB_PREFIX . "product` as `p`
+ LEFT JOIN `" . DB_PREFIX . "product_description` as `pd`
+ ON `p`.`product_id` = `pd`.`product_id`
+ AND `pd`.`language_id` = '" . (int)$this->config->get('config_language_id') . "'")->rows;
+
+ $result = array();
+ $this->load->model('extension/module/openstock');
+ $this->load->model('tool/image');
+ foreach($rows as $row) {
+ if ($row['has_option'] == 1) {
+ $stock_opts = $this->model_setting_module_openstock->getVariants($row['product_id']);
+ foreach($stock_opts as $opt) {
+ if ($this->productLinkExists($row['product_id'], $opt['sku'])) {
+ continue;
+ }
+ $row['combination'] = $opt['combination'];
+ $row['sku'] = $opt['sku'];
+ $result[] = $row;
+ }
+ } else {
+ if (!$this->productLinkExists($row['product_id'], $row['sku'])) {
+ $result[] = $row;
+ }
+ }
+ }
+ } else {
+ $result = $this->db->query("
+ SELECT `p`.`product_id`, `p`.`model`, `p`.`sku`, `pd`.`name` as `product_name`, '' as `var`, '' as `combination`
+ FROM `" . DB_PREFIX . "product` as `p`
+ LEFT JOIN `" . DB_PREFIX . "product_description` as `pd`
+ ON `p`.`product_id` = `pd`.`product_id`
+ LEFT JOIN `" . DB_PREFIX . "amazon_product_link` as `apl`
+ ON `apl`.`product_id` = `p`.`product_id`
+ WHERE `apl`.`amazon_sku` IS NULL
+ AND `pd`.`language_id` = '" . (int)$this->config->get('config_language_id') . "'")->rows;
+ }
+
+ return $result;
+ }
+
+ private function productLinkExists($product_id, $var) {
+ $link = $this->db->query("SELECT * FROM `" . DB_PREFIX . "amazon_product_link` WHERE `product_id` = " . (int)$product_id . " AND var = '" . $this->db->escape($var) . "'")->row;
+
+ if (empty($link)) {
+ return false;
+ } else {
+ return true;
+ }
+ }
+
+ public function getOrderStatusString($order_id) {
+ $row = $this->db->query("
+ SELECT `s`.`key`
+ FROM `" . DB_PREFIX . "order` `o`
+ JOIN `" . DB_PREFIX . "setting` `s` ON `o`.`order_id` = " . (int)$order_id . " AND `s`.`value` = `o`.`order_status_id`
+ WHERE `s`.`key` = 'openbay_amazon_order_status_shipped' OR `s`.`key` = 'openbay_amazon_order_status_canceled'
+ LIMIT 1")->row;
+
+ if (!isset($row['key']) || empty($row['key'])) {
+ return null;
+ }
+
+ $key = $row['key'];
+
+ switch ($key) {
+ case 'openbay_amazon_order_status_shipped':
+ $order_status = 'shipped';
+ break;
+ case 'openbay_amazon_order_status_canceled':
+ $order_status = 'canceled';
+ break;
+
+ default:
+ $order_status = null;
+ break;
+ }
+
+ return $order_status;
+ }
+
+ public function updateAmazonOrderTracking($order_id, $courier_id, $courier_from_list, $tracking_no) {
+ $this->db->query("UPDATE `" . DB_PREFIX . "amazon_order` SET `courier_id` = '" . $this->db->escape($courier_id) . "', `courier_other` = " . (int)!$courier_from_list . ", `tracking_no` = '" . $this->db->escape($tracking_no) . "' WHERE `order_id` = " . (int)$order_id . "");
+ }
+
+ public function getAmazonOrderId($order_id) {
+ $row = $this->db->query("
+ SELECT `amazon_order_id`
+ FROM `" . DB_PREFIX . "amazon_order`
+ WHERE `order_id` = " . (int)$order_id . "
+ LIMIT 1")->row;
+
+ if (isset($row['amazon_order_id']) && !empty($row['amazon_order_id'])) {
+ return $row['amazon_order_id'];
+ }
+
+ return null;
+ }
+
+ public function getAmazonOrderedProducts($order_id) {
+ return $this->db->query("
+ SELECT `aop`.`amazon_order_item_id`, `op`.`quantity`
+ FROM `" . DB_PREFIX . "amazon_order_product` `aop`
+ JOIN `" . DB_PREFIX . "order_product` `op` ON `op`.`order_product_id` = `aop`.`order_product_id`
+ AND `op`.`order_id` = " . (int)$order_id)->rows;
+ }
+
+ public function getProductQuantity($product_id, $var = '') {
+ $result = null;
+
+ if ($var !== '' && $this->openbay->addonLoad('openstock')) {
+ $this->load->model('tool/image');
+ $this->load->model('extension/module/openstock');
+ $option_stocks = $this->model_setting_module_openstock->getVariants($product_id);
+
+ $option = null;
+ foreach ($option_stocks as $option_iterator) {
+ if ($option_iterator['sku'] === $var) {
+ $option = $option_iterator;
+ break;
+ }
+ }
+
+ if ($option != null) {
+ $result = $option['stock'];
+ }
+ } else {
+ $this->load->model('catalog/product');
+ $product_info = $this->model_catalog_product->getProduct($product_id);
+
+ if (isset($product_info['quantity'])) {
+ $result = $product_info['quantity'];
+ }
+ }
+ return $result;
+ }
+
+ public function getProductSearchTotal($data = array()) {
+ $sql = "
+ SELECT COUNT(*) AS product_total
+ FROM " . DB_PREFIX . "product p
+ LEFT JOIN " . DB_PREFIX . "amazon_product_search aps ON p.product_id = aps.product_id AND aps.marketplace = '" . $this->db->escape($data['filter_marketplace']) . "'
+ LEFT JOIN " . DB_PREFIX . "amazon_product_link apl ON p.product_id = apl.product_id
+ LEFT JOIN " . DB_PREFIX . "amazon_product ap ON p.product_id = ap.product_id
+ WHERE apl.product_id IS NULL AND ap.product_id IS NULL ";
+
+ if (!empty($data['status'])) {
+ $sql .= " AND aps.status = '" . $this->db->escape($data['status']) . "'";
+ }
+
+ return $this->db->query($sql)->row['product_total'];
+ }
+
+ public function getProductSearch($data = array()) {
+ $sql = "
+ SELECT p.product_id, marketplace, aps.status, aps.data, aps.matches
+ FROM " . DB_PREFIX . "product p
+ LEFT JOIN " . DB_PREFIX . "amazon_product_search aps ON p.product_id = aps.product_id AND aps.marketplace = '" . $this->db->escape($data['filter_marketplace']) . "'
+ LEFT JOIN " . DB_PREFIX . "amazon_product_link apl ON p.product_id = apl.product_id
+ LEFT JOIN " . DB_PREFIX . "amazon_product ap ON p.product_id = ap.product_id
+ WHERE apl.product_id IS NULL AND ap.product_id IS NULL ";
+
+ if (!empty($data['status'])) {
+ $sql .= " AND aps.status = '" . $this->db->escape($data['status']) . "'";
+ }
+
+ $sql .= " LIMIT " . (int)$data['start'] . ", " . (int)$data['limit'];
+
+ $results = array();
+
+ $rows = $this->db->query($sql)->rows;
+
+ foreach ($rows as $row) {
+ $results[] = array(
+ 'product_id' => $row['product_id'],
+ 'marketplace' => $row['marketplace'],
+ 'status' => $row['status'],
+ 'matches' => $row['matches'],
+ 'data' => json_decode($row['data'], 1),
+ );
+ }
+
+ return $results;
+ }
+
+ public function updateAmazonSkusQuantities($skus) {
+ $sku_array = array();
+
+ foreach ($skus as $sku) {
+ $sku_array[] = "'" . $this->db->escape($sku) . "'";
+ }
+
+ if ($this->openbay->addonLoad('openstock')) {
+ $rows = $this->db->query("SELECT apl.amazon_sku, if (pov.product_id IS NULL, p.quantity, pov.stock) AS 'quantity' FROM " . DB_PREFIX . "amazon_product_link apl JOIN " . DB_PREFIX . "product p ON apl.product_id = p.product_id LEFT JOIN " . DB_PREFIX . "product_option_variant pov ON apl.product_id = pov.product_id AND apl.var = pov.sku WHERE apl.amazon_sku IN (" . implode(',', $sku_array) . ")")->rows;
+ } else {
+ $rows = $this->db->query("SELECT apl.amazon_sku, p.quantity FROM " . DB_PREFIX . "amazon_product_link apl JOIN " . DB_PREFIX . "product p ON apl.product_id = p.product_id WHERE apl.amazon_sku IN (" . implode(',', $sku_array) . ")")->rows;
+ }
+
+ $return = array();
+
+ foreach ($rows as $row) {
+ $return[$row['amazon_sku']] = $row['quantity'];
+ }
+
+ $this->openbay->amazon->updateQuantities($return);
+ }
+
+ public function deleteListingReports($marketplace) {
+ $this->db->query("DELETE FROM " . DB_PREFIX . "amazon_listing_report WHERE marketplace = '" . $this->db->escape($marketplace) . "'");
+ }
+
+ public function getTotalUnlinkedItemsFromReport($marketplace) {
+ if ($this->openbay->addonLoad('openstock')) {
+
+ $sql = "
+ SELECT alr.sku AS 'amazon_sku', alr.quantity AS 'amazon_quantity', alr.asin, alr.price AS 'amazon_price', oc_sku.product_id, pd.name, oc_sku.sku, oc_sku.var, oc_sku.quantity, oc_sku.pov_id
+ FROM " . DB_PREFIX . "amazon_listing_report alr
+ LEFT JOIN (
+ SELECT p.product_id, if (por.product_id IS NULL, p.sku, por.sku) AS 'sku', if (por.product_id IS NULL, NULL, por.sku) AS 'var', if (por.product_id IS NULL, p.quantity, por.stock) AS 'quantity', por.product_option_variant_id AS pov_id
+ FROM " . DB_PREFIX . "product p
+ LEFT JOIN " . DB_PREFIX . "product_option_variant por USING(product_id)
+ ) AS oc_sku ON alr.sku = oc_sku.sku
+ LEFT JOIN " . DB_PREFIX . "amazon_product_link apl ON (oc_sku.var IS NULL AND oc_sku.product_id = apl.product_id) OR (oc_sku.var IS NOT NULL AND oc_sku.product_id = apl.product_id AND oc_sku.var = apl.var)
+ LEFT JOIN " . DB_PREFIX . "product_description pd ON oc_sku.product_id = pd.product_id AND pd.language_id = " . (int)$this->config->get('config_language_id') . "
+ WHERE apl.product_id IS NULL AND alr.marketplace = '" . $this->db->escape($marketplace) . "'
+ ORDER BY alr.sku
+ ";
+
+ $result = $this->db->query($sql);
+ } else {
+ $result = $this->db->query("
+ SELECT alr.sku AS 'amazon_sku', alr.quantity AS 'amazon_quantity', alr.asin, alr.price AS 'amazon_price', oc_sku.product_id, pd.name, oc_sku.sku, oc_sku.var, oc_sku.quantity
+ FROM " . DB_PREFIX . "amazon_listing_report alr
+ LEFT JOIN (
+ SELECT p.product_id, p.sku, NULL AS 'var', p.quantity
+ FROM " . DB_PREFIX . "product p
+ ) AS oc_sku ON alr.sku = oc_sku.sku
+ LEFT JOIN " . DB_PREFIX . "amazon_product_link apl ON (oc_sku.var IS NULL AND oc_sku.product_id = apl.product_id) OR (oc_sku.var IS NOT NULL AND oc_sku.product_id = apl.product_id AND oc_sku.var = apl.var)
+ LEFT JOIN " . DB_PREFIX . "product_description pd ON oc_sku.product_id = pd.product_id AND pd.language_id = " . (int)$this->config->get('config_language_id') . "
+ WHERE apl.product_id IS NULL AND alr.marketplace = '" . $this->db->escape($marketplace) . "'
+ ORDER BY alr.sku
+ ");
+ }
+
+ return (int)$result->num_rows;
+ }
+
+ public function getUnlinkedItemsFromReport($marketplace, $limit = 100, $page = 1) {
+ $start = $limit * ($page - 1);
+
+ if ($this->openbay->addonLoad('openstock')) {
+ $this->load->model('extension/module/openstock');
+ $rows = $this->db->query("
+ SELECT alr.sku AS 'amazon_sku', alr.quantity AS 'amazon_quantity', alr.asin, alr.price AS 'amazon_price', oc_sku.product_id, pd.name, oc_sku.sku, oc_sku.var, oc_sku.quantity, oc_sku.pov_id
+ FROM " . DB_PREFIX . "amazon_listing_report alr
+ LEFT JOIN (
+ SELECT p.product_id, if (por.product_id IS NULL, p.sku, por.sku) AS 'sku', if (por.product_id IS NULL, NULL, por.sku) AS 'var', if (por.product_id IS NULL, p.quantity, por.stock) AS 'quantity', por.product_option_variant_id AS pov_id
+ FROM " . DB_PREFIX . "product p
+ LEFT JOIN " . DB_PREFIX . "product_option_variant por USING(product_id)
+ ) AS oc_sku ON alr.sku = oc_sku.sku
+ LEFT JOIN " . DB_PREFIX . "amazon_product_link apl ON (oc_sku.var IS NULL AND oc_sku.product_id = apl.product_id) OR (oc_sku.var IS NOT NULL AND oc_sku.product_id = apl.product_id AND oc_sku.var = apl.var)
+ LEFT JOIN " . DB_PREFIX . "product_description pd ON oc_sku.product_id = pd.product_id AND pd.language_id = " . (int)$this->config->get('config_language_id') . "
+ WHERE apl.product_id IS NULL AND alr.marketplace = '" . $this->db->escape($marketplace) . "'
+ ORDER BY alr.sku
+ LIMIT " . (int)$start . "," . (int)$limit)->rows;
+ } else {
+ $rows = $this->db->query("
+ SELECT alr.sku AS 'amazon_sku', alr.quantity AS 'amazon_quantity', alr.asin, alr.price AS 'amazon_price', oc_sku.product_id, pd.name, oc_sku.sku, oc_sku.var, oc_sku.quantity
+ FROM " . DB_PREFIX . "amazon_listing_report alr
+ LEFT JOIN (
+ SELECT p.product_id, p.sku, NULL AS 'var', p.quantity
+ FROM " . DB_PREFIX . "product p
+ ) AS oc_sku ON alr.sku = oc_sku.sku
+ LEFT JOIN " . DB_PREFIX . "amazon_product_link apl ON (oc_sku.var IS NULL AND oc_sku.product_id = apl.product_id) OR (oc_sku.var IS NOT NULL AND oc_sku.product_id = apl.product_id AND oc_sku.var = apl.var)
+ LEFT JOIN " . DB_PREFIX . "product_description pd ON oc_sku.product_id = pd.product_id AND pd.language_id = " . (int)$this->config->get('config_language_id') . "
+ WHERE apl.product_id IS NULL AND alr.marketplace = '" . $this->db->escape($marketplace) . "'
+ ORDER BY alr.sku
+ LIMIT " . (int)$start . "," . (int)$limit)->rows;
+ }
+
+ $products = array();
+
+ foreach ($rows as $row) {
+ $combinations = array();
+
+ if (isset($row['pov_id']) && !empty($row['pov_id'])) {
+ $variants = (isset($row['pov_id']) ? $this->model_setting_module_openstock->getVariant($row['pov_id']) : '');
+
+ foreach ($variants as $variant) {
+ $combinations[] = $variant['option_value_name'];
+ }
+ }
+
+ $products[] = array(
+ 'product_id' => $row['product_id'],
+ 'name' => $row['name'],
+ 'sku' => $row['sku'],
+ 'var' => $row['var'],
+ 'quantity' => $row['quantity'],
+ 'amazon_sku' => $row['amazon_sku'],
+ 'amazon_quantity' => $row['amazon_quantity'],
+ 'amazon_price' => number_format($row['amazon_price'], 2, '.', ''),
+ 'asin' => $row['asin'],
+ 'combination' => implode(' > ', $combinations),
+ );
+ }
+
+ return $products;
+ }
+
+ public function getAsinLink($asin, $marketplace) {
+ switch ($marketplace) {
+ case 'uk':
+ $link = 'https://www.amazon.co.uk/dp/' . $asin . '/';
+ break;
+ case 'de':
+ $link = 'https://www.amazon.de/dp/' . $asin . '/';
+ break;
+ case 'fr':
+ $link = 'https://www.amazon.fr/dp/' . $asin . '/';
+ break;
+ case 'it':
+ $link = 'https://www.amazon.it/dp/' . $asin . '/';
+ break;
+ case 'es':
+ $link = 'https://www.amazon.es/dp/' . $asin . '/';
+ break;
+ }
+
+ return $link;
+ }
+}
diff --git a/public/admin/model/extension/openbay/amazon_listing.php b/public/admin/model/extension/openbay/amazon_listing.php
new file mode 100644
index 0000000..a4ad286
--- /dev/null
+++ b/public/admin/model/extension/openbay/amazon_listing.php
@@ -0,0 +1,231 @@
+<?php
+class ModelExtensionOpenBayAmazonListing extends Model {
+ private $tabs = array();
+
+ public function search($search_string, $marketplace) {
+ $search_params = array(
+ 'search_string' => $search_string,
+ 'marketplace' => $marketplace,
+ );
+
+ $results = json_decode($this->openbay->amazon->call('productv3/search', $search_params), 1);
+
+ $products = array();
+
+ if (!empty($results)) {
+ foreach ($results['Products'] as $result) {
+ if ($result['price']['amount'] && $result['price']['currency']) {
+ $price = $result['price']['amount'] . ' ' . $result['price']['currency'];
+ } else {
+ $price = '-';
+ }
+
+ $link = '';
+
+ switch ($marketplace) {
+ case 'uk':
+ $link = 'https://www.amazon.co.uk/dp/' . $result['asin'] . '/';
+ break;
+ case 'de':
+ $link = 'https://www.amazon.de/dp/' . $result['asin'] . '/';
+ break;
+ case 'fr':
+ $link = 'https://www.amazon.fr/dp/' . $result['asin'] . '/';
+ break;
+ case 'it':
+ $link = 'https://www.amazon.it/dp/' . $result['asin'] . '/';
+ break;
+ case 'es':
+ $link = 'https://www.amazon.es/dp/' . $result['asin'] . '/';
+ break;
+ }
+
+ $products[] = array(
+ 'name' => $result['name'],
+ 'asin' => $result['asin'],
+ 'image' => $result['image'],
+ 'price' => $price,
+ 'link' => $link,
+ );
+ }
+ }
+
+ return $products;
+ }
+
+ public function getProductByAsin($asin, $market) {
+ $data = array(
+ 'asin' => $asin,
+ 'marketplace' => $market,
+ );
+
+ $results = json_decode($this->openbay->amazon->call('productv3/getProduct', $data), 1);
+
+ return $results;
+ }
+
+ public function getBestPrice($asin, $condition, $marketplace) {
+ $search_params = array(
+ 'asin' => $asin,
+ 'condition' => $condition,
+ 'marketplace' => $marketplace,
+ );
+
+ $best_price = '';
+
+ $result = json_decode($this->openbay->amazon->call('productv3/getPrice', $search_params), 1);
+
+ if (isset($result['Price']['Amount']) && $result['Price']['Currency'] && $this->currency->has($result['Price']['Currency'])) {
+ $best_price['amount'] = number_format($this->currency->convert($result['Price']['Amount'], $result['Price']['Currency'], $this->config->get('config_currency')), 2, '.', '');
+ $best_price['shipping'] = number_format($this->currency->convert($result['Price']['Shipping'], $result['Price']['Currency'], $this->config->get('config_currency')), 2, '.', '');
+ $best_price['currency'] = $result['Price']['Currency'];
+ }
+
+ return $best_price;
+ }
+
+ public function simpleListing($data) {
+ $request = array(
+ 'asin' => $data['asin'],
+ 'sku' => $data['sku'],
+ 'quantity' => $data['quantity'],
+ 'price' => $data['price'],
+ 'sale' => array(
+ 'price' => $data['sale_price'],
+ 'from' => $data['sale_from'],
+ 'to' => $data['sale_to'],
+ ),
+ 'condition' => $data['condition'],
+ 'condition_note' => $data['condition_note'],
+ 'start_selling' => $data['start_selling'],
+ 'restock_date' => $data['restock_date'],
+ 'marketplace' => $data['marketplace'],
+ 'response_url' => HTTPS_CATALOG . 'index.php?route=extension/openbay/amazon/listing',
+ 'product_id' => $data['product_id'],
+ );
+
+ $response = $this->openbay->amazon->call('productv3/simpleListing', $request);
+ $response = json_decode($response);
+
+ if (empty($response)) {
+ return array(
+ 'status' => 0,
+ 'message' => 'Problem connecting OpenBay: API'
+ );
+ }
+
+ $response = (array)$response;
+
+ if (($response['status'] === 1)) {
+ $this->db->query("
+ REPLACE INTO `" . DB_PREFIX . "amazon_product`
+ SET `product_id` = " . (int)$data['product_id'] . ",
+ `status` = 'uploaded',
+ `marketplaces` = '" . $this->db->escape($data['marketplace']) . "',
+ `version` = 3,
+ `var` = ''
+ ");
+ }
+
+ return $response;
+ }
+
+ public function getBrowseNodes($request) {
+ return $this->openbay->amazon->call('productv3/getBrowseNodes', $request);
+ }
+
+ public function doBulkSearch($search_data) {
+ foreach ($search_data as $products) {
+ foreach ($products as $product) {
+ $this->db->query("
+ REPLACE INTO " . DB_PREFIX . "amazon_product_search (product_id, `status`, marketplace)
+ VALUES (" . (int)$product['product_id'] . ", 'searching', '" . $this->db->escape($product['marketplace']) . "')");
+ }
+ }
+
+ $request_data = array(
+ 'search' => $search_data,
+ 'response_url' => HTTPS_CATALOG . 'index.php?route=extension/openbay/amazon/search'
+ );
+
+ $this->openbay->amazon->call('productv3/bulkSearch', $request_data);
+ }
+
+ public function deleteSearchResults($marketplace, $product_ids) {
+ $imploded_ids = array();
+
+ foreach ($product_ids as $product_id) {
+ $imploded_ids[] = (int)$product_id;
+ }
+
+ $imploded_ids = implode(',', $imploded_ids);
+
+ $this->db->query("
+ DELETE FROM " . DB_PREFIX . "amazon_product_search
+ WHERE marketplace = '" . $this->db->escape($marketplace) . "' AND product_id IN ($imploded_ids)
+ ");
+ }
+
+ public function doBulkListing($data) {
+ $this->load->model('catalog/product');
+ $request = array();
+
+ $marketplace_mapping = array(
+ 'uk' => 'A1F83G8C2ARO7P',
+ 'de' => 'A1PA6795UKMFR9',
+ 'fr' => 'A13V1IB3VIYZZH',
+ 'it' => 'APJ6JRA9NG5V4',
+ 'es' => 'A1RKKUPIHCS9HS',
+ );
+
+ foreach($data['products'] as $product_id => $asin) {
+ $product = $this->model_catalog_product->getProduct($product_id);
+
+ if ($product) {
+ $price = $product['price'];
+
+ if ($this->config->get('openbay_amazon_listing_tax_added') && $this->config->get('openbay_amazon_listing_tax_added') > 0) {
+ $price += $price * ($this->config->get('openbay_amazon_listing_tax_added') / 100);
+ }
+
+ $request[] = array(
+ 'asin' => $asin,
+ 'sku' => $product['sku'],
+ 'quantity' => $product['quantity'],
+ 'price' => number_format($price, 2, '.', ''),
+ 'sale' => array(),
+ 'condition' => (isset($data['condition']) ? $data['condition'] : ''),
+ 'condition_note' => (isset($data['condition_note']) ? $data['condition_note'] : ''),
+ 'start_selling' => (isset($data['start_selling']) ? $data['start_selling'] : ''),
+ 'restock_date' => '',
+ 'marketplace' => $data['marketplace'],
+ 'response_url' => HTTPS_CATALOG . 'index.php?route=extension/openbay/amazon/listing',
+ 'product_id' => $product['product_id'],
+ );
+ }
+ }
+
+ if ($request) {
+ $response = $this->openbay->amazon->call('productv3/bulkListing', $request);
+
+ $response = json_decode($response, 1);
+
+ if ($response['status'] == 1) {
+ foreach ($request as $product) {
+ $this->db->query("
+ REPLACE INTO `" . DB_PREFIX . "amazon_product`
+ SET `product_id` = " . (int)$product['product_id'] . ",
+ `status` = 'uploaded',
+ `marketplaces` = '" . $this->db->escape($data['marketplace']) . "',
+ `version` = 3,
+ `var` = ''
+ ");
+ }
+
+ return true;
+ }
+ }
+
+ return false;
+ }
+} \ No newline at end of file
diff --git a/public/admin/model/extension/openbay/amazonus.php b/public/admin/model/extension/openbay/amazonus.php
new file mode 100644
index 0000000..ccc4a78
--- /dev/null
+++ b/public/admin/model/extension/openbay/amazonus.php
@@ -0,0 +1,720 @@
+<?php
+class ModelExtensionOpenBayAmazonus extends Model {
+ public function install() {
+ $this->load->model('setting/event');
+
+ $this->model_setting_event->addEvent('openbay_amazonus_add_order', 'catalog/model/checkout/order/addOrderHistory/after', 'extension/openbay/amazonus/eventAddOrderHistory');
+
+ $this->db->query("
+ CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "amazonus_order` (
+ `order_id` int(11) NOT NULL ,
+ `amazonus_order_id` char(19) NOT NULL ,
+ `courier_id` varchar(255) NOT NULL ,
+ `courier_other` tinyint(1) NOT NULL,
+ `tracking_no` varchar(255) NOT NULL ,
+ PRIMARY KEY (`order_id`, `amazonus_order_id`)
+ ) DEFAULT COLLATE=utf8_general_ci;");
+
+ $this->db->query("
+ CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "amazonus_order_product` (
+ `order_product_id` int(11) NOT NULL ,
+ `amazonus_order_item_id` varchar(255) NOT NULL,
+ PRIMARY KEY(`order_product_id`, `amazonus_order_item_id`)
+ );");
+
+ $this->db->query("
+ CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "amazonus_product_unshipped` (
+ `order_id` int(11) NOT NULL,
+ `product_id` int(11) NOT NULL,
+ `quantity` int(11) NOT NULL DEFAULT '0',
+ PRIMARY KEY (`order_id`,`product_id`)
+ ) DEFAULT COLLATE=utf8_general_ci;");
+
+ $this->db->query("
+ CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "amazonus_product` (
+ `version` int(11) NOT NULL DEFAULT 2,
+ `product_id` int(11) NOT NULL ,
+ `category` varchar(255) NOT NULL ,
+ `sku` varchar(255) NOT NULL ,
+ `insertion_id` varchar(255) NOT NULL ,
+ `data` text NOT NULL ,
+ `status` enum('saved','uploaded','ok','error') NOT NULL ,
+ `price` decimal(15,4) NOT NULL COMMENT 'Price on Amazonus' ,
+ `var` char(100) NOT NULL DEFAULT '',
+ `marketplaces` text NOT NULL ,
+ `messages` text NOT NULL,
+ PRIMARY KEY (`product_id`, `var`)
+ );");
+
+ $this->db->query("
+ CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "amazonus_product_error` (
+ `error_id` int(11) NOT NULL AUTO_INCREMENT,
+ `sku` varchar(255) NOT NULL ,
+ `insertion_id` varchar(255) NOT NULL ,
+ `error_code` int(11) NOT NULL ,
+ `message` text NOT NULL ,
+ PRIMARY KEY (`error_id`)
+ );");
+
+ $this->db->query("
+ CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "amazonus_product_link` (
+ `id` int(11) NOT NULL AUTO_INCREMENT,
+ `amazonus_sku` varchar(255) NOT NULL,
+ `var` char(100) NOT NULL DEFAULT '',
+ `product_id` int(11) NOT NULL,
+ PRIMARY KEY (`id`)
+ ) DEFAULT COLLATE=utf8_general_ci;");
+
+ $this->db->query("
+ CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "amazonus_product_search` (
+ `product_id` int(11) NOT NULL,
+ `status` enum('searching','finished') NOT NULL,
+ `matches` int(11) DEFAULT NULL,
+ `data` text,
+ PRIMARY KEY (`product_id`)
+ ) DEFAULT COLLATE=utf8_general_ci;");
+
+ $this->db->query("
+ CREATE TABLE IF NOT EXISTS`" . DB_PREFIX . "amazonus_listing_report` (
+ `sku` varchar(255) NOT NULL,
+ `quantity` int(10) unsigned NOT NULL,
+ `asin` varchar(255) NOT NULL,
+ `price` decimal(10,4) NOT NULL,
+ PRIMARY KEY (`sku`)
+ ) DEFAULT COLLATE=utf8_general_ci;
+ ");
+ }
+
+ public function uninstall() {
+ $this->db->query("DROP TABLE IF EXISTS `" . DB_PREFIX . "amazonus_order`");
+ $this->db->query("DROP TABLE IF EXISTS `" . DB_PREFIX . "amazonus_order_product`");
+ $this->db->query("DROP TABLE IF EXISTS `" . DB_PREFIX . "amazonus_product2`");
+ $this->db->query("DROP TABLE IF EXISTS `" . DB_PREFIX . "amazonus_product`");
+ $this->db->query("DROP TABLE IF EXISTS `" . DB_PREFIX . "amazonus_product_link`");
+ $this->db->query("DROP TABLE IF EXISTS `" . DB_PREFIX . "amazonus_product_unshipped`");
+ $this->db->query("DROP TABLE IF EXISTS `" . DB_PREFIX . "amazonus_product_error`");
+ $this->db->query("DROP TABLE IF EXISTS `" . DB_PREFIX . "amazonus_process`");
+ $this->db->query("DROP TABLE IF EXISTS `" . DB_PREFIX . "amazonus_product_search`");
+ $this->db->query("DROP TABLE IF EXISTS `" . DB_PREFIX . "amazonus_listing_report`");
+
+ $this->db->query("DELETE FROM `" . DB_PREFIX . "setting` WHERE `code` = 'openbay_amazonus'");
+
+ $this->load->model('setting/event');
+ $this->model_setting_event->deleteEventByCode('openbay_amazonus_add_order');
+ }
+
+ public function patch() {
+ if ($this->config->get('openbay_amazonus_status') == 1) {
+
+ }
+ }
+
+ public function verifyConfig($data) {
+ $log = new Log('amazonus.log');
+
+ $request_xml = new SimpleXMLElement("<Request></Request>");
+ $request_xml->addChild("ResponseURL", HTTP_CATALOG . 'index.php?route=extension/openbay/amazonus/order');
+
+ $response = $this->openbay->amazonus->call('order/scheduleOrders', $request_xml->asXML(), false);
+
+ libxml_use_internal_errors(true);
+ $response_xml = simplexml_load_string($response);
+ libxml_use_internal_errors(false);
+
+ if ($response_xml && $response_xml->Status == '0') {
+ $log->write('Scheduling orders call was successful');
+ return true;
+ }
+
+ $log->write('Failed to schedule orders. Response: ' . $response);
+
+ return false;
+ }
+
+ public function saveProduct($product_id, $data_array) {
+ if (isset($data_array['fields']['item-price'])) {
+ $price = $data_array['fields']['item-price'];
+ } else if (isset($data_array['fields']['price'])) {
+ $price = $data_array['fields']['price'];
+ } else if (isset($data_array['fields']['StandardPrice'])) {
+ $price = $data_array['fields']['StandardPrice'];
+ } else {
+ $price = 0;
+ }
+
+ $category = (isset($data_array['category'])) ? $data_array['category'] : "";
+ $sku = (isset($data_array['fields']['sku'])) ? $data_array['fields']['sku'] : "";
+ if (isset($data_array['fields']['sku'])) {
+ $sku = $data_array['fields']['sku'];
+ } else if (isset($data_array['fields']['SKU'])) {
+ $sku = $data_array['fields']['SKU'];
+ }
+
+ $var = isset($data_array['optionVar']) ? $data_array['optionVar'] : '';
+
+ $marketplaces = isset($data_array['marketplace_ids']) ? serialize($data_array['marketplace_ids']) : serialize(array());
+
+ $data_encoded = json_encode(array('fields' => $data_array['fields']));
+
+ $this->db->query("
+ REPLACE INTO `" . DB_PREFIX . "amazonus_product`
+ SET `product_id` = '" . (int)$product_id . "',
+ `sku` = '" . $this->db->escape($sku) . "',
+ `category` = '" . $this->db->escape($category) . "',
+ `data` = '" . $this->db->escape($data_encoded) . "',
+ `status` = 'saved',
+ `insertion_id` = '',
+ `price` = '" . $price . "',
+ `var` = '" . $this->db->escape($var) . "',
+ `marketplaces` = '" . $this->db->escape($marketplaces) . "'");
+ }
+
+ public function deleteSaved($product_id, $var = '') {
+ $this->db->query("DELETE FROM `" . DB_PREFIX . "amazonus_product`
+ WHERE `product_id` = '" . (int)$product_id . "' AND `var` = '" . $this->db->escape($var) . "'");
+ }
+
+ public function getSavedProducts() {
+ return $this->db->query("
+ SELECT `ap`.`status`, `ap`.`product_id`, `ap`.`sku` as `amazonus_sku`, `pd`.`name` as `product_name`, `p`.`model` as `product_model`, `p`.`sku` as `product_sku`, `ap`.`var` as `var`
+ FROM `" . DB_PREFIX . "amazonus_product` as `ap`
+ LEFT JOIN `" . DB_PREFIX . "product_description` as `pd`
+ ON `ap`.`product_id` = `pd`.`product_id`
+ LEFT JOIN `" . DB_PREFIX . "product` as `p`
+ ON `ap`.`product_id` = `p`.`product_id`
+ WHERE `ap`.`status` = 'saved'
+ AND `pd`.`language_id` = '" . (int)$this->config->get('config_language_id') . "'")->rows;
+ }
+
+ public function getSavedProductsData() {
+ return $this->db->query("
+ SELECT * FROM `" . DB_PREFIX . "amazonus_product`
+ WHERE `status` = 'saved' AND `version` = 2")->rows;
+ }
+
+ public function getProduct($product_id, $var = '') {
+ return $this->db->query("
+ SELECT * FROM `" . DB_PREFIX . "amazonus_product`
+ WHERE `product_id` = '" . (int)$product_id . "' AND `var` = '" . $this->db->escape($var) . "' AND `version` = 2")->row;
+ }
+
+ public function getProductCategory($product_id, $var = '') {
+ $row = $this->db->query("
+ SELECT `category` FROM `" . DB_PREFIX . "amazonus_product`
+ WHERE `product_id` = '" . (int)$product_id . "' AND `var` = '" . $this->db->escape($var) . "' AND `version` = 2")->row;
+ if (isset($row['category'])) {
+ return $row['category'];
+ } else {
+ return "";
+ }
+ }
+
+ public function setProductUploaded($product_id, $insertion_id, $var = '') {
+ $this->db->query(
+ "UPDATE `" . DB_PREFIX . "amazonus_product`
+ SET `status` = 'uploaded', `insertion_id` = '" . $this->db->escape($insertion_id) . "'
+ WHERE `product_id` = '" . (int)$product_id . "' AND `var` = '" . $this->db->escape($var) . "' AND `version` = 2");
+ }
+
+ public function resetUploaded($insertion_id) {
+ $this->db->query(
+ "UPDATE `" . DB_PREFIX . "amazonus_product`
+ SET `status` = 'saved', `insertion_id` = ''
+ WHERE `insertion_id` = '" . $this->db->escape($insertion_id) . "' AND `version` = 2");
+ }
+
+ public function getProductStatus($product_id) {
+
+ $rows_uploaded = $this->db->query("
+ SELECT COUNT(*) count
+ FROM `" . DB_PREFIX . "amazonus_product`
+ WHERE `product_id` = '" . (int)$product_id . "' AND status = 'uploaded'")->row;
+ $rows_uploaded = $rows_uploaded['count'];
+
+ $rows_ok = $this->db->query("
+ SELECT COUNT(*) count
+ FROM `" . DB_PREFIX . "amazonus_product`
+ WHERE `product_id` = '" . (int)$product_id . "' AND status = 'ok'")->row;
+ $rows_ok = $rows_ok['count'];
+
+ $rows_error = $this->db->query("
+ SELECT COUNT(*) count
+ FROM `" . DB_PREFIX . "amazonus_product`
+ WHERE `product_id` = '" . (int)$product_id . "' AND status = 'error'")->row;
+ $rows_error = $rows_error['count'];
+
+ $rows_saved = $this->db->query("
+ SELECT COUNT(*) count
+ FROM `" . DB_PREFIX . "amazonus_product`
+ WHERE `product_id` = '" . (int)$product_id . "' AND status = 'saved'")->row;
+ $rows_saved = $rows_saved['count'];
+
+ $rows_total = $rows_uploaded + $rows_ok + $rows_error + $rows_saved;
+
+ $links = $this->db->query("
+ SELECT COUNT(*) as count
+ FROM `" . DB_PREFIX . "amazonus_product_link`
+ WHERE `product_id` = '" . (int)$product_id . "'")->row;
+ $links = $links['count'];
+
+ if ($rows_total === 0 && $links > 0) {
+ return 'linked';
+ } else if ($rows_total == 0) {
+ return false;
+ }
+
+ if ($rows_uploaded > 0) {
+ return 'processing';
+ }
+
+ if ($rows_uploaded == 0 && $rows_ok > 0 && $rows_error == 0) {
+ return 'ok';
+ }
+
+ if ($rows_saved > 0) {
+ return 'saved';
+ }
+
+ if ($rows_uploaded == 0 && $rows_error > 0 && $rows_ok == 0) {
+ $quick = $this->db->query("SELECT * FROM `" . DB_PREFIX . "amazonus_product` WHERE `product_id` = " . (int)$product_id . " AND `version` = 3")->row;
+
+ if ($quick) {
+ return 'error_quick';
+ } else {
+ return 'error_advanced';
+ }
+ } else {
+ return 'error_few';
+ }
+
+ return false;
+ }
+
+ public function getProductErrors($product_id, $version = 2) {
+ if ($version == 3) {
+ $message_row = $this->db->query("
+ SELECT `messages` FROM `" . DB_PREFIX . "amazonus_product`
+ WHERE `product_id` = '" . (int)$product_id . "' AND `version` = 3")->row;
+
+ return json_decode($message_row['messages']);
+ }
+
+ $result = array();
+
+ $insertion_rows = $this->db->query("SELECT `sku`, `insertion_id` FROM `" . DB_PREFIX . "amazonus_product` WHERE `product_id` = '" . (int)$product_id . "' AND `version` = 2")->rows;
+
+ if (!empty($insertion_rows)) {
+ foreach($insertion_rows as $insertion_row) {
+ $error_rows = $this->db->query("SELECT * FROM `" . DB_PREFIX . "amazonus_product_error` WHERE `sku` = '" . $this->db->escape($insertion_row['sku']) . "' AND `insertion_id` = '" . $this->db->escape($insertion_row['insertion_id']) . "'")->rows;
+
+ foreach($error_rows as $error_row) {
+ $result[] = $error_row;
+ }
+ }
+ }
+ return $result;
+ }
+
+ public function getProductsWithErrors() {
+ return $this->db->query("
+ SELECT `product_id`, `sku` FROM `" . DB_PREFIX . "amazonus_product`
+ WHERE `status` = 'error' AND `version` = 2")->rows;
+ }
+
+ public function deleteProduct($product_id) {
+ $this->db->query(
+ "DELETE FROM `" . DB_PREFIX . "amazonus_product`
+ WHERE `product_id` = '" . (int)$product_id . "'");
+ }
+
+ public function linkProduct($amazonus_sku, $product_id, $var = '') {
+ $count = $this->db->query("SELECT COUNT(*) as `count` FROM `" . DB_PREFIX . "amazonus_product_link` WHERE `product_id` = '" . (int)$product_id . "' AND `amazonus_sku` = '" . $this->db->escape($amazonus_sku) . "' AND `var` = '" . $this->db->escape($var) . "' LIMIT 1")->row;
+
+ if ($count['count'] == 0) {
+ $this->db->query("INSERT INTO `" . DB_PREFIX . "amazonus_product_link` SET `product_id` = '" . (int)$product_id . "', `amazonus_sku` = '" . $this->db->escape($amazonus_sku) . "', `var` = '" . $this->db->escape($var) . "'");
+ }
+ }
+
+ public function removeProductLink($amazonus_sku) {
+ $this->db->query(
+ "DELETE FROM `" . DB_PREFIX . "amazonus_product_link`
+ WHERE `amazonus_sku` = '" . $this->db->escape($amazonus_sku) . "'");
+ }
+
+ public function removeAdvancedErrors($product_id) {
+ $product_rows = $this->db->query("
+ SELECT `insertion_id` FROM `" . DB_PREFIX . "amazonus_product`
+ WHERE `product_id` = '" . (int)$product_id . "' AND `version` = 2")->rows;
+
+ foreach ($product_rows as $product) {
+ $this->db->query(
+ "DELETE FROM `" . DB_PREFIX . "amazonus_product_error`
+ WHERE `insertion_id` = '" . $this->db->escape($product['insertion_id']) . "'");
+ }
+
+ $this->db->query(
+ "UPDATE `" . DB_PREFIX . "amazonus_product`
+ SET `status` = 'saved', `insertion_id` = ''
+ WHERE `product_id` = '" . (int)$product_id . "' AND `status` = 'error' AND `version` = 2");
+ }
+
+ public function getProductLinks($product_id = 'all') {
+ $query = "SELECT `apl`.`amazonus_sku`, `apl`.`product_id`, `pd`.`name` as `product_name`, `p`.`model`, `p`.`sku`, `apl`.`var`, '' as `combination`
+ FROM `" . DB_PREFIX . "amazonus_product_link` as `apl`
+ LEFT JOIN `" . DB_PREFIX . "product_description` as `pd`
+ ON `apl`.`product_id` = `pd`.`product_id`
+ LEFT JOIN `" . DB_PREFIX . "product` as `p`
+ ON `apl`.`product_id` = `p`.`product_id`";
+ if ($product_id != 'all') {
+ $query .= " WHERE `apl`.`product_id` = '" . (int)$product_id . "' AND `pd`.`language_id` = '" . (int)$this->config->get('config_language_id') . "'";
+ } else {
+ $query .= "WHERE `pd`.`language_id` = '" . (int)$this->config->get('config_language_id') . "'";
+ }
+
+ $product_links = $this->db->query($query)->rows;
+
+ if ($this->openbay->addonLoad('openstock')) {
+ $this->load->model('extension/module/openstock');
+ $this->load->model('tool/image');
+
+ foreach ($product_links as $key => $product_link) {
+ $variants = $this->model_setting_module_openstock->getVariants($product_link['product_id']);
+
+ if (!empty($variants)) {
+ foreach($variants as $variant) {
+ if ($variant['sku'] == $product_link['var']) {
+ $product_links[$key]['combination'] = $variant['combination'];
+ break;
+ }
+ }
+ }
+ }
+
+ return $product_links;
+ } else {
+ return $product_links;
+ }
+ }
+
+ public function getUnlinkedProducts() {
+ if ($this->openbay->addonLoad('openstock')) {
+ $rows = $this->db->query("
+ SELECT `p`.`product_id`, `p`.`model`, `p`.`sku`, `pd`.`name` as `product_name`, '' as `var`, '' as `combination`, `p`.`has_option`
+ FROM `" . DB_PREFIX . "product` as `p`
+ LEFT JOIN `" . DB_PREFIX . "product_description` as `pd`
+ ON `p`.`product_id` = `pd`.`product_id`
+ AND `pd`.`language_id` = '" . (int)$this->config->get('config_language_id') . "'")->rows;
+
+ $result = array();
+ $this->load->model('extension/module/openstock');
+ $this->load->model('tool/image');
+ foreach($rows as $row) {
+ if ($row['has_option'] == 1) {
+ $stock_opts = $this->model_setting_module_openstock->getVariants($row['product_id']);
+ foreach($stock_opts as $opt) {
+ if ($this->productLinkExists($row['product_id'], $opt['sku'])) {
+ continue;
+ }
+ $row['sku'] = $opt['sku'];
+ $row['combination'] = $opt['combination'];
+ $row['sku'] = $opt['sku'];
+ $result[] = $row;
+ }
+ } else {
+ if (!$this->productLinkExists($row['product_id'], $row['sku'])) {
+ $result[] = $row;
+ }
+ }
+ }
+ } else {
+ $result = $this->db->query("
+ SELECT `p`.`product_id`, `p`.`model`, `p`.`sku`, `pd`.`name` as `product_name`, '' as `var`, '' as `combination`
+ FROM `" . DB_PREFIX . "product` as `p`
+ LEFT JOIN `" . DB_PREFIX . "product_description` as `pd`
+ ON `p`.`product_id` = `pd`.`product_id`
+ LEFT JOIN `" . DB_PREFIX . "amazonus_product_link` as `apl`
+ ON `apl`.`product_id` = `p`.`product_id`
+ WHERE `apl`.`amazonus_sku` IS NULL
+ AND `pd`.`language_id` = '" . (int)$this->config->get('config_language_id') . "'")->rows;
+ }
+
+ return $result;
+ }
+
+ private function productLinkExists($product_id, $var) {
+ $link = $this->db->query("SELECT * FROM `" . DB_PREFIX . "amazonus_product_link` WHERE `product_id` = " . (int)$product_id . " AND var = '" . $this->db->escape($var) . "'")->row;
+
+ if (empty($link)) {
+ return false;
+ } else {
+ return true;
+ }
+ }
+
+ public function getOrderStatusString($order_id) {
+ $row = $this->db->query("
+ SELECT `s`.`key`
+ FROM `" . DB_PREFIX . "order` `o`
+ JOIN `" . DB_PREFIX . "setting` `s` ON `o`.`order_id` = " . (int)$order_id . " AND `s`.`value` = `o`.`order_status_id`
+ WHERE `s`.`key` = 'openbay_amazonus_order_status_shipped' OR `s`.`key` = 'openbay_amazonus_order_status_canceled'
+ LIMIT 1")->row;
+
+ if (!isset($row['key']) || empty($row['key'])) {
+ return null;
+ }
+
+ $key = $row['key'];
+
+ switch ($key) {
+ case 'openbay_amazonus_order_status_shipped':
+ $order_status = 'shipped';
+ break;
+ case 'openbay_amazonus_order_status_canceled':
+ $order_status = 'canceled';
+ break;
+
+ default:
+ $order_status = null;
+ break;
+ }
+
+ return $order_status;
+ }
+
+ public function updateAmazonusOrderTracking($order_id, $courier_id, $courier_from_list, $tracking_no) {
+ $this->db->query("UPDATE `" . DB_PREFIX . "amazonus_order` SET `courier_id` = '" . $this->db->escape($courier_id) . "', `courier_other` = " . (int)!$courier_from_list . ", `tracking_no` = '" . $this->db->escape($tracking_no) . "' WHERE `order_id` = " . (int)$order_id . "");
+ }
+
+ public function getAmazonusOrderId($order_id) {
+ $row = $this->db->query("
+ SELECT `amazonus_order_id`
+ FROM `" . DB_PREFIX . "amazonus_order`
+ WHERE `order_id` = " . (int)$order_id . "
+ LIMIT 1")->row;
+
+ if (isset($row['amazonus_order_id']) && !empty($row['amazonus_order_id'])) {
+ return $row['amazonus_order_id'];
+ }
+
+ return null;
+ }
+
+ public function getAmazonusOrderedProducts($order_id) {
+ return $this->db->query("
+ SELECT `aop`.`amazonus_order_item_id`, `op`.`quantity`
+ FROM `" . DB_PREFIX . "amazonus_order_product` `aop`
+ JOIN `" . DB_PREFIX . "order_product` `op` ON `op`.`order_product_id` = `aop`.`order_product_id`
+ AND `op`.`order_id` = " . (int)$order_id)->rows;
+ }
+
+ public function getProductQuantity($product_id, $var = '') {
+ $result = null;
+
+ if ($var !== '' && $this->openbay->addonLoad('openstock')) {
+ $this->load->model('tool/image');
+ $this->load->model('extension/module/openstock');
+ $option_stocks = $this->model_setting_module_openstock->getVariants($product_id);
+
+ $option = null;
+ foreach ($option_stocks as $option_iterator) {
+ if ($option_iterator['sku'] === $var) {
+ $option = $option_iterator;
+ break;
+ }
+ }
+
+ if ($option != null) {
+ $result = $option['stock'];
+ }
+ } else {
+ $this->load->model('catalog/product');
+ $product_info = $this->model_catalog_product->getProduct($product_id);
+
+ if (isset($product_info['quantity'])) {
+ $result = $product_info['quantity'];
+ }
+ }
+ return $result;
+ }
+
+ public function getProductSearchTotal($data = array()) {
+ $sql = "
+ SELECT COUNT(*) AS product_total
+ FROM " . DB_PREFIX . "product p
+ LEFT JOIN " . DB_PREFIX . "amazonus_product_search aps ON p.product_id = aps.product_id
+ LEFT JOIN " . DB_PREFIX . "amazonus_product_link apl ON p.product_id = apl.product_id
+ LEFT JOIN " . DB_PREFIX . "amazonus_product ap ON p.product_id = ap.product_id
+ WHERE apl.product_id IS NULL AND ap.product_id IS NULL ";
+
+ if (!empty($data['status'])) {
+ $sql .= " AND aps.status = '" . $this->db->escape($data['status']) . "'";
+ }
+
+ return $this->db->query($sql)->row['product_total'];
+ }
+
+ public function getProductSearch($data = array()) {
+ $sql = "
+ SELECT p.product_id, aps.status, aps.data, aps.matches
+ FROM " . DB_PREFIX . "product p
+ LEFT JOIN " . DB_PREFIX . "amazonus_product_search aps ON p.product_id = aps.product_id
+ LEFT JOIN " . DB_PREFIX . "amazonus_product_link apl ON p.product_id = apl.product_id
+ LEFT JOIN " . DB_PREFIX . "amazonus_product ap ON p.product_id = ap.product_id
+ WHERE apl.product_id IS NULL AND ap.product_id IS NULL ";
+
+ if (!empty($data['status'])) {
+ $sql .= " AND aps.status = '" . $this->db->escape($data['status']) . "'";
+ }
+
+ $sql .= " LIMIT " . (int)$data['start'] . ", " . (int)$data['limit'];
+
+ $results = array();
+
+ $rows = $this->db->query($sql)->rows;
+
+ foreach ($rows as $row) {
+ $results[] = array(
+ 'product_id' => $row['product_id'],
+ 'status' => $row['status'],
+ 'matches' => $row['matches'],
+ 'data' => json_decode($row['data'], 1),
+ );
+ }
+
+ return $results;
+ }
+
+ public function updateAmazonSkusQuantities($skus) {
+ $sku_array = array();
+
+ foreach ($skus as $sku) {
+ $sku_array[] = "'" . $this->db->escape($sku) . "'";
+ }
+
+ if ($this->openbay->addonLoad('openstock')) {
+ $rows = $this->db->query("
+ SELECT apl.amazonus_sku, if (por.product_id IS NULL, p.quantity, por.stock) AS 'quantity'
+ FROM " . DB_PREFIX . "amazonus_product_link apl
+ JOIN " . DB_PREFIX . "product p ON apl.product_id = p.product_id
+ LEFT JOIN " . DB_PREFIX . "product_option_variant por ON apl.product_id = por.product_id AND apl.var = por.sku
+ WHERE apl.amazonus_sku IN (" . implode(',', $sku_array) . ")
+ ")->rows;
+ } else {
+ $rows = $this->db->query("
+ SELECT apl.amazonus_sku, p.quantity
+ FROM " . DB_PREFIX . "amazonus_product_link apl
+ JOIN " . DB_PREFIX . "product p ON apl.product_id = p.product_id
+ WHERE apl.amazonus_sku IN (" . implode(',', $sku_array) . ")
+ ")->rows;
+ }
+
+ $return = array();
+
+ foreach ($rows as $row) {
+ $return[$row['amazonus_sku']] = $row['quantity'];
+ }
+
+ $this->openbay->amazonus->updateQuantities($return);
+ }
+
+ public function getTotalUnlinkedItemsFromReport() {
+ if ($this->openbay->addonLoad('openstock')) {
+ $result = $this->db->query("
+ SELECT alr.sku AS 'amazon_sku', alr.quantity AS 'amazon_quantity', alr.asin, alr.price AS 'amazon_price', oc_sku.product_id, pd.name, oc_sku.sku, oc_sku.var, oc_sku.quantity, oc_sku.pov_id
+ FROM " . DB_PREFIX . "amazonus_listing_report alr
+ LEFT JOIN (
+ SELECT p.product_id, if (por.product_id IS NULL, p.sku, por.sku) AS 'sku', if (por.product_id IS NULL, NULL, por.sku) AS 'var', if (por.product_id IS NULL, p.quantity, por.stock) AS 'quantity', por.product_option_variant_id AS pov_id
+ FROM " . DB_PREFIX . "product p
+ LEFT JOIN " . DB_PREFIX . "product_option_variant por USING(product_id)
+ ) AS oc_sku ON alr.sku = oc_sku.sku
+ LEFT JOIN " . DB_PREFIX . "amazonus_product_link apl ON (oc_sku.var IS NULL AND oc_sku.product_id = apl.product_id) OR (oc_sku.var IS NOT NULL AND oc_sku.product_id = apl.product_id AND oc_sku.var = apl.var)
+ LEFT JOIN " . DB_PREFIX . "product_description pd ON oc_sku.product_id = pd.product_id AND pd.language_id = " . (int)$this->config->get('config_language_id') . "
+ WHERE apl.product_id IS NULL
+ ");
+ } else {
+ $result = $this->db->query("
+ SELECT alr.sku AS 'amazon_sku', alr.quantity AS 'amazon_quantity', alr.asin, alr.price AS 'amazon_price', oc_sku.product_id, pd.name, oc_sku.sku, oc_sku.var, oc_sku.quantity, '' AS combination
+ FROM " . DB_PREFIX . "amazonus_listing_report alr
+ LEFT JOIN (
+ SELECT p.product_id, p.sku, NULL AS 'var', p.quantity
+ FROM " . DB_PREFIX . "product p
+ ) AS oc_sku ON alr.sku = oc_sku.sku
+ LEFT JOIN " . DB_PREFIX . "amazonus_product_link apl ON (oc_sku.var IS NULL AND oc_sku.product_id = apl.product_id) OR (oc_sku.var IS NOT NULL AND oc_sku.product_id = apl.product_id AND oc_sku.var = apl.var)
+ LEFT JOIN " . DB_PREFIX . "product_description pd ON oc_sku.product_id = pd.product_id AND pd.language_id = " . (int)$this->config->get('config_language_id') . "
+ WHERE apl.product_id IS NULL
+ ORDER BY alr.sku
+ ");
+ }
+
+ return (int)$result->num_rows;
+ }
+
+ public function getUnlinkedItemsFromReport($limit = 100, $page = 1) {
+ $start = $limit * ($page - 1);
+
+ if ($this->openbay->addonLoad('openstock')) {
+ $this->load->model('extension/module/openstock');
+ $rows = $this->db->query("
+ SELECT alr.sku AS 'amazon_sku', alr.quantity AS 'amazon_quantity', alr.asin, alr.price AS 'amazon_price', oc_sku.product_id, pd.name, oc_sku.sku, oc_sku.var, oc_sku.quantity, oc_sku.pov_id
+ FROM " . DB_PREFIX . "amazonus_listing_report alr
+ LEFT JOIN (
+ SELECT p.product_id, if (por.product_id IS NULL, p.sku, por.sku) AS 'sku', if (por.product_id IS NULL, NULL, por.sku) AS 'var', if (por.product_id IS NULL, p.quantity, por.stock) AS 'quantity', por.product_option_variant_id AS pov_id
+ FROM " . DB_PREFIX . "product p
+ LEFT JOIN " . DB_PREFIX . "product_option_variant por USING(product_id)
+ ) AS oc_sku ON alr.sku = oc_sku.sku
+ LEFT JOIN " . DB_PREFIX . "amazonus_product_link apl ON (oc_sku.var IS NULL AND oc_sku.product_id = apl.product_id) OR (oc_sku.var IS NOT NULL AND oc_sku.product_id = apl.product_id AND oc_sku.var = apl.var)
+ LEFT JOIN " . DB_PREFIX . "product_description pd ON oc_sku.product_id = pd.product_id AND pd.language_id = " . (int)$this->config->get('config_language_id') . "
+ WHERE apl.product_id IS NULL
+ ORDER BY alr.sku
+ LIMIT " . (int)$start . "," . (int)$limit)->rows;
+ } else {
+ $rows = $this->db->query("
+ SELECT alr.sku AS 'amazon_sku', alr.quantity AS 'amazon_quantity', alr.asin, alr.price AS 'amazon_price', oc_sku.product_id, pd.name, oc_sku.sku, oc_sku.var, oc_sku.quantity, '' AS combination
+ FROM " . DB_PREFIX . "amazonus_listing_report alr
+ LEFT JOIN (
+ SELECT p.product_id, p.sku, NULL AS 'var', p.quantity
+ FROM " . DB_PREFIX . "product p
+ ) AS oc_sku ON alr.sku = oc_sku.sku
+ LEFT JOIN " . DB_PREFIX . "amazonus_product_link apl ON (oc_sku.var IS NULL AND oc_sku.product_id = apl.product_id) OR (oc_sku.var IS NOT NULL AND oc_sku.product_id = apl.product_id AND oc_sku.var = apl.var)
+ LEFT JOIN " . DB_PREFIX . "product_description pd ON oc_sku.product_id = pd.product_id AND pd.language_id = " . (int)$this->config->get('config_language_id') . "
+ WHERE apl.product_id IS NULL
+ ORDER BY alr.sku
+ LIMIT " . (int)$start . "," . (int)$limit)->rows;
+ }
+
+ $products = array();
+
+ foreach ($rows as $row) {
+ $combinations = array();
+
+ if (isset($row['pov_id']) && !empty($row['pov_id'])) {
+ $variants = (isset($row['pov_id']) ? $this->model_setting_module_openstock->getVariant($row['pov_id']) : '');
+
+ foreach ($variants as $variant) {
+ $combinations[] = $variant['option_value_name'];
+ }
+ }
+
+ $products[] = array(
+ 'product_id' => $row['product_id'],
+ 'name' => $row['name'],
+ 'sku' => $row['sku'],
+ 'var' => $row['var'],
+ 'quantity' => $row['quantity'],
+ 'amazon_sku' => $row['amazon_sku'],
+ 'amazon_quantity' => $row['amazon_quantity'],
+ 'amazon_price' => number_format($row['amazon_price'], 2, '.', ''),
+ 'asin' => $row['asin'],
+ 'combination' => implode(' > ', $combinations),
+ );
+ }
+
+ return $products;
+ }
+
+ public function deleteListingReports() {
+ $this->db->query("
+ DELETE FROM " . DB_PREFIX . "amazonus_listing_report
+ ");
+ }
+}
diff --git a/public/admin/model/extension/openbay/amazonus_listing.php b/public/admin/model/extension/openbay/amazonus_listing.php
new file mode 100644
index 0000000..beaea33
--- /dev/null
+++ b/public/admin/model/extension/openbay/amazonus_listing.php
@@ -0,0 +1,197 @@
+<?php
+class ModelExtensionOpenBayAmazonusListing extends Model {
+ private $tabs = array();
+
+ public function search($search_string) {
+
+ $search_params = array(
+ 'search_string' => $search_string,
+ );
+
+ $results = json_decode($this->openbay->amazonus->call('productv3/search', $search_params), 1);
+
+ $products = array();
+
+ if (!empty($results)) {
+ foreach ($results['Products'] as $result) {
+ if ($result['price']['amount'] && $result['price']['currency']) {
+ $price = $result['price']['amount'] . ' ' . $result['price']['currency'];
+ } else {
+ $price = '-';
+ }
+
+ $link = 'http://www.amazon.com/gp/product/' . $result['asin'] . '/';
+
+ $products[] = array(
+ 'name' => $result['name'],
+ 'asin' => $result['asin'],
+ 'image' => $result['image'],
+ 'price' => $price,
+ 'link' => $link,
+ );
+ }
+ }
+
+ return $products;
+ }
+
+ public function getProductByAsin($asin) {
+ $data = array(
+ 'asin' => $asin,
+ );
+
+ $results = json_decode($this->openbay->amazonus->call('productv3/getProduct', $data), 1);
+
+ return $results;
+ }
+
+ public function getBestPrice($asin, $condition) {
+ $search_params = array(
+ 'asin' => $asin,
+ 'condition' => $condition,
+ );
+
+ $best_price = '';
+
+ $result = json_decode($this->openbay->amazonus->call('productv3/getPrice', $search_params), 1);
+
+ if (isset($result['Price']['Amount']) && $result['Price']['Currency'] && $this->currency->has($result['Price']['Currency'])) {
+ $best_price['amount'] = number_format($this->currency->convert($result['Price']['Amount'], $result['Price']['Currency'], $this->config->get('config_currency')), 2, '.', '');
+ $best_price['shipping'] = number_format($this->currency->convert($result['Price']['Shipping'], $result['Price']['Currency'], $this->config->get('config_currency')), 2, '.', '');
+ $best_price['currency'] = $result['Price']['Currency'];
+ }
+
+ return $best_price;
+ }
+
+ public function simpleListing($data) {
+ $request = array(
+ 'asin' => $data['asin'],
+ 'sku' => $data['sku'],
+ 'quantity' => $data['quantity'],
+ 'price' => $data['price'],
+ 'sale' => array(
+ 'price' => $data['sale_price'],
+ 'from' => $data['sale_from'],
+ 'to' => $data['sale_to'],
+ ),
+ 'condition' => $data['condition'],
+ 'condition_note' => $data['condition_note'],
+ 'start_selling' => $data['start_selling'],
+ 'restock_date' => $data['restock_date'],
+ 'response_url' => HTTPS_CATALOG . 'index.php?route=extension/openbay/amazonus/listing',
+ 'product_id' => $data['product_id'],
+ );
+
+ $response = $this->openbay->amazonus->call('productv3/simpleListing', $request);
+ $response = json_decode($response);
+ if (empty($response)) {
+ return array(
+ 'status' => 0,
+ 'message' => 'Problem connecting OpenBay: API'
+ );
+ }
+ $response = (array)$response;
+
+ if ($response['status'] === 1) {
+ $this->db->query("
+ REPLACE INTO `" . DB_PREFIX . "amazonus_product`
+ SET `product_id` = " . (int)$data['product_id'] . ",
+ `status` = 'uploaded',
+ `version` = 3,
+ `var` = ''
+ ");
+ }
+
+ return $response;
+ }
+
+ public function getBrowseNodes($request) {
+ return $this->openbay->amazonus->call('productv3/getBrowseNodes', $request);
+ }
+
+ public function deleteSearchResults($product_ids) {
+ $imploded_ids = array();
+
+ foreach ($product_ids as $product_id) {
+ $imploded_ids[] = (int)$product_id;
+ }
+
+ $imploded_ids = implode(',', $imploded_ids);
+
+ $this->db->query("
+ DELETE FROM " . DB_PREFIX . "amazonus_product_search
+ WHERE product_id IN ($imploded_ids)
+ ");
+ }
+
+ public function doBulkListing($data) {
+ $this->load->model('catalog/product');
+ $request = array();
+
+ foreach($data['products'] as $product_id => $asin) {
+ $product = $this->model_catalog_product->getProduct($product_id);
+
+ if ($product) {
+ $price = $product['price'];
+
+ if ($this->config->get('openbay_amazonus_listing_tax_added') && $this->config->get('openbay_amazonus_listing_tax_added') > 0) {
+ $price += $price * ($this->config->get('openbay_amazonus_listing_tax_added') / 100);
+ }
+
+ $request[] = array(
+ 'asin' => $asin,
+ 'sku' => $product['sku'],
+ 'quantity' => $product['quantity'],
+ 'price' => number_format($price, 2, '.', ''),
+ 'sale' => array(),
+ 'condition' => (isset($data['condition']) ? $data['condition'] : ''),
+ 'condition_note' => (isset($data['condition_note']) ? $data['condition_note'] : ''),
+ 'start_selling' => (isset($data['start_selling']) ? $data['start_selling'] : ''),
+ 'restock_date' => '',
+ 'response_url' => HTTPS_CATALOG . 'index.php?route=extension/openbay/amazonus/listing',
+ 'product_id' => $product['product_id'],
+ );
+ }
+ }
+
+ if ($request) {
+ $response = $this->openbay->amazonus->call('productv3/bulkListing', $request);
+
+ $response = json_decode($response, 1);
+
+ if ($response['status'] == 1) {
+ foreach ($request as $product) {
+ $this->db->query("
+ REPLACE INTO `" . DB_PREFIX . "amazonus_product`
+ SET `product_id` = " . (int)$product['product_id'] . ",
+ `status` = 'uploaded',
+ `var` = '',
+ `version` = 3
+ ");
+ }
+
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ public function doBulkSearch($search_data) {
+ foreach ($search_data as $products) {
+ foreach ($products as $product) {
+ $this->db->query("
+ REPLACE INTO " . DB_PREFIX . "amazonus_product_search (product_id, `status`)
+ VALUES (" . (int)$product['product_id'] . ", 'searching')");
+ }
+ }
+
+ $request_data = array(
+ 'search' => $search_data,
+ 'response_url' => HTTPS_CATALOG . 'index.php?route=extension/openbay/amazonus/search'
+ );
+
+ $response = $this->openbay->amazonus->call('productv3/bulkSearch', $request_data);
+ }
+} \ No newline at end of file
diff --git a/public/admin/model/extension/openbay/ebay.php b/public/admin/model/extension/openbay/ebay.php
new file mode 100644
index 0000000..246f64e
--- /dev/null
+++ b/public/admin/model/extension/openbay/ebay.php
@@ -0,0 +1,832 @@
+<?php
+class ModelExtensionOpenBayEbay extends Model{
+ public function install() {
+ $this->load->model('setting/event');
+
+ $this->model_setting_event->addEvent('openbay_ebay_add_order', 'catalog/model/checkout/order/addOrderHistory/after', 'extension/openbay/ebay/eventAddOrderHistory');
+
+ $settings = array();
+ $settings["ebay_token"] = '';
+ $settings["ebay_secret"] = '';
+ $settings["ebay_encryption_key"] = '';
+ $settings["ebay_encryption_iv"] = '';
+ $settings["ebay_enditems"] = '0';
+ $settings["ebay_logging"] = '1';
+ $settings["ebay_payment_instruction"] = '';
+ $settings["ebay_payment_paypal_address"] = '';
+ $settings["ebay_tax"] = '0';
+ $settings["ebay_status_import_id"] = '1';
+ $settings["ebay_status_shipped_id"] = '3';
+ $settings["ebay_status_paid_id"] = '2';
+ $settings["ebay_status_cancelled_id"] = '7';
+ $settings["ebay_status_refunded_id"] = '11';
+ $settings["ebay_def_currency"] = 'GBP';
+ $settings["ebay_stock_allocate"] = '0';
+ $settings["ebay_update_notify"] = '1';
+ $settings["ebay_confirm_notify"] = '1';
+ $settings["ebay_confirmadmin_notify"] = '1';
+ $settings["ebay_created_hours"] = '48';
+ $settings["ebay_create_date"] = '0';
+ $settings["ebay_itm_link"] = 'http://www.ebay.com/itm/';
+ $settings["ebay_relistitems"] = 0;
+ $settings["ebay_time_offset"] = 0;
+ $settings["ebay_default_addressformat"] = '{firstname} {lastname}
+{company}
+{address_1}
+{address_2}
+{city}
+{zone}
+{postcode}
+{country}';
+
+ $this->model_setting_setting->editSetting('ebay', $settings);
+
+ $this->db->query("
+ CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "ebay_category` (
+ `ebay_category_id` int(11) NOT NULL AUTO_INCREMENT,
+ `CategoryID` int(11) NOT NULL,
+ `CategoryParentID` int(11) NOT NULL,
+ `CategoryLevel` smallint(6) NOT NULL,
+ `CategoryName` char(100) NOT NULL,
+ `BestOfferEnabled` tinyint(1) NOT NULL,
+ `AutoPayEnabled` tinyint(1) NOT NULL,
+ PRIMARY KEY (`ebay_category_id`)
+ ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci;");
+
+ $this->db->query("
+ CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "ebay_category_history` (
+ `ebay_category_history_id` int(11) NOT NULL AUTO_INCREMENT,
+ `CategoryID` int(11) NOT NULL,
+ `breadcrumb` varchar(255) NOT NULL,
+ `used` int(6) NOT NULL,
+ PRIMARY KEY (`ebay_category_history_id`)
+ ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci;");
+
+ $this->db->query("
+ CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "ebay_listing` (
+ `ebay_listing_id` int(11) NOT NULL AUTO_INCREMENT,
+ `ebay_item_id` char(100) NOT NULL,
+ `product_id` int(11) NOT NULL,
+ `variant` int(11) NOT NULL,
+ `status` SMALLINT(3) NOT NULL DEFAULT '1',
+ PRIMARY KEY (`ebay_listing_id`),
+ KEY `product_id` (`product_id`)
+ ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci;");
+ ;
+ $this->db->query("
+ CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "ebay_listing_pending` (
+ `ebay_listing_pending_id` int(11) NOT NULL AUTO_INCREMENT,
+ `ebay_item_id` char(25) NOT NULL,
+ `product_id` int(11) NOT NULL,
+ `key` char(50) NOT NULL,
+ `variant` int(11) NOT NULL,
+ PRIMARY KEY (`ebay_listing_pending_id`),
+ KEY `product_id` (`product_id`)
+ ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci;");
+
+ $this->db->query("
+ CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "ebay_shipping` (
+ `ebay_shipping_id` int(11) NOT NULL AUTO_INCREMENT,
+ `description` varchar(100) NOT NULL,
+ `InternationalService` tinyint(4) NOT NULL,
+ `ShippingService` varchar(100) NOT NULL,
+ `ShippingServiceID` int(11) NOT NULL,
+ `ServiceType` varchar(100) NOT NULL,
+ `ValidForSellingFlow` tinyint(4) NOT NULL,
+ `ShippingCategory` varchar(100) NOT NULL,
+ `ShippingTimeMin` int(11) NOT NULL,
+ `ShippingTimeMax` int(11) NOT NULL,
+ PRIMARY KEY (`ebay_shipping_id`)
+ ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci;");
+
+ $this->db->query("
+ CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "ebay_shipping_location` (
+ `ebay_shipping_id` int(11) NOT NULL AUTO_INCREMENT,
+ `description` varchar(100) NOT NULL,
+ `detail_version` varchar(100) NOT NULL,
+ `shipping_location` varchar(100) NOT NULL,
+ `update_time` varchar(100) NOT NULL,
+ PRIMARY KEY (`ebay_shipping_id`)
+ ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci;");
+
+ $this->db->query("
+ CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "ebay_payment_method` (
+ `ebay_payment_method_id` int(11) NOT NULL AUTO_INCREMENT,
+ `ebay_name` char(50) NOT NULL,
+ `local_name` char(50) NOT NULL,
+ PRIMARY KEY (`ebay_payment_method_id`)
+ ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci AUTO_INCREMENT=5;");
+
+ $this->db->query("
+ CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "ebay_transaction` (
+ `ebay_transaction_id` int(11) NOT NULL AUTO_INCREMENT,
+ `order_id` int(11) NOT NULL,
+ `product_id` int(11) NOT NULL,
+ `sku` varchar(100) NOT NULL,
+ `txn_id` varchar(100) NOT NULL,
+ `item_id` varchar(100) NOT NULL,
+ `containing_order_id` varchar(100) NOT NULL,
+ `order_line_id` varchar(100) NOT NULL,
+ `qty` int(11) NOT NULL,
+ `smp_id` int(11) NOT NULL,
+ `created` DATETIME NOT NULL,
+ `modified` DATETIME NOT NULL,
+ PRIMARY KEY (`ebay_transaction_id`),
+ KEY `product_id` (`product_id`),
+ KEY `order_id` (`order_id`),
+ KEY `smp_id` (`smp_id`)
+ ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci;");
+
+ $this->db->query("
+ CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "ebay_order` (
+ `ebay_order_id` int(11) NOT NULL AUTO_INCREMENT,
+ `parent_ebay_order_id` int(11) NOT NULL,
+ `order_id` int(11) NOT NULL,
+ `smp_id` int(11) NOT NULL,
+ `tracking_no` varchar(100) NOT NULL,
+ `carrier_id` varchar(100) NOT NULL,
+ PRIMARY KEY (`ebay_order_id`),
+ KEY `order_id` (`order_id`),
+ KEY `smp_id` (`smp_id`),
+ KEY `parent_ebay_order_id` (`parent_ebay_order_id`)
+ ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci;");
+
+ $this->db->query("
+ CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "ebay_profile` (
+ `ebay_profile_id` int(11) NOT NULL AUTO_INCREMENT,
+ `name` varchar(100) NOT NULL,
+ `description` text NOT NULL,
+ `type` int(11) NOT NULL,
+ `default` TINYINT(1) NOT NULL,
+ `data` text NOT NULL,
+ PRIMARY KEY (`ebay_profile_id`)
+ ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci;");
+
+ $this->db->query("
+ CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "ebay_setting_option` (
+ `ebay_setting_option_id` INT(11) NOT NULL AUTO_INCREMENT,
+ `key` VARCHAR(100) NOT NULL,
+ `last_updated` DATETIME NOT NULL,
+ `data` TEXT NOT NULL,
+ PRIMARY KEY (`ebay_setting_option_id`)
+ ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci;");
+
+ $this->db->query("
+ CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "ebay_image_import` (
+ `id` int(11) NOT NULL AUTO_INCREMENT,
+ `image_original` text NOT NULL,
+ `image_new` text NOT NULL,
+ `name` text NOT NULL,
+ `product_id` int(11) NOT NULL,
+ `imgcount` int(11) NOT NULL,
+ PRIMARY KEY (`id`)
+ ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci;");
+
+ $this->db->query("
+ CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "ebay_shipping_location_exclude` (
+ `ebay_shipping_exclude_id` int(11) NOT NULL AUTO_INCREMENT,
+ `description` varchar(100) NOT NULL,
+ `location` varchar(100) NOT NULL,
+ `region` varchar(100) NOT NULL,
+ PRIMARY KEY (`ebay_shipping_exclude_id`)
+ ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci;");
+
+ $this->db->query("
+ CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "ebay_stock_reserve` (
+ `id` int(11) NOT NULL AUTO_INCREMENT,
+ `product_id` int(11) NOT NULL,
+ `variant_id` varchar(100) NOT NULL,
+ `item_id` varchar(100) NOT NULL,
+ `reserve` int(11) NOT NULL,
+ PRIMARY KEY (`id`),
+ KEY `product_id` (`product_id`)
+ ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci;");
+
+ $this->db->query("
+ CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "ebay_order_lock` (
+ `smp_id` int(11) NOT NULL,
+ PRIMARY KEY (`smp_id`)
+ ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci;");
+
+ $this->db->query("
+ CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "ebay_template` (
+ `template_id` INT(11) NOT NULL AUTO_INCREMENT,
+ `name` VARCHAR(100) NOT NULL,
+ `html` MEDIUMTEXT NOT NULL,
+ PRIMARY KEY (`template_id`)
+ ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci;");
+ }
+
+ public function uninstall() {
+ $this->db->query("DROP TABLE IF EXISTS `" . DB_PREFIX . "ebay_category`;");
+ $this->db->query("DROP TABLE IF EXISTS `" . DB_PREFIX . "ebay_category_history`;");
+ $this->db->query("DROP TABLE IF EXISTS `" . DB_PREFIX . "ebay_listing`;");
+ $this->db->query("DROP TABLE IF EXISTS `" . DB_PREFIX . "ebay_listing_pending`;");
+ $this->db->query("DROP TABLE IF EXISTS `" . DB_PREFIX . "ebay_shipping`;");
+ $this->db->query("DROP TABLE IF EXISTS `" . DB_PREFIX . "ebay_shipping_location`;");
+ $this->db->query("DROP TABLE IF EXISTS `" . DB_PREFIX . "ebay_payment_method`;");
+ $this->db->query("DROP TABLE IF EXISTS `" . DB_PREFIX . "ebay_transaction`;");
+ $this->db->query("DROP TABLE IF EXISTS `" . DB_PREFIX . "ebay_order`;");
+ $this->db->query("DROP TABLE IF EXISTS `" . DB_PREFIX . "ebay_profile`;");
+
+ $this->load->model('setting/event');
+ $this->model_setting_event->deleteEventByCode('openbay_ebay_add_order');
+ }
+
+ public function patch() {
+ if ($this->config->get('ebay_status') == 1) {
+
+ }
+ }
+
+ public function totalLinked() {
+ $sql = "SELECT COUNT(DISTINCT p.product_id) AS total
+ FROM `" . DB_PREFIX . "ebay_listing` `el`
+ LEFT JOIN `" . DB_PREFIX . "product` `p` ON (`el`.`product_id` = `p`.`product_id`)
+ LEFT JOIN `" . DB_PREFIX . "product_description` `pd` ON (`p`.`product_id` = `pd`.`product_id`)
+ WHERE `el`.`status` = '1'
+ AND `pd`.`language_id` = '" . (int)$this->config->get('config_language_id') . "'";
+
+ $query = $this->db->query($sql);
+
+ return $query->row['total'];
+ }
+
+ public function loadLinked($limit = 100, $page = 1) {
+ $this->load->model('tool/image');
+
+ $start = $limit * ($page - 1);
+
+ $has_option = '';
+ if ($this->openbay->addonLoad('openstock') ) {
+ $this->load->model('extension/module/openstock');
+ $has_option = '`p`.`has_option`, ';
+ }
+
+ $sql = "
+ SELECT
+ " . $has_option . "
+ `el`.`ebay_item_id`,
+ `p`.`product_id`,
+ `p`.`sku`,
+ `p`.`model`,
+ `p`.`quantity`,
+ `pd`.`name`,
+ `esr`.`reserve`
+ FROM `" . DB_PREFIX . "ebay_listing` `el`
+ LEFT JOIN `" . DB_PREFIX . "product` `p` ON (`el`.`product_id` = `p`.`product_id`)
+ LEFT JOIN `" . DB_PREFIX . "product_description` `pd` ON (`p`.`product_id` = `pd`.`product_id`)
+ LEFT JOIN `" . DB_PREFIX . "ebay_stock_reserve` `esr` ON (`esr`.`product_id` = `p`.`product_id`)
+ WHERE `el`.`status` = '1'
+ AND `pd`.`language_id` = '" . (int)$this->config->get('config_language_id') . "'";
+
+ $sql .= " LIMIT " . (int)$start . "," . (int)$limit;
+
+ $qry = $this->db->query($sql);
+
+ $data = array();
+ if ($qry->num_rows) {
+ foreach ($qry->rows as $row) {
+ $data[$row['ebay_item_id']] = array(
+ 'product_id' => $row['product_id'],
+ 'sku' => $row['sku'],
+ 'model' => $row['model'],
+ 'qty' => $row['quantity'],
+ 'name' => $row['name'],
+ 'link_edit' => $this->url->link('catalog/product/edit', 'user_token=' . $this->session->data['user_token'] . '&product_id=' . $row['product_id'], true),
+ 'link_ebay' => $this->config->get('ebay_itm_link') . $row['ebay_item_id'],
+ 'reserve' => (int)$row['reserve'],
+ );
+
+ $data[$row['ebay_item_id']]['options'] = 0;
+
+ if ((isset($row['has_option']) && $row['has_option'] == 1) && $this->openbay->addonLoad('openstock')) {
+ $data[$row['ebay_item_id']]['options'] = $this->model_setting_module_openstock->getVariants((int)$row['product_id']);
+ }
+
+ //get the allocated stock - items that have been bought but not assigned to an order
+ if ($this->config->get('ebay_stock_allocate') == 0) {
+ $data[$row['ebay_item_id']]['allocated'] = $this->openbay->ebay->getAllocatedStock($row['product_id']);
+ } else {
+ $data[$row['ebay_item_id']]['allocated'] = 0;
+ }
+ }
+ }
+
+ return $data;
+ }
+
+ public function loadLinkedStatus($item_ids) {
+ $this->openbay->ebay->log('loadLinkedStatus() - Get item status from ebay for multiple IDs');
+ return $this->openbay->ebay->call('item/getItemsById/', array('item_ids' => $item_ids));
+ }
+
+ public function loadUnlinked($limit = 200, $page = 1, $filter = array()) {
+ $unlinked = array();
+ $current = 1;
+ $stop_flag = 0;
+
+ while(count($unlinked) < 5) {
+ if ($current > 5) {
+ $stop_flag = 1;
+ break;
+ } else {
+ $current++;
+ }
+
+ $this->openbay->ebay->log('Checking unlinked page: ' . $page);
+
+ $response = $this->openbay->ebay->getEbayItemList($limit, $page, $filter);
+
+ if ($this->openbay->ebay->lasterror == true) {
+ break;
+ }
+
+ foreach ($response['items'] as $item_id => $item) {
+ if ($this->openbay->ebay->getProductId($item_id, 1) == false) {
+ $unlinked[$item_id] = $item;
+ }
+ }
+
+ $this->openbay->ebay->log('Unlinked count: ' . count($unlinked));
+
+ if ($response['max_page'] == $page || count($unlinked) >= 5) {
+ break;
+ } else {
+ $page++;
+ }
+ }
+
+ return array(
+ 'items' => $unlinked,
+ 'break' => $stop_flag,
+ 'next_page' => $response['page']+1,
+ 'max_page' => $response['max_page']
+ );
+ }
+
+ public function loadItemLinks() {
+ $local = $this->openbay->ebay->getLiveListingArray();
+ $response = $this->openbay->ebay->getEbayActiveListings();
+
+ $data = array(
+ 'unlinked' => array(),
+ 'linked' => array()
+ );
+
+ if (!empty($response)) {
+ foreach ($response as $key => $value) {
+ if (!in_array($key, $local)) {
+ $data['unlinked'][$key] = $value;
+ } else {
+ $data['linked'][$key] = $value;
+ }
+ }
+ }
+
+ return $data;
+ }
+
+ public function saveItemLink($data) {
+ $this->openbay->ebay->log('Creating item link.');
+ $this->openbay->ebay->createLink($data['pid'], $data['itemId'], $data['variants']);
+
+ if (($data['qty'] != $data['ebayqty']) || $data['variants'] == 1) {
+ $this->load->model('catalog/product');
+ $this->openbay->ebay->log('Updating eBay with new qty');
+ $this->openbay->ebay->productUpdateListen($data['pid'], $this->model_catalog_product->getProduct($data['pid']));
+ } else {
+ $this->openbay->ebay->log('Qty on eBay is the same as our stock, no update needed');
+ return array('msg' => 'ok', 'error' => false);
+ }
+ }
+
+ public function getSellerStoreCategories() {
+ $qry = $this->db->query("SHOW TABLES LIKE '" . DB_PREFIX . "ebay_store_category'");
+
+ if ($qry->num_rows) {
+ $qry = $this->db->query("SELECT * FROM `" . DB_PREFIX . "ebay_store_category` WHERE `parent_id` = '0' ORDER BY `CategoryName` ASC");
+
+ if ($qry->num_rows) {
+ $cats = array();
+
+ foreach ($qry->rows as $row) {
+ $lev1 = $row['CategoryName'];
+ $qry2 = $this->db->query("SELECT * FROM `" . DB_PREFIX . "ebay_store_category` WHERE `parent_id` = '" . $row['ebay_store_category_id'] . "' ORDER BY `CategoryName` ASC");
+
+ if ($qry2->num_rows) {
+ foreach ($qry2->rows as $row2) {
+ $qry3 = $this->db->query("SELECT * FROM `" . DB_PREFIX . "ebay_store_category` WHERE `parent_id` = '" . $row2['ebay_store_category_id'] . "' ORDER BY `CategoryName` ASC");
+
+ if ($qry3->num_rows) {
+ foreach ($qry3->rows as $row3) {
+ $cats[$row3['CategoryID']] = $lev1 . ' > ' . $row2['CategoryName'] . ' > ' . $row3['CategoryName'];
+ }
+ } else {
+ $cats[$row2['CategoryID']] = $lev1 . ' > ' . $row2['CategoryName'];
+ }
+ }
+ } else {
+ $cats[$row['CategoryID']] = $lev1;
+ }
+ }
+
+ return $cats;
+ } else {
+ return false;
+ }
+ } else {
+ return false;
+ }
+ }
+
+ public function getCategory($parent) {
+ $this->load->language('extension/openbay/ebay_new');
+
+ $json = array();
+
+ if (empty($parent)) {
+ $cat_qry = $this->db->query("SELECT * FROM `" . DB_PREFIX . "ebay_category` WHERE `CategoryID` = `CategoryParentID`");
+ } else {
+ $cat_qry = $this->db->query("SELECT * FROM `" . DB_PREFIX . "ebay_category` WHERE `CategoryParentID` = '" . $parent . "'");
+ }
+
+ if ($cat_qry->num_rows) {
+ $json['cats'] = array();
+ foreach ($cat_qry->rows as $row) {
+ $json['cats'][] = $row;
+ }
+ $json['items'] = $cat_qry->num_rows;
+
+ } else {
+ if (empty($parent)) {
+ $json['error'] = $this->language->get('error_category_sync');
+ }
+
+ $json['items'] = null;
+ }
+
+ return $json;
+ }
+
+ public function getSuggestedCategories($qry) {
+ $response = array(
+ 'data' => $this->openbay->ebay->call('listing/getSuggestedCategories/', array('qry' => $qry)),
+ 'error' => $this->openbay->ebay->lasterror,
+ 'msg' => $this->openbay->ebay->lastmsg
+ );
+
+ return $response;
+ }
+
+ public function getShippingService($international, $type) {
+ $json = array();
+ $result = $this->db->query("SELECT * FROM `" . DB_PREFIX . "ebay_shipping` WHERE `InternationalService` = '" . (int)$international . "' AND `ValidForSellingFlow` = '1' AND `ServiceType` LIKE '%" . $this->db->escape($type) . "%'");
+
+ if ($result->num_rows) {
+ $json['service'] = array();
+ foreach ($result->rows as $row) {
+ $json['service'][$row['ShippingService']] = $row;
+ }
+ }
+
+ return $json;
+ }
+
+ public function getShippingLocations() {
+ $qry = $this->db->query("SELECT * FROM `" . DB_PREFIX . "ebay_shipping_location` WHERE `shipping_location` != 'None' AND `shipping_location` != 'Worldwide'");
+
+ if ($qry->num_rows) {
+ $json = array();
+ foreach ($qry->rows as $row) {
+ $json[] = $row;
+ }
+ return $json;
+ } else {
+ return false;
+ }
+ }
+
+ public function getEbayCategorySpecifics($category_id) {
+ $response['data'] = $this->openbay->ebay->call('listing/getEbayCategorySpecifics/', array('id' => $category_id));
+ $response['error'] = $this->openbay->ebay->lasterror;
+ $response['msg'] = $this->openbay->ebay->lastmsg;
+ return $response;
+ }
+
+ public function getCategoryFeatures($category_id) {
+ $response['data'] = $this->openbay->ebay->call('listing/getCategoryFeatures/', array('id' => $category_id));
+ $response['error'] = $this->openbay->ebay->lasterror;
+ $response['msg'] = $this->openbay->ebay->lastmsg;
+ return $response;
+ }
+
+ public function getSellerSummary() {
+ $response['data'] = $this->openbay->ebay->call('account/getSellerSummary/');
+ $response['error'] = $this->openbay->ebay->lasterror;
+ $response['msg'] = $this->openbay->ebay->lastmsg;
+
+ return $response;
+ }
+
+ public function getPaymentTypes() {
+ $cat_payment = $this->db->query("SELECT * FROM `" . DB_PREFIX . "ebay_payment_method`");
+ $payments = array();
+
+ foreach ($cat_payment->rows as $row) {
+ $payments[] = $row;
+ }
+
+ return $payments;
+ }
+
+ public function getPopularCategories() {
+ $res = $this->db->query("SELECT * FROM `" . DB_PREFIX . "ebay_category_history` ORDER BY `used` DESC LIMIT 5");
+ $cats = array();
+
+ foreach ($res->rows as $row) {
+ $cats[] = $row;
+ }
+
+ return $cats;
+ }
+
+ private function getCategoryStructure($id) {
+ $res = $this->db->query("SELECT * FROM `" . DB_PREFIX . "ebay_category` WHERE `CategoryID` = '" . $this->db->escape($id) . "' LIMIT 1");
+ return $res->row;
+ }
+
+ public function ebayVerifyAddItem($data, $options) {
+ if ($options == 'yes') {
+ $response['data'] = $this->openbay->ebay->call('listing/verifyFixedPrice/', $data);
+ } else {
+ $response['data'] = $this->openbay->ebay->call('listing/ebayVerifyAddItem/', $data);
+ }
+
+ $response['error'] = $this->openbay->ebay->lasterror;
+ $response['msg'] = $this->openbay->ebay->lastmsg;
+
+ return $response;
+ }
+
+ public function ebayAddItem($data, $options) {
+ if ($options == 'yes') {
+ $response = $this->openbay->ebay->call('listing/addFixedPrice/', $data);
+ $variant = 1;
+ } else {
+ $response = $this->openbay->ebay->call('listing/ebayAddItem/', $data);
+ $variant = 0;
+ }
+
+ $data2 = array();
+ $data2['data'] = $response;
+ $data2['error'] = $this->openbay->ebay->lasterror;
+ $data2['msg'] = $this->openbay->ebay->lastmsg;
+
+ if (!empty($response['ItemID'])) {
+ $this->openbay->ebay->createLink($data['product_id'], $response['ItemID'], $variant);
+ $this->openbay->ebay->addReserve($data, $response['ItemID'], $variant);
+
+ $item_link = $this->config->get('ebay_itm_link');
+
+ if (!empty($item_link)) {
+ $data2['data']['view_link'] = html_entity_decode($this->config->get('ebay_itm_link') . $response['ItemID']);
+ } else {
+ $data2['data']['view_link'] = '';
+ }
+ } else {
+ $data2['error'] = false;
+ $data2['msg'] = 'ok';
+ $data2['data']['Failed'] = true;
+ }
+
+ return $data2;
+ }
+
+ public function logCategoryUsed($category_id) {
+ $breadcrumb = array();
+ $original_id = $category_id;
+ $stop = false;
+ $i = 0; //fallback to stop infinate loop
+ $err = false;
+
+ while($stop == false && $i < 10) {
+ $cat = $this->getCategoryStructure($category_id);
+
+ if (!empty($cat)) {
+ $breadcrumb[] = $cat['CategoryName'];
+
+ if ($cat['CategoryParentID'] == $category_id) {
+ $stop = true;
+ } else {
+ $category_id = $cat['CategoryParentID'];
+ }
+
+ $i++;
+ } else {
+ $stop = true;
+ $err = true;
+ }
+ }
+
+ if ($err == false) {
+ $res = $this->db->query("SELECT `used` FROM `" . DB_PREFIX . "ebay_category_history` WHERE `CategoryID` = '" . $original_id . "' LIMIT 1");
+
+ if ($res->num_rows) {
+ $new = $res->row['used'] + 1;
+ $this->db->query("UPDATE `" . DB_PREFIX . "ebay_category_history` SET `used` = '" . $new . "' WHERE `CategoryID` = '" . $original_id . "' LIMIT 1");
+ } else {
+ $this->db->query("INSERT INTO `" . DB_PREFIX . "ebay_category_history` SET `CategoryID` = '" . $original_id . "', `breadcrumb` = '" . $this->db->escape(implode(' > ', array_reverse($breadcrumb))) . "', `used` = '1'");
+ }
+ }
+ }
+
+ public function getProductStock($id) {
+ $res = $this->db->query("SELECT * FROM `" . DB_PREFIX . "product` WHERE `product_id` = '" . $this->db->escape($id) . "' LIMIT 1");
+
+ if (isset($res->row['has_option']) && $res->row['has_option'] == 1) {
+ if ($this->openbay->addonLoad('openstock')) {
+ $this->load->model('extension/module/openstock');
+ $this->load->model('tool/image');
+ $variant = $this->model_setting_module_openstock->getVariants((int)$id);
+ } else {
+ $variant = 0;
+ }
+ } else {
+ $variant = 0;
+ }
+
+ return array(
+ 'qty' => $res->row['quantity'],
+ 'subtract' => (int)$res->row['subtract'],
+ 'allocated' => $this->openbay->ebay->getAllocatedStock($id),
+ 'variant' => $variant
+ );
+ }
+
+ public function getUsage() {
+ return $this->openbay->ebay->call('report/accountUse/');
+ }
+
+ public function getPlans() {
+ return $this->openbay->ebay->call('plan/getPlans/');
+ }
+
+ public function getMyPlan() {
+ return $this->openbay->ebay->call('plan/myPlan/');
+ }
+
+ public function getLiveListingArray() {
+ $qry = $this->db->query("SELECT `product_id`, `ebay_item_id` FROM `" . DB_PREFIX . "ebay_listing` WHERE `status` = 1");
+
+ $data = array();
+ if ($qry->num_rows) {
+ foreach ($qry->rows as $row) {
+ $data[$row['product_id']] = $row['ebay_item_id'];
+ }
+ }
+
+ return $data;
+ }
+
+ public function verifyCredentials() {
+ $this->request->post['domain'] = HTTPS_SERVER;
+
+ $data = $this->openbay->ebay->call('account/validate/', $this->request->post, array(), 'json', 1);
+
+ $return = array('error' => $this->openbay->ebay->lasterror, 'msg' => $this->openbay->ebay->lastmsg);
+
+ if ($this->openbay->ebay->lasterror != true) {
+ $return['data'] = $data;
+ }
+
+ return $return;
+ }
+
+ public function editSave($data) {
+ $this->openbay->ebay->log('editSave() - start..');
+
+ //get product id
+ $product_id = $this->openbay->ebay->getProductId($data['itemId']);
+
+ $this->openbay->ebay->log('editSave() - product_id: ' . $product_id);
+
+ if ($data['variant'] == 0) {
+ //save the reserve level
+ $this->openbay->ebay->updateReserve($product_id, $data['itemId'], $data['qty_reserve']);
+
+ //get the stock info
+ $stock = $this->openbay->ebay->getProductStockLevel($product_id);
+
+ //do the stock sync
+ $this->openbay->ebay->putStockUpdate($data['itemId'], $stock['quantity']);
+
+ //finish the revise item call
+ return $this->openbay->ebay->call('listing/reviseItem/', $data);
+ } else {
+ $this->openbay->ebay->log('editSave() - variant item');
+
+ $variant_data = array();
+ $this->load->model('tool/image');
+ $this->load->model('catalog/product');
+ $this->load->model('extension/module/openstock');
+
+ //get the options list for this product
+ $options = $this->model_setting_module_openstock->getVariants($product_id);
+
+ $variant_data['option_list'] = base64_encode(serialize($options[key($options)]['option_values']));
+
+ $variant_data['groups'] = $data['optGroupArray'];
+ $variant_data['related'] = $data['optGroupRelArray'];
+ $variant_data['id'] = $data['itemId'];
+
+ $stock_flag = false;
+
+ foreach ($data['opt'] as $k => $opt) {
+ //update the variant reserve level
+ $this->openbay->ebay->updateReserve($product_id, $data['itemId'], $opt['reserve'], $opt['sku'], 1);
+
+ //get the stock info
+ $stock = $this->openbay->ebay->getProductStockLevel($product_id, $opt['sku']);
+
+ $this->openbay->ebay->log('editSave() - stock: ' . serialize($stock));
+
+ if ($stock['quantity'] > 0 || $stock == true) {
+ $stock_flag = true;
+ }
+
+ // PRODUCT RESERVE LEVELS FOR VARIANT ITEMS (DOES NOT PASS THROUGH NORMAL SYSTEM)
+ $reserve = $this->openbay->ebay->getReserve($product_id, $data['itemId'], $opt['sku']);
+
+ $this->openbay->ebay->log('editSave() - reserve level: ' . $reserve);
+
+ if ($reserve != false) {
+ $this->openbay->ebay->log('editSave() / Variant (' . $opt['sku'] . ') - Reserve stock: ' . $reserve);
+
+ if ($stock['quantity'] > $reserve) {
+ $this->openbay->ebay->log('editSave() - Stock (' . $stock['quantity'] . ') is larger than reserve (' . $reserve . '), setting level to reserve');
+ $stock['quantity'] = $reserve;
+ }
+ }
+
+ $variant_data['opt'][$k]['sku'] = $opt['sku'];
+ $variant_data['opt'][$k]['qty'] = $stock['quantity'];
+ $variant_data['opt'][$k]['price'] = number_format($opt['price'], 2, '.', '');
+
+ // if any of the variants have 0 stock or no SKU set to inactive
+ if ($opt['sku'] == '' || $variant_data['opt'][$k]['qty'] < 1) {
+ $variant_data['opt'][$k]['active'] = 0;
+ } else {
+ $variant_data['opt'][$k]['active'] = $opt['active'];
+ }
+
+
+ $variant_option_values = $this->model_setting_module_openstock->getVariant($opt['product_option_variant_id']);
+
+ foreach ($variant_option_values as $variant_option_value) {
+ $variant_data['opt'][$k]['specifics'][] = array('name' => $variant_option_value['option_name'], 'value' => $variant_option_value['option_value_name']);
+ }
+ }
+
+ $this->openbay->ebay->log('editSave() - Debug - ' . serialize($variant_data));
+
+ //send to the api to process
+ if ($stock_flag == true) {
+ $this->openbay->ebay->log('editSave() - Sending to API');
+ $response = $this->openbay->ebay->call('item/reviseVariants', $variant_data);
+ return $response;
+ } else {
+ $this->openbay->ebay->log('editSave() - Ending item');
+ $this->openbay->ebay->endItem($data['itemId']);
+ }
+ }
+ }
+
+ public function getProductAttributes($product_id) {
+ $product_attribute_group_data = array();
+
+ $product_attribute_group_query = $this->db->query("SELECT ag.attribute_group_id, agd.name FROM " . DB_PREFIX . "product_attribute pa LEFT JOIN " . DB_PREFIX . "attribute a ON (pa.attribute_id = a.attribute_id) LEFT JOIN " . DB_PREFIX . "attribute_group ag ON (a.attribute_group_id = ag.attribute_group_id) LEFT JOIN " . DB_PREFIX . "attribute_group_description agd ON (ag.attribute_group_id = agd.attribute_group_id) WHERE pa.product_id = '" . (int)$product_id . "' AND agd.language_id = '" . (int)$this->config->get('config_language_id') . "' GROUP BY ag.attribute_group_id ORDER BY ag.sort_order, agd.name");
+
+ foreach ($product_attribute_group_query->rows as $product_attribute_group) {
+ $product_attribute_data = array();
+
+ $product_attribute_query = $this->db->query("SELECT a.attribute_id, ad.name, pa.text FROM " . DB_PREFIX . "product_attribute pa LEFT JOIN " . DB_PREFIX . "attribute a ON (pa.attribute_id = a.attribute_id) LEFT JOIN " . DB_PREFIX . "attribute_description ad ON (a.attribute_id = ad.attribute_id) WHERE pa.product_id = '" . (int)$product_id . "' AND a.attribute_group_id = '" . (int)$product_attribute_group['attribute_group_id'] . "' AND ad.language_id = '" . (int)$this->config->get('config_language_id') . "' AND pa.language_id = '" . (int)$this->config->get('config_language_id') . "' ORDER BY a.sort_order, ad.name");
+
+ foreach ($product_attribute_query->rows as $product_attribute) {
+ $product_attribute_data[] = array(
+ 'attribute_id' => $product_attribute['attribute_id'],
+ 'name' => $product_attribute['name'],
+ 'text' => $product_attribute['text']
+ );
+ }
+
+ $product_attribute_group_data[] = array(
+ 'attribute_group_id' => $product_attribute_group['attribute_group_id'],
+ 'name' => $product_attribute_group['name'],
+ 'attribute' => $product_attribute_data
+ );
+ }
+
+ return $product_attribute_group_data;
+ }
+}
diff --git a/public/admin/model/extension/openbay/ebay_product.php b/public/admin/model/extension/openbay/ebay_product.php
new file mode 100644
index 0000000..40c2af9
--- /dev/null
+++ b/public/admin/model/extension/openbay/ebay_product.php
@@ -0,0 +1,101 @@
+<?php
+class ModelExtensionOpenBayEbayProduct extends Model {
+ public function getTaxRate($class_id) {
+ return $this->openbay->getTaxRate($class_id);
+ }
+
+ public function countImportImages() {
+ $qry = $this->db->query("SELECT * FROM `" . DB_PREFIX . "ebay_image_import`");
+
+ return $qry->num_rows;
+ }
+
+ public function getProductOptions($product_id) {
+ $product_option_data = array();
+
+ $product_option_query = $this->db->query("SELECT * FROM " . DB_PREFIX . "product_option po LEFT JOIN `" . DB_PREFIX . "option` o ON (po.option_id = o.option_id) LEFT JOIN " . DB_PREFIX . "option_description od ON (o.option_id = od.option_id) WHERE po.product_id = '" . (int)$product_id . "' AND od.language_id = '" . (int)$this->config->get('config_language_id') . "' ORDER BY o.sort_order");
+
+ foreach ($product_option_query->rows as $product_option) {
+ if ($product_option['type'] == 'select' || $product_option['type'] == 'radio' || $product_option['type'] == 'image') {
+ $product_option_value_data = array();
+
+ $product_option_value_query = $this->db->query("SELECT * FROM " . DB_PREFIX . "product_option_value pov LEFT JOIN " . DB_PREFIX . "option_value ov ON (pov.option_value_id = ov.option_value_id) LEFT JOIN " . DB_PREFIX . "option_value_description ovd ON (ov.option_value_id = ovd.option_value_id) WHERE pov.product_option_id = '" . (int)$product_option['product_option_id'] . "' AND ovd.language_id = '" . (int)$this->config->get('config_language_id') . "' ORDER BY ov.sort_order");
+
+ foreach ($product_option_value_query->rows as $product_option_value) {
+ $product_option_value_data[] = array(
+ 'product_option_value_id' => $product_option_value['product_option_value_id'],
+ 'option_value_id' => $product_option_value['option_value_id'],
+ 'name' => $product_option_value['name'],
+ 'image' => $product_option_value['image'],
+ 'image_thumb' => (!empty($product_option_value['image'])) ? $this->model_tool_image->resize($product_option_value['image'], 100, 100) : '',
+ 'quantity' => $product_option_value['quantity'],
+ 'subtract' => $product_option_value['subtract'],
+ 'price' => $product_option_value['price'],
+ 'price_prefix' => $product_option_value['price_prefix'],
+ 'points' => $product_option_value['points'],
+ 'points_prefix' => $product_option_value['points_prefix'],
+ 'weight' => $product_option_value['weight'],
+ 'weight_prefix' => $product_option_value['weight_prefix']
+ );
+ }
+
+ $product_option_data[] = array(
+ 'product_option_id' => $product_option['product_option_id'],
+ 'option_id' => $product_option['option_id'],
+ 'name' => $product_option['name'],
+ 'type' => $product_option['type'],
+ 'product_option_value' => $product_option_value_data,
+ 'required' => $product_option['required']
+ );
+ }
+ }
+
+ return $product_option_data;
+ }
+
+ public function repairLinks() {
+ //get distinct product id's where they are active
+ $sql = $this->db->query("
+ SELECT DISTINCT `product_id`
+ FROM `" . DB_PREFIX . "ebay_listing`
+ WHERE `status` = '1'");
+
+ //loop over products and if count is more than 1, update all older entries to 0
+ foreach($sql->rows as $row) {
+ $sql2 = $this->db->query("SELECT * FROM `" . DB_PREFIX . "ebay_listing` WHERE `product_id` = '" . (int)$row['product_id'] . "' AND `status` = 1 ORDER BY `ebay_listing_id` DESC");
+
+ if ($sql2->num_rows > 1) {
+ $this->db->query("UPDATE `" . DB_PREFIX . "ebay_listing` SET `status` = 0 WHERE `product_id` = '" . (int)$row['product_id'] . "'");
+ $this->db->query("UPDATE `" . DB_PREFIX . "ebay_listing` SET `status` = 1 WHERE `ebay_listing_id` = '" . (int)$sql2->row['ebay_listing_id'] . "'");
+ }
+ }
+ }
+
+ public function searchEbayCatalog($search, $category_id, $page = 1) {
+ $response = $this->openbay->ebay->call('listing/searchCatalog/', array('page' => (int)$page, 'categoryId' => $category_id, 'search' => $search));
+
+ return $response;
+ }
+
+ public function getPartsCompatibilityOptions($category_id) {
+ $response = $this->openbay->ebay->call('partscompatibility/getOptions/', array('category_id' => $category_id));
+
+ return $response;
+ }
+
+ public function getPartsCompatibilityValues($filters) {
+ $response = $this->openbay->ebay->call('partscompatibility/getValues/', $filters);
+
+ return $response;
+ }
+
+ public function getItemRecommendations($filters) {
+ $response = $this->openbay->ebay->call('listingrecommendation/recommendations/', $filters);
+
+ return array(
+ 'error' => $this->openbay->ebay->lasterror,
+ 'error_message' => $this->openbay->ebay->lastmsg,
+ 'data' => $response
+ );
+ }
+} \ No newline at end of file
diff --git a/public/admin/model/extension/openbay/ebay_profile.php b/public/admin/model/extension/openbay/ebay_profile.php
new file mode 100644
index 0000000..0099039
--- /dev/null
+++ b/public/admin/model/extension/openbay/ebay_profile.php
@@ -0,0 +1,106 @@
+<?php
+class ModelExtensionOpenBayEbayProfile extends Model{
+ public function add($data) {
+ if ($data['default'] == 1) {
+ $this->clearDefault($data['type']);
+ }
+
+ $this->db->query("INSERT INTO `" . DB_PREFIX . "ebay_profile` SET `name` = '" . $this->db->escape($data['name']) . "', `description` = '" . $this->db->escape($data['description']) . "', `type` = '" . (int)$data['type'] . "', `default` = '" . (int)$data['default'] . "', `data` = '" . $this->db->escape(serialize($data['data'])) . "'");
+
+ return $this->db->getLastId();
+ }
+
+ public function edit($id, $data) {
+ if ($data['default'] == 1) {
+ $this->clearDefault($data['type']);
+ }
+
+ $this->db->query("UPDATE `" . DB_PREFIX . "ebay_profile` SET `name` = '" . $this->db->escape($data['name']) . "', `description` = '" . $this->db->escape($data['description']) . "', `data` = '" . $this->db->escape(serialize($data['data'])) . "', `default` = '" . (int)$data['default'] . "' WHERE `ebay_profile_id` = '" . (int)$id . "' LIMIT 1");
+ }
+
+ public function delete($id) {
+ $this->db->query("DELETE FROM `" . DB_PREFIX . "ebay_profile` WHERE `ebay_profile_id` = '" . (int)$id . "' LIMIT 1");
+
+ if ($this->db->countAffected() > 0) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ public function get($id) {
+ $qry = $this->db->query("SELECT * FROM `" . DB_PREFIX . "ebay_profile` WHERE `ebay_profile_id` = '" . (int)$id . "' LIMIT 1");
+
+ if ($qry->num_rows) {
+ $row = $qry->row;
+ $row['link_edit'] = $this->url->link('extension/openbay/ebay_profile/edit', 'user_token=' . $this->session->data['user_token'] . '&ebay_profile_id=' . $row['ebay_profile_id'], true);
+ $row['link_delete'] = $this->url->link('extension/openbay/ebay_profile/delete', 'user_token=' . $this->session->data['user_token'] . '&ebay_profile_id=' . $row['ebay_profile_id'], true);
+ $row['data'] = unserialize($row['data']);
+
+ return $row;
+ } else {
+ return false;
+ }
+ }
+
+ public function getAll($type = '') {
+ $sql = "SELECT * FROM `" . DB_PREFIX . "ebay_profile`";
+
+ if ($type !== '') {
+ $sql .= " WHERE `type` = '" . (int)$type . "'";
+ }
+
+ $qry = $this->db->query($sql);
+
+ if ($qry->num_rows) {
+ $profiles = array();
+ foreach ($qry->rows as $row) {
+ $row['link_edit'] = $this->url->link('extension/openbay/ebay_profile/edit', 'user_token=' . $this->session->data['user_token'] . '&ebay_profile_id=' . $row['ebay_profile_id'], true);
+ $row['link_delete'] = $this->url->link('extension/openbay/ebay_profile/delete', 'user_token=' . $this->session->data['user_token'] . '&ebay_profile_id=' . $row['ebay_profile_id'], true);
+ $row['data'] = !empty($row['data']) ? unserialize($row['data']) : array();
+ $profiles[] = $row;
+ }
+
+ return $profiles;
+ } else {
+ return false;
+ }
+ }
+
+ public function getTypes() {
+ $types = array(
+ 0 => array(
+ 'name' => $this->language->get('text_type_shipping'),
+ 'template' => 'extension/openbay/ebay_profile_form_shipping'
+ ),
+ 1 => array(
+ 'name' => $this->language->get('text_type_returns'),
+ 'template' => 'extension/openbay/ebay_profile_form_returns'
+ ),
+ 2 => array(
+ 'name' => $this->language->get('text_type_template'),
+ 'template' => 'extension/openbay/ebay_profile_form_template'
+ ),
+ 3 => array(
+ 'name' => $this->language->get('text_type_general'),
+ 'template' => 'extension/openbay/ebay_profile_form_generic'
+ )
+ );
+
+ return $types;
+ }
+
+ public function getDefault($type) {
+ $qry = $this->db->query("SELECT `ebay_profile_id` FROM `" . DB_PREFIX . "ebay_profile` WHERE `type` = '" . (int)$type . "' AND `default` = '1'LIMIT 1");
+
+ if ($qry->num_rows) {
+ return (int)$qry->row['ebay_profile_id'];
+ } else {
+ return false;
+ }
+ }
+
+ private function clearDefault($type) {
+ $this->db->query("UPDATE `" . DB_PREFIX . "ebay_profile` SET `default` = '0' WHERE `type` = '" . (int)$type . "'");
+ }
+} \ No newline at end of file
diff --git a/public/admin/model/extension/openbay/ebay_template.php b/public/admin/model/extension/openbay/ebay_template.php
new file mode 100644
index 0000000..b367059
--- /dev/null
+++ b/public/admin/model/extension/openbay/ebay_template.php
@@ -0,0 +1,51 @@
+<?php
+class ModelExtensionOpenBayEbayTemplate extends Model {
+ public function add($data) {
+ $this->db->query("INSERT INTO `" . DB_PREFIX . "ebay_template` SET `name` = '" . $this->db->escape($data['name']) . "', `html` = '" . $this->db->escape($data['html']) . "'");
+ return $this->db->getLastId();
+ }
+
+ public function edit($id, $data) {
+ $this->db->query("UPDATE `" . DB_PREFIX . "ebay_template` SET `name` = '" . $this->db->escape($data['name']) . "', `html` = '" . $this->db->escape($data['html']) . "' WHERE `template_id` = '" . (int)$id . "' LIMIT 1");
+ }
+
+ public function delete($id) {
+ $qry = $this->db->query("DELETE FROM `" . DB_PREFIX . "ebay_template` WHERE `template_id` = '" . (int)$id . "' LIMIT 1");
+
+ if ($qry->countAffected() > 0) {
+ return true;
+ }else{
+ return false;
+ }
+ }
+
+ public function get($id) {
+ $qry = $this->db->query("SELECT * FROM `" . DB_PREFIX . "ebay_template` WHERE `template_id` = '" . (int)$id . "' LIMIT 1");
+
+ if ($qry->num_rows) {
+ $row = $qry->row;
+ $row['link_edit'] = $this->url->link('extension/openbay/ebay_template/edit&user_token=' . $this->session->data['user_token'] . '&template_id=' . $row['template_id'], true);
+ $row['link_delete'] = $this->url->link('extension/openbay/ebay_template/delete&user_token=' . $this->session->data['user_token'] . '&template_id=' . $row['template_id'], true);
+
+ return $row;
+ }else{
+ return false;
+ }
+ }
+
+ public function getAll() {
+ $qry = $this->db->query("SELECT * FROM `" . DB_PREFIX . "ebay_template`");
+
+ $templates = array();
+
+ if($qry->num_rows) {
+ foreach($qry->rows as $row) {
+ $row['link_edit'] = $this->url->link('extension/openbay/ebay_template/edit&user_token=' . $this->session->data['user_token'] . '&template_id=' . $row['template_id'], true);
+ $row['link_delete'] = $this->url->link('extension/openbay/ebay_template/delete&user_token=' . $this->session->data['user_token'] . '&template_id=' . $row['template_id'], true);
+ $templates[] = $row;
+ }
+ }
+
+ return $templates;
+ }
+}
diff --git a/public/admin/model/extension/openbay/etsy.php b/public/admin/model/extension/openbay/etsy.php
new file mode 100644
index 0000000..fec7862
--- /dev/null
+++ b/public/admin/model/extension/openbay/etsy.php
@@ -0,0 +1,73 @@
+<?php
+class ModelExtensionOpenBayEtsy extends Model{
+ public function install() {
+ $this->load->model('setting/event');
+
+ $this->model_setting_event->addEvent('openbay_etsy_add_order', 'catalog/model/checkout/order/addOrderHistory/after', 'extension/openbay/etsy/eventAddOrderHistory');
+
+ $settings = array();
+ $settings["etsy_token"] = '';
+ $settings["etsy_secret"] = '';
+ $settings["etsy_encryption_key"] = '';
+ $settings["etsy_encryption_iv"] = '';
+ $settings["etsy_logging"] = '1';
+
+ $this->model_setting_setting->editSetting('etsy', $settings);
+
+ $this->db->query("
+ CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "etsy_setting_option` (
+ `etsy_setting_option_id` INT(11) NOT NULL AUTO_INCREMENT,
+ `key` VARCHAR(100) NOT NULL,
+ `last_updated` DATETIME NOT NULL,
+ `data` TEXT NOT NULL,
+ PRIMARY KEY (`etsy_setting_option_id`)
+ ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci;");
+
+ $this->db->query("
+ CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "etsy_listing` (
+ `etsy_listing_id` int(11) NOT NULL AUTO_INCREMENT,
+ `etsy_item_id` char(100) NOT NULL,
+ `product_id` int(11) NOT NULL,
+ `status` SMALLINT(3) NOT NULL DEFAULT '1',
+ `created` DATETIME NOT NULL,
+ PRIMARY KEY (`etsy_listing_id`),
+ KEY `product_id` (`product_id`)
+ ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci;");
+
+ $this->db->query("
+ CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "etsy_order` (
+ `etsy_order_id` int(11) NOT NULL AUTO_INCREMENT,
+ `order_id` int(11) NOT NULL,
+ `receipt_id` int(11) NOT NULL,
+ `paid` int(1) NOT NULL,
+ `shipped` int(1) NOT NULL,
+ PRIMARY KEY (`etsy_order_id`),
+ KEY `order_id` (`order_id`)
+ ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci;");
+
+ $this->db->query("
+ CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "etsy_order_lock` (
+ `order_id` int(11) NOT NULL,
+ PRIMARY KEY (`order_id`)
+ ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci;");
+ }
+
+ public function uninstall() {
+ $this->load->model('setting/event');
+ $this->model_setting_event->deleteEventByCode('openbay_etsy_add_order');
+ }
+
+ public function patch() {
+ if ($this->config->get('etsy_status') == 1) {
+
+ }
+ }
+
+ public function verifyAccount() {
+ if ($this->openbay->etsy->validate() == true) {
+ return $this->openbay->etsy->call('v1/etsy/account/info/', 'GET');
+ } else {
+ return false;
+ }
+ }
+}
diff --git a/public/admin/model/extension/openbay/etsy_product.php b/public/admin/model/extension/openbay/etsy_product.php
new file mode 100644
index 0000000..876ef16
--- /dev/null
+++ b/public/admin/model/extension/openbay/etsy_product.php
@@ -0,0 +1,75 @@
+<?php
+class ModelExtensionOpenBayEtsyProduct extends Model{
+ public function getStatus($product_id) {
+ $query = $this->db->query("SELECT * FROM `" . DB_PREFIX . "etsy_listing` WHERE `product_id` = '" . (int)$product_id . "' AND `status` = 1 LIMIT 1");
+
+ if ($query->num_rows == 0) {
+ return 0;
+ } else {
+ return 1;
+ }
+ }
+
+ public function totalLinked() {
+ $sql = "SELECT COUNT(DISTINCT p.product_id) AS total
+ FROM `" . DB_PREFIX . "etsy_listing` `el`
+ LEFT JOIN `" . DB_PREFIX . "product` `p` ON (`el`.`product_id` = `p`.`product_id`)
+ LEFT JOIN `" . DB_PREFIX . "product_description` `pd` ON (`p`.`product_id` = `pd`.`product_id`)
+ WHERE `el`.`status` = '1'
+ AND `pd`.`language_id` = '" . (int)$this->config->get('config_language_id') . "'";
+
+ $query = $this->db->query($sql);
+
+ return (int)$query->row['total'];
+ }
+
+ public function addLink($product_id, $etsy_item_id, $status_id = 0) {
+ $this->db->query("INSERT INTO `" . DB_PREFIX . "etsy_listing` SET `product_id` = '" . (int)$product_id . "', `etsy_item_id` = '" . $this->db->escape($etsy_item_id) . "', `status` = '" . (int)$status_id . "', `created` = now()");
+ }
+
+ public function loadLinked($limit = 100, $page = 1) {
+ $this->load->model('tool/image');
+
+ $start = $limit * ($page - 1);
+
+ $sql = "
+ SELECT
+ `el`.`etsy_listing_id`,
+ `el`.`etsy_item_id`,
+ `el`.`status`,
+ `p`.`product_id`,
+ `p`.`sku`,
+ `p`.`model`,
+ `p`.`quantity`,
+ `pd`.`name`
+ FROM `" . DB_PREFIX . "etsy_listing` `el`
+ LEFT JOIN `" . DB_PREFIX . "product` `p` ON (`el`.`product_id` = `p`.`product_id`)
+ LEFT JOIN `" . DB_PREFIX . "product_description` `pd` ON (`p`.`product_id` = `pd`.`product_id`)
+ WHERE `el`.`status` = '1'
+ AND `pd`.`language_id` = '" . (int)$this->config->get('config_language_id') . "'";
+
+ $sql .= " LIMIT " . (int)$start . "," . (int)$limit;
+
+ $qry = $this->db->query($sql);
+
+ $data = array();
+ if ($qry->num_rows) {
+ foreach($qry->rows as $row) {
+ $data[] = array(
+ 'etsy_listing_id' => $row['etsy_listing_id'],
+ 'product_id' => $row['product_id'],
+ 'sku' => $row['sku'],
+ 'model' => $row['model'],
+ 'quantity' => $row['quantity'],
+ 'name' => $row['name'],
+ 'status' => $row['status'],
+ 'etsy_item_id' => $row['etsy_item_id'],
+ 'link_edit' => $this->url->link('catalog/product/edit', 'user_token=' . $this->session->data['user_token'] . '&product_id=' . $row['product_id'], true),
+ 'link_etsy' => 'http://www.etsy.com/listing/' . $row['etsy_item_id'],
+ );
+ }
+ }
+
+ return $data;
+ }
+} \ No newline at end of file
diff --git a/public/admin/model/extension/openbay/fba.php b/public/admin/model/extension/openbay/fba.php
new file mode 100644
index 0000000..f74641d
--- /dev/null
+++ b/public/admin/model/extension/openbay/fba.php
@@ -0,0 +1,65 @@
+<?php
+class ModelExtensionOpenBayFba extends Model {
+ public function install() {
+ $this->load->model('setting/event');
+
+ $this->model_setting_event->addEvent('openbay_fba_add_order', 'catalog/model/checkout/order/addOrder/after', 'extension/openbay/fba/eventAddOrder');
+ $this->model_setting_event->addEvent('openbay_fba_add_orderhistory', 'catalog/model/checkout/order/addOrderHistory/after', 'extension/openbay/fba/eventAddOrderHistory');
+
+ $this->db->query("
+ CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "fba_order` (
+ `order_id` INT(11) NOT NULL,
+ `fba_order_fulfillment_id` INT(11) NOT NULL,
+ `fba_order_fulfillment_ref` CHAR(50) NOT NULL,
+ `status` CHAR(10) NOT NULL,
+ `created` DATETIME NOT NULL,
+ KEY `fba_order_id` (`order_id`)
+ ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci;");
+
+ $this->db->query("
+ CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "fba_order_fulfillment` (
+ `fba_order_fulfillment_id` INT(11) NOT NULL AUTO_INCREMENT,
+ `order_id` INT(11) NOT NULL,
+ `created` DATETIME NOT NULL,
+ `request_body` TEXT NOT NULL,
+ `response_body` TEXT NOT NULL,
+ `response_header_code` INT(3) NOT NULL,
+ `type` INT(3) NOT NULL,
+ PRIMARY KEY (`fba_order_fulfillment_id`),
+ KEY `order_id` (`order_id`)
+ ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci;");
+
+ // Default settings
+ $setting = array();
+ $setting["openbay_fba_status"] = 0;
+ $setting["openbay_fba_send_orders"] = 0;
+ $setting["openbay_fba_debug_log"] = 1;
+ $setting["openbay_fba_order_trigger_status"] = 15;
+ $setting["openbay_fba_cancel_order_trigger_status"] = 7;
+ $setting["openbay_fba_fulfill_policy"] = 'FillAllAvailable';
+ $setting["openbay_fba_shipping_speed"] = 'Standard';
+ $setting["openbay_fba_order_prefix"] = 'OC-';
+
+ $this->model_setting_setting->editSetting('openbay_fba', $setting);
+ }
+
+ public function uninstall() {
+ $this->db->query("DELETE FROM `" . DB_PREFIX . "setting` WHERE `code` = 'openbay_fba'");
+
+ $this->load->model('setting/event');
+ $this->model_setting_event->deleteEventByCode('openbay_fba_add_order');
+ $this->model_setting_event->deleteEventByCode('openbay_fba_add_orderhistory');
+ }
+
+ public function patch() {
+ if ($this->config->get('openbay_fba_status') == 1) {
+
+ }
+ }
+
+ public function countFbaOrders() {
+ $query = $this->db->query("SELECT COUNT(*) AS `total` FROM `" . DB_PREFIX . "fba_order`");
+
+ return (int)$query->row['total'];
+ }
+}
diff --git a/public/admin/model/extension/openbay/openbay.php b/public/admin/model/extension/openbay/openbay.php
new file mode 100644
index 0000000..c40c357
--- /dev/null
+++ b/public/admin/model/extension/openbay/openbay.php
@@ -0,0 +1,761 @@
+<?php
+class ModelExtensionOpenBayOpenbay extends Model {
+ private $url = 'https://account.openbaypro.com/';
+ private $error;
+ private $branch_version = 6;
+
+ public function patch() {
+
+ }
+
+ public function updateTest() {
+ $this->error = array();
+
+ $this->openbay->log('Starting update test');
+
+ if (!function_exists("exception_error_handler")) {
+ function exception_error_handler($errno, $errstr, $errfile, $errline ) {
+ throw new ErrorException($errstr, 0, $errno, $errfile, $errline);
+ }
+ }
+
+ set_error_handler('exception_error_handler');
+
+ // create a tmp folder
+ if (!is_dir(DIR_DOWNLOAD . '/tmp')) {
+ try {
+ mkdir(DIR_DOWNLOAD . '/tmp');
+ } catch(ErrorException $ex) {
+ $this->error[] = $ex->getMessage();
+ }
+ }
+
+ // create tmp file
+ try {
+ $tmp_file = fopen(DIR_DOWNLOAD . '/tmp/test_file.php', 'w+');
+ } catch(ErrorException $ex) {
+ $this->error[] = $ex->getMessage();
+ }
+
+ // open and write over tmp file
+ try {
+ $output = '<?php' . "\n";
+ $output .= '$test = \'12345\';' . "\n";
+ $output .= 'echo $test;' . "\n";
+
+ fwrite($tmp_file, $output);
+ fclose($tmp_file);
+ } catch(ErrorException $ex) {
+ $this->error[] = $ex->getMessage();
+ }
+
+ // try and read the file
+
+ // remove tmp file
+ try {
+ unlink(DIR_DOWNLOAD . '/tmp/test_file.php');
+ } catch(ErrorException $ex) {
+ $this->error[] = $ex->getMessage();
+ }
+
+ // delete tmp folder
+ try {
+ rmdir(DIR_DOWNLOAD . '/tmp');
+ } catch(ErrorException $ex) {
+ $this->error[] = $ex->getMessage();
+ }
+
+ // reset to the OC error handler
+ restore_error_handler();
+
+ $this->openbay->log('Finished update test');
+
+ if (!$this->error) {
+ $this->openbay->log('Finished update test - no errors');
+ return array('error' => 0, 'response' => '', 'percent_complete' => 20, 'status_message' => $this->language->get('text_check_new'));
+ } else {
+ $this->openbay->log('Finished update test - errors: ' . print_r($this->error));
+ return array('error' => 1, 'response' => $this->error);
+ }
+ }
+
+ public function updateCheckVersion($beta = 0) {
+ $current_version = $this->config->get('feed_openbaypro_version');
+
+ $this->openbay->log('Start check version, beta: ' . $beta . ', current: ' . $current_version);
+
+ $post = array('version' => $this->branch_version, 'beta' => $beta);
+
+ $data = $this->call('update/version/', $post);
+
+ if ($this->lasterror == true) {
+ $this->openbay->log('Check version error: ' . $this->lastmsg);
+
+ return array('error' => 1, 'response' => $this->lastmsg . ' (' . VERSION . ')');
+ } else {
+ if ($data['version'] > $current_version) {
+ $this->openbay->log('Check version new available: ' . $data['version']);
+ return array('error' => 0, 'response' => $data['version'], 'percent_complete' => 40, 'status_message' => $this->language->get('text_downloading'));
+ } else {
+ $this->openbay->log('Check version - already latest');
+ return array('error' => 1, 'response' => $this->language->get('text_version_ok') . $current_version);
+ }
+ }
+ }
+
+ public function updateDownload($beta = 0) {
+ $this->openbay->log('Downloading');
+
+ $local_file = DIR_DOWNLOAD . '/openbaypro_update.zip';
+ $handle = fopen($local_file, "w+");
+
+ $post = array('version' => $this->branch_version, 'beta' => $beta);
+
+ $defaults = array(
+ CURLOPT_POST => 1,
+ CURLOPT_HEADER => 0,
+ CURLOPT_URL => $this->url . 'update/download/',
+ CURLOPT_USERAGENT => 'OpenBay Pro update script',
+ CURLOPT_FRESH_CONNECT => 1,
+ CURLOPT_RETURNTRANSFER => 1,
+ CURLOPT_FORBID_REUSE => 1,
+ CURLOPT_TIMEOUT => 0,
+ CURLOPT_SSL_VERIFYPEER => 0,
+ CURLOPT_SSL_VERIFYHOST => 0,
+ CURLOPT_POSTFIELDS => http_build_query($post, '', "&"),
+ CURLOPT_FILE => $handle
+ );
+
+ $curl = curl_init();
+ curl_setopt_array($curl, $defaults);
+ curl_exec($curl);
+
+ $curl_error = curl_error ($curl);
+
+ $this->openbay->log('Download errors: ' . $curl_error);
+
+ curl_close($curl);
+
+ return array('error' => 0, 'response' => $curl_error, 'percent_complete' => 60, 'status_message' => $this->language->get('text_extracting'));
+ }
+
+ public function updateExtract() {
+ $this->error = array();
+
+ $web_root = preg_replace('/system\/$/', '', DIR_SYSTEM);
+
+ if (!function_exists("exception_error_handler")) {
+ function exception_error_handler($errno, $errstr, $errfile, $errline ) {
+ throw new ErrorException($errstr, 0, $errno, $errfile, $errline);
+ }
+ }
+
+ set_error_handler('exception_error_handler');
+
+ try {
+ $zip = new ZipArchive();
+
+ if ($zip->open(DIR_DOWNLOAD . 'openbaypro_update.zip')) {
+ $zip->extractTo($web_root);
+ $zip->close();
+ } else {
+ $this->openbay->log('Unable to extract update files');
+
+ $this->error[] = $this->language->get('text_fail_patch');
+ }
+ } catch(ErrorException $ex) {
+ $this->openbay->log('Unable to extract update files');
+ $this->error[] = $ex->getMessage();
+ }
+
+ // reset to the OC error handler
+ restore_error_handler();
+
+ if (!$this->error) {
+ return array('error' => 0, 'response' => '', 'percent_complete' => 80, 'status_message' => $this->language->get('text_remove_files'));
+ } else {
+ return array('error' => 1, 'response' => $this->error);
+ }
+ }
+
+ public function updateRemove($beta = 0) {
+ $this->error = array();
+
+ $web_root = preg_replace('/system\/$/', '', DIR_SYSTEM);
+
+ if (!function_exists("exception_error_handler")) {
+ function exception_error_handler($errno, $errstr, $errfile, $errline ) {
+ throw new ErrorException($errstr, 0, $errno, $errfile, $errline);
+ }
+ }
+
+ $this->openbay->log('Get files to remove, beta: ' . $beta);
+
+ $post = array('beta' => $beta);
+
+ $files = $this->call('update/getRemoveList/', $post);
+
+ $this->openbay->log("Remove Files: " . print_r($files, 1));
+
+ if (!empty($files['asset']) && is_array($files['asset'])) {
+ foreach($files['asset'] as $file) {
+ $filename = $web_root . implode('/', $file['locations']['location']) . '/' . $file['name'];
+
+ if (file_exists($filename)) {
+ try {
+ unlink($filename);
+ } catch(ErrorException $ex) {
+ $this->openbay->log('Unable to remove file: ' . $filename . ', ' . $ex->getMessage());
+ $this->error[] = $filename;
+ }
+ }
+ }
+ }
+
+ // reset to the OC error handler
+ restore_error_handler();
+
+ if (!$this->error) {
+ return array('error' => 0, 'response' => '', 'percent_complete' => 90, 'status_message' => $this->language->get('text_running_patch'));
+ } else {
+ $response_error = '<p>' . $this->language->get('error_file_delete') . '</p>';
+ $response_error .= '<ul>';
+
+ foreach($this->error as $error_file) {
+ $response_error .= '<li>' . $error_file . '</li>';
+ }
+
+ $response_error .= '</ul>';
+
+ return array('error' => 1, 'response' => $response_error, 'percent_complete' => 90, 'status_message' => $this->language->get('text_running_patch'));
+ }
+ }
+
+ public function updateUpdateVersion($beta = 0) {
+ $this->openbay->log('Updating the version in settings');
+
+ $post = array('version' => $this->branch_version, 'beta' => $beta);
+
+ $data = $this->call('update/version/', $post);
+
+ if ($this->lasterror == true) {
+ $this->openbay->log('Update version error: ' . $this->lastmsg);
+
+ return array('error' => 1, 'response' => $this->lastmsg . ' (' . VERSION . ')');
+ } else {
+ $this->load->model('setting/setting');
+
+ $settings = $this->model_setting_setting->getSetting('feed_openbaypro');
+
+ $settings['feed_openbaypro_version'] = $data['version'];
+
+ $this->model_setting_setting->editSetting('feed_openbaypro', $settings);
+
+ return array('error' => 0, 'response' => $data['version'], 'percent_complete' => 100, 'status_message' => $this->language->get('text_updated_ok') . $data['version']);
+ }
+ }
+
+ public function setUrl($url) {
+ $this->url = $url;
+ }
+
+ public function getNotifications() {
+ $data = $this->call('update/getNotifications/');
+ return $data;
+ }
+
+ public function version() {
+ $data = $this->call('update/getStableVersion/');
+
+ if ($this->lasterror == true) {
+ $data = array(
+ 'error' => true,
+ 'msg' => $this->lastmsg . ' (' . VERSION . ')',
+ );
+
+ return $data;
+ } else {
+ return $data;
+ }
+ }
+
+ public function faqGet($route) {
+ if ($this->faqIsDismissed($route) != true) {
+ $data = $this->call('faq/get/', array('route' => $route));
+
+ return $data;
+ } else {
+ return false;
+ }
+ }
+
+ public function faqIsDismissed($route) {
+ $this->faqDbTableCheck();
+
+ $sql = $this->db->query("SELECT * FROM `" . DB_PREFIX . "openbay_faq` WHERE `route` = '" . $this->db->escape($route) . "'");
+
+ if ($sql->num_rows > 0) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ public function faqDismiss($route) {
+ $this->faqDbTableCheck();
+ $this->db->query("INSERT INTO `" . DB_PREFIX . "openbay_faq` SET `route` = '" . $this->db->escape($route) . "'");
+ }
+
+ public function faqClear() {
+ $this->faqDbTableCheck();
+ $this->db->query("TRUNCATE `" . DB_PREFIX . "openbay_faq`");
+ }
+
+ public function faqDbTableCheck() {
+ if (!$this->openbay->testDbTable(DB_PREFIX . "openbay_faq")) {
+ $this->db->query("CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "openbay_faq` (`id` int(11) NOT NULL AUTO_INCREMENT,`route` text NOT NULL, PRIMARY KEY (`id`)) ENGINE=MyISAM DEFAULT CHARSET=utf8;");
+ }
+ }
+
+ public function requirementTest() {
+ $error = array();
+
+ // check for mkdir enabled
+ if (!function_exists('mkdir')) {
+ $error[] = $this->language->get('error_mkdir');
+ }
+
+ if (!function_exists('openssl_encrypt')) {
+ $error[] = $this->language->get('error_openssl_encrypt');
+ }
+
+ if (!function_exists('openssl_decrypt')) {
+ $error[] = $this->language->get('error_openssl_decrypt');
+ }
+
+ if (!function_exists('fopen')) {
+ $error[] = $this->language->get('error_fopen');
+ }
+
+ if (!function_exists('set_time_limit')) {
+ $error[] = $this->language->get('error_fopen');
+ }
+
+ if (!ini_get('allow_url_fopen')) {
+ $error[] = $this->language->get('error_url_fopen');
+ }
+
+ if (!extension_loaded('curl')) {
+ $error[] = $this->language->get('error_curl');
+ }
+
+ if (!extension_loaded('zip')) {
+ $error[] = $this->language->get('error_zip');
+ }
+
+ if (!function_exists('mb_detect_encoding')) {
+ $error[] = $this->language->get('error_mbstring');
+ }
+
+ return $error;
+ }
+
+ private function call($call, array $post = null, array $options = array(), $content_type = 'json') {
+ $data = array(
+ 'language' => $this->config->get('feed_openbaypro_language'),
+ 'server' => 1,
+ 'domain' => HTTP_CATALOG,
+ 'openbay_version' => (int)$this->config->get('feed_openbaypro_version'),
+ 'data' => $post,
+ 'content_type' => $content_type,
+ 'ocversion' => VERSION
+ );
+
+ $useragent = "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.1) Gecko/20061204 Firefox/2.0.0.1";
+
+ $defaults = array(
+ CURLOPT_POST => 1,
+ CURLOPT_HEADER => 0,
+ CURLOPT_URL => $this->url . $call,
+ CURLOPT_USERAGENT => $useragent,
+ CURLOPT_FRESH_CONNECT => 1,
+ CURLOPT_RETURNTRANSFER => 1,
+ CURLOPT_FORBID_REUSE => 1,
+ CURLOPT_TIMEOUT => 0,
+ CURLOPT_SSL_VERIFYPEER => 0,
+ CURLOPT_SSL_VERIFYHOST => 0,
+ CURLOPT_POSTFIELDS => http_build_query($data, '', "&")
+ );
+
+ $curl = curl_init();
+ curl_setopt_array($curl, ($options + $defaults));
+ $result = curl_exec($curl);
+ curl_close($curl);
+
+ if ($content_type == 'json') {
+ $encoding = mb_detect_encoding($result);
+
+ /* some json data may have BOM due to php not handling types correctly */
+ if ($encoding == 'UTF-8') {
+ $result = preg_replace('/[^(\x20-\x7F)]*/', '', $result);
+ }
+
+ $result = json_decode($result, 1);
+ $this->lasterror = $result['error'];
+ $this->lastmsg = $result['msg'];
+
+ if (!empty($result['data'])) {
+ return $result['data'];
+ } else {
+ return false;
+ }
+ } elseif ($content_type == 'xml') {
+ $result = simplexml_load_string($result);
+ $this->lasterror = $result->error;
+ $this->lastmsg = $result->msg;
+
+ if (!empty($result->data)) {
+ return $result->data;
+ } else {
+ return false;
+ }
+ }
+ }
+
+ public function getTotalProducts($data = array()) {
+ $sql = "SELECT COUNT(DISTINCT p.product_id) AS total FROM " . DB_PREFIX . "product p LEFT JOIN " . DB_PREFIX . "product_description pd ON (p.product_id = pd.product_id)";
+
+ if (!empty($data['filter_category'])) {
+ $sql .= " LEFT JOIN " . DB_PREFIX . "product_to_category p2c ON (p.product_id = p2c.product_id)";
+ }
+
+ if ($data['filter_market_name'] == 'ebay') {
+ $sql .= " LEFT JOIN `" . DB_PREFIX . "ebay_listing` `ebay` ON (`p`.`product_id` = `ebay`.`product_id`)";
+
+ if ($data['filter_market_id'] == 0) {
+ $sql .= " LEFT JOIN (SELECT product_id, IF( SUM( `status` ) = 0, 0, 1 ) AS 'listing_status' FROM " . DB_PREFIX . "ebay_listing GROUP BY product_id ) ebay2 ON (p.product_id = ebay2.product_id)";
+ }
+ }
+
+ if ($data['filter_market_name'] == 'amazon') {
+ if ($data['filter_market_id'] <= 4) {
+ $sql .= " LEFT JOIN " . DB_PREFIX . "amazon_product ap ON p.product_id = ap.product_id";
+ } else {
+ $sql .= " LEFT JOIN " . DB_PREFIX . "amazon_product_link apl ON p.product_id = apl.product_id";
+ }
+
+ $amazon_status = array(
+ 1 => 'saved',
+ 2 => 'uploaded',
+ 3 => 'ok',
+ 4 => 'error',
+ 5 => 'amazon_linked',
+ 6 => 'amazon_not_linked',
+ );
+ }
+
+ $sql .= " WHERE pd.language_id = '" . (int)$this->config->get('config_language_id') . "'";
+
+ if (!empty($data['filter_category'])) {
+ if ($data['filter_category'] == 'none') {
+ $sql .= " AND p2c.category_id IS NULL";
+ } else {
+ $sql .= " AND p2c.category_id = '" . (int)$data['filter_category'] . "'";
+ }
+ }
+
+ if ($data['filter_market_name'] == 'ebay') {
+ if ($data['filter_market_id'] == 0) {
+ $sql .= " AND (ebay.ebay_listing_id IS NULL OR ebay2.listing_status = 0)";
+ } else {
+ $sql .= " AND (ebay.ebay_listing_id IS NOT NULL AND ebay.status = 1)";
+ }
+ }
+
+ if ($data['filter_market_name'] == 'amazon') {
+ if ($data['filter_market_id'] == 0) {
+ $sql .= " AND ap.product_id IS NULL ";
+ } elseif ($data['filter_market_id'] == 5) {
+ $sql .= " AND apl.id IS NOT NULL";
+ } elseif ($data['filter_market_id'] == 6) {
+ $sql .= " AND apl.id IS NULL";
+ } else {
+ $sql .= " AND FIND_IN_SET('" . $this->db->escape($amazon_status[$data['filter_market_id']]) . "', ap.`status`) != 0";
+ }
+ }
+
+ if (isset($data['filter_name']) && !empty($data['filter_name']) && !is_null($data['filter_name'])) {
+ $sql .= " AND pd.name LIKE '" . $this->db->escape($data['filter_name']) . "%'";
+ }
+ if (isset($data['filter_model']) && !empty($data['filter_model']) && !is_null($data['filter_model'])) {
+ $sql .= " AND p.model LIKE '" . $this->db->escape($data['filter_model']) . "%'";
+ }
+ if (isset($data['filter_price']) && !empty($data['filter_price']) && !is_null($data['filter_price'])) {
+ $sql .= " AND p.price >= '" . (double)$data['filter_price'] . "'";
+ }
+ if (isset($data['filter_price_to']) && !empty($data['filter_price_to']) && !is_null($data['filter_price_to'])) {
+ $sql .= " AND p.price <= '" . (double)$data['filter_price_to'] . "'";
+ }
+ if (isset($data['filter_quantity']) && !empty($data['filter_quantity']) && !is_null($data['filter_quantity'])) {
+ $sql .= " AND p.quantity >= " . (int)$data['filter_quantity'];
+ }
+ if (isset($data['filter_quantity_to']) && !empty($data['filter_quantity_to']) && !is_null($data['filter_quantity_to'])) {
+ $sql .= " AND p.quantity <= " . (int)$data['filter_quantity_to'];
+ }
+ if (isset($data['filter_status']) && !empty($data['filter_status']) && !is_null($data['filter_status'])) {
+ $sql .= " AND p.status = " . (int)$data['filter_status'];
+ }
+ if (isset($data['filter_sku']) && !empty($data['filter_sku']) && !is_null($data['filter_sku'])) {
+ $sql .= " AND p.sku != ''";
+ }
+ if (isset($data['filter_desc']) && !empty($data['filter_desc']) && !is_null($data['filter_desc'])) {
+ $sql .= " AND pd.description != ''";
+ }
+ if (isset($data['filter_manufacturer']) && !empty($data['filter_price_to']) && !is_null($data['filter_manufacturer'])) {
+ $sql .= " AND p.manufacturer_id = " . (int)$data['filter_manufacturer'];
+ }
+
+ $query = $this->db->query($sql);
+
+ return $query->row['total'];
+ }
+
+ public function getProducts($data = array()) {
+ $sql = "SELECT p.*, pd.* FROM " . DB_PREFIX . "product p LEFT JOIN " . DB_PREFIX . "product_description pd ON (p.product_id = pd.product_id)";
+
+ if (!empty($data['filter_category'])) {
+ $sql .= " LEFT JOIN " . DB_PREFIX . "product_to_category p2c ON (p.product_id = p2c.product_id)";
+ }
+
+ if ($data['filter_market_name'] == 'ebay') {
+ $sql .= " LEFT JOIN `" . DB_PREFIX . "ebay_listing` `ebay` ON (`p`.`product_id` = `ebay`.`product_id`)";
+
+ if ($data['filter_market_id'] == 0) {
+ $sql .= " LEFT JOIN (SELECT product_id, IF( SUM( `status` ) = 0, 0, 1 ) AS 'listing_status' FROM " . DB_PREFIX . "ebay_listing GROUP BY product_id ) ebay2 ON (p.product_id = ebay2.product_id)";
+ }
+ }
+
+ if ($data['filter_market_name'] == 'amazon') {
+ if ($data['filter_market_id'] <= 4) {
+ $sql .= " LEFT JOIN " . DB_PREFIX . "amazon_product ap ON p.product_id = ap.product_id";
+ } elseif ($data['filter_market_id'] <= 6) {
+ $sql .= " LEFT JOIN " . DB_PREFIX . "amazon_product_link apl ON p.product_id = apl.product_id";
+ }
+
+ $amazon_status = array(
+ 1 => 'saved',
+ 2 => 'uploaded',
+ 3 => 'ok',
+ 4 => 'error',
+ );
+ }
+
+ if ($data['filter_market_name'] == 'amazonus') {
+ if ($data['filter_market_id'] <= 4) {
+ $sql .= " LEFT JOIN " . DB_PREFIX . "amazonus_product ap ON p.product_id = ap.product_id";
+ } elseif ($data['filter_market_id'] <= 6) {
+ $sql .= " LEFT JOIN " . DB_PREFIX . "amazonus_product_link apl ON p.product_id = apl.product_id";
+ }
+
+ $amazonus_status = array(
+ 1 => 'saved',
+ 2 => 'uploaded',
+ 3 => 'ok',
+ 4 => 'error',
+ );
+ }
+
+ $sql .= " WHERE pd.language_id = '" . (int)$this->config->get('config_language_id') . "'";
+
+ if (!empty($data['filter_category'])) {
+ if ($data['filter_category'] == 'none') {
+ $sql .= " AND p2c.category_id IS NULL";
+ } else {
+ $sql .= " AND p2c.category_id = '" . (int)$data['filter_category'] . "'";
+ }
+ }
+
+ if ($data['filter_market_name'] == 'ebay') {
+ if ($data['filter_market_id'] == 0) {
+ $sql .= " AND (ebay.ebay_listing_id IS NULL OR ebay2.listing_status = 0)";
+ } else {
+ $sql .= " AND (ebay.ebay_listing_id IS NOT NULL AND ebay.status = 1)";
+ }
+ }
+
+ if ($data['filter_market_name'] == 'amazon') {
+ if ($data['filter_market_id'] == 0) {
+ $sql .= " AND ap.product_id IS NULL ";
+ } elseif ($data['filter_market_id'] == 5) {
+ $sql .= " AND apl.id IS NOT NULL";
+ } elseif ($data['filter_market_id'] == 6) {
+ $sql .= " AND apl.id IS NULL";
+ } else {
+ $sql .= " AND FIND_IN_SET('" . $this->db->escape($amazon_status[$data['filter_market_id']]) . "', ap.`status`) != 0";
+ }
+ }
+
+ if ($data['filter_market_name'] == 'amazonus') {
+ if ($data['filter_market_id'] == 0) {
+ $sql .= " AND ap.product_id IS NULL ";
+ } elseif ($data['filter_market_id'] == 5) {
+ $sql .= " AND apl.id IS NOT NULL";
+ } elseif ($data['filter_market_id'] == 6) {
+ $sql .= " AND apl.id IS NULL";
+ } else {
+ $sql .= " AND FIND_IN_SET('" . $this->db->escape($amazonus_status[$data['filter_market_id']]) . "', ap.`status`) != 0";
+ }
+ }
+
+ if (isset($data['filter_name']) && !empty($data['filter_name']) && !is_null($data['filter_name'])) {
+ $sql .= " AND pd.name LIKE '" . $this->db->escape($data['filter_name']) . "%'";
+ }
+ if (isset($data['filter_model']) && !empty($data['filter_model']) && !is_null($data['filter_model'])) {
+ $sql .= " AND p.model LIKE '" . $this->db->escape($data['filter_model']) . "%'";
+ }
+ if (isset($data['filter_price']) && !empty($data['filter_price']) && !is_null($data['filter_price'])) {
+ $sql .= " AND p.price >= '" . (double)$data['filter_price'] . "'";
+ }
+ if (isset($data['filter_price_to']) && !empty($data['filter_price_to']) && !is_null($data['filter_price_to'])) {
+ $sql .= " AND p.price <= '" . (double)$data['filter_price_to'] . "'";
+ }
+ if (isset($data['filter_quantity']) && !empty($data['filter_quantity']) && !is_null($data['filter_quantity'])) {
+ $sql .= " AND p.quantity >= " . (int)$data['filter_quantity'];
+ }
+ if (isset($data['filter_quantity_to']) && !empty($data['filter_quantity_to']) && !is_null($data['filter_quantity_to'])) {
+ $sql .= " AND p.quantity <= " . (int)$data['filter_quantity_to'];
+ }
+ if (isset($data['filter_status']) && !empty($data['filter_status']) && !is_null($data['filter_status'])) {
+ $sql .= " AND p.status = " . (int)$data['filter_status'];
+ }
+ if (isset($data['filter_sku']) && !empty($data['filter_sku']) && !is_null($data['filter_sku'])) {
+ $sql .= " AND p.sku != ''";
+ }
+ if (isset($data['filter_desc']) && !empty($data['filter_desc']) && !is_null($data['filter_desc'])) {
+ $sql .= " AND pd.description != ''";
+ }
+ if (isset($data['filter_manufacturer']) && !empty($data['filter_price_to']) && !is_null($data['filter_manufacturer'])) {
+ $sql .= " AND p.manufacturer_id = " . (int)$data['filter_manufacturer'];
+ }
+
+ $sql .= " GROUP BY p.product_id";
+
+ $sort_data = array(
+ 'pd.name',
+ 'p.model',
+ 'p.price',
+ 'p.quantity',
+ 'p.status',
+ 'p.sort_order'
+ );
+
+ if (isset($data['sort']) && in_array($data['sort'], $sort_data)) {
+ $sql .= " ORDER BY " . $data['sort'];
+ } else {
+ $sql .= " ORDER BY pd.name";
+ }
+
+ 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'];
+ }
+
+ $query = $this->db->query($sql);
+
+ return $query->rows;
+ }
+
+ public function addOrderHistory($order_id, $post_data, $api_token) {
+ $defaults = array(
+ CURLOPT_POST => true,
+ CURLOPT_HEADER => false,
+ CURLOPT_USERAGENT => $this->request->server['HTTP_USER_AGENT'],
+ CURLOPT_URL => HTTPS_CATALOG . 'index.php?route=api/order/history&api_token=' . $api_token . '&store_id=0&order_id=' . (int)$order_id,
+ CURLOPT_SSL_VERIFYPEER => 0,
+ CURLOPT_SSL_VERIFYHOST => 0,
+ CURLOPT_FORBID_REUSE => true,
+ CURLOPT_RETURNTRANSFER => true,
+ CURLOPT_POSTFIELDS => http_build_query($post_data, '', "&"),
+ CURLOPT_TIMEOUT => 60,
+ );
+
+ $curl = curl_init();
+ curl_setopt_array($curl, $defaults);
+ $result = curl_exec($curl);
+ curl_close($curl);
+
+ $result = json_decode($result, 1);
+
+ return $result;
+ }
+
+ public function storeImage($filename, $width, $height, $sub_directory = '') {
+ /**
+ * This method should be used to save images for the marketplaces where the image will be used in a listing template.
+ * It will save to a dedicated folder in the /images location and not the /cache folder.
+ * This is due to people clearing the cache folder - only to realise all remotely references images are now gone.
+ */
+
+ if (!is_file(DIR_IMAGE . $filename) || substr(str_replace('\\', '/', realpath(DIR_IMAGE . $filename)), 0, strlen(DIR_IMAGE)) != DIR_IMAGE) {
+ return;
+ }
+
+ $extension = pathinfo($filename, PATHINFO_EXTENSION);
+
+ $image_old = $filename;
+
+ $new_path = 'openbay_template_images/';
+ if ($sub_directory != '') {
+ $new_path = $new_path . '/' .$sub_directory . '/';
+ }
+
+ $image_new = $new_path . utf8_substr($filename, 0, utf8_strrpos($filename, '.')) . '-' . $width . 'x' . $height . '.' . $extension;
+
+ if (!is_file(DIR_IMAGE . $image_new) || (filemtime(DIR_IMAGE . $image_old) > filemtime(DIR_IMAGE . $image_new))) {
+ list($width_orig, $height_orig, $image_type) = getimagesize(DIR_IMAGE . $image_old);
+
+ if (!in_array($image_type, array(IMAGETYPE_PNG, IMAGETYPE_JPEG, IMAGETYPE_GIF))) {
+ return DIR_IMAGE . $image_old;
+ }
+
+ $path = '';
+
+ $directories = explode('/', dirname($image_new));
+
+ foreach ($directories as $directory) {
+ $path = $path . '/' . $directory;
+
+ if (!is_dir(DIR_IMAGE . $path)) {
+ @mkdir(DIR_IMAGE . $path, 0777);
+ }
+ }
+
+ if ($width_orig != $width || $height_orig != $height) {
+ $image = new Image(DIR_IMAGE . $image_old);
+ $image->resize($width, $height);
+ $image->save(DIR_IMAGE . $image_new);
+ } else {
+ copy(DIR_IMAGE . $image_old, DIR_IMAGE . $image_new);
+ }
+ }
+
+ if ($this->request->server['HTTPS']) {
+ return HTTPS_CATALOG . 'image/' . $image_new;
+ } else {
+ return HTTP_CATALOG . 'image/' . $image_new;
+ }
+ }
+}
diff --git a/public/admin/model/extension/openbay/order.php b/public/admin/model/extension/openbay/order.php
new file mode 100644
index 0000000..d6aa936
--- /dev/null
+++ b/public/admin/model/extension/openbay/order.php
@@ -0,0 +1,228 @@
+<?php
+class ModelExtensionOpenBayOrder extends Model {
+ public function getTotalOrders($data = array()) {
+ $sql = "SELECT COUNT(*) AS `total` FROM `" . DB_PREFIX . "order` AS o";
+
+ if ($this->config->get('ebay_status')) {
+ $sql .= " LEFT JOIN " . DB_PREFIX . "ebay_order eo ON o.order_id = eo.order_id ";
+ } else {
+ $sql .= " JOIN (SELECT NULL AS order_id) eo ";
+ }
+
+ if ($this->config->get('openbay_amazon_status')) {
+ $sql .= " LEFT JOIN " . DB_PREFIX . "amazon_order ao ON o.order_id = ao.order_id ";
+ } else {
+ $sql .= " JOIN (SELECT NULL AS order_id) ao ";
+ }
+
+ if ($this->config->get('openbay_amazonus_status')) {
+ $sql .= " LEFT JOIN " . DB_PREFIX . "amazonus_order auso ON o.order_id = auso.order_id ";
+ } else {
+ $sql .= " JOIN (SELECT NULL AS order_id) auso ";
+ }
+
+ if ($this->config->get('etsy_status')) {
+ $sql .= " LEFT JOIN " . DB_PREFIX . "etsy_order eto ON o.order_id = eto.order_id ";
+ } else {
+ $sql .= " JOIN (SELECT NULL AS order_id) eto ";
+ }
+
+ if (isset($data['filter_order_status_id']) && !empty($data['filter_order_status_id']) && !is_null($data['filter_order_status_id'])) {
+ $sql .= " WHERE `o`.`order_status_id` = '" . (int)$data['filter_order_status_id'] . "'";
+ } else {
+ $sql .= " WHERE `o`.`order_status_id` > '0'";
+ }
+
+ if (!empty($data['filter_order_id'])) {
+ $sql .= " AND o.`order_id` = '" . (int)$data['filter_order_id'] . "'";
+ }
+
+ if (!empty($data['filter_customer'])) {
+ $sql .= " AND CONCAT(`firstname`, ' ', `lastname`) LIKE '%" . $this->db->escape($data['filter_customer']) . "%'";
+ }
+
+ if (!empty($data['filter_date_added'])) {
+ $sql .= " AND DATE(`date_added`) = DATE('" . $this->db->escape($data['filter_date_added']) . "')";
+ }
+
+ if (!empty($data['filter_channel'])) {
+ $sql .= " AND IF(eto.order_id IS NULL, IF(ao.order_id IS NULL, IF(auso.order_id IS NULL, IF(eo.order_id IS NULL, 'web', 'ebay'), 'amazonus'), 'amazon'), 'etsy') = '" . $this->db->escape($data['filter_channel']) . "'";
+ }
+
+ $query = $this->db->query($sql);
+
+ return $query->row['total'];
+ }
+
+ public function getOrders($data = array()) {
+ $sql = "SELECT o.order_id, o.customer_id, CONCAT(o.firstname, ' ', o.lastname) AS customer,";
+
+ if ($this->config->get('ebay_status')) {
+ $sql .= " `eo`.`smp_id` AS `ebay_order_ref`,";
+ } else {
+ $sql .= " NULL AS `ebay_order_ref`,";
+ }
+
+ if ($this->config->get('openbay_amazon_status')) {
+ $sql .= " `ao`.`amazon_order_id` AS `amazon_order_ref`,";
+ } else {
+ $sql .= " NULL AS `amazon_order_ref`,";
+ }
+
+ if ($this->config->get('openbay_amazonus_status')) {
+ $sql .= " `auso`.`amazonus_order_id` AS `amazonus_order_ref`,";
+ } else {
+ $sql .= " NULL AS `amazonus_order_ref`,";
+ }
+
+ if ($this->config->get('etsy_status')) {
+ $sql .= " `eto`.`receipt_id` AS `etsy_order_ref`,";
+ } else {
+ $sql .= " NULL AS `etsy_order_ref`,";
+ }
+
+ $sql .= " (SELECT os.name FROM " . DB_PREFIX . "order_status os WHERE os.order_status_id = o.order_status_id AND os.language_id = '" . (int)$this->config->get('config_language_id') . "') AS `status`, o.currency_code, o.currency_value, o.date_added, IF(eto.order_id IS NULL, IF(ao.order_id IS NULL, IF(auso.order_id IS NULL, IF(eo.order_id IS NULL, 'web', 'ebay'), 'amazonus'), 'amazon'), 'etsy') AS channel FROM `" . DB_PREFIX . "order` o";
+
+ if ($this->config->get('ebay_status')) {
+ $sql .= " LEFT JOIN " . DB_PREFIX . "ebay_order eo ON eo.order_id = o.order_id";
+ } else {
+ $sql .= " JOIN (SELECT NULL AS order_id) eo ";
+ }
+
+ if ($this->config->get('openbay_amazon_status')) {
+ $sql .= " LEFT JOIN " . DB_PREFIX . "amazon_order ao ON ao.order_id = o.order_id ";
+ } else {
+ $sql .= " JOIN (SELECT NULL AS order_id) ao ";
+ }
+
+ if ($this->config->get('openbay_amazonus_status')) {
+ $sql .= " LEFT JOIN " . DB_PREFIX . "amazonus_order auso ON auso.order_id = o.order_id ";
+ } else {
+ $sql .= " JOIN (SELECT NULL AS order_id) auso ";
+ }
+
+ if ($this->config->get('etsy_status')) {
+ $sql .= " LEFT JOIN " . DB_PREFIX . "etsy_order eto ON eto.order_id = o.order_id ";
+ } else {
+ $sql .= " JOIN (SELECT NULL AS order_id) eto ";
+ }
+
+ if (isset($data['filter_order_status_id']) && !empty($data['filter_order_status_id']) && !is_null($data['filter_order_status_id'])) {
+ $sql .= " WHERE o.order_status_id = '" . (int)$data['filter_order_status_id'] . "'";
+ } else {
+ $sql .= " WHERE o.order_status_id > '0'";
+ }
+
+ if (!empty($data['filter_order_id'])) {
+ $sql .= " AND o.order_id = '" . (int)$data['filter_order_id'] . "'";
+ }
+
+ if (!empty($data['filter_customer'])) {
+ $sql .= " AND LCASE(CONCAT(o.firstname, ' ', o.lastname)) LIKE '" . $this->db->escape(utf8_strtolower($data['filter_customer'])) . "%'";
+ }
+
+ if (!empty($data['filter_date_added'])) {
+ $sql .= " AND DATE(o.date_added) = DATE('" . $this->db->escape($data['filter_date_added']) . "')";
+ }
+
+ if (!empty($data['filter_channel'])) {
+ $sql .= " HAVING channel = '" . $this->db->escape($data['filter_channel']) . "'";
+ }
+
+ $sort_data = array(
+ 'o.order_id',
+ 'customer',
+ 'status',
+ 'o.date_added',
+ 'channel',
+ );
+
+ if (isset($data['sort']) && in_array($data['sort'], $sort_data)) {
+ $sql .= " ORDER BY " . $data['sort'];
+ } else {
+ $sql .= " ORDER BY o.order_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'];
+ }
+
+ $query = $this->db->query($sql);
+
+ return $query->rows;
+ }
+
+ public function getOrder($order_id) {
+ $sql = "SELECT o.order_id, o.order_status_id, o.shipping_method, CONCAT(o.firstname, ' ', o.lastname) AS customer,";
+
+ if ($this->config->get('ebay_status')) {
+ $sql .= " `eo`.`smp_id` AS `ebay_order_ref`,";
+ } else {
+ $sql .= " NULL AS `ebay_order_ref`,";
+ }
+
+ if ($this->config->get('openbay_amazon_status')) {
+ $sql .= " `ao`.`amazon_order_id` AS `amazon_order_ref`,";
+ } else {
+ $sql .= " NULL AS `amazon_order_ref`,";
+ }
+
+ if ($this->config->get('openbay_amazonus_status')) {
+ $sql .= " `auso`.`amazonus_order_id` AS `amazonus_order_ref`,";
+ } else {
+ $sql .= " NULL AS `amazonus_order_ref`,";
+ }
+
+ if ($this->config->get('etsy_status')) {
+ $sql .= " `eto`.`receipt_id` AS `etsy_order_ref`,";
+ } else {
+ $sql .= " NULL AS `etsy_order_ref`,";
+ }
+
+ $sql .= " (SELECT os.name FROM " . DB_PREFIX . "order_status os WHERE os.order_status_id = o.order_status_id AND os.language_id = '" . (int)$this->config->get('config_language_id') . "') AS status, o.currency_code, o.currency_value, o.date_added, IF(eto.order_id IS NULL, IF(ao.order_id IS NULL, IF(auso.order_id IS NULL, IF(eo.order_id IS NULL, 'web', 'ebay'), 'amazonus'), 'amazon'), 'etsy') AS channel FROM `" . DB_PREFIX . "order` o";
+
+ if ($this->config->get('ebay_status')) {
+ $sql .= " LEFT JOIN " . DB_PREFIX . "ebay_order eo ON eo.order_id = o.order_id ";
+ } else {
+ $sql .= " JOIN (SELECT NULL AS order_id) eo ";
+ }
+
+ if ($this->config->get('openbay_amazon_status')) {
+ $sql .= " LEFT JOIN " . DB_PREFIX . "amazon_order ao ON ao.order_id = o.order_id ";
+ } else {
+ $sql .= " JOIN (SELECT NULL AS order_id) ao ";
+ }
+
+ if ($this->config->get('openbay_amazonus_status')) {
+ $sql .= " LEFT JOIN " . DB_PREFIX . "amazonus_order auso ON auso.order_id = o.order_id ";
+ } else {
+ $sql .= " JOIN (SELECT NULL AS order_id) auso ";
+ }
+
+ if ($this->config->get('etsy_status')) {
+ $sql .= " LEFT JOIN " . DB_PREFIX . "etsy_order eto ON eto.order_id = o.order_id ";
+ } else {
+ $sql .= " JOIN (SELECT NULL AS order_id) eto ";
+ }
+
+ $sql .= " WHERE `o`.`order_id` = '" . (int)$order_id . "'";
+
+ $sql = $this->db->query($sql);
+
+ return $sql->row;
+ }
+} \ No newline at end of file
diff --git a/public/admin/model/extension/openbay/version.php b/public/admin/model/extension/openbay/version.php
new file mode 100644
index 0000000..eaa07a8
--- /dev/null
+++ b/public/admin/model/extension/openbay/version.php
@@ -0,0 +1,7 @@
+<?php
+class ModelExtensionOpenBayVersion extends Model {
+ public function version() {
+ return (int)3250;
+
+ }
+}
diff --git a/public/admin/model/extension/payment/amazon_login_pay.php b/public/admin/model/extension/payment/amazon_login_pay.php
new file mode 100644
index 0000000..a89037c
--- /dev/null
+++ b/public/admin/model/extension/payment/amazon_login_pay.php
@@ -0,0 +1,452 @@
+<?php
+class ModelExtensionPaymentAmazonLoginPay extends Model {
+
+ public function install() {
+ $this->db->query("
+ CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "amazon_login_pay_order` (
+ `amazon_login_pay_order_id` INT(11) NOT NULL AUTO_INCREMENT,
+ `order_id` int(11) NOT NULL,
+ `amazon_order_reference_id` varchar(255) NOT NULL,
+ `amazon_authorization_id` varchar(255) NOT NULL,
+ `free_shipping` tinyint NOT NULL DEFAULT 0,
+ `date_added` DATETIME NOT NULL,
+ `modified` DATETIME NOT NULL,
+ `capture_status` INT(1) DEFAULT NULL,
+ `cancel_status` INT(1) DEFAULT NULL,
+ `refund_status` INT(1) DEFAULT NULL,
+ `currency_code` CHAR(3) NOT NULL,
+ `total` DECIMAL( 10, 2 ) NOT NULL,
+ KEY `amazon_order_reference_id` (`amazon_order_reference_id`),
+ PRIMARY KEY `amazon_login_pay_order_id` (`amazon_login_pay_order_id`)
+ ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci;
+ ");
+
+ $this->db->query("
+ CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "amazon_login_pay_order_transaction` (
+ `amazon_login_pay_order_transaction_id` INT(11) NOT NULL AUTO_INCREMENT,
+ `amazon_login_pay_order_id` INT(11) NOT NULL,
+ `amazon_authorization_id` varchar(255),
+ `amazon_capture_id` varchar(255),
+ `amazon_refund_id` varchar(255),
+ `date_added` DATETIME NOT NULL,
+ `type` ENUM('authorization', 'capture', 'refund', 'cancel') DEFAULT NULL,
+ `status` ENUM('Open', 'Pending', 'Completed', 'Suspended', 'Declined', 'Closed', 'Canceled') DEFAULT NULL,
+ `amount` DECIMAL( 10, 2 ) NOT NULL,
+ PRIMARY KEY (`amazon_login_pay_order_transaction_id`)
+ ) ENGINE=MyISAM DEFAULT COLLATE=utf8_general_ci;
+ ");
+ }
+
+ public function uninstall() {
+ $this->db->query("DROP TABLE IF EXISTS `" . DB_PREFIX . "amazon_login_pay_order`;");
+ $this->db->query("DROP TABLE IF EXISTS `" . DB_PREFIX . "amazon_login_pay_order_total_tax`;");
+ $this->db->query("DROP TABLE IF EXISTS `" . DB_PREFIX . "amazon_login_pay_order_transaction`;");
+ }
+
+ public function deleteEvents() {
+ $this->load->model('setting/event');
+ $this->model_setting_event->deleteEventByCode('amazon_edit_capture');
+ $this->model_setting_event->deleteEventByCode('amazon_history_capture');
+ }
+
+ public function addEvents() {
+ $this->load->model('setting/event');
+ $this->model_setting_event->addEvent('amazon_edit_capture', 'catalog/model/checkout/order/editOrder/after', 'extension/payment/amazon_login_pay/capture');
+ $this->model_setting_event->addEvent('amazon_history_capture', 'catalog/model/checkout/order/addOrderHistory/after', 'extension/payment/amazon_login_pay/capture');
+ }
+
+ public function getOrder($order_id) {
+
+ $qry = $this->db->query("SELECT * FROM `" . DB_PREFIX . "amazon_login_pay_order` WHERE `order_id` = '" . (int)$order_id . "' LIMIT 1");
+
+ if ($qry->num_rows) {
+ $order = $qry->row;
+ $order['transactions'] = $this->getTransactions($order['amazon_login_pay_order_id'], $qry->row['currency_code']);
+ return $order;
+ } else {
+ return false;
+ }
+ }
+
+ public function cancel($amazon_login_pay_order) {
+ $total_captured = $this->getTotalCaptured($amazon_login_pay_order['amazon_login_pay_order_id']);
+
+ if (!empty($amazon_login_pay_order) && $total_captured == 0) {
+
+ $cancel_response = array();
+ $cancel_paramter_data = array();
+
+ $cancel_paramter_data['AmazonOrderReferenceId'] = $amazon_login_pay_order['amazon_order_reference_id'];
+ $cancel_details = $this->offAmazon('CancelOrderReference', $cancel_paramter_data);
+ $cancel_details_xml = simplexml_load_string($cancel_details['ResponseBody']);
+ $this->logger($cancel_details_xml);
+ if (isset($cancel_details_xml->Error)) {
+ $cancel_response['status'] = 'Error';
+ $cancel_response['status_detail'] = (string)$cancel_details_xml->Error->Code . ': ' . (string)$cancel_details_xml->Error->Message;
+ } else {
+ $cancel_response['status'] = 'Completed';
+ }
+ return $cancel_response;
+ } else {
+ return false;
+ }
+ }
+
+ public function updateCancelStatus($amazon_login_pay_order_id, $status) {
+ $this->db->query("UPDATE `" . DB_PREFIX . "amazon_login_pay_order` SET `cancel_status` = '" . (int)$status . "' WHERE `amazon_login_pay_order_id` = '" . (int)$amazon_login_pay_order_id . "'");
+ }
+
+ public function hasOpenAuthorization($transactions) {
+ foreach ($transactions as $transaction) {
+ if ($transaction['type'] == 'authorization' && $transaction['status'] == 'Open') {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ public function capture($amazon_login_pay_order, $amount) {
+ $total_captured = $this->getTotalCaptured($amazon_login_pay_order['amazon_login_pay_order_id']);
+
+ if (!empty($amazon_login_pay_order) && $amazon_login_pay_order['capture_status'] == 0 && ($total_captured + $amount <= $amazon_login_pay_order['total'])) {
+ if (!$this->hasOpenAuthorization($amazon_login_pay_order['transactions'])) {
+ $amazon_authorization = $this->authorize($amazon_login_pay_order, $amount);
+ if (isset($amazon_authorization['AmazonAuthorizationId'])) {
+ $amazon_authorization_id = $amazon_authorization['AmazonAuthorizationId'];
+ } else {
+ return $amazon_authorization;
+ }
+ } else {
+ $amazon_authorization_id = $amazon_login_pay_order['amazon_authorization_id'];
+ }
+
+ $capture_paramter_data = array();
+ $capture_paramter_data['AmazonOrderReferenceId'] = $amazon_login_pay_order['amazon_order_reference_id'];
+ $capture_paramter_data['AmazonAuthorizationId'] = $amazon_authorization_id;
+ $capture_paramter_data['CaptureAmount.Amount'] = $amount;
+ $capture_paramter_data['CaptureAmount.CurrencyCode'] = $amazon_login_pay_order['currency_code'];
+ $capture_paramter_data['CaptureReferenceId'] = 'capture_' . mt_rand();
+ $capture_paramter_data['TransactionTimeout'] = 0;
+ $capture_details = $this->offAmazon('Capture', $capture_paramter_data);
+
+ $capture_response = $this->validateResponse('Capture', $capture_details);
+ $capture_response['AmazonAuthorizationId'] = $amazon_authorization_id;
+ return $capture_response;
+ } else {
+ return false;
+ }
+ }
+
+ private function authorize($amazon_login_pay_order, $amount) {
+ $authorize_paramter_data = array();
+ $authorize_paramter_data['AmazonOrderReferenceId'] = $amazon_login_pay_order['amazon_order_reference_id'];
+ $authorize_paramter_data['AuthorizationAmount.Amount'] = $amount;
+ $authorize_paramter_data['AuthorizationAmount.CurrencyCode'] = $amazon_login_pay_order['currency_code'];
+ $authorize_paramter_data['AuthorizationReferenceId'] = 'auth_' . mt_rand();
+ $authorize_paramter_data['TransactionTimeout'] = 0;
+ $authorize_details = $this->offAmazon('Authorize', $authorize_paramter_data);
+
+ return $this->validateResponse('Authorize', $authorize_details);
+ }
+
+ public function closeOrderRef($amazon_order_reference_id) {
+ $close_paramter_data = array();
+ $close_paramter_data['AmazonOrderReferenceId'] = $amazon_order_reference_id;
+ $this->offAmazon('CloseOrderReference', $close_paramter_data);
+ $close_details = $this->offAmazon('CloseOrderReference', $close_paramter_data);
+ $this->logger($close_details);
+ }
+
+ public function updateCaptureStatus($amazon_login_pay_order_id, $status) {
+ $this->db->query("UPDATE `" . DB_PREFIX . "amazon_login_pay_order` SET `capture_status` = '" . (int)$status . "' WHERE `amazon_login_pay_order_id` = '" . (int)$amazon_login_pay_order_id . "'");
+ }
+
+ public function refund($amazon_login_pay_order, $amount) {
+ if (!empty($amazon_login_pay_order) && $amazon_login_pay_order['refund_status'] != 1) {
+ $amazon_captures_remaining = $this->getUnCaptured($amazon_login_pay_order['amazon_login_pay_order_id']);
+
+ $refund_response = array();
+ $i = 0;
+ $count = count($amazon_captures_remaining);
+ for ($amount; $amount > 0 && $count > $i; $amount -= $amazon_captures_remaining[$i++]['capture_remaining']) {
+ $refund_amount = $amount;
+ if ($amazon_captures_remaining[$i]['capture_remaining'] <= $amount) {
+ $refund_amount = $amazon_captures_remaining[$i]['capture_remaining'];
+ }
+
+ $refund_paramter_data = array();
+ $refund_paramter_data['AmazonOrderReferenceId'] = $amazon_login_pay_order['amazon_order_reference_id'];
+ $refund_paramter_data['AmazonCaptureId'] = $amazon_captures_remaining[$i]['amazon_capture_id'];
+ $refund_paramter_data['RefundAmount.Amount'] = $refund_amount;
+ $refund_paramter_data['RefundAmount.CurrencyCode'] = $amazon_login_pay_order['currency_code'];
+ $refund_paramter_data['RefundReferenceId'] = 'refund_' . mt_rand();
+ $refund_paramter_data['TransactionTimeout'] = 0;
+ $refund_details = $this->offAmazon('Refund', $refund_paramter_data);
+ $refund_response[$i] = $this->validateResponse('Refund', $refund_details);
+ $refund_response[$i]['amazon_authorization_id'] = $amazon_captures_remaining[$i]['amazon_authorization_id'];
+ $refund_response[$i]['amazon_capture_id'] = $amazon_captures_remaining[$i]['amazon_capture_id'];
+ $refund_response[$i]['amount'] = $refund_amount;
+ }
+
+ return $refund_response;
+ } else {
+ return false;
+ }
+ }
+
+ public function getUnCaptured($amazon_login_pay_order_id) {
+ $qry = $this->db->query("SELECT * FROM `" . DB_PREFIX . "amazon_login_pay_order_transaction` WHERE (`type` = 'refund' OR `type` = 'capture') AND `amazon_login_pay_order_id` = '" . (int)$amazon_login_pay_order_id . "' ORDER BY `date_added`");
+ $uncaptured = array();
+ foreach ($qry->rows as $row) {
+ $uncaptured[$row['amazon_capture_id']]['amazon_authorization_id'] = $row['amazon_authorization_id'];
+ $uncaptured[$row['amazon_capture_id']]['amazon_capture_id'] = $row['amazon_capture_id'];
+ if (isset($uncaptured[$row['amazon_capture_id']]['capture_remaining'])) {
+ $uncaptured[$row['amazon_capture_id']]['capture_remaining'] += $row['amount'];
+ } else {
+ $uncaptured[$row['amazon_capture_id']]['capture_remaining'] = $row['amount'];
+ }
+
+ if ($uncaptured[$row['amazon_capture_id']]['capture_remaining'] == 0) {
+ unset($uncaptured[$row['amazon_capture_id']]);
+ }
+ }
+ return array_values($uncaptured);
+ }
+
+ public function updateRefundStatus($amazon_login_pay_order_id, $status) {
+ $this->db->query("UPDATE `" . DB_PREFIX . "amazon_login_pay_order` SET `refund_status` = '" . (int)$status . "' WHERE `amazon_login_pay_order_id` = '" . (int)$amazon_login_pay_order_id . "'");
+ }
+
+ public function getCapturesRemaining($amazon_login_pay_order_id) {
+ $query = $this->db->query("SELECT * FROM `" . DB_PREFIX . "amazon_login_pay_order_transaction` WHERE `amazon_login_pay_order_id` = '" . (int)$amazon_login_pay_order_id . "' AND capture_remaining != '0' ORDER BY `date_added`");
+ if ($query->num_rows) {
+ return $query->rows;
+ } else {
+ return false;
+ }
+ }
+
+ private function getTransactions($amazon_login_pay_order_id, $currency_code) {
+ $query = $this->db->query("SELECT * FROM `" . DB_PREFIX . "amazon_login_pay_order_transaction` WHERE `amazon_login_pay_order_id` = '" . (int)$amazon_login_pay_order_id . "' ORDER BY `date_added` DESC");
+
+ $transactions = array();
+ if ($query->num_rows) {
+ foreach ($query->rows as $row) {
+ $row['amount'] = $this->currency->format($row['amount'], $currency_code, true, true);
+ $transactions[] = $row;
+ }
+ return $transactions;
+ } else {
+ return false;
+ }
+ }
+
+ public function addTransaction($amazon_login_pay_order_id, $type, $status, $total, $amazon_authorization_id = null, $amazon_capture_id = null, $amazon_refund_id = null) {
+ $this->db->query("INSERT INTO `" . DB_PREFIX . "amazon_login_pay_order_transaction` SET `amazon_login_pay_order_id` = '" . (int)$amazon_login_pay_order_id . "',`amazon_authorization_id` = '" . $this->db->escape($amazon_authorization_id) . "',`amazon_capture_id` = '" . $this->db->escape($amazon_capture_id) . "',`amazon_refund_id` = '" . $this->db->escape($amazon_refund_id) . "', `date_added` = now(), `type` = '" . $this->db->escape($type) . "', `amount` = '" . (double)$total . "', `status` = '" . $this->db->escape($status) . "'");
+ }
+
+ public function updateAuthorizationStatus($amazon_authorization_id, $status) {
+ $this->db->query("UPDATE `" . DB_PREFIX . "amazon_login_pay_order_transaction` SET `status` = '" . $this->db->escape($status) . "' WHERE `amazon_authorization_id`='" . $this->db->escape($amazon_authorization_id) . "' AND `type`='authorization'");
+ }
+
+ public function isOrderInState($order_reference_id, $states = array()) {
+ return in_array((string)$this->fetchOrder($order_reference_id)->OrderReferenceStatus->State, $states);
+ }
+
+ public function fetchOrder($order_reference_id) {
+ $order = $this->offAmazon("GetOrderReferenceDetails", array(
+ 'AmazonOrderReferenceId' => $order_reference_id
+ ));
+
+ $responseBody = $order['ResponseBody'];
+
+ $details_xml = simplexml_load_string($responseBody);
+
+ return $details_xml
+ ->GetOrderReferenceDetailsResult
+ ->OrderReferenceDetails;
+ }
+
+ public function getTotalCaptured($amazon_login_pay_order_id) {
+ $query = $this->db->query("SELECT SUM(`amount`) AS `total` FROM `" . DB_PREFIX . "amazon_login_pay_order_transaction` WHERE `amazon_login_pay_order_id` = '" . (int)$amazon_login_pay_order_id . "' AND (`type` = 'capture' OR `type` = 'refund') AND (`status` = 'Completed' OR `status` = 'Closed')");
+
+ return (double)$query->row['total'];
+ }
+
+ public function getTotalRefunded($amazon_login_pay_order_id) {
+ $query = $this->db->query("SELECT SUM(`amount`) AS `total` FROM `" . DB_PREFIX . "amazon_login_pay_order_transaction` WHERE `amazon_login_pay_order_id` = '" . (int)$amazon_login_pay_order_id . "' AND 'refund'");
+
+ return (double)$query->row['total'];
+ }
+
+ public function validateDetails($data) {
+ $validate_paramter_data = array();
+ $validate_paramter_data['AWSAccessKeyId'] = $data['payment_amazon_login_pay_access_key'];
+ $validate_paramter_data['SellerId'] = $data['payment_amazon_login_pay_merchant_id'];
+ $validate_paramter_data['AmazonOrderReferenceId'] = 'validate details';
+ $validate_details = $this->offAmazon('GetOrderReferenceDetails', $validate_paramter_data);
+ $validate_response = $this->validateResponse('GetOrderReferenceDetails', $validate_details, true);
+ if($validate_response['error_code'] && $validate_response['error_code'] != 'InvalidOrderReferenceId'){
+ return $validate_response;
+ }
+ }
+
+ public function offAmazon($Action, $parameter_data, $post_data = array()) {
+ if(!empty($post_data)){
+ $merchant_id = $post_data['payment_amazon_login_pay_merchant_id'];
+ $access_key = $post_data['payment_amazon_login_pay_access_key'];
+ $access_secret = $post_data['payment_amazon_login_pay_access_secret'];
+ $test = $post_data['payment_amazon_login_pay_test'];
+ $payment_region = $post_data['payment_amazon_login_pay_payment_region'];
+ } else {
+ $merchant_id = $this->config->get('payment_amazon_login_pay_merchant_id');
+ $access_key = $this->config->get('payment_amazon_login_pay_access_key');
+ $access_secret = $this->config->get('payment_amazon_login_pay_access_secret');
+ $test = $this->config->get('payment_amazon_login_pay_test');
+ $payment_region = $this->config->get('payment_amazon_login_pay_payment_region');
+
+ }
+
+ if ($test == 'sandbox') {
+ if ($payment_region == 'USD') {
+ $url = 'https://mws.amazonservices.com/OffAmazonPayments_Sandbox/2013-01-01/';
+ } else {
+ $url = 'https://mws-eu.amazonservices.com/OffAmazonPayments_Sandbox/2013-01-01/';
+ }
+ } else {
+ if ($payment_region == 'USD') {
+ $url = 'https://mws.amazonservices.com/OffAmazonPayments/2013-01-01/';
+ } else {
+ $url = 'https://mws-eu.amazonservices.com/OffAmazonPayments/2013-01-01/';
+ }
+ }
+
+ $parameters = array();
+ $parameters['AWSAccessKeyId'] = $access_key;
+ $parameters['Action'] = $Action;
+ $parameters['SellerId'] = $merchant_id;
+ $parameters['SignatureMethod'] = 'HmacSHA256';
+ $parameters['SignatureVersion'] = 2;
+ $parameters['Timestamp'] = date('c', time());
+ $parameters['Version'] = '2013-01-01';
+ foreach ($parameter_data as $k => $v) {
+ $parameters[$k] = $v;
+ }
+
+ $query = $this->calculateStringToSignV2($parameters, $url);
+
+ $parameters['Signature'] = base64_encode(hash_hmac('sha256', $query, $access_secret, true));
+
+ return $this->sendCurl($url, $parameters);
+ }
+
+ private function validateResponse($action, $details, $skip_logger = false) {
+ $details_xml = simplexml_load_string($details['ResponseBody']);
+ if (!$skip_logger) {
+ $this->logger($details_xml);
+ }
+ switch ($action) {
+ case 'Authorize':
+ $result = 'AuthorizeResult';
+ $details = 'AuthorizationDetails';
+ $status = 'AuthorizationStatus';
+ $amazon_id = 'AmazonAuthorizationId';
+ break;
+ case 'Capture':
+ $result = 'CaptureResult';
+ $details = 'CaptureDetails';
+ $status = 'CaptureStatus';
+ $amazon_id = 'AmazonCaptureId';
+ break;
+ case 'Refund':
+ $result = 'RefundResult';
+ $details = 'RefundDetails';
+ $status = 'RefundStatus';
+ $amazon_id = 'AmazonRefundId';
+ }
+
+ $details_xml->registerXPathNamespace('m', 'http://mws.amazonservices.com/schema/OffAmazonPayments/2013-01-01');
+ $error_set = $details_xml->xpath('//m:ReasonCode');
+
+ if (isset($details_xml->Error)) {
+ $response['status'] = 'Error';
+ $response['error_code'] = (string)$details_xml->Error->Code;
+ $response['status_detail'] = (string)$details_xml->Error->Code . ': ' . (string)$details_xml->Error->Message;
+ } elseif (!empty($error_set)) {
+ $response['status'] = (string)$details_xml->$result->$details->$status->State;
+ $response['status_detail'] = (string)$details_xml->$result->$details->$status->ReasonCode;
+ } else {
+ $response['status'] = (string)$details_xml->$result->$details->$status->State;
+ $response[$amazon_id] = (string)$details_xml->$result->$details->$amazon_id;
+ }
+
+ return $response;
+ }
+
+ public function sendCurl($url, $parameters) {
+ $query = $this->getParametersAsString($parameters);
+
+ $curl = curl_init($url);
+
+ curl_setopt($curl, CURLOPT_URL, $url);
+ curl_setopt($curl, CURLOPT_PORT, 443);
+ curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, true);
+ curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 2);
+ curl_setopt($curl, CURLOPT_USERAGENT, $this->request->server['HTTP_USER_AGENT']);
+ curl_setopt($curl, CURLOPT_POST, true);
+ curl_setopt($curl, CURLOPT_POSTFIELDS, $query);
+ curl_setopt($curl, CURLOPT_HEADER, true);
+ curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
+
+ $response = curl_exec($curl);
+ curl_close($curl);
+
+ list($other, $responseBody) = explode("\r\n\r\n", $response, 2);
+ $other = preg_split("/\r\n|\n|\r/", $other);
+
+ list($protocol, $code, $text) = explode(' ', trim(array_shift($other)), 3);
+ return array('status' => (int)$code, 'ResponseBody' => $responseBody);
+ }
+
+ private function getParametersAsString(array $parameters) {
+ $queryParameters = array();
+ foreach ($parameters as $key => $value) {
+ $queryParameters[] = $key . '=' . $this->urlencode($value);
+ }
+ return implode('&', $queryParameters);
+ }
+
+ private function calculateStringToSignV2(array $parameters, $url) {
+ $data = 'POST';
+ $data .= "\n";
+ $endpoint = parse_url($url);
+ $data .= $endpoint['host'];
+ $data .= "\n";
+ $uri = array_key_exists('path', $endpoint) ? $endpoint['path'] : null;
+ if (!isset($uri)) {
+ $uri = "/";
+ }
+ $uriencoded = implode("/", array_map(array($this, "urlencode"), explode("/", $uri)));
+ $data .= $uriencoded;
+ $data .= "\n";
+ uksort($parameters, 'strcmp');
+ $data .= $this->getParametersAsString($parameters);
+ return $data;
+ }
+
+ private function urlencode($value) {
+ return str_replace('%7E', '~', rawurlencode($value));
+ }
+
+ public function logger($message) {
+ if ($this->config->get('payment_amazon_login_pay_debug') == 1) {
+ $log = new Log('amazon_login_pay_admin.log');
+ $backtrace = debug_backtrace();
+ $class = isset($backtrace[6]['class']) ? $backtrace[6]['class'] . '::' : '';
+ $log->write('Origin: ' . $class . $backtrace[6]['function']);
+ $log->write(!is_string($message) ? print_r($message, true) : $message);
+ unset($log);
+ }
+ }
+} \ No newline at end of file
diff --git a/public/admin/model/extension/payment/bluepay_hosted.php b/public/admin/model/extension/payment/bluepay_hosted.php
new file mode 100644
index 0000000..d1a85ac
--- /dev/null
+++ b/public/admin/model/extension/payment/bluepay_hosted.php
@@ -0,0 +1,235 @@
+<?php
+class ModelExtensionPaymentBluePayHosted extends Model {
+ public function install() {
+ $this->db->query("
+ CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "bluepay_hosted_order` (
+ `bluepay_hosted_order_id` INT(11) NOT NULL AUTO_INCREMENT,
+ `order_id` INT(11) NOT NULL,
+ `transaction_id` VARCHAR(50),
+ `date_added` DATETIME NOT NULL,
+ `date_modified` DATETIME NOT NULL,
+ `release_status` INT(1) DEFAULT 0,
+ `void_status` INT(1) DEFAULT 0,
+ `rebate_status` INT(1) DEFAULT 0,
+ `currency_code` CHAR(3) NOT NULL,
+ `total` DECIMAL( 10, 2 ) NOT NULL,
+ PRIMARY KEY (`bluepay_hosted_order_id`)
+ ) ENGINE=MyISAM DEFAULT COLLATE=utf8_general_ci;");
+
+ $this->db->query("
+ CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "bluepay_hosted_order_transaction` (
+ `bluepay_hosted_order_transaction_id` INT(11) NOT NULL AUTO_INCREMENT,
+ `bluepay_hosted_order_id` INT(11) NOT NULL,
+ `date_added` DATETIME NOT NULL,
+ `type` ENUM('auth', 'payment', 'rebate', 'void') DEFAULT NULL,
+ `amount` DECIMAL( 10, 2 ) NOT NULL,
+ PRIMARY KEY (`bluepay_hosted_order_transaction_id`)
+ ) ENGINE=MyISAM DEFAULT COLLATE=utf8_general_ci;");
+
+ $this->db->query("
+ CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "bluepay_hosted_card` (
+ `card_id` INT(11) NOT NULL AUTO_INCREMENT,
+ `customer_id` INT(11) NOT NULL,
+ `token` VARCHAR(50) NOT NULL,
+ `digits` VARCHAR(4) NOT NULL,
+ `expiry` VARCHAR(5) NOT NULL,
+ `type` VARCHAR(50) NOT NULL,
+ PRIMARY KEY (`card_id`)
+ ) ENGINE=MyISAM DEFAULT COLLATE=utf8_general_ci;");
+ }
+
+ public function uninstall() {
+ $this->db->query("DROP TABLE IF EXISTS `" . DB_PREFIX . "bluepay_hosted_order`;");
+ $this->db->query("DROP TABLE IF EXISTS `" . DB_PREFIX . "bluepay_hosted_order_transaction`;");
+ $this->db->query("DROP TABLE IF EXISTS `" . DB_PREFIX . "bluepay_hosted_card`;");
+ }
+
+ public function void($order_id) {
+ $bluepay_hosted_order = $this->getOrder($order_id);
+
+ if (!empty($bluepay_hosted_order) && $bluepay_hosted_order['release_status'] == 1) {
+
+ $void_data = array();
+
+ $void_data['MERCHANT'] = $this->config->get('payment_bluepay_hosted_account_id');
+ $void_data["TRANSACTION_TYPE"] = 'VOID';
+ $void_data["MODE"] = strtoupper($this->config->get('payment_bluepay_hosted_test'));
+ $void_data["RRNO"] = $bluepay_hosted_order['transaction_id'];
+
+ $void_data['APPROVED_URL'] = HTTP_CATALOG . 'index.php?route=extension/payment/bluepay_hosted/adminCallback';
+ $void_data['DECLINED_URL'] = HTTP_CATALOG . 'index.php?route=extension/payment/bluepay_hosted/adminCallback';
+ $void_data['MISSING_URL'] = HTTP_CATALOG . 'index.php?route=extension/payment/bluepay_hosted/adminCallback';
+
+ if (isset($this->request->server["REMOTE_ADDR"])) {
+ $void_data["REMOTE_IP"] = $this->request->server["REMOTE_ADDR"];
+ }
+
+ $tamper_proof_data = $this->config->get('payment_bluepay_hosted_secret_key') . $void_data['MERCHANT'] . $void_data["TRANSACTION_TYPE"] . $void_data["RRNO"] . $void_data["MODE"];
+
+ $void_data["TAMPER_PROOF_SEAL"] = md5($tamper_proof_data);
+
+ $this->logger('$void_data:\r\n' . print_r($void_data, 1));
+
+ $response_data = $this->sendCurl('https://secure.bluepay.com/interfaces/bp10emu', $void_data);
+
+ return $response_data;
+ } else {
+ return false;
+ }
+ }
+
+ public function updateVoidStatus($bluepay_hosted_order_id, $status) {
+ $this->logger('$bluepay_hosted_order_id:\r\n' . print_r($bluepay_hosted_order_id, 1));
+ $this->logger('$status:\r\n' . print_r($status, 1));
+ $this->db->query("UPDATE `" . DB_PREFIX . "bluepay_hosted_order` SET `void_status` = '" . (int)$status . "' WHERE `bluepay_hosted_order_id` = '" . (int)$bluepay_hosted_order_id . "'");
+ }
+
+ public function release($order_id, $amount) {
+ $bluepay_hosted_order = $this->getOrder($order_id);
+ $total_released = $this->getTotalReleased($bluepay_hosted_order['bluepay_hosted_order_id']);
+
+ if (!empty($bluepay_hosted_order) && $bluepay_hosted_order['release_status'] == 0 && ($total_released + $amount <= $bluepay_hosted_order['total'])) {
+ $release_data = array();
+
+ $release_data['MERCHANT'] = $this->config->get('payment_bluepay_hosted_account_id');
+ $release_data["TRANSACTION_TYPE"] = 'CAPTURE';
+ $release_data["MODE"] = strtoupper($this->config->get('payment_bluepay_hosted_test'));
+ $release_data["RRNO"] = $bluepay_hosted_order['transaction_id'];
+
+ $release_data['APPROVED_URL'] = HTTP_CATALOG . 'index.php?route=extension/payment/bluepay_hosted/adminCallback';
+ $release_data['DECLINED_URL'] = HTTP_CATALOG . 'index.php?route=extension/payment/bluepay_hosted/adminCallback';
+ $release_data['MISSING_URL'] = HTTP_CATALOG . 'index.php?route=extension/payment/bluepay_hosted/adminCallback';
+
+ if (isset($this->request->server["REMOTE_ADDR"])) {
+ $release_data["REMOTE_IP"] = $this->request->server["REMOTE_ADDR"];
+ }
+
+ $tamper_proof_data = $this->config->get('payment_bluepay_hosted_secret_key') . $release_data['MERCHANT'] . $release_data["TRANSACTION_TYPE"] . $release_data["RRNO"] . $release_data["MODE"];
+
+ $release_data["TAMPER_PROOF_SEAL"] = md5($tamper_proof_data);
+
+ $response_data = $this->sendCurl('https://secure.bluepay.com/interfaces/bp10emu', $release_data);
+
+ return $response_data;
+ } else {
+ return false;
+ }
+ }
+
+ public function updateReleaseStatus($bluepay_hosted_order_id, $status) {
+ $this->db->query("UPDATE `" . DB_PREFIX . "bluepay_hosted_order` SET `release_status` = '" . (int)$status . "' WHERE `bluepay_hosted_order_id` = '" . (int)$bluepay_hosted_order_id . "'");
+ }
+
+ public function rebate($order_id, $amount) {
+ $bluepay_hosted_order = $this->getOrder($order_id);
+
+ if (!empty($bluepay_hosted_order) && $bluepay_hosted_order['rebate_status'] != 1) {
+ $rebate_data = array();
+
+ $rebate_data['MERCHANT'] = $this->config->get('payment_bluepay_hosted_account_id');
+ $rebate_data["TRANSACTION_TYPE"] = 'REFUND';
+ $rebate_data["MODE"] = strtoupper($this->config->get('payment_bluepay_hosted_test'));
+ $rebate_data["RRNO"] = $bluepay_hosted_order['transaction_id'];
+ $rebate_data["AMOUNT"] = $amount;
+ $rebate_data['APPROVED_URL'] = HTTP_CATALOG . 'index.php?route=extension/payment/bluepay_hosted/adminCallback';
+ $rebate_data['DECLINED_URL'] = HTTP_CATALOG . 'index.php?route=extension/payment/bluepay_hosted/adminCallback';
+ $rebate_data['MISSING_URL'] = HTTP_CATALOG . 'index.php?route=extension/payment/bluepay_hosted/adminCallback';
+
+ if (isset($this->request->server["REMOTE_ADDR"])) {
+ $rebate_data["REMOTE_IP"] = $this->request->server["REMOTE_ADDR"];
+ }
+
+ $tamper_proof_data = $this->config->get('payment_bluepay_hosted_secret_key') . $rebate_data['MERCHANT'] . $rebate_data["TRANSACTION_TYPE"] . $rebate_data['AMOUNT'] . $rebate_data["RRNO"] . $rebate_data["MODE"];
+
+ $rebate_data["TAMPER_PROOF_SEAL"] = md5($tamper_proof_data);
+
+ $response_data = $this->sendCurl('https://secure.bluepay.com/interfaces/bp10emu', $rebate_data);
+
+ return $response_data;
+ } else {
+ return false;
+ }
+ }
+
+ public function updateRebateStatus($bluepay_hosted_order_id, $status) {
+ $this->db->query("UPDATE `" . DB_PREFIX . "bluepay_hosted_order` SET `rebate_status` = '" . (int)$status . "' WHERE `bluepay_hosted_order_id` = '" . (int)$bluepay_hosted_order_id . "'");
+ }
+
+ public function updateTransactionId($bluepay_hosted_order_id, $transaction_id) {
+ $this->db->query("UPDATE `" . DB_PREFIX . "bluepay_hosted_order` SET `transaction_id` = '" . (int)$transaction_id . "' WHERE `bluepay_hosted_order_id` = '" . (int)$bluepay_hosted_order_id . "'");
+ }
+
+ public function getOrder($order_id) {
+
+ $qry = $this->db->query("SELECT * FROM `" . DB_PREFIX . "bluepay_hosted_order` WHERE `order_id` = '" . (int)$order_id . "' LIMIT 1");
+
+ if ($qry->num_rows) {
+ $order = $qry->row;
+ $order['transactions'] = $this->getTransactions($order['bluepay_hosted_order_id']);
+
+ return $order;
+ } else {
+ return false;
+ }
+ }
+
+ private function getTransactions($bluepay_hosted_order_id) {
+ $qry = $this->db->query("SELECT * FROM `" . DB_PREFIX . "bluepay_hosted_order_transaction` WHERE `bluepay_hosted_order_id` = '" . (int)$bluepay_hosted_order_id . "'");
+
+ if ($qry->num_rows) {
+ return $qry->rows;
+ } else {
+ return false;
+ }
+ }
+
+ public function addTransaction($bluepay_hosted_order_id, $type, $total) {
+ $this->logger('$type:\r\n' . print_r($type, 1));
+ $this->logger('$total:\r\n' . print_r($total, 1));
+ $this->db->query("INSERT INTO `" . DB_PREFIX . "bluepay_hosted_order_transaction` SET `bluepay_hosted_order_id` = '" . (int)$bluepay_hosted_order_id . "', `date_added` = now(), `type` = '" . $this->db->escape($type) . "', `amount` = '" . (float)$total . "'");
+ }
+
+ public function getTotalReleased($bluepay_hosted_order_id) {
+ $query = $this->db->query("SELECT SUM(`amount`) AS `total` FROM `" . DB_PREFIX . "bluepay_hosted_order_transaction` WHERE `bluepay_hosted_order_id` = '" . (int)$bluepay_hosted_order_id . "' AND (`type` = 'payment' OR `type` = 'rebate')");
+
+ return (float)$query->row['total'];
+ }
+
+ public function getTotalRebated($bluepay_hosted_order_id) {
+ $query = $this->db->query("SELECT SUM(`amount`) AS `total` FROM `" . DB_PREFIX . "bluepay_hosted_order_transaction` WHERE `bluepay_hosted_order_id` = '" . (int)$bluepay_hosted_order_id . "' AND 'rebate'");
+
+ return (float)$query->row['total'];
+ }
+
+ public function sendCurl($url, $post_data) {
+ $curl = curl_init($url);
+
+ curl_setopt($curl, CURLOPT_PORT, 443);
+ curl_setopt($curl, CURLOPT_HEADER, 0);
+ curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, 0);
+ curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
+ curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true);
+ curl_setopt($curl, CURLOPT_FORBID_REUSE, 1);
+ curl_setopt($curl, CURLOPT_FRESH_CONNECT, 1);
+ curl_setopt($curl, CURLOPT_POST, 1);
+ curl_setopt($curl, CURLOPT_POSTFIELDS, http_build_query($post_data));
+
+ $response_data = curl_exec($curl);
+
+ curl_close($curl);
+
+ return json_decode($response_data, true);
+ }
+
+ public function adminCallback() {
+ $this->response->addHeader('Content-Type: application/json');
+ $this->response->setOutput(json_encode($this->request->get));
+ }
+
+ public function logger($message) {
+ if ($this->config->get('payment_bluepay_hosted_debug') == 1) {
+ $log = new Log('bluepay_hosted.log');
+ $log->write($message);
+ }
+ }
+} \ No newline at end of file
diff --git a/public/admin/model/extension/payment/bluepay_redirect.php b/public/admin/model/extension/payment/bluepay_redirect.php
new file mode 100644
index 0000000..e6df201
--- /dev/null
+++ b/public/admin/model/extension/payment/bluepay_redirect.php
@@ -0,0 +1,228 @@
+<?php
+class ModelExtensionPaymentBluepayredirect extends Model {
+ public function install() {
+ $this->db->query("
+ CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "bluepay_redirect_order` (
+ `bluepay_redirect_order_id` INT(11) NOT NULL AUTO_INCREMENT,
+ `order_id` INT(11) NOT NULL,
+ `transaction_id` VARCHAR(50),
+ `date_added` DATETIME NOT NULL,
+ `date_modified` DATETIME NOT NULL,
+ `release_status` INT(1) DEFAULT 0,
+ `void_status` INT(1) DEFAULT 0,
+ `rebate_status` INT(1) DEFAULT 0,
+ `currency_code` CHAR(3) NOT NULL,
+ `total` DECIMAL( 10, 2 ) NOT NULL,
+ PRIMARY KEY (`bluepay_redirect_order_id`)
+ ) ENGINE=MyISAM DEFAULT COLLATE=utf8_general_ci;");
+
+ $this->db->query("
+ CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "bluepay_redirect_order_transaction` (
+ `bluepay_redirect_order_transaction_id` INT(11) NOT NULL AUTO_INCREMENT,
+ `bluepay_redirect_order_id` INT(11) NOT NULL,
+ `date_added` DATETIME NOT NULL,
+ `type` ENUM('auth', 'payment', 'rebate', 'void') DEFAULT NULL,
+ `amount` DECIMAL( 10, 2 ) NOT NULL,
+ PRIMARY KEY (`bluepay_redirect_order_transaction_id`)
+ ) ENGINE=MyISAM DEFAULT COLLATE=utf8_general_ci;");
+
+ $this->db->query("
+ CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "bluepay_redirect_card` (
+ `card_id` INT(11) NOT NULL AUTO_INCREMENT,
+ `customer_id` INT(11) NOT NULL,
+ `token` VARCHAR(50) NOT NULL,
+ `digits` VARCHAR(4) NOT NULL,
+ `expiry` VARCHAR(5) NOT NULL,
+ `type` VARCHAR(50) NOT NULL,
+ PRIMARY KEY (`card_id`)
+ ) ENGINE=MyISAM DEFAULT COLLATE=utf8_general_ci;");
+ }
+
+ public function uninstall() {
+ $this->db->query("DROP TABLE IF EXISTS `" . DB_PREFIX . "bluepay_redirect_order`;");
+ $this->db->query("DROP TABLE IF EXISTS `" . DB_PREFIX . "bluepay_redirect_order_transaction`;");
+ $this->db->query("DROP TABLE IF EXISTS `" . DB_PREFIX . "bluepay_redirect_card`;");
+ }
+
+ public function void($order_id) {
+ $bluepay_redirect_order = $this->getOrder($order_id);
+
+ if (!empty($bluepay_redirect_order) && $bluepay_redirect_order['release_status'] == 1) {
+
+ $void_data = array();
+
+ $void_data['MERCHANT'] = $this->config->get('payment_bluepay_redirect_account_id');
+ $void_data["TRANSACTION_TYPE"] = 'VOID';
+ $void_data["MODE"] = strtoupper($this->config->get('payment_bluepay_redirect_test'));
+ $void_data["RRNO"] = $bluepay_redirect_order['transaction_id'];
+
+ $void_data['APPROVED_URL'] = HTTP_CATALOG . 'index.php?route=extension/payment/bluepay_redirect/callback';
+ $void_data['DECLINED_URL'] = HTTP_CATALOG . 'index.php?route=extension/payment/bluepay_redirect/callback';
+ $void_data['MISSING_URL'] = HTTP_CATALOG . 'index.php?route=extension/payment/bluepay_redirect/callback';
+
+ if (isset($this->request->server["REMOTE_ADDR"])) {
+ $void_data["REMOTE_IP"] = $this->request->server["REMOTE_ADDR"];
+ }
+
+ $tamper_proof_data = $this->config->get('payment_bluepay_redirect_secret_key') . $void_data['MERCHANT'] . $void_data["TRANSACTION_TYPE"] . $void_data["RRNO"] . $void_data["MODE"];
+
+ $void_data["TAMPER_PROOF_SEAL"] = md5($tamper_proof_data);
+
+ $response_data = $this->sendCurl('https://secure.bluepay.com/interfaces/bp10emu', $void_data);
+
+ return $response_data;
+ } else {
+ return false;
+ }
+ }
+
+ public function updateVoidStatus($bluepay_redirect_order_id, $status) {
+ $this->db->query("UPDATE `" . DB_PREFIX . "bluepay_redirect_order` SET `void_status` = '" . (int)$status . "' WHERE `bluepay_redirect_order_id` = '" . (int)$bluepay_redirect_order_id . "'");
+ }
+
+ public function release($order_id, $amount) {
+ $bluepay_redirect_order = $this->getOrder($order_id);
+ $total_released = $this->getTotalReleased($bluepay_redirect_order['bluepay_redirect_order_id']);
+
+ if (!empty($bluepay_redirect_order) && $bluepay_redirect_order['release_status'] == 0 && ($total_released + $amount <= $bluepay_redirect_order['total'])) {
+ $release_data = array();
+
+ $release_data['MERCHANT'] = $this->config->get('payment_bluepay_redirect_account_id');
+ $release_data["TRANSACTION_TYPE"] = 'CAPTURE';
+ $release_data["MODE"] = strtoupper($this->config->get('payment_bluepay_redirect_test'));
+ $release_data["RRNO"] = $bluepay_redirect_order['transaction_id'];
+ $release_data["AMOUNT"] = $amount;
+ $release_data['APPROVED_URL'] = HTTP_CATALOG . 'index.php?route=extension/payment/bluepay_redirect/callback';
+ $release_data['DECLINED_URL'] = HTTP_CATALOG . 'index.php?route=extension/payment/bluepay_redirect/callback';
+ $release_data['MISSING_URL'] = HTTP_CATALOG . 'index.php?route=extension/payment/bluepay_redirect/callback';
+
+ if (isset($this->request->server["REMOTE_ADDR"])) {
+ $release_data["REMOTE_IP"] = $this->request->server["REMOTE_ADDR"];
+ }
+
+ $tamper_proof_data = $this->config->get('payment_bluepay_redirect_secret_key') . $release_data['MERCHANT'] . $release_data["TRANSACTION_TYPE"] . $release_data["AMOUNT"] . $release_data["RRNO"] . $release_data["MODE"];
+
+ $release_data["TAMPER_PROOF_SEAL"] = md5($tamper_proof_data);
+
+ $response_data = $this->sendCurl('https://secure.bluepay.com/interfaces/bp10emu', $release_data);
+
+ return $response_data;
+ } else {
+ return false;
+ }
+ }
+
+ public function updateReleaseStatus($bluepay_redirect_order_id, $status) {
+ $this->db->query("UPDATE `" . DB_PREFIX . "bluepay_redirect_order` SET `release_status` = '" . (int)$status . "' WHERE `bluepay_redirect_order_id` = '" . (int)$bluepay_redirect_order_id . "'");
+ }
+
+ public function rebate($order_id, $amount) {
+ $bluepay_redirect_order = $this->getOrder($order_id);
+
+ if (!empty($bluepay_redirect_order) && $bluepay_redirect_order['rebate_status'] != 1) {
+ $rebate_data = array();
+
+ $rebate_data['MERCHANT'] = $this->config->get('payment_bluepay_redirect_account_id');
+ $rebate_data["TRANSACTION_TYPE"] = 'REFUND';
+ $rebate_data["MODE"] = strtoupper($this->config->get('payment_bluepay_redirect_test'));
+ $rebate_data["RRNO"] = $bluepay_redirect_order['transaction_id'];
+ $rebate_data["AMOUNT"] = $amount;
+ $rebate_data['APPROVED_URL'] = HTTP_CATALOG . 'index.php?route=extension/payment/bluepay_redirect/callback';
+ $rebate_data['DECLINED_URL'] = HTTP_CATALOG . 'index.php?route=extension/payment/bluepay_redirect/callback';
+ $rebate_data['MISSING_URL'] = HTTP_CATALOG . 'index.php?route=extension/payment/bluepay_redirect/callback';
+
+ if (isset($this->request->server["REMOTE_ADDR"])) {
+ $rebate_data["REMOTE_IP"] = $this->request->server["REMOTE_ADDR"];
+ }
+
+ $tamper_proof_data = $this->config->get('payment_bluepay_redirect_secret_key') . $rebate_data['MERCHANT'] . $rebate_data["TRANSACTION_TYPE"] . $rebate_data['AMOUNT'] . $rebate_data["RRNO"] . $rebate_data["MODE"];
+
+ $rebate_data["TAMPER_PROOF_SEAL"] = md5($tamper_proof_data);
+
+ $response_data = $this->sendCurl('https://secure.bluepay.com/interfaces/bp10emu', $rebate_data);
+
+ return $response_data;
+ } else {
+ return false;
+ }
+ }
+
+ public function updateRebateStatus($bluepay_redirect_order_id, $status) {
+ $this->db->query("UPDATE `" . DB_PREFIX . "bluepay_redirect_order` SET `rebate_status` = '" . (int)$status . "' WHERE `bluepay_redirect_order_id` = '" . (int)$bluepay_redirect_order_id . "'");
+ }
+
+ public function updateTransactionId($bluepay_redirect_order_id, $transaction_id) {
+ $this->db->query("UPDATE `" . DB_PREFIX . "bluepay_redirect_order` SET `transaction_id` = '" . (int)$transaction_id . "' WHERE `bluepay_redirect_order_id` = '" . (int)$bluepay_redirect_order_id . "'");
+ }
+
+ public function getOrder($order_id) {
+
+ $qry = $this->db->query("SELECT * FROM `" . DB_PREFIX . "bluepay_redirect_order` WHERE `order_id` = '" . (int)$order_id . "' LIMIT 1");
+
+ if ($qry->num_rows) {
+ $order = $qry->row;
+ $order['transactions'] = $this->getTransactions($order['bluepay_redirect_order_id']);
+
+ return $order;
+ } else {
+ return false;
+ }
+ }
+
+ private function getTransactions($bluepay_redirect_order_id) {
+ $qry = $this->db->query("SELECT * FROM `" . DB_PREFIX . "bluepay_redirect_order_transaction` WHERE `bluepay_redirect_order_id` = '" . (int)$bluepay_redirect_order_id . "'");
+
+ if ($qry->num_rows) {
+ return $qry->rows;
+ } else {
+ return false;
+ }
+ }
+
+ public function addTransaction($bluepay_redirect_order_id, $type, $total) {
+ $this->db->query("INSERT INTO `" . DB_PREFIX . "bluepay_redirect_order_transaction` SET `bluepay_redirect_order_id` = '" . (int)$bluepay_redirect_order_id . "', `date_added` = now(), `type` = '" . $this->db->escape($type) . "', `amount` = '" . (float)$total . "'");
+ }
+
+ public function getTotalReleased($bluepay_redirect_order_id) {
+ $query = $this->db->query("SELECT SUM(`amount`) AS `total` FROM `" . DB_PREFIX . "bluepay_redirect_order_transaction` WHERE `bluepay_redirect_order_id` = '" . (int)$bluepay_redirect_order_id . "' AND (`type` = 'payment' OR `type` = 'rebate')");
+
+ return (float)$query->row['total'];
+ }
+
+ public function getTotalRebated($bluepay_redirect_order_id) {
+ $query = $this->db->query("SELECT SUM(`amount`) AS `total` FROM `" . DB_PREFIX . "bluepay_redirect_order_transaction` WHERE `bluepay_redirect_order_id` = '" . (int)$bluepay_redirect_order_id . "' AND 'rebate'");
+
+ return (float)$query->row['total'];
+ }
+
+ public function sendCurl($url, $post_data) {
+ $curl = curl_init($url);
+
+ curl_setopt($curl, CURLOPT_PORT, 443);
+ curl_setopt($curl, CURLOPT_HEADER, 0);
+ curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, 0);
+ curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
+ curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true);
+ curl_setopt($curl, CURLOPT_FORBID_REUSE, 1);
+ curl_setopt($curl, CURLOPT_FRESH_CONNECT, 1);
+ curl_setopt($curl, CURLOPT_POST, 1);
+ curl_setopt($curl, CURLOPT_POSTFIELDS, http_build_query($post_data));
+
+ $response_data = curl_exec($curl);
+ curl_close($curl);
+
+ return json_decode($response_data, true);
+ }
+
+ public function callback() {
+ $this->response->addHeader('Content-Type: application/json');
+ $this->response->setOutput(json_encode($this->request->get));
+ }
+
+ public function logger($message) {
+ if ($this->config->get('payment_bluepay_redirect_debug') == 1) {
+ $log = new Log('bluepay_redirect.log');
+ $log->write($message);
+ }
+ }
+}
diff --git a/public/admin/model/extension/payment/cardconnect.php b/public/admin/model/extension/payment/cardconnect.php
new file mode 100644
index 0000000..4cb4b60
--- /dev/null
+++ b/public/admin/model/extension/payment/cardconnect.php
@@ -0,0 +1,328 @@
+<?php
+class ModelExtensionPaymentCardConnect extends Model {
+ public function install() {
+ $this->db->query("
+ CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "cardconnect_card` (
+ `cardconnect_card_id` INT(11) NOT NULL AUTO_INCREMENT,
+ `cardconnect_order_id` INT(11) NOT NULL DEFAULT '0',
+ `customer_id` INT(11) NOT NULL DEFAULT '0',
+ `profileid` VARCHAR(16) NOT NULL DEFAULT '',
+ `token` VARCHAR(19) NOT NULL DEFAULT '',
+ `type` VARCHAR(50) NOT NULL DEFAULT '',
+ `account` VARCHAR(4) NOT NULL DEFAULT '',
+ `expiry` VARCHAR(4) NOT NULL DEFAULT '',
+ `date_added` DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00',
+ PRIMARY KEY (`cardconnect_card_id`)
+ ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci");
+
+ $this->db->query("
+ CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "cardconnect_order` (
+ `cardconnect_order_id` INT(11) NOT NULL AUTO_INCREMENT,
+ `order_id` INT(11) NOT NULL DEFAULT '0',
+ `customer_id` INT(11) NOT NULL DEFAULT '0',
+ `payment_method` VARCHAR(255) NOT NULL DEFAULT '',
+ `retref` VARCHAR(12) NOT NULL DEFAULT '',
+ `authcode` VARCHAR(6) NOT NULL DEFAULT '',
+ `currency_code` VARCHAR(3) NOT NULL DEFAULT '',
+ `total` DECIMAL(10, 2) NOT NULL DEFAULT '0.00',
+ `date_added` DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00',
+ PRIMARY KEY (`cardconnect_order_id`)
+ ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci");
+
+ $this->db->query("
+ CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "cardconnect_order_transaction` (
+ `cardconnect_order_transaction_id` INT(11) NOT NULL AUTO_INCREMENT,
+ `cardconnect_order_id` INT(11) NOT NULL DEFAULT '0',
+ `type` VARCHAR(50) NOT NULL DEFAULT '',
+ `retref` VARCHAR(12) NOT NULL DEFAULT '',
+ `amount` DECIMAL(10, 2) NOT NULL DEFAULT '0.00',
+ `status` VARCHAR(255) NOT NULL DEFAULT '',
+ `date_modified` DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00',
+ `date_added` DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00',
+ PRIMARY KEY (`cardconnect_order_transaction_id`)
+ ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci");
+ }
+
+ public function uninstall() {
+ $this->db->query("DROP TABLE IF EXISTS `" . DB_PREFIX . "cardconnect_card`");
+ $this->db->query("DROP TABLE IF EXISTS `" . DB_PREFIX . "cardconnect_order`");
+ $this->db->query("DROP TABLE IF EXISTS `" . DB_PREFIX . "cardconnect_order_transaction`");
+
+ $this->log('Module uninstalled');
+ }
+
+ public function getOrder($order_id) {
+ $query = $this->db->query("SELECT * FROM `" . DB_PREFIX . "cardconnect_order` WHERE `order_id` = '" . (int)$order_id . "' LIMIT 1");
+
+ if ($query->num_rows) {
+ $order = $query->row;
+
+ $order['transactions'] = $this->getTransactions($order['cardconnect_order_id']);
+
+ return $order;
+ } else {
+ return false;
+ }
+ }
+
+ private function getTransactions($cardconnect_order_id) {
+ $query = $this->db->query("SELECT * FROM `" . DB_PREFIX . "cardconnect_order_transaction` WHERE `cardconnect_order_id` = '" . (int)$cardconnect_order_id . "'");
+
+ if ($query->num_rows) {
+ return $query->rows;
+ } else {
+ return array();
+ }
+ }
+
+ public function getTotalCaptured($cardconnect_order_id) {
+ $query = $this->db->query("SELECT SUM(`amount`) AS `total` FROM `" . DB_PREFIX . "cardconnect_order_transaction` WHERE `cardconnect_order_id` = '" . (int)$cardconnect_order_id . "' AND (`type` = 'payment' OR `type` = 'refund')");
+
+ return (float)$query->row['total'];
+ }
+
+ public function inquire($order_info, $retref) {
+ $this->log('Posting inquire to CardConnect');
+
+ $this->log('Order ID: ' . $order_info['order_id']);
+
+ $url = 'https://' . $this->config->get('cardconnect_site') . '.cardconnect.com:' . (($this->config->get('cardconnect_environment') == 'live') ? 8443 : 6443) . '/cardconnect/rest/inquire/' . $retref . '/' . $this->config->get('payment_cardconnect_merchant_id');
+
+ $header = array();
+
+ $header[] = 'Content-type: application/json';
+ $header[] = 'Authorization: Basic ' . base64_encode($this->config->get('cardconnect_api_username') . ':' . $this->config->get('cardconnect_api_password'));
+
+ $this->model_extension_payment_cardconnect->log('Header: ' . print_r($header, true));
+
+ $this->model_extension_payment_cardconnect->log('URL: ' . $url);
+
+ $ch = curl_init();
+ curl_setopt($ch, CURLOPT_URL, $url);
+ curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
+ curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
+ curl_setopt($ch, CURLOPT_TIMEOUT, 30);
+ curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
+ $response_data = curl_exec($ch);
+ if (curl_errno($ch)) {
+ $this->model_extension_payment_cardconnect->log('cURL error: ' . curl_errno($ch));
+ }
+ curl_close($ch);
+
+ $response_data = json_decode($response_data, true);
+
+ $this->log('Response: ' . print_r($response_data, true));
+
+ return $response_data;
+ }
+
+ public function capture($order_info, $amount) {
+ $this->load->model('sale/order');
+
+ $this->log('Posting capture to CardConnect');
+
+ $this->log('Order ID: ' . $order_info['order_id']);
+
+ $order = $this->model_sale_order->getOrder($order_info['order_id']);
+
+ $totals = $this->model_sale_order->getOrderTotals($order_info['order_id']);
+
+ $shipping_cost = '';
+
+ foreach($totals as $total) {
+ if ($total['code'] == 'shipping') {
+ $shipping_cost = $total['value'];
+ }
+ }
+
+ $products = $this->model_sale_order->getOrderProducts($order_info['order_id']);
+
+ $items = array();
+
+ $i = 1;
+
+ foreach ($products as $product) {
+ $items[] = array(
+ 'lineno' => $i,
+ 'material' => '',
+ 'description' => $product['name'],
+ 'upc' => '',
+ 'quantity' => $product['quantity'],
+ 'uom' => '',
+ 'unitcost' => $product['price'],
+ 'netamnt' => $product['total'],
+ 'taxamnt' => $product['tax'],
+ 'discamnt' => ''
+ );
+
+ $i++;
+ }
+
+ $data = array(
+ 'merchid' => $this->config->get('payment_cardconnect_merchant_id'),
+ 'retref' => $order_info['retref'],
+ 'authcode' => $order_info['authcode'],
+ 'ponumber' => $order_info['order_id'],
+ 'amount' => round(floatval($amount), 2, PHP_ROUND_HALF_DOWN),
+ 'currency' => $order_info['currency_code'],
+ 'frtamnt' => $shipping_cost,
+ 'dutyamnt' => '',
+ 'orderdate' => '',
+ 'shiptozip' => $order['shipping_postcode'],
+ 'shipfromzip' => '',
+ 'shiptocountry' => $order['shipping_iso_code_2'],
+ 'Items' => $items
+ );
+
+ $data_json = json_encode($data);
+
+ $url = 'https://' . $this->config->get('cardconnect_site') . '.cardconnect.com:' . (($this->config->get('cardconnect_environment') == 'live') ? 8443 : 6443) . '/cardconnect/rest/capture';
+
+ $header = array();
+
+ $header[] = 'Content-type: application/json';
+ $header[] = 'Content-length: ' . strlen($data_json);
+ $header[] = 'Authorization: Basic ' . base64_encode($this->config->get('cardconnect_api_username') . ':' . $this->config->get('cardconnect_api_password'));
+
+ $this->model_extension_payment_cardconnect->log('Header: ' . print_r($header, true));
+
+ $this->model_extension_payment_cardconnect->log('Post Data: ' . print_r($data, true));
+
+ $this->model_extension_payment_cardconnect->log('URL: ' . $url);
+
+ $ch = curl_init();
+ curl_setopt($ch, CURLOPT_URL, $url);
+ curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
+ curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PUT');
+ curl_setopt($ch, CURLOPT_POSTFIELDS, $data_json);
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
+ curl_setopt($ch, CURLOPT_TIMEOUT, 30);
+ curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
+ $response_data = curl_exec($ch);
+ if (curl_errno($ch)) {
+ $this->model_extension_payment_cardconnect->log('cURL error: ' . curl_errno($ch));
+ }
+ curl_close($ch);
+
+ $response_data = json_decode($response_data, true);
+
+ $this->log('Response: ' . print_r($response_data, true));
+
+ return $response_data;
+ }
+
+ public function refund($order_info, $amount) {
+ $this->log('Posting refund to CardConnect');
+
+ $this->log('Order ID: ' . $order_info['order_id']);
+
+ $data = array(
+ 'merchid' => $this->config->get('payment_cardconnect_merchant_id'),
+ 'amount' => round(floatval($amount), 2, PHP_ROUND_HALF_DOWN),
+ 'currency' => $order_info['currency_code'],
+ 'retref' => $order_info['retref']
+ );
+
+ $data_json = json_encode($data);
+
+ $url = 'https://' . $this->config->get('cardconnect_site') . '.cardconnect.com:' . (($this->config->get('cardconnect_environment') == 'live') ? 8443 : 6443) . '/cardconnect/rest/refund';
+
+ $header = array();
+
+ $header[] = 'Content-type: application/json';
+ $header[] = 'Content-length: ' . strlen($data_json);
+ $header[] = 'Authorization: Basic ' . base64_encode($this->config->get('cardconnect_api_username') . ':' . $this->config->get('cardconnect_api_password'));
+
+ $this->model_extension_payment_cardconnect->log('Header: ' . print_r($header, true));
+
+ $this->model_extension_payment_cardconnect->log('Post Data: ' . print_r($data, true));
+
+ $this->model_extension_payment_cardconnect->log('URL: ' . $url);
+
+ $ch = curl_init();
+ curl_setopt($ch, CURLOPT_URL, $url);
+ curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
+ curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PUT');
+ curl_setopt($ch, CURLOPT_POSTFIELDS, $data_json);
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
+ curl_setopt($ch, CURLOPT_TIMEOUT, 30);
+ curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
+ $response_data = curl_exec($ch);
+ if (curl_errno($ch)) {
+ $this->model_extension_payment_cardconnect->log('cURL error: ' . curl_errno($ch));
+ }
+ curl_close($ch);
+
+ $response_data = json_decode($response_data, true);
+
+ $this->log('Response: ' . print_r($response_data, true));
+
+ return $response_data;
+ }
+
+ public function void($order_info, $retref) {
+ $this->log('Posting void to CardConnect');
+
+ $this->log('Order ID: ' . $order_info['order_id']);
+
+ $data = array(
+ 'merchid' => $this->config->get('payment_cardconnect_merchant_id'),
+ 'amount' => 0,
+ 'currency' => $order_info['currency_code'],
+ 'retref' => $retref
+ );
+
+ $data_json = json_encode($data);
+
+ $url = 'https://' . $this->config->get('cardconnect_site') . '.cardconnect.com:' . (($this->config->get('cardconnect_environment') == 'live') ? 8443 : 6443) . '/cardconnect/rest/void';
+
+ $header = array();
+
+ $header[] = 'Content-type: application/json';
+ $header[] = 'Content-length: ' . strlen($data_json);
+ $header[] = 'Authorization: Basic ' . base64_encode($this->config->get('cardconnect_api_username') . ':' . $this->config->get('cardconnect_api_password'));
+
+ $this->model_extension_payment_cardconnect->log('Header: ' . print_r($header, true));
+
+ $this->model_extension_payment_cardconnect->log('Post Data: ' . print_r($data, true));
+
+ $this->model_extension_payment_cardconnect->log('URL: ' . $url);
+
+ $ch = curl_init();
+ curl_setopt($ch, CURLOPT_URL, $url);
+ curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
+ curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PUT');
+ curl_setopt($ch, CURLOPT_POSTFIELDS, $data_json);
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
+ curl_setopt($ch, CURLOPT_TIMEOUT, 30);
+ curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
+ $response_data = curl_exec($ch);
+ if (curl_errno($ch)) {
+ $this->model_extension_payment_cardconnect->log('cURL error: ' . curl_errno($ch));
+ }
+ curl_close($ch);
+
+ $response_data = json_decode($response_data, true);
+
+ $this->log('Response: ' . print_r($response_data, true));
+
+ return $response_data;
+ }
+
+ public function updateTransactionStatusByRetref($retref, $status) {
+ $this->db->query("UPDATE `" . DB_PREFIX . "cardconnect_order_transaction` SET `status` = '" . $this->db->escape($status) . "', `date_modified` = NOW() WHERE `retref` = '" . $this->db->escape($retref) . "'");
+ }
+
+ public function addTransaction($cardconnect_order_id, $type, $retref, $amount, $status) {
+ $this->db->query("INSERT INTO `" . DB_PREFIX . "cardconnect_order_transaction` SET `cardconnect_order_id` = '" . (int)$cardconnect_order_id . "', `type` = '" . $this->db->escape($type) . "', `retref` = '" . $this->db->escape($retref) . "', `amount` = '" . (float)$amount . "', `status` = '" . $this->db->escape($status) . "', `date_modified` = NOW(), `date_added` = NOW()");
+ }
+
+ public function log($data) {
+ if ($this->config->get('cardconnect_logging')) {
+ $log = new Log('cardconnect.log');
+
+ $log->write($data);
+ }
+ }
+} \ No newline at end of file
diff --git a/public/admin/model/extension/payment/cardinity.php b/public/admin/model/extension/payment/cardinity.php
new file mode 100644
index 0000000..81ee76a
--- /dev/null
+++ b/public/admin/model/extension/payment/cardinity.php
@@ -0,0 +1,98 @@
+<?php
+use Cardinity\Client;
+use Cardinity\Method\Payment;
+use Cardinity\Method\Refund;
+
+class ModelExtensionPaymentCardinity extends Model {
+ public function getOrder($order_id) {
+ $query = $this->db->query("SELECT * FROM `" . DB_PREFIX . "cardinity_order` WHERE `order_id` = '" . (int)$order_id . "' LIMIT 1");
+
+ return $query->row;
+ }
+
+ public function createClient($credentials) {
+ return Client::create(array(
+ 'consumerKey' => $credentials['key'],
+ 'consumerSecret' => $credentials['secret'],
+ ));
+ }
+
+ public function verifyCredentials($client) {
+ $method = new Payment\GetAll(10);
+
+ try {
+ $client->call($method);
+
+ return true;
+ } catch (Exception $e) {
+ $this->log($e->getMessage());
+
+ return false;
+ }
+ }
+
+ public function getPayment($client, $payment_id) {
+ $method = new Payment\Get($payment_id);
+
+ try {
+ $payment = $client->call($method);
+
+ return $payment;
+ } catch (Exception $e) {
+ $this->log($e->getMessage());
+
+ return false;
+ }
+ }
+
+ public function getRefunds($client, $payment_id) {
+ $method = new Refund\GetAll($payment_id);
+
+ try {
+ $refunds = $client->call($method);
+
+ return $refunds;
+ } catch (Exception $e) {
+ $this->log($e->getMessage());
+
+ return false;
+ }
+ }
+
+ public function refundPayment($client, $payment_id, $amount, $description) {
+ $method = new Refund\Create($payment_id, $amount, $description);
+
+ try {
+ $refund = $client->call($method);
+
+ return $refund;
+ } catch (Exception $e) {
+ $this->log($e->getMessage());
+
+ return false;
+ }
+ }
+
+ public function log($data) {
+ if ($this->config->get('payment_cardinity_debug')) {
+ $backtrace = debug_backtrace();
+ $log = new Log('cardinity.log');
+ $log->write('(' . $backtrace[1]['class'] . '::' . $backtrace[1]['function'] . ') - ' . print_r($data, true));
+ }
+ }
+
+ public function install() {
+ $this->db->query("
+ CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "cardinity_order` (
+ `cardinity_order_id` INT(11) NOT NULL AUTO_INCREMENT,
+ `order_id` INT(11) NOT NULL,
+ `payment_id` VARCHAR(255),
+ PRIMARY KEY (`cardinity_order_id`)
+ ) ENGINE=MyISAM DEFAULT COLLATE=utf8_general_ci;
+ ");
+ }
+
+ public function uninstall() {
+ $this->db->query("DROP TABLE IF EXISTS `" . DB_PREFIX . "cardinity_order`;");
+ }
+} \ No newline at end of file
diff --git a/public/admin/model/extension/payment/divido.php b/public/admin/model/extension/payment/divido.php
new file mode 100644
index 0000000..b8c6116
--- /dev/null
+++ b/public/admin/model/extension/payment/divido.php
@@ -0,0 +1,81 @@
+<?php
+class ModelExtensionPaymentDivido extends Model {
+ const CACHE_KEY_PLANS = 'divido_plans';
+
+ public function getAllPlans() {
+ if ($plans = $this->cache->get(self::CACHE_KEY_PLANS)) {
+ // OpenCart 2.1 decodes json objects to associative arrays so we
+ // need to make sure we're getting a list of simple objects back.
+ $plans = array_map(function ($plan) {
+ return (object)$plan;
+ }, $plans);
+
+ return $plans;
+ }
+
+ $api_key = $this->config->get('payment_divido_api_key');
+ if (!$api_key) {
+ throw new Exception("No Divido api-key defined");
+ }
+
+ Divido::setMerchant($api_key);
+
+ $response = Divido_Finances::all();
+ if ($response->status != 'ok') {
+ throw new Exception("Can't get list of finance plans from Divido!");
+ }
+
+ $plans = $response->finances;
+
+ // OpenCart 2.1 switched to json for their file storage cache, so
+ // we need to convert to a simple object.
+ $plans_plain = array();
+ foreach ($plans as $plan) {
+ $plan_copy = new stdClass();
+ $plan_copy->id = $plan->id;
+ $plan_copy->text = $plan->text;
+ $plan_copy->country = $plan->country;
+ $plan_copy->min_amount = $plan->min_amount;
+ $plan_copy->min_deposit = $plan->min_deposit;
+ $plan_copy->max_deposit = $plan->max_deposit;
+ $plan_copy->interest_rate = $plan->interest_rate;
+ $plan_copy->deferral_period = $plan->deferral_period;
+ $plan_copy->agreement_duration = $plan->agreement_duration;
+
+ $plans_plain[] = $plan_copy;
+ }
+
+ $this->cache->set(self::CACHE_KEY_PLANS, $plans_plain);
+
+ return $plans_plain;
+ }
+
+ public function getLookupByOrderId($order_id) {
+ return $this->db->query("SELECT * FROM `" . DB_PREFIX . "divido_lookup` WHERE `order_id` = " . (int)$order_id);
+ }
+
+ public function install() {
+ $this->db->query("
+ CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "divido_product` (
+ `product_id` INT(11) NOT NULL,
+ `display` CHAR(7) NOT NULL,
+ `plans` text,
+ PRIMARY KEY (`product_id`)
+ ) ENGINE=MyISAM DEFAULT COLLATE=utf8_general_ci;");
+
+ $this->db->query("
+ CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "divido_lookup` (
+ `order_id` INT(11) NOT NULL,
+ `salt` CHAR(64) NOT NULL,
+ `proposal_id` CHAR(40),
+ `application_id` CHAR(40),
+ `deposit_amount` NUMERIC(6,2),
+ PRIMARY KEY (`order_id`)
+ ) ENGINE=MyISAM DEFAULT COLLATE=utf8_general_ci;");
+ }
+
+ public function uninstall() {
+ $this->db->query("DROP TABLE IF EXISTS `" . DB_PREFIX . "divido_product`;");
+ $this->db->query("DROP TABLE IF EXISTS `" . DB_PREFIX . "divido_lookup`;");
+ }
+}
diff --git a/public/admin/model/extension/payment/eway.php b/public/admin/model/extension/payment/eway.php
new file mode 100644
index 0000000..070a8d5
--- /dev/null
+++ b/public/admin/model/extension/payment/eway.php
@@ -0,0 +1,227 @@
+<?php
+
+class ModelExtensionPaymentEway extends Model {
+
+ public function install() {
+ $this->db->query("
+ CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "eway_order` (
+ `eway_order_id` int(11) NOT NULL AUTO_INCREMENT,
+ `order_id` int(11) NOT NULL,
+ `created` DATETIME NOT NULL,
+ `modified` DATETIME NOT NULL,
+ `amount` DECIMAL( 10, 2 ) NOT NULL,
+ `currency_code` CHAR(3) NOT NULL,
+ `transaction_id` VARCHAR(24) NOT NULL,
+ `debug_data` TEXT,
+ `capture_status` INT(1) DEFAULT NULL,
+ `void_status` INT(1) DEFAULT NULL,
+ `refund_status` INT(1) DEFAULT NULL,
+ PRIMARY KEY (`eway_order_id`)
+ ) ENGINE=MyISAM DEFAULT COLLATE=utf8_general_ci;");
+
+ $this->db->query("
+ CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "eway_transactions` (
+ `eway_order_transaction_id` int(11) NOT NULL AUTO_INCREMENT,
+ `eway_order_id` int(11) NOT NULL,
+ `transaction_id` VARCHAR(24) NOT NULL,
+ `created` DATETIME NOT NULL,
+ `type` ENUM('auth', 'payment', 'refund', 'void') DEFAULT NULL,
+ `amount` DECIMAL( 10, 2 ) NOT NULL,
+ PRIMARY KEY (`eway_order_transaction_id`)
+ ) ENGINE=MyISAM DEFAULT COLLATE=utf8_general_ci;");
+
+ $this->db->query("
+ CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "eway_card` (
+ `card_id` INT(11) NOT NULL AUTO_INCREMENT,
+ `customer_id` INT(11) NOT NULL,
+ `order_id` INT(11) NOT NULL,
+ `token` VARCHAR(50) NOT NULL,
+ `digits` VARCHAR(4) NOT NULL,
+ `expiry` VARCHAR(5) NOT NULL,
+ `type` VARCHAR(50) NOT NULL,
+ PRIMARY KEY (`card_id`)
+ ) ENGINE=MyISAM DEFAULT COLLATE=utf8_general_ci;");
+ }
+
+ public function uninstall() {
+ //$this->model_setting_setting->deleteSetting($this->request->get['extension']);
+ $this->db->query("DROP TABLE IF EXISTS `" . DB_PREFIX . "eway_order`;");
+ $this->db->query("DROP TABLE IF EXISTS `" . DB_PREFIX . "eway_transactions`;");
+ $this->db->query("DROP TABLE IF EXISTS `" . DB_PREFIX . "eway_card`;");
+ }
+
+ public function getOrder($order_id) {
+ $qry = $this->db->query("SELECT * FROM `" . DB_PREFIX . "eway_order` WHERE `order_id` = '" . (int)$order_id . "' LIMIT 1");
+
+ if ($qry->num_rows) {
+ $order = $qry->row;
+ $order['transactions'] = $this->getTransactions($order['eway_order_id']);
+ return $order;
+ } else {
+ return false;
+ }
+ }
+
+ public function addRefundRecord($order, $result) {
+ $transaction_id = $result->TransactionID;
+ $total_amount = $result->Refund->TotalAmount / 100;
+ $refund_amount = $order['refund_amount'] + $total_amount;
+
+ if (isset($order['refund_transaction_id']) && !empty($order['refund_transaction_id'])) {
+ $order['refund_transaction_id'] .= ',';
+ }
+ $order['refund_transaction_id'] .= $transaction_id;
+
+ $this->db->query("UPDATE `" . DB_PREFIX . "eway_order` SET `modified` = NOW(), refund_amount = '" . (double)$refund_amount . "', `refund_transaction_id` = '" . $this->db->escape($order['refund_transaction_id']) . "' WHERE eway_order_id = '" . $order['eway_order_id'] . "'");
+ }
+
+ public function capture($order_id, $capture_amount, $currency) {
+ $eway_order = $this->getOrder($order_id);
+
+ if ($eway_order && $capture_amount > 0 ) {
+
+ $capture_data = new stdClass();
+ $capture_data->Payment = new stdClass();
+ $capture_data->Payment->TotalAmount = (int)(number_format($capture_amount, 2, '.', '') * 100);
+ $capture_data->Payment->CurrencyCode = $currency;
+ $capture_data->TransactionID = $eway_order['transaction_id'];
+
+ if ($this->config->get('payment_eway_test')) {
+ $url = 'https://api.sandbox.ewaypayments.com/CapturePayment';
+ } else {
+ $url = 'https://api.ewaypayments.com/CapturePayment';
+ }
+
+ $response = $this->sendCurl($url, $capture_data);
+
+ return json_decode($response);
+
+ } else {
+ return false;
+ }
+ }
+
+ public function updateCaptureStatus($eway_order_id, $status) {
+ $this->db->query("UPDATE `" . DB_PREFIX . "eway_order` SET `capture_status` = '" . (int)$status . "' WHERE `eway_order_id` = '" . (int)$eway_order_id . "'");
+ }
+
+ public function updateTransactionId($eway_order_id, $transaction_id) {
+ $this->db->query("UPDATE `" . DB_PREFIX . "eway_order` SET `transaction_id` = '" . $transaction_id . "' WHERE `eway_order_id` = '" . (int)$eway_order_id . "'");
+ }
+
+ public function void($order_id) {
+ $eway_order = $this->getOrder($order_id);
+ if ($eway_order) {
+
+ $data = new stdClass();
+ $data->TransactionID = $eway_order['transaction_id'];
+
+ if ($this->config->get('payment_eway_test')) {
+ $url = 'https://api.sandbox.ewaypayments.com/CancelAuthorisation';
+ } else {
+ $url = 'https://api.ewaypayments.com/CancelAuthorisation';
+ }
+
+ $response = $this->sendCurl($url, $data);
+
+ return json_decode($response);
+
+ } else {
+ return false;
+ }
+ }
+
+ public function updateVoidStatus($eway_order_id, $status) {
+ $this->db->query("UPDATE `" . DB_PREFIX . "eway_order` SET `void_status` = '" . (int)$status . "' WHERE `eway_order_id` = '" . (int)$eway_order_id . "'");
+ }
+
+ public function refund($order_id, $refund_amount) {
+ $eway_order = $this->getOrder($order_id);
+
+ if ($eway_order && $refund_amount > 0) {
+
+ $refund_data = new stdClass();
+ $refund_data->Refund = new stdClass();
+ $refund_data->Refund->TotalAmount = (int)(number_format($refund_amount, 2, '.', '') * 100);
+ $refund_data->Refund->TransactionID = $eway_order['transaction_id'];
+ $refund_data->Refund->CurrencyCode = $eway_order['currency_code'];
+
+ if ($this->config->get('payment_eway_test')) {
+ $url = 'https://api.sandbox.ewaypayments.com/Transaction/' . $eway_order['transaction_id'] . '/Refund';
+ } else {
+ $url = 'https://api.ewaypayments.com/Transaction/' . $eway_order['transaction_id'] . '/Refund';
+ }
+
+ $response = $this->sendCurl($url, $refund_data);
+
+ return json_decode($response);
+ } else {
+ return false;
+ }
+ }
+
+ public function updateRefundStatus($eway_order_id, $status) {
+ $this->db->query("UPDATE `" . DB_PREFIX . "eway_order` SET `refund_status` = '" . (int)$status . "' WHERE `eway_order_id` = '" . (int)$eway_order_id . "'");
+ }
+
+ public function sendCurl($url, $data) {
+ $ch = curl_init($url);
+
+ $eway_username = html_entity_decode($this->config->get('payment_eway_username'), ENT_QUOTES, 'UTF-8');
+ $eway_password = html_entity_decode($this->config->get('payment_eway_password'), ENT_QUOTES, 'UTF-8');
+
+ curl_setopt($ch, CURLOPT_HTTPHEADER, array("Content-Type: application/json"));
+ curl_setopt($ch, CURLOPT_USERPWD, $eway_username . ":" . $eway_password);
+ curl_setopt($ch, CURLOPT_POST, 1);
+ curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
+ curl_setopt($ch, CURLOPT_TIMEOUT, 60);
+ curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 1);
+
+ $response = curl_exec($ch);
+
+ if (curl_errno($ch) != CURLE_OK) {
+ $response = new stdClass();
+ $response->Errors = "POST Error: " . curl_error($ch) . " URL: $url";
+ $response = json_encode($response);
+ } else {
+ $info = curl_getinfo($ch);
+ if ($info['http_code'] == 401 || $info['http_code'] == 404) {
+ $response = new stdClass();
+ $response->Errors = "Please check the API Key and Password";
+ $response = json_encode($response);
+ }
+ }
+
+ curl_close($ch);
+
+ return $response;
+ }
+
+ private function getTransactions($eway_order_id) {
+ $qry = $this->db->query("SELECT * FROM `" . DB_PREFIX . "eway_transactions` WHERE `eway_order_id` = '" . (int)$eway_order_id . "'");
+
+ if ($qry->num_rows) {
+ return $qry->rows;
+ } else {
+ return false;
+ }
+ }
+
+ public function addTransaction($eway_order_id, $transactionid, $type, $total, $currency) {
+ $this->db->query("INSERT INTO `" . DB_PREFIX . "eway_transactions` SET `eway_order_id` = '" . (int)$eway_order_id . "', `created` = NOW(), `transaction_id` = '" . $this->db->escape($transactionid) . "', `type` = '" . $this->db->escape($type) . "', `amount` = '" . $this->currency->format($total, $currency, false, false) . "'");
+ }
+
+ public function getTotalCaptured($eway_order_id) {
+ $query = $this->db->query("SELECT SUM(`amount`) AS `total` FROM `" . DB_PREFIX . "eway_transactions` WHERE `eway_order_id` = '" . (int)$eway_order_id . "' AND `type` = 'payment' ");
+
+ return (double)$query->row['total'];
+ }
+
+ public function getTotalRefunded($eway_order_id) {
+ $query = $this->db->query("SELECT SUM(`amount`) AS `total` FROM `" . DB_PREFIX . "eway_transactions` WHERE `eway_order_id` = '" . (int)$eway_order_id . "' AND `type` = 'refund'");
+
+ return (double)$query->row['total'];
+ }
+
+} \ No newline at end of file
diff --git a/public/admin/model/extension/payment/firstdata.php b/public/admin/model/extension/payment/firstdata.php
new file mode 100644
index 0000000..bac5b8e
--- /dev/null
+++ b/public/admin/model/extension/payment/firstdata.php
@@ -0,0 +1,222 @@
+<?php
+class ModelExtensionPaymentFirstdata extends Model {
+ public function install() {
+ $this->db->query("
+ CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "firstdata_order` (
+ `firstdata_order_id` INT(11) NOT NULL AUTO_INCREMENT,
+ `order_id` INT(11) NOT NULL,
+ `order_ref` CHAR(50) NOT NULL,
+ `order_ref_previous` CHAR(50) NOT NULL,
+ `pasref` VARCHAR(50) NOT NULL,
+ `pasref_previous` VARCHAR(50) NOT NULL,
+ `tdate` DATETIME NOT NULL,
+ `date_added` DATETIME NOT NULL,
+ `date_modified` DATETIME NOT NULL,
+ `capture_status` INT(1) DEFAULT NULL,
+ `void_status` INT(1) DEFAULT NULL,
+ `currency_code` CHAR(3) NOT NULL,
+ `authcode` VARCHAR(30) NOT NULL,
+ `account` VARCHAR(30) NOT NULL,
+ `total` DECIMAL( 10, 2 ) NOT NULL,
+ PRIMARY KEY (`firstdata_order_id`)
+ ) ENGINE=MyISAM DEFAULT COLLATE=utf8_general_ci;");
+
+ $this->db->query("
+ CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "firstdata_order_transaction` (
+ `firstdata_order_transaction_id` INT(11) NOT NULL AUTO_INCREMENT,
+ `firstdata_order_id` INT(11) NOT NULL,
+ `date_added` DATETIME NOT NULL,
+ `type` ENUM('auth', 'payment', 'void') DEFAULT NULL,
+ `amount` DECIMAL( 10, 2 ) NOT NULL,
+ PRIMARY KEY (`firstdata_order_transaction_id`)
+ ) ENGINE=MyISAM DEFAULT COLLATE=utf8_general_ci;");
+
+ $this->db->query("
+ CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "firstdata_card` (
+ `firstdata_card_id` INT(11) NOT NULL AUTO_INCREMENT,
+ `customer_id` INT(11) NOT NULL,
+ `date_added` DATETIME NOT NULL,
+ `digits` CHAR(25) NOT NULL,
+ `expire_month` INT(2) NOT NULL,
+ `expire_year` INT(2) NOT NULL,
+ `token` CHAR(64) NOT NULL,
+ PRIMARY KEY (`firstdata_card_id`)
+ ) ENGINE=MyISAM DEFAULT COLLATE=utf8_general_ci;");
+ }
+
+ public function uninstall() {
+ $this->db->query("DROP TABLE IF EXISTS `" . DB_PREFIX . "firstdata_order`;");
+ $this->db->query("DROP TABLE IF EXISTS `" . DB_PREFIX . "firstdata_order_transaction`;");
+ $this->db->query("DROP TABLE IF EXISTS `" . DB_PREFIX . "firstdata_card`;");
+ }
+
+ public function void($order_id) {
+ $firstdata_order = $this->getOrder($order_id);
+
+ if (!empty($firstdata_order)) {
+ $timestamp = strftime("%Y%m%d%H%M%S");
+ $merchant_id = $this->config->get('payment_firstdata_merchant_id');
+ $secret = $this->config->get('payment_firstdata_secret');
+
+ $this->logger('Void hash construct: ' . $timestamp . ' . ' . $merchant_id . ' . ' . $firstdata_order['order_ref'] . ' . . . ');
+
+ $tmp = $timestamp . ' . ' . $merchant_id . ' . ' . $firstdata_order['order_ref'] . ' . . . ';
+ $hash = sha1($tmp);
+ $tmp = $hash . ' . ' . $secret;
+ $hash = sha1($tmp);
+
+ $xml = '';
+ $xml .= '<request type="void" timestamp="' . $timestamp . '">';
+ $xml .= '<merchantid>' . $merchant_id . '</merchantid>';
+ $xml .= '<account>' . $firstdata_order['account'] . '</account>';
+ $xml .= '<orderid>' . $firstdata_order['order_ref'] . '</orderid>';
+ $xml .= '<pasref>' . $firstdata_order['pasref'] . '</pasref>';
+ $xml .= '<authcode>' . $firstdata_order['authcode'] . '</authcode>';
+ $xml .= '<sha1hash>' . $hash . '</sha1hash>';
+ $xml .= '</request>';
+
+ $this->logger('Void XML request:\r\n' . print_r(simplexml_load_string($xml), 1));
+
+ $ch = curl_init();
+ curl_setopt($ch, CURLOPT_URL, "https://epage.payandshop.com/epage-remote.cgi");
+ curl_setopt($ch, CURLOPT_POST, 1);
+ curl_setopt($ch, CURLOPT_USERAGENT, "OpenCart " . VERSION);
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
+ curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);
+ curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
+ $response = curl_exec ($ch);
+ curl_close ($ch);
+
+ return simplexml_load_string($response);
+ } else {
+ return false;
+ }
+ }
+
+ public function updateVoidStatus($firstdata_order_id, $status) {
+ $this->db->query("UPDATE `" . DB_PREFIX . "firstdata_order` SET `void_status` = '" . (int)$status . "' WHERE `firstdata_order_id` = '" . (int)$firstdata_order_id . "'");
+ }
+
+ public function capture($order_id, $amount) {
+ $firstdata_order = $this->getOrder($order_id);
+
+ if (!empty($firstdata_order) && $firstdata_order['capture_status'] == 0) {
+ $timestamp = strftime("%Y%m%d%H%M%S");
+ $merchant_id = $this->config->get('payment_firstdata_merchant_id');
+ $secret = $this->config->get('payment_firstdata_secret');
+
+ if ($firstdata_order['settle_type'] == 2) {
+ $this->logger('Capture hash construct: ' . $timestamp . ' . ' . $merchant_id . ' . ' . $firstdata_order['order_ref'] . ' . ' . (int)round($amount*100) . ' . ' . (string)$firstdata_order['currency_code'] . ' . ');
+
+ $tmp = $timestamp . ' . ' . $merchant_id . ' . ' . $firstdata_order['order_ref'] . ' . ' . (int)round($amount*100) . ' . ' . (string)$firstdata_order['currency_code'] . ' . ';
+ $hash = sha1($tmp);
+ $tmp = $hash . ' . ' . $secret;
+ $hash = sha1($tmp);
+
+ $settle_type = 'multisettle';
+ $xml_amount = '<amount currency="' . (string)$firstdata_order['currency_code'] . '">' . (int)round($amount*100) . '</amount>';
+ } else {
+ //$this->logger('Capture hash construct: ' . $timestamp . ' . ' . $merchant_id . ' . ' . $firstdata_order['order_ref'] . ' . . . ');
+ $this->logger('Capture hash construct: ' . $timestamp . ' . ' . $merchant_id . ' . ' . $firstdata_order['order_ref'] . ' . ' . (int)round($amount*100) . ' . ' . (string)$firstdata_order['currency_code'] . ' . ');
+
+ $tmp = $timestamp . ' . ' . $merchant_id . ' . ' . $firstdata_order['order_ref'] . ' . ' . (int)round($amount*100) . ' . ' . (string)$firstdata_order['currency_code'] . ' . ';
+ $hash = sha1($tmp);
+ $tmp = $hash . ' . ' . $secret;
+ $hash = sha1($tmp);
+
+ $settle_type = 'settle';
+ $xml_amount = '<amount currency="' . (string)$firstdata_order['currency_code'] . '">' . (int)round($amount*100) . '</amount>';
+ }
+
+ $xml = '';
+ $xml .= '<request type="' . $settle_type . '" timestamp="' . $timestamp . '">';
+ $xml .= '<merchantid>' . $merchant_id . '</merchantid>';
+ $xml .= '<account>' . $firstdata_order['account'] . '</account>';
+ $xml .= '<orderid>' . $firstdata_order['order_ref'] . '</orderid>';
+ $xml .= $xml_amount;
+ $xml .= '<pasref>' . $firstdata_order['pasref'] . '</pasref>';
+ $xml .= '<autosettle flag="1" />';
+ $xml .= '<authcode>' . $firstdata_order['authcode'] . '</authcode>';
+ $xml .= '<sha1hash>' . $hash . '</sha1hash>';
+ $xml .= '</request>';
+
+ $this->logger('Settle XML request:\r\n' . print_r(simplexml_load_string($xml), 1));
+
+ $ch = curl_init();
+ curl_setopt($ch, CURLOPT_URL, "https://epage.payandshop.com/epage-remote.cgi");
+ curl_setopt($ch, CURLOPT_POST, 1);
+ curl_setopt($ch, CURLOPT_USERAGENT, "OpenCart " . VERSION);
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
+ curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);
+ curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
+ $response = curl_exec ($ch);
+ curl_close ($ch);
+
+ return simplexml_load_string($response);
+ } else {
+ return false;
+ }
+ }
+
+ public function updateCaptureStatus($firstdata_order_id, $status) {
+ $this->db->query("UPDATE `" . DB_PREFIX . "firstdata_order` SET `capture_status` = '" . (int)$status . "' WHERE `firstdata_order_id` = '" . (int)$firstdata_order_id . "'");
+ }
+
+ public function getOrder($order_id) {
+ $this->logger('getOrder - ' . $order_id);
+
+ $qry = $this->db->query("SELECT * FROM `" . DB_PREFIX . "firstdata_order` WHERE `order_id` = '" . (int)$order_id . "' LIMIT 1");
+
+ if ($qry->num_rows) {
+ $order = $qry->row;
+ $order['transactions'] = $this->getTransactions($order['firstdata_order_id']);
+
+ $this->logger(print_r($order, 1));
+
+ return $order;
+ } else {
+ return false;
+ }
+ }
+
+ private function getTransactions($firstdata_order_id) {
+ $qry = $this->db->query("SELECT * FROM `" . DB_PREFIX . "firstdata_order_transaction` WHERE `firstdata_order_id` = '" . (int)$firstdata_order_id . "'");
+
+ if ($qry->num_rows) {
+ return $qry->rows;
+ } else {
+ return false;
+ }
+ }
+
+ public function addTransaction($firstdata_order_id, $type, $total) {
+ $this->db->query("INSERT INTO `" . DB_PREFIX . "firstdata_order_transaction` SET `firstdata_order_id` = '" . (int)$firstdata_order_id . "', `date_added` = now(), `type` = '" . $this->db->escape($type) . "', `amount` = '" . (float)$total . "'");
+ }
+
+ public function logger($message) {
+ if ($this->config->get('payment_firstdata_debug') == 1) {
+ $log = new Log('firstdata.log');
+ $log->write($message);
+ }
+ }
+
+ public function getTotalCaptured($firstdata_order_id) {
+ $query = $this->db->query("SELECT SUM(`amount`) AS `total` FROM `" . DB_PREFIX . "firstdata_order_transaction` WHERE `firstdata_order_id` = '" . (int)$firstdata_order_id . "' AND (`type` = 'payment' OR `type` = 'refund')");
+
+ return (float)$query->row['total'];
+ }
+
+ public function mapCurrency($code) {
+ $currency = array(
+ 'GBP' => 826,
+ 'USD' => 840,
+ 'EUR' => 978,
+ );
+
+ if (array_key_exists($code, $currency)) {
+ return $currency[$code];
+ } else {
+ return false;
+ }
+ }
+} \ No newline at end of file
diff --git a/public/admin/model/extension/payment/firstdata_remote.php b/public/admin/model/extension/payment/firstdata_remote.php
new file mode 100644
index 0000000..9cbd1bc
--- /dev/null
+++ b/public/admin/model/extension/payment/firstdata_remote.php
@@ -0,0 +1,278 @@
+<?php
+class ModelExtensionPaymentFirstdataRemote extends Model {
+ public function install() {
+ $this->db->query("
+ CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "firstdata_remote_order` (
+ `firstdata_remote_order_id` INT(11) NOT NULL AUTO_INCREMENT,
+ `order_id` INT(11) NOT NULL,
+ `order_ref` CHAR(50) NOT NULL,
+ `date_added` DATETIME NOT NULL,
+ `date_modified` DATETIME NOT NULL,
+ `tdate` VARCHAR(30) NOT NULL,
+ `capture_status` INT(1) DEFAULT NULL,
+ `void_status` INT(1) DEFAULT NULL,
+ `refund_status` INT(1) DEFAULT NULL,
+ `currency_code` CHAR(3) NOT NULL,
+ `authcode` VARCHAR(30) NOT NULL,
+ `total` DECIMAL( 10, 2 ) NOT NULL,
+ PRIMARY KEY (`firstdata_remote_order_id`)
+ ) ENGINE=MyISAM DEFAULT COLLATE=utf8_general_ci;");
+
+ $this->db->query("
+ CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "firstdata_remote_order_transaction` (
+ `firstdata_remote_order_transaction_id` INT(11) NOT NULL AUTO_INCREMENT,
+ `firstdata_remote_order_id` INT(11) NOT NULL,
+ `date_added` DATETIME NOT NULL,
+ `type` ENUM('auth', 'payment', 'refund', 'void') DEFAULT NULL,
+ `amount` DECIMAL( 10, 2 ) NOT NULL,
+ PRIMARY KEY (`firstdata_remote_order_transaction_id`)
+ ) ENGINE=MyISAM DEFAULT COLLATE=utf8_general_ci;");
+
+ $this->db->query("
+ CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "firstdata_remote_card` (
+ `firstdata_remote_card_id` INT(11) NOT NULL AUTO_INCREMENT,
+ `customer_id` INT(11) NOT NULL,
+ `date_added` DATETIME NOT NULL,
+ `digits` CHAR(4) NOT NULL,
+ `expire_month` INT(2) NOT NULL,
+ `expire_year` INT(2) NOT NULL,
+ `card_type` CHAR(15) NOT NULL,
+ `token` CHAR(64) NOT NULL,
+ PRIMARY KEY (`firstdata_remote_card_id`)
+ ) ENGINE=MyISAM DEFAULT COLLATE=utf8_general_ci;");
+ }
+
+ public function uninstall() {
+ $this->db->query("DROP TABLE IF EXISTS `" . DB_PREFIX . "firstdata_remote_order`;");
+ $this->db->query("DROP TABLE IF EXISTS `" . DB_PREFIX . "firstdata_remote_order_transaction`;");
+ $this->db->query("DROP TABLE IF EXISTS `" . DB_PREFIX . "firstdata_remote_card`;");
+ }
+
+ public function call($xml) {
+ $ch = curl_init();
+ curl_setopt($ch, CURLOPT_URL, "https://test.ipg-online.com/ipgapi/services");
+ curl_setopt($ch, CURLOPT_POST, 1);
+ curl_setopt($ch, CURLOPT_HTTPHEADER, array("Content-Type: text/xml"));
+ curl_setopt($ch, CURLOPT_HTTPAUTH, 'CURLAUTH_BASIC');
+ curl_setopt($ch, CURLOPT_USERPWD, $this->config->get('firstdata_remote_user_id') . ':' . $this->config->get('firstdata_remote_password'));
+ curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 1);
+ curl_setopt($ch, CURLOPT_CAINFO, $this->config->get('firstdata_remote_ca'));
+ curl_setopt($ch, CURLOPT_SSLCERT, $this->config->get('firstdata_remote_certificate'));
+ curl_setopt($ch, CURLOPT_SSLKEY, $this->config->get('firstdata_remote_key'));
+ curl_setopt($ch, CURLOPT_SSLKEYPASSWD, $this->config->get('firstdata_remote_key_pw'));
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
+ curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);
+ //curl_setopt($ch, CURLOPT_STDERR, fopen(DIR_LOGS . "/headers.txt", "w+"));
+ curl_setopt($ch, CURLOPT_VERBOSE, true);
+ $response = curl_exec ($ch);
+
+ $this->logger('Post data: ' . print_r($this->request->post, 1));
+ $this->logger('Request: ' . $xml);
+ $this->logger('Curl error #: ' . curl_errno($ch));
+ $this->logger('Curl error text: ' . curl_error($ch));
+ $this->logger('Curl response info: ' . print_r(curl_getinfo($ch), 1));
+ $this->logger('Curl response: ' . $response);
+
+ curl_close ($ch);
+
+ return $response;
+ }
+
+ public function void($order_ref, $tdate) {
+ $xml = '<?xml version="1.0" encoding="UTF-8"?>';
+ $xml .= '<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">';
+ $xml .= '<SOAP-ENV:Header />';
+ $xml .= '<SOAP-ENV:Body>';
+ $xml .= '<ipgapi:IPGApiOrderRequest xmlns:v1="http://ipg-online.com/ipgapi/schemas/v1" xmlns:ipgapi="http://ipg-online.com/ipgapi/schemas/ipgapi">';
+ $xml .= '<v1:Transaction>';
+ $xml .= '<v1:CreditCardTxType>';
+ $xml .= '<v1:Type>void</v1:Type>';
+ $xml .= '</v1:CreditCardTxType>';
+ $xml .= '<v1:TransactionDetails>';
+ $xml .= '<v1:OrderId>' . $order_ref . '</v1:OrderId>';
+ $xml .= '<v1:TDate>' . $tdate . '</v1:TDate>';
+ $xml .= '</v1:TransactionDetails>';
+ $xml .= '</v1:Transaction>';
+ $xml .= '</ipgapi:IPGApiOrderRequest>';
+ $xml .= '</SOAP-ENV:Body>';
+ $xml .= '</SOAP-ENV:Envelope>';
+
+ $xml = simplexml_load_string($this->call($xml));
+
+ $xml->registerXPathNamespace('ipgapi', 'http://ipg-online.com/ipgapi/schemas/ipgapi');
+ $xml->registerXPathNamespace('soap', 'http://schemas.xmlsoap.org/soap/envelope/');
+
+ $fault = $xml->xpath('//soap:Fault');
+
+ $response['fault'] = '';
+ if (!empty($fault[0]) && isset($fault[0]->detail)) {
+ $response['fault'] = (string)$fault[0]->detail;
+ }
+
+ $string = $xml->xpath('//ipgapi:ErrorMessage');
+ $response['error'] = isset($string[0]) ? (string)$string[0] : '';
+
+ $string = $xml->xpath('//ipgapi:TransactionResult');
+ $response['transaction_result'] = isset($string[0]) ? (string)$string[0] : '';
+
+ return $response;
+ }
+
+ public function updateVoidStatus($firstdata_remote_order_id, $status) {
+ $this->db->query("UPDATE `" . DB_PREFIX . "firstdata_remote_order` SET `void_status` = '" . (int)$status . "' WHERE `firstdata_remote_order_id` = '" . (int)$firstdata_remote_order_id . "'");
+ }
+
+ public function capture($order_ref, $total, $currency_code) {
+ $xml = '<?xml version="1.0" encoding="UTF-8"?>';
+ $xml .= '<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">';
+ $xml .= '<SOAP-ENV:Header />';
+ $xml .= '<SOAP-ENV:Body>';
+ $xml .= '<ipgapi:IPGApiOrderRequest xmlns:v1="http://ipg-online.com/ipgapi/schemas/v1" xmlns:ipgapi="http://ipg-online.com/ipgapi/schemas/ipgapi">';
+ $xml .= '<v1:Transaction>';
+ $xml .= '<v1:CreditCardTxType>';
+ $xml .= '<v1:Type>postAuth</v1:Type>';
+ $xml .= '</v1:CreditCardTxType>';
+ $xml .= '<v1:Payment>';
+ $xml .= '<v1:ChargeTotal>' . $total . '</v1:ChargeTotal>';
+ $xml .= '<v1:Currency>' . $this->mapCurrency($currency_code) . '</v1:Currency>';
+ $xml .= '</v1:Payment>';
+ $xml .= '<v1:TransactionDetails>';
+ $xml .= '<v1:OrderId>' . $order_ref . '</v1:OrderId>';
+ $xml .= '</v1:TransactionDetails>';
+ $xml .= '</v1:Transaction>';
+ $xml .= '</ipgapi:IPGApiOrderRequest>';
+ $xml .= '</SOAP-ENV:Body>';
+ $xml .= '</SOAP-ENV:Envelope>';
+
+ $xml = simplexml_load_string($this->call($xml));
+
+ $xml->registerXPathNamespace('ipgapi', 'http://ipg-online.com/ipgapi/schemas/ipgapi');
+ $xml->registerXPathNamespace('soap', 'http://schemas.xmlsoap.org/soap/envelope/');
+
+ $fault = $xml->xpath('//soap:Fault');
+
+ $response['fault'] = '';
+ if (!empty($fault[0]) && isset($fault[0]->detail)) {
+ $response['fault'] = (string)$fault[0]->detail;
+ }
+
+ $string = $xml->xpath('//ipgapi:ErrorMessage');
+ $response['error'] = isset($string[0]) ? (string)$string[0] : '';
+
+ $string = $xml->xpath('//ipgapi:TransactionResult');
+ $response['transaction_result'] = isset($string[0]) ? (string)$string[0] : '';
+
+ return $response;
+ }
+
+ public function updateCaptureStatus($firstdata_remote_order_id, $status) {
+ $this->db->query("UPDATE `" . DB_PREFIX . "firstdata_remote_order` SET `capture_status` = '" . (int)$status . "' WHERE `firstdata_remote_order_id` = '" . (int)$firstdata_remote_order_id . "'");
+ }
+
+ public function refund($order_ref, $total, $currency_code) {
+ $xml = '<?xml version="1.0" encoding="UTF-8"?>';
+ $xml .= '<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">';
+ $xml .= '<SOAP-ENV:Header />';
+ $xml .= '<SOAP-ENV:Body>';
+ $xml .= '<ipgapi:IPGApiOrderRequest xmlns:v1="http://ipg-online.com/ipgapi/schemas/v1" xmlns:ipgapi="http://ipg-online.com/ipgapi/schemas/ipgapi">';
+ $xml .= '<v1:Transaction>';
+ $xml .= '<v1:CreditCardTxType>';
+ $xml .= '<v1:Type>return</v1:Type>';
+ $xml .= '</v1:CreditCardTxType>';
+ $xml .= '<v1:Payment>';
+ $xml .= '<v1:ChargeTotal>' . $total . '</v1:ChargeTotal>';
+ $xml .= '<v1:Currency>' . $this->mapCurrency($currency_code) . '</v1:Currency>';
+ $xml .= '</v1:Payment>';
+ $xml .= '<v1:TransactionDetails>';
+ $xml .= '<v1:OrderId>' . $order_ref . '</v1:OrderId>';
+ $xml .= '</v1:TransactionDetails>';
+ $xml .= '</v1:Transaction>';
+ $xml .= '</ipgapi:IPGApiOrderRequest>';
+ $xml .= '</SOAP-ENV:Body>';
+ $xml .= '</SOAP-ENV:Envelope>';
+
+ $xml = simplexml_load_string($this->call($xml));
+
+ $xml->registerXPathNamespace('ipgapi', 'http://ipg-online.com/ipgapi/schemas/ipgapi');
+ $xml->registerXPathNamespace('soap', 'http://schemas.xmlsoap.org/soap/envelope/');
+
+ $fault = $xml->xpath('//soap:Fault');
+
+ $response['fault'] = '';
+ if (!empty($fault[0]) && isset($fault[0]->detail)) {
+ $response['fault'] = (string)$fault[0]->detail;
+ }
+
+ $string = $xml->xpath('//ipgapi:ErrorMessage');
+ $response['error'] = isset($string[0]) ? (string)$string[0] : '';
+
+ $string = $xml->xpath('//ipgapi:TransactionResult');
+ $response['transaction_result'] = isset($string[0]) ? (string)$string[0] : '';
+
+ return $response;
+ }
+
+ public function updateRefundStatus($firstdata_remote_order_id, $status) {
+ $this->db->query("UPDATE `" . DB_PREFIX . "firstdata_remote_order` SET `refund_status` = '" . (int)$status . "' WHERE `firstdata_remote_order_id` = '" . (int)$firstdata_remote_order_id . "'");
+ }
+
+ public function getOrder($order_id) {
+ $qry = $this->db->query("SELECT * FROM `" . DB_PREFIX . "firstdata_remote_order` WHERE `order_id` = '" . (int)$order_id . "' LIMIT 1");
+
+ if ($qry->num_rows) {
+ $order = $qry->row;
+ $order['transactions'] = $this->getTransactions($order['firstdata_remote_order_id']);
+
+ return $order;
+ } else {
+ return false;
+ }
+ }
+
+ private function getTransactions($firstdata_remote_order_id) {
+ $qry = $this->db->query("SELECT * FROM `" . DB_PREFIX . "firstdata_remote_order_transaction` WHERE `firstdata_remote_order_id` = '" . (int)$firstdata_remote_order_id . "'");
+
+ if ($qry->num_rows) {
+ return $qry->rows;
+ } else {
+ return false;
+ }
+ }
+
+ public function addTransaction($firstdata_remote_order_id, $type, $total) {
+ $this->db->query("INSERT INTO `" . DB_PREFIX . "firstdata_remote_order_transaction` SET `firstdata_remote_order_id` = '" . (int)$firstdata_remote_order_id . "', `date_added` = now(), `type` = '" . $this->db->escape($type) . "', `amount` = '" . (float)$total . "'");
+ }
+
+ public function logger($message) {
+ if ($this->config->get('firstdata_remote_debug') == 1) {
+ $log = new Log('firstdata_remote.log');
+ $log->write($message);
+ }
+ }
+
+ public function getTotalCaptured($firstdata_order_id) {
+ $query = $this->db->query("SELECT SUM(`amount`) AS `total` FROM `" . DB_PREFIX . "firstdata_remote_order_transaction` WHERE `firstdata_remote_order_id` = '" . (int)$firstdata_order_id . "' AND (`type` = 'payment' OR `type` = 'refund')");
+
+ return (float)$query->row['total'];
+ }
+
+ public function getTotalRefunded($firstdata_order_id) {
+ $query = $this->db->query("SELECT SUM(`amount`) AS `total` FROM `" . DB_PREFIX . "firstdata_remote_order_transaction` WHERE `firstdata_remote_order_id` = '" . (int)$firstdata_order_id . "' AND 'refund'");
+
+ return (float)$query->row['total'];
+ }
+
+ public function mapCurrency($code) {
+ $currency = array(
+ 'GBP' => 826,
+ 'USD' => 840,
+ 'EUR' => 978,
+ );
+
+ if (array_key_exists($code, $currency)) {
+ return $currency[$code];
+ } else {
+ return false;
+ }
+ }
+} \ No newline at end of file
diff --git a/public/admin/model/extension/payment/g2apay.php b/public/admin/model/extension/payment/g2apay.php
new file mode 100644
index 0000000..83ea7b8
--- /dev/null
+++ b/public/admin/model/extension/payment/g2apay.php
@@ -0,0 +1,145 @@
+<?php
+
+class ModelExtensionPaymentG2aPay extends Model {
+
+ public function install() {
+ $this->db->query("
+ CREATE TABLE `" . DB_PREFIX . "g2apay_order` (
+ `g2apay_order_id` INT(11) NOT NULL AUTO_INCREMENT,
+ `order_id` int(11) NOT NULL,
+ `g2apay_transaction_id` varchar(255) NOT NULL,
+ `date_added` DATETIME NOT NULL,
+ `modified` DATETIME NOT NULL,
+ `refund_status` INT(1) DEFAULT NULL,
+ `currency_code` CHAR(3) NOT NULL,
+ `total` DECIMAL( 10, 2 ) NOT NULL,
+ KEY `g2apay_transaction_id` (`g2apay_transaction_id`),
+ PRIMARY KEY `g2apay_order_id` (`g2apay_order_id`)
+ ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci;
+ ");
+
+ $this->db->query("
+ CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "g2apay_order_transaction` (
+ `g2apay_order_transaction_id` INT(11) NOT NULL AUTO_INCREMENT,
+ `g2apay_order_id` INT(11) NOT NULL,
+ `date_added` DATETIME NOT NULL,
+ `type` ENUM('payment', 'refund') DEFAULT NULL,
+ `amount` DECIMAL( 10, 2 ) NOT NULL,
+ PRIMARY KEY (`g2apay_order_transaction_id`)
+ ) ENGINE=MyISAM DEFAULT COLLATE=utf8_general_ci;
+ ");
+ }
+
+ public function uninstall() {
+ $this->db->query("DROP TABLE IF EXISTS `" . DB_PREFIX . "g2apay_order`;");
+ $this->db->query("DROP TABLE IF EXISTS `" . DB_PREFIX . "g2apay_order_transaction`;");
+ }
+
+ public function getOrder($order_id) {
+
+ $qry = $this->db->query("SELECT * FROM `" . DB_PREFIX . "g2apay_order` WHERE `order_id` = '" . (int)$order_id . "' LIMIT 1");
+
+ if ($qry->num_rows) {
+ $order = $qry->row;
+ $order['transactions'] = $this->getTransactions($order['g2apay_order_id'], $qry->row['currency_code']);
+ return $order;
+ } else {
+ return false;
+ }
+ }
+
+ public function getTotalReleased($g2apay_order_id) {
+ $query = $this->db->query("SELECT SUM(`amount`) AS `total` FROM `" . DB_PREFIX . "g2apay_order_transaction` WHERE `g2apay_order_id` = '" . (int)$g2apay_order_id . "' AND (`type` = 'payment' OR `type` = 'refund')");
+
+ return (double)$query->row['total'];
+ }
+
+ public function refund($g2apay_order, $amount) {
+ if (!empty($g2apay_order) && $g2apay_order['refund_status'] != 1) {
+ if ($this->config->get('payment_g2apay_environment') == 1) {
+ $url = 'https://pay.g2a.com/rest/transactions/' . $g2apay_order['g2apay_transaction_id'];
+ } else {
+ $url = 'https://www.test.pay.g2a.com/rest/transactions/' . $g2apay_order['g2apay_transaction_id'];
+ }
+
+ $refunded_amount = round($amount, 2);
+
+ $string = $g2apay_order['g2apay_transaction_id'] . $g2apay_order['order_id'] . round($g2apay_order['total'], 2) . $refunded_amount . html_entity_decode($this->config->get('payment_g2apay_secret'));
+ $hash = hash('sha256', $string);
+
+ $fields = array(
+ 'action' => 'refund',
+ 'amount' => $refunded_amount,
+ 'hash' => $hash,
+ );
+
+ return $this->sendCurl($url, $fields);
+ } else {
+ return false;
+ }
+ }
+
+ public function updateRefundStatus($g2apay_order_id, $status) {
+ $this->db->query("UPDATE `" . DB_PREFIX . "g2apay_order` SET `refund_status` = '" . (int)$status . "' WHERE `g2apay_order_id` = '" . (int)$g2apay_order_id . "'");
+ }
+
+ private function getTransactions($g2apay_order_id, $currency_code) {
+ $query = $this->db->query("SELECT * FROM `" . DB_PREFIX . "g2apay_order_transaction` WHERE `g2apay_order_id` = '" . (int)$g2apay_order_id . "'");
+
+ $transactions = array();
+ if ($query->num_rows) {
+ foreach ($query->rows as $row) {
+ $row['amount'] = $this->currency->format($row['amount'], $currency_code, true, true);
+ $transactions[] = $row;
+ }
+ return $transactions;
+ } else {
+ return false;
+ }
+ }
+
+ public function addTransaction($g2apay_order_id, $type, $total) {
+ $this->db->query("INSERT INTO `" . DB_PREFIX . "g2apay_order_transaction` SET `g2apay_order_id` = '" . (int)$g2apay_order_id . "',`date_added` = now(), `type` = '" . $this->db->escape($type) . "', `amount` = '" . (double)$total . "'");
+ }
+
+ public function getTotalRefunded($g2apay_order_id) {
+ $query = $this->db->query("SELECT SUM(`amount`) AS `total` FROM `" . DB_PREFIX . "g2apay_order_transaction` WHERE `g2apay_order_id` = '" . (int)$g2apay_order_id . "' AND 'refund'");
+
+ return (double)$query->row['total'];
+ }
+
+ public function sendCurl($url, $fields) {
+ $curl = curl_init($url);
+ curl_setopt($curl, CURLOPT_URL, $url);
+ curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
+ curl_setopt($curl, CURLOPT_CUSTOMREQUEST, "PUT");
+ curl_setopt($curl, CURLOPT_POSTFIELDS, http_build_query($fields));
+
+ $auth_hash = hash('sha256', $this->config->get('payment_g2apay_api_hash') . $this->config->get('payment_g2apay_username') . html_entity_decode($this->config->get('payment_g2apay_secret')));
+ $authorization = $this->config->get('payment_g2apay_api_hash') . ";" . $auth_hash;
+ curl_setopt(
+ $curl, CURLOPT_HTTPHEADER, array(
+ "Authorization: " . $authorization
+ )
+ );
+
+ $response = json_decode(curl_exec($curl));
+
+ curl_close($curl);
+ if (is_object($response)) {
+ return (string)$response->status;
+ } else {
+ return str_replace('"', "", $response);
+ }
+ }
+
+ public function logger($message) {
+ if ($this->config->get('payment_g2apay_debug') == 1) {
+ $log = new Log('g2apay.log');
+ $backtrace = debug_backtrace();
+ $log->write('Origin: ' . $backtrace[6]['class'] . '::' . $backtrace[6]['function']);
+ $log->write(print_r($message, 1));
+ }
+ }
+
+}
diff --git a/public/admin/model/extension/payment/globalpay.php b/public/admin/model/extension/payment/globalpay.php
new file mode 100644
index 0000000..a28dbb2
--- /dev/null
+++ b/public/admin/model/extension/payment/globalpay.php
@@ -0,0 +1,265 @@
+<?php
+class ModelExtensionPaymentGlobalpay extends Model {
+ public function install() {
+ $this->db->query("
+ CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "globalpay_order` (
+ `globalpay_order_id` INT(11) NOT NULL AUTO_INCREMENT,
+ `order_id` INT(11) NOT NULL,
+ `order_ref` CHAR(50) NOT NULL,
+ `order_ref_previous` CHAR(50) NOT NULL,
+ `pasref` VARCHAR(50) NOT NULL,
+ `pasref_previous` VARCHAR(50) NOT NULL,
+ `date_added` DATETIME NOT NULL,
+ `date_modified` DATETIME NOT NULL,
+ `capture_status` INT(1) DEFAULT NULL,
+ `void_status` INT(1) DEFAULT NULL,
+ `settle_type` INT(1) DEFAULT NULL,
+ `rebate_status` INT(1) DEFAULT NULL,
+ `currency_code` CHAR(3) NOT NULL,
+ `authcode` VARCHAR(30) NOT NULL,
+ `account` VARCHAR(30) NOT NULL,
+ `total` DECIMAL( 10, 2 ) NOT NULL,
+ PRIMARY KEY (`globalpay_order_id`)
+ ) ENGINE=MyISAM DEFAULT COLLATE=utf8_general_ci;");
+
+ $this->db->query("
+ CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "globalpay_order_transaction` (
+ `globalpay_order_transaction_id` INT(11) NOT NULL AUTO_INCREMENT,
+ `globalpay_order_id` INT(11) NOT NULL,
+ `date_added` DATETIME NOT NULL,
+ `type` ENUM('auth', 'payment', 'rebate', 'void') DEFAULT NULL,
+ `amount` DECIMAL( 10, 2 ) NOT NULL,
+ PRIMARY KEY (`globalpay_order_transaction_id`)
+ ) ENGINE=MyISAM DEFAULT COLLATE=utf8_general_ci;");
+ }
+
+ public function void($order_id) {
+ $globalpay_order = $this->getOrder($order_id);
+
+ if (!empty($globalpay_order)) {
+ $timestamp = strftime("%Y%m%d%H%M%S");
+ $merchant_id = $this->config->get('payment_globalpay_merchant_id');
+ $secret = $this->config->get('payment_globalpay_secret');
+
+ $this->logger('Void hash construct: ' . $timestamp . '.' . $merchant_id . '.' . $globalpay_order['order_ref'] . '...');
+
+ $tmp = $timestamp . '.' . $merchant_id . '.' . $globalpay_order['order_ref'] . '...';
+ $hash = sha1($tmp);
+ $tmp = $hash . '.' . $secret;
+ $hash = sha1($tmp);
+
+ $xml = '';
+ $xml .= '<request type="void" timestamp="' . $timestamp . '">';
+ $xml .= '<merchantid>' . $merchant_id . '</merchantid>';
+ $xml .= '<account>' . $globalpay_order['account'] . '</account>';
+ $xml .= '<orderid>' . $globalpay_order['order_ref'] . '</orderid>';
+ $xml .= '<pasref>' . $globalpay_order['pasref'] . '</pasref>';
+ $xml .= '<authcode>' . $globalpay_order['authcode'] . '</authcode>';
+ $xml .= '<sha1hash>' . $hash . '</sha1hash>';
+ $xml .= '</request>';
+
+ $this->logger('Void XML request:\r\n' . print_r(simplexml_load_string($xml), 1));
+
+ $ch = curl_init();
+ curl_setopt($ch, CURLOPT_URL, "https://epage.payandshop.com/epage-remote.cgi");
+ curl_setopt($ch, CURLOPT_POST, 1);
+ curl_setopt($ch, CURLOPT_USERAGENT, "OpenCart " . VERSION);
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
+ curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);
+ curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
+ $response = curl_exec ($ch);
+ curl_close ($ch);
+
+ return simplexml_load_string($response);
+ } else {
+ return false;
+ }
+ }
+
+ public function updateVoidStatus($globalpay_order_id, $status) {
+ $this->db->query("UPDATE `" . DB_PREFIX . "globalpay_order` SET `void_status` = '" . (int)$status . "' WHERE `globalpay_order_id` = '" . (int)$globalpay_order_id . "'");
+ }
+
+ public function capture($order_id, $amount) {
+ $globalpay_order = $this->getOrder($order_id);
+
+ if (!empty($globalpay_order) && $globalpay_order['capture_status'] == 0) {
+ $timestamp = strftime("%Y%m%d%H%M%S");
+ $merchant_id = $this->config->get('payment_globalpay_merchant_id');
+ $secret = $this->config->get('payment_globalpay_secret');
+
+ if ($globalpay_order['settle_type'] == 2) {
+ $this->logger('Capture hash construct: ' . $timestamp . '.' . $merchant_id . '.' . $globalpay_order['order_ref'] . '.' . (int)round($amount*100) . '.' . (string)$globalpay_order['currency_code'] . '.');
+
+ $tmp = $timestamp . '.' . $merchant_id . '.' . $globalpay_order['order_ref'] . '.' . (int)round($amount*100) . '.' . (string)$globalpay_order['currency_code'] . '.';
+ $hash = sha1($tmp);
+ $tmp = $hash . '.' . $secret;
+ $hash = sha1($tmp);
+
+ $settle_type = 'multisettle';
+ $xml_amount = '<amount currency="' . (string)$globalpay_order['currency_code'] . '">' . (int)round($amount*100) . '</amount>';
+ } else {
+ //$this->logger('Capture hash construct: ' . $timestamp . '.' . $merchant_id . '.' . $globalpay_order['order_ref'] . '...');
+ $this->logger('Capture hash construct: ' . $timestamp . '.' . $merchant_id . '.' . $globalpay_order['order_ref'] . '.' . (int)round($amount*100) . '.' . (string)$globalpay_order['currency_code'] . '.');
+
+ $tmp = $timestamp . '.' . $merchant_id . '.' . $globalpay_order['order_ref'] . '.' . (int)round($amount*100) . '.' . (string)$globalpay_order['currency_code'] . '.';
+ $hash = sha1($tmp);
+ $tmp = $hash . '.' . $secret;
+ $hash = sha1($tmp);
+
+ $settle_type = 'settle';
+ $xml_amount = '<amount currency="' . (string)$globalpay_order['currency_code'] . '">' . (int)round($amount*100) . '</amount>';
+ }
+
+ $xml = '';
+ $xml .= '<request type="' . $settle_type . '" timestamp="' . $timestamp . '">';
+ $xml .= '<merchantid>' . $merchant_id . '</merchantid>';
+ $xml .= '<account>' . $globalpay_order['account'] . '</account>';
+ $xml .= '<orderid>' . $globalpay_order['order_ref'] . '</orderid>';
+ $xml .= $xml_amount;
+ $xml .= '<pasref>' . $globalpay_order['pasref'] . '</pasref>';
+ $xml .= '<autosettle flag="1" />';
+ $xml .= '<authcode>' . $globalpay_order['authcode'] . '</authcode>';
+ $xml .= '<sha1hash>' . $hash . '</sha1hash>';
+ $xml .= '</request>';
+
+ $this->logger('Settle XML request:\r\n' . print_r(simplexml_load_string($xml), 1));
+
+ $ch = curl_init();
+ curl_setopt($ch, CURLOPT_URL, "https://epage.payandshop.com/epage-remote.cgi");
+ curl_setopt($ch, CURLOPT_POST, 1);
+ curl_setopt($ch, CURLOPT_USERAGENT, "OpenCart " . VERSION);
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
+ curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);
+ curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
+ $response = curl_exec ($ch);
+ curl_close ($ch);
+
+ return simplexml_load_string($response);
+ } else {
+ return false;
+ }
+ }
+
+ public function updateCaptureStatus($globalpay_order_id, $status) {
+ $this->db->query("UPDATE `" . DB_PREFIX . "globalpay_order` SET `capture_status` = '" . (int)$status . "' WHERE `globalpay_order_id` = '" . (int)$globalpay_order_id . "'");
+ }
+
+ public function updateForRebate($globalpay_order_id, $pas_ref, $order_ref) {
+ $this->db->query("UPDATE `" . DB_PREFIX . "globalpay_order` SET `order_ref_previous` = '_multisettle_" . $this->db->escape($order_ref) . "', `pasref_previous` = '" . $this->db->escape($pas_ref) . "' WHERE `globalpay_order_id` = '" . (int)$globalpay_order_id . "' LIMIT 1");
+ }
+
+ public function rebate($order_id, $amount) {
+ $globalpay_order = $this->getOrder($order_id);
+
+ if (!empty($globalpay_order) && $globalpay_order['rebate_status'] != 1) {
+ $timestamp = strftime("%Y%m%d%H%M%S");
+ $merchant_id = $this->config->get('payment_globalpay_merchant_id');
+ $secret = $this->config->get('payment_globalpay_secret');
+
+ if ($globalpay_order['settle_type'] == 2) {
+ $order_ref = '_multisettle_' . $globalpay_order['order_ref'];
+
+ if (empty($globalpay_order['pasref_previous'])) {
+ $pas_ref = $globalpay_order['pasref'];
+ } else {
+ $pas_ref = $globalpay_order['pasref_previous'];
+ }
+ } else {
+ $order_ref = $globalpay_order['order_ref'];
+ $pas_ref = $globalpay_order['pasref'];
+ }
+
+ $this->logger('Rebate hash construct: ' . $timestamp . '.' . $merchant_id . '.' . $order_ref . '.' . (int)round($amount*100) . '.' . $globalpay_order['currency_code'] . '.');
+
+ $tmp = $timestamp . '.' . $merchant_id . '.' . $order_ref . '.' . (int)round($amount*100) . '.' . $globalpay_order['currency_code'] . '.';
+ $hash = sha1($tmp);
+ $tmp = $hash . '.' . $secret;
+ $hash = sha1($tmp);
+
+ $rebate_hash = sha1($this->config->get('payment_globalpay_rebate_password'));
+
+ $xml = '';
+ $xml .= '<request type="rebate" timestamp="' . $timestamp . '">';
+ $xml .= '<merchantid>' . $merchant_id . '</merchantid>';
+ $xml .= '<account>' . $globalpay_order['account'] . '</account>';
+ $xml .= '<orderid>' . $order_ref . '</orderid>';
+ $xml .= '<pasref>' . $pas_ref . '</pasref>';
+ $xml .= '<authcode>' . $globalpay_order['authcode'] . '</authcode>';
+ $xml .= '<amount currency="' . (string)$globalpay_order['currency_code'] . '">' . (int)round($amount*100) . '</amount>';
+ $xml .= '<refundhash>' . $rebate_hash . '</refundhash>';
+ $xml .= '<sha1hash>' . $hash . '</sha1hash>';
+ $xml .= '</request>';
+
+ $this->logger('Rebate XML request:\r\n' . print_r(simplexml_load_string($xml), 1));
+
+ $ch = curl_init();
+ curl_setopt($ch, CURLOPT_URL, "https://epage.payandshop.com/epage-remote.cgi");
+ curl_setopt($ch, CURLOPT_POST, 1);
+ curl_setopt($ch, CURLOPT_USERAGENT, "OpenCart " . VERSION);
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
+ curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);
+ curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
+ $response = curl_exec ($ch);
+ curl_close ($ch);
+
+ return simplexml_load_string($response);
+ } else {
+ return false;
+ }
+ }
+
+ public function updateRebateStatus($globalpay_order_id, $status) {
+ $this->db->query("UPDATE `" . DB_PREFIX . "globalpay_order` SET `rebate_status` = '" . (int)$status . "' WHERE `globalpay_order_id` = '" . (int)$globalpay_order_id . "'");
+ }
+
+ public function getOrder($order_id) {
+ $this->logger('getOrder - ' . $order_id);
+
+ $qry = $this->db->query("SELECT * FROM `" . DB_PREFIX . "globalpay_order` WHERE `order_id` = '" . (int)$order_id . "' LIMIT 1");
+
+ if ($qry->num_rows) {
+ $order = $qry->row;
+ $order['transactions'] = $this->getTransactions($order['globalpay_order_id']);
+
+ $this->logger(print_r($order, 1));
+
+ return $order;
+ } else {
+ return false;
+ }
+ }
+
+ private function getTransactions($globalpay_order_id) {
+ $qry = $this->db->query("SELECT * FROM `" . DB_PREFIX . "globalpay_order_transaction` WHERE `globalpay_order_id` = '" . (int)$globalpay_order_id . "'");
+
+ if ($qry->num_rows) {
+ return $qry->rows;
+ } else {
+ return false;
+ }
+ }
+
+ public function addTransaction($globalpay_order_id, $type, $total) {
+ $this->db->query("INSERT INTO `" . DB_PREFIX . "globalpay_order_transaction` SET `globalpay_order_id` = '" . (int)$globalpay_order_id . "', `date_added` = now(), `type` = '" . $this->db->escape($type) . "', `amount` = '" . (float)$total . "'");
+ }
+
+ public function logger($message) {
+ if ($this->config->get('payment_globalpay_debug') == 1) {
+ $log = new Log('globalpay.log');
+ $log->write($message);
+ }
+ }
+
+ public function getTotalCaptured($globalpay_order_id) {
+ $query = $this->db->query("SELECT SUM(`amount`) AS `total` FROM `" . DB_PREFIX . "globalpay_order_transaction` WHERE `globalpay_order_id` = '" . (int)$globalpay_order_id . "' AND (`type` = 'payment' OR `type` = 'rebate')");
+
+ return (float)$query->row['total'];
+ }
+
+ public function getTotalRebated($globalpay_order_id) {
+ $query = $this->db->query("SELECT SUM(`amount`) AS `total` FROM `" . DB_PREFIX . "globalpay_order_transaction` WHERE `globalpay_order_id` = '" . (int)$globalpay_order_id . "' AND 'rebate'");
+
+ return (float)$query->row['total'];
+ }
+} \ No newline at end of file
diff --git a/public/admin/model/extension/payment/globalpay_remote.php b/public/admin/model/extension/payment/globalpay_remote.php
new file mode 100644
index 0000000..788e70b
--- /dev/null
+++ b/public/admin/model/extension/payment/globalpay_remote.php
@@ -0,0 +1,260 @@
+<?php
+class ModelExtensionPaymentGlobalpayRemote extends Model {
+ public function install() {
+ $this->db->query("
+ CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "globalpay_remote_order` (
+ `globalpay_remote_order_id` INT(11) NOT NULL AUTO_INCREMENT,
+ `order_id` INT(11) NOT NULL,
+ `order_ref` CHAR(50) NOT NULL,
+ `order_ref_previous` CHAR(50) NOT NULL,
+ `pasref` VARCHAR(50) NOT NULL,
+ `pasref_previous` VARCHAR(50) NOT NULL,
+ `date_added` DATETIME NOT NULL,
+ `date_modified` DATETIME NOT NULL,
+ `capture_status` INT(1) DEFAULT NULL,
+ `void_status` INT(1) DEFAULT NULL,
+ `settle_type` INT(1) DEFAULT NULL,
+ `rebate_status` INT(1) DEFAULT NULL,
+ `currency_code` CHAR(3) NOT NULL,
+ `authcode` VARCHAR(30) NOT NULL,
+ `account` VARCHAR(30) NOT NULL,
+ `total` DECIMAL( 10, 2 ) NOT NULL,
+ PRIMARY KEY (`globalpay_remote_order_id`)
+ ) ENGINE=MyISAM DEFAULT COLLATE=utf8_general_ci;");
+
+ $this->db->query("
+ CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "globalpay_remote_order_transaction` (
+ `globalpay_remote_order_transaction_id` INT(11) NOT NULL AUTO_INCREMENT,
+ `globalpay_remote_order_id` INT(11) NOT NULL,
+ `date_added` DATETIME NOT NULL,
+ `type` ENUM('auth', 'payment', 'rebate', 'void') DEFAULT NULL,
+ `amount` DECIMAL( 10, 2 ) NOT NULL,
+ PRIMARY KEY (`globalpay_remote_order_transaction_id`)
+ ) ENGINE=MyISAM DEFAULT COLLATE=utf8_general_ci;");
+ }
+
+ public function void($order_id) {
+ $globalpay_order = $this->getOrder($order_id);
+
+ if (!empty($globalpay_order)) {
+ $timestamp = strftime("%Y%m%d%H%M%S");
+ $merchant_id = $this->config->get('payment_globalpay_remote_merchant_id');
+ $secret = $this->config->get('payment_globalpay_remote_secret');
+
+ $this->logger('Void hash construct: ' . $timestamp . '.' . $merchant_id . '.' . $globalpay_order['order_ref'] . '...');
+
+ $tmp = $timestamp . '.' . $merchant_id . '.' . $globalpay_order['order_ref'] . '...';
+ $hash = sha1($tmp);
+ $tmp = $hash . '.' . $secret;
+ $hash = sha1($tmp);
+
+ $xml = '';
+ $xml .= '<request type="void" timestamp="' . $timestamp . '">';
+ $xml .= '<merchantid>' . $merchant_id . '</merchantid>';
+ $xml .= '<account>' . $globalpay_order['account'] . '</account>';
+ $xml .= '<orderid>' . $globalpay_order['order_ref'] . '</orderid>';
+ $xml .= '<pasref>' . $globalpay_order['pasref'] . '</pasref>';
+ $xml .= '<authcode>' . $globalpay_order['authcode'] . '</authcode>';
+ $xml .= '<sha1hash>' . $hash . '</sha1hash>';
+ $xml .= '</request>';
+
+ $this->logger('Void XML request:\r\n' . print_r(simplexml_load_string($xml), 1));
+
+ $ch = curl_init();
+ curl_setopt($ch, CURLOPT_URL, "https://epage.payandshop.com/epage-remote.cgi");
+ curl_setopt($ch, CURLOPT_POST, 1);
+ curl_setopt($ch, CURLOPT_USERAGENT, "OpenCart " . VERSION);
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
+ curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);
+ curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
+ $response = curl_exec ($ch);
+ curl_close ($ch);
+
+ return simplexml_load_string($response);
+ } else {
+ return false;
+ }
+ }
+
+ public function updateVoidStatus($globalpay_remote_order_id, $status) {
+ $this->db->query("UPDATE `" . DB_PREFIX . "globalpay_remote_order` SET `void_status` = '" . (int)$status . "' WHERE `globalpay_remote_order_id` = '" . (int)$globalpay_remote_order_id . "'");
+ }
+
+ public function capture($order_id, $amount) {
+ $globalpay_order = $this->getOrder($order_id);
+
+ if (!empty($globalpay_order) && $globalpay_order['capture_status'] == 0) {
+ $timestamp = strftime("%Y%m%d%H%M%S");
+ $merchant_id = $this->config->get('payment_globalpay_remote_merchant_id');
+ $secret = $this->config->get('payment_globalpay_remote_secret');
+
+ if ($globalpay_order['settle_type'] == 2) {
+ $this->logger('Capture hash construct: ' . $timestamp . '.' . $merchant_id . '.' . $globalpay_order['order_ref'] . '.' . (int)round($amount*100) . '.' . (string)$globalpay_order['currency_code'] . '.');
+
+ $tmp = $timestamp . '.' . $merchant_id . '.' . $globalpay_order['order_ref'] . '.' . (int)round($amount*100) . '.' . (string)$globalpay_order['currency_code'] . '.';
+ $hash = sha1($tmp);
+ $tmp = $hash . '.' . $secret;
+ $hash = sha1($tmp);
+
+ $settle_type = 'multisettle';
+ $xml_amount = '<amount currency="' . (string)$globalpay_order['currency_code'] . '">' . (int)round($amount*100) . '</amount>';
+ } else {
+ //$this->logger('Capture hash construct: ' . $timestamp . '.' . $merchant_id . '.' . $globalpay_order['order_ref'] . '...');
+ $this->logger('Capture hash construct: ' . $timestamp . '.' . $merchant_id . '.' . $globalpay_order['order_ref'] . '.' . (int)round($amount*100) . '.' . (string)$globalpay_order['currency_code'] . '.');
+
+ $tmp = $timestamp . '.' . $merchant_id . '.' . $globalpay_order['order_ref'] . '.' . (int)round($amount*100) . '.' . (string)$globalpay_order['currency_code'] . '.';
+ $hash = sha1($tmp);
+ $tmp = $hash . '.' . $secret;
+ $hash = sha1($tmp);
+
+ $settle_type = 'settle';
+ $xml_amount = '<amount currency="' . (string)$globalpay_order['currency_code'] . '">' . (int)round($amount*100) . '</amount>';
+ }
+
+ $xml = '';
+ $xml .= '<request type="' . $settle_type . '" timestamp="' . $timestamp . '">';
+ $xml .= '<merchantid>' . $merchant_id . '</merchantid>';
+ $xml .= '<account>' . $globalpay_order['account'] . '</account>';
+ $xml .= '<orderid>' . $globalpay_order['order_ref'] . '</orderid>';
+ $xml .= $xml_amount;
+ $xml .= '<pasref>' . $globalpay_order['pasref'] . '</pasref>';
+ $xml .= '<authcode>' . $globalpay_order['authcode'] . '</authcode>';
+ $xml .= '<sha1hash>' . $hash . '</sha1hash>';
+ $xml .= '</request>';
+
+ $this->logger('Settle XML request:\r\n' . print_r(simplexml_load_string($xml), 1));
+
+ $ch = curl_init();
+ curl_setopt($ch, CURLOPT_URL, "https://epage.payandshop.com/epage-remote.cgi");
+ curl_setopt($ch, CURLOPT_POST, 1);
+ curl_setopt($ch, CURLOPT_USERAGENT, "OpenCart " . VERSION);
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
+ curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);
+ curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
+ $response = curl_exec ($ch);
+ curl_close ($ch);
+
+ return simplexml_load_string($response);
+ } else {
+ return false;
+ }
+ }
+
+ public function updateCaptureStatus($globalpay_remote_order_id, $status) {
+ $this->db->query("UPDATE `" . DB_PREFIX . "globalpay_remote_order` SET `capture_status` = '" . (int)$status . "' WHERE `globalpay_remote_order_id` = '" . (int)$globalpay_remote_order_id . "'");
+ }
+
+ public function updateForRebate($globalpay_remote_order_id, $pas_ref, $order_ref) {
+ $this->db->query("UPDATE `" . DB_PREFIX . "globalpay_remote_order` SET `order_ref_previous` = '_multisettle_" . $this->db->escape($order_ref) . "', `pasref_previous` = '" . $this->db->escape($pas_ref) . "' WHERE `globalpay_remote_order_id` = '" . (int)$globalpay_remote_order_id . "' LIMIT 1");
+ }
+
+ public function rebate($order_id, $amount) {
+ $globalpay_order = $this->getOrder($order_id);
+
+ if (!empty($globalpay_order) && $globalpay_order['rebate_status'] != 1) {
+ $timestamp = strftime("%Y%m%d%H%M%S");
+ $merchant_id = $this->config->get('payment_globalpay_remote_merchant_id');
+ $secret = $this->config->get('payment_globalpay_remote_secret');
+
+ if ($globalpay_order['settle_type'] == 2) {
+ $order_ref = '_multisettle_' . $globalpay_order['order_ref'];
+
+ if (empty($globalpay_order['pasref_previous'])) {
+ $pas_ref = $globalpay_order['pasref'];
+ } else {
+ $pas_ref = $globalpay_order['pasref_previous'];
+ }
+ } else {
+ $order_ref = $globalpay_order['order_ref'];
+ $pas_ref = $globalpay_order['pasref'];
+ }
+
+ $this->logger('Rebate hash construct: ' . $timestamp . '.' . $merchant_id . '.' . $order_ref . '.' . (int)round($amount*100) . '.' . $globalpay_order['currency_code'] . '.');
+
+ $tmp = $timestamp . '.' . $merchant_id . '.' . $order_ref . '.' . (int)round($amount*100) . '.' . $globalpay_order['currency_code'] . '.';
+ $hash = sha1($tmp);
+ $tmp = $hash . '.' . $secret;
+ $hash = sha1($tmp);
+
+ $rebatehash = sha1($this->config->get('payment_globalpay_remote_rebate_password'));
+
+ $xml = '';
+ $xml .= '<request type="rebate" timestamp="' . $timestamp . '">';
+ $xml .= '<merchantid>' . $merchant_id . '</merchantid>';
+ $xml .= '<account>' . $globalpay_order['account'] . '</account>';
+ $xml .= '<orderid>' . $order_ref . '</orderid>';
+ $xml .= '<pasref>' . $pas_ref . '</pasref>';
+ $xml .= '<authcode>' . $globalpay_order['authcode'] . '</authcode>';
+ $xml .= '<amount currency="' . (string)$globalpay_order['currency_code'] . '">' . (int)round($amount*100) . '</amount>';
+ $xml .= '<refundhash>' . $rebatehash . '</refundhash>';
+ $xml .= '<sha1hash>' . $hash . '</sha1hash>';
+ $xml .= '</request>';
+
+ $this->logger('Rebate XML request:\r\n' . print_r(simplexml_load_string($xml), 1));
+
+ $ch = curl_init();
+ curl_setopt($ch, CURLOPT_URL, "https://epage.payandshop.com/epage-remote.cgi");
+ curl_setopt($ch, CURLOPT_POST, 1);
+ curl_setopt($ch, CURLOPT_USERAGENT, "OpenCart " . VERSION);
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
+ curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);
+ curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
+ $response = curl_exec ($ch);
+ curl_close ($ch);
+
+ return simplexml_load_string($response);
+ } else {
+ return false;
+ }
+ }
+
+ public function updateRebateStatus($globalpay_remote_order_id, $status) {
+ $this->db->query("UPDATE `" . DB_PREFIX . "globalpay_remote_order` SET `rebate_status` = '" . (int)$status . "' WHERE `globalpay_remote_order_id` = '" . (int)$globalpay_remote_order_id . "'");
+ }
+
+ public function getOrder($order_id) {
+ $qry = $this->db->query("SELECT * FROM `" . DB_PREFIX . "globalpay_remote_order` WHERE `order_id` = '" . (int)$order_id . "' LIMIT 1");
+
+ if ($qry->num_rows) {
+ $order = $qry->row;
+ $order['transactions'] = $this->getTransactions($order['globalpay_remote_order_id']);
+
+ return $order;
+ } else {
+ return false;
+ }
+ }
+
+ private function getTransactions($globalpay_remote_order_id) {
+ $qry = $this->db->query("SELECT * FROM `" . DB_PREFIX . "globalpay_remote_order_transaction` WHERE `globalpay_remote_order_id` = '" . (int)$globalpay_remote_order_id . "'");
+
+ if ($qry->num_rows) {
+ return $qry->rows;
+ } else {
+ return false;
+ }
+ }
+
+ public function addTransaction($globalpay_remote_order_id, $type, $total) {
+ $this->db->query("INSERT INTO `" . DB_PREFIX . "globalpay_remote_order_transaction` SET `globalpay_remote_order_id` = '" . (int)$globalpay_remote_order_id . "', `date_added` = now(), `type` = '" . $this->db->escape($type) . "', `amount` = '" . (float)$total . "'");
+ }
+
+ public function logger($message) {
+ if ($this->config->get('payment_globalpay_remote_debug') == 1) {
+ $log = new Log('globalpay_remote.log');
+ $log->write($message);
+ }
+ }
+
+ public function getTotalCaptured($globalpay_order_id) {
+ $query = $this->db->query("SELECT SUM(`amount`) AS `total` FROM `" . DB_PREFIX . "globalpay_remote_order_transaction` WHERE `globalpay_remote_order_id` = '" . (int)$globalpay_order_id . "' AND (`type` = 'payment' OR `type` = 'rebate')");
+
+ return (float)$query->row['total'];
+ }
+
+ public function getTotalRebated($globalpay_order_id) {
+ $query = $this->db->query("SELECT SUM(`amount`) AS `total` FROM `" . DB_PREFIX . "globalpay_remote_order_transaction` WHERE `globalpay_remote_order_id` = '" . (int)$globalpay_order_id . "' AND 'rebate'");
+
+ return (double)$query->row['total'];
+ }
+} \ No newline at end of file
diff --git a/public/admin/model/extension/payment/klarna_checkout.php b/public/admin/model/extension/payment/klarna_checkout.php
new file mode 100644
index 0000000..d9e9cbc
--- /dev/null
+++ b/public/admin/model/extension/payment/klarna_checkout.php
@@ -0,0 +1,226 @@
+<?php
+use Klarna\Rest\Transport\Connector as KCConnector;
+use Klarna\Rest\Transport\ConnectorInterface as KCConnectorInterface;
+use Klarna\Rest\OrderManagement\Order as KCOrder;
+
+class ModelExtensionPaymentKlarnaCheckout extends Model {
+ public function connector($merchant_id, $secret, $url) {
+ try {
+ $connector = KCConnector::create(
+ $merchant_id,
+ $secret,
+ $url
+ );
+
+ return $connector;
+ } catch (\Exception $e) {
+ $this->log($e->getMessage());
+
+ return false;
+ }
+ }
+
+ public function omRetrieve(KCConnector $connector, $order_id) {
+ try {
+ $order = new KCOrder($connector, $order_id);
+
+ return $order->fetch();
+ } catch (\Exception $e) {
+ $this->log($e->getMessage());
+
+ return false;
+ }
+ }
+
+ public function omCancel(KCConnector $connector, $order_id) {
+ try {
+ $order = new KCOrder($connector, $order_id);
+
+ return $order->cancel();
+ } catch (\Exception $e) {
+ $this->log($e->getMessage());
+
+ return false;
+ }
+ }
+
+ public function omCapture(KCConnector $connector, $order_id, $data) {
+ try {
+ $order = new KCOrder($connector, $order_id);
+
+ return $order->createCapture($data);
+ } catch (\Exception $e) {
+ $this->log($e->getMessage());
+
+ return false;
+ }
+ }
+
+ public function omRefund(KCConnector $connector, $order_id, $data) {
+ try {
+ $order = new KCOrder($connector, $order_id);
+
+ return $order->refund($data);
+ } catch (\Exception $e) {
+ $this->log($e->getMessage());
+
+ return false;
+ }
+ }
+
+ public function omExtendAuthorizationTime(KCConnector $connector, $order_id) {
+ try {
+ $order = new KCOrder($connector, $order_id);
+
+ return $order->extendAuthorizationTime();
+ } catch (\Exception $e) {
+ $this->log($e->getMessage());
+
+ return false;
+ }
+ }
+
+ public function omUpdateMerchantReference(KCConnector $connector, $order_id, $data) {
+ try {
+ $order = new KCOrder($connector, $order_id);
+
+ return $order->updateMerchantReferences($data);
+ } catch (\Exception $e) {
+ $this->log($e->getMessage());
+
+ return false;
+ }
+ }
+
+ public function omUpdateAddress(KCConnector $connector, $order_id, $data) {
+ try {
+ $order = new KCOrder($connector, $order_id);
+
+ return $order->updateCustomerDetails($data);
+ } catch (\Exception $e) {
+ $this->log($e->getMessage());
+
+ return false;
+ }
+ }
+
+ public function omReleaseAuthorization(KCConnector $connector, $order_id) {
+ try {
+ $order = new KCOrder($connector, $order_id);
+
+ return $order->releaseRemainingAuthorization();
+ } catch (\Exception $e) {
+ $this->log($e->getMessage());
+
+ return false;
+ }
+ }
+
+ public function omShippingInfo(KCConnector $connector, $order_id, $capture_id, $data) {
+ try {
+ $order = new KCOrder($connector, $order_id);
+
+ $capture = $order->fetchCapture($capture_id);
+ return $capture->addShippingInfo($data);
+ } catch (\Exception $e) {
+ $this->log($e->getMessage());
+
+ return false;
+ }
+ }
+
+ public function omCustomerDetails(KCConnector $connector, $order_id, $capture_id, $data) {
+ try {
+ $order = new KCOrder($connector, $order_id);
+
+ $capture = $order->fetchCapture($capture_id);
+ return $capture->updateCustomerDetails($data);
+ } catch (\Exception $e) {
+ $this->log($e->getMessage());
+
+ return false;
+ }
+ }
+
+ public function omTriggerSendOut(KCConnector $connector, $order_id, $capture_id) {
+ try {
+ $order = new KCOrder($connector, $order_id);
+
+ $capture = $order->fetchCapture($capture_id);
+ return $capture->triggerSendout();
+ } catch (\Exception $e) {
+ $this->log($e->getMessage());
+
+ return false;
+ }
+ }
+
+ public function getConnector($accounts, $currency) {
+ $klarna_account = false;
+ $connector = false;
+
+ if ($accounts && $currency) {
+ foreach ($accounts as $account) {
+ if ($account['currency'] == $currency) {
+ if ($account['environment'] == 'test') {
+ if ($account['api'] == 'NA') {
+ $base_url = KCConnectorInterface::NA_TEST_BASE_URL;
+ } elseif ($account['api'] == 'EU') {
+ $base_url = KCConnectorInterface::EU_TEST_BASE_URL;
+ }
+ } elseif ($account['environment'] == 'live') {
+ if ($account['api'] == 'NA') {
+ $base_url = KCConnectorInterface::NA_BASE_URL;
+ } elseif ($account['api'] == 'EU') {
+ $base_url = KCConnectorInterface::EU_BASE_URL;
+ }
+ }
+
+ $klarna_account = $account;
+ $connector = $this->connector(
+ $account['merchant_id'],
+ $account['secret'],
+ $base_url
+ );
+
+ break;
+ }
+ }
+ }
+
+ return array($klarna_account, $connector);
+ }
+
+ public function getOrder($order_id) {
+ return $this->db->query("SELECT * FROM `" . DB_PREFIX . "klarna_checkout_order` WHERE `order_id` = '" . (int)$order_id . "' LIMIT 1")->row;
+ }
+
+ public function checkForPaymentTaxes() {
+ $query = $this->db->query("SELECT COUNT(*) AS `total` FROM " . DB_PREFIX . "product p LEFT JOIN " . DB_PREFIX . "tax_rule tr ON (`tr`.`tax_class_id` = `p`.`tax_class_id`) WHERE `tr`.`based` = 'payment'");
+
+ return $query->row['total'];
+ }
+
+ public function install() {
+ $this->db->query("
+ CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "klarna_checkout_order` (
+ `klarna_checkout_order_id` INT(11) NOT NULL AUTO_INCREMENT,
+ `order_id` INT(11) NOT NULL,
+ `order_ref` VARCHAR(255) NOT NULL,
+ `data` text NOT NULL,
+ PRIMARY KEY (`klarna_checkout_order_id`)
+ ) ENGINE=MyISAM DEFAULT COLLATE=utf8_general_ci;");
+ }
+
+ public function uninstall() {
+ $this->db->query("DROP TABLE IF EXISTS `" . DB_PREFIX . "klarna_checkout_order`;");
+ }
+
+ public function log($data) {
+ if ($this->config->get('klarna_checkout_debug')) {
+ $backtrace = debug_backtrace();
+ $log = new Log('klarna_checkout.log');
+ $log->write('(' . $backtrace[1]['class'] . '::' . $backtrace[1]['function'] . ') - ' . print_r($data, true));
+ }
+ }
+} \ No newline at end of file
diff --git a/public/admin/model/extension/payment/laybuy.php b/public/admin/model/extension/payment/laybuy.php
new file mode 100644
index 0000000..f9689fd
--- /dev/null
+++ b/public/admin/model/extension/payment/laybuy.php
@@ -0,0 +1,362 @@
+<?php
+class ModelExtensionPaymentLaybuy extends Model {
+ public function addRevisedTransaction($data = array()) {
+ $query = $this->db->query("INSERT INTO `" . DB_PREFIX . "laybuy_revise_request` SET `laybuy_transaction_id` = '" . (int)$data['transaction_id'] . "', `type` = '" . $this->db->escape($data['type']) . "', `order_id` = '" . (int)$data['order_id'] . "', `firstname` = '" . $this->db->escape($data['firstname']) . "', `lastname` = '" . $this->db->escape($data['lastname']) . "', `address` = '" . $this->db->escape($data['address']) . "', `suburb` = '" . $this->db->escape($data['suburb']) . "', `state` = '" . $this->db->escape($data['state']) . "', `country` = '" . $this->db->escape($data['country']) . "', `postcode` = '" . $this->db->escape($data['postcode']) . "', `email` = '" . $this->db->escape($data['email']) . "', `amount` = '" . (float)$data['amount'] . "', `currency` = '" . $this->db->escape($data['currency']) . "', `downpayment` = '" . $this->db->escape($data['downpayment']) . "', `months` = '" . (int)$data['months'] . "', `downpayment_amount` = '" . (float)$data['downpayment_amount'] . "', `payment_amounts` = '" . (float)$data['payment_amounts'] . "', `first_payment_due` = '" . $this->db->escape($data['first_payment_due']) . "', `last_payment_due` = '" . $this->db->escape($data['last_payment_due']) . "', `store_id` = '" . (int)$data['store_id'] . "', `status` = '" . (int)$data['status'] . "', `report` = '" . $this->db->escape($data['report']) . "', `transaction` = '" . (int)$data['transaction'] . "', `paypal_profile_id` = '" . $this->db->escape($data['paypal_profile_id']) . "', `laybuy_ref_no` = '" . (int)$data['laybuy_ref_no'] . "', `payment_type` = '" . (int)$data['payment_type'] . "', `date_added` = NOW()");
+
+ return $this->db->getLastId();
+ }
+
+ public function getCustomerIdByOrderId($order_id) {
+ $query = $this->db->query("SELECT `customer_id` FROM `" . DB_PREFIX . "order` WHERE `order_id` = '" . (int)$order_id . "'");
+
+ if ($query->num_rows) {
+ return $query->row['customer_id'];
+ } else {
+ return 0;
+ }
+ }
+
+ public function getInitialPayments() {
+ $minimum = $this->config->get('payment_laybuy_min_deposit') ? $this->config->get('payment_laybuy_min_deposit') : 20;
+
+ $maximum = $this->config->get('payment_laybuy_max_deposit') ? $this->config->get('payment_laybuy_max_deposit') : 50;
+
+ $initial_payments = array();
+
+ for ($i = $minimum; $i <= $maximum; $i += 10) {
+ $initial_payments[] = $i;
+ }
+
+ return $initial_payments;
+ }
+
+ public function getMonths() {
+ $this->load->language('extension/payment/laybuy');
+
+ $max_months = $this->config->get('payment_laybuy_max_months');
+
+ if (!$max_months) {
+ $max_months = 3;
+ }
+
+ if ($max_months < 1) {
+ $max_months = 1;
+ }
+
+ $months = array();
+
+ for ($i = 1; $i <= $max_months; $i++) {
+ $months[] = array(
+ 'value' => $i,
+ 'label' => $i . ' ' . (($i > 1) ? $this->language->get('text_months') : $this->language->get('text_month'))
+ );
+ }
+
+ return $months;
+ }
+
+ public function getPayPalProfileIds() {
+ $query = $this->db->query("SELECT `paypal_profile_id` FROM `" . DB_PREFIX . "laybuy_transaction` WHERE `status` = '1'");
+
+ return $query->rows;
+ }
+
+ public function getRevisedTransaction($id) {
+ $query = $this->db->query("SELECT * FROM `" . DB_PREFIX . "laybuy_revise_request` WHERE `laybuy_revise_request_id` = '" . (int)$id . "'");
+
+ return $query->row;
+ }
+
+ public function getRemainingAmount($amount, $downpayment_amount, $payment_amounts, $transaction = 2) {
+ return $amount - ($downpayment_amount + (((int)$transaction - 2) * $payment_amounts));
+ }
+
+ public function getRevisedTransactions($id) {
+ $query = $this->db->query("SELECT * FROM `" . DB_PREFIX . "laybuy_revise_request` WHERE `laybuy_revise_request_id` = '" . (int)$id . "'");
+
+ return $query->rows;
+ }
+
+ public function getStatusLabel($id) {
+ $statuses = $this->getTransactionStatuses();
+
+ foreach ($statuses as $status) {
+ if ($status['status_id'] == $id && $status['status_name'] != '') {
+ return $status['status_name'];
+
+ break;
+ }
+ }
+
+ return $id;
+ }
+
+ public function getTransaction($id) {
+ $query = $this->db->query("SELECT * FROM `" . DB_PREFIX . "laybuy_transaction` WHERE `laybuy_transaction_id` = '" . (int)$id . "'");
+
+ return $query->row;
+ }
+
+ public function getTransactions($data = array()) {
+ $sql = "SELECT *, CONCAT(firstname, ' ', lastname) AS `customer` FROM `" . DB_PREFIX . "laybuy_transaction` `lt` WHERE 1 = 1";
+
+ $implode = array();
+
+ if (!empty($data['filter_order_id'])) {
+ $implode[] = "`lt`.`order_id` = '" . (int)$data['filter_order_id'] . "'";
+ }
+
+ if (!empty($data['filter_customer'])) {
+ $implode[] = "CONCAT(firstname, ' ', lastname) LIKE '%" . $this->db->escape($data['filter_customer']) . "%'";
+ }
+
+ if (!empty($data['filter_dp_percent'])) {
+ $implode[] = "`lt`.`downpayment` = '" . (int)$data['filter_dp_percent'] . "'";
+ }
+
+ if (!empty($data['filter_months'])) {
+ $implode[] = "`lt`.`months` = '" . (int)$data['filter_months'] . "'";
+ }
+
+ if (!empty($data['filter_status'])) {
+ $implode[] = "`lt`.`status` = '" . (int)$data['filter_status'] . "'";
+ }
+
+ if (!empty($data['filter_date_added'])) {
+ $implode[] = "DATE(`lt`.`date_added`) = DATE('" . $this->db->escape($data['filter_date_added']) . "')";
+ }
+
+ if ($implode) {
+ $sql .= " AND " . implode(" AND ", $implode);
+ }
+
+ $sort_data = array(
+ 'lt.order_id',
+ 'customer',
+ 'lt.amount',
+ 'lt.downpayment',
+ 'lt.months',
+ 'lt.downpayment_amount',
+ 'lt.first_payment_due',
+ 'lt.last_payment_due',
+ 'lt.status',
+ 'lt.date_added'
+ );
+
+ if (isset($data['sort']) && in_array($data['sort'], $sort_data)) {
+ $sql .= " ORDER BY " . $data['sort'];
+ } else {
+ $sql .= " ORDER BY order_id";
+ }
+
+ if (isset($data['order']) && ($data['order'] == 'DESC')) {
+ $sql .= " DESC";
+ } else {
+ $sql .= " ASC";
+ }
+
+ if (isset($data['sort']) && $data['sort'] != 'lt.date_added') {
+ $sql .= ", lt.date_added DESC";
+ }
+
+ 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'];
+ }
+
+ $query = $this->db->query($sql);
+
+ return $query->rows;
+ }
+
+ public function getTotalTransactions($data = array()) {
+ $sql = "SELECT COUNT(*) AS `total` FROM `" . DB_PREFIX . "laybuy_transaction` `lt` WHERE 1 = 1";
+
+ $implode = array();
+
+ if (!empty($data['filter_order_id'])) {
+ $implode[] = "`lt`.`order_id` = '" . (int)$data['filter_order_id'] . "'";
+ }
+
+ if (!empty($data['filter_customer'])) {
+ $implode[] = "CONCAT(firstname, ' ', lastname) LIKE '%" . $this->db->escape($data['filter_customer']) . "%'";
+ }
+
+ if (!empty($data['filter_dp_percent'])) {
+ $implode[] = "`lt`.`downpayment` = '" . (int)$data['filter_dp_percent'] . "'";
+ }
+
+ if (!empty($data['filter_months'])) {
+ $implode[] = "`lt`.`months` = '" . (int)$data['filter_months'] . "'";
+ }
+
+ if (!empty($data['filter_status'])) {
+ $implode[] = "`lt`.`status` = '" . (int)$data['filter_status'] . "'";
+ }
+
+ if (!empty($data['filter_date_added'])) {
+ $implode[] = "DATE(`lt`.`date_added`) = DATE('" . $this->db->escape($data['filter_date_added']) . "')";
+ }
+
+ if ($implode) {
+ $sql .= " AND " . implode(" AND ", $implode);
+ }
+
+ $query = $this->db->query($sql);
+
+ return $query->row['total'];
+ }
+
+ public function getTransactionByLayBuyRefId($laybuy_ref_id) {
+ $query = $this->db->query("SELECT * FROM `" . DB_PREFIX . "laybuy_transaction` WHERE `laybuy_ref_no` = '" . (int)$laybuy_ref_id . "'");
+
+ return $query->row;
+ }
+
+ public function getTransactionByOrderId($order_id) {
+ $query = $this->db->query("SELECT * FROM `" . DB_PREFIX . "laybuy_transaction` WHERE `order_id` = '" . (int)$order_id . "' ORDER BY `laybuy_ref_no` DESC LIMIT 1");
+
+ return $query->row;
+ }
+
+ public function getTransactionStatuses() {
+ $this->load->language('extension/payment/laybuy');
+
+ $transaction_statuses = array(
+ array(
+ 'status_id' => 1,
+ 'status_name' => $this->language->get('text_status_1')
+ ),
+ array(
+ 'status_id' => 5,
+ 'status_name' => $this->language->get('text_status_5')
+ ),
+ array(
+ 'status_id' => 7,
+ 'status_name' => $this->language->get('text_status_7')
+ ),
+ array(
+ 'status_id' => 50,
+ 'status_name' => $this->language->get('text_status_50')
+ ),
+ array(
+ 'status_id' => 51,
+ 'status_name' => $this->language->get('text_status_51')
+ )
+ );
+
+ return $transaction_statuses;
+ }
+
+ public function install() {
+ $this->db->query("CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "laybuy_transaction` (
+ `laybuy_transaction_id` int(11) NOT NULL AUTO_INCREMENT,
+ `order_id` int(11) NOT NULL DEFAULT '0',
+ `firstname` varchar(32) NOT NULL DEFAULT '',
+ `lastname` varchar(32) NOT NULL DEFAULT '',
+ `address` text,
+ `suburb` varchar(128) NOT NULL DEFAULT '',
+ `state` varchar(128) NOT NULL DEFAULT '',
+ `country` varchar(32) NOT NULL DEFAULT '',
+ `postcode` varchar(10) NOT NULL DEFAULT '',
+ `email` varchar(96) NOT NULL DEFAULT '',
+ `amount` double NOT NULL,
+ `currency` varchar(5) NOT NULL,
+ `downpayment` double NOT NULL,
+ `months` int(11) NOT NULL,
+ `downpayment_amount` double NOT NULL,
+ `payment_amounts` double NOT NULL,
+ `first_payment_due` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
+ `last_payment_due` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
+ `store_id` int(11) NOT NULL DEFAULT '0',
+ `status` int(11) NOT NULL DEFAULT '1',
+ `report` text,
+ `transaction` int(11) NOT NULL DEFAULT '2',
+ `paypal_profile_id` varchar(250) NOT NULL DEFAULT '',
+ `laybuy_ref_no` int(11) NOT NULL DEFAULT '0',
+ `date_added` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
+ PRIMARY KEY (`laybuy_transaction_id`)
+ ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci");
+
+ $this->db->query("CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "laybuy_revise_request` (
+ `laybuy_revise_request_id` int(11) NOT NULL AUTO_INCREMENT,
+ `laybuy_transaction_id` int(11) DEFAULT '0',
+ `type` varchar(250) NOT NULL DEFAULT '',
+ `order_id` int(11) NOT NULL DEFAULT '0',
+ `firstname` varchar(32) NOT NULL DEFAULT '',
+ `lastname` varchar(32) NOT NULL DEFAULT '',
+ `address` text,
+ `suburb` varchar(128) NOT NULL DEFAULT '',
+ `state` varchar(128) NOT NULL DEFAULT '',
+ `country` varchar(32) NOT NULL DEFAULT '',
+ `postcode` varchar(10) NOT NULL DEFAULT '',
+ `email` varchar(96) NOT NULL DEFAULT '',
+ `amount` double NOT NULL,
+ `currency` varchar(5) NOT NULL,
+ `downpayment` double NOT NULL,
+ `months` int(11) NOT NULL,
+ `downpayment_amount` double NOT NULL,
+ `payment_amounts` double NOT NULL,
+ `first_payment_due` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
+ `last_payment_due` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
+ `store_id` int(11) NOT NULL DEFAULT '0',
+ `status` int(11) NOT NULL DEFAULT '1',
+ `report` text,
+ `transaction` int(11) NOT NULL DEFAULT '2',
+ `paypal_profile_id` varchar(250) NOT NULL DEFAULT '',
+ `laybuy_ref_no` int(11) NOT NULL DEFAULT '0',
+ `payment_type` tinyint(1) NOT NULL DEFAULT '1',
+ `date_added` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
+ PRIMARY KEY (`laybuy_revise_request_id`)
+ ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci");
+
+ $this->load->model('setting/event');
+
+ $this->model_setting_event->addEvent('laybuy', 'catalog/model/checkout/order/deleteOrder/after', 'extension/payment/laybuy/deleteOrder');
+ }
+
+ public function log($data, $step = 6) {
+ if ($this->config->get('payment_laybuy_logging')) {
+ $backtrace = debug_backtrace();
+
+ $log = new Log('laybuy.log');
+
+ $log->write('(' . $backtrace[$step]['class'] . '::' . $backtrace[$step]['function'] . ') - ' . $data);
+ }
+ }
+
+ public function uninstall() {
+ $this->db->query("DROP TABLE IF EXISTS `" . DB_PREFIX . "laybuy_transaction`");
+
+ $this->db->query("DROP TABLE IF EXISTS `" . DB_PREFIX . "laybuy_revise_request`");
+
+ $this->load->model('setting/event');
+
+ $this->model_setting_event->deleteEventByCode('laybuy');
+ }
+
+ public function updateOrderStatus($order_id, $order_status_id, $comment) {
+ $this->db->query("UPDATE `" . DB_PREFIX . "order` SET `order_status_id` = '" . (int)$order_status_id . "', `date_modified` = NOW() WHERE `order_id` = '" . (int)$order_id . "'");
+
+ $this->db->query("INSERT INTO `" . DB_PREFIX . "order_history` SET `order_id` = '" . (int)$order_id . "', `order_status_id` = '" . (int)$order_status_id . "', `notify` = '0', `comment` = '" . $this->db->escape($comment) . "', `date_added` = NOW()");
+ }
+
+ public function updateRevisedTransaction($id, $data = array()) {
+ $this->db->query("UPDATE `" . DB_PREFIX . "laybuy_revise_request` SET `laybuy_transaction_id` = '" . (int)$data['transaction_id'] . "', `type` = '" . $this->db->escape($data['type']) . "', `order_id` = '" . (int)$data['order_id'] . "', `firstname` = '" . $this->db->escape($data['firstname']) . "', `lastname` = '" . $this->db->escape($data['lastname']) . "', `address` = '" . $this->db->escape($data['address']) . "', `suburb` = '" . $this->db->escape($data['suburb']) . "', `state` = '" . $this->db->escape($data['state']) . "', `country` = '" . $this->db->escape($data['country']) . "', `postcode` = '" . $this->db->escape($data['postcode']) . "', `email` = '" . $this->db->escape($data['email']) . "', `amount` = '" . (float)$data['amount'] . "', `currency` = '" . $this->db->escape($data['currency']) . "', `downpayment` = '" . $this->db->escape($data['downpayment']) . "', `months` = '" . (int)$data['months'] . "', `downpayment_amount` = '" . (float)$data['downpayment_amount'] . "', `payment_amounts` = '" . (float)$data['payment_amounts'] . "', `first_payment_due` = '" . $this->db->escape($data['first_payment_due']) . "', `last_payment_due` = '" . $this->db->escape($data['last_payment_due']) . "', `store_id` = '" . (int)$data['store_id'] . "', `status` = '" . (int)$data['status'] . "', `report` = '" . $this->db->escape($data['report']) . "', `transaction` = '" . (int)$data['transaction'] . "', `paypal_profile_id` = '" . $this->db->escape($data['paypal_profile_id']) . "', `laybuy_ref_no` = '" . (int)$data['laybuy_ref_no'] . "', `payment_type` = '" . (int)$data['payment_type'] . "', `date_added` = NOW() WHERE `laybuy_revise_request_id` = '" . (int)$id . "'");
+ }
+
+ public function updateTransaction($id, $status, $report, $transaction) {
+ $this->db->query("UPDATE `" . DB_PREFIX . "laybuy_transaction` SET `status` = '" . (int)$status . "', `report` = '" . $this->db->escape($report) . "', `transaction` = '" . (int)$transaction . "' WHERE `laybuy_transaction_id` = '" . (int)$id . "'");
+ }
+
+ public function updateTransactionStatus($id, $status) {
+ $this->db->query("UPDATE `" . DB_PREFIX . "laybuy_transaction` SET `status` = '" . (int)$status . "' WHERE `laybuy_transaction_id` = '" . (int)$id . "'");
+ }
+} \ No newline at end of file
diff --git a/public/admin/model/extension/payment/pilibaba.php b/public/admin/model/extension/payment/pilibaba.php
new file mode 100644
index 0000000..718680d
--- /dev/null
+++ b/public/admin/model/extension/payment/pilibaba.php
@@ -0,0 +1,165 @@
+<?php
+class ModelExtensionPaymentPilibaba extends Model {
+ public function install() {
+ $this->db->query("CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "pilibaba_order` (
+ `pilibaba_order_id` int(11) NOT NULL AUTO_INCREMENT,
+ `order_id` int(11) NOT NULL DEFAULT '0',
+ `amount` double NOT NULL,
+ `fee` double NOT NULL,
+ `tracking` VARCHAR(50) NOT NULL DEFAULT '',
+ `date_added` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
+ PRIMARY KEY (`pilibaba_order_id`)
+ ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci");
+ }
+
+ public function uninstall() {
+ $this->db->query("DROP TABLE IF EXISTS `" . DB_PREFIX . "pilibaba_order`");
+
+ $this->disablePiliExpress();
+
+ $this->log('Module uninstalled');
+ }
+
+ public function getCurrencies() {
+ $ch = curl_init();
+ curl_setopt($ch, CURLOPT_URL, 'http://www.pilibaba.com/pilipay/getCurrency');
+ curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
+ curl_setopt($ch, CURLOPT_HEADER, false);
+ curl_setopt($ch, CURLOPT_TIMEOUT, 30);
+ curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
+ $response = curl_exec($ch);
+ curl_close($ch);
+
+ return json_decode($response, true);
+ }
+
+ public function getWarehouses() {
+ $ch = curl_init();
+ curl_setopt($ch, CURLOPT_URL, 'http://www.pilibaba.com/pilipay/getAddressList');
+ curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
+ curl_setopt($ch, CURLOPT_HEADER, false);
+ curl_setopt($ch, CURLOPT_TIMEOUT, 30);
+ curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
+ $response = curl_exec($ch);
+ curl_close($ch);
+
+ return json_decode($response, true);
+ }
+
+ public function getOrder($order_id) {
+ $query = $this->db->query("SELECT * FROM `" . DB_PREFIX . "pilibaba_order` WHERE `order_id` = '" . (int)$order_id . "' LIMIT 1");
+
+ if ($query->num_rows) {
+ return $query->row;
+ } else {
+ return false;
+ }
+ }
+
+ public function register($email, $password, $currency, $warehouse, $country, $environment) {
+ $this->log('Posting register');
+
+ if ($warehouse == 'other') {
+ $warehouse = '';
+ }
+
+ if ($warehouse) {
+ $country = '';
+ }
+
+ if ($environment == 'live') {
+ $url = 'http://en.pilibaba.com/autoRegist';
+ } else {
+ $url = 'http://preen.pilibaba.com/autoRegist';
+ }
+
+ $this->log('URL: ' . $url);
+
+ $app_secret = strtoupper(md5((($warehouse) ? $warehouse : $country) . '0210000574' . '0b8l3ww5' . $currency . $email . md5($password)));
+
+ $data = array(
+ 'platformNo' => '0210000574',
+ 'appSecret' => $app_secret,
+ 'email' => $email,
+ 'password' => md5($password),
+ 'currency' => $currency,
+ 'logistics' => $warehouse,
+ 'countryCode' => $country
+ );
+
+ $this->log('Data: ' . print_r($data, true));
+
+ $headers = array('Accept: application/json','Content-Type: application/json');
+
+ $ch = curl_init();
+ curl_setopt($ch, CURLOPT_URL, $url);
+ curl_setopt($ch, CURLOPT_POST, true);
+ curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
+ curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
+ curl_setopt($ch, CURLOPT_TIMEOUT, 30);
+ curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
+ $response = curl_exec($ch);
+ if (curl_errno($ch)) {
+ $this->log('cURL error: ' . curl_errno($ch));
+ }
+ curl_close($ch);
+
+ $this->log('Response: ' . print_r($response, true));
+
+ return json_decode($response, true);
+ }
+
+ public function updateTrackingNumber($order_id, $tracking_number, $merchant_number) {
+ $this->log('Posting tracking');
+
+ $sign_msg = strtoupper(md5($order_id . $tracking_number . $merchant_number . $this->config->get('payment_pilibaba_secret_key')));
+
+ if ($this->config->get('payment_pilibaba_environment') == 'live') {
+ $url = 'https://www.pilibaba.com/pilipay/updateTrackNo';
+ } else {
+ $url = 'http://pre.pilibaba.com/pilipay/updateTrackNo';
+ }
+
+ $url .= '?orderNo=' . $order_id . '&logisticsNo=' . $tracking_number . '&merchantNo=' . $merchant_number . '&signMsg=' . $sign_msg;
+
+ $this->log('URL: ' . $url);
+
+ $ch = curl_init();
+ curl_setopt($ch, CURLOPT_URL, $url);
+ curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
+ curl_setopt($ch, CURLOPT_HEADER, false);
+ curl_setopt($ch, CURLOPT_TIMEOUT, 30);
+ curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
+ $response = curl_exec($ch);
+ if (curl_errno($ch)) {
+ $this->log('cURL error: ' . curl_errno($ch));
+ }
+ curl_close($ch);
+
+ $this->db->query("UPDATE `" . DB_PREFIX . "pilibaba_order` SET `tracking` = '" . $this->db->escape($tracking_number) . "' WHERE `order_id` = '" . (int)$order_id . "'");
+ }
+
+ public function enablePiliExpress() {
+ $query = $this->db->query("SELECT * FROM `" . DB_PREFIX . "extension` WHERE `type` = 'shipping' AND `code` = 'pilibaba'");
+
+ if (!$query->num_rows) {
+ $this->db->query("INSERT INTO `" . DB_PREFIX . "extension` SET `type` = 'shipping', `code` = 'pilibaba'");
+ }
+ }
+
+ public function disablePiliExpress() {
+ $this->db->query("DELETE FROM `" . DB_PREFIX . "extension` WHERE `type` = 'shipping' AND `code` = 'pilibaba'");
+ }
+
+ public function log($data) {
+ if ($this->config->has('payment_pilibaba_logging') && $this->config->get('payment_pilibaba_logging')) {
+ $log = new Log('pilibaba.log');
+
+ $log->write($data);
+ }
+ }
+} \ No newline at end of file
diff --git a/public/admin/model/extension/payment/pp_braintree.php b/public/admin/model/extension/payment/pp_braintree.php
new file mode 100644
index 0000000..af0e604
--- /dev/null
+++ b/public/admin/model/extension/payment/pp_braintree.php
@@ -0,0 +1,168 @@
+<?php
+class ModelExtensionPaymentPPBraintree extends Model {
+ public function generateToken($gateway, $data = array()) {
+ try {
+ if ($gateway != null) {
+ $client_token = $gateway->clientToken()->generate($data);
+ } else {
+ $client_token = Braintree_ClientToken::generate($data);
+ }
+
+ return $client_token;
+ } catch (Exception $e) {
+ $this->log($e->getMessage());
+
+ return false;
+ }
+ }
+
+ public function getTransaction($gateway, $transaction_id) {
+ try {
+ if ($gateway != null) {
+ $transaction = $gateway->transaction()->find($transaction_id);
+ } else {
+ $transaction = Braintree_Transaction::find($transaction_id);
+ }
+
+ if ($transaction) {
+ return $transaction;
+ } else {
+ return false;
+ }
+ } catch (Exception $e) {
+ $this->log($e->getMessage());
+
+ return false;
+ }
+ }
+
+ public function getTransactions($gateway, $data = array()) {
+ try {
+ if ($gateway != null) {
+ $transactions = $gateway->transaction()->search($data);
+ } else {
+ $transactions = Braintree_Transaction::search($data);
+ }
+
+ if ($transactions) {
+ return $transactions;
+ } else {
+ return false;
+ }
+ } catch (Exception $e) {
+ $this->log($e->getMessage());
+
+ return false;
+ }
+ }
+
+ public function voidTransaction($gateway, $transaction_id) {
+ try {
+ if ($gateway != null) {
+ $transaction = $gateway->transaction()->void($transaction_id);
+ } else {
+ $transaction = Braintree_Transaction::void($transaction_id);
+ }
+
+ if ($transaction) {
+ return $transaction;
+ } else {
+ return false;
+ }
+ } catch (Exception $e) {
+ $this->log($e->getMessage());
+
+ return false;
+ }
+ }
+
+ public function settleTransaction($gateway, $transaction_id, $amount) {
+ try {
+ if ($gateway != null) {
+ $transaction = $gateway->transaction()->submitForSettlement($transaction_id, $amount);
+ } else {
+ $transaction = Braintree_Transaction::submitForSettlement($transaction_id, $amount);
+ }
+
+ if ($transaction) {
+ return $transaction;
+ } else {
+ return false;
+ }
+ } catch (Exception $e) {
+ $this->log($e->getMessage());
+
+ return false;
+ }
+ }
+
+ public function refundTransaction($gateway, $transaction_id, $amount) {
+ try {
+ if ($gateway != null) {
+ $transaction = $gateway->transaction()->refund($transaction_id, $amount);
+ } else {
+ $transaction = Braintree_Transaction::refund($transaction_id, $amount);
+ }
+
+ if ($transaction) {
+ return $transaction;
+ } else {
+ return false;
+ }
+ } catch (Exception $e) {
+ $this->log($e->getMessage());
+
+ return false;
+ }
+ }
+
+ public function verifyCredentials($gateway) {
+ try {
+ //Try API call, if no exception is thrown, the credentials are correct
+ if ($gateway != null) {
+ $client_token = $gateway->clientToken()->generate();
+ } else {
+ $client_token = Braintree_ClientToken::generate();
+ }
+
+ return $client_token;
+ } catch (Exception $e) {
+ $this->log($e->getMessage());
+
+ return false;
+ }
+ }
+
+ public function verifyMerchantAccount($gateway, $merchant_account_id) {
+ try {
+ //Try API call, if no exception is thrown, the above credentials are correct
+ if ($gateway != null) {
+ $merchant_account = $gateway->merchantAccount()->find($merchant_account_id);
+ } else {
+ $merchant_account = Braintree_MerchantAccount::find($merchant_account_id);
+ }
+
+ if ($merchant_account && $merchant_account->status == 'active') {
+ return $merchant_account;
+ } else {
+ return false;
+ }
+ } catch (Exception $e) {
+ $this->log($e->getMessage());
+
+ return false;
+ }
+ }
+
+ public function setGateway($access_token) {
+ return new Braintree_Gateway(array('accessToken' => $access_token));
+ }
+
+ public function log($data) {
+ if ($this->config->get('payment_pp_braintree_debug')) {
+ $backtrace = debug_backtrace();
+ $log = new Log('braintree.log');
+ $log->write('(' . $backtrace[1]['class'] . '::' . $backtrace[1]['function'] . ') - ' . print_r($data, true));
+ }
+ }
+}
diff --git a/public/admin/model/extension/payment/pp_express.php b/public/admin/model/extension/payment/pp_express.php
new file mode 100644
index 0000000..5c82d30
--- /dev/null
+++ b/public/admin/model/extension/payment/pp_express.php
@@ -0,0 +1,376 @@
+<?php
+class ModelExtensionPaymentPPExpress extends Model {
+ public function install() {
+ $this->db->query("
+ CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "paypal_order` (
+ `paypal_order_id` int(11) NOT NULL AUTO_INCREMENT,
+ `order_id` int(11) NOT NULL,
+ `date_added` DATETIME NOT NULL,
+ `date_modified` DATETIME NOT NULL,
+ `capture_status` ENUM('Complete','NotComplete') DEFAULT NULL,
+ `currency_code` CHAR(3) NOT NULL,
+ `authorization_id` VARCHAR(30) NOT NULL,
+ `total` DECIMAL( 10, 2 ) NOT NULL,
+ PRIMARY KEY (`paypal_order_id`)
+ ) ENGINE=MyISAM DEFAULT COLLATE=utf8_general_ci
+ ");
+
+ $this->db->query("
+ CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "paypal_order_transaction` (
+ `paypal_order_transaction_id` int(11) NOT NULL AUTO_INCREMENT,
+ `paypal_order_id` int(11) NOT NULL,
+ `transaction_id` CHAR(20) NOT NULL,
+ `parent_id` CHAR(20) NOT NULL,
+ `date_added` DATETIME NOT NULL,
+ `note` VARCHAR(255) NOT NULL,
+ `msgsubid` CHAR(38) NOT NULL,
+ `receipt_id` CHAR(20) NOT NULL,
+ `payment_type` ENUM('none','echeck','instant', 'refund', 'void') DEFAULT NULL,
+ `payment_status` CHAR(20) NOT NULL,
+ `pending_reason` CHAR(50) NOT NULL,
+ `transaction_entity` CHAR(50) NOT NULL,
+ `amount` DECIMAL( 10, 2 ) NOT NULL,
+ `debug_data` TEXT NOT NULL,
+ `call_data` TEXT NOT NULL,
+ PRIMARY KEY (`paypal_order_transaction_id`)
+ ) ENGINE=MyISAM DEFAULT COLLATE=utf8_general_ci
+ ");
+
+ $this->load->model('setting/setting');
+
+ $defaults = array();
+
+ // Order Status defaults
+ $defaults['payment_pp_express_canceled_reversal_status_id'] = 9;
+ $defaults['payment_pp_express_completed_status_id'] = 5;
+ $defaults['payment_pp_express_denied_status_id'] = 8;
+ $defaults['payment_pp_express_expired_status_id'] = 14;
+ $defaults['payment_pp_express_failed_status_id'] = 10;
+ $defaults['payment_pp_express_pending_status_id'] = 1;
+ $defaults['payment_pp_express_processed_status_id'] = 15;
+ $defaults['payment_pp_express_refunded_status_id'] = 11;
+ $defaults['payment_pp_express_reversed_status_id'] = 12;
+ $defaults['payment_pp_express_voided_status_id'] = 16;
+
+ $defaults['payment_pp_express_status'] = 0;
+ $defaults['payment_pp_express_currency'] = "USD";
+
+ $this->model_setting_setting->editSetting('payment_pp_express', $defaults);
+
+ $this->load->model('setting/event');
+ $this->model_setting_event->addEvent('extension_pp_express_checkout_js', 'catalog/controller/checkout/checkout/before', 'extension/payment/pp_express/eventLoadCheckoutJs');
+ }
+
+ public function uninstall() {
+ $this->db->query("DROP TABLE IF EXISTS `" . DB_PREFIX . "paypal_order_transaction`");
+ $this->db->query("DROP TABLE IF EXISTS `" . DB_PREFIX . "paypal_order`");
+
+ $this->load->model('setting/event');
+ $this->model_setting_event->deleteEventByCode('extension_pp_express_checkout_js');
+ }
+
+ public function getPayPalOrder($order_id) {
+ $query = $this->db->query("SELECT * FROM `" . DB_PREFIX . "paypal_order` WHERE `order_id` = '" . (int)$order_id . "'");
+
+ return $query->row;
+ }
+
+ public function editPayPalOrderStatus($order_id, $capture_status) {
+ $this->db->query("UPDATE `" . DB_PREFIX . "paypal_order` SET `capture_status` = '" . $this->db->escape($capture_status) . "', `date_modified` = NOW() WHERE `order_id` = '" . (int)$order_id . "'");
+ }
+
+ public function addTransaction($transaction_data, $request_data = array()) {
+ if ($request_data) {
+ $serialized_data = json_encode($request_data);
+
+ $this->db->query("UPDATE " . DB_PREFIX . "paypal_order_transaction SET call_data = '" . $this->db->escape($serialized_data) . "' WHERE paypal_order_transaction_id = " . (int)$paypal_order_transaction_id . " LIMIT 1");
+ }
+
+
+
+ $this->db->query("INSERT INTO `" . DB_PREFIX . "paypal_order_transaction` SET `paypal_order_id` = '" . (int)$transaction_data['paypal_order_id'] . "', `transaction_id` = '" . $this->db->escape($transaction_data['transaction_id']) . "', `parent_id` = '" . $this->db->escape($transaction_data['parent_id']) . "', `date_added` = NOW(), `note` = '" . $this->db->escape($transaction_data['note']) . "', `msgsubid` = '" . $this->db->escape($transaction_data['msgsubid']) . "', `receipt_id` = '" . $this->db->escape($transaction_data['receipt_id']) . "', `payment_type` = '" . $this->db->escape($transaction_data['payment_type']) . "', `payment_status` = '" . $this->db->escape($transaction_data['payment_status']) . "', `pending_reason` = '" . $this->db->escape($transaction_data['pending_reason']) . "', `transaction_entity` = '" . $this->db->escape($transaction_data['transaction_entity']) . "', `amount` = '" . (float)$transaction_data['amount'] . "', `debug_data` = '" . $this->db->escape($transaction_data['debug_data']) . "'");
+
+ return $this->db->getLastId();
+ }
+
+ public function updateTransaction($transaction) {
+ $this->db->query("UPDATE " . DB_PREFIX . "paypal_order_transaction SET paypal_order_id = " . (int)$transaction['paypal_order_id'] . ", transaction_id = '" . $this->db->escape($transaction['transaction_id']) . "', parent_id = '" . $this->db->escape($transaction['parent_id']) . "', date_added = '" . $this->db->escape($transaction['date_added']) . "', note = '" . $this->db->escape($transaction['note']) . "', msgsubid = '" . $this->db->escape($transaction['msgsubid']) . "', receipt_id = '" . $this->db->escape($transaction['receipt_id']) . "', payment_type = '" . $this->db->escape($transaction['payment_type']) . "', payment_status = '" . $this->db->escape($transaction['payment_status']) . "', pending_reason = '" . $this->db->escape($transaction['pending_reason']) . "', transaction_entity = '" . $this->db->escape($transaction['transaction_entity']) . "', amount = '" . $this->db->escape($transaction['amount']) . "', debug_data = '" . $this->db->escape($transaction['debug_data']) . "', call_data = '" . $this->db->escape($transaction['call_data']) . "' WHERE paypal_order_transaction_id = '" . (int)$transaction['paypal_order_transaction_id'] . "'");
+ }
+
+ public function getPaypalOrderByTransactionId($transaction_id) {
+ $query = $this->db->query("SELECT * FROM " . DB_PREFIX . "paypal_order_transaction WHERE transaction_id = '" . $this->db->escape($transaction_id) . "'");
+
+ return $query->rows;
+ }
+
+ public function getFailedTransaction($paypal_order_transaction_id) {
+ $query = $this->db->query("SELECT * FROM " . DB_PREFIX . "paypal_order_transaction WHERE paypal_order_transaction_id = '" . (int)$paypal_order_transaction_id . "'");
+
+ return $query->row;
+ }
+
+ public function getLocalTransaction($transaction_id) {
+ $result = $this->db->query("SELECT * FROM " . DB_PREFIX . "paypal_order_transaction WHERE transaction_id = '" . $this->db->escape($transaction_id) . "'")->row;
+
+ if ($result) {
+ return $result;
+ } else {
+ return false;
+ }
+ }
+
+ public function getTransaction($transaction_id) {
+ $call_data = array(
+ 'METHOD' => 'GetTransactionDetails',
+ 'TRANSACTIONID' => $transaction_id,
+ );
+
+ return $this->call($call_data);
+ }
+
+ public function getCurrencies() {
+ return array(
+ 'AUD',
+ 'BRL',
+ 'CAD',
+ 'CZK',
+ 'DKK',
+ 'EUR',
+ 'HKD',
+ 'HUF',
+ 'ILS',
+ 'JPY',
+ 'MYR',
+ 'MXN',
+ 'NOK',
+ 'NZD',
+ 'PHP',
+ 'PLN',
+ 'GBP',
+ 'SGD',
+ 'SEK',
+ 'CHF',
+ 'TWD',
+ 'THB',
+ 'TRY',
+ 'USD',
+ );
+ }
+
+ public function getOrderId($transaction_id) {
+ $query = $this->db->query("SELECT `o`.`order_id` FROM `" . DB_PREFIX . "paypal_order_transaction` `ot` LEFT JOIN `" . DB_PREFIX . "paypal_order` `o` ON `o`.`paypal_order_id` = `ot`.`paypal_order_id` WHERE `ot`.`transaction_id` = '" . $this->db->escape($transaction_id) . "' LIMIT 1");
+
+ return $query->row['order_id'];
+ }
+
+ public function getCapturedTotal($paypal_order_id) {
+ $query = $this->db->query("SELECT SUM(`amount`) AS `amount` FROM `" . DB_PREFIX . "paypal_order_transaction` WHERE `paypal_order_id` = '" . (int)$paypal_order_id . "' AND `pending_reason` != 'authorization' AND (`payment_status` = 'Partially-Refunded' OR `payment_status` = 'Completed' OR `payment_status` = 'Pending') AND `transaction_entity` = 'payment'");
+
+ return $query->row['amount'];
+ }
+
+ public function getRefundedTotal($paypal_order_id) {
+ $query = $this->db->query("SELECT SUM(`amount`) AS `amount` FROM `" . DB_PREFIX . "paypal_order_transaction` WHERE `paypal_order_id` = '" . (int)$paypal_order_id . "' AND `payment_status` = 'Refunded' AND `parent_id` != ''");
+
+ return $query->row['amount'];
+ }
+
+ public function getRefundedTotalByParentId($transaction_id) {
+ $query = $this->db->query("SELECT SUM(`amount`) AS `amount` FROM `" . DB_PREFIX . "paypal_order_transaction` WHERE `parent_id` = '" . $this->db->escape($transaction_id) . "' AND `payment_type` = 'refund'");
+
+ return $query->row['amount'];
+ }
+
+ public function cleanReturn($data) {
+ $data = explode('&', $data);
+
+ $arr = array();
+
+ foreach ($data as $k => $v) {
+ $tmp = explode('=', $v);
+ $arr[$tmp[0]] = urldecode($tmp[1]);
+ }
+
+ return $arr;
+ }
+
+ public function log($data, $title = null) {
+ if ($this->config->get('payment_pp_express_debug')) {
+ $this->log->write('PayPal Express debug (' . $title . '): ' . json_encode($data));
+ }
+ }
+
+ public function getOrder($order_id) {
+ $qry = $this->db->query("SELECT * FROM `" . DB_PREFIX . "paypal_order` WHERE `order_id` = '" . (int)$order_id . "' LIMIT 1");
+
+ if ($qry->num_rows) {
+ $order = $qry->row;
+ $order['transactions'] = $this->getTransactions($order['paypal_order_id']);
+ $order['captured'] = $this->totalCaptured($order['paypal_order_id']);
+ return $order;
+ } else {
+ return false;
+ }
+ }
+
+ public function totalCaptured($paypal_order_id) {
+ $qry = $this->db->query("SELECT SUM(`amount`) AS `amount` FROM `" . DB_PREFIX . "paypal_order_transaction` WHERE `paypal_order_id` = '" . (int)$paypal_order_id . "' AND `pending_reason` != 'authorization' AND (`payment_status` = 'Partially-Refunded' OR `payment_status` = 'Completed' OR `payment_status` = 'Pending') AND `transaction_entity` = 'payment'");
+
+ return $qry->row['amount'];
+ }
+
+ public function getTransactions($paypal_order_id) {
+ $query = $this->db->query("SELECT `ot`.*, (SELECT COUNT(`ot2`.`paypal_order_id`) FROM `" . DB_PREFIX . "paypal_order_transaction` `ot2` WHERE `ot2`.`parent_id` = `ot`.`transaction_id`) AS `children` FROM `" . DB_PREFIX . "paypal_order_transaction` `ot` WHERE `paypal_order_id` = '" . (int)$paypal_order_id . "' ORDER BY `date_added` ASC");
+
+ return $query->rows;
+ }
+
+ public function getTokens($test) {
+ if ($test == 'sandbox') {
+ $endpoint = 'https://api.sandbox.paypal.com/v1/oauth2/token';
+ $client_id = 'Ad3QTBAHwhuNI_blejO4_RqvES74yWRUC61c5QVNDbxkq9csbLpDZogWp_0n';
+ $client_secret = 'EGqgGxCqjs1GIa5l1Ex_Flq0Mb2oMT3rJu2kwz6FuF9QKyxCg6qNqyddxCCW';
+ } else {
+ $endpoint = 'https://api.paypal.com/v1/oauth2/token';
+ $client_id = 'AWyAiBCUYsE156N8YpiiISQpSpep2HPoXXPrf33VBeYleE0SQJg40pgEqZvq';
+ $client_secret = 'EEkc6xB30fDkgUO_YldWWHxKDquY7LBRId6FJ-parAR1CsVpK35zB6U0SIh4';
+ }
+
+ $request = '';
+ $request .= 'client_id=' . $client_id;
+ $request .= '&client_secret=' . $client_secret;
+ $request .= '&grant_type=client_credentials';
+
+ $additional_opts = array(
+ CURLOPT_USERPWD => $client_id . ':' . $client_secret,
+ CURLOPT_POST => true,
+ CURLOPT_POSTFIELDS => $request
+ );
+
+ $curl = $this->curl($endpoint, $additional_opts);
+
+ $this->log('cURL Response 1: ' . print_r($curl, 1));
+
+ return $curl;
+ }
+
+ public function getUserInfo($merchant_id, $test, $access_token) {
+ if ($test == 'sandbox') {
+ $endpoint = 'https://api.sandbox.paypal.com/v1/customer/partners/T4E8WSXT43QPJ/merchant-integrations';
+ } else {
+ $endpoint = 'https://api.paypal.com/v1/customer/partners/9PDNYE4RZBVFJ/merchant-integrations';
+ }
+
+ $endpoint1 = $endpoint . '?tracking_id=' . $merchant_id;
+
+ $header = array();
+ $header[] = 'Content-Type: application/json';
+ $header[] = 'Authorization: Bearer ' . $access_token;
+ $header[] = 'PAYPAL_SERVICE_VERSION:1.2.0';
+
+ $additional_opts = array(
+ CURLOPT_HTTPHEADER => $header,
+ );
+
+ $curl = $this->curl($endpoint1, $additional_opts);
+
+ $this->log('cURL Response 2: ' . print_r($curl, 1));
+
+ if (isset($curl->merchant_id)) {
+ $endpoint2 = $endpoint . '/' . $curl->merchant_id;
+ $curl2 = $this->curl($endpoint2, $additional_opts);
+
+ $this->log('cURL Response 3: ' . print_r($curl2, 1));
+
+ if (isset($curl2->api_credentials->signature)) {
+ return $curl2->api_credentials->signature;
+ } else {
+ return;
+ }
+ } else {
+ return;
+ }
+ }
+
+ public function call($data) {
+ if ($this->config->get('payment_pp_express_test') == 1) {
+ $api_endpoint = 'https://api-3t.sandbox.paypal.com/nvp';
+ $user = $this->config->get('payment_pp_express_sandbox_username');
+ $password = $this->config->get('payment_pp_express_sandbox_password');
+ $signature = $this->config->get('payment_pp_express_sandbox_signature');
+ } else {
+ $api_endpoint = 'https://api-3t.paypal.com/nvp';
+ $user = $this->config->get('payment_pp_express_username');
+ $password = $this->config->get('payment_pp_express_password');
+ $signature = $this->config->get('payment_pp_express_signature');
+ }
+
+ $settings = array(
+ 'USER' => $user,
+ 'PWD' => $password,
+ 'SIGNATURE' => $signature,
+ 'VERSION' => '84',
+ 'BUTTONSOURCE' => 'OpenCart_Cart_EC',
+ );
+
+ $this->log($data, 'Call data');
+
+ $defaults = array(
+ CURLOPT_POST => 1,
+ CURLOPT_HEADER => 0,
+ CURLOPT_URL => $api_endpoint,
+ CURLOPT_USERAGENT => "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.1) Gecko/20061204 Firefox/2.0.0.1",
+ CURLOPT_FRESH_CONNECT => 1,
+ CURLOPT_RETURNTRANSFER => 1,
+ CURLOPT_FORBID_REUSE => 1,
+ CURLOPT_TIMEOUT => 0,
+ CURLOPT_SSL_VERIFYPEER => 0,
+ CURLOPT_SSL_VERIFYHOST => 0,
+ CURLOPT_POSTFIELDS => http_build_query(array_merge($data, $settings), '', "&")
+ );
+
+ $ch = curl_init();
+
+ curl_setopt_array($ch, $defaults);
+
+ if (!$result = curl_exec($ch)) {
+ $log_data = array(
+ 'curl_error' => curl_error($ch),
+ 'curl_errno' => curl_errno($ch)
+ );
+
+ $this->log($log_data, 'CURL failed');
+ return false;
+ }
+
+ $this->log($result, 'Result');
+
+ curl_close($ch);
+
+ return $this->cleanReturn($result);
+ }
+
+ private function curl($endpoint, $additional_opts = array()) {
+ $default_opts = array(
+ CURLOPT_PORT => 443,
+ CURLOPT_HEADER => 0,
+ CURLOPT_SSL_VERIFYPEER => 0,
+ CURLOPT_RETURNTRANSFER => 1,
+ CURLOPT_FORBID_REUSE => 1,
+ CURLOPT_FRESH_CONNECT => 1,
+ CURLOPT_URL => $endpoint,
+ );
+
+ $ch = curl_init($endpoint);
+
+ $opts = $default_opts + $additional_opts;
+
+ curl_setopt_array($ch, $opts);
+
+ $response = json_decode(curl_exec($ch));
+
+ curl_close($ch);
+
+ return $response;
+ }
+}
diff --git a/public/admin/model/extension/payment/pp_payflow_iframe.php b/public/admin/model/extension/payment/pp_payflow_iframe.php
new file mode 100644
index 0000000..34c2251
--- /dev/null
+++ b/public/admin/model/extension/payment/pp_payflow_iframe.php
@@ -0,0 +1,136 @@
+<?php
+class ModelExtensionPaymentPPPayflowIFrame extends Model {
+ public function install() {
+ $this->db->query("
+ CREATE TABLE `" . DB_PREFIX . "paypal_payflow_iframe_order` (
+ `order_id` int(11) DEFAULT NULL,
+ `secure_token_id` varchar(255) NOT NULL,
+ `transaction_reference` varchar(255) DEFAULT NULL,
+ `transaction_type` varchar(1) DEFAULT NULL,
+ `complete` tinyint(4) NOT NULL DEFAULT '0',
+ PRIMARY KEY(`order_id`),
+ KEY `secure_token_id` (`secure_token_id`)
+ ) ENGINE=MyISAM DEFAULT COLLATE=utf8_general_ci");
+
+ $this->db->query("
+ CREATE TABLE `" . DB_PREFIX . "paypal_payflow_iframe_order_transaction` (
+ `order_id` int(11) NOT NULL,
+ `transaction_reference` varchar(255) NOT NULL,
+ `transaction_type` char(1) NOT NULL,
+ `time` datetime NOT NULL,
+ `amount` decimal(10,4) DEFAULT NULL,
+ PRIMARY KEY (`transaction_reference`),
+ KEY `order_id` (`order_id`)
+ ) ENGINE=MyISAM DEFAULT CHARSET=utf8;");
+ }
+
+ public function uninstall() {
+ $this->db->query("DROP TABLE IF EXISTS `" . DB_PREFIX . "paypal_payflow_iframe_order`;");
+ $this->db->query("DROP TABLE IF EXISTS `" . DB_PREFIX . "paypal_payflow_iframe_order_transaction`;");
+ }
+
+ public function log($message) {
+ if ($this->config->get('payment_pp_payflow_iframe_debug')) {
+ $log = new Log('payflow-iframe.log');
+ $log->write($message);
+ }
+ }
+
+ public function getOrder($order_id) {
+ $result = $this->db->query("SELECT * FROM " . DB_PREFIX . "paypal_payflow_iframe_order WHERE order_id = " . (int)$order_id);
+
+ if ($result->num_rows) {
+ $order = $result->row;
+ } else {
+ $order = false;
+ }
+
+ return $order;
+ }
+
+ public function updateOrderStatus($order_id, $status) {
+ $this->db->query("
+ UPDATE " . DB_PREFIX . "paypal_payflow_iframe_order
+ SET `complete` = " . (int)$status . "
+ WHERE order_id = '" . (int)$order_id . "'
+ ");
+ }
+
+ public function addTransaction($data) {
+ $this->db->query("
+ INSERT INTO " . DB_PREFIX . "paypal_payflow_iframe_order_transaction
+ SET order_id = " . (int)$data['order_id'] . ",
+ transaction_reference = '" . $this->db->escape($data['transaction_reference']) . "',
+ transaction_type = '" . $this->db->escape($data['type']) . "',
+ `time` = NOW(),
+ `amount` = '" . $this->db->escape($data['amount']) . "'
+ ");
+ }
+
+ public function getTransactions($order_id) {
+ return $this->db->query("
+ SELECT *
+ FROM " . DB_PREFIX . "paypal_payflow_iframe_order_transaction
+ WHERE order_id = " . (int)$order_id . "
+ ORDER BY `time` ASC")->rows;
+ }
+
+ public function getTransaction($transaction_reference) {
+ $result = $this->db->query("
+ SELECT *
+ FROM " . DB_PREFIX . "paypal_payflow_iframe_order_transaction
+ WHERE transaction_reference = '" . $this->db->escape($transaction_reference) . "'")->row;
+
+ if ($result) {
+ $transaction = $result;
+ } else {
+ $transaction = false;
+ }
+
+ return $transaction;
+ }
+
+ public function call($data) {
+ $default_parameters = array(
+ 'USER' => $this->config->get('payment_pp_payflow_iframe_user'),
+ 'VENDOR' => $this->config->get('payment_pp_payflow_iframe_vendor'),
+ 'PWD' => $this->config->get('payment_pp_payflow_iframe_password'),
+ 'PARTNER' => $this->config->get('payment_pp_payflow_iframe_partner'),
+ 'BUTTONSOURCE' => 'OpenCart_Cart_PFP',
+ );
+
+ $call_parameters = array_merge($data, $default_parameters);
+
+ if ($this->config->get('payment_pp_payflow_iframe_test')) {
+ $url = 'https://pilot-payflowpro.paypal.com';
+ } else {
+ $url = 'https://payflowpro.paypal.com';
+ }
+
+ $query_params = array();
+
+ foreach ($call_parameters as $key => $value) {
+ $query_params[] = $key . '=' . utf8_decode($value);
+ }
+
+ $this->log('Call data: ' . implode('&', $query_params));
+
+ $curl = curl_init($url);
+
+ curl_setopt($curl, CURLOPT_POST, true);
+ curl_setopt($curl, CURLOPT_POSTFIELDS, implode('&', $query_params));
+ curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
+ curl_setopt($curl, CURLOPT_HEADER, false);
+ curl_setopt($curl, CURLOPT_TIMEOUT, 30);
+ curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
+
+ $response = curl_exec($curl);
+
+ $this->log('Response data: ' . $response);
+
+ $response_params = array();
+ parse_str($response, $response_params);
+
+ return $response_params;
+ }
+} \ No newline at end of file
diff --git a/public/admin/model/extension/payment/pp_pro_iframe.php b/public/admin/model/extension/payment/pp_pro_iframe.php
new file mode 100644
index 0000000..f1df3b5
--- /dev/null
+++ b/public/admin/model/extension/payment/pp_pro_iframe.php
@@ -0,0 +1,261 @@
+<?php
+class ModelExtensionPaymentPPProIframe extends Model {
+ public function install() {
+ $this->db->query("
+ CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "paypal_iframe_order` (
+ `paypal_iframe_order_id` int(11) NOT NULL AUTO_INCREMENT,
+ `order_id` int(11) NOT NULL,
+ `date_added` DATETIME NOT NULL,
+ `date_modified` DATETIME NOT NULL,
+ `capture_status` ENUM('Complete','NotComplete') DEFAULT NULL,
+ `currency_code` CHAR(3) NOT NULL,
+ `authorization_id` VARCHAR(30) NOT NULL,
+ `total` DECIMAL( 10, 2 ) NOT NULL,
+ PRIMARY KEY (`paypal_iframe_order_id`)
+ ) ENGINE=MyISAM DEFAULT COLLATE=utf8_general_ci;");
+
+ $this->db->query("
+ CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "paypal_iframe_order_transaction` (
+ `paypal_iframe_order_transaction_id` int(11) NOT NULL AUTO_INCREMENT,
+ `paypal_iframe_order_id` int(11) NOT NULL,
+ `transaction_id` CHAR(20) NOT NULL,
+ `parent_id` CHAR(20) NOT NULL,
+ `date_added` DATETIME NOT NULL,
+ `note` VARCHAR(255) NOT NULL,
+ `msgsubid` CHAR(38) NOT NULL,
+ `receipt_id` CHAR(20) NOT NULL,
+ `payment_type` ENUM('none','echeck','instant', 'refund', 'void') DEFAULT NULL,
+ `payment_status` CHAR(20) NOT NULL,
+ `pending_reason` CHAR(50) NOT NULL,
+ `transaction_entity` CHAR(50) NOT NULL,
+ `amount` DECIMAL( 10, 2 ) NOT NULL,
+ `debug_data` TEXT NOT NULL,
+ `call_data` TEXT NOT NULL,
+ PRIMARY KEY (`paypal_iframe_order_transaction_id`)
+ ) ENGINE=MyISAM DEFAULT COLLATE=utf8_general_ci;");
+ }
+
+ public function uninstall() {
+ $this->db->query("DROP TABLE IF EXISTS `" . DB_PREFIX . "paypal_iframe_order_transaction`;");
+ $this->db->query("DROP TABLE IF EXISTS `" . DB_PREFIX . "paypal_iframe_order`;");
+ }
+
+ private function getTransactions($paypal_iframe_order_id) {
+ $qry = $this->db->query("SELECT `ot`.*, ( SELECT count(`ot2`.`paypal_iframe_order_id`) FROM `" . DB_PREFIX . "paypal_iframe_order_transaction` `ot2` WHERE `ot2`.`parent_id` = `ot`.`transaction_id` ) AS `children` FROM `" . DB_PREFIX . "paypal_iframe_order_transaction` `ot` WHERE `paypal_iframe_order_id` = '" . (int)$paypal_iframe_order_id . "'");
+
+ if ($qry->num_rows) {
+ return $qry->rows;
+ } else {
+ return false;
+ }
+ }
+
+ public function getTotalCaptured($paypal_iframe_order_id) {
+ $qry = $this->db->query("SELECT SUM(`amount`) AS `amount` FROM `" . DB_PREFIX . "paypal_iframe_order_transaction` WHERE `paypal_iframe_order_id` = '" . (int)$paypal_iframe_order_id . "' AND `pending_reason` != 'authorization' AND (`payment_status` = 'Partially-Refunded' OR `payment_status` = 'Completed' OR `payment_status` = 'Pending') AND `transaction_entity` = 'payment'");
+
+ return $qry->row['amount'];
+ }
+
+ public function getTotalRefunded($paypal_iframe_order_id) {
+ $qry = $this->db->query("SELECT SUM(`amount`) AS `amount` FROM `" . DB_PREFIX . "paypal_iframe_order_transaction` WHERE `paypal_iframe_order_id` = '" . (int)$paypal_iframe_order_id . "' AND `payment_status` = 'Refunded'");
+
+ return $qry->row['amount'];
+ }
+
+ public function getTotalRefundedTransaction($transaction_id) {
+ $qry = $this->db->query("SELECT SUM(`amount`) AS `amount` FROM `" . DB_PREFIX . "paypal_iframe_order_transaction` WHERE `parent_id` = '" . $this->db->escape($transaction_id) . "' AND `payment_type` = 'refund'");
+
+ return $qry->row['amount'];
+ }
+
+ public function getOrder($order_id) {
+ $qry = $this->db->query("SELECT * FROM `" . DB_PREFIX . "paypal_iframe_order` WHERE `order_id` = '" . (int)$order_id . "' LIMIT 1");
+
+ if ($qry->num_rows) {
+ $order = $qry->row;
+ $order['transactions'] = $this->getTransactions($order['paypal_iframe_order_id']);
+ $order['captured'] = $this->getTotalCaptured($order['paypal_iframe_order_id']);
+ return $order;
+ } else {
+ return false;
+ }
+ }
+
+ public function call($data) {
+
+ if ($this->config->get('payment_pp_pro_iframe_test') == 1) {
+ $api_endpoint = 'https://api-3t.sandbox.paypal.com/nvp';
+ } else {
+ $api_endpoint = 'https://api-3t.paypal.com/nvp';
+ }
+
+ $settings = array(
+ 'USER' => $this->config->get('payment_pp_pro_iframe_user'),
+ 'PWD' => $this->config->get('payment_pp_pro_iframe_password'),
+ 'SIGNATURE' => $this->config->get('payment_pp_pro_iframe_sig'),
+ 'VERSION' => '84',
+ 'BUTTONSOURCE' => 'WM_PRO_OPENCART_UK_' . VERSION,
+ );
+
+ $this->log($data, 'Call data');
+
+ $defaults = array(
+ CURLOPT_POST => 1,
+ CURLOPT_HEADER => 0,
+ CURLOPT_URL => $api_endpoint,
+ CURLOPT_USERAGENT => "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.1) Gecko/20061204 Firefox/2.0.0.1",
+ CURLOPT_FRESH_CONNECT => 1,
+ CURLOPT_RETURNTRANSFER => 1,
+ CURLOPT_FORBID_REUSE => 1,
+ CURLOPT_TIMEOUT => 0,
+ CURLOPT_SSL_VERIFYPEER => 0,
+ CURLOPT_SSL_VERIFYHOST => 0,
+ CURLOPT_POSTFIELDS => http_build_query(array_merge($data, $settings), '', "&")
+ );
+
+ $ch = curl_init();
+
+ curl_setopt_array($ch, $defaults);
+
+ if (!$result = curl_exec($ch)) {
+
+ $log_data = array(
+ 'curl_error' => curl_error($ch),
+ 'curl_errno' => curl_errno($ch)
+ );
+
+ $this->log($log_data, 'CURL failed');
+
+ return false;
+ }
+
+ $this->log($result, 'Result');
+
+ curl_close($ch);
+
+ return $this->cleanReturn($result);
+ }
+
+ public function updateOrder($capture_status, $order_id) {
+ $this->db->query("UPDATE `" . DB_PREFIX . "paypal_iframe_order` SET `date_modified` = now(), `capture_status` = '" . $this->db->escape($capture_status) . "' WHERE `order_id` = '" . (int)$order_id . "'");
+ }
+
+ public function updateTransaction($transaction) {
+ $this->db->query("
+ UPDATE " . DB_PREFIX . "paypal_iframe_order_transaction
+ SET paypal_iframe_order_id = " . (int)$transaction['paypal_iframe_order_id'] . ",
+ transaction_id = '" . $this->db->escape($transaction['transaction_id']) . "',
+ parent_id = '" . $this->db->escape($transaction['parent_id']) . "',
+ date_added = '" . $this->db->escape($transaction['date_added']) . "',
+ note = '" . $this->db->escape($transaction['note']) . "',
+ msgsubid = '" . $this->db->escape($transaction['msgsubid']) . "',
+ receipt_id = '" . $this->db->escape($transaction['receipt_id']) . "',
+ payment_type = '" . $this->db->escape($transaction['payment_type']) . "',
+ payment_status = '" . $this->db->escape($transaction['payment_status']) . "',
+ pending_reason = '" . $this->db->escape($transaction['pending_reason']) . "',
+ transaction_entity = '" . $this->db->escape($transaction['transaction_entity']) . "',
+ amount = '" . $this->db->escape($transaction['amount']) . "',
+ debug_data = '" . $this->db->escape($transaction['debug_data']) . "',
+ call_data = '" . $this->db->escape($transaction['call_data']) . "'
+ WHERE paypal_iframe_order_transaction_id = " . (int)$transaction['paypal_iframe_order_transaction_id'] . "
+ ");
+ }
+
+ public function addTransaction($transaction_data, $request_data = array()) {
+ $this->db->query("INSERT INTO `" . DB_PREFIX . "paypal_iframe_order_transaction` SET `paypal_iframe_order_id` = '" . (int)$transaction_data['paypal_iframe_order_id'] . "', `transaction_id` = '" . $this->db->escape($transaction_data['transaction_id']) . "', `parent_id` = '" . $this->db->escape($transaction_data['parent_id']) . "', `date_added` = NOW(), `note` = '" . $this->db->escape($transaction_data['note']) . "', `msgsubid` = '" . $this->db->escape($transaction_data['msgsubid']) . "', `receipt_id` = '" . $this->db->escape($transaction_data['receipt_id']) . "', `payment_type` = '" . $this->db->escape($transaction_data['payment_type']) . "', `payment_status` = '" . $this->db->escape($transaction_data['payment_status']) . "', `pending_reason` = '" . $this->db->escape($transaction_data['pending_reason']) . "', `transaction_entity` = '" . $this->db->escape($transaction_data['transaction_entity']) . "', `amount` = '" . (float)$transaction_data['amount'] . "', `debug_data` = '" . $this->db->escape($transaction_data['debug_data']) . "'");
+
+ $paypal_iframe_order_transaction_id = $this->db->getLastId();
+
+ if ($request_data) {
+ $serialized_data = json_encode($request_data);
+
+ $this->db->query("
+ UPDATE " . DB_PREFIX . "paypal_iframe_order_transaction
+ SET call_data = '" . $this->db->escape($serialized_data) . "'
+ WHERE paypal_iframe_order_transaction_id = " . (int)$paypal_iframe_order_transaction_id . "
+ LIMIT 1
+ ");
+ }
+
+ return $paypal_iframe_order_transaction_id;
+ }
+
+ public function log($data, $title = null) {
+ if ($this->config->get('payment_pp_pro_iframe_debug')) {
+ $log = new Log('pp_pro_iframe.log');
+ $log->write($title . ': ' . json_encode($data));
+ }
+ }
+
+ public function getTransaction($transaction_id) {
+ $call_data = array(
+ 'METHOD' => 'GetTransactionDetails',
+ 'TRANSACTIONID' => $transaction_id,
+ );
+
+ return $this->call($call_data);
+ }
+
+ public function getOrderId($transaction_id) {
+ $qry = $this->db->query("SELECT `o`.`order_id` FROM `" . DB_PREFIX . "paypal_iframe_order_transaction` `ot` LEFT JOIN `" . DB_PREFIX . "paypal_iframe_order` `o` ON `o`.`paypal_iframe_order_id` = `ot`.`paypal_iframe_order_id` WHERE `ot`.`transaction_id` = '" . $this->db->escape($transaction_id) . "' LIMIT 1");
+
+ if ($qry->num_rows) {
+ return $qry->row['order_id'];
+ } else {
+ return false;
+ }
+ }
+
+ public function updateAuthorizationId($paypal_iframe_order_id, $authorization_id) {
+ $this->db->query("
+ UPDATE `" . DB_PREFIX . "paypal_iframe_order`
+ SET `authorization_id` = '" . $this->db->escape($authorization_id) . "'
+ WHERE `paypal_iframe_order_id` = '" . $this->db->escape($paypal_iframe_order_id) . "'
+ ");
+ }
+
+ public function updateRefundTransaction($transaction_id, $transaction_type) {
+ $this->db->query("UPDATE `" . DB_PREFIX . "paypal_iframe_order_transaction` SET `payment_status` = '" . $this->db->escape($transaction_type) . "' WHERE `transaction_id` = '" . $this->db->escape($transaction_id) . "' LIMIT 1");
+ }
+
+ public function getFailedTransaction($paypl_iframe_order_transaction_id) {
+ $result = $this->db->query("
+ SELECT *
+ FROM " . DB_PREFIX . "paypal_iframe_order_transaction
+ WHERE paypal_iframe_order_transaction_id = " . (int)$paypl_iframe_order_transaction_id . "
+ ")->row;
+
+ if ($result) {
+ return $result;
+ } else {
+ return false;
+ }
+ }
+
+ public function getLocalTransaction($transaction_id) {
+ $result = $this->db->query("
+ SELECT *
+ FROM " . DB_PREFIX . "paypal_iframe_order_transaction
+ WHERE transaction_id = '" . $this->db->escape($transaction_id) . "'
+ ")->row;
+
+ if ($result) {
+ return $result;
+ } else {
+ return false;
+ }
+ }
+
+ protected function cleanReturn($data) {
+ $data = explode('&', $data);
+
+ $arr = array();
+
+ foreach ($data as $k => $v) {
+ $tmp = explode('=', $v);
+ $arr[$tmp[0]] = urldecode($tmp[1]);
+ }
+
+ return $arr;
+ }
+} \ No newline at end of file
diff --git a/public/admin/model/extension/payment/realex.php b/public/admin/model/extension/payment/realex.php
new file mode 100644
index 0000000..d2b7a7a
--- /dev/null
+++ b/public/admin/model/extension/payment/realex.php
@@ -0,0 +1,265 @@
+<?php
+class ModelExtensionPaymentRealex extends Model {
+ public function install() {
+ $this->db->query("
+ CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "realex_order` (
+ `realex_order_id` INT(11) NOT NULL AUTO_INCREMENT,
+ `order_id` INT(11) NOT NULL,
+ `order_ref` CHAR(50) NOT NULL,
+ `order_ref_previous` CHAR(50) NOT NULL,
+ `pasref` VARCHAR(50) NOT NULL,
+ `pasref_previous` VARCHAR(50) NOT NULL,
+ `date_added` DATETIME NOT NULL,
+ `date_modified` DATETIME NOT NULL,
+ `capture_status` INT(1) DEFAULT NULL,
+ `void_status` INT(1) DEFAULT NULL,
+ `settle_type` INT(1) DEFAULT NULL,
+ `rebate_status` INT(1) DEFAULT NULL,
+ `currency_code` CHAR(3) NOT NULL,
+ `authcode` VARCHAR(30) NOT NULL,
+ `account` VARCHAR(30) NOT NULL,
+ `total` DECIMAL( 10, 2 ) NOT NULL,
+ PRIMARY KEY (`realex_order_id`)
+ ) ENGINE=MyISAM DEFAULT COLLATE=utf8_general_ci;");
+
+ $this->db->query("
+ CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "realex_order_transaction` (
+ `realex_order_transaction_id` INT(11) NOT NULL AUTO_INCREMENT,
+ `realex_order_id` INT(11) NOT NULL,
+ `date_added` DATETIME NOT NULL,
+ `type` ENUM('auth', 'payment', 'rebate', 'void') DEFAULT NULL,
+ `amount` DECIMAL( 10, 2 ) NOT NULL,
+ PRIMARY KEY (`realex_order_transaction_id`)
+ ) ENGINE=MyISAM DEFAULT COLLATE=utf8_general_ci;");
+ }
+
+ public function void($order_id) {
+ $realex_order = $this->getOrder($order_id);
+
+ if (!empty($realex_order)) {
+ $timestamp = strftime("%Y%m%d%H%M%S");
+ $merchant_id = $this->config->get('payment_realex_merchant_id');
+ $secret = $this->config->get('payment_realex_secret');
+
+ $this->logger('Void hash construct: ' . $timestamp . '.' . $merchant_id . '.' . $realex_order['order_ref'] . '...');
+
+ $tmp = $timestamp . '.' . $merchant_id . '.' . $realex_order['order_ref'] . '...';
+ $hash = sha1($tmp);
+ $tmp = $hash . '.' . $secret;
+ $hash = sha1($tmp);
+
+ $xml = '';
+ $xml .= '<request type="void" timestamp="' . $timestamp . '">';
+ $xml .= '<merchantid>' . $merchant_id . '</merchantid>';
+ $xml .= '<account>' . $realex_order['account'] . '</account>';
+ $xml .= '<orderid>' . $realex_order['order_ref'] . '</orderid>';
+ $xml .= '<pasref>' . $realex_order['pasref'] . '</pasref>';
+ $xml .= '<authcode>' . $realex_order['authcode'] . '</authcode>';
+ $xml .= '<sha1hash>' . $hash . '</sha1hash>';
+ $xml .= '</request>';
+
+ $this->logger('Void XML request:\r\n' . print_r(simplexml_load_string($xml), 1));
+
+ $ch = curl_init();
+ curl_setopt($ch, CURLOPT_URL, "https://epage.payandshop.com/epage-remote.cgi");
+ curl_setopt($ch, CURLOPT_POST, 1);
+ curl_setopt($ch, CURLOPT_USERAGENT, "OpenCart " . VERSION);
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
+ curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);
+ curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
+ $response = curl_exec ($ch);
+ curl_close ($ch);
+
+ return simplexml_load_string($response);
+ } else {
+ return false;
+ }
+ }
+
+ public function updateVoidStatus($realex_order_id, $status) {
+ $this->db->query("UPDATE `" . DB_PREFIX . "realex_order` SET `void_status` = '" . (int)$status . "' WHERE `realex_order_id` = '" . (int)$realex_order_id . "'");
+ }
+
+ public function capture($order_id, $amount) {
+ $realex_order = $this->getOrder($order_id);
+
+ if (!empty($realex_order) && $realex_order['capture_status'] == 0) {
+ $timestamp = strftime("%Y%m%d%H%M%S");
+ $merchant_id = $this->config->get('payment_realex_merchant_id');
+ $secret = $this->config->get('payment_realex_secret');
+
+ if ($realex_order['settle_type'] == 2) {
+ $this->logger('Capture hash construct: ' . $timestamp . '.' . $merchant_id . '.' . $realex_order['order_ref'] . '.' . (int)round($amount*100) . '.' . (string)$realex_order['currency_code'] . '.');
+
+ $tmp = $timestamp . '.' . $merchant_id . '.' . $realex_order['order_ref'] . '.' . (int)round($amount*100) . '.' . (string)$realex_order['currency_code'] . '.';
+ $hash = sha1($tmp);
+ $tmp = $hash . '.' . $secret;
+ $hash = sha1($tmp);
+
+ $settle_type = 'multisettle';
+ $xml_amount = '<amount currency="' . (string)$realex_order['currency_code'] . '">' . (int)round($amount*100) . '</amount>';
+ } else {
+ //$this->logger('Capture hash construct: ' . $timestamp . '.' . $merchant_id . '.' . $realex_order['order_ref'] . '...');
+ $this->logger('Capture hash construct: ' . $timestamp . '.' . $merchant_id . '.' . $realex_order['order_ref'] . '.' . (int)round($amount*100) . '.' . (string)$realex_order['currency_code'] . '.');
+
+ $tmp = $timestamp . '.' . $merchant_id . '.' . $realex_order['order_ref'] . '.' . (int)round($amount*100) . '.' . (string)$realex_order['currency_code'] . '.';
+ $hash = sha1($tmp);
+ $tmp = $hash . '.' . $secret;
+ $hash = sha1($tmp);
+
+ $settle_type = 'settle';
+ $xml_amount = '<amount currency="' . (string)$realex_order['currency_code'] . '">' . (int)round($amount*100) . '</amount>';
+ }
+
+ $xml = '';
+ $xml .= '<request type="' . $settle_type . '" timestamp="' . $timestamp . '">';
+ $xml .= '<merchantid>' . $merchant_id . '</merchantid>';
+ $xml .= '<account>' . $realex_order['account'] . '</account>';
+ $xml .= '<orderid>' . $realex_order['order_ref'] . '</orderid>';
+ $xml .= $xml_amount;
+ $xml .= '<pasref>' . $realex_order['pasref'] . '</pasref>';
+ $xml .= '<autosettle flag="1" />';
+ $xml .= '<authcode>' . $realex_order['authcode'] . '</authcode>';
+ $xml .= '<sha1hash>' . $hash . '</sha1hash>';
+ $xml .= '</request>';
+
+ $this->logger('Settle XML request:\r\n' . print_r(simplexml_load_string($xml), 1));
+
+ $ch = curl_init();
+ curl_setopt($ch, CURLOPT_URL, "https://epage.payandshop.com/epage-remote.cgi");
+ curl_setopt($ch, CURLOPT_POST, 1);
+ curl_setopt($ch, CURLOPT_USERAGENT, "OpenCart " . VERSION);
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
+ curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);
+ curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
+ $response = curl_exec ($ch);
+ curl_close ($ch);
+
+ return simplexml_load_string($response);
+ } else {
+ return false;
+ }
+ }
+
+ public function updateCaptureStatus($realex_order_id, $status) {
+ $this->db->query("UPDATE `" . DB_PREFIX . "realex_order` SET `capture_status` = '" . (int)$status . "' WHERE `realex_order_id` = '" . (int)$realex_order_id . "'");
+ }
+
+ public function updateForRebate($realex_order_id, $pas_ref, $order_ref) {
+ $this->db->query("UPDATE `" . DB_PREFIX . "realex_order` SET `order_ref_previous` = '_multisettle_" . $this->db->escape($order_ref) . "', `pasref_previous` = '" . $this->db->escape($pas_ref) . "' WHERE `realex_order_id` = '" . (int)$realex_order_id . "' LIMIT 1");
+ }
+
+ public function rebate($order_id, $amount) {
+ $realex_order = $this->getOrder($order_id);
+
+ if (!empty($realex_order) && $realex_order['rebate_status'] != 1) {
+ $timestamp = strftime("%Y%m%d%H%M%S");
+ $merchant_id = $this->config->get('payment_realex_merchant_id');
+ $secret = $this->config->get('payment_realex_secret');
+
+ if ($realex_order['settle_type'] == 2) {
+ $order_ref = '_multisettle_' . $realex_order['order_ref'];
+
+ if (empty($realex_order['pasref_previous'])) {
+ $pas_ref = $realex_order['pasref'];
+ } else {
+ $pas_ref = $realex_order['pasref_previous'];
+ }
+ } else {
+ $order_ref = $realex_order['order_ref'];
+ $pas_ref = $realex_order['pasref'];
+ }
+
+ $this->logger('Rebate hash construct: ' . $timestamp . '.' . $merchant_id . '.' . $order_ref . '.' . (int)round($amount*100) . '.' . $realex_order['currency_code'] . '.');
+
+ $tmp = $timestamp . '.' . $merchant_id . '.' . $order_ref . '.' . (int)round($amount*100) . '.' . $realex_order['currency_code'] . '.';
+ $hash = sha1($tmp);
+ $tmp = $hash . '.' . $secret;
+ $hash = sha1($tmp);
+
+ $rebate_hash = sha1($this->config->get('payment_realex_rebate_password'));
+
+ $xml = '';
+ $xml .= '<request type="rebate" timestamp="' . $timestamp . '">';
+ $xml .= '<merchantid>' . $merchant_id . '</merchantid>';
+ $xml .= '<account>' . $realex_order['account'] . '</account>';
+ $xml .= '<orderid>' . $order_ref . '</orderid>';
+ $xml .= '<pasref>' . $pas_ref . '</pasref>';
+ $xml .= '<authcode>' . $realex_order['authcode'] . '</authcode>';
+ $xml .= '<amount currency="' . (string)$realex_order['currency_code'] . '">' . (int)round($amount*100) . '</amount>';
+ $xml .= '<refundhash>' . $rebate_hash . '</refundhash>';
+ $xml .= '<sha1hash>' . $hash . '</sha1hash>';
+ $xml .= '</request>';
+
+ $this->logger('Rebate XML request:\r\n' . print_r(simplexml_load_string($xml), 1));
+
+ $ch = curl_init();
+ curl_setopt($ch, CURLOPT_URL, "https://epage.payandshop.com/epage-remote.cgi");
+ curl_setopt($ch, CURLOPT_POST, 1);
+ curl_setopt($ch, CURLOPT_USERAGENT, "OpenCart " . VERSION);
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
+ curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);
+ curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
+ $response = curl_exec ($ch);
+ curl_close ($ch);
+
+ return simplexml_load_string($response);
+ } else {
+ return false;
+ }
+ }
+
+ public function updateRebateStatus($realex_order_id, $status) {
+ $this->db->query("UPDATE `" . DB_PREFIX . "realex_order` SET `rebate_status` = '" . (int)$status . "' WHERE `realex_order_id` = '" . (int)$realex_order_id . "'");
+ }
+
+ public function getOrder($order_id) {
+ $this->logger('getOrder - ' . $order_id);
+
+ $qry = $this->db->query("SELECT * FROM `" . DB_PREFIX . "realex_order` WHERE `order_id` = '" . (int)$order_id . "' LIMIT 1");
+
+ if ($qry->num_rows) {
+ $order = $qry->row;
+ $order['transactions'] = $this->getTransactions($order['realex_order_id']);
+
+ $this->logger(print_r($order, 1));
+
+ return $order;
+ } else {
+ return false;
+ }
+ }
+
+ private function getTransactions($realex_order_id) {
+ $qry = $this->db->query("SELECT * FROM `" . DB_PREFIX . "realex_order_transaction` WHERE `realex_order_id` = '" . (int)$realex_order_id . "'");
+
+ if ($qry->num_rows) {
+ return $qry->rows;
+ } else {
+ return false;
+ }
+ }
+
+ public function addTransaction($realex_order_id, $type, $total) {
+ $this->db->query("INSERT INTO `" . DB_PREFIX . "realex_order_transaction` SET `realex_order_id` = '" . (int)$realex_order_id . "', `date_added` = now(), `type` = '" . $this->db->escape($type) . "', `amount` = '" . (float)$total . "'");
+ }
+
+ public function logger($message) {
+ if ($this->config->get('payment_realex_debug') == 1) {
+ $log = new Log('realex.log');
+ $log->write($message);
+ }
+ }
+
+ public function getTotalCaptured($realex_order_id) {
+ $query = $this->db->query("SELECT SUM(`amount`) AS `total` FROM `" . DB_PREFIX . "realex_order_transaction` WHERE `realex_order_id` = '" . (int)$realex_order_id . "' AND (`type` = 'payment' OR `type` = 'rebate')");
+
+ return (float)$query->row['total'];
+ }
+
+ public function getTotalRebated($realex_order_id) {
+ $query = $this->db->query("SELECT SUM(`amount`) AS `total` FROM `" . DB_PREFIX . "realex_order_transaction` WHERE `realex_order_id` = '" . (int)$realex_order_id . "' AND 'rebate'");
+
+ return (float)$query->row['total'];
+ }
+} \ No newline at end of file
diff --git a/public/admin/model/extension/payment/realex_remote.php b/public/admin/model/extension/payment/realex_remote.php
new file mode 100644
index 0000000..be40791
--- /dev/null
+++ b/public/admin/model/extension/payment/realex_remote.php
@@ -0,0 +1,260 @@
+<?php
+class ModelExtensionPaymentRealexRemote extends Model {
+ public function install() {
+ $this->db->query("
+ CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "realex_remote_order` (
+ `realex_remote_order_id` INT(11) NOT NULL AUTO_INCREMENT,
+ `order_id` INT(11) NOT NULL,
+ `order_ref` CHAR(50) NOT NULL,
+ `order_ref_previous` CHAR(50) NOT NULL,
+ `pasref` VARCHAR(50) NOT NULL,
+ `pasref_previous` VARCHAR(50) NOT NULL,
+ `date_added` DATETIME NOT NULL,
+ `date_modified` DATETIME NOT NULL,
+ `capture_status` INT(1) DEFAULT NULL,
+ `void_status` INT(1) DEFAULT NULL,
+ `settle_type` INT(1) DEFAULT NULL,
+ `rebate_status` INT(1) DEFAULT NULL,
+ `currency_code` CHAR(3) NOT NULL,
+ `authcode` VARCHAR(30) NOT NULL,
+ `account` VARCHAR(30) NOT NULL,
+ `total` DECIMAL( 10, 2 ) NOT NULL,
+ PRIMARY KEY (`realex_remote_order_id`)
+ ) ENGINE=MyISAM DEFAULT COLLATE=utf8_general_ci;");
+
+ $this->db->query("
+ CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "realex_remote_order_transaction` (
+ `realex_remote_order_transaction_id` INT(11) NOT NULL AUTO_INCREMENT,
+ `realex_remote_order_id` INT(11) NOT NULL,
+ `date_added` DATETIME NOT NULL,
+ `type` ENUM('auth', 'payment', 'rebate', 'void') DEFAULT NULL,
+ `amount` DECIMAL( 10, 2 ) NOT NULL,
+ PRIMARY KEY (`realex_remote_order_transaction_id`)
+ ) ENGINE=MyISAM DEFAULT COLLATE=utf8_general_ci;");
+ }
+
+ public function void($order_id) {
+ $realex_order = $this->getOrder($order_id);
+
+ if (!empty($realex_order)) {
+ $timestamp = strftime("%Y%m%d%H%M%S");
+ $merchant_id = $this->config->get('payment_realex_remote_merchant_id');
+ $secret = $this->config->get('payment_realex_remote_secret');
+
+ $this->logger('Void hash construct: ' . $timestamp . '.' . $merchant_id . '.' . $realex_order['order_ref'] . '...');
+
+ $tmp = $timestamp . '.' . $merchant_id . '.' . $realex_order['order_ref'] . '...';
+ $hash = sha1($tmp);
+ $tmp = $hash . '.' . $secret;
+ $hash = sha1($tmp);
+
+ $xml = '';
+ $xml .= '<request type="void" timestamp="' . $timestamp . '">';
+ $xml .= '<merchantid>' . $merchant_id . '</merchantid>';
+ $xml .= '<account>' . $realex_order['account'] . '</account>';
+ $xml .= '<orderid>' . $realex_order['order_ref'] . '</orderid>';
+ $xml .= '<pasref>' . $realex_order['pasref'] . '</pasref>';
+ $xml .= '<authcode>' . $realex_order['authcode'] . '</authcode>';
+ $xml .= '<sha1hash>' . $hash . '</sha1hash>';
+ $xml .= '</request>';
+
+ $this->logger('Void XML request:\r\n' . print_r(simplexml_load_string($xml), 1));
+
+ $ch = curl_init();
+ curl_setopt($ch, CURLOPT_URL, "https://epage.payandshop.com/epage-remote.cgi");
+ curl_setopt($ch, CURLOPT_POST, 1);
+ curl_setopt($ch, CURLOPT_USERAGENT, "OpenCart " . VERSION);
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
+ curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);
+ curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
+ $response = curl_exec ($ch);
+ curl_close ($ch);
+
+ return simplexml_load_string($response);
+ } else {
+ return false;
+ }
+ }
+
+ public function updateVoidStatus($realex_remote_order_id, $status) {
+ $this->db->query("UPDATE `" . DB_PREFIX . "realex_remote_order` SET `void_status` = '" . (int)$status . "' WHERE `realex_remote_order_id` = '" . (int)$realex_remote_order_id . "'");
+ }
+
+ public function capture($order_id, $amount) {
+ $realex_order = $this->getOrder($order_id);
+
+ if (!empty($realex_order) && $realex_order['capture_status'] == 0) {
+ $timestamp = strftime("%Y%m%d%H%M%S");
+ $merchant_id = $this->config->get('payment_realex_remote_merchant_id');
+ $secret = $this->config->get('payment_realex_remote_secret');
+
+ if ($realex_order['settle_type'] == 2) {
+ $this->logger('Capture hash construct: ' . $timestamp . '.' . $merchant_id . '.' . $realex_order['order_ref'] . '.' . (int)round($amount*100) . '.' . (string)$realex_order['currency_code'] . '.');
+
+ $tmp = $timestamp . '.' . $merchant_id . '.' . $realex_order['order_ref'] . '.' . (int)round($amount*100) . '.' . (string)$realex_order['currency_code'] . '.';
+ $hash = sha1($tmp);
+ $tmp = $hash . '.' . $secret;
+ $hash = sha1($tmp);
+
+ $settle_type = 'multisettle';
+ $xml_amount = '<amount currency="' . (string)$realex_order['currency_code'] . '">' . (int)round($amount*100) . '</amount>';
+ } else {
+ //$this->logger('Capture hash construct: ' . $timestamp . '.' . $merchant_id . '.' . $realex_order['order_ref'] . '...');
+ $this->logger('Capture hash construct: ' . $timestamp . '.' . $merchant_id . '.' . $realex_order['order_ref'] . '.' . (int)round($amount*100) . '.' . (string)$realex_order['currency_code'] . '.');
+
+ $tmp = $timestamp . '.' . $merchant_id . '.' . $realex_order['order_ref'] . '.' . (int)round($amount*100) . '.' . (string)$realex_order['currency_code'] . '.';
+ $hash = sha1($tmp);
+ $tmp = $hash . '.' . $secret;
+ $hash = sha1($tmp);
+
+ $settle_type = 'settle';
+ $xml_amount = '<amount currency="' . (string)$realex_order['currency_code'] . '">' . (int)round($amount*100) . '</amount>';
+ }
+
+ $xml = '';
+ $xml .= '<request type="' . $settle_type . '" timestamp="' . $timestamp . '">';
+ $xml .= '<merchantid>' . $merchant_id . '</merchantid>';
+ $xml .= '<account>' . $realex_order['account'] . '</account>';
+ $xml .= '<orderid>' . $realex_order['order_ref'] . '</orderid>';
+ $xml .= $xml_amount;
+ $xml .= '<pasref>' . $realex_order['pasref'] . '</pasref>';
+ $xml .= '<authcode>' . $realex_order['authcode'] . '</authcode>';
+ $xml .= '<sha1hash>' . $hash . '</sha1hash>';
+ $xml .= '</request>';
+
+ $this->logger('Settle XML request:\r\n' . print_r(simplexml_load_string($xml), 1));
+
+ $ch = curl_init();
+ curl_setopt($ch, CURLOPT_URL, "https://epage.payandshop.com/epage-remote.cgi");
+ curl_setopt($ch, CURLOPT_POST, 1);
+ curl_setopt($ch, CURLOPT_USERAGENT, "OpenCart " . VERSION);
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
+ curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);
+ curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
+ $response = curl_exec ($ch);
+ curl_close ($ch);
+
+ return simplexml_load_string($response);
+ } else {
+ return false;
+ }
+ }
+
+ public function updateCaptureStatus($realex_remote_order_id, $status) {
+ $this->db->query("UPDATE `" . DB_PREFIX . "realex_remote_order` SET `capture_status` = '" . (int)$status . "' WHERE `realex_remote_order_id` = '" . (int)$realex_remote_order_id . "'");
+ }
+
+ public function updateForRebate($realex_remote_order_id, $pas_ref, $order_ref) {
+ $this->db->query("UPDATE `" . DB_PREFIX . "realex_remote_order` SET `order_ref_previous` = '_multisettle_" . $this->db->escape($order_ref) . "', `pasref_previous` = '" . $this->db->escape($pas_ref) . "' WHERE `realex_remote_order_id` = '" . (int)$realex_remote_order_id . "' LIMIT 1");
+ }
+
+ public function rebate($order_id, $amount) {
+ $realex_order = $this->getOrder($order_id);
+
+ if (!empty($realex_order) && $realex_order['rebate_status'] != 1) {
+ $timestamp = strftime("%Y%m%d%H%M%S");
+ $merchant_id = $this->config->get('payment_realex_remote_merchant_id');
+ $secret = $this->config->get('payment_realex_remote_secret');
+
+ if ($realex_order['settle_type'] == 2) {
+ $order_ref = '_multisettle_' . $realex_order['order_ref'];
+
+ if (empty($realex_order['pasref_previous'])) {
+ $pas_ref = $realex_order['pasref'];
+ } else {
+ $pas_ref = $realex_order['pasref_previous'];
+ }
+ } else {
+ $order_ref = $realex_order['order_ref'];
+ $pas_ref = $realex_order['pasref'];
+ }
+
+ $this->logger('Rebate hash construct: ' . $timestamp . '.' . $merchant_id . '.' . $order_ref . '.' . (int)round($amount*100) . '.' . $realex_order['currency_code'] . '.');
+
+ $tmp = $timestamp . '.' . $merchant_id . '.' . $order_ref . '.' . (int)round($amount*100) . '.' . $realex_order['currency_code'] . '.';
+ $hash = sha1($tmp);
+ $tmp = $hash . '.' . $secret;
+ $hash = sha1($tmp);
+
+ $rebatehash = sha1($this->config->get('payment_realex_remote_rebate_password'));
+
+ $xml = '';
+ $xml .= '<request type="rebate" timestamp="' . $timestamp . '">';
+ $xml .= '<merchantid>' . $merchant_id . '</merchantid>';
+ $xml .= '<account>' . $realex_order['account'] . '</account>';
+ $xml .= '<orderid>' . $order_ref . '</orderid>';
+ $xml .= '<pasref>' . $pas_ref . '</pasref>';
+ $xml .= '<authcode>' . $realex_order['authcode'] . '</authcode>';
+ $xml .= '<amount currency="' . (string)$realex_order['currency_code'] . '">' . (int)round($amount*100) . '</amount>';
+ $xml .= '<refundhash>' . $rebatehash . '</refundhash>';
+ $xml .= '<sha1hash>' . $hash . '</sha1hash>';
+ $xml .= '</request>';
+
+ $this->logger('Rebate XML request:\r\n' . print_r(simplexml_load_string($xml), 1));
+
+ $ch = curl_init();
+ curl_setopt($ch, CURLOPT_URL, "https://epage.payandshop.com/epage-remote.cgi");
+ curl_setopt($ch, CURLOPT_POST, 1);
+ curl_setopt($ch, CURLOPT_USERAGENT, "OpenCart " . VERSION);
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
+ curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);
+ curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
+ $response = curl_exec ($ch);
+ curl_close ($ch);
+
+ return simplexml_load_string($response);
+ } else {
+ return false;
+ }
+ }
+
+ public function updateRebateStatus($realex_remote_order_id, $status) {
+ $this->db->query("UPDATE `" . DB_PREFIX . "realex_remote_order` SET `rebate_status` = '" . (int)$status . "' WHERE `realex_remote_order_id` = '" . (int)$realex_remote_order_id . "'");
+ }
+
+ public function getOrder($order_id) {
+ $qry = $this->db->query("SELECT * FROM `" . DB_PREFIX . "realex_remote_order` WHERE `order_id` = '" . (int)$order_id . "' LIMIT 1");
+
+ if ($qry->num_rows) {
+ $order = $qry->row;
+ $order['transactions'] = $this->getTransactions($order['realex_remote_order_id']);
+
+ return $order;
+ } else {
+ return false;
+ }
+ }
+
+ private function getTransactions($realex_remote_order_id) {
+ $qry = $this->db->query("SELECT * FROM `" . DB_PREFIX . "realex_remote_order_transaction` WHERE `realex_remote_order_id` = '" . (int)$realex_remote_order_id . "'");
+
+ if ($qry->num_rows) {
+ return $qry->rows;
+ } else {
+ return false;
+ }
+ }
+
+ public function addTransaction($realex_remote_order_id, $type, $total) {
+ $this->db->query("INSERT INTO `" . DB_PREFIX . "realex_remote_order_transaction` SET `realex_remote_order_id` = '" . (int)$realex_remote_order_id . "', `date_added` = now(), `type` = '" . $this->db->escape($type) . "', `amount` = '" . (float)$total . "'");
+ }
+
+ public function logger($message) {
+ if ($this->config->get('payment_realex_remote_debug') == 1) {
+ $log = new Log('realex_remote.log');
+ $log->write($message);
+ }
+ }
+
+ public function getTotalCaptured($realex_order_id) {
+ $query = $this->db->query("SELECT SUM(`amount`) AS `total` FROM `" . DB_PREFIX . "realex_remote_order_transaction` WHERE `realex_remote_order_id` = '" . (int)$realex_order_id . "' AND (`type` = 'payment' OR `type` = 'rebate')");
+
+ return (float)$query->row['total'];
+ }
+
+ public function getTotalRebated($realex_order_id) {
+ $query = $this->db->query("SELECT SUM(`amount`) AS `total` FROM `" . DB_PREFIX . "realex_remote_order_transaction` WHERE `realex_remote_order_id` = '" . (int)$realex_order_id . "' AND 'rebate'");
+
+ return (double)$query->row['total'];
+ }
+} \ No newline at end of file
diff --git a/public/admin/model/extension/payment/sagepay_direct.php b/public/admin/model/extension/payment/sagepay_direct.php
new file mode 100644
index 0000000..370e4f0
--- /dev/null
+++ b/public/admin/model/extension/payment/sagepay_direct.php
@@ -0,0 +1,265 @@
+<?php
+class ModelExtensionPaymentSagepayDirect extends Model {
+ public function install() {
+ $this->db->query("
+ CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "sagepay_direct_order` (
+ `sagepay_direct_order_id` INT(11) NOT NULL AUTO_INCREMENT,
+ `order_id` INT(11) NOT NULL,
+ `VPSTxId` VARCHAR(50),
+ `VendorTxCode` VARCHAR(50) NOT NULL,
+ `SecurityKey` CHAR(50) NOT NULL,
+ `TxAuthNo` INT(50),
+ `date_added` DATETIME NOT NULL,
+ `date_modified` DATETIME NOT NULL,
+ `release_status` INT(1) DEFAULT NULL,
+ `void_status` INT(1) DEFAULT NULL,
+ `settle_type` INT(1) DEFAULT NULL,
+ `rebate_status` INT(1) DEFAULT NULL,
+ `currency_code` CHAR(3) NOT NULL,
+ `total` DECIMAL( 10, 2 ) NOT NULL,
+ `card_id` INT(11),
+ PRIMARY KEY (`sagepay_direct_order_id`)
+ ) ENGINE=MyISAM DEFAULT COLLATE=utf8_general_ci;");
+
+ $this->db->query("
+ CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "sagepay_direct_order_transaction` (
+ `sagepay_direct_order_transaction_id` INT(11) NOT NULL AUTO_INCREMENT,
+ `sagepay_direct_order_id` INT(11) NOT NULL,
+ `date_added` DATETIME NOT NULL,
+ `type` ENUM('auth', 'payment', 'rebate', 'void') DEFAULT NULL,
+ `amount` DECIMAL( 10, 2 ) NOT NULL,
+ PRIMARY KEY (`sagepay_direct_order_transaction_id`)
+ ) ENGINE=MyISAM DEFAULT COLLATE=utf8_general_ci;");
+
+ $this->db->query("
+ CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "sagepay_direct_order_recurring` (
+ `sagepay_direct_order_recurring_id` INT(11) NOT NULL AUTO_INCREMENT,
+ `order_id` INT(11) NOT NULL,
+ `order_recurring_id` INT(11) NOT NULL,
+ `VPSTxId` VARCHAR(50),
+ `VendorTxCode` VARCHAR(50) NOT NULL,
+ `SecurityKey` CHAR(50) NOT NULL,
+ `TxAuthNo` INT(50),
+ `date_added` DATETIME NOT NULL,
+ `date_modified` DATETIME NOT NULL,
+ `next_payment` DATETIME NOT NULL,
+ `trial_end` datetime DEFAULT NULL,
+ `subscription_end` datetime DEFAULT NULL,
+ `currency_code` CHAR(3) NOT NULL,
+ `total` DECIMAL( 10, 2 ) NOT NULL,
+ PRIMARY KEY (`sagepay_direct_order_recurring_id`)
+ ) ENGINE=MyISAM DEFAULT COLLATE=utf8_general_ci;");
+
+ $this->db->query("
+ CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "sagepay_direct_card` (
+ `card_id` INT(11) NOT NULL AUTO_INCREMENT,
+ `customer_id` INT(11) NOT NULL,
+ `token` VARCHAR(50) NOT NULL,
+ `digits` VARCHAR(4) NOT NULL,
+ `expiry` VARCHAR(5) NOT NULL,
+ `type` VARCHAR(50) NOT NULL,
+ PRIMARY KEY (`card_id`)
+ ) ENGINE=MyISAM DEFAULT COLLATE=utf8_general_ci;");
+ }
+
+ public function uninstall() {
+ $this->db->query("DROP TABLE IF EXISTS `" . DB_PREFIX . "sagepay_direct_order`;");
+ $this->db->query("DROP TABLE IF EXISTS `" . DB_PREFIX . "sagepay_direct_order_transaction`;");
+ $this->db->query("DROP TABLE IF EXISTS `" . DB_PREFIX . "sagepay_direct_order_recurring`;");
+ $this->db->query("DROP TABLE IF EXISTS `" . DB_PREFIX . "sagepay_direct_card`;");
+ }
+
+ public function void($order_id) {
+ $sagepay_direct_order = $this->getOrder($order_id);
+
+ if (!empty($sagepay_direct_order) && $sagepay_direct_order['release_status'] == 0) {
+
+ $void_data = array();
+
+ if ($this->config->get('payment_sagepay_direct_test') == 'live') {
+ $url = 'https://live.sagepay.com/gateway/service/void.vsp';
+ $void_data['VPSProtocol'] = '3.00';
+ } elseif ($this->config->get('payment_sagepay_direct_test') == 'test') {
+ $url = 'https://test.sagepay.com/gateway/service/void.vsp';
+ $void_data['VPSProtocol'] = '3.00';
+ } elseif ($this->config->get('payment_sagepay_direct_test') == 'sim') {
+ $url = 'https://test.sagepay.com/Simulator/VSPServerGateway.asp?Service=VendorVoidTx';
+ $void_data['VPSProtocol'] = '2.23';
+ }
+
+ $void_data['TxType'] = 'VOID';
+ $void_data['Vendor'] = $this->config->get('payment_sagepay_direct_vendor');
+ $void_data['VendorTxCode'] = $sagepay_direct_order['VendorTxCode'];
+ $void_data['VPSTxId'] = $sagepay_direct_order['VPSTxId'];
+ $void_data['SecurityKey'] = $sagepay_direct_order['SecurityKey'];
+ $void_data['TxAuthNo'] = $sagepay_direct_order['TxAuthNo'];
+
+ $response_data = $this->sendCurl($url, $void_data);
+
+ return $response_data;
+ } else {
+ return false;
+ }
+ }
+
+ public function updateVoidStatus($sagepay_direct_order_id, $status) {
+ $this->db->query("UPDATE `" . DB_PREFIX . "sagepay_direct_order` SET `void_status` = '" . (int)$status . "' WHERE `sagepay_direct_order_id` = '" . (int)$sagepay_direct_order_id . "'");
+ }
+
+ public function release($order_id, $amount) {
+ $sagepay_direct_order = $this->getOrder($order_id);
+ $total_released = $this->getTotalReleased($sagepay_direct_order['sagepay_direct_order_id']);
+
+ if (!empty($sagepay_direct_order) && $sagepay_direct_order['release_status'] == 0 && ($total_released + $amount <= $sagepay_direct_order['total'])) {
+ $release_data = array();
+
+ if ($this->config->get('payment_sagepay_direct_test') == 'live') {
+ $url = 'https://live.sagepay.com/gateway/service/release.vsp';
+ $release_data['VPSProtocol'] = '3.00';
+ } elseif ($this->config->get('payment_sagepay_direct_test') == 'test') {
+ $url = 'https://test.sagepay.com/gateway/service/release.vsp';
+ $release_data['VPSProtocol'] = '3.00';
+ } elseif ($this->config->get('payment_sagepay_direct_test') == 'sim') {
+ $url = 'https://test.sagepay.com/Simulator/VSPServerGateway.asp?Service=VendorReleaseTx';
+ $release_data['VPSProtocol'] = '2.23';
+ }
+
+ $release_data['TxType'] = 'RELEASE';
+ $release_data['Vendor'] = $this->config->get('payment_sagepay_direct_vendor');
+ $release_data['VendorTxCode'] = $sagepay_direct_order['VendorTxCode'];
+ $release_data['VPSTxId'] = $sagepay_direct_order['VPSTxId'];
+ $release_data['SecurityKey'] = $sagepay_direct_order['SecurityKey'];
+ $release_data['TxAuthNo'] = $sagepay_direct_order['TxAuthNo'];
+ $release_data['Amount'] = $amount;
+
+ $response_data = $this->sendCurl($url, $release_data);
+
+ return $response_data;
+ } else {
+ return false;
+ }
+ }
+
+ public function updateReleaseStatus($sagepay_direct_order_id, $status) {
+ $this->db->query("UPDATE `" . DB_PREFIX . "sagepay_direct_order` SET `release_status` = '" . (int)$status . "' WHERE `sagepay_direct_order_id` = '" . (int)$sagepay_direct_order_id . "'");
+ }
+
+ public function rebate($order_id, $amount) {
+ $sagepay_direct_order = $this->getOrder($order_id);
+
+ if (!empty($sagepay_direct_order) && $sagepay_direct_order['rebate_status'] != 1) {
+
+ $refund_data = array();
+
+ if ($this->config->get('payment_sagepay_direct_test') == 'live') {
+ $url = 'https://live.sagepay.com/gateway/service/refund.vsp';
+ $refund_data['VPSProtocol'] = '3.00';
+ } elseif ($this->config->get('payment_sagepay_direct_test') == 'test') {
+ $url = 'https://test.sagepay.com/gateway/service/refund.vsp';
+ $refund_data['VPSProtocol'] = '3.00';
+ } elseif ($this->config->get('payment_sagepay_direct_test') == 'sim') {
+ $url = 'https://test.sagepay.com/Simulator/VSPServerGateway.asp?Service=VendorRefundTx';
+ $refund_data['VPSProtocol'] = '2.23';
+ }
+
+ $refund_data['TxType'] = 'REFUND';
+ $refund_data['Vendor'] = $this->config->get('payment_sagepay_direct_vendor');
+ $refund_data['VendorTxCode'] = $sagepay_direct_order['sagepay_direct_order_id'] . rand();
+ $refund_data['Amount'] = $amount;
+ $refund_data['Currency'] = $sagepay_direct_order['currency_code'];
+ $refund_data['Description'] = substr($this->config->get('config_name'), 0, 100);
+ $refund_data['RelatedVPSTxId'] = $sagepay_direct_order['VPSTxId'];
+ $refund_data['RelatedVendorTxCode'] = $sagepay_direct_order['VendorTxCode'];
+ $refund_data['RelatedSecurityKey'] = $sagepay_direct_order['SecurityKey'];
+ $refund_data['RelatedTxAuthNo'] = $sagepay_direct_order['TxAuthNo'];
+
+ $response_data = $this->sendCurl($url, $refund_data);
+
+ return $response_data;
+ } else {
+ return false;
+ }
+ }
+
+ public function updateRebateStatus($sagepay_direct_order_id, $status) {
+ $this->db->query("UPDATE `" . DB_PREFIX . "sagepay_direct_order` SET `rebate_status` = '" . (int)$status . "' WHERE `sagepay_direct_order_id` = '" . (int)$sagepay_direct_order_id . "'");
+ }
+
+ public function getOrder($order_id) {
+
+ $qry = $this->db->query("SELECT * FROM `" . DB_PREFIX . "sagepay_direct_order` WHERE `order_id` = '" . (int)$order_id . "' LIMIT 1");
+
+ if ($qry->num_rows) {
+ $order = $qry->row;
+ $order['transactions'] = $this->getTransactions($order['sagepay_direct_order_id']);
+
+ return $order;
+ } else {
+ return false;
+ }
+ }
+
+ private function getTransactions($sagepay_direct_order_id) {
+ $qry = $this->db->query("SELECT * FROM `" . DB_PREFIX . "sagepay_direct_order_transaction` WHERE `sagepay_direct_order_id` = '" . (int)$sagepay_direct_order_id . "'");
+
+ if ($qry->num_rows) {
+ return $qry->rows;
+ } else {
+ return false;
+ }
+ }
+
+ public function addTransaction($sagepay_direct_order_id, $type, $total) {
+ $this->db->query("INSERT INTO `" . DB_PREFIX . "sagepay_direct_order_transaction` SET `sagepay_direct_order_id` = '" . (int)$sagepay_direct_order_id . "', `date_added` = now(), `type` = '" . $this->db->escape($type) . "', `amount` = '" . (float)$total . "'");
+ }
+
+ public function getTotalReleased($sagepay_direct_order_id) {
+ $query = $this->db->query("SELECT SUM(`amount`) AS `total` FROM `" . DB_PREFIX . "sagepay_direct_order_transaction` WHERE `sagepay_direct_order_id` = '" . (int)$sagepay_direct_order_id . "' AND (`type` = 'payment' OR `type` = 'rebate')");
+
+ return (float)$query->row['total'];
+ }
+
+ public function getTotalRebated($sagepay_direct_order_id) {
+ $query = $this->db->query("SELECT SUM(`amount`) AS `total` FROM `" . DB_PREFIX . "sagepay_direct_order_transaction` WHERE `sagepay_direct_order_id` = '" . (int)$sagepay_direct_order_id . "' AND 'rebate'");
+
+ return (float)$query->row['total'];
+ }
+
+ public function sendCurl($url, $payment_data) {
+ $curl = curl_init($url);
+
+ curl_setopt($curl, CURLOPT_PORT, 443);
+ curl_setopt($curl, CURLOPT_HEADER, 0);
+ curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, 0);
+ curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
+ curl_setopt($curl, CURLOPT_FOLLOWLOCATION, false);
+ curl_setopt($curl, CURLOPT_FORBID_REUSE, 1);
+ curl_setopt($curl, CURLOPT_FRESH_CONNECT, 1);
+ curl_setopt($curl, CURLOPT_POST, 1);
+ curl_setopt($curl, CURLOPT_POSTFIELDS, http_build_query($payment_data));
+
+ $response = curl_exec($curl);
+
+ curl_close($curl);
+
+ $response_info = explode(chr(10), $response);
+
+ foreach ($response_info as $string) {
+ if (strpos($string, '=') && isset($i)) {
+ $parts = explode('=', $string, 2);
+ $data['RepeatResponseData_' . $i][trim($parts[0])] = trim($parts[1]);
+ } elseif (strpos($string, '=')) {
+ $parts = explode('=', $string, 2);
+ $data[trim($parts[0])] = trim($parts[1]);
+ }
+ }
+ return $data;
+ }
+
+ public function logger($title, $data) {
+ if ($this->config->get('payment_sagepay_direct_debug')) {
+ $log = new Log('sagepay_direct.log');
+ $log->write($title . ': ' . print_r($data, 1));
+ }
+ }
+}
diff --git a/public/admin/model/extension/payment/sagepay_server.php b/public/admin/model/extension/payment/sagepay_server.php
new file mode 100644
index 0000000..8dacbd9
--- /dev/null
+++ b/public/admin/model/extension/payment/sagepay_server.php
@@ -0,0 +1,266 @@
+<?php
+class ModelExtensionPaymentSagepayServer extends Model {
+ public function install() {
+ $this->db->query("
+ CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "sagepay_server_order` (
+ `sagepay_server_order_id` INT(11) NOT NULL AUTO_INCREMENT,
+ `order_id` INT(11) NOT NULL,
+ `customer_id` INT(11) NOT NULL,
+ `VPSTxId` VARCHAR(50),
+ `VendorTxCode` VARCHAR(50) NOT NULL,
+ `SecurityKey` CHAR(50) NOT NULL,
+ `TxAuthNo` INT(50),
+ `date_added` DATETIME NOT NULL,
+ `date_modified` DATETIME NOT NULL,
+ `release_status` INT(1) DEFAULT NULL,
+ `void_status` INT(1) DEFAULT NULL,
+ `settle_type` INT(1) DEFAULT NULL,
+ `rebate_status` INT(1) DEFAULT NULL,
+ `currency_code` CHAR(3) NOT NULL,
+ `total` DECIMAL( 10, 2 ) NOT NULL,
+ PRIMARY KEY (`sagepay_server_order_id`)
+ ) ENGINE=MyISAM DEFAULT COLLATE=utf8_general_ci;");
+
+ $this->db->query("
+ CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "sagepay_server_order_transaction` (
+ `sagepay_server_order_transaction_id` INT(11) NOT NULL AUTO_INCREMENT,
+ `sagepay_server_order_id` INT(11) NOT NULL,
+ `date_added` DATETIME NOT NULL,
+ `type` ENUM('auth', 'payment', 'rebate', 'void') DEFAULT NULL,
+ `amount` DECIMAL( 10, 2 ) NOT NULL,
+ PRIMARY KEY (`sagepay_server_order_transaction_id`)
+ ) ENGINE=MyISAM DEFAULT COLLATE=utf8_general_ci;");
+
+ $this->db->query("
+ CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "sagepay_server_order_recurring` (
+ `sagepay_server_order_recurring_id` INT(11) NOT NULL AUTO_INCREMENT,
+ `order_id` INT(11) NOT NULL,
+ `order_recurring_id` INT(11) NOT NULL,
+ `VPSTxId` VARCHAR(50),
+ `VendorTxCode` VARCHAR(50) NOT NULL,
+ `SecurityKey` CHAR(50) NOT NULL,
+ `TxAuthNo` INT(50),
+ `date_added` DATETIME NOT NULL,
+ `date_modified` DATETIME NOT NULL,
+ `next_payment` DATETIME NOT NULL,
+ `trial_end` datetime DEFAULT NULL,
+ `subscription_end` datetime DEFAULT NULL,
+ `currency_code` CHAR(3) NOT NULL,
+ `total` DECIMAL( 10, 2 ) NOT NULL,
+ PRIMARY KEY (`sagepay_server_order_recurring_id`)
+ ) ENGINE=MyISAM DEFAULT COLLATE=utf8_general_ci;");
+
+ $this->db->query("
+ CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "sagepay_server_card` (
+ `card_id` INT(11) NOT NULL AUTO_INCREMENT,
+ `customer_id` INT(11) NOT NULL,
+ `order_id` INT(11) NOT NULL,
+ `token` VARCHAR(50) NOT NULL,
+ `digits` VARCHAR(4) NOT NULL,
+ `expiry` VARCHAR(5) NOT NULL,
+ `type` VARCHAR(50) NOT NULL,
+ PRIMARY KEY (`card_id`)
+ ) ENGINE=MyISAM DEFAULT COLLATE=utf8_general_ci;");
+ }
+
+ public function uninstall() {
+ $this->db->query("DROP TABLE IF EXISTS `" . DB_PREFIX . "sagepay_server_order`;");
+ $this->db->query("DROP TABLE IF EXISTS `" . DB_PREFIX . "sagepay_server_order_transaction`;");
+ $this->db->query("DROP TABLE IF EXISTS `" . DB_PREFIX . "sagepay_server_order_recurring`;");
+ $this->db->query("DROP TABLE IF EXISTS `" . DB_PREFIX . "sagepay_server_card`;");
+ }
+
+ public function void($order_id) {
+ $sagepay_server_order = $this->getOrder($order_id);
+
+ if (!empty($sagepay_server_order) && $sagepay_server_order['release_status'] == 0) {
+
+ $void_data = array();
+
+ if ($this->config->get('payment_sagepay_server_test') == 'live') {
+ $url = 'https://live.sagepay.com/gateway/service/void.vsp';
+ $void_data['VPSProtocol'] = '3.00';
+ } elseif ($this->config->get('payment_sagepay_server_test') == 'test') {
+ $url = 'https://test.sagepay.com/gateway/service/void.vsp';
+ $void_data['VPSProtocol'] = '3.00';
+ } elseif ($this->config->get('payment_sagepay_server_test') == 'sim') {
+ $url = 'https://test.sagepay.com/Simulator/VSPServerGateway.asp?Service=VendorVoidTx';
+ $void_data['VPSProtocol'] = '2.23';
+ }
+
+ $void_data['TxType'] = 'VOID';
+ $void_data['Vendor'] = $this->config->get('payment_sagepay_server_vendor');
+ $void_data['VendorTxCode'] = $sagepay_server_order['VendorTxCode'];
+ $void_data['VPSTxId'] = $sagepay_server_order['VPSTxId'];
+ $void_data['SecurityKey'] = $sagepay_server_order['SecurityKey'];
+ $void_data['TxAuthNo'] = $sagepay_server_order['TxAuthNo'];
+
+ $response_data = $this->sendCurl($url, $void_data);
+
+ return $response_data;
+ } else {
+ return false;
+ }
+ }
+
+ public function updateVoidStatus($sagepay_server_order_id, $status) {
+ $this->db->query("UPDATE `" . DB_PREFIX . "sagepay_server_order` SET `void_status` = '" . (int)$status . "' WHERE `sagepay_server_order_id` = '" . (int)$sagepay_server_order_id . "'");
+ }
+
+ public function release($order_id, $amount) {
+ $sagepay_server_order = $this->getOrder($order_id);
+ $total_released = $this->getTotalReleased($sagepay_server_order['sagepay_server_order_id']);
+
+ if (!empty($sagepay_server_order) && $sagepay_server_order['release_status'] == 0 && ($total_released + $amount <= $sagepay_server_order['total'])) {
+ $release_data = array();
+
+ if ($this->config->get('payment_sagepay_server_test') == 'live') {
+ $url = 'https://live.sagepay.com/gateway/service/release.vsp';
+ $release_data['VPSProtocol'] = '3.00';
+ } elseif ($this->config->get('payment_sagepay_server_test') == 'test') {
+ $url = 'https://test.sagepay.com/gateway/service/release.vsp';
+ $release_data['VPSProtocol'] = '3.00';
+ } elseif ($this->config->get('payment_sagepay_server_test') == 'sim') {
+ $url = 'https://test.sagepay.com/Simulator/VSPServerGateway.asp?Service=VendorReleaseTx';
+ $release_data['VPSProtocol'] = '2.23';
+ }
+
+ $release_data['TxType'] = 'RELEASE';
+ $release_data['Vendor'] = $this->config->get('payment_sagepay_server_vendor');
+ $release_data['VendorTxCode'] = $sagepay_server_order['VendorTxCode'];
+ $release_data['VPSTxId'] = $sagepay_server_order['VPSTxId'];
+ $release_data['SecurityKey'] = $sagepay_server_order['SecurityKey'];
+ $release_data['TxAuthNo'] = $sagepay_server_order['TxAuthNo'];
+ $release_data['Amount'] = $amount;
+
+ $response_data = $this->sendCurl($url, $release_data);
+
+ return $response_data;
+ } else {
+ return false;
+ }
+ }
+
+ public function updateReleaseStatus($sagepay_server_order_id, $status) {
+ $this->db->query("UPDATE `" . DB_PREFIX . "sagepay_server_order` SET `release_status` = '" . (int)$status . "' WHERE `sagepay_server_order_id` = '" . (int)$sagepay_server_order_id . "'");
+ }
+
+ public function updateForRebate($sagepay_server_order_id, $order_ref) {
+ $this->db->query("UPDATE `" . DB_PREFIX . "sagepay_server_order` SET `order_ref_previous` = '_multisettle_" . $this->db->escape($order_ref) . "' WHERE `sagepay_server_order_id` = '" . (int)$sagepay_server_order_id . "' LIMIT 1");
+ }
+
+ public function rebate($order_id, $amount) {
+ $sagepay_server_order = $this->getOrder($order_id);
+
+ if (!empty($sagepay_server_order) && $sagepay_server_order['rebate_status'] != 1) {
+
+ $refund_data = array();
+
+ if ($this->config->get('payment_sagepay_server_test') == 'live') {
+ $url = 'https://live.sagepay.com/gateway/service/refund.vsp';
+ $refund_data['VPSProtocol'] = '3.00';
+ } elseif ($this->config->get('payment_sagepay_server_test') == 'test') {
+ $url = 'https://test.sagepay.com/gateway/service/refund.vsp';
+ $refund_data['VPSProtocol'] = '3.00';
+ } elseif ($this->config->get('payment_sagepay_server_test') == 'sim') {
+ $url = 'https://test.sagepay.com/Simulator/VSPServerGateway.asp?Service=VendorRefundTx';
+ $refund_data['VPSProtocol'] = '2.23';
+ }
+
+ $refund_data['TxType'] = 'REFUND';
+ $refund_data['Vendor'] = $this->config->get('payment_sagepay_server_vendor');
+ $refund_data['VendorTxCode'] = $sagepay_server_order['sagepay_server_order_id'] . rand();
+ $refund_data['Amount'] = $amount;
+ $refund_data['Currency'] = $sagepay_server_order['currency_code'];
+ $refund_data['Description'] = substr($this->config->get('config_name'), 0, 100);
+ $refund_data['RelatedVPSTxId'] = $sagepay_server_order['VPSTxId'];
+ $refund_data['RelatedVendorTxCode'] = $sagepay_server_order['VendorTxCode'];
+ $refund_data['RelatedSecurityKey'] = $sagepay_server_order['SecurityKey'];
+ $refund_data['RelatedTxAuthNo'] = $sagepay_server_order['TxAuthNo'];
+
+ $response_data = $this->sendCurl($url, $refund_data);
+
+ return $response_data;
+ } else {
+ return false;
+ }
+ }
+
+ public function getOrder($order_id) {
+
+ $qry = $this->db->query("SELECT * FROM `" . DB_PREFIX . "sagepay_server_order` WHERE `order_id` = '" . (int)$order_id . "' LIMIT 1");
+
+ if ($qry->num_rows) {
+ $order = $qry->row;
+ $order['transactions'] = $this->getTransactions($order['sagepay_server_order_id']);
+
+ return $order;
+ } else {
+ return false;
+ }
+ }
+
+ private function getTransactions($sagepay_server_order_id) {
+ $qry = $this->db->query("SELECT * FROM `" . DB_PREFIX . "sagepay_server_order_transaction` WHERE `sagepay_server_order_id` = '" . (int)$sagepay_server_order_id . "'");
+
+ if ($qry->num_rows) {
+ return $qry->rows;
+ } else {
+ return false;
+ }
+ }
+
+ public function addTransaction($sagepay_server_order_id, $type, $total) {
+ $this->db->query("INSERT INTO `" . DB_PREFIX . "sagepay_server_order_transaction` SET `sagepay_server_order_id` = '" . (int)$sagepay_server_order_id . "', `date_added` = now(), `type` = '" . $this->db->escape($type) . "', `amount` = '" . (float)$total . "'");
+ }
+
+ public function getTotalReleased($sagepay_server_order_id) {
+ $query = $this->db->query("SELECT SUM(`amount`) AS `total` FROM `" . DB_PREFIX . "sagepay_server_order_transaction` WHERE `sagepay_server_order_id` = '" . (int)$sagepay_server_order_id . "' AND (`type` = 'payment' OR `type` = 'rebate')");
+
+ return (float)$query->row['total'];
+ }
+
+ public function getTotalRebated($sagepay_server_order_id) {
+ $query = $this->db->query("SELECT SUM(`amount`) AS `total` FROM `" . DB_PREFIX . "sagepay_server_order_transaction` WHERE `sagepay_server_order_id` = '" . (int)$sagepay_server_order_id . "' AND 'rebate'");
+
+ return (float)$query->row['total'];
+ }
+
+ public function sendCurl($url, $payment_data) {
+ $curl = curl_init($url);
+
+ curl_setopt($curl, CURLOPT_PORT, 443);
+ curl_setopt($curl, CURLOPT_HEADER, 0);
+ curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, 0);
+ curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
+ curl_setopt($curl, CURLOPT_FOLLOWLOCATION, false);
+ curl_setopt($curl, CURLOPT_FORBID_REUSE, 1);
+ curl_setopt($curl, CURLOPT_FRESH_CONNECT, 1);
+ curl_setopt($curl, CURLOPT_POST, 1);
+ curl_setopt($curl, CURLOPT_POSTFIELDS, http_build_query($payment_data));
+
+ $response = curl_exec($curl);
+
+ curl_close($curl);
+
+ $response_info = explode(chr(10), $response);
+
+ foreach ($response_info as $string) {
+ if (strpos($string, '=') && isset($i)) {
+ $parts = explode('=', $string, 2);
+ $data['RepeatResponseData_' . $i][trim($parts[0])] = trim($parts[1]);
+ } elseif (strpos($string, '=')) {
+ $parts = explode('=', $string, 2);
+ $data[trim($parts[0])] = trim($parts[1]);
+ }
+ }
+ return $data;
+ }
+
+ public function logger($title, $data) {
+ if ($this->config->get('payment_sagepay_server_debug')) {
+ $log = new Log('sagepay_server.log');
+ $log->write($title . ': ' . print_r($data, 1));
+ }
+ }
+} \ No newline at end of file
diff --git a/public/admin/model/extension/payment/securetrading_pp.php b/public/admin/model/extension/payment/securetrading_pp.php
new file mode 100644
index 0000000..2e21b3a
--- /dev/null
+++ b/public/admin/model/extension/payment/securetrading_pp.php
@@ -0,0 +1,208 @@
+<?php
+class ModelExtensionPaymentSecureTradingPp extends Model {
+ public function install() {
+ $this->db->query("
+ CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "securetrading_pp_order` (
+ `securetrading_pp_order_id` INT(11) NOT NULL AUTO_INCREMENT,
+ `order_id` INT(11) NOT NULL,
+ `transaction_reference` varchar(127) DEFAULT NULL,
+ `created` DATETIME NOT NULL,
+ `modified` DATETIME NOT NULL,
+ `release_status` INT(1) DEFAULT NULL,
+ `void_status` INT(1) DEFAULT NULL,
+ `settle_type` INT(1) DEFAULT NULL,
+ `rebate_status` INT(1) DEFAULT NULL,
+ `currency_code` CHAR(3) NOT NULL,
+ `total` DECIMAL( 10, 2 ) NOT NULL,
+ PRIMARY KEY (`securetrading_pp_order_id`)
+ ) ENGINE=MyISAM DEFAULT COLLATE=utf8_general_ci;");
+
+ $this->db->query("
+ CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "securetrading_pp_order_transaction` (
+ `securetrading_pp_order_transaction_id` INT(11) NOT NULL AUTO_INCREMENT,
+ `securetrading_pp_order_id` INT(11) NOT NULL,
+ `created` DATETIME NOT NULL,
+ `type` ENUM('auth', 'payment', 'rebate', 'reversed') DEFAULT NULL,
+ `amount` DECIMAL( 10, 2 ) NOT NULL,
+ PRIMARY KEY (`securetrading_pp_order_transaction_id`)
+ ) ENGINE=MyISAM DEFAULT COLLATE=utf8_general_ci;");
+ }
+
+ public function uninstall() {
+ $this->db->query("DROP TABLE IF EXISTS " . DB_PREFIX . "securetrading_pp_order");
+ $this->db->query("DROP TABLE IF EXISTS `" . DB_PREFIX . "securetrading_pp_order_transaction`;");
+ }
+
+ public function void($order_id) {
+ $securetrading_pp_order = $this->getOrder($order_id);
+
+ if (!empty($securetrading_pp_order) && $securetrading_pp_order['release_status'] == 0) {
+
+ $requestblock_xml = new SimpleXMLElement('<requestblock></requestblock>');
+ $requestblock_xml->addAttribute('version', '3.67');
+ $requestblock_xml->addChild('alias', $this->config->get('payment_securetrading_pp_webservice_username'));
+
+ $request_node = $requestblock_xml->addChild('request');
+ $request_node->addAttribute('type', 'TRANSACTIONUPDATE');
+
+ $filter_node = $request_node->addChild('filter');
+ $filter_node->addChild('sitereference', $this->config->get('payment_securetrading_pp_site_reference'));
+ $filter_node->addChild('transactionreference', $securetrading_pp_order['transaction_reference']);
+
+ $request_node->addChild('updates')->addChild('settlement')->addChild('settlestatus', 3);
+
+ return $this->call($requestblock_xml->asXML());
+ } else {
+ return false;
+ }
+ }
+
+ public function updateVoidStatus($securetrading_pp_order_id, $status) {
+ $this->db->query("UPDATE `" . DB_PREFIX . "securetrading_pp_order` SET `void_status` = '" . (int)$status . "' WHERE `securetrading_pp_order_id` = '" . (int)$securetrading_pp_order_id . "'");
+ }
+
+ public function release($order_id, $amount) {
+ $securetrading_pp_order = $this->getOrder($order_id);
+ $total_released = $this->getTotalReleased($securetrading_pp_order['securetrading_pp_order_id']);
+
+ if (!empty($securetrading_pp_order) && $securetrading_pp_order['release_status'] == 0 && $total_released <= $amount) {
+
+ $requestblock_xml = new SimpleXMLElement('<requestblock></requestblock>');
+ $requestblock_xml->addAttribute('version', '3.67');
+ $requestblock_xml->addChild('alias', $this->config->get('payment_securetrading_pp_webservice_username'));
+
+ $request_node = $requestblock_xml->addChild('request');
+ $request_node->addAttribute('type', 'TRANSACTIONUPDATE');
+
+ $filter_node = $request_node->addChild('filter');
+ $filter_node->addChild('sitereference', $this->config->get('payment_securetrading_pp_site_reference'));
+ $filter_node->addChild('transactionreference', $securetrading_pp_order['transaction_reference']);
+
+ $settlement_node = $request_node->addChild('updates')->addChild('settlement');
+ $settlement_node->addChild('settlestatus', 0);
+ $settlement_node->addChild('settlemainamount', $amount)->addAttribute('currencycode', $securetrading_pp_order['currency_code']);
+
+ return $this->call($requestblock_xml->asXML());
+ } else {
+ return false;
+ }
+ }
+
+ public function updateReleaseStatus($securetrading_pp_order_id, $status) {
+ $this->db->query("UPDATE `" . DB_PREFIX . "securetrading_pp_order` SET `release_status` = '" . (int)$status . "' WHERE `securetrading_pp_order_id` = '" . (int)$securetrading_pp_order_id . "'");
+ }
+
+ public function updateForRebate($securetrading_pp_order_id, $order_ref) {
+ $this->db->query("UPDATE `" . DB_PREFIX . "securetrading_pp_order` SET `order_ref_previous` = '_multisettle_" . $this->db->escape($order_ref) . "' WHERE `securetrading_pp_order_id` = '" . (int)$securetrading_pp_order_id . "' LIMIT 1");
+ }
+
+ public function rebate($order_id, $refunded_amount) {
+ $securetrading_pp_order = $this->getOrder($order_id);
+
+ if (!empty($securetrading_pp_order) && $securetrading_pp_order['rebate_status'] != 1) {
+
+ $requestblock_xml = new SimpleXMLElement('<requestblock></requestblock>');
+ $requestblock_xml->addAttribute('version', '3.67');
+ $requestblock_xml->addChild('alias', $this->config->get('payment_securetrading_pp_webservice_username'));
+
+ $request_node = $requestblock_xml->addChild('request');
+ $request_node->addAttribute('type', 'REFUND');
+
+ $request_node->addChild('merchant')->addChild('orderreference', $order_id);
+
+ $operation_node = $request_node->addChild('operation');
+ $operation_node->addChild('accounttypedescription', 'ECOM');
+ $operation_node->addChild('parenttransactionreference', $securetrading_pp_order['transaction_reference']);
+ $operation_node->addChild('sitereference', $this->config->get('payment_securetrading_pp_site_reference'));
+
+ $billing_node = $request_node->addChild('billing');
+ $billing_node->addAttribute('currencycode', $securetrading_pp_order['currency_code']);
+ $billing_node->addChild('amount', str_replace('.', '', $refunded_amount));
+
+ return $this->call($requestblock_xml->asXML());
+ } else {
+ return false;
+ }
+ }
+
+ public function getOrder($order_id) {
+ $qry = $this->db->query("SELECT * FROM `" . DB_PREFIX . "securetrading_pp_order` WHERE `order_id` = '" . (int)$order_id . "' LIMIT 1");
+
+ if ($qry->num_rows) {
+ $order = $qry->row;
+ $order['transactions'] = $this->getTransactions($order['securetrading_pp_order_id']);
+
+ return $order;
+ } else {
+ return false;
+ }
+ }
+
+ private function getTransactions($securetrading_pp_order_id) {
+ $qry = $this->db->query("SELECT * FROM `" . DB_PREFIX . "securetrading_pp_order_transaction` WHERE `securetrading_pp_order_id` = '" . (int)$securetrading_pp_order_id . "'");
+
+ if ($qry->num_rows) {
+ return $qry->rows;
+ } else {
+ return false;
+ }
+ }
+
+ public function addTransaction($securetrading_pp_order_id, $type, $total) {
+ $this->db->query("INSERT INTO `" . DB_PREFIX . "securetrading_pp_order_transaction` SET `securetrading_pp_order_id` = '" . (int)$securetrading_pp_order_id . "', `created` = now(), `type` = '" . $this->db->escape($type) . "', `amount` = '" . (double)$total . "'");
+ }
+
+ public function getTotalReleased($securetrading_pp_order_id) {
+ $query = $this->db->query("SELECT SUM(`amount`) AS `total` FROM `" . DB_PREFIX . "securetrading_pp_order_transaction` WHERE `securetrading_pp_order_id` = '" . (int)$securetrading_pp_order_id . "' AND (`type` = 'payment' OR `type` = 'rebate')");
+
+ return (double)$query->row['total'];
+ }
+
+ public function getTotalRebated($securetrading_pp_order_id) {
+ $query = $this->db->query("SELECT SUM(`amount`) AS `total` FROM `" . DB_PREFIX . "securetrading_pp_order_transaction` WHERE `securetrading_pp_order_id` = '" . (int)$securetrading_pp_order_id . "' AND 'rebate'");
+
+ return (double)$query->row['total'];
+ }
+
+ public function increaseRefundedAmount($order_id, $amount) {
+ $this->db->query("UPDATE " . DB_PREFIX . "securetrading_pp_order SET refunded = refunded + " . (double)$amount . " WHERE order_id = " . (int)$order_id);
+ }
+
+ public function call($data) {
+ $ch = curl_init();
+
+ $defaults = array(
+ CURLOPT_POST => 1,
+ CURLOPT_HEADER => 0,
+ CURLOPT_SSL_VERIFYPEER => 0,
+ CURLOPT_URL => 'https://webservices.securetrading.net/xml/',
+ CURLOPT_FRESH_CONNECT => 1,
+ CURLOPT_RETURNTRANSFER => 1,
+ CURLOPT_FORBID_REUSE => 1,
+ CURLOPT_TIMEOUT => 15,
+ CURLOPT_HTTPHEADER => array(
+ 'User-Agent: OpenCart - Secure Trading PP',
+ 'Content-Length: ' . strlen($data),
+ 'Authorization: Basic ' . base64_encode($this->config->get('payment_securetrading_pp_webservice_username') . ':' . $this->config->get('payment_securetrading_pp_webservice_password')),
+ ),
+ CURLOPT_POSTFIELDS => $data,
+ );
+
+ curl_setopt_array($ch, $defaults);
+
+ $response = curl_exec($ch);
+
+ if ($response === false) {
+ $this->log->write('Secure Trading PP CURL Error: (' . curl_errno($ch) . ') ' . curl_error($ch));
+ }
+
+ curl_close($ch);
+
+ return $response;
+ }
+
+ public function logger($message) {
+ $log = new Log('securetrading_pp.log');
+ $log->write($message);
+ }
+} \ No newline at end of file
diff --git a/public/admin/model/extension/payment/securetrading_ws.php b/public/admin/model/extension/payment/securetrading_ws.php
new file mode 100644
index 0000000..5b2b567
--- /dev/null
+++ b/public/admin/model/extension/payment/securetrading_ws.php
@@ -0,0 +1,351 @@
+<?php
+class ModelExtensionPaymentSecureTradingWs extends Model {
+ public function install() {
+ $this->db->query("
+ CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "securetrading_ws_order` (
+ `securetrading_ws_order_id` INT(11) NOT NULL AUTO_INCREMENT,
+ `order_id` INT(11) NOT NULL,
+ `md` varchar(1024) DEFAULT NULL,
+ `transaction_reference` varchar(127) DEFAULT NULL,
+ `created` DATETIME NOT NULL,
+ `modified` DATETIME NOT NULL,
+ `release_status` INT(1) DEFAULT NULL,
+ `void_status` INT(1) DEFAULT NULL,
+ `settle_type` INT(1) DEFAULT NULL,
+ `rebate_status` INT(1) DEFAULT NULL,
+ `currency_code` CHAR(3) NOT NULL,
+ `total` DECIMAL( 10, 2 ) NOT NULL,
+ PRIMARY KEY (`securetrading_ws_order_id`)
+ ) ENGINE=MyISAM DEFAULT COLLATE=utf8_general_ci;");
+
+ $this->db->query("
+ CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "securetrading_ws_order_transaction` (
+ `securetrading_ws_order_transaction_id` INT(11) NOT NULL AUTO_INCREMENT,
+ `securetrading_ws_order_id` INT(11) NOT NULL,
+ `created` DATETIME NOT NULL,
+ `type` ENUM('auth', 'payment', 'rebate', 'reversed') DEFAULT NULL,
+ `amount` DECIMAL( 10, 2 ) NOT NULL,
+ PRIMARY KEY (`securetrading_ws_order_transaction_id`)
+ ) ENGINE=MyISAM DEFAULT COLLATE=utf8_general_ci;");
+ }
+
+ public function uninstall() {
+ $this->db->query("DROP TABLE IF EXISTS " . DB_PREFIX . "securetrading_ws_order");
+ $this->db->query("DROP TABLE IF EXISTS `" . DB_PREFIX . "securetrading_ws_order_transaction`;");
+ }
+
+ public function void($order_id) {
+ $securetrading_ws_order = $this->getOrder($order_id);
+
+ if (!empty($securetrading_ws_order) && $securetrading_ws_order['release_status'] == 0) {
+
+ $requestblock_xml = new SimpleXMLElement('<requestblock></requestblock>');
+ $requestblock_xml->addAttribute('version', '3.67');
+ $requestblock_xml->addChild('alias', $this->config->get('payment_securetrading_ws_username'));
+
+ $request_node = $requestblock_xml->addChild('request');
+ $request_node->addAttribute('type', 'TRANSACTIONUPDATE');
+
+ $filter_node = $request_node->addChild('filter');
+ $filter_node->addChild('sitereference', $this->config->get('payment_securetrading_ws_site_reference'));
+ $filter_node->addChild('transactionreference', $securetrading_ws_order['transaction_reference']);
+
+ $request_node->addChild('updates')->addChild('settlement')->addChild('settlestatus', 3);
+
+ return $this->call($requestblock_xml->asXML());
+ } else {
+ return false;
+ }
+ }
+
+ public function updateVoidStatus($securetrading_ws_order_id, $status) {
+ $this->db->query("UPDATE `" . DB_PREFIX . "securetrading_ws_order` SET `void_status` = '" . (int)$status . "' WHERE `securetrading_ws_order_id` = '" . (int)$securetrading_ws_order_id . "'");
+ }
+
+ public function release($order_id, $amount) {
+ $securetrading_ws_order = $this->getOrder($order_id);
+ $total_released = $this->getTotalReleased($securetrading_ws_order['securetrading_ws_order_id']);
+
+ if (!empty($securetrading_ws_order) && $securetrading_ws_order['release_status'] == 0 && $total_released <= $amount) {
+
+ $requestblock_xml = new SimpleXMLElement('<requestblock></requestblock>');
+ $requestblock_xml->addAttribute('version', '3.67');
+ $requestblock_xml->addChild('alias', $this->config->get('payment_securetrading_ws_username'));
+
+ $request_node = $requestblock_xml->addChild('request');
+ $request_node->addAttribute('type', 'TRANSACTIONUPDATE');
+
+ $filter_node = $request_node->addChild('filter');
+ $filter_node->addChild('sitereference', $this->config->get('payment_securetrading_ws_site_reference'));
+ $filter_node->addChild('transactionreference', $securetrading_ws_order['transaction_reference']);
+
+ $settlement_node = $request_node->addChild('updates')->addChild('settlement');
+ $settlement_node->addChild('settlestatus', 0);
+ $settlement_node->addChild('settlemainamount', $amount)->addAttribute('currencycode', $securetrading_ws_order['currency_code']);
+
+ return $this->call($requestblock_xml->asXML());
+ } else {
+ return false;
+ }
+ }
+
+ public function updateReleaseStatus($securetrading_ws_order_id, $status) {
+ $this->db->query("UPDATE `" . DB_PREFIX . "securetrading_ws_order` SET `release_status` = '" . (int)$status . "' WHERE `securetrading_ws_order_id` = '" . (int)$securetrading_ws_order_id . "'");
+ }
+
+ public function updateForRebate($securetrading_ws_order_id, $order_ref) {
+ $this->db->query("UPDATE `" . DB_PREFIX . "securetrading_ws_order` SET `order_ref_previous` = '_multisettle_" . $this->db->escape($order_ref) . "' WHERE `securetrading_ws_order_id` = '" . (int)$securetrading_ws_order_id . "' LIMIT 1");
+ }
+
+ public function rebate($order_id, $refunded_amount) {
+ $securetrading_ws_order = $this->getOrder($order_id);
+
+ if (!empty($securetrading_ws_order) && $securetrading_ws_order['rebate_status'] != 1) {
+
+ $requestblock_xml = new SimpleXMLElement('<requestblock></requestblock>');
+ $requestblock_xml->addAttribute('version', '3.67');
+ $requestblock_xml->addChild('alias', $this->config->get('payment_securetrading_ws_username'));
+
+ $request_node = $requestblock_xml->addChild('request');
+ $request_node->addAttribute('type', 'REFUND');
+
+ $request_node->addChild('merchant')->addChild('orderreference', $order_id);
+
+ $operation_node = $request_node->addChild('operation');
+ $operation_node->addChild('accounttypedescription', 'ECOM');
+ $operation_node->addChild('parenttransactionreference', $securetrading_ws_order['transaction_reference']);
+ $operation_node->addChild('sitereference', $this->config->get('payment_securetrading_ws_site_reference'));
+
+ $billing_node = $request_node->addChild('billing');
+ $billing_node->addAttribute('currencycode', $securetrading_ws_order['currency_code']);
+ $billing_node->addChild('amount', str_replace('.', '', $refunded_amount));
+
+ return $this->call($requestblock_xml->asXML());
+ } else {
+ return false;
+ }
+ }
+
+ public function getOrder($order_id) {
+ $qry = $this->db->query("SELECT * FROM `" . DB_PREFIX . "securetrading_ws_order` WHERE `order_id` = '" . (int)$order_id . "' LIMIT 1");
+
+ if ($qry->num_rows) {
+ $order = $qry->row;
+ $order['transactions'] = $this->getTransactions($order['securetrading_ws_order_id']);
+
+ return $order;
+ } else {
+ return false;
+ }
+ }
+
+ private function getTransactions($securetrading_ws_order_id) {
+ $qry = $this->db->query("SELECT * FROM `" . DB_PREFIX . "securetrading_ws_order_transaction` WHERE `securetrading_ws_order_id` = '" . (int)$securetrading_ws_order_id . "'");
+
+ if ($qry->num_rows) {
+ return $qry->rows;
+ } else {
+ return false;
+ }
+ }
+
+ public function addTransaction($securetrading_ws_order_id, $type, $total) {
+ $this->db->query("INSERT INTO `" . DB_PREFIX . "securetrading_ws_order_transaction` SET `securetrading_ws_order_id` = '" . (int)$securetrading_ws_order_id . "', `created` = now(), `type` = '" . $this->db->escape($type) . "', `amount` = '" . (double)$total . "'");
+ }
+
+ public function getTotalReleased($securetrading_ws_order_id) {
+ $query = $this->db->query("SELECT SUM(`amount`) AS `total` FROM `" . DB_PREFIX . "securetrading_ws_order_transaction` WHERE `securetrading_ws_order_id` = '" . (int)$securetrading_ws_order_id . "' AND (`type` = 'payment' OR `type` = 'rebate')");
+
+ return (double)$query->row['total'];
+ }
+
+ public function getTotalRebated($securetrading_ws_order_id) {
+ $query = $this->db->query("SELECT SUM(`amount`) AS `total` FROM `" . DB_PREFIX . "securetrading_ws_order_transaction` WHERE `securetrading_ws_order_id` = '" . (int)$securetrading_ws_order_id . "' AND 'rebate'");
+
+ return (double)$query->row['total'];
+ }
+
+ public function increaseRefundedAmount($order_id, $amount) {
+ $this->db->query("UPDATE " . DB_PREFIX . "securetrading_ws_order SET refunded = refunded + " . (double)$amount . " WHERE order_id = " . (int)$order_id);
+ }
+
+ public function getCsv($data) {
+ $ch = curl_init();
+
+ $post_data = array();
+ $post_data['sitereferences'] = $this->config->get('payment_securetrading_ws_site_reference');
+ $post_data['startdate'] = $data['date_from'];
+ $post_data['enddate'] = $data['date_to'];
+ $post_data['accounttypedescriptions'] = 'ECOM';
+
+ if ($data['detail']) {
+ $post_data['optionalfields'] = array(
+ 'parenttransactionreference',
+ 'accounttypedescription',
+ 'requesttypedescription',
+ 'mainamount',
+ 'currencyiso3a',
+ 'errorcode',
+ 'authcode',
+ 'customerip',
+ 'fraudrating',
+ 'orderreference',
+ 'paymenttypedescription',
+ 'maskedpan',
+ 'expirydate',
+ 'settlestatus',
+ 'settlemainamount',
+ 'settleduedate',
+ 'securityresponsesecuritycode',
+ 'securityresponseaddress',
+ 'securityresponsepostcode',
+ 'billingprefixname',
+ 'billingfirstname',
+ 'billingmiddlename',
+ 'billinglastname',
+ 'billingpremise',
+ 'billingstreet',
+ 'billingtown',
+ 'billingcounty',
+ 'billingemail',
+ 'billingcountryiso2a',
+ 'billingpostcode',
+ 'billingtelephones',
+ 'customerprefixname',
+ 'customerfirstname',
+ 'customermiddlename',
+ 'customerlastname',
+ 'customerpremise',
+ 'customerstreet',
+ 'customertown',
+ 'customercounty',
+ 'customeremail',
+ 'customercountryiso2a',
+ 'customerpostcode',
+ 'customertelephones',
+ );
+ } else {
+ $post_data['optionalfields'] = array(
+ 'orderreference',
+ 'currencyiso3a',
+ 'errorcode',
+ 'paymenttypedescription',
+ 'settlestatus',
+ 'requesttypedescription',
+ 'mainamount',
+ 'billingfirstname',
+ 'billinglastname',
+ );
+ }
+
+ if (isset($data['currency']) && !empty($data['currency'])) {
+ $post_data['currencyiso3as'] = $data['currency'];
+ }
+
+ if (isset($data['status']) && !empty($data['status'])) {
+ $post_data['errorcodes'] = $data['status'];
+ }
+
+ if (isset($data['payment_type']) && !empty($data['payment_type'])) {
+ $post_data['paymenttypedescriptions'] = $data['payment_type'];
+ }
+
+ if (isset($data['request']) && !empty($data['request'])) {
+ $post_data['requesttypedescriptions'] = $data['request'];
+ }
+
+ if (isset($data['settle_status']) && !empty($data['settle_status'])) {
+ $post_data['settlestatuss'] = $data['settle_status'];
+ }
+
+ $defaults = array(
+ CURLOPT_POST => 1,
+ CURLOPT_HEADER => 0,
+ CURLOPT_SSL_VERIFYPEER => 0,
+ CURLOPT_URL => 'https://myst.securetrading.net/auto/transactions/transactionsearch',
+ CURLOPT_FRESH_CONNECT => 1,
+ CURLOPT_RETURNTRANSFER => 1,
+ CURLOPT_FORBID_REUSE => 1,
+ CURLOPT_TIMEOUT => 15,
+ CURLOPT_HTTPHEADER => array(
+ 'User-Agent: OpenCart - Secure Trading WS',
+ 'Authorization: Basic ' . base64_encode($this->config->get('payment_securetrading_ws_csv_username') . ':' . $this->config->get('payment_securetrading_ws_csv_password')),
+ ),
+ CURLOPT_POSTFIELDS => $this->encodePost($post_data),
+ );
+
+ curl_setopt_array($ch, $defaults);
+
+ $response = curl_exec($ch);
+
+ if ($response === false) {
+ $this->log->write('Secure Trading WS CURL Error: (' . curl_errno($ch) . ') ' . curl_error($ch));
+ }
+
+ curl_close($ch);
+
+ if (empty($response) || $response === 'No records found for search') {
+ return false;
+ }
+
+ if (preg_match('/401 Authorization Required/', $response)) {
+ return false;
+ }
+
+ return $response;
+ }
+
+ private function encodePost($data) {
+ $params = array();
+
+ foreach ($data as $key => $value) {
+ if (is_array($value)) {
+ foreach ($value as $v) {
+ $params[] = $key . '=' . rawurlencode($v);
+ }
+ } else {
+ $params[] = $key . '=' . rawurlencode($value);
+ }
+ }
+
+ return implode('&', $params);
+ }
+
+ public function call($data) {
+ $ch = curl_init();
+
+ $defaults = array(
+ CURLOPT_POST => 1,
+ CURLOPT_HEADER => 0,
+ CURLOPT_SSL_VERIFYPEER => 0,
+ CURLOPT_URL => 'https://webservices.securetrading.net/xml/',
+ CURLOPT_FRESH_CONNECT => 1,
+ CURLOPT_RETURNTRANSFER => 1,
+ CURLOPT_FORBID_REUSE => 1,
+ CURLOPT_TIMEOUT => 15,
+ CURLOPT_HTTPHEADER => array(
+ 'User-Agent: OpenCart - Secure Trading WS',
+ 'Content-Length: ' . strlen($data),
+ 'Authorization: Basic ' . base64_encode($this->config->get('payment_securetrading_ws_username') . ':' . $this->config->get('payment_securetrading_ws_password')),
+ ),
+ CURLOPT_POSTFIELDS => $data,
+ );
+
+ curl_setopt_array($ch, $defaults);
+
+ $response = curl_exec($ch);
+
+ if ($response === false) {
+ $this->log->write('Secure Trading WS CURL Error: (' . curl_errno($ch) . ') ' . curl_error($ch));
+ }
+
+ curl_close($ch);
+
+ return $response;
+ }
+
+ public function logger($message) {
+ $log = new Log('securetrading_ws.log');
+ $log->write($message);
+ }
+} \ No newline at end of file
diff --git a/public/admin/model/extension/payment/squareup.php b/public/admin/model/extension/payment/squareup.php
new file mode 100644
index 0000000..d5c428c
--- /dev/null
+++ b/public/admin/model/extension/payment/squareup.php
@@ -0,0 +1,117 @@
+<?php
+
+class ModelExtensionPaymentSquareup extends Model {
+ const RECURRING_ACTIVE = 1;
+ const RECURRING_INACTIVE = 2;
+ const RECURRING_CANCELLED = 3;
+ const RECURRING_SUSPENDED = 4;
+ const RECURRING_EXPIRED = 5;
+ const RECURRING_PENDING = 6;
+
+ public function getTransaction($squareup_transaction_id) {
+ return $this->db->query("SELECT * FROM `" . DB_PREFIX . "squareup_transaction` WHERE squareup_transaction_id='" . (int)$squareup_transaction_id . "'")->row;
+ }
+
+ public function getTransactions($data) {
+ $sql = "SELECT * FROM `" . DB_PREFIX . "squareup_transaction`";
+
+ if (isset($data['order_id'])) {
+ $sql .= " WHERE order_id='" . (int)$data['order_id'] . "'";
+ }
+
+ $sql .= " ORDER BY created_at DESC";
+
+ if (isset($data['start']) && isset($data['limit'])) {
+ $sql .= " LIMIT " . $data['start'] . ', ' . $data['limit'];
+ }
+
+ return $this->db->query($sql)->rows;
+ }
+
+ public function getTotalTransactions($data) {
+ $sql = "SELECT COUNT(*) as total FROM `" . DB_PREFIX . "squareup_transaction`";
+
+ if (isset($data['order_id'])) {
+ $sql .= " WHERE order_id='" . (int)$data['order_id'] . "'";
+ }
+
+ return $this->db->query($sql)->row['total'];
+ }
+
+ public function updateTransaction($squareup_transaction_id, $type, $refunds = array()) {
+ $this->db->query("UPDATE `" . DB_PREFIX . "squareup_transaction` SET transaction_type='" . $this->db->escape($type) . "', is_refunded='" . (int)!empty($refunds) . "', refunds='" . $this->db->escape(json_encode($refunds)) . "' WHERE squareup_transaction_id='" . (int)$squareup_transaction_id . "'");
+ }
+
+ public function getOrderStatusId($order_id, $transaction_status = null) {
+ if ($transaction_status) {
+ return $this->config->get('payment_squareup_status_' . strtolower($transaction_status));
+ } else {
+ $this->load->model('sale/order');
+
+ $order_info = $this->model_sale_order->getOrder($order_id);
+
+ return $order_info['order_status_id'];
+ }
+ }
+
+ public function editOrderRecurringStatus($order_recurring_id, $status) {
+ $this->db->query("UPDATE `" . DB_PREFIX . "order_recurring` SET `status` = '" . (int)$status . "' WHERE `order_recurring_id` = '" . (int)$order_recurring_id . "'");
+ }
+
+ public function createTables() {
+ $this->db->query("CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "squareup_transaction` (
+ `squareup_transaction_id` int(11) UNSIGNED NOT NULL AUTO_INCREMENT,
+ `transaction_id` char(40) NOT NULL,
+ `merchant_id` char(32) NOT NULL,
+ `location_id` varchar(32) NOT NULL,
+ `order_id` int(11) NOT NULL,
+ `transaction_type` char(20) NOT NULL,
+ `transaction_amount` decimal(15,2) NOT NULL,
+ `transaction_currency` char(3) NOT NULL,
+ `billing_address_city` char(100) NOT NULL,
+ `billing_address_company` char(100) NOT NULL,
+ `billing_address_country` char(3) NOT NULL,
+ `billing_address_postcode` char(10) NOT NULL,
+ `billing_address_province` char(20) NOT NULL,
+ `billing_address_street_1` char(100) NOT NULL,
+ `billing_address_street_2` char(100) NOT NULL,
+ `device_browser` char(255) NOT NULL,
+ `device_ip` char(15) NOT NULL,
+ `created_at` char(29) NOT NULL,
+ `is_refunded` tinyint(1) NOT NULL,
+ `refunded_at` varchar(29) NOT NULL,
+ `tenders` text NOT NULL,
+ `refunds` text NOT NULL,
+ PRIMARY KEY (`squareup_transaction_id`),
+ KEY `order_id` (`order_id`),
+ KEY `transaction_id` (`transaction_id`)
+ ) ENGINE=InnoDB DEFAULT CHARSET=utf8;");
+
+ $this->db->query("CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "squareup_token` (
+ `squareup_token_id` int(11) unsigned NOT NULL AUTO_INCREMENT,
+ `customer_id` int(11) NOT NULL,
+ `sandbox` tinyint(1) NOT NULL,
+ `token` char(40) NOT NULL,
+ `date_added` datetime NOT NULL,
+ `brand` VARCHAR(32) NOT NULL,
+ `ends_in` VARCHAR(4) NOT NULL,
+ PRIMARY KEY (`squareup_token_id`),
+ KEY `getCards` (`customer_id`, `sandbox`),
+ KEY `verifyCardCustomer` (`squareup_token_id`, `customer_id`),
+ KEY `cardExists` (`customer_id`, `brand`, `ends_in`)
+ ) ENGINE=InnoDB DEFAULT CHARSET=utf8");
+
+ $this->db->query("CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "squareup_customer` (
+ `customer_id` int(11) NOT NULL,
+ `sandbox` tinyint(1) NOT NULL,
+ `square_customer_id` varchar(32) NOT NULL,
+ PRIMARY KEY (`customer_id`, `sandbox`)
+ ) ENGINE=InnoDB DEFAULT CHARSET=utf8");
+ }
+
+ public function dropTables() {
+ $this->db->query("DROP TABLE IF EXISTS `" . DB_PREFIX . "squareup_transaction`");
+ $this->db->query("DROP TABLE IF EXISTS `" . DB_PREFIX . "squareup_token`");
+ $this->db->query("DROP TABLE IF EXISTS `" . DB_PREFIX . "squareup_customer`");
+ }
+} \ No newline at end of file
diff --git a/public/admin/model/extension/payment/worldpay.php b/public/admin/model/extension/payment/worldpay.php
new file mode 100644
index 0000000..ae2d9ce
--- /dev/null
+++ b/public/admin/model/extension/payment/worldpay.php
@@ -0,0 +1,175 @@
+<?php
+
+class ModelExtensionPaymentWorldpay extends Model {
+
+ public function install() {
+ $this->db->query("
+ CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "worldpay_order` (
+ `worldpay_order_id` INT(11) NOT NULL AUTO_INCREMENT,
+ `order_id` INT(11) NOT NULL,
+ `order_code` VARCHAR(50),
+ `date_added` DATETIME NOT NULL,
+ `date_modified` DATETIME NOT NULL,
+ `refund_status` INT(1) DEFAULT NULL,
+ `currency_code` CHAR(3) NOT NULL,
+ `total` DECIMAL( 10, 2 ) NOT NULL,
+ PRIMARY KEY (`worldpay_order_id`)
+ ) ENGINE=MyISAM DEFAULT COLLATE=utf8_general_ci;");
+
+ $this->db->query("
+ CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "worldpay_order_transaction` (
+ `worldpay_order_transaction_id` INT(11) NOT NULL AUTO_INCREMENT,
+ `worldpay_order_id` INT(11) NOT NULL,
+ `date_added` DATETIME NOT NULL,
+ `type` ENUM('payment', 'refund') DEFAULT NULL,
+ `amount` DECIMAL( 10, 2 ) NOT NULL,
+ PRIMARY KEY (`worldpay_order_transaction_id`)
+ ) ENGINE=MyISAM DEFAULT COLLATE=utf8_general_ci;");
+
+ $this->db->query("
+ CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "worldpay_order_recurring` (
+ `worldpay_order_recurring_id` INT(11) NOT NULL AUTO_INCREMENT,
+ `order_id` INT(11) NOT NULL,
+ `order_recurring_id` INT(11) NOT NULL,
+ `order_code` VARCHAR(50),
+ `token` VARCHAR(50),
+ `date_added` DATETIME NOT NULL,
+ `date_modified` DATETIME NOT NULL,
+ `next_payment` DATETIME NOT NULL,
+ `trial_end` datetime DEFAULT NULL,
+ `subscription_end` datetime DEFAULT NULL,
+ `currency_code` CHAR(3) NOT NULL,
+ `total` DECIMAL( 10, 2 ) NOT NULL,
+ PRIMARY KEY (`worldpay_order_recurring_id`)
+ ) ENGINE=MyISAM DEFAULT COLLATE=utf8_general_ci;");
+
+ $this->db->query("
+ CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "worldpay_card` (
+ `card_id` INT(11) NOT NULL AUTO_INCREMENT,
+ `customer_id` INT(11) NOT NULL,
+ `order_id` INT(11) NOT NULL,
+ `token` VARCHAR(50) NOT NULL,
+ `digits` VARCHAR(22) NOT NULL,
+ `expiry` VARCHAR(5) NOT NULL,
+ `type` VARCHAR(50) NOT NULL,
+ PRIMARY KEY (`card_id`)
+ ) ENGINE=MyISAM DEFAULT COLLATE=utf8_general_ci;");
+ }
+
+ public function uninstall() {
+ $this->db->query("DROP TABLE IF EXISTS `" . DB_PREFIX . "worldpay_order`;");
+ $this->db->query("DROP TABLE IF EXISTS `" . DB_PREFIX . "worldpay_order_transaction`;");
+ $this->db->query("DROP TABLE IF EXISTS `" . DB_PREFIX . "worldpay_order_recurring`;");
+ $this->db->query("DROP TABLE IF EXISTS `" . DB_PREFIX . "worldpay_card`;");
+ }
+
+ public function refund($order_id, $amount) {
+ $worldpay_order = $this->getOrder($order_id);
+
+ if (!empty($worldpay_order) && $worldpay_order['refund_status'] != 1) {
+ $order['refundAmount'] = (int)($amount * 100);
+
+ $url = $worldpay_order['order_code'] . '/refund';
+
+ $response_data = $this->sendCurl($url, $order);
+
+ return $response_data;
+ } else {
+ return false;
+ }
+ }
+
+ public function updateRefundStatus($worldpay_order_id, $status) {
+ $this->db->query("UPDATE `" . DB_PREFIX . "worldpay_order` SET `refund_status` = '" . (int)$status . "' WHERE `worldpay_order_id` = '" . (int)$worldpay_order_id . "'");
+ }
+
+ public function getOrder($order_id) {
+
+ $qry = $this->db->query("SELECT * FROM `" . DB_PREFIX . "worldpay_order` WHERE `order_id` = '" . (int)$order_id . "' LIMIT 1");
+
+ if ($qry->num_rows) {
+ $order = $qry->row;
+ $order['transactions'] = $this->getTransactions($order['worldpay_order_id'], $qry->row['currency_code']);
+
+ return $order;
+ } else {
+ return false;
+ }
+ }
+
+ private function getTransactions($worldpay_order_id, $currency_code) {
+ $query = $this->db->query("SELECT * FROM `" . DB_PREFIX . "worldpay_order_transaction` WHERE `worldpay_order_id` = '" . (int)$worldpay_order_id . "'");
+
+ $transactions = array();
+ if ($query->num_rows) {
+ foreach ($query->rows as $row) {
+ $row['amount'] = $this->currency->format($row['amount'], $currency_code, false);
+ $transactions[] = $row;
+ }
+ return $transactions;
+ } else {
+ return false;
+ }
+ }
+
+ public function addTransaction($worldpay_order_id, $type, $total) {
+ $this->db->query("INSERT INTO `" . DB_PREFIX . "worldpay_order_transaction` SET `worldpay_order_id` = '" . (int)$worldpay_order_id . "', `date_added` = now(), `type` = '" . $this->db->escape($type) . "', `amount` = '" . (double)$total . "'");
+ }
+
+ public function getTotalReleased($worldpay_order_id) {
+ $query = $this->db->query("SELECT SUM(`amount`) AS `total` FROM `" . DB_PREFIX . "worldpay_order_transaction` WHERE `worldpay_order_id` = '" . (int)$worldpay_order_id . "' AND (`type` = 'payment' OR `type` = 'refund')");
+
+ return (double)$query->row['total'];
+ }
+
+ public function getTotalRefunded($worldpay_order_id) {
+ $query = $this->db->query("SELECT SUM(`amount`) AS `total` FROM `" . DB_PREFIX . "worldpay_order_transaction` WHERE `worldpay_order_id` = '" . (int)$worldpay_order_id . "' AND 'refund'");
+
+ return (double)$query->row['total'];
+ }
+
+ public function sendCurl($url, $order) {
+
+ $json = json_encode($order);
+
+ $curl = curl_init();
+
+ curl_setopt($curl, CURLOPT_URL, 'https://api.worldpay.com/v1/orders/' . $url);
+ curl_setopt($curl, CURLOPT_CUSTOMREQUEST, 'POST');
+ curl_setopt($curl, CURLOPT_POSTFIELDS, $json);
+ curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
+ curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 0);
+ curl_setopt($curl, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
+ curl_setopt($curl, CURLOPT_TIMEOUT, 10);
+ curl_setopt(
+ $curl, CURLOPT_HTTPHEADER, array(
+ "Authorization: " . $this->config->get('payment_worldpay_service_key'),
+ "Content-Type: application/json",
+ "Content-Length: " . strlen($json)
+ )
+ );
+
+ $result = json_decode(curl_exec($curl));
+ curl_close($curl);
+
+ $response = array();
+
+ if (isset($result)) {
+ $response['status'] = $result->httpStatusCode;
+ $response['message'] = $result->message;
+ $response['full_details'] = $result;
+ } else {
+ $response['status'] = 'success';
+ }
+
+ return $response;
+ }
+
+ public function logger($message) {
+ if ($this->config->get('payment_worldpay_debug') == 1) {
+ $log = new Log('worldpay.log');
+ $log->write($message);
+ }
+ }
+
+}
diff --git a/public/admin/model/extension/report/activity.php b/public/admin/model/extension/report/activity.php
new file mode 100644
index 0000000..94612f7
--- /dev/null
+++ b/public/admin/model/extension/report/activity.php
@@ -0,0 +1,8 @@
+<?php
+class ModelExtensionReportActivity extends Model {
+ public function getActivities() {
+ $query = $this->db->query("SELECT a.key, a.data, a.date_added FROM ((SELECT CONCAT('customer_', ca.key) AS `key`, ca.data, ca.date_added FROM `" . DB_PREFIX . "customer_activity` ca) UNION (SELECT CONCAT('affiliate_', aa.key) AS `key`, aa.data, aa.date_added FROM `" . DB_PREFIX . "affiliate_activity` aa)) a ORDER BY a.date_added DESC LIMIT 0,5");
+
+ return $query->rows;
+ }
+} \ No newline at end of file
diff --git a/public/admin/model/extension/report/coupon.php b/public/admin/model/extension/report/coupon.php
new file mode 100644
index 0000000..86038c7
--- /dev/null
+++ b/public/admin/model/extension/report/coupon.php
@@ -0,0 +1,60 @@
+<?php
+class ModelExtensionReportCoupon extends Model {
+ public function getCoupons($data = array()) {
+ $sql = "SELECT ch.coupon_id, c.name, c.code, COUNT(DISTINCT ch.order_id) AS `orders`, SUM(ch.amount) AS total FROM `" . DB_PREFIX . "coupon_history` ch LEFT JOIN `" . DB_PREFIX . "coupon` c ON (ch.coupon_id = c.coupon_id)";
+
+ $implode = array();
+
+ if (!empty($data['filter_date_start'])) {
+ $implode[] = "DATE(ch.date_added) >= '" . $this->db->escape($data['filter_date_start']) . "'";
+ }
+
+ if (!empty($data['filter_date_end'])) {
+ $implode[] = "DATE(ch.date_added) <= '" . $this->db->escape($data['filter_date_end']) . "'";
+ }
+
+ if ($implode) {
+ $sql .= " WHERE " . implode(" AND ", $implode);
+ }
+
+ $sql .= " GROUP BY ch.coupon_id ORDER BY total DESC";
+
+ 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'];
+ }
+
+ $query = $this->db->query($sql);
+
+ return $query->rows;
+ }
+
+ public function getTotalCoupons($data = array()) {
+ $sql = "SELECT COUNT(DISTINCT coupon_id) AS total FROM `" . DB_PREFIX . "coupon_history`";
+
+ $implode = array();
+
+ if (!empty($data['filter_date_start'])) {
+ $implode[] = "DATE(date_added) >= '" . $this->db->escape($data['filter_date_start']) . "'";
+ }
+
+ if (!empty($data['filter_date_end'])) {
+ $implode[] = "DATE(date_added) <= '" . $this->db->escape($data['filter_date_end']) . "'";
+ }
+
+ if ($implode) {
+ $sql .= " WHERE " . implode(" AND ", $implode);
+ }
+
+ $query = $this->db->query($sql);
+
+ return $query->row['total'];
+ }
+} \ No newline at end of file
diff --git a/public/admin/model/extension/report/customer.php b/public/admin/model/extension/report/customer.php
new file mode 100644
index 0000000..93e9c33
--- /dev/null
+++ b/public/admin/model/extension/report/customer.php
@@ -0,0 +1,380 @@
+<?php
+class ModelExtensionReportCustomer extends Model {
+ public function getTotalCustomersByDay() {
+ $customer_data = array();
+
+ for ($i = 0; $i < 24; $i++) {
+ $customer_data[$i] = array(
+ 'hour' => $i,
+ 'total' => 0
+ );
+ }
+
+ $query = $this->db->query("SELECT COUNT(*) AS total, HOUR(date_added) AS hour FROM `" . DB_PREFIX . "customer` WHERE DATE(date_added) = DATE(NOW()) GROUP BY HOUR(date_added) ORDER BY date_added ASC");
+
+ foreach ($query->rows as $result) {
+ $customer_data[$result['hour']] = array(
+ 'hour' => $result['hour'],
+ 'total' => $result['total']
+ );
+ }
+
+ return $customer_data;
+ }
+
+ public function getTotalCustomersByWeek() {
+ $customer_data = array();
+
+ $date_start = strtotime('-' . date('w') . ' days');
+
+ for ($i = 0; $i < 7; $i++) {
+ $date = date('Y-m-d', $date_start + ($i * 86400));
+
+ $customer_data[date('w', strtotime($date))] = array(
+ 'day' => date('D', strtotime($date)),
+ 'total' => 0
+ );
+ }
+
+ $query = $this->db->query("SELECT COUNT(*) AS total, date_added FROM `" . DB_PREFIX . "customer` WHERE DATE(date_added) >= DATE('" . $this->db->escape(date('Y-m-d', $date_start)) . "') GROUP BY DAYNAME(date_added)");
+
+ foreach ($query->rows as $result) {
+ $customer_data[date('w', strtotime($result['date_added']))] = array(
+ 'day' => date('D', strtotime($result['date_added'])),
+ 'total' => $result['total']
+ );
+ }
+
+ return $customer_data;
+ }
+
+ public function getTotalCustomersByMonth() {
+ $customer_data = array();
+
+ for ($i = 1; $i <= date('t'); $i++) {
+ $date = date('Y') . '-' . date('m') . '-' . $i;
+
+ $customer_data[date('j', strtotime($date))] = array(
+ 'day' => date('d', strtotime($date)),
+ 'total' => 0
+ );
+ }
+
+ $query = $this->db->query("SELECT COUNT(*) AS total, date_added FROM `" . DB_PREFIX . "customer` WHERE DATE(date_added) >= '" . $this->db->escape(date('Y') . '-' . date('m') . '-1') . "' GROUP BY DATE(date_added)");
+
+ foreach ($query->rows as $result) {
+ $customer_data[date('j', strtotime($result['date_added']))] = array(
+ 'day' => date('d', strtotime($result['date_added'])),
+ 'total' => $result['total']
+ );
+ }
+
+ return $customer_data;
+ }
+
+ public function getTotalCustomersByYear() {
+ $customer_data = array();
+
+ for ($i = 1; $i <= 12; $i++) {
+ $customer_data[$i] = array(
+ 'month' => date('M', mktime(0, 0, 0, $i)),
+ 'total' => 0
+ );
+ }
+
+ $query = $this->db->query("SELECT COUNT(*) AS total, date_added FROM `" . DB_PREFIX . "customer` WHERE YEAR(date_added) = YEAR(NOW()) GROUP BY MONTH(date_added)");
+
+ foreach ($query->rows as $result) {
+ $customer_data[date('n', strtotime($result['date_added']))] = array(
+ 'month' => date('M', strtotime($result['date_added'])),
+ 'total' => $result['total']
+ );
+ }
+
+ return $customer_data;
+ }
+
+ public function getOrders($data = array()) {
+ $sql = "SELECT c.customer_id, CONCAT(c.firstname, ' ', c.lastname) AS customer, c.email, cgd.name AS customer_group, c.status, o.order_id, SUM(op.quantity) as products, o.total AS total FROM `" . DB_PREFIX . "order` o LEFT JOIN `" . DB_PREFIX . "order_product` op ON (o.order_id = op.order_id) LEFT JOIN `" . DB_PREFIX . "customer` c ON (o.customer_id = c.customer_id) LEFT JOIN `" . DB_PREFIX . "customer_group_description` cgd ON (c.customer_group_id = cgd.customer_group_id) WHERE o.customer_id > 0 AND cgd.language_id = '" . (int)$this->config->get('config_language_id') . "'";
+
+ if (!empty($data['filter_date_start'])) {
+ $sql .= " AND DATE(o.date_added) >= '" . $this->db->escape($data['filter_date_start']) . "'";
+ }
+
+ if (!empty($data['filter_date_end'])) {
+ $sql .= " AND DATE(o.date_added) <= '" . $this->db->escape($data['filter_date_end']) . "'";
+ }
+
+ if (!empty($data['filter_customer'])) {
+ $sql .= " AND CONCAT(c.firstname, ' ', c.lastname) LIKE '" . $this->db->escape($data['filter_customer']) . "'";
+ }
+
+ if (!empty($data['filter_order_status_id'])) {
+ $sql .= " AND o.order_status_id = '" . (int)$data['filter_order_status_id'] . "'";
+ } else {
+ $sql .= " AND o.order_status_id > '0'";
+ }
+
+ $sql .= " GROUP BY o.order_id";
+
+ $sql = "SELECT t.customer_id, t.customer, t.email, t.customer_group, t.status, COUNT(DISTINCT t.order_id) AS orders, SUM(t.products) AS products, SUM(t.total) AS total FROM (" . $sql . ") AS t GROUP BY t.customer_id ORDER BY total DESC";
+
+ 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'];
+ }
+
+ $query = $this->db->query($sql);
+
+ return $query->rows;
+ }
+
+ public function getTotalOrders($data = array()) {
+ $sql = "SELECT COUNT(DISTINCT o.customer_id) AS total FROM `" . DB_PREFIX . "order` o LEFT JOIN `" . DB_PREFIX . "customer` c ON (o.customer_id = c.customer_id) WHERE o.customer_id > '0'";
+
+ if (!empty($data['filter_date_start'])) {
+ $sql .= " AND DATE(o.date_added) >= '" . $this->db->escape($data['filter_date_start']) . "'";
+ }
+
+ if (!empty($data['filter_date_end'])) {
+ $sql .= " AND DATE(o.date_added) <= '" . $this->db->escape($data['filter_date_end']) . "'";
+ }
+
+ if (!empty($data['filter_customer'])) {
+ $sql .= " AND CONCAT(c.firstname, ' ', c.lastname) LIKE '" . $this->db->escape($data['filter_customer']) . "'";
+ }
+
+ if (!empty($data['filter_order_status_id'])) {
+ $sql .= " AND o.order_status_id = '" . (int)$data['filter_order_status_id'] . "'";
+ } else {
+ $sql .= " AND o.order_status_id > '0'";
+ }
+
+ $query = $this->db->query($sql);
+
+ return $query->row['total'];
+ }
+
+ public function getRewardPoints($data = array()) {
+ $sql = "SELECT cr.customer_id, CONCAT(c.firstname, ' ', c.lastname) AS customer, c.email, cgd.name AS customer_group, c.status, SUM(cr.points) AS points, COUNT(o.order_id) AS orders, SUM(o.total) AS total FROM " . DB_PREFIX . "customer_reward cr LEFT JOIN `" . DB_PREFIX . "customer` c ON (cr.customer_id = c.customer_id) LEFT JOIN " . DB_PREFIX . "customer_group_description cgd ON (c.customer_group_id = cgd.customer_group_id) LEFT JOIN `" . DB_PREFIX . "order` o ON (cr.order_id = o.order_id) WHERE cgd.language_id = '" . (int)$this->config->get('config_language_id') . "'";
+
+ if (!empty($data['filter_date_start'])) {
+ $sql .= " AND DATE(cr.date_added) >= '" . $this->db->escape($data['filter_date_start']) . "'";
+ }
+
+ if (!empty($data['filter_date_end'])) {
+ $sql .= " AND DATE(cr.date_added) <= '" . $this->db->escape($data['filter_date_end']) . "'";
+ }
+
+ if (!empty($data['filter_customer'])) {
+ $sql .= " AND CONCAT(c.firstname, ' ', c.lastname) LIKE '" . $this->db->escape($data['filter_customer']) . "'";
+ }
+
+ $sql .= " GROUP BY cr.customer_id ORDER BY points DESC";
+
+ 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'];
+ }
+
+ $query = $this->db->query($sql);
+
+ return $query->rows;
+ }
+
+ public function getTotalRewardPoints($data = array()) {
+ $sql = "SELECT COUNT(DISTINCT cr.customer_id) AS total FROM `" . DB_PREFIX . "customer_reward` cr LEFT JOIN `" . DB_PREFIX . "customer` c ON (cr.customer_id = c.customer_id)";
+
+ $implode = array();
+
+ if (!empty($data['filter_date_start'])) {
+ $implode[] = "DATE(cr.date_added) >= '" . $this->db->escape($data['filter_date_start']) . "'";
+ }
+
+ if (!empty($data['filter_date_end'])) {
+ $implode[] = "DATE(cr.date_added) <= '" . $this->db->escape($data['filter_date_end']) . "'";
+ }
+
+ if (!empty($data['filter_customer'])) {
+ $implode[] = "CONCAT(c.firstname, ' ', c.lastname) LIKE '" . $this->db->escape($data['filter_customer']) . "'";
+ }
+
+ if ($implode) {
+ $sql .= " WHERE " . implode(" AND ", $implode);
+ }
+
+ $query = $this->db->query($sql);
+
+ return $query->row['total'];
+ }
+
+ public function getCustomerActivities($data = array()) {
+ $sql = "SELECT ca.customer_activity_id, ca.customer_id, ca.key, ca.data, ca.ip, ca.date_added FROM " . DB_PREFIX . "customer_activity ca LEFT JOIN " . DB_PREFIX . "customer c ON (ca.customer_id = c.customer_id)";
+
+ $implode = array();
+
+ if (!empty($data['filter_date_start'])) {
+ $implode[] = "DATE(ca.date_added) >= '" . $this->db->escape($data['filter_date_start']) . "'";
+ }
+
+ if (!empty($data['filter_date_end'])) {
+ $implode[] = "DATE(ca.date_added) <= '" . $this->db->escape($data['filter_date_end']) . "'";
+ }
+
+ if (!empty($data['filter_customer'])) {
+ $implode[] = "CONCAT(c.firstname, ' ', c.lastname) LIKE '" . $this->db->escape($data['filter_customer']) . "'";
+ }
+
+ if (!empty($data['filter_ip'])) {
+ $implode[] = "ca.ip LIKE '" . $this->db->escape($data['filter_ip']) . "'";
+ }
+
+ if ($implode) {
+ $sql .= " WHERE " . implode(" AND ", $implode);
+ }
+
+ $sql .= " ORDER BY ca.date_added DESC";
+
+ 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'];
+ }
+
+ $query = $this->db->query($sql);
+
+ return $query->rows;
+ }
+
+ public function getTotalCustomerActivities($data = array()) {
+ $sql = "SELECT COUNT(*) AS total FROM `" . DB_PREFIX . "customer_activity` ca LEFT JOIN " . DB_PREFIX . "customer c ON (ca.customer_id = c.customer_id)";
+
+ $implode = array();
+
+ if (!empty($data['filter_date_start'])) {
+ $implode[] = "DATE(ca.date_added) >= '" . $this->db->escape($data['filter_date_start']) . "'";
+ }
+
+ if (!empty($data['filter_date_end'])) {
+ $implode[] = "DATE(ca.date_added) <= '" . $this->db->escape($data['filter_date_end']) . "'";
+ }
+
+ if (!empty($data['filter_customer'])) {
+ $implode[] = "CONCAT(c.firstname, ' ', c.lastname) LIKE '" . $this->db->escape($data['filter_customer']) . "'";
+ }
+
+ if (!empty($data['filter_ip'])) {
+ $implode[] = "ca.ip LIKE '" . $this->db->escape($data['filter_ip']) . "'";
+ }
+
+ if ($implode) {
+ $sql .= " WHERE " . implode(" AND ", $implode);
+ }
+
+ $query = $this->db->query($sql);
+
+ return $query->row['total'];
+ }
+
+ public function getCustomerSearches($data = array()) {
+ $sql = "SELECT cs.customer_id, cs.keyword, cs.category_id, cs.products, cs.ip, cs.date_added, CONCAT(c.firstname, ' ', c.lastname) AS customer FROM " . DB_PREFIX . "customer_search cs LEFT JOIN " . DB_PREFIX . "customer c ON (cs.customer_id = c.customer_id)";
+
+ $implode = array();
+
+ if (!empty($data['filter_date_start'])) {
+ $implode[] = "DATE(cs.date_added) >= '" . $this->db->escape($data['filter_date_start']) . "'";
+ }
+
+ if (!empty($data['filter_date_end'])) {
+ $implode[] = "DATE(cs.date_added) <= '" . $this->db->escape($data['filter_date_end']) . "'";
+ }
+
+ if (!empty($data['filter_keyword'])) {
+ $implode[] = "cs.keyword LIKE '" . $this->db->escape($data['filter_keyword']) . "%'";
+ }
+
+ if (!empty($data['filter_customer'])) {
+ $implode[] = "CONCAT(c.firstname, ' ', c.lastname) LIKE '" . $this->db->escape($data['filter_customer']) . "'";
+ }
+
+ if (!empty($data['filter_ip'])) {
+ $implode[] = "cs.ip LIKE '" . $this->db->escape($data['filter_ip']) . "'";
+ }
+
+ if ($implode) {
+ $sql .= " WHERE " . implode(" AND ", $implode);
+ }
+
+ $sql .= " ORDER BY cs.date_added DESC";
+
+ 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'];
+ }
+
+ $query = $this->db->query($sql);
+
+ return $query->rows;
+ }
+
+ public function getTotalCustomerSearches($data = array()) {
+ $sql = "SELECT COUNT(*) AS total FROM `" . DB_PREFIX . "customer_search` cs LEFT JOIN " . DB_PREFIX . "customer c ON (cs.customer_id = c.customer_id)";
+
+ $implode = array();
+
+ if (!empty($data['filter_date_start'])) {
+ $implode[] = "DATE(cs.date_added) >= '" . $this->db->escape($data['filter_date_start']) . "'";
+ }
+
+ if (!empty($data['filter_date_end'])) {
+ $implode[] = "DATE(cs.date_added) <= '" . $this->db->escape($data['filter_date_end']) . "'";
+ }
+
+ if (!empty($data['filter_keyword'])) {
+ $implode[] = "cs.keyword LIKE '" . $this->db->escape($data['filter_keyword']) . "%'";
+ }
+
+ if (!empty($data['filter_customer'])) {
+ $implode[] = "CONCAT(c.firstname, ' ', c.lastname) LIKE '" . $this->db->escape($data['filter_customer']) . "'";
+ }
+
+ if (!empty($data['filter_ip'])) {
+ $implode[] = "cs.ip LIKE '" . $this->db->escape($data['filter_ip']) . "'";
+ }
+
+ if ($implode) {
+ $sql .= " WHERE " . implode(" AND ", $implode);
+ }
+
+ $query = $this->db->query($sql);
+
+ return $query->row['total'];
+ }
+}
diff --git a/public/admin/model/extension/report/customer_transaction.php b/public/admin/model/extension/report/customer_transaction.php
new file mode 100644
index 0000000..02ca94e
--- /dev/null
+++ b/public/admin/model/extension/report/customer_transaction.php
@@ -0,0 +1,62 @@
+<?php
+class ModelExtensionReportCustomerTransaction extends Model {
+ public function getTransactions($data = array()) {
+ $sql = "SELECT ct.customer_id, CONCAT(c.firstname, ' ', c.lastname) AS customer, c.email, cgd.name AS customer_group, c.status, SUM(ct.amount) AS total FROM `" . DB_PREFIX . "customer_transaction` ct LEFT JOIN `" . DB_PREFIX . "customer` c ON (ct.customer_id = c.customer_id) LEFT JOIN `" . DB_PREFIX . "customer_group_description` cgd ON (c.customer_group_id = cgd.customer_group_id) WHERE cgd.language_id = '" . (int)$this->config->get('config_language_id') . "'";
+
+ if (!empty($data['filter_date_start'])) {
+ $sql .= " AND DATE(ct.date_added) >= '" . $this->db->escape($data['filter_date_start']) . "'";
+ }
+
+ if (!empty($data['filter_date_end'])) {
+ $sql .= " AND DATE(ct.date_added) <= '" . $this->db->escape($data['filter_date_end']) . "'";
+ }
+
+ if (!empty($data['filter_customer'])) {
+ $sql .= " AND CONCAT(c.firstname, ' ', c.lastname) LIKE '" . $this->db->escape($data['filter_customer']) . "'";
+ }
+
+ $sql .= " GROUP BY ct.customer_id ORDER BY total DESC";
+
+ 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'];
+ }
+
+ $query = $this->db->query($sql);
+
+ return $query->rows;
+ }
+
+ public function getTotalTransactions($data = array()) {
+ $sql = "SELECT COUNT(DISTINCT ct.customer_id) AS total FROM `" . DB_PREFIX . "customer_transaction` ct LEFT JOIN `" . DB_PREFIX . "customer` c ON (ct.customer_id = c.customer_id)";
+
+ $implode = array();
+
+ if (!empty($data['filter_date_start'])) {
+ $implode[] = "DATE(ct.date_added) >= '" . $this->db->escape($data['filter_date_start']) . "'";
+ }
+
+ if (!empty($data['filter_date_end'])) {
+ $implode[] = "DATE(ct.date_added) <= '" . $this->db->escape($data['filter_date_end']) . "'";
+ }
+
+ if (!empty($data['filter_customer'])) {
+ $implode[] = "CONCAT(c.firstname, ' ', c.lastname) LIKE '" . $this->db->escape($data['filter_customer']) . "'";
+ }
+
+ if ($implode) {
+ $sql .= " WHERE " . implode(" AND ", $implode);
+ }
+
+ $query = $this->db->query($sql);
+
+ return $query->row['total'];
+ }
+} \ No newline at end of file
diff --git a/public/admin/model/extension/report/marketing.php b/public/admin/model/extension/report/marketing.php
new file mode 100644
index 0000000..0eba986
--- /dev/null
+++ b/public/admin/model/extension/report/marketing.php
@@ -0,0 +1,60 @@
+<?php
+class ModelExtensionReportMarketing extends Model {
+ public function getMarketing($data = array()) {
+ $sql = "SELECT m.marketing_id, m.name AS campaign, m.code, m.clicks AS clicks, (SELECT COUNT(DISTINCT order_id) FROM `" . DB_PREFIX . "order` o1 WHERE o1.marketing_id = m.marketing_id";
+
+ if (!empty($data['filter_order_status_id'])) {
+ $sql .= " AND o1.order_status_id = '" . (int)$data['filter_order_status_id'] . "'";
+ } else {
+ $sql .= " AND o1.order_status_id > '0'";
+ }
+
+ if (!empty($data['filter_date_start'])) {
+ $sql .= " AND DATE(o1.date_added) >= '" . $this->db->escape($data['filter_date_start']) . "'";
+ }
+
+ if (!empty($data['filter_date_end'])) {
+ $sql .= " AND DATE(o1.date_added) <= '" . $this->db->escape($data['filter_date_end']) . "'";
+ }
+
+ $sql .= ") AS `orders`, (SELECT SUM(total) FROM `" . DB_PREFIX . "order` o2 WHERE o2.marketing_id = m.marketing_id";
+
+ if (!empty($data['filter_order_status_id'])) {
+ $sql .= " AND o2.order_status_id = '" . (int)$data['filter_order_status_id'] . "'";
+ } else {
+ $sql .= " AND o2.order_status_id > '0'";
+ }
+
+ if (!empty($data['filter_date_start'])) {
+ $sql .= " AND DATE(o2.date_added) >= '" . $this->db->escape($data['filter_date_start']) . "'";
+ }
+
+ if (!empty($data['filter_date_end'])) {
+ $sql .= " AND DATE(o2.date_added) <= '" . $this->db->escape($data['filter_date_end']) . "'";
+ }
+
+ $sql .= " GROUP BY o2.marketing_id) AS `total` FROM `" . DB_PREFIX . "marketing` m ORDER BY m.date_added 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'];
+ }
+
+ $query = $this->db->query($sql);
+
+ return $query->rows;
+ }
+
+ public function getTotalMarketing($data = array()) {
+ $query = $this->db->query("SELECT COUNT(*) AS total FROM `" . DB_PREFIX . "marketing`");
+
+ return $query->row['total'];
+ }
+} \ No newline at end of file
diff --git a/public/admin/model/extension/report/product.php b/public/admin/model/extension/report/product.php
new file mode 100644
index 0000000..78a0ae0
--- /dev/null
+++ b/public/admin/model/extension/report/product.php
@@ -0,0 +1,96 @@
+<?php
+class ModelExtensionReportProduct extends Model {
+ public function getProductsViewed($data = array()) {
+ $sql = "SELECT pd.name, p.model, p.viewed FROM " . DB_PREFIX . "product p LEFT JOIN " . DB_PREFIX . "product_description pd ON (p.product_id = pd.product_id) WHERE pd.language_id = '" . (int)$this->config->get('config_language_id') . "' AND p.viewed > 0 ORDER BY p.viewed DESC";
+
+ 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'];
+ }
+
+ $query = $this->db->query($sql);
+
+ return $query->rows;
+ }
+
+ public function getTotalProductViews() {
+ $query = $this->db->query("SELECT SUM(viewed) AS total FROM " . DB_PREFIX . "product");
+
+ return $query->row['total'];
+ }
+
+ public function getTotalProductsViewed() {
+ $query = $this->db->query("SELECT COUNT(*) AS total FROM " . DB_PREFIX . "product WHERE viewed > 0");
+
+ return $query->row['total'];
+ }
+
+ public function reset() {
+ $this->db->query("UPDATE " . DB_PREFIX . "product SET viewed = '0'");
+ }
+
+ public function getPurchased($data = array()) {
+ $sql = "SELECT op.name, op.model, SUM(op.quantity) AS quantity, SUM((op.price + op.tax) * op.quantity) AS total FROM " . DB_PREFIX . "order_product op LEFT JOIN `" . DB_PREFIX . "order` o ON (op.order_id = o.order_id)";
+
+ if (!empty($data['filter_order_status_id'])) {
+ $sql .= " WHERE o.order_status_id = '" . (int)$data['filter_order_status_id'] . "'";
+ } else {
+ $sql .= " WHERE o.order_status_id > '0'";
+ }
+
+ if (!empty($data['filter_date_start'])) {
+ $sql .= " AND DATE(o.date_added) >= '" . $this->db->escape($data['filter_date_start']) . "'";
+ }
+
+ if (!empty($data['filter_date_end'])) {
+ $sql .= " AND DATE(o.date_added) <= '" . $this->db->escape($data['filter_date_end']) . "'";
+ }
+
+ $sql .= " GROUP BY op.product_id ORDER BY total DESC";
+
+ 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'];
+ }
+
+ $query = $this->db->query($sql);
+
+ return $query->rows;
+ }
+
+ public function getTotalPurchased($data) {
+ $sql = "SELECT COUNT(DISTINCT op.product_id) AS total FROM `" . DB_PREFIX . "order_product` op LEFT JOIN `" . DB_PREFIX . "order` o ON (op.order_id = o.order_id)";
+
+ if (!empty($data['filter_order_status_id'])) {
+ $sql .= " WHERE o.order_status_id = '" . (int)$data['filter_order_status_id'] . "'";
+ } else {
+ $sql .= " WHERE o.order_status_id > '0'";
+ }
+
+ if (!empty($data['filter_date_start'])) {
+ $sql .= " AND DATE(o.date_added) >= '" . $this->db->escape($data['filter_date_start']) . "'";
+ }
+
+ if (!empty($data['filter_date_end'])) {
+ $sql .= " AND DATE(o.date_added) <= '" . $this->db->escape($data['filter_date_end']) . "'";
+ }
+
+ $query = $this->db->query($sql);
+
+ return $query->row['total'];
+ }
+}
diff --git a/public/admin/model/extension/report/return.php b/public/admin/model/extension/report/return.php
new file mode 100644
index 0000000..1afff7b
--- /dev/null
+++ b/public/admin/model/extension/report/return.php
@@ -0,0 +1,100 @@
+<?php
+class ModelExtensionReportReturn extends Model {
+ public function getReturns($data = array()) {
+ $sql = "SELECT MIN(r.date_added) AS date_start, MAX(r.date_added) AS date_end, COUNT(r.return_id) AS `returns` FROM `" . DB_PREFIX . "return` r";
+
+ if (!empty($data['filter_return_status_id'])) {
+ $sql .= " WHERE r.return_status_id = '" . (int)$data['filter_return_status_id'] . "'";
+ } else {
+ $sql .= " WHERE r.return_status_id > '0'";
+ }
+
+ if (!empty($data['filter_date_start'])) {
+ $sql .= " AND DATE(r.date_added) >= '" . $this->db->escape($data['filter_date_start']) . "'";
+ }
+
+ if (!empty($data['filter_date_end'])) {
+ $sql .= " AND DATE(r.date_added) <= '" . $this->db->escape($data['filter_date_end']) . "'";
+ }
+
+ if (isset($data['filter_group'])) {
+ $group = $data['filter_group'];
+ } else {
+ $group = 'week';
+ }
+
+ switch($group) {
+ case 'day';
+ $sql .= " GROUP BY YEAR(r.date_added), MONTH(r.date_added), DAY(r.date_added)";
+ break;
+ default:
+ case 'week':
+ $sql .= " GROUP BY YEAR(r.date_added), WEEK(r.date_added)";
+ break;
+ case 'month':
+ $sql .= " GROUP BY YEAR(r.date_added), MONTH(r.date_added)";
+ break;
+ case 'year':
+ $sql .= " GROUP BY YEAR(r.date_added)";
+ break;
+ }
+
+ 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'];
+ }
+
+ $query = $this->db->query($sql);
+
+ return $query->rows;
+ }
+
+ public function getTotalReturns($data = array()) {
+ if (!empty($data['filter_group'])) {
+ $group = $data['filter_group'];
+ } else {
+ $group = 'week';
+ }
+
+ switch($group) {
+ case 'day';
+ $sql = "SELECT COUNT(DISTINCT YEAR(date_added), MONTH(date_added), DAY(date_added)) AS total FROM `" . DB_PREFIX . "return`";
+ break;
+ default:
+ case 'week':
+ $sql = "SELECT COUNT(DISTINCT YEAR(date_added), WEEK(date_added)) AS total FROM `" . DB_PREFIX . "return`";
+ break;
+ case 'month':
+ $sql = "SELECT COUNT(DISTINCT YEAR(date_added), MONTH(date_added)) AS total FROM `" . DB_PREFIX . "return`";
+ break;
+ case 'year':
+ $sql = "SELECT COUNT(DISTINCT YEAR(date_added)) AS total FROM `" . DB_PREFIX . "return`";
+ break;
+ }
+
+ if (!empty($data['filter_return_status_id'])) {
+ $sql .= " WHERE return_status_id = '" . (int)$data['filter_return_status_id'] . "'";
+ } else {
+ $sql .= " WHERE return_status_id > '0'";
+ }
+
+ if (!empty($data['filter_date_start'])) {
+ $sql .= " AND DATE(date_added) >= '" . $this->db->escape($data['filter_date_start']) . "'";
+ }
+
+ if (!empty($data['filter_date_end'])) {
+ $sql .= " AND DATE(date_added) <= '" . $this->db->escape($data['filter_date_end']) . "'";
+ }
+
+ $query = $this->db->query($sql);
+
+ return $query->row['total'];
+ }
+} \ No newline at end of file
diff --git a/public/admin/model/extension/report/sale.php b/public/admin/model/extension/report/sale.php
new file mode 100644
index 0000000..21073f5
--- /dev/null
+++ b/public/admin/model/extension/report/sale.php
@@ -0,0 +1,438 @@
+<?php
+class ModelExtensionReportSale extends Model {
+ public function getTotalSales($data = array()) {
+ $sql = "SELECT SUM(total) AS total FROM `" . DB_PREFIX . "order` WHERE order_status_id > '0'";
+
+ if (!empty($data['filter_date_added'])) {
+ $sql .= " AND DATE(date_added) = DATE('" . $this->db->escape($data['filter_date_added']) . "')";
+ }
+
+ $query = $this->db->query($sql);
+
+ return $query->row['total'];
+ }
+
+ public function getTotalOrdersByCountry() {
+ $query = $this->db->query("SELECT COUNT(*) AS total, SUM(o.total) AS amount, c.iso_code_2 FROM `" . DB_PREFIX . "order` o LEFT JOIN `" . DB_PREFIX . "country` c ON (o.payment_country_id = c.country_id) WHERE o.order_status_id > '0' GROUP BY o.payment_country_id");
+
+ return $query->rows;
+ }
+
+ public function getTotalOrdersByDay() {
+ $implode = array();
+
+ foreach ($this->config->get('config_complete_status') as $order_status_id) {
+ $implode[] = "'" . (int)$order_status_id . "'";
+ }
+
+ $order_data = array();
+
+ for ($i = 0; $i < 24; $i++) {
+ $order_data[$i] = array(
+ 'hour' => $i,
+ 'total' => 0
+ );
+ }
+
+ $query = $this->db->query("SELECT COUNT(*) AS total, HOUR(date_added) AS hour FROM `" . DB_PREFIX . "order` WHERE order_status_id IN(" . implode(",", $implode) . ") AND DATE(date_added) = DATE(NOW()) GROUP BY HOUR(date_added) ORDER BY date_added ASC");
+
+ foreach ($query->rows as $result) {
+ $order_data[$result['hour']] = array(
+ 'hour' => $result['hour'],
+ 'total' => $result['total']
+ );
+ }
+
+ return $order_data;
+ }
+
+ public function getTotalOrdersByWeek() {
+ $implode = array();
+
+ foreach ($this->config->get('config_complete_status') as $order_status_id) {
+ $implode[] = "'" . (int)$order_status_id . "'";
+ }
+
+ $order_data = array();
+
+ $date_start = strtotime('-' . date('w') . ' days');
+
+ for ($i = 0; $i < 7; $i++) {
+ $date = date('Y-m-d', $date_start + ($i * 86400));
+
+ $order_data[date('w', strtotime($date))] = array(
+ 'day' => date('D', strtotime($date)),
+ 'total' => 0
+ );
+ }
+
+ $query = $this->db->query("SELECT COUNT(*) AS total, date_added FROM `" . DB_PREFIX . "order` WHERE order_status_id IN(" . implode(",", $implode) . ") AND DATE(date_added) >= DATE('" . $this->db->escape(date('Y-m-d', $date_start)) . "') GROUP BY DAYNAME(date_added)");
+
+ foreach ($query->rows as $result) {
+ $order_data[date('w', strtotime($result['date_added']))] = array(
+ 'day' => date('D', strtotime($result['date_added'])),
+ 'total' => $result['total']
+ );
+ }
+
+ return $order_data;
+ }
+
+ public function getTotalOrdersByMonth() {
+ $implode = array();
+
+ foreach ($this->config->get('config_complete_status') as $order_status_id) {
+ $implode[] = "'" . (int)$order_status_id . "'";
+ }
+
+ $order_data = array();
+
+ for ($i = 1; $i <= date('t'); $i++) {
+ $date = date('Y') . '-' . date('m') . '-' . $i;
+
+ $order_data[date('j', strtotime($date))] = array(
+ 'day' => date('d', strtotime($date)),
+ 'total' => 0
+ );
+ }
+
+ $query = $this->db->query("SELECT COUNT(*) AS total, date_added FROM `" . DB_PREFIX . "order` WHERE order_status_id IN(" . implode(",", $implode) . ") AND DATE(date_added) >= '" . $this->db->escape(date('Y') . '-' . date('m') . '-1') . "' GROUP BY DATE(date_added)");
+
+ foreach ($query->rows as $result) {
+ $order_data[date('j', strtotime($result['date_added']))] = array(
+ 'day' => date('d', strtotime($result['date_added'])),
+ 'total' => $result['total']
+ );
+ }
+
+ return $order_data;
+ }
+
+ public function getTotalOrdersByYear() {
+ $implode = array();
+
+ foreach ($this->config->get('config_complete_status') as $order_status_id) {
+ $implode[] = "'" . (int)$order_status_id . "'";
+ }
+
+ $order_data = array();
+
+ for ($i = 1; $i <= 12; $i++) {
+ $order_data[$i] = array(
+ 'month' => date('M', mktime(0, 0, 0, $i)),
+ 'total' => 0
+ );
+ }
+
+ $query = $this->db->query("SELECT COUNT(*) AS total, date_added FROM `" . DB_PREFIX . "order` WHERE order_status_id IN(" . implode(",", $implode) . ") AND YEAR(date_added) = YEAR(NOW()) GROUP BY MONTH(date_added)");
+
+ foreach ($query->rows as $result) {
+ $order_data[date('n', strtotime($result['date_added']))] = array(
+ 'month' => date('M', strtotime($result['date_added'])),
+ 'total' => $result['total']
+ );
+ }
+
+ return $order_data;
+ }
+
+ public function getOrders($data = array()) {
+ $sql = "SELECT MIN(o.date_added) AS date_start, MAX(o.date_added) AS date_end, COUNT(*) AS `orders`, SUM((SELECT SUM(op.quantity) FROM `" . DB_PREFIX . "order_product` op WHERE op.order_id = o.order_id GROUP BY op.order_id)) AS products, SUM((SELECT SUM(ot.value) FROM `" . DB_PREFIX . "order_total` ot WHERE ot.order_id = o.order_id AND ot.code = 'tax' GROUP BY ot.order_id)) AS tax, SUM(o.total) AS `total` FROM `" . DB_PREFIX . "order` o";
+
+ if (!empty($data['filter_order_status_id'])) {
+ $sql .= " WHERE o.order_status_id = '" . (int)$data['filter_order_status_id'] . "'";
+ } else {
+ $sql .= " WHERE o.order_status_id > '0'";
+ }
+
+ if (!empty($data['filter_date_start'])) {
+ $sql .= " AND DATE(o.date_added) >= '" . $this->db->escape($data['filter_date_start']) . "'";
+ }
+
+ if (!empty($data['filter_date_end'])) {
+ $sql .= " AND DATE(o.date_added) <= '" . $this->db->escape($data['filter_date_end']) . "'";
+ }
+
+ if (!empty($data['filter_group'])) {
+ $group = $data['filter_group'];
+ } else {
+ $group = 'week';
+ }
+
+ switch($group) {
+ case 'day';
+ $sql .= " GROUP BY YEAR(o.date_added), MONTH(o.date_added), DAY(o.date_added)";
+ break;
+ default:
+ case 'week':
+ $sql .= " GROUP BY YEAR(o.date_added), WEEK(o.date_added)";
+ break;
+ case 'month':
+ $sql .= " GROUP BY YEAR(o.date_added), MONTH(o.date_added)";
+ break;
+ case 'year':
+ $sql .= " GROUP BY YEAR(o.date_added)";
+ break;
+ }
+
+ $sql .= " ORDER BY o.date_added DESC";
+
+ 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'];
+ }
+
+ $query = $this->db->query($sql);
+
+ return $query->rows;
+ }
+
+ public function getTotalOrders($data = array()) {
+ if (!empty($data['filter_group'])) {
+ $group = $data['filter_group'];
+ } else {
+ $group = 'week';
+ }
+
+ switch($group) {
+ case 'day';
+ $sql = "SELECT COUNT(DISTINCT YEAR(date_added), MONTH(date_added), DAY(date_added)) AS total FROM `" . DB_PREFIX . "order`";
+ break;
+ default:
+ case 'week':
+ $sql = "SELECT COUNT(DISTINCT YEAR(date_added), WEEK(date_added)) AS total FROM `" . DB_PREFIX . "order`";
+ break;
+ case 'month':
+ $sql = "SELECT COUNT(DISTINCT YEAR(date_added), MONTH(date_added)) AS total FROM `" . DB_PREFIX . "order`";
+ break;
+ case 'year':
+ $sql = "SELECT COUNT(DISTINCT YEAR(date_added)) AS total FROM `" . DB_PREFIX . "order`";
+ break;
+ }
+
+ if (!empty($data['filter_order_status_id'])) {
+ $sql .= " WHERE order_status_id = '" . (int)$data['filter_order_status_id'] . "'";
+ } else {
+ $sql .= " WHERE order_status_id > '0'";
+ }
+
+ if (!empty($data['filter_date_start'])) {
+ $sql .= " AND DATE(date_added) >= '" . $this->db->escape($data['filter_date_start']) . "'";
+ }
+
+ if (!empty($data['filter_date_end'])) {
+ $sql .= " AND DATE(date_added) <= '" . $this->db->escape($data['filter_date_end']) . "'";
+ }
+
+ $query = $this->db->query($sql);
+
+ return $query->row['total'];
+ }
+
+ public function getTaxes($data = array()) {
+ $sql = "SELECT MIN(o.date_added) AS date_start, MAX(o.date_added) AS date_end, ot.title, SUM(ot.value) AS total, COUNT(o.order_id) AS `orders` FROM `" . DB_PREFIX . "order` o LEFT JOIN `" . DB_PREFIX . "order_total` ot ON (ot.order_id = o.order_id) WHERE ot.code = 'tax'";
+
+ if (!empty($data['filter_order_status_id'])) {
+ $sql .= " AND o.order_status_id = '" . (int)$data['filter_order_status_id'] . "'";
+ } else {
+ $sql .= " AND o.order_status_id > '0'";
+ }
+
+ if (!empty($data['filter_date_start'])) {
+ $sql .= " AND DATE(o.date_added) >= '" . $this->db->escape($data['filter_date_start']) . "'";
+ }
+
+ if (!empty($data['filter_date_end'])) {
+ $sql .= " AND DATE(o.date_added) <= '" . $this->db->escape($data['filter_date_end']) . "'";
+ }
+
+ if (!empty($data['filter_group'])) {
+ $group = $data['filter_group'];
+ } else {
+ $group = 'week';
+ }
+
+ switch($group) {
+ case 'day';
+ $sql .= " GROUP BY YEAR(o.date_added), MONTH(o.date_added), DAY(o.date_added), ot.title";
+ break;
+ default:
+ case 'week':
+ $sql .= " GROUP BY YEAR(o.date_added), WEEK(o.date_added), ot.title";
+ break;
+ case 'month':
+ $sql .= " GROUP BY YEAR(o.date_added), MONTH(o.date_added), ot.title";
+ break;
+ case 'year':
+ $sql .= " GROUP BY YEAR(o.date_added), ot.title";
+ break;
+ }
+
+ 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'];
+ }
+
+ $query = $this->db->query($sql);
+
+ return $query->rows;
+ }
+
+ public function getTotalTaxes($data = array()) {
+ if (!empty($data['filter_group'])) {
+ $group = $data['filter_group'];
+ } else {
+ $group = 'week';
+ }
+
+ switch($group) {
+ case 'day';
+ $sql = "SELECT COUNT(DISTINCT YEAR(o.date_added), MONTH(o.date_added), DAY(o.date_added), ot.title) AS total FROM `" . DB_PREFIX . "order` o";
+ break;
+ default:
+ case 'week':
+ $sql = "SELECT COUNT(DISTINCT YEAR(o.date_added), WEEK(o.date_added), ot.title) AS total FROM `" . DB_PREFIX . "order` o";
+ break;
+ case 'month':
+ $sql = "SELECT COUNT(DISTINCT YEAR(o.date_added), MONTH(o.date_added), ot.title) AS total FROM `" . DB_PREFIX . "order` o";
+ break;
+ case 'year':
+ $sql = "SELECT COUNT(DISTINCT YEAR(o.date_added), ot.title) AS total FROM `" . DB_PREFIX . "order` o";
+ break;
+ }
+
+ $sql .= " LEFT JOIN `" . DB_PREFIX . "order_total` ot ON (o.order_id = ot.order_id) WHERE ot.code = 'tax'";
+
+ if (!empty($data['filter_order_status_id'])) {
+ $sql .= " AND o.order_status_id = '" . (int)$data['filter_order_status_id'] . "'";
+ } else {
+ $sql .= " AND o.order_status_id > '0'";
+ }
+
+ if (!empty($data['filter_date_start'])) {
+ $sql .= " AND DATE(o.date_added) >= '" . $this->db->escape($data['filter_date_start']) . "'";
+ }
+
+ if (!empty($data['filter_date_end'])) {
+ $sql .= " AND DATE(o.date_added) <= '" . $this->db->escape($data['filter_date_end']) . "'";
+ }
+
+ $query = $this->db->query($sql);
+
+ return $query->row['total'];
+ }
+
+ public function getShipping($data = array()) {
+ $sql = "SELECT MIN(o.date_added) AS date_start, MAX(o.date_added) AS date_end, ot.title, SUM(ot.value) AS total, COUNT(o.order_id) AS `orders` FROM `" . DB_PREFIX . "order` o LEFT JOIN `" . DB_PREFIX . "order_total` ot ON (o.order_id = ot.order_id) WHERE ot.code = 'shipping'";
+
+ if (!empty($data['filter_order_status_id'])) {
+ $sql .= " AND o.order_status_id = '" . (int)$data['filter_order_status_id'] . "'";
+ } else {
+ $sql .= " AND o.order_status_id > '0'";
+ }
+
+ if (!empty($data['filter_date_start'])) {
+ $sql .= " AND DATE(o.date_added) >= '" . $this->db->escape($data['filter_date_start']) . "'";
+ }
+
+ if (!empty($data['filter_date_end'])) {
+ $sql .= " AND DATE(o.date_added) <= '" . $this->db->escape($data['filter_date_end']) . "'";
+ }
+
+ if (!empty($data['filter_group'])) {
+ $group = $data['filter_group'];
+ } else {
+ $group = 'week';
+ }
+
+ switch($group) {
+ case 'day';
+ $sql .= " GROUP BY YEAR(o.date_added), MONTH(o.date_added), DAY(o.date_added), ot.title";
+ break;
+ default:
+ case 'week':
+ $sql .= " GROUP BY YEAR(o.date_added), WEEK(o.date_added), ot.title";
+ break;
+ case 'month':
+ $sql .= " GROUP BY YEAR(o.date_added), MONTH(o.date_added), ot.title";
+ break;
+ case 'year':
+ $sql .= " GROUP BY YEAR(o.date_added), ot.title";
+ break;
+ }
+
+ 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'];
+ }
+
+ $query = $this->db->query($sql);
+
+ return $query->rows;
+ }
+
+ public function getTotalShipping($data = array()) {
+ if (!empty($data['filter_group'])) {
+ $group = $data['filter_group'];
+ } else {
+ $group = 'week';
+ }
+
+ switch($group) {
+ case 'day';
+ $sql = "SELECT COUNT(DISTINCT YEAR(o.date_added), MONTH(o.date_added), DAY(o.date_added), ot.title) AS total FROM `" . DB_PREFIX . "order` o";
+ break;
+ default:
+ case 'week':
+ $sql = "SELECT COUNT(DISTINCT YEAR(o.date_added), WEEK(o.date_added), ot.title) AS total FROM `" . DB_PREFIX . "order` o";
+ break;
+ case 'month':
+ $sql = "SELECT COUNT(DISTINCT YEAR(o.date_added), MONTH(o.date_added), ot.title) AS total FROM `" . DB_PREFIX . "order` o";
+ break;
+ case 'year':
+ $sql = "SELECT COUNT(DISTINCT YEAR(o.date_added), ot.title) AS total FROM `" . DB_PREFIX . "order` o";
+ break;
+ }
+
+ $sql .= " LEFT JOIN `" . DB_PREFIX . "order_total` ot ON (o.order_id = ot.order_id) WHERE ot.code = 'shipping'";
+
+ if (!empty($data['filter_order_status_id'])) {
+ $sql .= " AND order_status_id = '" . (int)$data['filter_order_status_id'] . "'";
+ } else {
+ $sql .= " AND order_status_id > '0'";
+ }
+
+ if (!empty($data['filter_date_start'])) {
+ $sql .= " AND DATE(o.date_added) >= '" . $this->db->escape($data['filter_date_start']) . "'";
+ }
+
+ if (!empty($data['filter_date_end'])) {
+ $sql .= " AND DATE(o.date_added) <= '" . $this->db->escape($data['filter_date_end']) . "'";
+ }
+
+ $query = $this->db->query($sql);
+
+ return $query->row['total'];
+ }
+} \ No newline at end of file
diff --git a/public/admin/model/localisation/country.php b/public/admin/model/localisation/country.php
new file mode 100644
index 0000000..065ddf0
--- /dev/null
+++ b/public/admin/model/localisation/country.php
@@ -0,0 +1,86 @@
+<?php
+class ModelLocalisationCountry extends Model {
+ public function addCountry($data) {
+ $this->db->query("INSERT INTO " . DB_PREFIX . "country SET name = '" . $this->db->escape($data['name']) . "', iso_code_2 = '" . $this->db->escape($data['iso_code_2']) . "', iso_code_3 = '" . $this->db->escape($data['iso_code_3']) . "', address_format = '" . $this->db->escape($data['address_format']) . "', postcode_required = '" . (int)$data['postcode_required'] . "', status = '" . (int)$data['status'] . "'");
+
+ $this->cache->delete('country');
+
+ return $this->db->getLastId();
+ }
+
+ public function editCountry($country_id, $data) {
+ $this->db->query("UPDATE " . DB_PREFIX . "country SET name = '" . $this->db->escape($data['name']) . "', iso_code_2 = '" . $this->db->escape($data['iso_code_2']) . "', iso_code_3 = '" . $this->db->escape($data['iso_code_3']) . "', address_format = '" . $this->db->escape($data['address_format']) . "', postcode_required = '" . (int)$data['postcode_required'] . "', status = '" . (int)$data['status'] . "' WHERE country_id = '" . (int)$country_id . "'");
+
+ $this->cache->delete('country');
+ }
+
+ public function deleteCountry($country_id) {
+ $this->db->query("DELETE FROM " . DB_PREFIX . "country WHERE country_id = '" . (int)$country_id . "'");
+
+ $this->cache->delete('country');
+ }
+
+ public function getCountry($country_id) {
+ $query = $this->db->query("SELECT DISTINCT * FROM " . DB_PREFIX . "country WHERE country_id = '" . (int)$country_id . "'");
+
+ return $query->row;
+ }
+
+ public function getCountries($data = array()) {
+ if ($data) {
+ $sql = "SELECT * FROM " . DB_PREFIX . "country";
+
+ $sort_data = array(
+ 'name',
+ 'iso_code_2',
+ 'iso_code_3'
+ );
+
+ if (isset($data['sort']) && in_array($data['sort'], $sort_data)) {
+ $sql .= " ORDER BY " . $data['sort'];
+ } else {
+ $sql .= " ORDER BY name";
+ }
+
+ 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'];
+ }
+
+ $query = $this->db->query($sql);
+
+ return $query->rows;
+ } else {
+ $country_data = $this->cache->get('country.admin');
+
+ if (!$country_data) {
+ $query = $this->db->query("SELECT * FROM " . DB_PREFIX . "country ORDER BY name ASC");
+
+ $country_data = $query->rows;
+
+ $this->cache->set('country.admin', $country_data);
+ }
+
+ return $country_data;
+ }
+ }
+
+ public function getTotalCountries() {
+ $query = $this->db->query("SELECT COUNT(*) AS total FROM " . DB_PREFIX . "country");
+
+ return $query->row['total'];
+ }
+} \ No newline at end of file
diff --git a/public/admin/model/localisation/currency.php b/public/admin/model/localisation/currency.php
new file mode 100644
index 0000000..3e478e5
--- /dev/null
+++ b/public/admin/model/localisation/currency.php
@@ -0,0 +1,159 @@
+<?php
+class ModelLocalisationCurrency extends Model {
+ public function addCurrency($data) {
+ $this->db->query("INSERT INTO " . DB_PREFIX . "currency SET title = '" . $this->db->escape($data['title']) . "', code = '" . $this->db->escape($data['code']) . "', symbol_left = '" . $this->db->escape($data['symbol_left']) . "', symbol_right = '" . $this->db->escape($data['symbol_right']) . "', decimal_place = '" . $this->db->escape($data['decimal_place']) . "', value = '" . $this->db->escape($data['value']) . "', status = '" . (int)$data['status'] . "', date_modified = NOW()");
+
+ $currency_id = $this->db->getLastId();
+
+ if ($this->config->get('config_currency_auto')) {
+ $this->refresh(true);
+ }
+
+ $this->cache->delete('currency');
+
+ return $currency_id;
+ }
+
+ public function editCurrency($currency_id, $data) {
+ $this->db->query("UPDATE " . DB_PREFIX . "currency SET title = '" . $this->db->escape($data['title']) . "', code = '" . $this->db->escape($data['code']) . "', symbol_left = '" . $this->db->escape($data['symbol_left']) . "', symbol_right = '" . $this->db->escape($data['symbol_right']) . "', decimal_place = '" . $this->db->escape($data['decimal_place']) . "', value = '" . $this->db->escape($data['value']) . "', status = '" . (int)$data['status'] . "', date_modified = NOW() WHERE currency_id = '" . (int)$currency_id . "'");
+
+ $this->cache->delete('currency');
+ }
+
+ public function deleteCurrency($currency_id) {
+ $this->db->query("DELETE FROM " . DB_PREFIX . "currency WHERE currency_id = '" . (int)$currency_id . "'");
+
+ $this->cache->delete('currency');
+ }
+
+ public function getCurrency($currency_id) {
+ $query = $this->db->query("SELECT DISTINCT * FROM " . DB_PREFIX . "currency WHERE currency_id = '" . (int)$currency_id . "'");
+
+ return $query->row;
+ }
+
+ public function getCurrencyByCode($currency) {
+ $query = $this->db->query("SELECT DISTINCT * FROM " . DB_PREFIX . "currency WHERE code = '" . $this->db->escape($currency) . "'");
+
+ return $query->row;
+ }
+
+ public function getCurrencies($data = array()) {
+ if ($data) {
+ $sql = "SELECT * FROM " . DB_PREFIX . "currency";
+
+ $sort_data = array(
+ 'title',
+ 'code',
+ 'value',
+ 'date_modified'
+ );
+
+ if (isset($data['sort']) && in_array($data['sort'], $sort_data)) {
+ $sql .= " ORDER BY " . $data['sort'];
+ } else {
+ $sql .= " ORDER BY title";
+ }
+
+ 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'];
+ }
+
+ $query = $this->db->query($sql);
+
+ return $query->rows;
+ } else {
+ $currency_data = $this->cache->get('currency');
+
+ if (!$currency_data) {
+ $currency_data = array();
+
+ $query = $this->db->query("SELECT * FROM " . DB_PREFIX . "currency ORDER BY title ASC");
+
+ foreach ($query->rows as $result) {
+ $currency_data[$result['code']] = array(
+ 'currency_id' => $result['currency_id'],
+ 'title' => $result['title'],
+ 'code' => $result['code'],
+ 'symbol_left' => $result['symbol_left'],
+ 'symbol_right' => $result['symbol_right'],
+ 'decimal_place' => $result['decimal_place'],
+ 'value' => $result['value'],
+ 'status' => $result['status'],
+ 'date_modified' => $result['date_modified']
+ );
+ }
+
+ $this->cache->set('currency', $currency_data);
+ }
+
+ return $currency_data;
+ }
+ }
+
+ public function refresh($force = false) {
+ $currency_data = array();
+
+ if ($force) {
+ $query = $this->db->query("SELECT * FROM " . DB_PREFIX . "currency WHERE code != '" . $this->db->escape($this->config->get('config_currency')) . "'");
+ } else {
+ $query = $this->db->query("SELECT * FROM " . DB_PREFIX . "currency WHERE code != '" . $this->db->escape($this->config->get('config_currency')) . "' AND date_modified < '" . $this->db->escape(date('Y-m-d H:i:s', strtotime('-1 day'))) . "'");
+ }
+
+ foreach ($query->rows as $result) {
+ $currency_data[] = $this->config->get('config_currency') . $result['code'] . '=X';
+ $currency_data[] = $result['code'] . $this->config->get('config_currency') . '=X';
+ }
+
+ $curl = curl_init();
+
+ curl_setopt($curl, CURLOPT_URL, 'http://download.finance.yahoo.com/d/quotes.csv?s=' . implode(',', $currency_data) . '&f=sl1&e=.json');
+ curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
+ curl_setopt($curl, CURLOPT_HEADER, false);
+ curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 30);
+ curl_setopt($curl, CURLOPT_TIMEOUT, 30);
+
+ $content = curl_exec($curl);
+
+ curl_close($curl);
+
+ $line = explode("\n", trim($content));
+
+ for ($i = 0; $i < count($line); $i = $i + 2) {
+ $currency = utf8_substr($line[$i], 4, 3);
+ $value = utf8_substr($line[$i], 11, 6);
+
+ if ((float)$value < 1 && isset($line[$i + 1])) {
+ $value = (1 / utf8_substr($line[$i + 1], 11, 6));
+ }
+
+ if ((float)$value) {
+ $this->db->query("UPDATE " . DB_PREFIX . "currency SET value = '" . (float)$value . "', date_modified = '" . $this->db->escape(date('Y-m-d H:i:s')) . "' WHERE code = '" . $this->db->escape($currency) . "'");
+ }
+ }
+
+ $this->db->query("UPDATE " . DB_PREFIX . "currency SET value = '1.00000', date_modified = '" . $this->db->escape(date('Y-m-d H:i:s')) . "' WHERE code = '" . $this->db->escape($this->config->get('config_currency')) . "'");
+
+ $this->cache->delete('currency');
+ }
+
+ public function getTotalCurrencies() {
+ $query = $this->db->query("SELECT COUNT(*) AS total FROM " . DB_PREFIX . "currency");
+
+ return $query->row['total'];
+ }
+} \ No newline at end of file
diff --git a/public/admin/model/localisation/geo_zone.php b/public/admin/model/localisation/geo_zone.php
new file mode 100644
index 0000000..d682641
--- /dev/null
+++ b/public/admin/model/localisation/geo_zone.php
@@ -0,0 +1,130 @@
+<?php
+class ModelLocalisationGeoZone extends Model {
+ public function addGeoZone($data) {
+ $this->db->query("INSERT INTO " . DB_PREFIX . "geo_zone SET name = '" . $this->db->escape($data['name']) . "', description = '" . $this->db->escape($data['description']) . "', date_added = NOW()");
+
+ $geo_zone_id = $this->db->getLastId();
+
+ if (isset($data['zone_to_geo_zone'])) {
+ foreach ($data['zone_to_geo_zone'] as $value) {
+ $this->db->query("DELETE FROM " . DB_PREFIX . "zone_to_geo_zone WHERE geo_zone_id = '" . (int)$geo_zone_id . "' AND country_id = '" . (int)$value['country_id'] . "' AND zone_id = '" . (int)$value['zone_id'] . "'");
+
+ $this->db->query("INSERT INTO " . DB_PREFIX . "zone_to_geo_zone SET country_id = '" . (int)$value['country_id'] . "', zone_id = '" . (int)$value['zone_id'] . "', geo_zone_id = '" . (int)$geo_zone_id . "', date_added = NOW()");
+ }
+ }
+
+ $this->cache->delete('geo_zone');
+
+ return $geo_zone_id;
+ }
+
+ public function editGeoZone($geo_zone_id, $data) {
+ $this->db->query("UPDATE " . DB_PREFIX . "geo_zone SET name = '" . $this->db->escape($data['name']) . "', description = '" . $this->db->escape($data['description']) . "', date_modified = NOW() WHERE geo_zone_id = '" . (int)$geo_zone_id . "'");
+
+ $this->db->query("DELETE FROM " . DB_PREFIX . "zone_to_geo_zone WHERE geo_zone_id = '" . (int)$geo_zone_id . "'");
+
+ if (isset($data['zone_to_geo_zone'])) {
+ foreach ($data['zone_to_geo_zone'] as $value) {
+ $this->db->query("DELETE FROM " . DB_PREFIX . "zone_to_geo_zone WHERE geo_zone_id = '" . (int)$geo_zone_id . "' AND country_id = '" . (int)$value['country_id'] . "' AND zone_id = '" . (int)$value['zone_id'] . "'");
+
+ $this->db->query("INSERT INTO " . DB_PREFIX . "zone_to_geo_zone SET country_id = '" . (int)$value['country_id'] . "', zone_id = '" . (int)$value['zone_id'] . "', geo_zone_id = '" . (int)$geo_zone_id . "', date_added = NOW()");
+ }
+ }
+
+ $this->cache->delete('geo_zone');
+ }
+
+ public function deleteGeoZone($geo_zone_id) {
+ $this->db->query("DELETE FROM " . DB_PREFIX . "geo_zone WHERE geo_zone_id = '" . (int)$geo_zone_id . "'");
+ $this->db->query("DELETE FROM " . DB_PREFIX . "zone_to_geo_zone WHERE geo_zone_id = '" . (int)$geo_zone_id . "'");
+
+ $this->cache->delete('geo_zone');
+ }
+
+ public function getGeoZone($geo_zone_id) {
+ $query = $this->db->query("SELECT DISTINCT * FROM " . DB_PREFIX . "geo_zone WHERE geo_zone_id = '" . (int)$geo_zone_id . "'");
+
+ return $query->row;
+ }
+
+ public function getGeoZones($data = array()) {
+ if ($data) {
+ $sql = "SELECT * FROM " . DB_PREFIX . "geo_zone";
+
+ $sort_data = array(
+ 'name',
+ 'description'
+ );
+
+ if (isset($data['sort']) && in_array($data['sort'], $sort_data)) {
+ $sql .= " ORDER BY " . $data['sort'];
+ } else {
+ $sql .= " ORDER BY name";
+ }
+
+ 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'];
+ }
+
+ $query = $this->db->query($sql);
+
+ return $query->rows;
+ } else {
+ $geo_zone_data = $this->cache->get('geo_zone');
+
+ if (!$geo_zone_data) {
+ $query = $this->db->query("SELECT * FROM " . DB_PREFIX . "geo_zone ORDER BY name ASC");
+
+ $geo_zone_data = $query->rows;
+
+ $this->cache->set('geo_zone', $geo_zone_data);
+ }
+
+ return $geo_zone_data;
+ }
+ }
+
+ public function getTotalGeoZones() {
+ $query = $this->db->query("SELECT COUNT(*) AS total FROM " . DB_PREFIX . "geo_zone");
+
+ return $query->row['total'];
+ }
+
+ public function getZoneToGeoZones($geo_zone_id) {
+ $query = $this->db->query("SELECT * FROM " . DB_PREFIX . "zone_to_geo_zone WHERE geo_zone_id = '" . (int)$geo_zone_id . "'");
+
+ return $query->rows;
+ }
+
+ public function getTotalZoneToGeoZoneByGeoZoneId($geo_zone_id) {
+ $query = $this->db->query("SELECT COUNT(*) AS total FROM " . DB_PREFIX . "zone_to_geo_zone WHERE geo_zone_id = '" . (int)$geo_zone_id . "'");
+
+ return $query->row['total'];
+ }
+
+ public function getTotalZoneToGeoZoneByCountryId($country_id) {
+ $query = $this->db->query("SELECT COUNT(*) AS total FROM " . DB_PREFIX . "zone_to_geo_zone WHERE country_id = '" . (int)$country_id . "'");
+
+ return $query->row['total'];
+ }
+
+ public function getTotalZoneToGeoZoneByZoneId($zone_id) {
+ $query = $this->db->query("SELECT COUNT(*) AS total FROM " . DB_PREFIX . "zone_to_geo_zone WHERE zone_id = '" . (int)$zone_id . "'");
+
+ return $query->row['total'];
+ }
+} \ No newline at end of file
diff --git a/public/admin/model/localisation/language.php b/public/admin/model/localisation/language.php
new file mode 100644
index 0000000..2e48c6c
--- /dev/null
+++ b/public/admin/model/localisation/language.php
@@ -0,0 +1,313 @@
+<?php
+class ModelLocalisationLanguage extends Model {
+ public function addLanguage($data) {
+ $this->db->query("INSERT INTO " . DB_PREFIX . "language SET name = '" . $this->db->escape($data['name']) . "', code = '" . $this->db->escape($data['code']) . "', locale = '" . $this->db->escape($data['locale']) . "', sort_order = '" . (int)$data['sort_order'] . "', status = '" . (int)$data['status'] . "'");
+
+ $this->cache->delete('catalog.language');
+ $this->cache->delete('admin.language');
+
+ $language_id = $this->db->getLastId();
+
+ // Attribute
+ $query = $this->db->query("SELECT * FROM " . DB_PREFIX . "attribute_description WHERE language_id = '" . (int)$this->config->get('config_language_id') . "'");
+
+ foreach ($query->rows as $attribute) {
+ $this->db->query("INSERT INTO " . DB_PREFIX . "attribute_description SET attribute_id = '" . (int)$attribute['attribute_id'] . "', language_id = '" . (int)$language_id . "', name = '" . $this->db->escape($attribute['name']) . "'");
+ }
+
+ // Attribute Group
+ $query = $this->db->query("SELECT * FROM " . DB_PREFIX . "attribute_group_description WHERE language_id = '" . (int)$this->config->get('config_language_id') . "'");
+
+ foreach ($query->rows as $attribute_group) {
+ $this->db->query("INSERT INTO " . DB_PREFIX . "attribute_group_description SET attribute_group_id = '" . (int)$attribute_group['attribute_group_id'] . "', language_id = '" . (int)$language_id . "', name = '" . $this->db->escape($attribute_group['name']) . "'");
+ }
+
+ $this->cache->delete('attribute');
+
+ // Banner
+ $query = $this->db->query("SELECT * FROM " . DB_PREFIX . "banner_image WHERE language_id = '" . (int)$this->config->get('config_language_id') . "'");
+
+ foreach ($query->rows as $banner_image) {
+ $this->db->query("INSERT INTO " . DB_PREFIX . "banner_image SET banner_id = '" . (int)$banner_image['banner_id'] . "', language_id = '" . (int)$language_id . "', title = '" . $this->db->escape($banner_image['title']) . "', link = '" . $this->db->escape($banner_image['link']) . "', image = '" . $this->db->escape($banner_image['image']) . "', sort_order = '" . (int)$banner_image['sort_order'] . "'");
+ }
+
+ $this->cache->delete('banner');
+
+ // Category
+ $query = $this->db->query("SELECT * FROM " . DB_PREFIX . "category_description WHERE language_id = '" . (int)$this->config->get('config_language_id') . "'");
+
+ foreach ($query->rows as $category) {
+ $this->db->query("INSERT INTO " . DB_PREFIX . "category_description SET category_id = '" . (int)$category['category_id'] . "', language_id = '" . (int)$language_id . "', name = '" . $this->db->escape($category['name']) . "', description = '" . $this->db->escape($category['description']) . "', meta_title = '" . $this->db->escape($category['meta_title']) . "', meta_description = '" . $this->db->escape($category['meta_description']) . "', meta_keyword = '" . $this->db->escape($category['meta_keyword']) . "'");
+ }
+
+ $this->cache->delete('category');
+
+ // Customer Group
+ $query = $this->db->query("SELECT * FROM " . DB_PREFIX . "customer_group_description WHERE language_id = '" . (int)$this->config->get('config_language_id') . "'");
+
+ foreach ($query->rows as $customer_group) {
+ $this->db->query("INSERT INTO " . DB_PREFIX . "customer_group_description SET customer_group_id = '" . (int)$customer_group['customer_group_id'] . "', language_id = '" . (int)$language_id . "', name = '" . $this->db->escape($customer_group['name']) . "', description = '" . $this->db->escape($customer_group['description']) . "'");
+ }
+
+ // Custom Field
+ $query = $this->db->query("SELECT * FROM " . DB_PREFIX . "custom_field_description WHERE language_id = '" . (int)$this->config->get('config_language_id') . "'");
+
+ foreach ($query->rows as $custom_field) {
+ $this->db->query("INSERT INTO " . DB_PREFIX . "custom_field_description SET custom_field_id = '" . (int)$custom_field['custom_field_id'] . "', language_id = '" . (int)$language_id . "', name = '" . $this->db->escape($custom_field['name']) . "'");
+ }
+
+ // Custom Field Value
+ $query = $this->db->query("SELECT * FROM " . DB_PREFIX . "custom_field_value_description WHERE language_id = '" . (int)$this->config->get('config_language_id') . "'");
+
+ foreach ($query->rows as $custom_field_value) {
+ $this->db->query("INSERT INTO " . DB_PREFIX . "custom_field_value_description SET custom_field_value_id = '" . (int)$custom_field_value['custom_field_value_id'] . "', language_id = '" . (int)$language_id . "', custom_field_id = '" . (int)$custom_field_value['custom_field_id'] . "', name = '" . $this->db->escape($custom_field_value['name']) . "'");
+ }
+
+ // Download
+ $query = $this->db->query("SELECT * FROM " . DB_PREFIX . "download_description WHERE language_id = '" . (int)$this->config->get('config_language_id') . "'");
+
+ foreach ($query->rows as $download) {
+ $this->db->query("INSERT INTO " . DB_PREFIX . "download_description SET download_id = '" . (int)$download['download_id'] . "', language_id = '" . (int)$language_id . "', name = '" . $this->db->escape($download['name']) . "'");
+ }
+
+ // Filter
+ $query = $this->db->query("SELECT * FROM " . DB_PREFIX . "filter_description WHERE language_id = '" . (int)$this->config->get('config_language_id') . "'");
+
+ foreach ($query->rows as $filter) {
+ $this->db->query("INSERT INTO " . DB_PREFIX . "filter_description SET filter_id = '" . (int)$filter['filter_id'] . "', language_id = '" . (int)$language_id . "', filter_group_id = '" . (int)$filter['filter_group_id'] . "', name = '" . $this->db->escape($filter['name']) . "'");
+ }
+
+ // Filter Group
+ $query = $this->db->query("SELECT * FROM " . DB_PREFIX . "filter_group_description WHERE language_id = '" . (int)$this->config->get('config_language_id') . "'");
+
+ foreach ($query->rows as $filter_group) {
+ $this->db->query("INSERT INTO " . DB_PREFIX . "filter_group_description SET filter_group_id = '" . (int)$filter_group['filter_group_id'] . "', language_id = '" . (int)$language_id . "', name = '" . $this->db->escape($filter_group['name']) . "'");
+ }
+
+ // Information
+ $query = $this->db->query("SELECT * FROM " . DB_PREFIX . "information_description WHERE language_id = '" . (int)$this->config->get('config_language_id') . "'");
+
+ foreach ($query->rows as $information) {
+ $this->db->query("INSERT INTO " . DB_PREFIX . "information_description SET information_id = '" . (int)$information['information_id'] . "', language_id = '" . (int)$language_id . "', title = '" . $this->db->escape($information['title']) . "', description = '" . $this->db->escape($information['description']) . "', meta_title = '" . $this->db->escape($information['meta_title']) . "', meta_description = '" . $this->db->escape($information['meta_description']) . "', meta_keyword = '" . $this->db->escape($information['meta_keyword']) . "'");
+ }
+
+ $this->cache->delete('information');
+
+ // Length
+ $query = $this->db->query("SELECT * FROM " . DB_PREFIX . "length_class_description WHERE language_id = '" . (int)$this->config->get('config_language_id') . "'");
+
+ foreach ($query->rows as $length) {
+ $this->db->query("INSERT INTO " . DB_PREFIX . "length_class_description SET length_class_id = '" . (int)$length['length_class_id'] . "', language_id = '" . (int)$language_id . "', title = '" . $this->db->escape($length['title']) . "', unit = '" . $this->db->escape($length['unit']) . "'");
+ }
+
+ $this->cache->delete('length_class');
+
+ // Option
+ $query = $this->db->query("SELECT * FROM " . DB_PREFIX . "option_description WHERE language_id = '" . (int)$this->config->get('config_language_id') . "'");
+
+ foreach ($query->rows as $option) {
+ $this->db->query("INSERT INTO " . DB_PREFIX . "option_description SET option_id = '" . (int)$option['option_id'] . "', language_id = '" . (int)$language_id . "', name = '" . $this->db->escape($option['name']) . "'");
+ }
+
+ // Option Value
+ $query = $this->db->query("SELECT * FROM " . DB_PREFIX . "option_value_description WHERE language_id = '" . (int)$this->config->get('config_language_id') . "'");
+
+ foreach ($query->rows as $option_value) {
+ $this->db->query("INSERT INTO " . DB_PREFIX . "option_value_description SET option_value_id = '" . (int)$option_value['option_value_id'] . "', language_id = '" . (int)$language_id . "', option_id = '" . (int)$option_value['option_id'] . "', name = '" . $this->db->escape($option_value['name']) . "'");
+ }
+
+ // Order Status
+ $query = $this->db->query("SELECT * FROM " . DB_PREFIX . "order_status WHERE language_id = '" . (int)$this->config->get('config_language_id') . "'");
+
+ foreach ($query->rows as $order_status) {
+ $this->db->query("INSERT INTO " . DB_PREFIX . "order_status SET order_status_id = '" . (int)$order_status['order_status_id'] . "', language_id = '" . (int)$language_id . "', name = '" . $this->db->escape($order_status['name']) . "'");
+ }
+
+ $this->cache->delete('order_status');
+
+ // Product
+ $query = $this->db->query("SELECT * FROM " . DB_PREFIX . "product_description WHERE language_id = '" . (int)$this->config->get('config_language_id') . "'");
+
+ foreach ($query->rows as $product) {
+ $this->db->query("INSERT INTO " . DB_PREFIX . "product_description SET product_id = '" . (int)$product['product_id'] . "', language_id = '" . (int)$language_id . "', name = '" . $this->db->escape($product['name']) . "', description = '" . $this->db->escape($product['description']) . "', tag = '" . $this->db->escape($product['tag']) . "', meta_title = '" . $this->db->escape($product['meta_title']) . "', meta_description = '" . $this->db->escape($product['meta_description']) . "', meta_keyword = '" . $this->db->escape($product['meta_keyword']) . "'");
+ }
+
+ $this->cache->delete('product');
+
+ // Product Attribute
+ $query = $this->db->query("SELECT * FROM " . DB_PREFIX . "product_attribute WHERE language_id = '" . (int)$this->config->get('config_language_id') . "'");
+
+ foreach ($query->rows as $product_attribute) {
+ $this->db->query("INSERT INTO " . DB_PREFIX . "product_attribute SET product_id = '" . (int)$product_attribute['product_id'] . "', attribute_id = '" . (int)$product_attribute['attribute_id'] . "', language_id = '" . (int)$language_id . "', text = '" . $this->db->escape($product_attribute['text']) . "'");
+ }
+
+ // Return Action
+ $query = $this->db->query("SELECT * FROM " . DB_PREFIX . "return_action WHERE language_id = '" . (int)$this->config->get('config_language_id') . "'");
+
+ foreach ($query->rows as $return_action) {
+ $this->db->query("INSERT INTO " . DB_PREFIX . "return_action SET return_action_id = '" . (int)$return_action['return_action_id'] . "', language_id = '" . (int)$language_id . "', name = '" . $this->db->escape($return_action['name']) . "'");
+ }
+
+ // Return Reason
+ $query = $this->db->query("SELECT * FROM " . DB_PREFIX . "return_reason WHERE language_id = '" . (int)$this->config->get('config_language_id') . "'");
+
+ foreach ($query->rows as $return_reason) {
+ $this->db->query("INSERT INTO " . DB_PREFIX . "return_reason SET return_reason_id = '" . (int)$return_reason['return_reason_id'] . "', language_id = '" . (int)$language_id . "', name = '" . $this->db->escape($return_reason['name']) . "'");
+ }
+
+ // Return Status
+ $query = $this->db->query("SELECT * FROM " . DB_PREFIX . "return_status WHERE language_id = '" . (int)$this->config->get('config_language_id') . "'");
+
+ foreach ($query->rows as $return_status) {
+ $this->db->query("INSERT INTO " . DB_PREFIX . "return_status SET return_status_id = '" . (int)$return_status['return_status_id'] . "', language_id = '" . (int)$language_id . "', name = '" . $this->db->escape($return_status['name']) . "'");
+ }
+
+ // Stock Status
+ $query = $this->db->query("SELECT * FROM " . DB_PREFIX . "stock_status WHERE language_id = '" . (int)$this->config->get('config_language_id') . "'");
+
+ foreach ($query->rows as $stock_status) {
+ $this->db->query("INSERT INTO " . DB_PREFIX . "stock_status SET stock_status_id = '" . (int)$stock_status['stock_status_id'] . "', language_id = '" . (int)$language_id . "', name = '" . $this->db->escape($stock_status['name']) . "'");
+ }
+
+ $this->cache->delete('stock_status');
+
+ // Voucher Theme
+ $query = $this->db->query("SELECT * FROM " . DB_PREFIX . "voucher_theme_description WHERE language_id = '" . (int)$this->config->get('config_language_id') . "'");
+
+ foreach ($query->rows as $voucher_theme) {
+ $this->db->query("INSERT INTO " . DB_PREFIX . "voucher_theme_description SET voucher_theme_id = '" . (int)$voucher_theme['voucher_theme_id'] . "', language_id = '" . (int)$language_id . "', name = '" . $this->db->escape($voucher_theme['name']) . "'");
+ }
+
+ $this->cache->delete('voucher_theme');
+
+ // Weight Class
+ $query = $this->db->query("SELECT * FROM " . DB_PREFIX . "weight_class_description WHERE language_id = '" . (int)$this->config->get('config_language_id') . "'");
+
+ foreach ($query->rows as $weight_class) {
+ $this->db->query("INSERT INTO " . DB_PREFIX . "weight_class_description SET weight_class_id = '" . (int)$weight_class['weight_class_id'] . "', language_id = '" . (int)$language_id . "', title = '" . $this->db->escape($weight_class['title']) . "', unit = '" . $this->db->escape($weight_class['unit']) . "'");
+ }
+
+ $this->cache->delete('weight_class');
+
+ // Profiles
+ $query = $this->db->query("SELECT * FROM " . DB_PREFIX . "recurring_description WHERE language_id = '" . (int)$this->config->get('config_language_id') . "'");
+
+ foreach ($query->rows as $recurring) {
+ $this->db->query("INSERT INTO " . DB_PREFIX . "recurring_description SET recurring_id = '" . (int)$recurring['recurring_id'] . "', language_id = '" . (int)$language_id . "', name = '" . $this->db->escape($recurring['name']));
+ }
+
+ return $language_id;
+ }
+
+ public function editLanguage($language_id, $data) {
+ $language_query = $this->db->query("SELECT `code` FROM " . DB_PREFIX . "language WHERE language_id = '" . (int)$language_id . "'");
+
+ $this->db->query("UPDATE " . DB_PREFIX . "language SET name = '" . $this->db->escape($data['name']) . "', code = '" . $this->db->escape($data['code']) . "', locale = '" . $this->db->escape($data['locale']) . "', sort_order = '" . (int)$data['sort_order'] . "', status = '" . (int)$data['status'] . "' WHERE language_id = '" . (int)$language_id . "'");
+
+ if ($language_query->row['code'] != $data['code']) {
+ $this->db->query("UPDATE " . DB_PREFIX . "setting SET value = '" . $this->db->escape($data['code']) . "' WHERE `key` = 'config_language' AND value = '" . $this->db->escape($language_query->row['code']) . "'");
+ $this->db->query("UPDATE " . DB_PREFIX . "setting SET value = '" . $this->db->escape($data['code']) . "' WHERE `key` = 'config_admin_language' AND value = '" . $this->db->escape($language_query->row['code']) . "'");
+ }
+
+ $this->cache->delete('catalog.language');
+ $this->cache->delete('admin.language');
+ }
+
+ public function deleteLanguage($language_id) {
+ $this->db->query("DELETE FROM " . DB_PREFIX . "language WHERE language_id = '" . (int)$language_id . "'");
+
+ $this->cache->delete('catalog.language');
+ $this->cache->delete('admin.language');
+
+ /*
+ Do not put any delete code for related tables for languages!!!!!!!!!
+
+ It is not required as when ever you re save to a multi language table then the entries for the deleted language will also be deleted!
+
+ Wasting my time with people adding code here!
+ */
+ }
+
+ public function getLanguage($language_id) {
+ $query = $this->db->query("SELECT DISTINCT * FROM " . DB_PREFIX . "language WHERE language_id = '" . (int)$language_id . "'");
+
+ return $query->row;
+ }
+
+ public function getLanguages($data = array()) {
+ if ($data) {
+ $sql = "SELECT * FROM " . DB_PREFIX . "language";
+
+ $sort_data = array(
+ 'name',
+ 'code',
+ 'sort_order'
+ );
+
+ if (isset($data['sort']) && in_array($data['sort'], $sort_data)) {
+ $sql .= " ORDER BY " . $data['sort'];
+ } else {
+ $sql .= " ORDER BY sort_order, name";
+ }
+
+ 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'];
+ }
+
+ $query = $this->db->query($sql);
+
+ return $query->rows;
+ } else {
+ $language_data = $this->cache->get('language');
+
+ if (!$language_data) {
+ $language_data = array();
+
+ $query = $this->db->query("SELECT * FROM " . DB_PREFIX . "language ORDER BY sort_order, name");
+
+ foreach ($query->rows as $result) {
+ $language_data[$result['code']] = array(
+ 'language_id' => $result['language_id'],
+ 'name' => $result['name'],
+ 'code' => $result['code'],
+ 'locale' => $result['locale'],
+ 'image' => $result['image'],
+ 'directory' => $result['directory'],
+ 'sort_order' => $result['sort_order'],
+ 'status' => $result['status']
+ );
+ }
+
+ $this->cache->set('admin.language', $language_data);
+ }
+
+ return $language_data;
+ }
+ }
+
+ public function getLanguageByCode($code) {
+ $query = $this->db->query("SELECT * FROM `" . DB_PREFIX . "language` WHERE code = '" . $this->db->escape($code) . "'");
+
+ return $query->row;
+ }
+
+ public function getTotalLanguages() {
+ $query = $this->db->query("SELECT COUNT(*) AS total FROM " . DB_PREFIX . "language");
+
+ return $query->row['total'];
+ }
+}
diff --git a/public/admin/model/localisation/length_class.php b/public/admin/model/localisation/length_class.php
new file mode 100644
index 0000000..8de3b31
--- /dev/null
+++ b/public/admin/model/localisation/length_class.php
@@ -0,0 +1,120 @@
+<?php
+class ModelLocalisationLengthClass extends Model {
+ public function addLengthClass($data) {
+ $this->db->query("INSERT INTO " . DB_PREFIX . "length_class SET value = '" . (float)$data['value'] . "'");
+
+ $length_class_id = $this->db->getLastId();
+
+ foreach ($data['length_class_description'] as $language_id => $value) {
+ $this->db->query("INSERT INTO " . DB_PREFIX . "length_class_description SET length_class_id = '" . (int)$length_class_id . "', language_id = '" . (int)$language_id . "', title = '" . $this->db->escape($value['title']) . "', unit = '" . $this->db->escape($value['unit']) . "'");
+ }
+
+ $this->cache->delete('length_class');
+
+ return $length_class_id;
+ }
+
+ public function editLengthClass($length_class_id, $data) {
+ $this->db->query("UPDATE " . DB_PREFIX . "length_class SET value = '" . (float)$data['value'] . "' WHERE length_class_id = '" . (int)$length_class_id . "'");
+
+ $this->db->query("DELETE FROM " . DB_PREFIX . "length_class_description WHERE length_class_id = '" . (int)$length_class_id . "'");
+
+ foreach ($data['length_class_description'] as $language_id => $value) {
+ $this->db->query("INSERT INTO " . DB_PREFIX . "length_class_description SET length_class_id = '" . (int)$length_class_id . "', language_id = '" . (int)$language_id . "', title = '" . $this->db->escape($value['title']) . "', unit = '" . $this->db->escape($value['unit']) . "'");
+ }
+
+ $this->cache->delete('length_class');
+ }
+
+ public function deleteLengthClass($length_class_id) {
+ $this->db->query("DELETE FROM " . DB_PREFIX . "length_class WHERE length_class_id = '" . (int)$length_class_id . "'");
+ $this->db->query("DELETE FROM " . DB_PREFIX . "length_class_description WHERE length_class_id = '" . (int)$length_class_id . "'");
+
+ $this->cache->delete('length_class');
+ }
+
+ public function getLengthClasses($data = array()) {
+ if ($data) {
+ $sql = "SELECT * FROM " . DB_PREFIX . "length_class lc LEFT JOIN " . DB_PREFIX . "length_class_description lcd ON (lc.length_class_id = lcd.length_class_id) WHERE lcd.language_id = '" . (int)$this->config->get('config_language_id') . "'";
+
+ $sort_data = array(
+ 'title',
+ 'unit',
+ 'value'
+ );
+
+ if (isset($data['sort']) && in_array($data['sort'], $sort_data)) {
+ $sql .= " ORDER BY " . $data['sort'];
+ } else {
+ $sql .= " ORDER BY title";
+ }
+
+ 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'];
+ }
+
+ $query = $this->db->query($sql);
+
+ return $query->rows;
+ } else {
+ $length_class_data = $this->cache->get('length_class.' . (int)$this->config->get('config_language_id'));
+
+ if (!$length_class_data) {
+ $query = $this->db->query("SELECT * FROM " . DB_PREFIX . "length_class lc LEFT JOIN " . DB_PREFIX . "length_class_description lcd ON (lc.length_class_id = lcd.length_class_id) WHERE lcd.language_id = '" . (int)$this->config->get('config_language_id') . "'");
+
+ $length_class_data = $query->rows;
+
+ $this->cache->set('length_class.' . (int)$this->config->get('config_language_id'), $length_class_data);
+ }
+
+ return $length_class_data;
+ }
+ }
+
+ public function getLengthClass($length_class_id) {
+ $query = $this->db->query("SELECT * FROM " . DB_PREFIX . "length_class lc LEFT JOIN " . DB_PREFIX . "length_class_description lcd ON (lc.length_class_id = lcd.length_class_id) WHERE lc.length_class_id = '" . (int)$length_class_id . "' AND lcd.language_id = '" . (int)$this->config->get('config_language_id') . "'");
+
+ return $query->row;
+ }
+
+ public function getLengthClassDescriptionByUnit($unit) {
+ $query = $this->db->query("SELECT * FROM " . DB_PREFIX . "length_class_description WHERE unit = '" . $this->db->escape($unit) . "' AND language_id = '" . (int)$this->config->get('config_language_id') . "'");
+
+ return $query->row;
+ }
+
+ public function getLengthClassDescriptions($length_class_id) {
+ $length_class_data = array();
+
+ $query = $this->db->query("SELECT * FROM " . DB_PREFIX . "length_class_description WHERE length_class_id = '" . (int)$length_class_id . "'");
+
+ foreach ($query->rows as $result) {
+ $length_class_data[$result['language_id']] = array(
+ 'title' => $result['title'],
+ 'unit' => $result['unit']
+ );
+ }
+
+ return $length_class_data;
+ }
+
+ public function getTotalLengthClasses() {
+ $query = $this->db->query("SELECT COUNT(*) AS total FROM " . DB_PREFIX . "length_class");
+
+ return $query->row['total'];
+ }
+} \ No newline at end of file
diff --git a/public/admin/model/localisation/location.php b/public/admin/model/localisation/location.php
new file mode 100644
index 0000000..bda96fb
--- /dev/null
+++ b/public/admin/model/localisation/location.php
@@ -0,0 +1,65 @@
+<?php
+class ModelLocalisationLocation extends Model {
+ public function addLocation($data) {
+ $this->db->query("INSERT INTO " . DB_PREFIX . "location SET name = '" . $this->db->escape($data['name']) . "', address = '" . $this->db->escape($data['address']) . "', geocode = '" . $this->db->escape($data['geocode']) . "', telephone = '" . $this->db->escape($data['telephone']) . "', fax = '" . $this->db->escape($data['fax']) . "', image = '" . $this->db->escape($data['image']) . "', open = '" . $this->db->escape($data['open']) . "', comment = '" . $this->db->escape($data['comment']) . "'");
+
+ return $this->db->getLastId();
+ }
+
+ public function editLocation($location_id, $data) {
+ $this->db->query("UPDATE " . DB_PREFIX . "location SET name = '" . $this->db->escape($data['name']) . "', address = '" . $this->db->escape($data['address']) . "', geocode = '" . $this->db->escape($data['geocode']) . "', telephone = '" . $this->db->escape($data['telephone']) . "', fax = '" . $this->db->escape($data['fax']) . "', image = '" . $this->db->escape($data['image']) . "', open = '" . $this->db->escape($data['open']) . "', comment = '" . $this->db->escape($data['comment']) . "' WHERE location_id = '" . (int)$location_id . "'");
+ }
+
+ public function deleteLocation($location_id) {
+ $this->db->query("DELETE FROM " . DB_PREFIX . "location WHERE location_id = " . (int)$location_id);
+ }
+
+ public function getLocation($location_id) {
+ $query = $this->db->query("SELECT DISTINCT * FROM " . DB_PREFIX . "location WHERE location_id = '" . (int)$location_id . "'");
+
+ return $query->row;
+ }
+
+ public function getLocations($data = array()) {
+ $sql = "SELECT location_id, name, address FROM " . DB_PREFIX . "location";
+
+ $sort_data = array(
+ 'name',
+ 'address',
+ );
+
+ if (isset($data['sort']) && in_array($data['sort'], $sort_data)) {
+ $sql .= " ORDER BY " . $data['sort'];
+ } else {
+ $sql .= " ORDER BY name";
+ }
+
+ 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'];
+ }
+
+ $query = $this->db->query($sql);
+
+ return $query->rows;
+ }
+
+ public function getTotalLocations() {
+ $query = $this->db->query("SELECT COUNT(*) AS total FROM " . DB_PREFIX . "location");
+
+ return $query->row['total'];
+ }
+}
diff --git a/public/admin/model/localisation/order_status.php b/public/admin/model/localisation/order_status.php
new file mode 100644
index 0000000..7f98836
--- /dev/null
+++ b/public/admin/model/localisation/order_status.php
@@ -0,0 +1,100 @@
+<?php
+class ModelLocalisationOrderStatus extends Model {
+ public function addOrderStatus($data) {
+ foreach ($data['order_status'] as $language_id => $value) {
+ if (isset($order_status_id)) {
+ $this->db->query("INSERT INTO " . DB_PREFIX . "order_status SET order_status_id = '" . (int)$order_status_id . "', language_id = '" . (int)$language_id . "', name = '" . $this->db->escape($value['name']) . "'");
+ } else {
+ $this->db->query("INSERT INTO " . DB_PREFIX . "order_status SET language_id = '" . (int)$language_id . "', name = '" . $this->db->escape($value['name']) . "'");
+
+ $order_status_id = $this->db->getLastId();
+ }
+ }
+
+ $this->cache->delete('order_status');
+
+ return $order_status_id;
+ }
+
+ public function editOrderStatus($order_status_id, $data) {
+ $this->db->query("DELETE FROM " . DB_PREFIX . "order_status WHERE order_status_id = '" . (int)$order_status_id . "'");
+
+ foreach ($data['order_status'] as $language_id => $value) {
+ $this->db->query("INSERT INTO " . DB_PREFIX . "order_status SET order_status_id = '" . (int)$order_status_id . "', language_id = '" . (int)$language_id . "', name = '" . $this->db->escape($value['name']) . "'");
+ }
+
+ $this->cache->delete('order_status');
+ }
+
+ public function deleteOrderStatus($order_status_id) {
+ $this->db->query("DELETE FROM " . DB_PREFIX . "order_status WHERE order_status_id = '" . (int)$order_status_id . "'");
+
+ $this->cache->delete('order_status');
+ }
+
+ public function getOrderStatus($order_status_id) {
+ $query = $this->db->query("SELECT * FROM " . DB_PREFIX . "order_status WHERE order_status_id = '" . (int)$order_status_id . "' AND language_id = '" . (int)$this->config->get('config_language_id') . "'");
+
+ return $query->row;
+ }
+
+ public function getOrderStatuses($data = array()) {
+ if ($data) {
+ $sql = "SELECT * FROM " . DB_PREFIX . "order_status WHERE language_id = '" . (int)$this->config->get('config_language_id') . "'";
+
+ $sql .= " ORDER BY name";
+
+ 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'];
+ }
+
+ $query = $this->db->query($sql);
+
+ return $query->rows;
+ } else {
+ $order_status_data = $this->cache->get('order_status.' . (int)$this->config->get('config_language_id'));
+
+ if (!$order_status_data) {
+ $query = $this->db->query("SELECT order_status_id, name FROM " . DB_PREFIX . "order_status WHERE language_id = '" . (int)$this->config->get('config_language_id') . "' ORDER BY name");
+
+ $order_status_data = $query->rows;
+
+ $this->cache->set('order_status.' . (int)$this->config->get('config_language_id'), $order_status_data);
+ }
+
+ return $order_status_data;
+ }
+ }
+
+ public function getOrderStatusDescriptions($order_status_id) {
+ $order_status_data = array();
+
+ $query = $this->db->query("SELECT * FROM " . DB_PREFIX . "order_status WHERE order_status_id = '" . (int)$order_status_id . "'");
+
+ foreach ($query->rows as $result) {
+ $order_status_data[$result['language_id']] = array('name' => $result['name']);
+ }
+
+ return $order_status_data;
+ }
+
+ public function getTotalOrderStatuses() {
+ $query = $this->db->query("SELECT COUNT(*) AS total FROM " . DB_PREFIX . "order_status WHERE language_id = '" . (int)$this->config->get('config_language_id') . "'");
+
+ return $query->row['total'];
+ }
+} \ No newline at end of file
diff --git a/public/admin/model/localisation/return_action.php b/public/admin/model/localisation/return_action.php
new file mode 100644
index 0000000..a121217
--- /dev/null
+++ b/public/admin/model/localisation/return_action.php
@@ -0,0 +1,100 @@
+<?php
+class ModelLocalisationReturnAction extends Model {
+ public function addReturnAction($data) {
+ foreach ($data['return_action'] as $language_id => $value) {
+ if (isset($return_action_id)) {
+ $this->db->query("INSERT INTO " . DB_PREFIX . "return_action SET return_action_id = '" . (int)$return_action_id . "', language_id = '" . (int)$language_id . "', name = '" . $this->db->escape($value['name']) . "'");
+ } else {
+ $this->db->query("INSERT INTO " . DB_PREFIX . "return_action SET language_id = '" . (int)$language_id . "', name = '" . $this->db->escape($value['name']) . "'");
+
+ $return_action_id = $this->db->getLastId();
+ }
+ }
+
+ $this->cache->delete('return_action');
+
+ return $return_action_id;
+ }
+
+ public function editReturnAction($return_action_id, $data) {
+ $this->db->query("DELETE FROM " . DB_PREFIX . "return_action WHERE return_action_id = '" . (int)$return_action_id . "'");
+
+ foreach ($data['return_action'] as $language_id => $value) {
+ $this->db->query("INSERT INTO " . DB_PREFIX . "return_action SET return_action_id = '" . (int)$return_action_id . "', language_id = '" . (int)$language_id . "', name = '" . $this->db->escape($value['name']) . "'");
+ }
+
+ $this->cache->delete('return_action');
+ }
+
+ public function deleteReturnAction($return_action_id) {
+ $this->db->query("DELETE FROM " . DB_PREFIX . "return_action WHERE return_action_id = '" . (int)$return_action_id . "'");
+
+ $this->cache->delete('return_action');
+ }
+
+ public function getReturnAction($return_action_id) {
+ $query = $this->db->query("SELECT * FROM " . DB_PREFIX . "return_action WHERE return_action_id = '" . (int)$return_action_id . "' AND language_id = '" . (int)$this->config->get('config_language_id') . "'");
+
+ return $query->row;
+ }
+
+ public function getReturnActions($data = array()) {
+ if ($data) {
+ $sql = "SELECT * FROM " . DB_PREFIX . "return_action WHERE language_id = '" . (int)$this->config->get('config_language_id') . "'";
+
+ $sql .= " ORDER BY name";
+
+ 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'];
+ }
+
+ $query = $this->db->query($sql);
+
+ return $query->rows;
+ } else {
+ $return_action_data = $this->cache->get('return_action.' . (int)$this->config->get('config_language_id'));
+
+ if (!$return_action_data) {
+ $query = $this->db->query("SELECT return_action_id, name FROM " . DB_PREFIX . "return_action WHERE language_id = '" . (int)$this->config->get('config_language_id') . "' ORDER BY name");
+
+ $return_action_data = $query->rows;
+
+ $this->cache->set('return_action.' . (int)$this->config->get('config_language_id'), $return_action_data);
+ }
+
+ return $return_action_data;
+ }
+ }
+
+ public function getReturnActionDescriptions($return_action_id) {
+ $return_action_data = array();
+
+ $query = $this->db->query("SELECT * FROM " . DB_PREFIX . "return_action WHERE return_action_id = '" . (int)$return_action_id . "'");
+
+ foreach ($query->rows as $result) {
+ $return_action_data[$result['language_id']] = array('name' => $result['name']);
+ }
+
+ return $return_action_data;
+ }
+
+ public function getTotalReturnActions() {
+ $query = $this->db->query("SELECT COUNT(*) AS total FROM " . DB_PREFIX . "return_action WHERE language_id = '" . (int)$this->config->get('config_language_id') . "'");
+
+ return $query->row['total'];
+ }
+} \ No newline at end of file
diff --git a/public/admin/model/localisation/return_reason.php b/public/admin/model/localisation/return_reason.php
new file mode 100644
index 0000000..b33ca3c
--- /dev/null
+++ b/public/admin/model/localisation/return_reason.php
@@ -0,0 +1,100 @@
+<?php
+class ModelLocalisationReturnReason extends Model {
+ public function addReturnReason($data) {
+ foreach ($data['return_reason'] as $language_id => $value) {
+ if (isset($return_reason_id)) {
+ $this->db->query("INSERT INTO " . DB_PREFIX . "return_reason SET return_reason_id = '" . (int)$return_reason_id . "', language_id = '" . (int)$language_id . "', name = '" . $this->db->escape($value['name']) . "'");
+ } else {
+ $this->db->query("INSERT INTO " . DB_PREFIX . "return_reason SET language_id = '" . (int)$language_id . "', name = '" . $this->db->escape($value['name']) . "'");
+
+ $return_reason_id = $this->db->getLastId();
+ }
+ }
+
+ $this->cache->delete('return_reason');
+
+ return $return_reason_id;
+ }
+
+ public function editReturnReason($return_reason_id, $data) {
+ $this->db->query("DELETE FROM " . DB_PREFIX . "return_reason WHERE return_reason_id = '" . (int)$return_reason_id . "'");
+
+ foreach ($data['return_reason'] as $language_id => $value) {
+ $this->db->query("INSERT INTO " . DB_PREFIX . "return_reason SET return_reason_id = '" . (int)$return_reason_id . "', language_id = '" . (int)$language_id . "', name = '" . $this->db->escape($value['name']) . "'");
+ }
+
+ $this->cache->delete('return_reason');
+ }
+
+ public function deleteReturnReason($return_reason_id) {
+ $this->db->query("DELETE FROM " . DB_PREFIX . "return_reason WHERE return_reason_id = '" . (int)$return_reason_id . "'");
+
+ $this->cache->delete('return_reason');
+ }
+
+ public function getReturnReason($return_reason_id) {
+ $query = $this->db->query("SELECT * FROM " . DB_PREFIX . "return_reason WHERE return_reason_id = '" . (int)$return_reason_id . "' AND language_id = '" . (int)$this->config->get('config_language_id') . "'");
+
+ return $query->row;
+ }
+
+ public function getReturnReasons($data = array()) {
+ if ($data) {
+ $sql = "SELECT * FROM " . DB_PREFIX . "return_reason WHERE language_id = '" . (int)$this->config->get('config_language_id') . "'";
+
+ $sql .= " ORDER BY name";
+
+ 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'];
+ }
+
+ $query = $this->db->query($sql);
+
+ return $query->rows;
+ } else {
+ $return_reason_data = $this->cache->get('return_reason.' . (int)$this->config->get('config_language_id'));
+
+ if (!$return_reason_data) {
+ $query = $this->db->query("SELECT return_reason_id, name FROM " . DB_PREFIX . "return_reason WHERE language_id = '" . (int)$this->config->get('config_language_id') . "' ORDER BY name");
+
+ $return_reason_data = $query->rows;
+
+ $this->cache->set('return_reason.' . (int)$this->config->get('config_language_id'), $return_reason_data);
+ }
+
+ return $return_reason_data;
+ }
+ }
+
+ public function getReturnReasonDescriptions($return_reason_id) {
+ $return_reason_data = array();
+
+ $query = $this->db->query("SELECT * FROM " . DB_PREFIX . "return_reason WHERE return_reason_id = '" . (int)$return_reason_id . "'");
+
+ foreach ($query->rows as $result) {
+ $return_reason_data[$result['language_id']] = array('name' => $result['name']);
+ }
+
+ return $return_reason_data;
+ }
+
+ public function getTotalReturnReasons() {
+ $query = $this->db->query("SELECT COUNT(*) AS total FROM " . DB_PREFIX . "return_reason WHERE language_id = '" . (int)$this->config->get('config_language_id') . "'");
+
+ return $query->row['total'];
+ }
+} \ No newline at end of file
diff --git a/public/admin/model/localisation/return_status.php b/public/admin/model/localisation/return_status.php
new file mode 100644
index 0000000..8f258df
--- /dev/null
+++ b/public/admin/model/localisation/return_status.php
@@ -0,0 +1,100 @@
+<?php
+class ModelLocalisationReturnStatus extends Model {
+ public function addReturnStatus($data) {
+ foreach ($data['return_status'] as $language_id => $value) {
+ if (isset($return_status_id)) {
+ $this->db->query("INSERT INTO " . DB_PREFIX . "return_status SET return_status_id = '" . (int)$return_status_id . "', language_id = '" . (int)$language_id . "', name = '" . $this->db->escape($value['name']) . "'");
+ } else {
+ $this->db->query("INSERT INTO " . DB_PREFIX . "return_status SET language_id = '" . (int)$language_id . "', name = '" . $this->db->escape($value['name']) . "'");
+
+ $return_status_id = $this->db->getLastId();
+ }
+ }
+
+ $this->cache->delete('return_status');
+
+ return $return_status_id;
+ }
+
+ public function editReturnStatus($return_status_id, $data) {
+ $this->db->query("DELETE FROM " . DB_PREFIX . "return_status WHERE return_status_id = '" . (int)$return_status_id . "'");
+
+ foreach ($data['return_status'] as $language_id => $value) {
+ $this->db->query("INSERT INTO " . DB_PREFIX . "return_status SET return_status_id = '" . (int)$return_status_id . "', language_id = '" . (int)$language_id . "', name = '" . $this->db->escape($value['name']) . "'");
+ }
+
+ $this->cache->delete('return_status');
+ }
+
+ public function deleteReturnStatus($return_status_id) {
+ $this->db->query("DELETE FROM " . DB_PREFIX . "return_status WHERE return_status_id = '" . (int)$return_status_id . "'");
+
+ $this->cache->delete('return_status');
+ }
+
+ public function getReturnStatus($return_status_id) {
+ $query = $this->db->query("SELECT * FROM " . DB_PREFIX . "return_status WHERE return_status_id = '" . (int)$return_status_id . "' AND language_id = '" . (int)$this->config->get('config_language_id') . "'");
+
+ return $query->row;
+ }
+
+ public function getReturnStatuses($data = array()) {
+ if ($data) {
+ $sql = "SELECT * FROM " . DB_PREFIX . "return_status WHERE language_id = '" . (int)$this->config->get('config_language_id') . "'";
+
+ $sql .= " ORDER BY name";
+
+ 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'];
+ }
+
+ $query = $this->db->query($sql);
+
+ return $query->rows;
+ } else {
+ $return_status_data = $this->cache->get('return_status.' . (int)$this->config->get('config_language_id'));
+
+ if (!$return_status_data) {
+ $query = $this->db->query("SELECT return_status_id, name FROM " . DB_PREFIX . "return_status WHERE language_id = '" . (int)$this->config->get('config_language_id') . "' ORDER BY name");
+
+ $return_status_data = $query->rows;
+
+ $this->cache->set('return_status.' . (int)$this->config->get('config_language_id'), $return_status_data);
+ }
+
+ return $return_status_data;
+ }
+ }
+
+ public function getReturnStatusDescriptions($return_status_id) {
+ $return_status_data = array();
+
+ $query = $this->db->query("SELECT * FROM " . DB_PREFIX . "return_status WHERE return_status_id = '" . (int)$return_status_id . "'");
+
+ foreach ($query->rows as $result) {
+ $return_status_data[$result['language_id']] = array('name' => $result['name']);
+ }
+
+ return $return_status_data;
+ }
+
+ public function getTotalReturnStatuses() {
+ $query = $this->db->query("SELECT COUNT(*) AS total FROM " . DB_PREFIX . "return_status WHERE language_id = '" . (int)$this->config->get('config_language_id') . "'");
+
+ return $query->row['total'];
+ }
+} \ No newline at end of file
diff --git a/public/admin/model/localisation/stock_status.php b/public/admin/model/localisation/stock_status.php
new file mode 100644
index 0000000..dd5a2d6
--- /dev/null
+++ b/public/admin/model/localisation/stock_status.php
@@ -0,0 +1,100 @@
+<?php
+class ModelLocalisationStockStatus extends Model {
+ public function addStockStatus($data) {
+ foreach ($data['stock_status'] as $language_id => $value) {
+ if (isset($stock_status_id)) {
+ $this->db->query("INSERT INTO " . DB_PREFIX . "stock_status SET stock_status_id = '" . (int)$stock_status_id . "', language_id = '" . (int)$language_id . "', name = '" . $this->db->escape($value['name']) . "'");
+ } else {
+ $this->db->query("INSERT INTO " . DB_PREFIX . "stock_status SET language_id = '" . (int)$language_id . "', name = '" . $this->db->escape($value['name']) . "'");
+
+ $stock_status_id = $this->db->getLastId();
+ }
+ }
+
+ $this->cache->delete('stock_status');
+
+ return $stock_status_id;
+ }
+
+ public function editStockStatus($stock_status_id, $data) {
+ $this->db->query("DELETE FROM " . DB_PREFIX . "stock_status WHERE stock_status_id = '" . (int)$stock_status_id . "'");
+
+ foreach ($data['stock_status'] as $language_id => $value) {
+ $this->db->query("INSERT INTO " . DB_PREFIX . "stock_status SET stock_status_id = '" . (int)$stock_status_id . "', language_id = '" . (int)$language_id . "', name = '" . $this->db->escape($value['name']) . "'");
+ }
+
+ $this->cache->delete('stock_status');
+ }
+
+ public function deleteStockStatus($stock_status_id) {
+ $this->db->query("DELETE FROM " . DB_PREFIX . "stock_status WHERE stock_status_id = '" . (int)$stock_status_id . "'");
+
+ $this->cache->delete('stock_status');
+ }
+
+ public function getStockStatus($stock_status_id) {
+ $query = $this->db->query("SELECT * FROM " . DB_PREFIX . "stock_status WHERE stock_status_id = '" . (int)$stock_status_id . "' AND language_id = '" . (int)$this->config->get('config_language_id') . "'");
+
+ return $query->row;
+ }
+
+ public function getStockStatuses($data = array()) {
+ if ($data) {
+ $sql = "SELECT * FROM " . DB_PREFIX . "stock_status WHERE language_id = '" . (int)$this->config->get('config_language_id') . "'";
+
+ $sql .= " ORDER BY name";
+
+ 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'];
+ }
+
+ $query = $this->db->query($sql);
+
+ return $query->rows;
+ } else {
+ $stock_status_data = $this->cache->get('stock_status.' . (int)$this->config->get('config_language_id'));
+
+ if (!$stock_status_data) {
+ $query = $this->db->query("SELECT stock_status_id, name FROM " . DB_PREFIX . "stock_status WHERE language_id = '" . (int)$this->config->get('config_language_id') . "' ORDER BY name");
+
+ $stock_status_data = $query->rows;
+
+ $this->cache->set('stock_status.' . (int)$this->config->get('config_language_id'), $stock_status_data);
+ }
+
+ return $stock_status_data;
+ }
+ }
+
+ public function getStockStatusDescriptions($stock_status_id) {
+ $stock_status_data = array();
+
+ $query = $this->db->query("SELECT * FROM " . DB_PREFIX . "stock_status WHERE stock_status_id = '" . (int)$stock_status_id . "'");
+
+ foreach ($query->rows as $result) {
+ $stock_status_data[$result['language_id']] = array('name' => $result['name']);
+ }
+
+ return $stock_status_data;
+ }
+
+ public function getTotalStockStatuses() {
+ $query = $this->db->query("SELECT COUNT(*) AS total FROM " . DB_PREFIX . "stock_status WHERE language_id = '" . (int)$this->config->get('config_language_id') . "'");
+
+ return $query->row['total'];
+ }
+} \ No newline at end of file
diff --git a/public/admin/model/localisation/tax_class.php b/public/admin/model/localisation/tax_class.php
new file mode 100644
index 0000000..43b2164
--- /dev/null
+++ b/public/admin/model/localisation/tax_class.php
@@ -0,0 +1,105 @@
+<?php
+class ModelLocalisationTaxClass extends Model {
+ public function addTaxClass($data) {
+ $this->db->query("INSERT INTO " . DB_PREFIX . "tax_class SET title = '" . $this->db->escape($data['title']) . "', description = '" . $this->db->escape($data['description']) . "', date_added = NOW()");
+
+ $tax_class_id = $this->db->getLastId();
+
+ if (isset($data['tax_rule'])) {
+ foreach ($data['tax_rule'] as $tax_rule) {
+ $this->db->query("INSERT INTO " . DB_PREFIX . "tax_rule SET tax_class_id = '" . (int)$tax_class_id . "', tax_rate_id = '" . (int)$tax_rule['tax_rate_id'] . "', based = '" . $this->db->escape($tax_rule['based']) . "', priority = '" . (int)$tax_rule['priority'] . "'");
+ }
+ }
+
+ $this->cache->delete('tax_class');
+
+ return $tax_class_id;
+ }
+
+ public function editTaxClass($tax_class_id, $data) {
+ $this->db->query("UPDATE " . DB_PREFIX . "tax_class SET title = '" . $this->db->escape($data['title']) . "', description = '" . $this->db->escape($data['description']) . "', date_modified = NOW() WHERE tax_class_id = '" . (int)$tax_class_id . "'");
+
+ $this->db->query("DELETE FROM " . DB_PREFIX . "tax_rule WHERE tax_class_id = '" . (int)$tax_class_id . "'");
+
+ if (isset($data['tax_rule'])) {
+ foreach ($data['tax_rule'] as $tax_rule) {
+ $this->db->query("INSERT INTO " . DB_PREFIX . "tax_rule SET tax_class_id = '" . (int)$tax_class_id . "', tax_rate_id = '" . (int)$tax_rule['tax_rate_id'] . "', based = '" . $this->db->escape($tax_rule['based']) . "', priority = '" . (int)$tax_rule['priority'] . "'");
+ }
+ }
+
+ $this->cache->delete('tax_class');
+ }
+
+ public function deleteTaxClass($tax_class_id) {
+ $this->db->query("DELETE FROM " . DB_PREFIX . "tax_class WHERE tax_class_id = '" . (int)$tax_class_id . "'");
+ $this->db->query("DELETE FROM " . DB_PREFIX . "tax_rule WHERE tax_class_id = '" . (int)$tax_class_id . "'");
+
+ $this->cache->delete('tax_class');
+ }
+
+ public function getTaxClass($tax_class_id) {
+ $query = $this->db->query("SELECT * FROM " . DB_PREFIX . "tax_class WHERE tax_class_id = '" . (int)$tax_class_id . "'");
+
+ return $query->row;
+ }
+
+ public function getTaxClasses($data = array()) {
+ if ($data) {
+ $sql = "SELECT * FROM " . DB_PREFIX . "tax_class";
+
+ $sql .= " ORDER BY title";
+
+ 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'];
+ }
+
+ $query = $this->db->query($sql);
+
+ return $query->rows;
+ } else {
+ $tax_class_data = $this->cache->get('tax_class');
+
+ if (!$tax_class_data) {
+ $query = $this->db->query("SELECT * FROM " . DB_PREFIX . "tax_class");
+
+ $tax_class_data = $query->rows;
+
+ $this->cache->set('tax_class', $tax_class_data);
+ }
+
+ return $tax_class_data;
+ }
+ }
+
+ public function getTotalTaxClasses() {
+ $query = $this->db->query("SELECT COUNT(*) AS total FROM " . DB_PREFIX . "tax_class");
+
+ return $query->row['total'];
+ }
+
+ public function getTaxRules($tax_class_id) {
+ $query = $this->db->query("SELECT * FROM " . DB_PREFIX . "tax_rule WHERE tax_class_id = '" . (int)$tax_class_id . "'");
+
+ return $query->rows;
+ }
+
+ public function getTotalTaxRulesByTaxRateId($tax_rate_id) {
+ $query = $this->db->query("SELECT COUNT(DISTINCT tax_class_id) AS total FROM " . DB_PREFIX . "tax_rule WHERE tax_rate_id = '" . (int)$tax_rate_id . "'");
+
+ return $query->row['total'];
+ }
+} \ No newline at end of file
diff --git a/public/admin/model/localisation/tax_rate.php b/public/admin/model/localisation/tax_rate.php
new file mode 100644
index 0000000..0b049d0
--- /dev/null
+++ b/public/admin/model/localisation/tax_rate.php
@@ -0,0 +1,104 @@
+<?php
+class ModelLocalisationTaxRate extends Model {
+ public function addTaxRate($data) {
+ $this->db->query("INSERT INTO " . DB_PREFIX . "tax_rate SET name = '" . $this->db->escape($data['name']) . "', rate = '" . (float)$data['rate'] . "', `type` = '" . $this->db->escape($data['type']) . "', geo_zone_id = '" . (int)$data['geo_zone_id'] . "', date_added = NOW(), date_modified = NOW()");
+
+ $tax_rate_id = $this->db->getLastId();
+
+ if (isset($data['tax_rate_customer_group'])) {
+ foreach ($data['tax_rate_customer_group'] as $customer_group_id) {
+ $this->db->query("INSERT INTO " . DB_PREFIX . "tax_rate_to_customer_group SET tax_rate_id = '" . (int)$tax_rate_id . "', customer_group_id = '" . (int)$customer_group_id . "'");
+ }
+ }
+
+ return $tax_rate_id;
+ }
+
+ public function editTaxRate($tax_rate_id, $data) {
+ $this->db->query("UPDATE " . DB_PREFIX . "tax_rate SET name = '" . $this->db->escape($data['name']) . "', rate = '" . (float)$data['rate'] . "', `type` = '" . $this->db->escape($data['type']) . "', geo_zone_id = '" . (int)$data['geo_zone_id'] . "', date_modified = NOW() WHERE tax_rate_id = '" . (int)$tax_rate_id . "'");
+
+ $this->db->query("DELETE FROM " . DB_PREFIX . "tax_rate_to_customer_group WHERE tax_rate_id = '" . (int)$tax_rate_id . "'");
+
+ if (isset($data['tax_rate_customer_group'])) {
+ foreach ($data['tax_rate_customer_group'] as $customer_group_id) {
+ $this->db->query("INSERT INTO " . DB_PREFIX . "tax_rate_to_customer_group SET tax_rate_id = '" . (int)$tax_rate_id . "', customer_group_id = '" . (int)$customer_group_id . "'");
+ }
+ }
+ }
+
+ public function deleteTaxRate($tax_rate_id) {
+ $this->db->query("DELETE FROM " . DB_PREFIX . "tax_rate WHERE tax_rate_id = '" . (int)$tax_rate_id . "'");
+ $this->db->query("DELETE FROM " . DB_PREFIX . "tax_rate_to_customer_group WHERE tax_rate_id = '" . (int)$tax_rate_id . "'");
+ }
+
+ public function getTaxRate($tax_rate_id) {
+ $query = $this->db->query("SELECT tr.tax_rate_id, tr.name AS name, tr.rate, tr.type, tr.geo_zone_id, gz.name AS geo_zone, tr.date_added, tr.date_modified FROM " . DB_PREFIX . "tax_rate tr LEFT JOIN " . DB_PREFIX . "geo_zone gz ON (tr.geo_zone_id = gz.geo_zone_id) WHERE tr.tax_rate_id = '" . (int)$tax_rate_id . "'");
+
+ return $query->row;
+ }
+
+ public function getTaxRates($data = array()) {
+ $sql = "SELECT tr.tax_rate_id, tr.name AS name, tr.rate, tr.type, gz.name AS geo_zone, tr.date_added, tr.date_modified FROM " . DB_PREFIX . "tax_rate tr LEFT JOIN " . DB_PREFIX . "geo_zone gz ON (tr.geo_zone_id = gz.geo_zone_id)";
+
+ $sort_data = array(
+ 'tr.name',
+ 'tr.rate',
+ 'tr.type',
+ 'gz.name',
+ 'tr.date_added',
+ 'tr.date_modified'
+ );
+
+ if (isset($data['sort']) && in_array($data['sort'], $sort_data)) {
+ $sql .= " ORDER BY " . $data['sort'];
+ } else {
+ $sql .= " ORDER BY tr.name";
+ }
+
+ 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'];
+ }
+
+ $query = $this->db->query($sql);
+
+ return $query->rows;
+ }
+
+ public function getTaxRateCustomerGroups($tax_rate_id) {
+ $tax_customer_group_data = array();
+
+ $query = $this->db->query("SELECT * FROM " . DB_PREFIX . "tax_rate_to_customer_group WHERE tax_rate_id = '" . (int)$tax_rate_id . "'");
+
+ foreach ($query->rows as $result) {
+ $tax_customer_group_data[] = $result['customer_group_id'];
+ }
+
+ return $tax_customer_group_data;
+ }
+
+ public function getTotalTaxRates() {
+ $query = $this->db->query("SELECT COUNT(*) AS total FROM " . DB_PREFIX . "tax_rate");
+
+ return $query->row['total'];
+ }
+
+ public function getTotalTaxRatesByGeoZoneId($geo_zone_id) {
+ $query = $this->db->query("SELECT COUNT(*) AS total FROM " . DB_PREFIX . "tax_rate WHERE geo_zone_id = '" . (int)$geo_zone_id . "'");
+
+ return $query->row['total'];
+ }
+} \ No newline at end of file
diff --git a/public/admin/model/localisation/weight_class.php b/public/admin/model/localisation/weight_class.php
new file mode 100644
index 0000000..6e131ec
--- /dev/null
+++ b/public/admin/model/localisation/weight_class.php
@@ -0,0 +1,120 @@
+<?php
+class ModelLocalisationWeightClass extends Model {
+ public function addWeightClass($data) {
+ $this->db->query("INSERT INTO " . DB_PREFIX . "weight_class SET value = '" . (float)$data['value'] . "'");
+
+ $weight_class_id = $this->db->getLastId();
+
+ foreach ($data['weight_class_description'] as $language_id => $value) {
+ $this->db->query("INSERT INTO " . DB_PREFIX . "weight_class_description SET weight_class_id = '" . (int)$weight_class_id . "', language_id = '" . (int)$language_id . "', title = '" . $this->db->escape($value['title']) . "', unit = '" . $this->db->escape($value['unit']) . "'");
+ }
+
+ $this->cache->delete('weight_class');
+
+ return $weight_class_id;
+ }
+
+ public function editWeightClass($weight_class_id, $data) {
+ $this->db->query("UPDATE " . DB_PREFIX . "weight_class SET value = '" . (float)$data['value'] . "' WHERE weight_class_id = '" . (int)$weight_class_id . "'");
+
+ $this->db->query("DELETE FROM " . DB_PREFIX . "weight_class_description WHERE weight_class_id = '" . (int)$weight_class_id . "'");
+
+ foreach ($data['weight_class_description'] as $language_id => $value) {
+ $this->db->query("INSERT INTO " . DB_PREFIX . "weight_class_description SET weight_class_id = '" . (int)$weight_class_id . "', language_id = '" . (int)$language_id . "', title = '" . $this->db->escape($value['title']) . "', unit = '" . $this->db->escape($value['unit']) . "'");
+ }
+
+ $this->cache->delete('weight_class');
+ }
+
+ public function deleteWeightClass($weight_class_id) {
+ $this->db->query("DELETE FROM " . DB_PREFIX . "weight_class WHERE weight_class_id = '" . (int)$weight_class_id . "'");
+ $this->db->query("DELETE FROM " . DB_PREFIX . "weight_class_description WHERE weight_class_id = '" . (int)$weight_class_id . "'");
+
+ $this->cache->delete('weight_class');
+ }
+
+ public function getWeightClasses($data = array()) {
+ if ($data) {
+ $sql = "SELECT * FROM " . DB_PREFIX . "weight_class wc LEFT JOIN " . DB_PREFIX . "weight_class_description wcd ON (wc.weight_class_id = wcd.weight_class_id) WHERE wcd.language_id = '" . (int)$this->config->get('config_language_id') . "'";
+
+ $sort_data = array(
+ 'title',
+ 'unit',
+ 'value'
+ );
+
+ if (isset($data['sort']) && in_array($data['sort'], $sort_data)) {
+ $sql .= " ORDER BY " . $data['sort'];
+ } else {
+ $sql .= " ORDER BY title";
+ }
+
+ 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'];
+ }
+
+ $query = $this->db->query($sql);
+
+ return $query->rows;
+ } else {
+ $weight_class_data = $this->cache->get('weight_class.' . (int)$this->config->get('config_language_id'));
+
+ if (!$weight_class_data) {
+ $query = $this->db->query("SELECT * FROM " . DB_PREFIX . "weight_class wc LEFT JOIN " . DB_PREFIX . "weight_class_description wcd ON (wc.weight_class_id = wcd.weight_class_id) WHERE wcd.language_id = '" . (int)$this->config->get('config_language_id') . "'");
+
+ $weight_class_data = $query->rows;
+
+ $this->cache->set('weight_class.' . (int)$this->config->get('config_language_id'), $weight_class_data);
+ }
+
+ return $weight_class_data;
+ }
+ }
+
+ public function getWeightClass($weight_class_id) {
+ $query = $this->db->query("SELECT * FROM " . DB_PREFIX . "weight_class wc LEFT JOIN " . DB_PREFIX . "weight_class_description wcd ON (wc.weight_class_id = wcd.weight_class_id) WHERE wc.weight_class_id = '" . (int)$weight_class_id . "' AND wcd.language_id = '" . (int)$this->config->get('config_language_id') . "'");
+
+ return $query->row;
+ }
+
+ public function getWeightClassDescriptionByUnit($unit) {
+ $query = $this->db->query("SELECT * FROM " . DB_PREFIX . "weight_class_description WHERE unit = '" . $this->db->escape($unit) . "' AND language_id = '" . (int)$this->config->get('config_language_id') . "'");
+
+ return $query->row;
+ }
+
+ public function getWeightClassDescriptions($weight_class_id) {
+ $weight_class_data = array();
+
+ $query = $this->db->query("SELECT * FROM " . DB_PREFIX . "weight_class_description WHERE weight_class_id = '" . (int)$weight_class_id . "'");
+
+ foreach ($query->rows as $result) {
+ $weight_class_data[$result['language_id']] = array(
+ 'title' => $result['title'],
+ 'unit' => $result['unit']
+ );
+ }
+
+ return $weight_class_data;
+ }
+
+ public function getTotalWeightClasses() {
+ $query = $this->db->query("SELECT COUNT(*) AS total FROM " . DB_PREFIX . "weight_class");
+
+ return $query->row['total'];
+ }
+} \ No newline at end of file
diff --git a/public/admin/model/localisation/zone.php b/public/admin/model/localisation/zone.php
new file mode 100644
index 0000000..362c90d
--- /dev/null
+++ b/public/admin/model/localisation/zone.php
@@ -0,0 +1,92 @@
+<?php
+class ModelLocalisationZone extends Model {
+ public function addZone($data) {
+ $this->db->query("INSERT INTO " . DB_PREFIX . "zone SET status = '" . (int)$data['status'] . "', name = '" . $this->db->escape($data['name']) . "', code = '" . $this->db->escape($data['code']) . "', country_id = '" . (int)$data['country_id'] . "'");
+
+ $this->cache->delete('zone');
+
+ return $this->db->getLastId();
+ }
+
+ public function editZone($zone_id, $data) {
+ $this->db->query("UPDATE " . DB_PREFIX . "zone SET status = '" . (int)$data['status'] . "', name = '" . $this->db->escape($data['name']) . "', code = '" . $this->db->escape($data['code']) . "', country_id = '" . (int)$data['country_id'] . "' WHERE zone_id = '" . (int)$zone_id . "'");
+
+ $this->cache->delete('zone');
+ }
+
+ public function deleteZone($zone_id) {
+ $this->db->query("DELETE FROM " . DB_PREFIX . "zone WHERE zone_id = '" . (int)$zone_id . "'");
+
+ $this->cache->delete('zone');
+ }
+
+ public function getZone($zone_id) {
+ $query = $this->db->query("SELECT DISTINCT * FROM " . DB_PREFIX . "zone WHERE zone_id = '" . (int)$zone_id . "'");
+
+ return $query->row;
+ }
+
+ public function getZones($data = array()) {
+ $sql = "SELECT *, z.name, c.name AS country FROM " . DB_PREFIX . "zone z LEFT JOIN " . DB_PREFIX . "country c ON (z.country_id = c.country_id)";
+
+ $sort_data = array(
+ 'c.name',
+ 'z.name',
+ 'z.code'
+ );
+
+ if (isset($data['sort']) && in_array($data['sort'], $sort_data)) {
+ $sql .= " ORDER BY " . $data['sort'];
+ } else {
+ $sql .= " ORDER BY c.name";
+ }
+
+ 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'];
+ }
+
+ $query = $this->db->query($sql);
+
+ return $query->rows;
+ }
+
+ public function getZonesByCountryId($country_id) {
+ $zone_data = $this->cache->get('zone.' . (int)$country_id);
+
+ if (!$zone_data) {
+ $query = $this->db->query("SELECT * FROM " . DB_PREFIX . "zone WHERE country_id = '" . (int)$country_id . "' AND status = '1' ORDER BY name");
+
+ $zone_data = $query->rows;
+
+ $this->cache->set('zone.' . (int)$country_id, $zone_data);
+ }
+
+ return $zone_data;
+ }
+
+ public function getTotalZones() {
+ $query = $this->db->query("SELECT COUNT(*) AS total FROM " . DB_PREFIX . "zone");
+
+ return $query->row['total'];
+ }
+
+ public function getTotalZonesByCountryId($country_id) {
+ $query = $this->db->query("SELECT COUNT(*) AS total FROM " . DB_PREFIX . "zone WHERE country_id = '" . (int)$country_id . "'");
+
+ return $query->row['total'];
+ }
+} \ No newline at end of file
diff --git a/public/admin/model/marketing/coupon.php b/public/admin/model/marketing/coupon.php
new file mode 100644
index 0000000..7dbf093
--- /dev/null
+++ b/public/admin/model/marketing/coupon.php
@@ -0,0 +1,152 @@
+<?php
+class ModelMarketingCoupon extends Model {
+ public function addCoupon($data) {
+ $this->db->query("INSERT INTO " . DB_PREFIX . "coupon SET name = '" . $this->db->escape($data['name']) . "', code = '" . $this->db->escape($data['code']) . "', discount = '" . (float)$data['discount'] . "', type = '" . $this->db->escape($data['type']) . "', total = '" . (float)$data['total'] . "', logged = '" . (int)$data['logged'] . "', shipping = '" . (int)$data['shipping'] . "', date_start = '" . $this->db->escape($data['date_start']) . "', date_end = '" . $this->db->escape($data['date_end']) . "', uses_total = '" . (int)$data['uses_total'] . "', uses_customer = '" . (int)$data['uses_customer'] . "', status = '" . (int)$data['status'] . "', date_added = NOW()");
+
+ $coupon_id = $this->db->getLastId();
+
+ if (isset($data['coupon_product'])) {
+ foreach ($data['coupon_product'] as $product_id) {
+ $this->db->query("INSERT INTO " . DB_PREFIX . "coupon_product SET coupon_id = '" . (int)$coupon_id . "', product_id = '" . (int)$product_id . "'");
+ }
+ }
+
+ if (isset($data['coupon_category'])) {
+ foreach ($data['coupon_category'] as $category_id) {
+ $this->db->query("INSERT INTO " . DB_PREFIX . "coupon_category SET coupon_id = '" . (int)$coupon_id . "', category_id = '" . (int)$category_id . "'");
+ }
+ }
+
+ return $coupon_id;
+ }
+
+ public function editCoupon($coupon_id, $data) {
+ $this->db->query("UPDATE " . DB_PREFIX . "coupon SET name = '" . $this->db->escape($data['name']) . "', code = '" . $this->db->escape($data['code']) . "', discount = '" . (float)$data['discount'] . "', type = '" . $this->db->escape($data['type']) . "', total = '" . (float)$data['total'] . "', logged = '" . (int)$data['logged'] . "', shipping = '" . (int)$data['shipping'] . "', date_start = '" . $this->db->escape($data['date_start']) . "', date_end = '" . $this->db->escape($data['date_end']) . "', uses_total = '" . (int)$data['uses_total'] . "', uses_customer = '" . (int)$data['uses_customer'] . "', status = '" . (int)$data['status'] . "' WHERE coupon_id = '" . (int)$coupon_id . "'");
+
+ $this->db->query("DELETE FROM " . DB_PREFIX . "coupon_product WHERE coupon_id = '" . (int)$coupon_id . "'");
+
+ if (isset($data['coupon_product'])) {
+ foreach ($data['coupon_product'] as $product_id) {
+ $this->db->query("INSERT INTO " . DB_PREFIX . "coupon_product SET coupon_id = '" . (int)$coupon_id . "', product_id = '" . (int)$product_id . "'");
+ }
+ }
+
+ $this->db->query("DELETE FROM " . DB_PREFIX . "coupon_category WHERE coupon_id = '" . (int)$coupon_id . "'");
+
+ if (isset($data['coupon_category'])) {
+ foreach ($data['coupon_category'] as $category_id) {
+ $this->db->query("INSERT INTO " . DB_PREFIX . "coupon_category SET coupon_id = '" . (int)$coupon_id . "', category_id = '" . (int)$category_id . "'");
+ }
+ }
+ }
+
+ public function deleteCoupon($coupon_id) {
+ $this->db->query("DELETE FROM " . DB_PREFIX . "coupon WHERE coupon_id = '" . (int)$coupon_id . "'");
+ $this->db->query("DELETE FROM " . DB_PREFIX . "coupon_product WHERE coupon_id = '" . (int)$coupon_id . "'");
+ $this->db->query("DELETE FROM " . DB_PREFIX . "coupon_category WHERE coupon_id = '" . (int)$coupon_id . "'");
+ $this->db->query("DELETE FROM " . DB_PREFIX . "coupon_history WHERE coupon_id = '" . (int)$coupon_id . "'");
+ }
+
+ public function getCoupon($coupon_id) {
+ $query = $this->db->query("SELECT DISTINCT * FROM " . DB_PREFIX . "coupon WHERE coupon_id = '" . (int)$coupon_id . "'");
+
+ return $query->row;
+ }
+
+ public function getCouponByCode($code) {
+ $query = $this->db->query("SELECT DISTINCT * FROM " . DB_PREFIX . "coupon WHERE code = '" . $this->db->escape($code) . "'");
+
+ return $query->row;
+ }
+
+ public function getCoupons($data = array()) {
+ $sql = "SELECT coupon_id, name, code, discount, date_start, date_end, status FROM " . DB_PREFIX . "coupon";
+
+ $sort_data = array(
+ 'name',
+ 'code',
+ 'discount',
+ 'date_start',
+ 'date_end',
+ 'status'
+ );
+
+ if (isset($data['sort']) && in_array($data['sort'], $sort_data)) {
+ $sql .= " ORDER BY " . $data['sort'];
+ } else {
+ $sql .= " ORDER BY name";
+ }
+
+ 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'];
+ }
+
+ $query = $this->db->query($sql);
+
+ return $query->rows;
+ }
+
+ public function getCouponProducts($coupon_id) {
+ $coupon_product_data = array();
+
+ $query = $this->db->query("SELECT * FROM " . DB_PREFIX . "coupon_product WHERE coupon_id = '" . (int)$coupon_id . "'");
+
+ foreach ($query->rows as $result) {
+ $coupon_product_data[] = $result['product_id'];
+ }
+
+ return $coupon_product_data;
+ }
+
+ public function getCouponCategories($coupon_id) {
+ $coupon_category_data = array();
+
+ $query = $this->db->query("SELECT * FROM " . DB_PREFIX . "coupon_category WHERE coupon_id = '" . (int)$coupon_id . "'");
+
+ foreach ($query->rows as $result) {
+ $coupon_category_data[] = $result['category_id'];
+ }
+
+ return $coupon_category_data;
+ }
+
+ public function getTotalCoupons() {
+ $query = $this->db->query("SELECT COUNT(*) AS total FROM " . DB_PREFIX . "coupon");
+
+ return $query->row['total'];
+ }
+
+ public function getCouponHistories($coupon_id, $start = 0, $limit = 10) {
+ if ($start < 0) {
+ $start = 0;
+ }
+
+ if ($limit < 1) {
+ $limit = 10;
+ }
+
+ $query = $this->db->query("SELECT ch.order_id, CONCAT(c.firstname, ' ', c.lastname) AS customer, ch.amount, ch.date_added FROM " . DB_PREFIX . "coupon_history ch LEFT JOIN " . DB_PREFIX . "customer c ON (ch.customer_id = c.customer_id) WHERE ch.coupon_id = '" . (int)$coupon_id . "' ORDER BY ch.date_added ASC LIMIT " . (int)$start . "," . (int)$limit);
+
+ return $query->rows;
+ }
+
+ public function getTotalCouponHistories($coupon_id) {
+ $query = $this->db->query("SELECT COUNT(*) AS total FROM " . DB_PREFIX . "coupon_history WHERE coupon_id = '" . (int)$coupon_id . "'");
+
+ return $query->row['total'];
+ }
+} \ No newline at end of file
diff --git a/public/admin/model/marketing/marketing.php b/public/admin/model/marketing/marketing.php
new file mode 100644
index 0000000..df585e2
--- /dev/null
+++ b/public/admin/model/marketing/marketing.php
@@ -0,0 +1,118 @@
+<?php
+class ModelMarketingMarketing extends Model {
+ public function addMarketing($data) {
+ $this->db->query("INSERT INTO " . DB_PREFIX . "marketing SET name = '" . $this->db->escape($data['name']) . "', description = '" . $this->db->escape($data['description']) . "', code = '" . $this->db->escape($data['code']) . "', date_added = NOW()");
+
+ return $this->db->getLastId();
+ }
+
+ public function editMarketing($marketing_id, $data) {
+ $this->db->query("UPDATE " . DB_PREFIX . "marketing SET name = '" . $this->db->escape($data['name']) . "', description = '" . $this->db->escape($data['description']) . "', code = '" . $this->db->escape($data['code']) . "' WHERE marketing_id = '" . (int)$marketing_id . "'");
+ }
+
+ public function deleteMarketing($marketing_id) {
+ $this->db->query("DELETE FROM " . DB_PREFIX . "marketing WHERE marketing_id = '" . (int)$marketing_id . "'");
+ }
+
+ public function getMarketing($marketing_id) {
+ $query = $this->db->query("SELECT DISTINCT * FROM " . DB_PREFIX . "marketing WHERE marketing_id = '" . (int)$marketing_id . "'");
+
+ return $query->row;
+ }
+
+ public function getMarketingByCode($code) {
+ $query = $this->db->query("SELECT DISTINCT * FROM " . DB_PREFIX . "marketing WHERE code = '" . $this->db->escape($code) . "'");
+
+ return $query->row;
+ }
+
+ public function getMarketings($data = array()) {
+ $implode = array();
+
+ $order_statuses = $this->config->get('config_complete_status');
+
+ foreach ($order_statuses as $order_status_id) {
+ $implode[] = "o.order_status_id = '" . (int)$order_status_id . "'";
+ }
+
+ $sql = "SELECT *, (SELECT COUNT(*) FROM `" . DB_PREFIX . "order` o WHERE (" . implode(" OR ", $implode) . ") AND o.marketing_id = m.marketing_id) AS orders FROM " . DB_PREFIX . "marketing m";
+
+ $implode = array();
+
+ if (!empty($data['filter_name'])) {
+ $implode[] = "m.name LIKE '" . $this->db->escape($data['filter_name']) . "%'";
+ }
+
+ if (!empty($data['filter_code'])) {
+ $implode[] = "m.code = '" . $this->db->escape($data['filter_code']) . "'";
+ }
+
+ if (!empty($data['filter_date_added'])) {
+ $implode[] = "DATE(m.date_added) = DATE('" . $this->db->escape($data['filter_date_added']) . "')";
+ }
+
+ if ($implode) {
+ $sql .= " WHERE " . implode(" AND ", $implode);
+ }
+
+ $sort_data = array(
+ 'm.name',
+ 'm.code',
+ 'm.date_added'
+ );
+
+ if (isset($data['sort']) && in_array($data['sort'], $sort_data)) {
+ $sql .= " ORDER BY " . $data['sort'];
+ } else {
+ $sql .= " ORDER BY m.name";
+ }
+
+ 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'];
+ }
+
+ $query = $this->db->query($sql);
+
+ return $query->rows;
+ }
+
+ public function getTotalMarketings($data = array()) {
+ $sql = "SELECT COUNT(*) AS total FROM " . DB_PREFIX . "marketing";
+
+ $implode = array();
+
+ if (!empty($data['filter_name'])) {
+ $implode[] = "name LIKE '" . $this->db->escape($data['filter_name']) . "'";
+ }
+
+ if (!empty($data['filter_code'])) {
+ $implode[] = "code = '" . $this->db->escape($data['filter_code']) . "'";
+ }
+
+ if (!empty($data['filter_date_added'])) {
+ $implode[] = "DATE(date_added) = DATE('" . $this->db->escape($data['filter_date_added']) . "')";
+ }
+
+ if ($implode) {
+ $sql .= " WHERE " . implode(" AND ", $implode);
+ }
+
+ $query = $this->db->query($sql);
+
+ return $query->row['total'];
+ }
+} \ No newline at end of file
diff --git a/public/admin/model/report/online.php b/public/admin/model/report/online.php
new file mode 100644
index 0000000..8c13990
--- /dev/null
+++ b/public/admin/model/report/online.php
@@ -0,0 +1,60 @@
+<?php
+class ModelReportOnline extends Model {
+ public function getOnline($data = array()) {
+ $sql = "SELECT co.ip, co.customer_id, co.url, co.referer, co.date_added FROM " . DB_PREFIX . "customer_online co LEFT JOIN " . DB_PREFIX . "customer c ON (co.customer_id = c.customer_id)";
+
+ $implode = array();
+
+ if (!empty($data['filter_ip'])) {
+ $implode[] = "co.ip LIKE '" . $this->db->escape($data['filter_ip']) . "'";
+ }
+
+ if (!empty($data['filter_customer'])) {
+ $implode[] = "co.customer_id > 0 AND CONCAT(c.firstname, ' ', c.lastname) LIKE '" . $this->db->escape($data['filter_customer']) . "'";
+ }
+
+ if ($implode) {
+ $sql .= " WHERE " . implode(" AND ", $implode);
+ }
+
+ $sql .= " ORDER BY co.date_added DESC";
+
+ 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'];
+ }
+
+ $query = $this->db->query($sql);
+
+ return $query->rows;
+ }
+
+ public function getTotalOnline($data = array()) {
+ $sql = "SELECT COUNT(*) AS total FROM `" . DB_PREFIX . "customer_online` co LEFT JOIN " . DB_PREFIX . "customer c ON (co.customer_id = c.customer_id)";
+
+ $implode = array();
+
+ if (!empty($data['filter_ip'])) {
+ $implode[] = "co.ip LIKE '" . $this->db->escape($data['filter_ip']) . "'";
+ }
+
+ if (!empty($data['filter_customer'])) {
+ $implode[] = "co.customer_id > 0 AND CONCAT(c.firstname, ' ', c.lastname) LIKE '" . $this->db->escape($data['filter_customer']) . "'";
+ }
+
+ if ($implode) {
+ $sql .= " WHERE " . implode(" AND ", $implode);
+ }
+
+ $query = $this->db->query($sql);
+
+ return $query->row['total'];
+ }
+}
diff --git a/public/admin/model/report/statistics.php b/public/admin/model/report/statistics.php
new file mode 100644
index 0000000..9fe77d1
--- /dev/null
+++ b/public/admin/model/report/statistics.php
@@ -0,0 +1,30 @@
+<?php
+class ModelReportStatistics extends Model {
+ public function getStatistics() {
+ $query = $this->db->query("SELECT * FROM " . DB_PREFIX . "statistics");
+
+ return $query->rows;
+ }
+
+ public function getValue($code) {
+ $query = $this->db->query("SELECT value FROM " . DB_PREFIX . "statistics WHERE `code` = '" . $this->db->escape($code) . "'");
+
+ if ($query->num_rows) {
+ return $query->row['value'];
+ } else {
+ return null;
+ }
+ }
+
+ public function addValue($code, $value) {
+ $this->db->query("UPDATE " . DB_PREFIX . "statistics SET `value` = (`value` + '" . (float)$value . "') WHERE `code` = '" . $this->db->escape($code) . "'");
+ }
+
+ public function editValue($code, $value) {
+ $this->db->query("UPDATE " . DB_PREFIX . "statistics SET `value` = '" . (float)$value . "' WHERE `code` = '" . $this->db->escape($code) . "'");
+ }
+
+ public function removeValue($code, $value) {
+ $this->db->query("UPDATE " . DB_PREFIX . "statistics SET `value` = (`value` - '" . (float)$value . "') WHERE `code` = '" . $this->db->escape($code) . "'");
+ }
+}
diff --git a/public/admin/model/sale/order.php b/public/admin/model/sale/order.php
new file mode 100644
index 0000000..0c832f3
--- /dev/null
+++ b/public/admin/model/sale/order.php
@@ -0,0 +1,478 @@
+<?php
+class ModelSaleOrder extends Model {
+ public function getOrder($order_id) {
+ $order_query = $this->db->query("SELECT *, (SELECT CONCAT(c.firstname, ' ', c.lastname) FROM " . DB_PREFIX . "customer c WHERE c.customer_id = o.customer_id) AS customer, (SELECT os.name FROM " . DB_PREFIX . "order_status os WHERE os.order_status_id = o.order_status_id AND os.language_id = '" . (int)$this->config->get('config_language_id') . "') AS order_status FROM `" . DB_PREFIX . "order` o WHERE o.order_id = '" . (int)$order_id . "'");
+
+ if ($order_query->num_rows) {
+ $country_query = $this->db->query("SELECT * FROM `" . DB_PREFIX . "country` WHERE country_id = '" . (int)$order_query->row['payment_country_id'] . "'");
+
+ if ($country_query->num_rows) {
+ $payment_iso_code_2 = $country_query->row['iso_code_2'];
+ $payment_iso_code_3 = $country_query->row['iso_code_3'];
+ } else {
+ $payment_iso_code_2 = '';
+ $payment_iso_code_3 = '';
+ }
+
+ $zone_query = $this->db->query("SELECT * FROM `" . DB_PREFIX . "zone` WHERE zone_id = '" . (int)$order_query->row['payment_zone_id'] . "'");
+
+ if ($zone_query->num_rows) {
+ $payment_zone_code = $zone_query->row['code'];
+ } else {
+ $payment_zone_code = '';
+ }
+
+ $country_query = $this->db->query("SELECT * FROM `" . DB_PREFIX . "country` WHERE country_id = '" . (int)$order_query->row['shipping_country_id'] . "'");
+
+ if ($country_query->num_rows) {
+ $shipping_iso_code_2 = $country_query->row['iso_code_2'];
+ $shipping_iso_code_3 = $country_query->row['iso_code_3'];
+ } else {
+ $shipping_iso_code_2 = '';
+ $shipping_iso_code_3 = '';
+ }
+
+ $zone_query = $this->db->query("SELECT * FROM `" . DB_PREFIX . "zone` WHERE zone_id = '" . (int)$order_query->row['shipping_zone_id'] . "'");
+
+ if ($zone_query->num_rows) {
+ $shipping_zone_code = $zone_query->row['code'];
+ } else {
+ $shipping_zone_code = '';
+ }
+
+ $reward = 0;
+
+ $order_product_query = $this->db->query("SELECT * FROM " . DB_PREFIX . "order_product WHERE order_id = '" . (int)$order_id . "'");
+
+ foreach ($order_product_query->rows as $product) {
+ $reward += $product['reward'];
+ }
+
+ $this->load->model('customer/customer');
+
+ $affiliate_info = $this->model_customer_customer->getCustomer($order_query->row['affiliate_id']);
+
+ if ($affiliate_info) {
+ $affiliate_firstname = $affiliate_info['firstname'];
+ $affiliate_lastname = $affiliate_info['lastname'];
+ } else {
+ $affiliate_firstname = '';
+ $affiliate_lastname = '';
+ }
+
+ $this->load->model('localisation/language');
+
+ $language_info = $this->model_localisation_language->getLanguage($order_query->row['language_id']);
+
+ if ($language_info) {
+ $language_code = $language_info['code'];
+ } else {
+ $language_code = $this->config->get('config_language');
+ }
+
+ return array(
+ 'order_id' => $order_query->row['order_id'],
+ 'invoice_no' => $order_query->row['invoice_no'],
+ 'invoice_prefix' => $order_query->row['invoice_prefix'],
+ 'store_id' => $order_query->row['store_id'],
+ 'store_name' => $order_query->row['store_name'],
+ 'store_url' => $order_query->row['store_url'],
+ 'customer_id' => $order_query->row['customer_id'],
+ 'customer' => $order_query->row['customer'],
+ 'customer_group_id' => $order_query->row['customer_group_id'],
+ 'firstname' => $order_query->row['firstname'],
+ 'lastname' => $order_query->row['lastname'],
+ 'email' => $order_query->row['email'],
+ 'telephone' => $order_query->row['telephone'],
+ 'custom_field' => json_decode($order_query->row['custom_field'], true),
+ 'payment_firstname' => $order_query->row['payment_firstname'],
+ 'payment_lastname' => $order_query->row['payment_lastname'],
+ 'payment_company' => $order_query->row['payment_company'],
+ 'payment_address_1' => $order_query->row['payment_address_1'],
+ 'payment_address_2' => $order_query->row['payment_address_2'],
+ 'payment_postcode' => $order_query->row['payment_postcode'],
+ 'payment_city' => $order_query->row['payment_city'],
+ 'payment_zone_id' => $order_query->row['payment_zone_id'],
+ 'payment_zone' => $order_query->row['payment_zone'],
+ 'payment_zone_code' => $payment_zone_code,
+ 'payment_country_id' => $order_query->row['payment_country_id'],
+ 'payment_country' => $order_query->row['payment_country'],
+ 'payment_iso_code_2' => $payment_iso_code_2,
+ 'payment_iso_code_3' => $payment_iso_code_3,
+ 'payment_address_format' => $order_query->row['payment_address_format'],
+ 'payment_custom_field' => json_decode($order_query->row['payment_custom_field'], true),
+ 'payment_method' => $order_query->row['payment_method'],
+ 'payment_code' => $order_query->row['payment_code'],
+ 'shipping_firstname' => $order_query->row['shipping_firstname'],
+ 'shipping_lastname' => $order_query->row['shipping_lastname'],
+ 'shipping_company' => $order_query->row['shipping_company'],
+ 'shipping_address_1' => $order_query->row['shipping_address_1'],
+ 'shipping_address_2' => $order_query->row['shipping_address_2'],
+ 'shipping_postcode' => $order_query->row['shipping_postcode'],
+ 'shipping_city' => $order_query->row['shipping_city'],
+ 'shipping_zone_id' => $order_query->row['shipping_zone_id'],
+ 'shipping_zone' => $order_query->row['shipping_zone'],
+ 'shipping_zone_code' => $shipping_zone_code,
+ 'shipping_country_id' => $order_query->row['shipping_country_id'],
+ 'shipping_country' => $order_query->row['shipping_country'],
+ 'shipping_iso_code_2' => $shipping_iso_code_2,
+ 'shipping_iso_code_3' => $shipping_iso_code_3,
+ 'shipping_address_format' => $order_query->row['shipping_address_format'],
+ 'shipping_custom_field' => json_decode($order_query->row['shipping_custom_field'], true),
+ 'shipping_method' => $order_query->row['shipping_method'],
+ 'shipping_code' => $order_query->row['shipping_code'],
+ 'comment' => $order_query->row['comment'],
+ 'total' => $order_query->row['total'],
+ 'reward' => $reward,
+ 'order_status_id' => $order_query->row['order_status_id'],
+ 'order_status' => $order_query->row['order_status'],
+ 'affiliate_id' => $order_query->row['affiliate_id'],
+ 'affiliate_firstname' => $affiliate_firstname,
+ 'affiliate_lastname' => $affiliate_lastname,
+ 'commission' => $order_query->row['commission'],
+ 'language_id' => $order_query->row['language_id'],
+ 'language_code' => $language_code,
+ 'currency_id' => $order_query->row['currency_id'],
+ 'currency_code' => $order_query->row['currency_code'],
+ 'currency_value' => $order_query->row['currency_value'],
+ 'ip' => $order_query->row['ip'],
+ 'forwarded_ip' => $order_query->row['forwarded_ip'],
+ 'user_agent' => $order_query->row['user_agent'],
+ 'accept_language' => $order_query->row['accept_language'],
+ 'date_added' => $order_query->row['date_added'],
+ 'date_modified' => $order_query->row['date_modified']
+ );
+ } else {
+ return;
+ }
+ }
+
+ public function getOrders($data = array()) {
+ $sql = "SELECT o.order_id, CONCAT(o.firstname, ' ', o.lastname) AS customer, (SELECT os.name FROM " . DB_PREFIX . "order_status os WHERE os.order_status_id = o.order_status_id AND os.language_id = '" . (int)$this->config->get('config_language_id') . "') AS order_status, o.shipping_code, o.total, o.currency_code, o.currency_value, o.date_added, o.date_modified FROM `" . DB_PREFIX . "order` o";
+
+ if (!empty($data['filter_order_status'])) {
+ $implode = array();
+
+ $order_statuses = explode(',', $data['filter_order_status']);
+
+ foreach ($order_statuses as $order_status_id) {
+ $implode[] = "o.order_status_id = '" . (int)$order_status_id . "'";
+ }
+
+ if ($implode) {
+ $sql .= " WHERE (" . implode(" OR ", $implode) . ")";
+ }
+ } elseif (isset($data['filter_order_status_id']) && $data['filter_order_status_id'] !== '') {
+ $sql .= " WHERE o.order_status_id = '" . (int)$data['filter_order_status_id'] . "'";
+ } else {
+ $sql .= " WHERE o.order_status_id > '0'";
+ }
+
+ if (!empty($data['filter_order_id'])) {
+ $sql .= " AND o.order_id = '" . (int)$data['filter_order_id'] . "'";
+ }
+
+ if (!empty($data['filter_customer'])) {
+ $sql .= " AND CONCAT(o.firstname, ' ', o.lastname) LIKE '%" . $this->db->escape($data['filter_customer']) . "%'";
+ }
+
+ if (!empty($data['filter_date_added'])) {
+ $sql .= " AND DATE(o.date_added) = DATE('" . $this->db->escape($data['filter_date_added']) . "')";
+ }
+
+ if (!empty($data['filter_date_modified'])) {
+ $sql .= " AND DATE(o.date_modified) = DATE('" . $this->db->escape($data['filter_date_modified']) . "')";
+ }
+
+ if (!empty($data['filter_total'])) {
+ $sql .= " AND o.total = '" . (float)$data['filter_total'] . "'";
+ }
+
+ $sort_data = array(
+ 'o.order_id',
+ 'customer',
+ 'order_status',
+ 'o.date_added',
+ 'o.date_modified',
+ 'o.total'
+ );
+
+ if (isset($data['sort']) && in_array($data['sort'], $sort_data)) {
+ $sql .= " ORDER BY " . $data['sort'];
+ } else {
+ $sql .= " ORDER BY o.order_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'];
+ }
+
+ $query = $this->db->query($sql);
+
+ return $query->rows;
+ }
+
+ public function getOrderProducts($order_id) {
+ $query = $this->db->query("SELECT * FROM " . DB_PREFIX . "order_product WHERE order_id = '" . (int)$order_id . "'");
+
+ return $query->rows;
+ }
+
+ public function getOrderOptions($order_id, $order_product_id) {
+ $query = $this->db->query("SELECT * FROM " . DB_PREFIX . "order_option WHERE order_id = '" . (int)$order_id . "' AND order_product_id = '" . (int)$order_product_id . "'");
+
+ return $query->rows;
+ }
+
+ public function getOrderVouchers($order_id) {
+ $query = $this->db->query("SELECT * FROM " . DB_PREFIX . "order_voucher WHERE order_id = '" . (int)$order_id . "'");
+
+ return $query->rows;
+ }
+
+ public function getOrderVoucherByVoucherId($voucher_id) {
+ $query = $this->db->query("SELECT * FROM `" . DB_PREFIX . "order_voucher` WHERE voucher_id = '" . (int)$voucher_id . "'");
+
+ return $query->row;
+ }
+
+ public function getOrderTotals($order_id) {
+ $query = $this->db->query("SELECT * FROM " . DB_PREFIX . "order_total WHERE order_id = '" . (int)$order_id . "' ORDER BY sort_order");
+
+ return $query->rows;
+ }
+
+ public function getTotalOrders($data = array()) {
+ $sql = "SELECT COUNT(*) AS total FROM `" . DB_PREFIX . "order`";
+
+ if (!empty($data['filter_order_status'])) {
+ $implode = array();
+
+ $order_statuses = explode(',', $data['filter_order_status']);
+
+ foreach ($order_statuses as $order_status_id) {
+ $implode[] = "order_status_id = '" . (int)$order_status_id . "'";
+ }
+
+ if ($implode) {
+ $sql .= " WHERE (" . implode(" OR ", $implode) . ")";
+ }
+ } elseif (isset($data['filter_order_status_id']) && $data['filter_order_status_id'] !== '') {
+ $sql .= " WHERE order_status_id = '" . (int)$data['filter_order_status_id'] . "'";
+ } else {
+ $sql .= " WHERE order_status_id > '0'";
+ }
+
+ if (!empty($data['filter_order_id'])) {
+ $sql .= " AND order_id = '" . (int)$data['filter_order_id'] . "'";
+ }
+
+ if (!empty($data['filter_customer'])) {
+ $sql .= " AND CONCAT(firstname, ' ', lastname) LIKE '%" . $this->db->escape($data['filter_customer']) . "%'";
+ }
+
+ if (!empty($data['filter_date_added'])) {
+ $sql .= " AND DATE(date_added) = DATE('" . $this->db->escape($data['filter_date_added']) . "')";
+ }
+
+ if (!empty($data['filter_date_modified'])) {
+ $sql .= " AND DATE(date_modified) = DATE('" . $this->db->escape($data['filter_date_modified']) . "')";
+ }
+
+ if (!empty($data['filter_total'])) {
+ $sql .= " AND total = '" . (float)$data['filter_total'] . "'";
+ }
+
+ $query = $this->db->query($sql);
+
+ return $query->row['total'];
+ }
+
+ public function getTotalOrdersByStoreId($store_id) {
+ $query = $this->db->query("SELECT COUNT(*) AS total FROM `" . DB_PREFIX . "order` WHERE store_id = '" . (int)$store_id . "'");
+
+ return $query->row['total'];
+ }
+
+ public function getTotalOrdersByOrderStatusId($order_status_id) {
+ $query = $this->db->query("SELECT COUNT(*) AS total FROM `" . DB_PREFIX . "order` WHERE order_status_id = '" . (int)$order_status_id . "' AND order_status_id > '0'");
+
+ return $query->row['total'];
+ }
+
+ public function getTotalOrdersByProcessingStatus() {
+ $implode = array();
+
+ $order_statuses = $this->config->get('config_processing_status');
+
+ foreach ($order_statuses as $order_status_id) {
+ $implode[] = "order_status_id = '" . (int)$order_status_id . "'";
+ }
+
+ if ($implode) {
+ $query = $this->db->query("SELECT COUNT(*) AS total FROM `" . DB_PREFIX . "order` WHERE " . implode(" OR ", $implode));
+
+ return $query->row['total'];
+ } else {
+ return 0;
+ }
+ }
+
+ public function getTotalOrdersByCompleteStatus() {
+ $implode = array();
+
+ $order_statuses = $this->config->get('config_complete_status');
+
+ foreach ($order_statuses as $order_status_id) {
+ $implode[] = "order_status_id = '" . (int)$order_status_id . "'";
+ }
+
+ if ($implode) {
+ $query = $this->db->query("SELECT COUNT(*) AS total FROM `" . DB_PREFIX . "order` WHERE " . implode(" OR ", $implode) . "");
+
+ return $query->row['total'];
+ } else {
+ return 0;
+ }
+ }
+
+ public function getTotalOrdersByLanguageId($language_id) {
+ $query = $this->db->query("SELECT COUNT(*) AS total FROM `" . DB_PREFIX . "order` WHERE language_id = '" . (int)$language_id . "' AND order_status_id > '0'");
+
+ return $query->row['total'];
+ }
+
+ public function getTotalOrdersByCurrencyId($currency_id) {
+ $query = $this->db->query("SELECT COUNT(*) AS total FROM `" . DB_PREFIX . "order` WHERE currency_id = '" . (int)$currency_id . "' AND order_status_id > '0'");
+
+ return $query->row['total'];
+ }
+
+ public function getTotalSales($data = array()) {
+ $sql = "SELECT SUM(total) AS total FROM `" . DB_PREFIX . "order`";
+
+ if (!empty($data['filter_order_status'])) {
+ $implode = array();
+
+ $order_statuses = explode(',', $data['filter_order_status']);
+
+ foreach ($order_statuses as $order_status_id) {
+ $implode[] = "order_status_id = '" . (int)$order_status_id . "'";
+ }
+
+ if ($implode) {
+ $sql .= " WHERE (" . implode(" OR ", $implode) . ")";
+ }
+ } elseif (isset($data['filter_order_status_id']) && $data['filter_order_status_id'] !== '') {
+ $sql .= " WHERE order_status_id = '" . (int)$data['filter_order_status_id'] . "'";
+ } else {
+ $sql .= " WHERE order_status_id > '0'";
+ }
+
+ if (!empty($data['filter_order_id'])) {
+ $sql .= " AND order_id = '" . (int)$data['filter_order_id'] . "'";
+ }
+
+ if (!empty($data['filter_customer'])) {
+ $sql .= " AND CONCAT(firstname, ' ', o.lastname) LIKE '%" . $this->db->escape($data['filter_customer']) . "%'";
+ }
+
+ if (!empty($data['filter_date_added'])) {
+ $sql .= " AND DATE(date_added) = DATE('" . $this->db->escape($data['filter_date_added']) . "')";
+ }
+
+ if (!empty($data['filter_date_modified'])) {
+ $sql .= " AND DATE(date_modified) = DATE('" . $this->db->escape($data['filter_date_modified']) . "')";
+ }
+
+ if (!empty($data['filter_total'])) {
+ $sql .= " AND total = '" . (float)$data['filter_total'] . "'";
+ }
+
+ $query = $this->db->query($sql);
+
+ return $query->row['total'];
+ }
+
+ public function createInvoiceNo($order_id) {
+ $order_info = $this->getOrder($order_id);
+
+ if ($order_info && !$order_info['invoice_no']) {
+ $query = $this->db->query("SELECT MAX(invoice_no) AS invoice_no FROM `" . DB_PREFIX . "order` WHERE invoice_prefix = '" . $this->db->escape($order_info['invoice_prefix']) . "'");
+
+ if ($query->row['invoice_no']) {
+ $invoice_no = $query->row['invoice_no'] + 1;
+ } else {
+ $invoice_no = 1;
+ }
+
+ $this->db->query("UPDATE `" . DB_PREFIX . "order` SET invoice_no = '" . (int)$invoice_no . "', invoice_prefix = '" . $this->db->escape($order_info['invoice_prefix']) . "' WHERE order_id = '" . (int)$order_id . "'");
+
+ return $order_info['invoice_prefix'] . $invoice_no;
+ }
+ }
+
+ public function getOrderHistories($order_id, $start = 0, $limit = 10) {
+ if ($start < 0) {
+ $start = 0;
+ }
+
+ if ($limit < 1) {
+ $limit = 10;
+ }
+
+ $query = $this->db->query("SELECT oh.date_added, os.name AS status, oh.comment, oh.notify FROM " . DB_PREFIX . "order_history oh LEFT JOIN " . DB_PREFIX . "order_status os ON oh.order_status_id = os.order_status_id WHERE oh.order_id = '" . (int)$order_id . "' AND os.language_id = '" . (int)$this->config->get('config_language_id') . "' ORDER BY oh.date_added DESC LIMIT " . (int)$start . "," . (int)$limit);
+
+ return $query->rows;
+ }
+
+ public function getTotalOrderHistories($order_id) {
+ $query = $this->db->query("SELECT COUNT(*) AS total FROM " . DB_PREFIX . "order_history WHERE order_id = '" . (int)$order_id . "'");
+
+ return $query->row['total'];
+ }
+
+ public function getTotalOrderHistoriesByOrderStatusId($order_status_id) {
+ $query = $this->db->query("SELECT COUNT(*) AS total FROM " . DB_PREFIX . "order_history WHERE order_status_id = '" . (int)$order_status_id . "'");
+
+ return $query->row['total'];
+ }
+
+ public function getEmailsByProductsOrdered($products, $start, $end) {
+ $implode = array();
+
+ foreach ($products as $product_id) {
+ $implode[] = "op.product_id = '" . (int)$product_id . "'";
+ }
+
+ $query = $this->db->query("SELECT DISTINCT email FROM `" . DB_PREFIX . "order` o LEFT JOIN " . DB_PREFIX . "order_product op ON (o.order_id = op.order_id) WHERE (" . implode(" OR ", $implode) . ") AND o.order_status_id <> '0' LIMIT " . (int)$start . "," . (int)$end);
+
+ return $query->rows;
+ }
+
+ public function getTotalEmailsByProductsOrdered($products) {
+ $implode = array();
+
+ foreach ($products as $product_id) {
+ $implode[] = "op.product_id = '" . (int)$product_id . "'";
+ }
+
+ $query = $this->db->query("SELECT COUNT(DISTINCT email) AS total FROM `" . DB_PREFIX . "order` o LEFT JOIN " . DB_PREFIX . "order_product op ON (o.order_id = op.order_id) WHERE (" . implode(" OR ", $implode) . ") AND o.order_status_id <> '0'");
+
+ return $query->row['total'];
+ }
+}
diff --git a/public/admin/model/sale/recurring.php b/public/admin/model/sale/recurring.php
new file mode 100644
index 0000000..b2655b5
--- /dev/null
+++ b/public/admin/model/sale/recurring.php
@@ -0,0 +1,197 @@
+<?php
+class ModelSaleRecurring extends Model {
+ public function getRecurrings($data) {
+ $sql = "SELECT `or`.order_recurring_id, `or`.order_id, `or`.reference, `or`.`status`, `or`.`date_added`, CONCAT(`o`.firstname, ' ', `o`.lastname) AS customer FROM `" . DB_PREFIX . "order_recurring` `or` LEFT JOIN `" . DB_PREFIX . "order` `o` ON (`or`.order_id = `o`.order_id)";
+
+ $implode = array();
+
+ if (!empty($data['filter_order_recurring_id'])) {
+ $implode[] = "or.order_recurring_id = " . (int)$data['filter_order_recurring_id'];
+ }
+
+ if (!empty($data['filter_order_id'])) {
+ $implode[] = "or.order_id = " . (int)$data['filter_order_id'];
+ }
+
+ if (!empty($data['filter_reference'])) {
+ $implode[] = "or.reference LIKE '" . $this->db->escape($data['filter_reference']) . "%'";
+ }
+
+ if (!empty($data['filter_customer'])) {
+ $implode[] = "CONCAT(o.firstname, ' ', o.lastname) LIKE '" . $this->db->escape($data['filter_customer']) . "%'";
+ }
+
+ if (!empty($data['filter_status'])) {
+ $implode[] = "or.status = " . (int)$data['filter_status'];
+ }
+
+ if (!empty($data['filter_date_added'])) {
+ $implode[] = "DATE(or.date_added) = DATE('" . $this->db->escape($data['filter_date_added']) . "')";
+ }
+
+ if ($implode) {
+ $sql .= " WHERE " . implode(" AND ", $implode);
+ }
+
+ $sort_data = array(
+ 'or.order_recurring_id',
+ 'or.order_id',
+ 'or.reference',
+ 'customer',
+ 'or.status',
+ 'or.date_added'
+ );
+
+ if (isset($data['sort']) && in_array($data['sort'], $sort_data)) {
+ $sql .= " ORDER BY " . $data['sort'];
+ } else {
+ $sql .= " ORDER BY or.order_recurring_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'];
+ }
+
+ $query = $this->db->query($sql);
+
+ return $query->rows;
+ }
+
+ public function getRecurring($order_recurring_id) {
+ $query = $this->db->query("SELECT * FROM " . DB_PREFIX . "order_recurring WHERE order_recurring_id = " . (int)$order_recurring_id);
+
+ return $query->row;
+ }
+
+ public function getRecurringTransactions($order_recurring_id) {
+ $transactions = array();
+
+ $query = $this->db->query("SELECT amount, type, date_added FROM " . DB_PREFIX . "order_recurring_transaction WHERE order_recurring_id = " . (int)$order_recurring_id . " ORDER BY date_added DESC");
+
+ foreach ($query->rows as $result) {
+ switch ($result['type']) {
+ case 0:
+ $type = $this->language->get('text_transaction_date_added');
+ break;
+ case 1:
+ $type = $this->language->get('text_transaction_payment');
+ break;
+ case 2:
+ $type = $this->language->get('text_transaction_outstanding_payment');
+ break;
+ case 3:
+ $type = $this->language->get('text_transaction_skipped');
+ break;
+ case 4:
+ $type = $this->language->get('text_transaction_failed');
+ break;
+ case 5:
+ $type = $this->language->get('text_transaction_cancelled');
+ break;
+ case 6:
+ $type = $this->language->get('text_transaction_suspended');
+ break;
+ case 7:
+ $type = $this->language->get('text_transaction_suspended_failed');
+ break;
+ case 8:
+ $type = $this->language->get('text_transaction_outstanding_failed');
+ break;
+ case 9:
+ $type = $this->language->get('text_transaction_expired');
+ break;
+ default:
+ $type = '';
+ break;
+ }
+
+ $transactions[] = array(
+ 'date_added' => $result['date_added'],
+ 'amount' => $result['amount'],
+ 'type' => $type
+ );
+ }
+
+ return $transactions;
+ }
+
+ private function getStatus($status) {
+ switch ($status) {
+ case 1:
+ $result = $this->language->get('text_status_inactive');
+ break;
+ case 2:
+ $result = $this->language->get('text_status_active');
+ break;
+ case 3:
+ $result = $this->language->get('text_status_suspended');
+ break;
+ case 4:
+ $result = $this->language->get('text_status_cancelled');
+ break;
+ case 5:
+ $result = $this->language->get('text_status_expired');
+ break;
+ case 6:
+ $result = $this->language->get('text_status_pending');
+ break;
+ default:
+ $result = '';
+ break;
+ }
+
+ return $result;
+ }
+
+ public function getTotalRecurrings($data) {
+ $sql = "SELECT COUNT(*) AS `total` FROM `" . DB_PREFIX . "order_recurring` `or` LEFT JOIN `" . DB_PREFIX . "order` o ON (`or`.order_id = `o`.order_id)";
+
+ $implode = array();
+
+ if (!empty($data['filter_order_recurring_id'])) {
+ $implode[] .= "or.order_recurring_id = " . (int)$data['filter_order_recurring_id'];
+ }
+
+ if (!empty($data['filter_order_id'])) {
+ $implode[] .= "or.order_id = " . (int)$data['filter_order_id'];
+ }
+
+ if (!empty($data['filter_payment_reference'])) {
+ $implode[] .= " or.reference LIKE '" . $this->db->escape($data['filter_reference']) . "%'";
+ }
+
+ if (!empty($data['filter_customer'])) {
+ $implode[] .= "CONCAT(o.firstname, ' ', o.lastname) LIKE '" . $this->db->escape($data['filter_customer']) . "%'";
+ }
+
+ if (!empty($data['filter_status'])) {
+ $implode[] .= "or.status = " . (int)$data['filter_status'];
+ }
+
+ if (!empty($data['filter_date_added'])) {
+ $implode[] .= "DATE(or.date_added) = DATE('" . $this->db->escape($data['filter_date_added']) . "')";
+ }
+
+ if ($implode) {
+ $sql .= " WHERE " . implode(" AND ", $implode);
+ }
+
+ $query = $this->db->query($sql);
+
+ return $query->row['total'];
+ }
+}
diff --git a/public/admin/model/sale/return.php b/public/admin/model/sale/return.php
new file mode 100644
index 0000000..f3425e7
--- /dev/null
+++ b/public/admin/model/sale/return.php
@@ -0,0 +1,199 @@
+<?php
+class ModelSaleReturn extends Model {
+ public function addReturn($data) {
+ $this->db->query("INSERT INTO `" . DB_PREFIX . "return` SET order_id = '" . (int)$data['order_id'] . "', product_id = '" . (int)$data['product_id'] . "', customer_id = '" . (int)$data['customer_id'] . "', firstname = '" . $this->db->escape($data['firstname']) . "', lastname = '" . $this->db->escape($data['lastname']) . "', email = '" . $this->db->escape($data['email']) . "', telephone = '" . $this->db->escape($data['telephone']) . "', product = '" . $this->db->escape($data['product']) . "', model = '" . $this->db->escape($data['model']) . "', quantity = '" . (int)$data['quantity'] . "', opened = '" . (int)$data['opened'] . "', return_reason_id = '" . (int)$data['return_reason_id'] . "', return_action_id = '" . (int)$data['return_action_id'] . "', return_status_id = '" . (int)$data['return_status_id'] . "', comment = '" . $this->db->escape($data['comment']) . "', date_ordered = '" . $this->db->escape($data['date_ordered']) . "', date_added = NOW(), date_modified = NOW()");
+
+ return $this->db->getLastId();
+ }
+
+ public function editReturn($return_id, $data) {
+ $this->db->query("UPDATE `" . DB_PREFIX . "return` SET order_id = '" . (int)$data['order_id'] . "', product_id = '" . (int)$data['product_id'] . "', customer_id = '" . (int)$data['customer_id'] . "', firstname = '" . $this->db->escape($data['firstname']) . "', lastname = '" . $this->db->escape($data['lastname']) . "', email = '" . $this->db->escape($data['email']) . "', telephone = '" . $this->db->escape($data['telephone']) . "', product = '" . $this->db->escape($data['product']) . "', model = '" . $this->db->escape($data['model']) . "', quantity = '" . (int)$data['quantity'] . "', opened = '" . (int)$data['opened'] . "', return_reason_id = '" . (int)$data['return_reason_id'] . "', return_action_id = '" . (int)$data['return_action_id'] . "', comment = '" . $this->db->escape($data['comment']) . "', date_ordered = '" . $this->db->escape($data['date_ordered']) . "', date_modified = NOW() WHERE return_id = '" . (int)$return_id . "'");
+ }
+
+ public function deleteReturn($return_id) {
+ $this->db->query("DELETE FROM `" . DB_PREFIX . "return` WHERE `return_id` = '" . (int)$return_id . "'");
+ $this->db->query("DELETE FROM `" . DB_PREFIX . "return_history` WHERE `return_id` = '" . (int)$return_id . "'");
+ }
+
+ public function getReturn($return_id) {
+ $query = $this->db->query("SELECT DISTINCT *, (SELECT CONCAT(c.firstname, ' ', c.lastname) FROM " . DB_PREFIX . "customer c WHERE c.customer_id = r.customer_id) AS customer, (SELECT rs.name FROM " . DB_PREFIX . "return_status rs WHERE rs.return_status_id = r.return_status_id AND rs.language_id = '" . (int)$this->config->get('config_language_id') . "') AS return_status FROM `" . DB_PREFIX . "return` r WHERE r.return_id = '" . (int)$return_id . "'");
+
+ return $query->row;
+ }
+
+ public function getReturns($data = array()) {
+ $sql = "SELECT *, CONCAT(r.firstname, ' ', r.lastname) AS customer, (SELECT rs.name FROM " . DB_PREFIX . "return_status rs WHERE rs.return_status_id = r.return_status_id AND rs.language_id = '" . (int)$this->config->get('config_language_id') . "') AS return_status FROM `" . DB_PREFIX . "return` r";
+
+ $implode = array();
+
+ if (!empty($data['filter_return_id'])) {
+ $implode[] = "r.return_id = '" . (int)$data['filter_return_id'] . "'";
+ }
+
+ if (!empty($data['filter_order_id'])) {
+ $implode[] = "r.order_id = '" . (int)$data['filter_order_id'] . "'";
+ }
+
+ if (!empty($data['filter_customer'])) {
+ $implode[] = "CONCAT(r.firstname, ' ', r.lastname) LIKE '" . $this->db->escape($data['filter_customer']) . "%'";
+ }
+
+ if (!empty($data['filter_product'])) {
+ $implode[] = "r.product = '" . $this->db->escape($data['filter_product']) . "'";
+ }
+
+ if (!empty($data['filter_model'])) {
+ $implode[] = "r.model = '" . $this->db->escape($data['filter_model']) . "'";
+ }
+
+ if (!empty($data['filter_return_status_id'])) {
+ $implode[] = "r.return_status_id = '" . (int)$data['filter_return_status_id'] . "'";
+ }
+
+ if (!empty($data['filter_date_added'])) {
+ $implode[] = "DATE(r.date_added) = DATE('" . $this->db->escape($data['filter_date_added']) . "')";
+ }
+
+ if (!empty($data['filter_date_modified'])) {
+ $implode[] = "DATE(r.date_modified) = DATE('" . $this->db->escape($data['filter_date_modified']) . "')";
+ }
+
+ if ($implode) {
+ $sql .= " WHERE " . implode(" AND ", $implode);
+ }
+
+ $sort_data = array(
+ 'r.return_id',
+ 'r.order_id',
+ 'customer',
+ 'r.product',
+ 'r.model',
+ 'status',
+ 'r.date_added',
+ 'r.date_modified'
+ );
+
+ if (isset($data['sort']) && in_array($data['sort'], $sort_data)) {
+ $sql .= " ORDER BY " . $data['sort'];
+ } else {
+ $sql .= " ORDER BY r.return_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'];
+ }
+
+ $query = $this->db->query($sql);
+
+ return $query->rows;
+ }
+
+ public function getTotalReturns($data = array()) {
+ $sql = "SELECT COUNT(*) AS total FROM `" . DB_PREFIX . "return`r";
+
+ $implode = array();
+
+ if (!empty($data['filter_return_id'])) {
+ $implode[] = "r.return_id = '" . (int)$data['filter_return_id'] . "'";
+ }
+
+ if (!empty($data['filter_customer'])) {
+ $implode[] = "CONCAT(r.firstname, ' ', r.lastname) LIKE '" . $this->db->escape($data['filter_customer']) . "%'";
+ }
+
+ if (!empty($data['filter_order_id'])) {
+ $implode[] = "r.order_id = '" . $this->db->escape($data['filter_order_id']) . "'";
+ }
+
+ if (!empty($data['filter_product'])) {
+ $implode[] = "r.product = '" . $this->db->escape($data['filter_product']) . "'";
+ }
+
+ if (!empty($data['filter_model'])) {
+ $implode[] = "r.model = '" . $this->db->escape($data['filter_model']) . "'";
+ }
+
+ if (!empty($data['filter_return_status_id'])) {
+ $implode[] = "r.return_status_id = '" . (int)$data['filter_return_status_id'] . "'";
+ }
+
+ if (!empty($data['filter_date_added'])) {
+ $implode[] = "DATE(r.date_added) = DATE('" . $this->db->escape($data['filter_date_added']) . "')";
+ }
+
+ if (!empty($data['filter_date_modified'])) {
+ $implode[] = "DATE(r.date_modified) = DATE('" . $this->db->escape($data['filter_date_modified']) . "')";
+ }
+
+ if ($implode) {
+ $sql .= " WHERE " . implode(" AND ", $implode);
+ }
+
+ $query = $this->db->query($sql);
+
+ return $query->row['total'];
+ }
+
+ public function getTotalReturnsByReturnStatusId($return_status_id) {
+ $query = $this->db->query("SELECT COUNT(*) AS total FROM `" . DB_PREFIX . "return` WHERE return_status_id = '" . (int)$return_status_id . "'");
+
+ return $query->row['total'];
+ }
+
+ public function getTotalReturnsByReturnReasonId($return_reason_id) {
+ $query = $this->db->query("SELECT COUNT(*) AS total FROM `" . DB_PREFIX . "return` WHERE return_reason_id = '" . (int)$return_reason_id . "'");
+
+ return $query->row['total'];
+ }
+
+ public function getTotalReturnsByReturnActionId($return_action_id) {
+ $query = $this->db->query("SELECT COUNT(*) AS total FROM `" . DB_PREFIX . "return` WHERE return_action_id = '" . (int)$return_action_id . "'");
+
+ return $query->row['total'];
+ }
+
+ public function addReturnHistory($return_id, $return_status_id, $comment, $notify) {
+ $this->db->query("UPDATE `" . DB_PREFIX . "return` SET `return_status_id` = '" . (int)$return_status_id . "', date_modified = NOW() WHERE return_id = '" . (int)$return_id . "'");
+ $this->db->query("INSERT INTO `" . DB_PREFIX . "return_history` SET `return_id` = '" . (int)$return_id . "', return_status_id = '" . (int)$return_status_id . "', notify = '" . (int)$notify . "', comment = '" . $this->db->escape(strip_tags($comment)) . "', date_added = NOW()");
+ }
+
+ public function getReturnHistories($return_id, $start = 0, $limit = 10) {
+ if ($start < 0) {
+ $start = 0;
+ }
+
+ if ($limit < 1) {
+ $limit = 10;
+ }
+
+ $query = $this->db->query("SELECT rh.date_added, rs.name AS status, rh.comment, rh.notify FROM " . DB_PREFIX . "return_history rh LEFT JOIN " . DB_PREFIX . "return_status rs ON rh.return_status_id = rs.return_status_id WHERE rh.return_id = '" . (int)$return_id . "' AND rs.language_id = '" . (int)$this->config->get('config_language_id') . "' ORDER BY rh.date_added DESC LIMIT " . (int)$start . "," . (int)$limit);
+
+ return $query->rows;
+ }
+
+ public function getTotalReturnHistories($return_id) {
+ $query = $this->db->query("SELECT COUNT(*) AS total FROM " . DB_PREFIX . "return_history WHERE return_id = '" . (int)$return_id . "'");
+
+ return $query->row['total'];
+ }
+
+ public function getTotalReturnHistoriesByReturnStatusId($return_status_id) {
+ $query = $this->db->query("SELECT COUNT(*) AS total FROM " . DB_PREFIX . "return_history WHERE return_status_id = '" . (int)$return_status_id . "'");
+
+ return $query->row['total'];
+ }
+} \ No newline at end of file
diff --git a/public/admin/model/sale/voucher.php b/public/admin/model/sale/voucher.php
new file mode 100644
index 0000000..97fd867
--- /dev/null
+++ b/public/admin/model/sale/voucher.php
@@ -0,0 +1,103 @@
+<?php
+class ModelSaleVoucher extends Model {
+ public function addVoucher($data) {
+ $this->db->query("INSERT INTO " . DB_PREFIX . "voucher SET code = '" . $this->db->escape($data['code']) . "', from_name = '" . $this->db->escape($data['from_name']) . "', from_email = '" . $this->db->escape($data['from_email']) . "', to_name = '" . $this->db->escape($data['to_name']) . "', to_email = '" . $this->db->escape($data['to_email']) . "', voucher_theme_id = '" . (int)$data['voucher_theme_id'] . "', message = '" . $this->db->escape($data['message']) . "', amount = '" . (float)$data['amount'] . "', status = '" . (int)$data['status'] . "', date_added = NOW()");
+
+ return $this->db->getLastId();
+ }
+
+ public function editVoucher($voucher_id, $data) {
+ $this->db->query("UPDATE " . DB_PREFIX . "voucher SET code = '" . $this->db->escape($data['code']) . "', from_name = '" . $this->db->escape($data['from_name']) . "', from_email = '" . $this->db->escape($data['from_email']) . "', to_name = '" . $this->db->escape($data['to_name']) . "', to_email = '" . $this->db->escape($data['to_email']) . "', voucher_theme_id = '" . (int)$data['voucher_theme_id'] . "', message = '" . $this->db->escape($data['message']) . "', amount = '" . (float)$data['amount'] . "', status = '" . (int)$data['status'] . "' WHERE voucher_id = '" . (int)$voucher_id . "'");
+ }
+
+ public function deleteVoucher($voucher_id) {
+ $this->db->query("DELETE FROM " . DB_PREFIX . "voucher WHERE voucher_id = '" . (int)$voucher_id . "'");
+ $this->db->query("DELETE FROM " . DB_PREFIX . "voucher_history WHERE voucher_id = '" . (int)$voucher_id . "'");
+ }
+
+ public function getVoucher($voucher_id) {
+ $query = $this->db->query("SELECT DISTINCT * FROM " . DB_PREFIX . "voucher WHERE voucher_id = '" . (int)$voucher_id . "'");
+
+ return $query->row;
+ }
+
+ public function getVoucherByCode($code) {
+ $query = $this->db->query("SELECT DISTINCT * FROM " . DB_PREFIX . "voucher WHERE code = '" . $this->db->escape($code) . "'");
+
+ return $query->row;
+ }
+
+ public function getVouchers($data = array()) {
+ $sql = "SELECT v.voucher_id, v.order_id, v.code, v.from_name, v.from_email, v.to_name, v.to_email, (SELECT vtd.name FROM " . DB_PREFIX . "voucher_theme_description vtd WHERE vtd.voucher_theme_id = v.voucher_theme_id AND vtd.language_id = '" . (int)$this->config->get('config_language_id') . "') AS theme, v.amount, v.status, v.date_added FROM " . DB_PREFIX . "voucher v";
+
+ $sort_data = array(
+ 'v.code',
+ 'v.from_name',
+ 'v.to_name',
+ 'theme',
+ 'v.amount',
+ 'v.status',
+ 'v.date_added'
+ );
+
+ if (isset($data['sort']) && in_array($data['sort'], $sort_data)) {
+ $sql .= " ORDER BY " . $data['sort'];
+ } else {
+ $sql .= " ORDER BY v.date_added";
+ }
+
+ 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'];
+ }
+
+ $query = $this->db->query($sql);
+
+ return $query->rows;
+ }
+
+ public function getTotalVouchers() {
+ $query = $this->db->query("SELECT COUNT(*) AS total FROM " . DB_PREFIX . "voucher");
+
+ return $query->row['total'];
+ }
+
+ public function getTotalVouchersByVoucherThemeId($voucher_theme_id) {
+ $query = $this->db->query("SELECT COUNT(*) AS total FROM " . DB_PREFIX . "voucher WHERE voucher_theme_id = '" . (int)$voucher_theme_id . "'");
+
+ return $query->row['total'];
+ }
+
+ public function getVoucherHistories($voucher_id, $start = 0, $limit = 10) {
+ if ($start < 0) {
+ $start = 0;
+ }
+
+ if ($limit < 1) {
+ $limit = 10;
+ }
+
+ $query = $this->db->query("SELECT vh.order_id, CONCAT(o.firstname, ' ', o.lastname) AS customer, vh.amount, vh.date_added FROM " . DB_PREFIX . "voucher_history vh LEFT JOIN `" . DB_PREFIX . "order` o ON (vh.order_id = o.order_id) WHERE vh.voucher_id = '" . (int)$voucher_id . "' ORDER BY vh.date_added ASC LIMIT " . (int)$start . "," . (int)$limit);
+
+ return $query->rows;
+ }
+
+ public function getTotalVoucherHistories($voucher_id) {
+ $query = $this->db->query("SELECT COUNT(*) AS total FROM " . DB_PREFIX . "voucher_history WHERE voucher_id = '" . (int)$voucher_id . "'");
+
+ return $query->row['total'];
+ }
+}
diff --git a/public/admin/model/sale/voucher_theme.php b/public/admin/model/sale/voucher_theme.php
new file mode 100644
index 0000000..d3dc3c0
--- /dev/null
+++ b/public/admin/model/sale/voucher_theme.php
@@ -0,0 +1,99 @@
+<?php
+class ModelSaleVoucherTheme extends Model {
+ public function addVoucherTheme($data) {
+ $this->db->query("INSERT INTO " . DB_PREFIX . "voucher_theme SET image = '" . $this->db->escape($data['image']) . "'");
+
+ $voucher_theme_id = $this->db->getLastId();
+
+ foreach ($data['voucher_theme_description'] as $language_id => $value) {
+ $this->db->query("INSERT INTO " . DB_PREFIX . "voucher_theme_description SET voucher_theme_id = '" . (int)$voucher_theme_id . "', language_id = '" . (int)$language_id . "', name = '" . $this->db->escape($value['name']) . "'");
+ }
+
+ $this->cache->delete('voucher_theme');
+
+ return $voucher_theme_id;
+ }
+
+ public function editVoucherTheme($voucher_theme_id, $data) {
+ $this->db->query("UPDATE " . DB_PREFIX . "voucher_theme SET image = '" . $this->db->escape($data['image']) . "' WHERE voucher_theme_id = '" . (int)$voucher_theme_id . "'");
+
+ $this->db->query("DELETE FROM " . DB_PREFIX . "voucher_theme_description WHERE voucher_theme_id = '" . (int)$voucher_theme_id . "'");
+
+ foreach ($data['voucher_theme_description'] as $language_id => $value) {
+ $this->db->query("INSERT INTO " . DB_PREFIX . "voucher_theme_description SET voucher_theme_id = '" . (int)$voucher_theme_id . "', language_id = '" . (int)$language_id . "', name = '" . $this->db->escape($value['name']) . "'");
+ }
+
+ $this->cache->delete('voucher_theme');
+ }
+
+ public function deleteVoucherTheme($voucher_theme_id) {
+ $this->db->query("DELETE FROM " . DB_PREFIX . "voucher_theme WHERE voucher_theme_id = '" . (int)$voucher_theme_id . "'");
+ $this->db->query("DELETE FROM " . DB_PREFIX . "voucher_theme_description WHERE voucher_theme_id = '" . (int)$voucher_theme_id . "'");
+
+ $this->cache->delete('voucher_theme');
+ }
+
+ public function getVoucherTheme($voucher_theme_id) {
+ $query = $this->db->query("SELECT * FROM " . DB_PREFIX . "voucher_theme vt LEFT JOIN " . DB_PREFIX . "voucher_theme_description vtd ON (vt.voucher_theme_id = vtd.voucher_theme_id) WHERE vt.voucher_theme_id = '" . (int)$voucher_theme_id . "' AND vtd.language_id = '" . (int)$this->config->get('config_language_id') . "'");
+
+ return $query->row;
+ }
+
+ public function getVoucherThemes($data = array()) {
+ if ($data) {
+ $sql = "SELECT * FROM " . DB_PREFIX . "voucher_theme vt LEFT JOIN " . DB_PREFIX . "voucher_theme_description vtd ON (vt.voucher_theme_id = vtd.voucher_theme_id) WHERE vtd.language_id = '" . (int)$this->config->get('config_language_id') . "' ORDER BY vtd.name";
+
+ 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'];
+ }
+
+ $query = $this->db->query($sql);
+
+ return $query->rows;
+ } else {
+ $voucher_theme_data = $this->cache->get('voucher_theme.' . (int)$this->config->get('config_language_id'));
+
+ if (!$voucher_theme_data) {
+ $query = $this->db->query("SELECT * FROM " . DB_PREFIX . "voucher_theme vt LEFT JOIN " . DB_PREFIX . "voucher_theme_description vtd ON (vt.voucher_theme_id = vtd.voucher_theme_id) WHERE vtd.language_id = '" . (int)$this->config->get('config_language_id') . "' ORDER BY vtd.name");
+
+ $voucher_theme_data = $query->rows;
+
+ $this->cache->set('voucher_theme.' . (int)$this->config->get('config_language_id'), $voucher_theme_data);
+ }
+
+ return $voucher_theme_data;
+ }
+ }
+
+ public function getVoucherThemeDescriptions($voucher_theme_id) {
+ $voucher_theme_data = array();
+
+ $query = $this->db->query("SELECT * FROM " . DB_PREFIX . "voucher_theme_description WHERE voucher_theme_id = '" . (int)$voucher_theme_id . "'");
+
+ foreach ($query->rows as $result) {
+ $voucher_theme_data[$result['language_id']] = array('name' => $result['name']);
+ }
+
+ return $voucher_theme_data;
+ }
+
+ public function getTotalVoucherThemes() {
+ $query = $this->db->query("SELECT COUNT(*) AS total FROM " . DB_PREFIX . "voucher_theme");
+
+ return $query->row['total'];
+ }
+} \ No newline at end of file
diff --git a/public/admin/model/setting/event.php b/public/admin/model/setting/event.php
new file mode 100644
index 0000000..6e76425
--- /dev/null
+++ b/public/admin/model/setting/event.php
@@ -0,0 +1,88 @@
+<?php
+class ModelSettingEvent extends Model {
+ public function addEvent($code, $trigger, $action, $status = 1, $sort_order = 0) {
+ $this->db->query("INSERT INTO `" . DB_PREFIX . "event` SET `code` = '" . $this->db->escape($code) . "', `trigger` = '" . $this->db->escape($trigger) . "', `action` = '" . $this->db->escape($action) . "', `sort_order` = '" . (int)$sort_order . "', `status` = '" . (int)$status . "'");
+
+ return $this->db->getLastId();
+ }
+
+ public function deleteEvent($event_id) {
+ $this->db->query("DELETE FROM `" . DB_PREFIX . "event` WHERE `event_id` = '" . (int)$event_id . "'");
+ }
+
+ public function deleteEventByCode($code) {
+ $this->db->query("DELETE FROM `" . DB_PREFIX . "event` WHERE `code` = '" . $this->db->escape($code) . "'");
+ }
+
+ public function enableEvent($event_id) {
+ $this->db->query("UPDATE `" . DB_PREFIX . "event` SET `status` = '1' WHERE event_id = '" . (int)$event_id . "'");
+ }
+
+ public function disableEvent($event_id) {
+ $this->db->query("UPDATE `" . DB_PREFIX . "event` SET `status` = '0' WHERE event_id = '" . (int)$event_id . "'");
+ }
+
+ public function uninstall($type, $code) {
+ $this->db->query("DELETE FROM `" . DB_PREFIX . "extension` WHERE `type` = '" . $this->db->escape($type) . "' AND `code` = '" . $this->db->escape($code) . "'");
+ $this->db->query("DELETE FROM `" . DB_PREFIX . "setting` WHERE `code` = '" . $this->db->escape($code) . "'");
+ }
+
+ public function getEvent($event_id) {
+ $query = $this->db->query("SELECT DISTINCT * FROM `" . DB_PREFIX . "event` WHERE `event_id` = '" . (int)$event_id . "' LIMIT 1");
+
+ return $query->row;
+ }
+
+ public function getEventByCode($code) {
+ $query = $this->db->query("SELECT DISTINCT * FROM `" . DB_PREFIX . "event` WHERE `code` = '" . $this->db->escape($code) . "' LIMIT 1");
+
+ return $query->row;
+ }
+
+ public function getEvents($data = array()) {
+ $sql = "SELECT * FROM `" . DB_PREFIX . "event`";
+
+ $sort_data = array(
+ 'code',
+ 'trigger',
+ 'action',
+ 'sort_order',
+ 'status',
+ 'date_added'
+ );
+
+ if (isset($data['sort']) && in_array($data['sort'], $sort_data)) {
+ $sql .= " ORDER BY `" . $data['sort'] . "`";
+ } else {
+ $sql .= " ORDER BY `sort_order`";
+ }
+
+ 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'];
+ }
+
+ $query = $this->db->query($sql);
+
+ return $query->rows;
+ }
+
+ public function getTotalEvents() {
+ $query = $this->db->query("SELECT COUNT(*) AS total FROM `" . DB_PREFIX . "event`");
+
+ return $query->row['total'];
+ }
+} \ No newline at end of file
diff --git a/public/admin/model/setting/extension.php b/public/admin/model/setting/extension.php
new file mode 100644
index 0000000..4c42f0e
--- /dev/null
+++ b/public/admin/model/setting/extension.php
@@ -0,0 +1,77 @@
+<?php
+class ModelSettingExtension extends Model {
+ public function getInstalled($type) {
+ $extension_data = array();
+
+ $query = $this->db->query("SELECT * FROM `" . DB_PREFIX . "extension` WHERE `type` = '" . $this->db->escape($type) . "' ORDER BY `code`");
+
+ foreach ($query->rows as $result) {
+ $extension_data[] = $result['code'];
+ }
+
+ return $extension_data;
+ }
+
+ public function install($type, $code) {
+ $extensions = $this->getInstalled($type);
+
+ if (!in_array($code, $extensions)) {
+ $this->db->query("INSERT INTO `" . DB_PREFIX . "extension` SET `type` = '" . $this->db->escape($type) . "', `code` = '" . $this->db->escape($code) . "'");
+ }
+ }
+
+ public function uninstall($type, $code) {
+ $this->db->query("DELETE FROM `" . DB_PREFIX . "extension` WHERE `type` = '" . $this->db->escape($type) . "' AND `code` = '" . $this->db->escape($code) . "'");
+ $this->db->query("DELETE FROM `" . DB_PREFIX . "setting` WHERE `code` = '" . $this->db->escape($type . '_' . $code) . "'");
+ }
+
+ public function addExtensionInstall($filename, $extension_download_id = 0) {
+ $this->db->query("INSERT INTO `" . DB_PREFIX . "extension_install` SET `filename` = '" . $this->db->escape($filename) . "', `extension_download_id` = '" . (int)$extension_download_id . "', `date_added` = NOW()");
+
+ return $this->db->getLastId();
+ }
+
+ public function deleteExtensionInstall($extension_install_id) {
+ $this->db->query("DELETE FROM `" . DB_PREFIX . "extension_install` WHERE `extension_install_id` = '" . (int)$extension_install_id . "'");
+ }
+
+ public function getExtensionInstalls($start = 0, $limit = 10) {
+ if ($start < 0) {
+ $start = 0;
+ }
+
+ if ($limit < 1) {
+ $limit = 10;
+ }
+
+ $query = $this->db->query("SELECT * FROM `" . DB_PREFIX . "extension_install` ORDER BY date_added ASC LIMIT " . (int)$start . "," . (int)$limit);
+
+ return $query->rows;
+ }
+
+ public function getExtensionInstallByExtensionDownloadId($extension_download_id) {
+ $query = $this->db->query("SELECT * FROM `" . DB_PREFIX . "extension_install` WHERE `extension_download_id` = '" . (int)$extension_download_id . "'");
+
+ return $query->row;
+ }
+
+ public function getTotalExtensionInstalls() {
+ $query = $this->db->query("SELECT COUNT(*) AS total FROM `" . DB_PREFIX . "extension_install`");
+
+ return $query->row['total'];
+ }
+
+ public function addExtensionPath($extension_install_id, $path) {
+ $this->db->query("INSERT INTO `" . DB_PREFIX . "extension_path` SET `extension_install_id` = '" . (int)$extension_install_id . "', `path` = '" . $this->db->escape($path) . "', `date_added` = NOW()");
+ }
+
+ public function deleteExtensionPath($extension_path_id) {
+ $this->db->query("DELETE FROM `" . DB_PREFIX . "extension_path` WHERE `extension_path_id` = '" . (int)$extension_path_id . "'");
+ }
+
+ public function getExtensionPathsByExtensionInstallId($extension_install_id) {
+ $query = $this->db->query("SELECT * FROM `" . DB_PREFIX . "extension_path` WHERE `extension_install_id` = '" . (int)$extension_install_id . "' ORDER BY `date_added` ASC");
+
+ return $query->rows;
+ }
+} \ No newline at end of file
diff --git a/public/admin/model/setting/modification.php b/public/admin/model/setting/modification.php
new file mode 100644
index 0000000..28ca33c
--- /dev/null
+++ b/public/admin/model/setting/modification.php
@@ -0,0 +1,80 @@
+<?php
+class ModelSettingModification extends Model {
+ public function addModification($data) {
+ $this->db->query("INSERT INTO `" . DB_PREFIX . "modification` SET `extension_install_id` = '" . (int)$data['extension_install_id'] . "', `name` = '" . $this->db->escape($data['name']) . "', `code` = '" . $this->db->escape($data['code']) . "', `author` = '" . $this->db->escape($data['author']) . "', `version` = '" . $this->db->escape($data['version']) . "', `link` = '" . $this->db->escape($data['link']) . "', `xml` = '" . $this->db->escape($data['xml']) . "', `status` = '" . (int)$data['status'] . "', `date_added` = NOW()");
+ }
+
+ public function deleteModification($modification_id) {
+ $this->db->query("DELETE FROM `" . DB_PREFIX . "modification` WHERE `modification_id` = '" . (int)$modification_id . "'");
+ }
+
+ public function deleteModificationsByExtensionInstallId($extension_install_id) {
+ $this->db->query("DELETE FROM `" . DB_PREFIX . "modification` WHERE `extension_install_id` = '" . (int)$extension_install_id . "'");
+ }
+
+ public function enableModification($modification_id) {
+ $this->db->query("UPDATE `" . DB_PREFIX . "modification` SET `status` = '1' WHERE `modification_id` = '" . (int)$modification_id . "'");
+ }
+
+ public function disableModification($modification_id) {
+ $this->db->query("UPDATE `" . DB_PREFIX . "modification` SET `status` = '0' WHERE `modification_id` = '" . (int)$modification_id . "'");
+ }
+
+ public function getModification($modification_id) {
+ $query = $this->db->query("SELECT * FROM `" . DB_PREFIX . "modification` WHERE `modification_id` = '" . (int)$modification_id . "'");
+
+ return $query->row;
+ }
+
+ public function getModifications($data = array()) {
+ $sql = "SELECT * FROM `" . DB_PREFIX . "modification`";
+
+ $sort_data = array(
+ 'name',
+ 'author',
+ 'version',
+ 'status',
+ 'date_added'
+ );
+
+ if (isset($data['sort']) && in_array($data['sort'], $sort_data)) {
+ $sql .= " ORDER BY " . $data['sort'];
+ } else {
+ $sql .= " ORDER BY name";
+ }
+
+ 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'];
+ }
+
+ $query = $this->db->query($sql);
+
+ return $query->rows;
+ }
+
+ public function getTotalModifications() {
+ $query = $this->db->query("SELECT COUNT(*) AS total FROM `" . DB_PREFIX . "modification`");
+
+ return $query->row['total'];
+ }
+
+ public function getModificationByCode($code) {
+ $query = $this->db->query("SELECT * FROM `" . DB_PREFIX . "modification` WHERE `code` = '" . $this->db->escape($code) . "'");
+
+ return $query->row;
+ }
+} \ No newline at end of file
diff --git a/public/admin/model/setting/module.php b/public/admin/model/setting/module.php
new file mode 100644
index 0000000..c05b53a
--- /dev/null
+++ b/public/admin/model/setting/module.php
@@ -0,0 +1,42 @@
+<?php
+class ModelSettingModule extends Model {
+ public function addModule($code, $data) {
+ $this->db->query("INSERT INTO `" . DB_PREFIX . "module` SET `name` = '" . $this->db->escape($data['name']) . "', `code` = '" . $this->db->escape($code) . "', `setting` = '" . $this->db->escape(json_encode($data)) . "'");
+ }
+
+ public function editModule($module_id, $data) {
+ $this->db->query("UPDATE `" . DB_PREFIX . "module` SET `name` = '" . $this->db->escape($data['name']) . "', `setting` = '" . $this->db->escape(json_encode($data)) . "' WHERE `module_id` = '" . (int)$module_id . "'");
+ }
+
+ public function deleteModule($module_id) {
+ $this->db->query("DELETE FROM `" . DB_PREFIX . "module` WHERE `module_id` = '" . (int)$module_id . "'");
+ $this->db->query("DELETE FROM `" . DB_PREFIX . "layout_module` WHERE `code` LIKE '%." . (int)$module_id . "'");
+ }
+
+ public function getModule($module_id) {
+ $query = $this->db->query("SELECT * FROM `" . DB_PREFIX . "module` WHERE `module_id` = '" . (int)$module_id . "'");
+
+ if ($query->row) {
+ return json_decode($query->row['setting'], true);
+ } else {
+ return array();
+ }
+ }
+
+ public function getModules() {
+ $query = $this->db->query("SELECT * FROM `" . DB_PREFIX . "module` ORDER BY `code`");
+
+ return $query->rows;
+ }
+
+ public function getModulesByCode($code) {
+ $query = $this->db->query("SELECT * FROM `" . DB_PREFIX . "module` WHERE `code` = '" . $this->db->escape($code) . "' ORDER BY `name`");
+
+ return $query->rows;
+ }
+
+ public function deleteModulesByCode($code) {
+ $this->db->query("DELETE FROM `" . DB_PREFIX . "module` WHERE `code` = '" . $this->db->escape($code) . "'");
+ $this->db->query("DELETE FROM `" . DB_PREFIX . "layout_module` WHERE `code` LIKE '" . $this->db->escape($code) . "' OR `code` LIKE '" . $this->db->escape($code . '.%') . "'");
+ }
+} \ No newline at end of file
diff --git a/public/admin/model/setting/setting.php b/public/admin/model/setting/setting.php
new file mode 100644
index 0000000..613b621
--- /dev/null
+++ b/public/admin/model/setting/setting.php
@@ -0,0 +1,54 @@
+<?php
+class ModelSettingSetting extends Model {
+ public function getSetting($code, $store_id = 0) {
+ $setting_data = array();
+
+ $query = $this->db->query("SELECT * FROM " . DB_PREFIX . "setting WHERE store_id = '" . (int)$store_id . "' AND `code` = '" . $this->db->escape($code) . "'");
+
+ foreach ($query->rows as $result) {
+ if (!$result['serialized']) {
+ $setting_data[$result['key']] = $result['value'];
+ } else {
+ $setting_data[$result['key']] = json_decode($result['value'], true);
+ }
+ }
+
+ return $setting_data;
+ }
+
+ public function editSetting($code, $data, $store_id = 0) {
+ $this->db->query("DELETE FROM `" . DB_PREFIX . "setting` WHERE store_id = '" . (int)$store_id . "' AND `code` = '" . $this->db->escape($code) . "'");
+
+ foreach ($data as $key => $value) {
+ if (substr($key, 0, strlen($code)) == $code) {
+ if (!is_array($value)) {
+ $this->db->query("INSERT INTO " . DB_PREFIX . "setting SET store_id = '" . (int)$store_id . "', `code` = '" . $this->db->escape($code) . "', `key` = '" . $this->db->escape($key) . "', `value` = '" . $this->db->escape($value) . "'");
+ } else {
+ $this->db->query("INSERT INTO " . DB_PREFIX . "setting SET store_id = '" . (int)$store_id . "', `code` = '" . $this->db->escape($code) . "', `key` = '" . $this->db->escape($key) . "', `value` = '" . $this->db->escape(json_encode($value, true)) . "', serialized = '1'");
+ }
+ }
+ }
+ }
+
+ public function deleteSetting($code, $store_id = 0) {
+ $this->db->query("DELETE FROM " . DB_PREFIX . "setting WHERE store_id = '" . (int)$store_id . "' AND `code` = '" . $this->db->escape($code) . "'");
+ }
+
+ public function getSettingValue($key, $store_id = 0) {
+ $query = $this->db->query("SELECT value FROM " . DB_PREFIX . "setting WHERE store_id = '" . (int)$store_id . "' AND `key` = '" . $this->db->escape($key) . "'");
+
+ if ($query->num_rows) {
+ return $query->row['value'];
+ } else {
+ return null;
+ }
+ }
+
+ public function editSettingValue($code = '', $key = '', $value = '', $store_id = 0) {
+ if (!is_array($value)) {
+ $this->db->query("UPDATE " . DB_PREFIX . "setting SET `value` = '" . $this->db->escape($value) . "', serialized = '0' WHERE `code` = '" . $this->db->escape($code) . "' AND `key` = '" . $this->db->escape($key) . "' AND store_id = '" . (int)$store_id . "'");
+ } else {
+ $this->db->query("UPDATE " . DB_PREFIX . "setting SET `value` = '" . $this->db->escape(json_encode($value)) . "', serialized = '1' WHERE `code` = '" . $this->db->escape($code) . "' AND `key` = '" . $this->db->escape($key) . "' AND store_id = '" . (int)$store_id . "'");
+ }
+ }
+}
diff --git a/public/admin/model/setting/store.php b/public/admin/model/setting/store.php
new file mode 100644
index 0000000..5a12c05
--- /dev/null
+++ b/public/admin/model/setting/store.php
@@ -0,0 +1,108 @@
+<?php
+class ModelSettingStore extends Model {
+ public function addStore($data) {
+ $this->db->query("INSERT INTO " . DB_PREFIX . "store SET name = '" . $this->db->escape($data['config_name']) . "', `url` = '" . $this->db->escape($data['config_url']) . "', `ssl` = '" . $this->db->escape($data['config_ssl']) . "'");
+
+ $store_id = $this->db->getLastId();
+
+ // Layout Route
+ $query = $this->db->query("SELECT * FROM " . DB_PREFIX . "layout_route WHERE store_id = '0'");
+
+ foreach ($query->rows as $layout_route) {
+ $this->db->query("INSERT INTO " . DB_PREFIX . "layout_route SET layout_id = '" . (int)$layout_route['layout_id'] . "', route = '" . $this->db->escape($layout_route['route']) . "', store_id = '" . (int)$store_id . "'");
+ }
+
+ $this->cache->delete('store');
+
+ return $store_id;
+ }
+
+ public function editStore($store_id, $data) {
+ $this->db->query("UPDATE " . DB_PREFIX . "store SET name = '" . $this->db->escape($data['config_name']) . "', `url` = '" . $this->db->escape($data['config_url']) . "', `ssl` = '" . $this->db->escape($data['config_ssl']) . "' WHERE store_id = '" . (int)$store_id . "'");
+
+ $this->cache->delete('store');
+ }
+
+ public function deleteStore($store_id) {
+ $this->db->query("DELETE FROM " . DB_PREFIX . "store WHERE store_id = '" . (int)$store_id . "'");
+ $this->db->query("DELETE FROM " . DB_PREFIX . "layout_route WHERE store_id = '" . (int)$store_id . "'");
+
+ $this->cache->delete('store');
+ }
+
+ public function getStore($store_id) {
+ $query = $this->db->query("SELECT DISTINCT * FROM " . DB_PREFIX . "store WHERE store_id = '" . (int)$store_id . "'");
+
+ return $query->row;
+ }
+
+ public function getStores($data = array()) {
+ $store_data = $this->cache->get('store');
+
+ if (!$store_data) {
+ $query = $this->db->query("SELECT * FROM " . DB_PREFIX . "store ORDER BY url");
+
+ $store_data = $query->rows;
+
+ $this->cache->set('store', $store_data);
+ }
+
+ return $store_data;
+ }
+
+ public function getTotalStores() {
+ $query = $this->db->query("SELECT COUNT(*) AS total FROM " . DB_PREFIX . "store");
+
+ return $query->row['total'];
+ }
+
+ public function getTotalStoresByLayoutId($layout_id) {
+ $query = $this->db->query("SELECT COUNT(*) AS total FROM " . DB_PREFIX . "setting WHERE `key` = 'config_layout_id' AND `value` = '" . (int)$layout_id . "' AND store_id != '0'");
+
+ return $query->row['total'];
+ }
+
+ public function getTotalStoresByLanguage($language) {
+ $query = $this->db->query("SELECT COUNT(*) AS total FROM " . DB_PREFIX . "setting WHERE `key` = 'config_language' AND `value` = '" . $this->db->escape($language) . "' AND store_id != '0'");
+
+ return $query->row['total'];
+ }
+
+ public function getTotalStoresByCurrency($currency) {
+ $query = $this->db->query("SELECT COUNT(*) AS total FROM " . DB_PREFIX . "setting WHERE `key` = 'config_currency' AND `value` = '" . $this->db->escape($currency) . "' AND store_id != '0'");
+
+ return $query->row['total'];
+ }
+
+ public function getTotalStoresByCountryId($country_id) {
+ $query = $this->db->query("SELECT COUNT(*) AS total FROM " . DB_PREFIX . "setting WHERE `key` = 'config_country_id' AND `value` = '" . (int)$country_id . "' AND store_id != '0'");
+
+ return $query->row['total'];
+ }
+
+ public function getTotalStoresByZoneId($zone_id) {
+ $query = $this->db->query("SELECT COUNT(*) AS total FROM " . DB_PREFIX . "setting WHERE `key` = 'config_zone_id' AND `value` = '" . (int)$zone_id . "' AND store_id != '0'");
+
+ return $query->row['total'];
+ }
+
+ public function getTotalStoresByCustomerGroupId($customer_group_id) {
+ $query = $this->db->query("SELECT COUNT(*) AS total FROM " . DB_PREFIX . "setting WHERE `key` = 'config_customer_group_id' AND `value` = '" . (int)$customer_group_id . "' AND store_id != '0'");
+
+ return $query->row['total'];
+ }
+
+ public function getTotalStoresByInformationId($information_id) {
+ $account_query = $this->db->query("SELECT COUNT(*) AS total FROM " . DB_PREFIX . "setting WHERE `key` = 'config_account_id' AND `value` = '" . (int)$information_id . "' AND store_id != '0'");
+
+ $checkout_query = $this->db->query("SELECT COUNT(*) AS total FROM " . DB_PREFIX . "setting WHERE `key` = 'config_checkout_id' AND `value` = '" . (int)$information_id . "' AND store_id != '0'");
+
+ return ($account_query->row['total'] + $checkout_query->row['total']);
+ }
+
+ public function getTotalStoresByOrderStatusId($order_status_id) {
+ $query = $this->db->query("SELECT COUNT(*) AS total FROM " . DB_PREFIX . "setting WHERE `key` = 'config_order_status_id' AND `value` = '" . (int)$order_status_id . "' AND store_id != '0'");
+
+ return $query->row['total'];
+ }
+} \ No newline at end of file
diff --git a/public/admin/model/tool/backup.php b/public/admin/model/tool/backup.php
new file mode 100644
index 0000000..d8be774
--- /dev/null
+++ b/public/admin/model/tool/backup.php
@@ -0,0 +1,68 @@
+<?php
+class ModelToolBackup extends Model {
+ public function getTables() {
+ $table_data = array();
+
+ $query = $this->db->query("SHOW TABLES FROM `" . DB_DATABASE . "`");
+
+ foreach ($query->rows as $result) {
+ if (utf8_substr($result['Tables_in_' . DB_DATABASE], 0, strlen(DB_PREFIX)) == DB_PREFIX) {
+ if (isset($result['Tables_in_' . DB_DATABASE])) {
+ $table_data[] = $result['Tables_in_' . DB_DATABASE];
+ }
+ }
+ }
+
+ return $table_data;
+ }
+
+ public function backup($tables) {
+ $output = '';
+
+ foreach ($tables as $table) {
+ if (DB_PREFIX) {
+ if (strpos($table, DB_PREFIX) === false) {
+ $status = false;
+ } else {
+ $status = true;
+ }
+ } else {
+ $status = true;
+ }
+
+ if ($status) {
+ $output .= 'TRUNCATE TABLE `' . $table . '`;' . "\n\n";
+
+ $query = $this->db->query("SELECT * FROM `" . $table . "`");
+
+ foreach ($query->rows as $result) {
+ $fields = '';
+
+ foreach (array_keys($result) as $value) {
+ $fields .= '`' . $value . '`, ';
+ }
+
+ $values = '';
+
+ foreach (array_values($result) as $value) {
+ $value = str_replace(array("\x00", "\x0a", "\x0d", "\x1a"), array('\0', '\n', '\r', '\Z'), $value);
+ $value = str_replace(array("\n", "\r", "\t"), array('\n', '\r', '\t'), $value);
+ $value = str_replace('\\', '\\\\', $value);
+ $value = str_replace('\'', '\\\'', $value);
+ $value = str_replace('\\\n', '\n', $value);
+ $value = str_replace('\\\r', '\r', $value);
+ $value = str_replace('\\\t', '\t', $value);
+
+ $values .= '\'' . $value . '\', ';
+ }
+
+ $output .= 'INSERT INTO `' . $table . '` (' . preg_replace('/, $/', '', $fields) . ') VALUES (' . preg_replace('/, $/', '', $values) . ');' . "\n";
+ }
+
+ $output .= "\n\n";
+ }
+ }
+
+ return $output;
+ }
+} \ No newline at end of file
diff --git a/public/admin/model/tool/image.php b/public/admin/model/tool/image.php
new file mode 100644
index 0000000..5a3c536
--- /dev/null
+++ b/public/admin/model/tool/image.php
@@ -0,0 +1,47 @@
+<?php
+class ModelToolImage extends Model {
+ public function resize($filename, $width, $height) {
+ if (!is_file(DIR_IMAGE . $filename) || substr(str_replace('\\', '/', realpath(DIR_IMAGE . $filename)), 0, strlen(DIR_IMAGE)) != str_replace('\\', '/', DIR_IMAGE)) {
+ return;
+ }
+
+ $extension = pathinfo($filename, PATHINFO_EXTENSION);
+
+ $image_old = $filename;
+ $image_new = 'cache/' . utf8_substr($filename, 0, utf8_strrpos($filename, '.')) . '-' . $width . 'x' . $height . '.' . $extension;
+
+ if (!is_file(DIR_IMAGE . $image_new) || (filemtime(DIR_IMAGE . $image_old) > filemtime(DIR_IMAGE . $image_new))) {
+ list($width_orig, $height_orig, $image_type) = getimagesize(DIR_IMAGE . $image_old);
+
+ if (!in_array($image_type, array(IMAGETYPE_PNG, IMAGETYPE_JPEG, IMAGETYPE_GIF))) {
+ return DIR_IMAGE . $image_old;
+ }
+
+ $path = '';
+
+ $directories = explode('/', dirname($image_new));
+
+ foreach ($directories as $directory) {
+ $path = $path . '/' . $directory;
+
+ if (!is_dir(DIR_IMAGE . $path)) {
+ @mkdir(DIR_IMAGE . $path, 0777);
+ }
+ }
+
+ if ($width_orig != $width || $height_orig != $height) {
+ $image = new Image(DIR_IMAGE . $image_old);
+ $image->resize($width, $height);
+ $image->save(DIR_IMAGE . $image_new);
+ } else {
+ copy(DIR_IMAGE . $image_old, DIR_IMAGE . $image_new);
+ }
+ }
+
+ if ($this->request->server['HTTPS']) {
+ return HTTPS_CATALOG . 'image/' . $image_new;
+ } else {
+ return HTTP_CATALOG . 'image/' . $image_new;
+ }
+ }
+}
diff --git a/public/admin/model/tool/upload.php b/public/admin/model/tool/upload.php
new file mode 100644
index 0000000..3e77a9e
--- /dev/null
+++ b/public/admin/model/tool/upload.php
@@ -0,0 +1,108 @@
+<?php
+class ModelToolUpload extends Model {
+ public function addUpload($name, $filename) {
+ $code = sha1(uniqid(mt_rand(), true));
+
+ $this->db->query("INSERT INTO `" . DB_PREFIX . "upload` SET `name` = '" . $this->db->escape($name) . "', `filename` = '" . $this->db->escape($filename) . "', `code` = '" . $this->db->escape($code) . "', `date_added` = NOW()");
+
+ return $code;
+ }
+
+ public function deleteUpload($upload_id) {
+ $this->db->query("DELETE FROM " . DB_PREFIX . "upload WHERE upload_id = '" . (int)$upload_id . "'");
+ }
+
+ public function getUpload($upload_id) {
+ $query = $this->db->query("SELECT * FROM `" . DB_PREFIX . "upload` WHERE upload_id = '" . (int)$upload_id . "'");
+
+ return $query->row;
+ }
+
+ public function getUploadByCode($code) {
+ $query = $this->db->query("SELECT * FROM " . DB_PREFIX . "upload WHERE code = '" . $this->db->escape($code) . "'");
+
+ return $query->row;
+ }
+
+ public function getUploads($data = array()) {
+ $sql = "SELECT * FROM " . DB_PREFIX . "upload";
+
+ $implode = array();
+
+ if (!empty($data['filter_name'])) {
+ $implode[] = "name LIKE '" . $this->db->escape($data['filter_name']) . "%'";
+ }
+
+ if (!empty($data['filter_filename'])) {
+ $implode[] = "filename LIKE '" . $this->db->escape($data['filter_filename']) . "%'";
+ }
+
+ if (!empty($data['filter_date_added'])) {
+ $implode[] = "date_added = '" . $this->db->escape($data['filter_date_added']) . "%'";
+ }
+
+ if ($implode) {
+ $sql .= " WHERE " . implode(" AND ", $implode);
+ }
+
+ $sort_data = array(
+ 'name',
+ 'filename',
+ 'date_added'
+ );
+
+ if (isset($data['sort']) && in_array($data['sort'], $sort_data)) {
+ $sql .= " ORDER BY " . $data['sort'];
+ } else {
+ $sql .= " ORDER BY date_added";
+ }
+
+ 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'];
+ }
+
+ $query = $this->db->query($sql);
+
+ return $query->rows;
+ }
+
+ public function getTotalUploads() {
+ $sql = "SELECT COUNT(*) AS total FROM " . DB_PREFIX . "upload";
+
+ $implode = array();
+
+ if (!empty($data['filter_name'])) {
+ $implode[] = "name LIKE '" . $this->db->escape($data['filter_name']) . "%'";
+ }
+
+ if (!empty($data['filter_filename'])) {
+ $implode[] = "filename LIKE '" . $this->db->escape($data['filter_filename']) . "%'";
+ }
+
+ if (!empty($data['filter_date_added'])) {
+ $implode[] = "date_added = '" . $this->db->escape($data['filter_date_added']) . "'";
+ }
+
+ if ($implode) {
+ $sql .= " WHERE " . implode(" AND ", $implode);
+ }
+
+ $query = $this->db->query($sql);
+
+ return $query->row['total'];
+ }
+} \ No newline at end of file
diff --git a/public/admin/model/user/api.php b/public/admin/model/user/api.php
new file mode 100644
index 0000000..993451f
--- /dev/null
+++ b/public/admin/model/user/api.php
@@ -0,0 +1,123 @@
+<?php
+class ModelUserApi extends Model {
+ public function addApi($data) {
+ $this->db->query("INSERT INTO `" . DB_PREFIX . "api` SET username = '" . $this->db->escape($data['username']) . "', `key` = '" . $this->db->escape($data['key']) . "', status = '" . (int)$data['status'] . "', date_added = NOW(), date_modified = NOW()");
+
+ $api_id = $this->db->getLastId();
+
+ if (isset($data['api_ip'])) {
+ foreach ($data['api_ip'] as $ip) {
+ if ($ip) {
+ $this->db->query("INSERT INTO `" . DB_PREFIX . "api_ip` SET api_id = '" . (int)$api_id . "', ip = '" . $this->db->escape($ip) . "'");
+ }
+ }
+ }
+
+ return $api_id;
+ }
+
+ public function editApi($api_id, $data) {
+ $this->db->query("UPDATE `" . DB_PREFIX . "api` SET username = '" . $this->db->escape($data['username']) . "', `key` = '" . $this->db->escape($data['key']) . "', status = '" . (int)$data['status'] . "', date_modified = NOW() WHERE api_id = '" . (int)$api_id . "'");
+
+ $this->db->query("DELETE FROM " . DB_PREFIX . "api_ip WHERE api_id = '" . (int)$api_id . "'");
+
+ if (isset($data['api_ip'])) {
+ foreach ($data['api_ip'] as $ip) {
+ if ($ip) {
+ $this->db->query("INSERT INTO `" . DB_PREFIX . "api_ip` SET api_id = '" . (int)$api_id . "', ip = '" . $this->db->escape($ip) . "'");
+ }
+ }
+ }
+ }
+
+ public function deleteApi($api_id) {
+ $this->db->query("DELETE FROM `" . DB_PREFIX . "api` WHERE api_id = '" . (int)$api_id . "'");
+ }
+
+ public function getApi($api_id) {
+ $query = $this->db->query("SELECT * FROM `" . DB_PREFIX . "api` WHERE api_id = '" . (int)$api_id . "'");
+
+ return $query->row;
+ }
+
+ public function getApis($data = array()) {
+ $sql = "SELECT * FROM `" . DB_PREFIX . "api`";
+
+ $sort_data = array(
+ 'username',
+ 'status',
+ 'date_added',
+ 'date_modified'
+ );
+
+ if (isset($data['sort']) && in_array($data['sort'], $sort_data)) {
+ $sql .= " ORDER BY " . $data['sort'];
+ } else {
+ $sql .= " ORDER BY username";
+ }
+
+ 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'];
+ }
+
+ $query = $this->db->query($sql);
+
+ return $query->rows;
+ }
+
+ public function getTotalApis() {
+ $query = $this->db->query("SELECT COUNT(*) AS total FROM `" . DB_PREFIX . "api`");
+
+ return $query->row['total'];
+ }
+
+ public function addApiIp($api_id, $ip) {
+ $this->db->query("INSERT INTO `" . DB_PREFIX . "api_ip` SET api_id = '" . (int)$api_id . "', ip = '" . $this->db->escape($ip) . "'");
+ }
+
+ public function getApiIps($api_id) {
+ $query = $this->db->query("SELECT * FROM `" . DB_PREFIX . "api_ip` WHERE api_id = '" . (int)$api_id . "'");
+
+ return $query->rows;
+ }
+
+ public function addApiSession($api_id, $session_id, $ip) {
+ $api_ip_query = $this->db->query("SELECT * FROM `" . DB_PREFIX . "api_ip` WHERE ip = '" . $this->db->escape($ip) . "'");
+
+ if (!$api_ip_query->num_rows) {
+ $this->db->query("INSERT INTO `" . DB_PREFIX . "api_ip` SET api_id = '" . (int)$api_id . "', ip = '" . $this->db->escape($ip) . "'");
+ }
+
+ $this->db->query("INSERT INTO `" . DB_PREFIX . "api_session` SET api_id = '" . (int)$api_id . "', session_id = '" . $this->db->escape($session_id) . "', ip = '" . $this->db->escape($ip) . "', date_added = NOW(), date_modified = NOW()");
+
+ return $this->db->getLastId();
+ }
+
+ public function getApiSessions($api_id) {
+ $query = $this->db->query("SELECT * FROM `" . DB_PREFIX . "api_session` WHERE api_id = '" . (int)$api_id . "'");
+
+ return $query->rows;
+ }
+
+ public function deleteApiSession($api_session_id) {
+ $this->db->query("DELETE FROM `" . DB_PREFIX . "api_session` WHERE api_session_id = '" . (int)$api_session_id . "'");
+ }
+
+ public function deleteApiSessionBySessonId($session_id) {
+ $this->db->query("DELETE FROM `" . DB_PREFIX . "api_session` WHERE session_id = '" . $this->db->escape($session_id) . "'");
+ }
+}
diff --git a/public/admin/model/user/user.php b/public/admin/model/user/user.php
new file mode 100644
index 0000000..ccaa4c0
--- /dev/null
+++ b/public/admin/model/user/user.php
@@ -0,0 +1,108 @@
+<?php
+class ModelUserUser extends Model {
+ public function addUser($data) {
+ $this->db->query("INSERT INTO `" . DB_PREFIX . "user` SET username = '" . $this->db->escape($data['username']) . "', user_group_id = '" . (int)$data['user_group_id'] . "', salt = '" . $this->db->escape($salt = token(9)) . "', password = '" . $this->db->escape(sha1($salt . sha1($salt . sha1($data['password'])))) . "', firstname = '" . $this->db->escape($data['firstname']) . "', lastname = '" . $this->db->escape($data['lastname']) . "', email = '" . $this->db->escape($data['email']) . "', image = '" . $this->db->escape($data['image']) . "', status = '" . (int)$data['status'] . "', date_added = NOW()");
+
+ return $this->db->getLastId();
+ }
+
+ public function editUser($user_id, $data) {
+ $this->db->query("UPDATE `" . DB_PREFIX . "user` SET username = '" . $this->db->escape($data['username']) . "', user_group_id = '" . (int)$data['user_group_id'] . "', firstname = '" . $this->db->escape($data['firstname']) . "', lastname = '" . $this->db->escape($data['lastname']) . "', email = '" . $this->db->escape($data['email']) . "', image = '" . $this->db->escape($data['image']) . "', status = '" . (int)$data['status'] . "' WHERE user_id = '" . (int)$user_id . "'");
+
+ if ($data['password']) {
+ $this->db->query("UPDATE `" . DB_PREFIX . "user` SET salt = '" . $this->db->escape($salt = token(9)) . "', password = '" . $this->db->escape(sha1($salt . sha1($salt . sha1($data['password'])))) . "' WHERE user_id = '" . (int)$user_id . "'");
+ }
+ }
+
+ public function editPassword($user_id, $password) {
+ $this->db->query("UPDATE `" . DB_PREFIX . "user` SET salt = '" . $this->db->escape($salt = token(9)) . "', password = '" . $this->db->escape(sha1($salt . sha1($salt . sha1($password)))) . "', code = '' WHERE user_id = '" . (int)$user_id . "'");
+ }
+
+ public function editCode($email, $code) {
+ $this->db->query("UPDATE `" . DB_PREFIX . "user` SET code = '" . $this->db->escape($code) . "' WHERE LCASE(email) = '" . $this->db->escape(utf8_strtolower($email)) . "'");
+ }
+
+ public function deleteUser($user_id) {
+ $this->db->query("DELETE FROM `" . DB_PREFIX . "user` WHERE user_id = '" . (int)$user_id . "'");
+ }
+
+ public function getUser($user_id) {
+ $query = $this->db->query("SELECT *, (SELECT ug.name FROM `" . DB_PREFIX . "user_group` ug WHERE ug.user_group_id = u.user_group_id) AS user_group FROM `" . DB_PREFIX . "user` u WHERE u.user_id = '" . (int)$user_id . "'");
+
+ return $query->row;
+ }
+
+ public function getUserByUsername($username) {
+ $query = $this->db->query("SELECT * FROM `" . DB_PREFIX . "user` WHERE username = '" . $this->db->escape($username) . "'");
+
+ return $query->row;
+ }
+
+ public function getUserByEmail($email) {
+ $query = $this->db->query("SELECT DISTINCT * FROM `" . DB_PREFIX . "user` WHERE LCASE(email) = '" . $this->db->escape(utf8_strtolower($email)) . "'");
+
+ return $query->row;
+ }
+
+ public function getUserByCode($code) {
+ $query = $this->db->query("SELECT * FROM `" . DB_PREFIX . "user` WHERE code = '" . $this->db->escape($code) . "' AND code != ''");
+
+ return $query->row;
+ }
+
+ public function getUsers($data = array()) {
+ $sql = "SELECT * FROM `" . DB_PREFIX . "user`";
+
+ $sort_data = array(
+ 'username',
+ 'status',
+ 'date_added'
+ );
+
+ if (isset($data['sort']) && in_array($data['sort'], $sort_data)) {
+ $sql .= " ORDER BY " . $data['sort'];
+ } else {
+ $sql .= " ORDER BY username";
+ }
+
+ 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'];
+ }
+
+ $query = $this->db->query($sql);
+
+ return $query->rows;
+ }
+
+ public function getTotalUsers() {
+ $query = $this->db->query("SELECT COUNT(*) AS total FROM `" . DB_PREFIX . "user`");
+
+ return $query->row['total'];
+ }
+
+ public function getTotalUsersByGroupId($user_group_id) {
+ $query = $this->db->query("SELECT COUNT(*) AS total FROM `" . DB_PREFIX . "user` WHERE user_group_id = '" . (int)$user_group_id . "'");
+
+ return $query->row['total'];
+ }
+
+ public function getTotalUsersByEmail($email) {
+ $query = $this->db->query("SELECT COUNT(*) AS total FROM `" . DB_PREFIX . "user` WHERE LCASE(email) = '" . $this->db->escape(utf8_strtolower($email)) . "'");
+
+ return $query->row['total'];
+ }
+} \ No newline at end of file
diff --git a/public/admin/model/user/user_group.php b/public/admin/model/user/user_group.php
new file mode 100644
index 0000000..acf2776
--- /dev/null
+++ b/public/admin/model/user/user_group.php
@@ -0,0 +1,85 @@
+<?php
+class ModelUserUserGroup extends Model {
+ public function addUserGroup($data) {
+ $this->db->query("INSERT INTO " . DB_PREFIX . "user_group SET name = '" . $this->db->escape($data['name']) . "', permission = '" . (isset($data['permission']) ? $this->db->escape(json_encode($data['permission'])) : '') . "'");
+
+ return $this->db->getLastId();
+ }
+
+ public function editUserGroup($user_group_id, $data) {
+ $this->db->query("UPDATE " . DB_PREFIX . "user_group SET name = '" . $this->db->escape($data['name']) . "', permission = '" . (isset($data['permission']) ? $this->db->escape(json_encode($data['permission'])) : '') . "' WHERE user_group_id = '" . (int)$user_group_id . "'");
+ }
+
+ public function deleteUserGroup($user_group_id) {
+ $this->db->query("DELETE FROM " . DB_PREFIX . "user_group WHERE user_group_id = '" . (int)$user_group_id . "'");
+ }
+
+ public function getUserGroup($user_group_id) {
+ $query = $this->db->query("SELECT DISTINCT * FROM " . DB_PREFIX . "user_group WHERE user_group_id = '" . (int)$user_group_id . "'");
+
+ $user_group = array(
+ 'name' => $query->row['name'],
+ 'permission' => json_decode($query->row['permission'], true)
+ );
+
+ return $user_group;
+ }
+
+ public function getUserGroups($data = array()) {
+ $sql = "SELECT * FROM " . DB_PREFIX . "user_group";
+
+ $sql .= " ORDER BY name";
+
+ 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'];
+ }
+
+ $query = $this->db->query($sql);
+
+ return $query->rows;
+ }
+
+ public function getTotalUserGroups() {
+ $query = $this->db->query("SELECT COUNT(*) AS total FROM " . DB_PREFIX . "user_group");
+
+ return $query->row['total'];
+ }
+
+ public function addPermission($user_group_id, $type, $route) {
+ $user_group_query = $this->db->query("SELECT DISTINCT * FROM " . DB_PREFIX . "user_group WHERE user_group_id = '" . (int)$user_group_id . "'");
+
+ if ($user_group_query->num_rows) {
+ $data = json_decode($user_group_query->row['permission'], true);
+
+ $data[$type][] = $route;
+
+ $this->db->query("UPDATE " . DB_PREFIX . "user_group SET permission = '" . $this->db->escape(json_encode($data)) . "' WHERE user_group_id = '" . (int)$user_group_id . "'");
+ }
+ }
+
+ public function removePermission($user_group_id, $type, $route) {
+ $user_group_query = $this->db->query("SELECT DISTINCT * FROM " . DB_PREFIX . "user_group WHERE user_group_id = '" . (int)$user_group_id . "'");
+
+ if ($user_group_query->num_rows) {
+ $data = json_decode($user_group_query->row['permission'], true);
+
+ $data[$type] = array_diff($data[$type], array($route));
+
+ $this->db->query("UPDATE " . DB_PREFIX . "user_group SET permission = '" . $this->db->escape(json_encode($data)) . "' WHERE user_group_id = '" . (int)$user_group_id . "'");
+ }
+ }
+} \ No newline at end of file