Files
xstore/inc/Hura8/Components/Customer/Controller/bCustomerLoyaltyController.php

207 lines
7.1 KiB
PHP
Raw Normal View History

2025-10-04 11:46:59 +07:00
<?php
namespace Hura8\Components\Customer\Controller;
use ClientExtend\UserLoyaltyPointCalculation;
use Hura8\Components\Customer\Model\CustomerLoyaltyModel;
class bCustomerLoyaltyController
{
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;
/* @var CustomerLoyaltyModel $objCustomerLoyaltyModel */
protected $objCustomerLoyaltyModel;
public function __construct()
{
$this->objCustomerLoyaltyModel = new CustomerLoyaltyModel();
// 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)
{
return $this->objCustomerLoyaltyModel->getUserPoint($user_id, $condition, $return_type);
}
// remove rewarded point i.e. reward for successfull order and now order is marked canceled
public function reclaimRewardedPoint($user_id, $activity_type_tracker){
// todo:
}
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;
}
protected function updateStat($user_id, $changed_point, $changed_order_value=0) {
return $this->objCustomerLoyaltyModel->updateStat($user_id, $changed_point, $changed_order_value);
}
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;
}
}