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; } }