269 lines
9.4 KiB
PHP
269 lines
9.4 KiB
PHP
|
|
<?php
|
||
|
|
|
||
|
|
namespace Hura8\Components\Customer\Model;
|
||
|
|
|
||
|
|
use ClientExtend\UserLoyaltyPointCalculation;
|
||
|
|
use Hura8\Database\iConnectDB;
|
||
|
|
use Hura8\Interfaces\TableName;
|
||
|
|
|
||
|
|
class CustomerLoyaltyModel
|
||
|
|
{
|
||
|
|
|
||
|
|
/* @var iConnectDB $db */
|
||
|
|
protected $db;
|
||
|
|
|
||
|
|
protected $tb_point = TableName::CUSTOMER_POINT; // "idv_customer_point";
|
||
|
|
protected $tb_customer = TableName::CUSTOMER; // "idv_customer";
|
||
|
|
|
||
|
|
public static $POINT_NAME = 'điểm';
|
||
|
|
|
||
|
|
protected $point_setting = [];
|
||
|
|
protected $point_setting_config_file = ROOT_DIR . "/config/build/customer_point.php";
|
||
|
|
|
||
|
|
protected $level_setting = [];
|
||
|
|
protected $level_setting_config_file = ROOT_DIR . "/config/client/customer_level.php";
|
||
|
|
|
||
|
|
protected $level_by = '';// point|total_purchase_value as set by constant CHANGE_CUSTOMER_LEVEL_BY
|
||
|
|
|
||
|
|
/* @var $objUserLoyaltyPointCalculation UserLoyaltyPointCalculation */
|
||
|
|
protected $objUserLoyaltyPointCalculation;
|
||
|
|
|
||
|
|
|
||
|
|
public function __construct()
|
||
|
|
{
|
||
|
|
$this->db = get_db("", ENABLE_DB_DEBUG);
|
||
|
|
|
||
|
|
// import settings
|
||
|
|
//$new_info_file = "../config/build/customer_point.php" ;
|
||
|
|
//$config_file = ROOT_DIR . "/config/build/customer_point.php";
|
||
|
|
if(@file_exists($this->point_setting_config_file)) {
|
||
|
|
$this->point_setting = include $this->point_setting_config_file;
|
||
|
|
}
|
||
|
|
|
||
|
|
// customer level based on point gain
|
||
|
|
if( defined("ENABLE_CUSTOMER_POINT") && ENABLE_CUSTOMER_POINT ) {
|
||
|
|
if(@file_exists($this->level_setting_config_file)) {
|
||
|
|
$this->level_setting = include $this->level_setting_config_file;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// default is point
|
||
|
|
$this->level_by = (defined('CHANGE_CUSTOMER_LEVEL_BY')) ? CHANGE_CUSTOMER_LEVEL_BY : 'point';
|
||
|
|
|
||
|
|
$this->objUserLoyaltyPointCalculation = new UserLoyaltyPointCalculation($this->point_setting);
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
public function getPointSettingConfigFile() {
|
||
|
|
return $this->point_setting_config_file;
|
||
|
|
}
|
||
|
|
|
||
|
|
public function getPointSetting() {
|
||
|
|
return $this->point_setting;
|
||
|
|
}
|
||
|
|
|
||
|
|
public function getLevelSetting(){
|
||
|
|
return $this->level_setting;
|
||
|
|
}
|
||
|
|
|
||
|
|
// show estimate cart point
|
||
|
|
public function getEstimateCartPoint($cart_value){
|
||
|
|
$conversion_rate = (isset($this->point_setting['reward']['buy']['rate'])) ? $this->point_setting['reward']['buy']['rate'] : 0;
|
||
|
|
return ($conversion_rate) ? round($cart_value / $conversion_rate) : 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
public function getUserPoint($user_id, array $condition, $return_type)
|
||
|
|
{
|
||
|
|
|
||
|
|
if($return_type == "total") {
|
||
|
|
//Lay tong so
|
||
|
|
$query = $this->db->runQuery("SELECT COUNT(*) AS total FROM `". $this->tb_point ."` WHERE `customer_id` = ? " , ['d'], [$user_id]);
|
||
|
|
if($resultTotal = $this->db->fetchAssoc($query)){
|
||
|
|
return $resultTotal['total'];
|
||
|
|
}
|
||
|
|
return 0;
|
||
|
|
|
||
|
|
} else {
|
||
|
|
|
||
|
|
$numPerPage = (isset($condition['numPerPage'])) ? intval($condition['numPerPage']) : 50;
|
||
|
|
$page = getPageId();
|
||
|
|
|
||
|
|
$query = $this->db->runQuery("
|
||
|
|
SELECT * FROM `". $this->tb_point ."`
|
||
|
|
WHERE `customer_id` = ?
|
||
|
|
ORDER BY id DESC
|
||
|
|
LIMIT ".($page - 1) * $numPerPage .", ".$numPerPage." " , ['d'], [$user_id]);
|
||
|
|
|
||
|
|
$result = array();
|
||
|
|
$i = ($page - 1) * $numPerPage;
|
||
|
|
foreach ( $this->db->fetchAll($query) as $rs){
|
||
|
|
$i++;
|
||
|
|
$rs['counter'] = $i;
|
||
|
|
$rs['activity_type_name'] = (isset($this->point_setting[$rs['operation']][$rs['activity_type']])) ? $this->point_setting[$rs['operation']][$rs['activity_type']]['name'] : '--';
|
||
|
|
$result[] = $rs;
|
||
|
|
}
|
||
|
|
|
||
|
|
return $result;
|
||
|
|
}
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
public function usePoint($user_id, $use_point, $activity_type, $activity_type_tracker, $reason = '', $point_args = ['order_value' => 0]){
|
||
|
|
// no user or no config
|
||
|
|
if(!$user_id || !ENABLE_CUSTOMER_POINT) return false;
|
||
|
|
|
||
|
|
$result = $this->objUserLoyaltyPointCalculation->calculateUsePoint($user_id, $use_point, $activity_type, $activity_type_tracker, $point_args);
|
||
|
|
|
||
|
|
$this->pointOp('use', $user_id, $result['use_point'], $activity_type, $activity_type_tracker, $reason);
|
||
|
|
|
||
|
|
return $result;
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
public function rewardPoint($user_id, $activity_type, $activity_type_tracker, $reason = '', $point_args = ['order_id' => 0]){
|
||
|
|
// no user or no config
|
||
|
|
if(!$user_id || !ENABLE_CUSTOMER_POINT) return false;
|
||
|
|
|
||
|
|
$point = $this->objUserLoyaltyPointCalculation->calculateRewardPoint($user_id, $activity_type, $activity_type_tracker, $point_args);
|
||
|
|
|
||
|
|
$this->pointOp('reward', $user_id, $point, $activity_type, $activity_type_tracker, $reason);
|
||
|
|
|
||
|
|
return $point;
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
// $operation: reward|use
|
||
|
|
// $change_point: positive (reward) or nagative (use)
|
||
|
|
protected function pointOp($operation, $user_id, $change_point, $activity_type, $activity_type_tracker, $reason = '') {
|
||
|
|
|
||
|
|
if(!$change_point) return false;
|
||
|
|
|
||
|
|
$reason_prefix = ($operation == 'use') ? 'Sử dụng' : 'Thưởng';
|
||
|
|
if($activity_type == 'return') $reason_prefix = 'Hoàn lại';
|
||
|
|
$full_reason = join(" ", [$reason_prefix, $change_point, static::$POINT_NAME, ":", $reason]);
|
||
|
|
|
||
|
|
if($operation == 'use') $change_point = -1 * $change_point;
|
||
|
|
|
||
|
|
// security: hash the row to avoid editing point directly in the database
|
||
|
|
$hash_value = sha1(join(".", [
|
||
|
|
$operation,
|
||
|
|
$user_id,
|
||
|
|
$change_point,
|
||
|
|
$activity_type,
|
||
|
|
$activity_type_tracker,
|
||
|
|
CURRENT_TIME,
|
||
|
|
'ass@ss'
|
||
|
|
]));
|
||
|
|
|
||
|
|
$new_id = $this->db->insert(
|
||
|
|
$this->tb_point ,
|
||
|
|
[
|
||
|
|
'customer_id' => $user_id ,
|
||
|
|
'activity_type' => $activity_type,
|
||
|
|
'activity_type_tracker' => $activity_type_tracker ,
|
||
|
|
'operation' => $operation,
|
||
|
|
'point' => $change_point,
|
||
|
|
'create_time' => CURRENT_TIME,
|
||
|
|
'reason' => substr($full_reason, 0, 200),
|
||
|
|
'referer_url' => substr(REFERER_URL, 0, 150) ,
|
||
|
|
'hash_value' => $hash_value ,
|
||
|
|
]
|
||
|
|
);
|
||
|
|
|
||
|
|
//update user reward balance
|
||
|
|
if($new_id) {
|
||
|
|
$this->updateStat($user_id, $change_point);
|
||
|
|
}
|
||
|
|
|
||
|
|
return $new_id;
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
public function updateStat($user_id, $changed_point, $changed_order_value=0) {
|
||
|
|
$user_id = intval($user_id);
|
||
|
|
|
||
|
|
$query = $this->db->runQuery("SELECT
|
||
|
|
`loyalty_point`,
|
||
|
|
`loyalty_level`,
|
||
|
|
`total_value_success`
|
||
|
|
FROM ".$this->tb_customer."
|
||
|
|
WHERE `id` = ?
|
||
|
|
LIMIT 1 " , ['d'], [$user_id]);
|
||
|
|
|
||
|
|
if($current = $this->db->fetchAssoc($query)){
|
||
|
|
$new_point = $current['loyalty_point'] + $changed_point;
|
||
|
|
$new_purchase_value = $current['total_value_success'] + $changed_order_value;
|
||
|
|
|
||
|
|
$level = $current['loyalty_level'];
|
||
|
|
if($this->level_by == 'point' && $changed_point != 0) $level = $this->calculateLevelByPoint($new_point);
|
||
|
|
else if($changed_order_value) $level = $this->calculateLevelByOrderValue($new_purchase_value);
|
||
|
|
|
||
|
|
$this->db->update(
|
||
|
|
$this->tb_customer ,
|
||
|
|
[
|
||
|
|
'loyalty_point' => $new_point,
|
||
|
|
'loyalty_level' => $level,
|
||
|
|
'total_value_success' => $new_purchase_value,
|
||
|
|
],
|
||
|
|
[
|
||
|
|
'id' => $user_id,
|
||
|
|
],
|
||
|
|
1
|
||
|
|
);
|
||
|
|
}
|
||
|
|
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
private function calculateLevelByPoint($point) {
|
||
|
|
//if the point in between -> return the lowest level
|
||
|
|
$all_level = array_keys($this->level_setting);
|
||
|
|
|
||
|
|
foreach ( $all_level as $level) {
|
||
|
|
$next_level = $level + 1;
|
||
|
|
if(!in_array($next_level, $all_level)) $next_level = 0;
|
||
|
|
|
||
|
|
if($next_level) {
|
||
|
|
if( $point >= $this->level_setting[$level]["point_require"]
|
||
|
|
&& $point < $this->level_setting[$next_level]["point_require"] ) {
|
||
|
|
return $level;
|
||
|
|
}
|
||
|
|
}else{
|
||
|
|
if($point >= $this->level_setting[$level]["point_require"]) {
|
||
|
|
return $level;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
private function calculateLevelByOrderValue($aggregate_purchase_value = 0) {
|
||
|
|
|
||
|
|
//if the point in between -> return the lowest level
|
||
|
|
$all_level = array_keys($this->level_setting);
|
||
|
|
|
||
|
|
//tinh hang thanh vien theo so tien tich luy
|
||
|
|
foreach ( $all_level as $level ) {
|
||
|
|
$next_level = $level + 1;
|
||
|
|
if(!in_array($next_level, $all_level)) $next_level = 0;
|
||
|
|
|
||
|
|
if($next_level) {
|
||
|
|
if( $aggregate_purchase_value >= $this->level_setting[$level]["total_order_value"] &&
|
||
|
|
$aggregate_purchase_value < $this->level_setting[$next_level]["total_order_value"]
|
||
|
|
) {
|
||
|
|
return $level;
|
||
|
|
}
|
||
|
|
}else{
|
||
|
|
if( $aggregate_purchase_value >= $this->level_setting[$level]["total_order_value"]) {
|
||
|
|
return $level;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
}
|