558 lines
19 KiB
PHP
558 lines
19 KiB
PHP
<?php
|
|
|
|
namespace Hura8\Components\Order\Model;
|
|
|
|
|
|
use Hura8\Components\Order\Controller\OrderStatus;
|
|
use Hura8\Interfaces\AppResponse;
|
|
use Hura8\Interfaces\iEntityModel;
|
|
use Hura8\Interfaces\iSearch;
|
|
use Hura8\Interfaces\EntityType;
|
|
use Hura8\System\Model\aEntityBaseModel;
|
|
use Hura8\System\Security\DataClean;
|
|
use Hura8\System\Security\DataType;
|
|
use Hura8\System\TimeManager;
|
|
use Hura8\System\Url;
|
|
|
|
class OrderModel extends aEntityBaseModel implements iEntityModel
|
|
{
|
|
|
|
protected $tb_order_detail = "tb_order_detail";
|
|
|
|
/* @var iSearch $objSearchModel */
|
|
protected $objSearchModel;
|
|
|
|
public function __construct() {
|
|
|
|
$this->objSearchModel = new OrderSearchModel();
|
|
|
|
parent::__construct(EntityType::ORDER, '', $this->objSearchModel);
|
|
}
|
|
|
|
|
|
protected function extendedFilterOptions() : array
|
|
{
|
|
return [
|
|
// empty for now
|
|
];
|
|
}
|
|
|
|
|
|
public function getItems($orderId, $fields = "*") {
|
|
$query = $this->db->runQuery(
|
|
" SELECT ".$fields." FROM `".$this->tb_order_detail."` WHERE `order_id` = ? ",
|
|
['d'], [ $orderId ]);
|
|
|
|
$order_item = array();
|
|
foreach ( $this->db->fetchAll($query) as $info ) {
|
|
|
|
$item_info = ($info["item_info"]) ? \json_decode($info["item_info"], true) : false;
|
|
$in_cart = ($info["in_cart"]) ? \json_decode($info["in_cart"], true) : false;
|
|
|
|
|
|
$info['item_info'] = $item_info;
|
|
$info['in_cart'] = $in_cart;
|
|
|
|
$order_item[] = $info;
|
|
}
|
|
|
|
return $order_item;
|
|
}
|
|
|
|
//since we save the entire cart-structure for item_info, we need to re-construct it to make it easier to read and for various reporting/ email etc..
|
|
protected function buildOrderItemInfo($item_type, array $item_info) {
|
|
$new_info = [];
|
|
|
|
if($item_type == 'product') {
|
|
|
|
$new_info = System::stripProperty(array($item_info['info']), [
|
|
"variant_option",
|
|
'id',
|
|
'productId',
|
|
'priceUnit',
|
|
'price',
|
|
'currency',
|
|
'lastUpdate',
|
|
'warranty',
|
|
'productName',
|
|
'productUrl',
|
|
'productModel',
|
|
'productSummary',
|
|
'marketPrice',
|
|
'productImage',
|
|
'brand',
|
|
'visit',
|
|
'rating',
|
|
'reviewCount',
|
|
'quantity',
|
|
'productSKU',
|
|
'hasVAT',
|
|
'condition',
|
|
'specialOffer',
|
|
'specialOfferGroup',
|
|
'productType',
|
|
'thum_poster',
|
|
'promotion_price',
|
|
'addon'
|
|
])[0];
|
|
|
|
//find variants bought
|
|
if($new_info['config_count'] > 0) {
|
|
|
|
foreach ($item_info['in_cart'] as $_variant) {
|
|
$new_info['variants'][] = array(
|
|
"id" => $_variant['id'],
|
|
"sku" => $_variant['sku'],
|
|
"title" => $_variant['name'],
|
|
"image" => ($_variant['image']) ? $_variant['image'] : $item_info['info']['productImage']["medium"],
|
|
"url" => $item_info['info']['productUrl'],
|
|
"attribute" => $_variant['attribute'],
|
|
"price" => $_variant['price'],
|
|
"addon_total" => 0,
|
|
"currency" => $item_info['info']['currency'],
|
|
"priceUnit" => $item_info['info']['priceUnit'],
|
|
"quantity" => $_variant['quantity'],
|
|
"buyer_note" => $_variant['buyer_note'],
|
|
"addon" => [],
|
|
"promotion" => [
|
|
"list" => $item_info['info']['specialOffer'],
|
|
"group" => (isset($_variant['promotion'])) ? $this->buildPromotionFromGroup( $item_info['info']['specialOfferGroup'], $_variant['promotion']) : $this->buildPromotionFromGroup( $item_info['info']['specialOfferGroup'], array() ),
|
|
],
|
|
//..any other
|
|
);
|
|
}
|
|
|
|
}else{
|
|
|
|
//product does not have variant
|
|
$build_addon = [];
|
|
$total_addon_price = 0;
|
|
if(isset($item_info['info']['addon']) && isset($item_info['in_cart'][0]['addon'])) {
|
|
$build_addon = $this->getSelectedAddon($item_info['info']['addon'], $item_info['in_cart'][0]['addon']);
|
|
foreach ($build_addon as $addon) {
|
|
$total_addon_price += $addon['price'] * $addon['quantity'];
|
|
}
|
|
}
|
|
|
|
$variant_in_cart = (isset($item_info['in_cart'][0])) ? $item_info['in_cart'][0] : false;
|
|
|
|
$new_info['variants'][] = array(
|
|
"id" => 0,
|
|
"sku" => $item_info['info']['productSKU'],
|
|
"title" => $item_info['info']['productName'],
|
|
"image" => $item_info['info']['productImage']["medium"],
|
|
"url" => $item_info['info']['productUrl'],
|
|
"attribute" => [],
|
|
"price" => $item_info['info']['price'],
|
|
"addon_total" => $total_addon_price,
|
|
"currency" => $item_info['info']['currency'],
|
|
"priceUnit" => $item_info['info']['priceUnit'],
|
|
"quantity" => $variant_in_cart['quantity'],
|
|
"buyer_note" => $variant_in_cart['buyer_note'],
|
|
"addon" => $build_addon,
|
|
"promotion" => [
|
|
"list" => $item_info['info']['specialOffer'],
|
|
"group" => (isset($variant_in_cart['promotion'])) ? $this->buildPromotionFromGroup( $item_info['info']['specialOfferGroup'], $variant_in_cart['promotion']) : $this->buildPromotionFromGroup( $item_info['info']['specialOfferGroup'], array() ),
|
|
],
|
|
//..any other
|
|
);
|
|
}
|
|
|
|
//
|
|
return $new_info;
|
|
}
|
|
|
|
if($item_type == 'combo') {
|
|
|
|
$new_info = [
|
|
"price" => $item_info['info']['sale_price'],
|
|
"quantity" => $item_info['in_cart']['quantity'],
|
|
"buyer_note" => $item_info['in_cart']['buyer_note'],
|
|
"url" => '',
|
|
];
|
|
|
|
$new_info['product_list'] = System::stripProperty($item_info['info']['product_list'], [
|
|
"variant_option",
|
|
'id',
|
|
'productId',
|
|
'priceUnit',
|
|
'price',
|
|
'currency',
|
|
'lastUpdate',
|
|
'warranty',
|
|
//'productName',
|
|
//'productUrl',
|
|
//'productModel',
|
|
'productSummary',
|
|
'marketPrice',
|
|
'productImage',
|
|
'brand',
|
|
'visit',
|
|
'rating',
|
|
'reviewCount',
|
|
'config_count',
|
|
'quantity',
|
|
//'productSKU',
|
|
'hasVAT',
|
|
'condition',
|
|
'specialOffer',
|
|
'specialOfferGroup',
|
|
'productType',
|
|
'thum_poster',
|
|
'promotion_price',
|
|
'addon',
|
|
'imageCollection',
|
|
'variants'
|
|
]);
|
|
|
|
return $new_info;
|
|
}
|
|
|
|
if($item_type == 'deal') {
|
|
|
|
$new_info = [
|
|
"price" => $item_info['info']['price'],
|
|
"quantity" => $item_info['in_cart']['quantity'],
|
|
"buyer_note" => $item_info['in_cart']['buyer_note'],
|
|
"url" => '/deal/'.$item_info['info']['id'],
|
|
];
|
|
|
|
return $new_info;
|
|
}
|
|
|
|
return $new_info;
|
|
}
|
|
|
|
protected function getSelectedAddon($all_product_addons, $in_cart) {
|
|
|
|
if(!is_array($all_product_addons) || !is_array($in_cart)) return [];
|
|
|
|
$result = [];
|
|
foreach ($all_product_addons as $item) {
|
|
foreach ($in_cart as $selected) {
|
|
if($item['addon_id'] == $selected['id']) {
|
|
$result[] = [
|
|
"id" => $selected['id'],
|
|
"title" => $item['title'],
|
|
"price" => $item['price'],
|
|
"quantity" => (isset($selected['quantity'])) ? intval($selected['quantity']) : 1,
|
|
"related_article_url" => $item['related_article_url'],
|
|
];
|
|
}
|
|
}
|
|
}
|
|
|
|
return $result;
|
|
}
|
|
|
|
protected function buildPromotionFromGroup( $offer_group, $selected_one_promotion) {
|
|
|
|
if(!is_array($offer_group) && !is_array($selected_one_promotion)) return false;
|
|
|
|
$promotion = [];
|
|
|
|
foreach ($offer_group as $group) {
|
|
if($group['type'] == 'one') {
|
|
|
|
$selected_promotion = [];
|
|
foreach ($group['promotion'] as $promo) {
|
|
foreach ($selected_one_promotion as $selected) {
|
|
if($selected['promotion_id'] == $promo['id'] && $selected['group_id'] == $group['id']) {
|
|
$selected_promotion[] = $promo;
|
|
}
|
|
}
|
|
}
|
|
|
|
$promotion[] = [
|
|
"id" => $group['id'],
|
|
"title" => $group['title'],
|
|
"note" => $group['note'],
|
|
"promotion" => $selected_promotion,
|
|
];
|
|
|
|
|
|
}else{
|
|
$promotion[] = [
|
|
"id" => $group['id'],
|
|
"title" => $group['title'],
|
|
"note" => $group['note'],
|
|
"promotion" => $group['promotion'],
|
|
];
|
|
}
|
|
}
|
|
|
|
return $promotion;
|
|
|
|
}
|
|
|
|
|
|
protected function getListFilterCondition($list_id) {
|
|
|
|
if($list_id == 'mine') {
|
|
return [
|
|
'assign_to' => ADMIN_ID,
|
|
];
|
|
}
|
|
|
|
if($list_id == 'new') {
|
|
return [
|
|
'status' => 'new',
|
|
];
|
|
}
|
|
|
|
if($list_id == 'unpaid') {
|
|
return [
|
|
'payment' => 'unpaid',
|
|
];
|
|
}
|
|
|
|
if($list_id == 'partially-paid') {
|
|
return [
|
|
'payment' => 'partially-paid',
|
|
];
|
|
}
|
|
|
|
if($list_id == 'unfulfilled') {
|
|
return [
|
|
'fullfillment' => 'unfulfilled',
|
|
];
|
|
}
|
|
|
|
if($list_id == 'partially-fulfilled') {
|
|
return [
|
|
'fullfillment' => 'partially-fulfilled',
|
|
];
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
public function getStatusHistory($orderId){
|
|
$query = $this->db->runQuery("
|
|
select * from ".TB_ORDER_STATUS_HISTORY."
|
|
WHERE order_id = ?
|
|
order by id desc
|
|
limit 100
|
|
", ['d'], [ $orderId ] ) ;
|
|
|
|
return $this->db->fetchAll($query);
|
|
}
|
|
|
|
public function getItemsForOrderList(array $list_ids, $fields = "*") {
|
|
|
|
if(!sizeof($list_ids)) return [];
|
|
|
|
list($parameterized_ids, $bind_types) = create_bind_sql_parameter_from_value_list($list_ids, 'int');
|
|
|
|
$query = $this->db->runQuery("
|
|
SELECT ".$fields." FROM `".$this->tb_order_detail."`
|
|
WHERE `order_id` IN (".$parameterized_ids.")
|
|
", $bind_types, $list_ids);
|
|
|
|
$result = array();
|
|
foreach ( $this->db->fetchAll($query) as $rs ) {
|
|
|
|
$item_info = unserialize($rs['item_info']);
|
|
if( isset($item_info["info"]) && isset($item_info["in_cart"])) {
|
|
$rs['item_info'] = $this->buildOrderItemInfo($rs['item_type'], $item_info );
|
|
} else {
|
|
$rs['item_info'] = null;
|
|
}
|
|
|
|
$result[$rs['order_id']][] = $rs;
|
|
}
|
|
|
|
return $result;
|
|
}
|
|
|
|
protected function _buildQueryConditionExtend(array $conditions) : ?array
|
|
{
|
|
$catCondition = [];
|
|
$bind_types = [];
|
|
$bind_values = [];
|
|
|
|
/*
|
|
$conditions = array(
|
|
'orderCode' => '',
|
|
'query' => '',
|
|
'coupon' => '',
|
|
'cus_id' => '',
|
|
'province' => '',
|
|
'district' => '',
|
|
'folder' => '',
|
|
'view_status' => '',
|
|
'update_by' => '',
|
|
'shipping_status' => '',
|
|
'assign_to' => '',
|
|
'from_date' => '',
|
|
'to_date' => '',
|
|
'from_hour' => '',
|
|
'to_hour' => '',
|
|
'excluded_ids' => '',
|
|
'included_ids' => '',
|
|
'payment' => '',
|
|
'fullfillment' => '',
|
|
'list' => '',
|
|
);*/
|
|
|
|
|
|
// merge with special list
|
|
if(isset($conditions['list']) && $conditions['list']) {
|
|
$list_condition = $this->getListFilterCondition($conditions['list']);
|
|
if($list_condition) {
|
|
// update and over-write any key in $conditions if exist
|
|
foreach ($list_condition as $key => $value) {
|
|
$conditions[$key] = $value;
|
|
}
|
|
}
|
|
}
|
|
|
|
if(isset($conditions['orderCode']) && $conditions['orderCode']) {
|
|
$orderCode = DataClean::makeInputSafe($conditions['orderCode'],DataType::INTEGER);
|
|
$catCondition[] = " AND `orderId` LIKE '".$orderCode."%' ";
|
|
}
|
|
|
|
if(isset($conditions['coupon']) && $conditions['coupon']) {
|
|
$coupon = preg_replace("/[^a-z0-9_\-\.]/i","", $conditions['coupon']);
|
|
if($coupon) $catCondition[] = " AND ( LENGTH(`order_discount`) > 10 AND `order_discount` LIKE '%".$coupon."%' ) ";
|
|
}
|
|
|
|
if(isset($conditions['cus_id']) && $conditions['cus_id']) {
|
|
$catCondition[] = " AND buyerId = '".intval($conditions['cus_id'])."'";
|
|
}
|
|
|
|
if(isset($conditions['province']) && $conditions['province']) {
|
|
$catCondition[] = " AND province = '".intval($conditions['province'])."'";
|
|
}
|
|
|
|
if(isset($conditions['district']) && $conditions['district']) {
|
|
$catCondition[] = " AND district = '".intval($conditions['district'])."'";
|
|
}
|
|
|
|
if(isset($conditions['folder']) && $conditions['folder']) {
|
|
$catCondition[] = " AND `folder` = '". preg_replace("/[^a-z0-9_\-\.]/i", "", $conditions['folder'])."' ";
|
|
}
|
|
|
|
if(isset($conditions['payment']) && array_key_exists($conditions['payment'], OrderStatus::PAYMENT_STATUS ) ) {
|
|
$catCondition[] = " AND `payment_status` = '". $this->db->escape($conditions['payment'])."' ";
|
|
}
|
|
|
|
if(isset($conditions['fullfillment']) && array_key_exists($conditions['fullfillment'], OrderStatus::FULFILLMENT_STATUS) ) {
|
|
$catCondition[] = " AND `fulfillment_status` = '". $this->db->escape($conditions['fullfillment'])."' ";
|
|
}
|
|
|
|
if(isset($conditions['status']) && array_key_exists($conditions['status'], OrderStatus::ORDER_STATUS) ) {
|
|
$catCondition[] = " AND `order_status` = '". $this->db->escape($conditions['status'])."' ";
|
|
}
|
|
|
|
if(isset($conditions['view_status']) && $conditions['view_status']) {
|
|
if($conditions['view_status'] == 'no-status') {
|
|
$catCondition[] = " AND `status_id` = 0 ";
|
|
} else {
|
|
$catCondition[] = " AND `status_id` = '". intval($conditions['view_status'])."' ";
|
|
}
|
|
}
|
|
|
|
if(isset($conditions['update_by']) && $conditions['update_by']) {
|
|
$catCondition[] = " AND `status_update_by` = '". $this->db->escape($conditions['update_by'])."' ";
|
|
}
|
|
|
|
if(isset($conditions['shipping_status']) && $conditions['shipping_status']) {
|
|
$catCondition[] = " AND `admin_shipping_status` = '". preg_replace("/[^a-z0-9_\-\.]/i", "", $conditions['shipping_status'])."' ";
|
|
}
|
|
|
|
if(isset($conditions['assign_to']) && $conditions['assign_to']) {
|
|
$catCondition[] = " AND `assign_to` = '". intval($conditions['assign_to'])."' ";
|
|
}
|
|
|
|
//filter by date
|
|
if(isset($conditions['from_date']) && $conditions['from_date']) {
|
|
$catCondition[] = " AND order_time >= '". intval(strtotime(TimeManager::convert_date_from_javascript($conditions['from_date'])." 00:00"))."' ";
|
|
}
|
|
|
|
if(isset($conditions['to_date']) && $conditions['to_date']) {
|
|
$catCondition[] = " AND order_time <= '".strtotime(TimeManager::convert_date_from_javascript($conditions['to_date'])." 23:59")."' ";
|
|
}
|
|
|
|
//filter by hour
|
|
if(isset($conditions['from_hour']) && $conditions['from_hour']) {
|
|
$catCondition[] = " AND `order_hour` >= '".intval($conditions['from_hour'])."' ";
|
|
}
|
|
if(isset($conditions['to_hour']) && $conditions['to_hour']) {
|
|
$catCondition[] = " AND `order_hour` <= '".intval($conditions['to_hour'])."' ";
|
|
}
|
|
|
|
if(isset($conditions["excluded_ids"]) && $conditions["excluded_ids"] ){
|
|
$list_ids = filterNumber(explode(",", $conditions["excluded_ids"]));
|
|
if(sizeof($list_ids)) $catCondition[] = " AND `orderId` NOT IN (".join(',', $list_ids ).") ";
|
|
}
|
|
|
|
if(isset($conditions["included_ids"]) && $conditions["included_ids"] ){
|
|
$list_ids = filterNumber(explode(",", $conditions["included_ids"]));
|
|
if(sizeof($list_ids)) $catCondition[] = " AND `orderId` IN (".join(',', $list_ids ).") ";
|
|
}
|
|
|
|
|
|
return array( join(" ", $catCondition), $bind_types, $bind_values);
|
|
}
|
|
|
|
|
|
protected function beforeCreateItem(array $input_info) : AppResponse
|
|
{
|
|
$info = $input_info;
|
|
|
|
if(isset($info['file_external_url'])) {
|
|
if($info['file_external_url'] && !Url::isUrlValid($info['file_external_url'])) {
|
|
$info['file_external_url'] = '';
|
|
}
|
|
}
|
|
|
|
|
|
$info['create_time'] = CURRENT_TIME;
|
|
$info['create_by'] = ADMIN_NAME;
|
|
$info['last_update'] = CURRENT_TIME;
|
|
$info['last_update_by'] = ADMIN_NAME;
|
|
|
|
return new AppResponse('ok', null, $info);
|
|
}
|
|
|
|
|
|
protected function beforeUpdateItem($item_id, $current_item_info, $new_input_info) : AppResponse
|
|
{
|
|
$info = $new_input_info;
|
|
|
|
unset($info['id']);
|
|
|
|
if(isset($info['file_external_url']) && $info['file_external_url'] && !Url::isUrlValid($info['file_external_url'])) {
|
|
$info['file_external_url'] = '';
|
|
}
|
|
|
|
$info['last_update'] = CURRENT_TIME;
|
|
$info['last_update_by'] = ADMIN_NAME;
|
|
|
|
return new AppResponse('ok', null, $info);
|
|
}
|
|
|
|
protected function beforeDeleteItem($item_id, $item_info) : AppResponse
|
|
{
|
|
return new AppResponse('ok');
|
|
}
|
|
|
|
protected function afterDeleteItem($item_id, $item_info)
|
|
{
|
|
|
|
}
|
|
|
|
|
|
protected function afterCreateItem($new_item_id, $new_item_info)
|
|
{
|
|
|
|
}
|
|
|
|
protected function afterUpdateItem($item_id, $old_item_info, $new_item_info)
|
|
{
|
|
|
|
}
|
|
|
|
}
|