'自增id', 'user_e_coupon_id' => '会员电子券id', 'user_id' => '会员电子券所有者', 'amount' => '数量', 'code' => '核销码唯一', 'created_at' => 'Created At', 'updated_at' => 'Updated At', 'status' => '状态[-1:删除;0:禁用;1启用]', 'coupon_status' => '状态;1已核销;0未核销', 'clerk_user_id' => '核销员用户id', 'clerk_admin_id' => '核销员管理员id', 'approval_at' => '核销时间', 'mall_id' => '商城id', 'store_id' => '门店id', ]; } /** * 数据设置 */ public static function setData(array $params) { try{ if (!isset($params['mall_id']) || empty($params['mall_id'])) throw new Exception('缺少商城ID'); $mall_id = $params['mall_id']; if (isset($params['id']) && !empty($params['id'])) { $model = self::findOne(['id' => $params['id'], 'mall_id' => $mall_id, 'status' => StatusEnum::ENABLED]); if(empty($model)) throw new Exception('核销码记录不存在或已删除'); } else { $model = new self(); $model->loadDefaultValues(); $model->mall_id = $mall_id; } if (!$model->load($params,'') || !$model->save()) throw new Exception($model->getErrorMessage()); return $model; }catch(Exception $e){ self::setStaticError($e->getMessage()); return false; } } // 获取核销码 public static function getCodeContent(array $params) { $must_keys = ['user_e_coupon_id', 'amount', 'mall_id', 'user_id']; foreach ($must_keys as $key) { if (!in_array($key, array_keys($params))) { self::setStaticError('缺少必要的参数' . $key); return false; } } // 有没有对应未核销的记录 $info = self::getOne([ ['user_e_coupon_id' => $params['user_e_coupon_id']], ['mall_id' => $params['mall_id']], ['user_id' => $params['user_id']], ['amount' => $params['amount']], ['status' => StatusEnum::ENABLED], ['coupon_status' => ElectronCouponEnums::COUPON_CODE_CREATE], ], true, '', '', ['id', 'code']); if ($info) { return $info['code']; } $config = Yii::$app->services->setting->addons->get($params['mall_id'], ElectronCouponEnums::ADDONS_NAME, 'basic'); $customize_name = $config['customize_name'] ?? '电子券'; // 有没有对应已激活的电子券来核销 $user_coupon = ElectronCouponUserCoupon::getOne([ ['id' => $params['user_e_coupon_id']], ['mall_id' => $params['mall_id']], ['user_id' => $params['user_id']], ], true, '', '', ['active_amount', 'use_end_time']); if (!$user_coupon) { self::setStaticError($customize_name . '不存在'); return false; } if ($user_coupon['active_amount'] < $params['amount']) { self::setStaticError('已激活' . $customize_name . '数量不足'); return false; } if ($user_coupon['use_end_time'] < time()) { self::setStaticError('该' . $customize_name . '已过期'); return false; } while (true){ $code = self::createCode(); $res = self::findOne(['code'=>$code]); if(empty($res)) { break; } } $params['code'] = $code; $params['status'] = StatusEnum::ENABLED; $params['coupon_status'] = ElectronCouponEnums::COUPON_CODE_CREATE; $params['clerk_admin_id'] = 0; $params['clerk_user_id'] = 0; $params['approval_at'] = 0; $params['store_id'] = 0; $created = self::setData($params); if (!$created) { self::setStaticError('生成核销码失败'); return false; } return $code; } /** * 核销操作 * code 核销码 * mall_id 商城id * clerk_admin_id 核销管理员id 可为空,为空时 clerk_user_id 不为空 * clerk_user_id 核销会员id 可为空,为空时 clerk_admin_id 不为空 */ public static function doClerkCode($params) { if (empty($params['store_id'])) { throw new Exception('缺少门店ID'); } $tran = Yii::$app->db->beginTransaction(); try { if (!isset($params['code']) || !$params['code']) { throw new Exception('缺少核销码参数'); } if (!isset($params['mall_id']) || !$params['mall_id']) { throw new Exception('缺少商城ID'); } if ( (!isset($params['clerk_admin_id']) && !$params['clerk_admin_id']) && (!isset($params['clerk_user_id']) && !$params['clerk_user_id']) ) { throw new Exception('缺少核销员参数'); } // 核销码记录 $coupon_code = self::getOne([['code' => $params['code']], ['<>', 'status', StatusEnum::DELETE], ['mall_id' => $params['mall_id']]], true); if (!$coupon_code) { throw new Exception('核销码错误'); } if ($coupon_code['coupon_status'] == 1) { throw new Exception('请勿重复核销'); } if ($params['clerk_user_id']) { $clerk_user = User::getOne([ ['id' => $params['clerk_user_id']], [ 'mall_id' => $params['mall_id']], ['status' => StatusEnum::ENABLED] ], true); if (!$clerk_user) { throw new Exception('核销员ID不存在'); } } $config = Yii::$app->services->setting->addons->get($params['mall_id'], ElectronCouponEnums::ADDONS_NAME, 'basic'); $customize_name = $config['customize_name'] ?? '电子券'; // 会员电子券 $user_coupon = ElectronCouponUserCoupon::getOne([ ['id' => $coupon_code['user_e_coupon_id']], ['mall_id' => $params['mall_id']], ['user_id' => $coupon_code['user_id']] ], true); if (!$user_coupon) { throw new Exception('会员' . $customize_name . '不存在'); } if ($user_coupon['use_begin_time'] > time()) { throw new Exception('会员' . $customize_name . '未到使用时间 ' . date('Y-m-d H:i', $user_coupon['use_begin_time'])); } if ($user_coupon['use_end_time'] < time()) { throw new Exception('会员' . $customize_name . '已过期 ' . date('Y-m-d H:i', $user_coupon['use_end_time'])); } // 当前数量够不够 if ($coupon_code['amount'] > $user_coupon['active_amount']) { throw new Exception('会员' . $customize_name . '已激活数量不足'); } $coupon_info = ElectronCoupon::getOne([['id' => $user_coupon['e_coupon_id']], ['mall_id' => $params['mall_id']]], true); // 更改核销状态 $update_code_data = [ 'id' => $coupon_code['id'], 'coupon_status' => ElectronCouponEnums::COUPON_STATUS_ACTIVE, 'approval_at' => time(), 'clerk_admin_id' => $params['clerk_admin_id'] ?? 0, 'clerk_user_id' => $params['clerk_user_id'] ?? 0, 'mall_id' => $params['mall_id'] ?? 0, ]; $update_coupon_code = self::setData($update_code_data); if ($update_coupon_code == false) { throw new Exception(self::getStaticError()); } // 会员电子券减少激活数量,增加兑换数量 $user_coupon_data = [ 'active_amount' => -1 * $coupon_code['amount'], 'used_amount' => $coupon_code['amount'], 'last_used_time' => time(), 'mall_id' => $params['mall_id'], 'id' => $user_coupon['id'] ]; $update_user_coupon = ElectronCouponUserCoupon::setData($user_coupon_data); if ($update_user_coupon == false) { throw new Exception(ElectronCouponUserCoupon::getStaticError()); } // 电子券增加兑换数量 $update_coupon_info = ElectronCoupon::setData([ 'id' => $coupon_info['id'], 'mall_id' => $params['mall_id'], 'used_amount' => $coupon_code['amount'] ]); if ($update_coupon_info == false) { throw new Exception(ElectronCoupon::getStaticError()); } // 使用记录 $usage_data = [ 'mall_id' => $params['mall_id'], 'user_id' => $user_coupon['user_id'], 'user_e_coupon_id' => $coupon_code['user_e_coupon_id'], 'e_coupon_id' => $user_coupon['e_coupon_id'], 'e_coupon_name' => $coupon_info['name'], 'amount' => $coupon_code['amount'], 'clerk_user_id' => $update_code_data['clerk_user_id'], 'clerk_admin_id' => $update_code_data['clerk_admin_id'], 'proper_user_id' => $user_coupon['proper_id'], 'receive_time' => $user_coupon['last_receive_time'], 'usage_time' => time(), 'status' => StatusEnum::ENABLED ]; $insert_usage = ElectronCouponUsageLog::setData($usage_data); if ($insert_usage == false) { throw new Exception(ElectronCouponUsageLog::getStaticError()); } // 赠积分、佣金 // 是否是专有者 if ($user_coupon['is_proper'] == ElectronCouponEnums::COUPON_IS_PROPER && $user_coupon['proper_id'] > 0) { // 专有者为奖励者 $reward_user_id = $user_coupon['proper_id']; } else { // 使用者为奖励者 $reward_user_id = $user_coupon['user_id']; } // 奖励充值 $insert_wallet = []; // 奖励积分 if ($coupon_info['give_score'] > 0) { $reward_amount = (float) bcmul($coupon_info['give_score'], $coupon_code['amount'], 2); $wallet_type = UserWalletService::WALLET_TYPE_SCORE; $reward_desc = $customize_name . '兑换积分'; // 收益明细表 $approval_income_log = [ 'e_coupon_code_id' => $coupon_code['id'], 'user_e_coupon_id' => $coupon_code['user_e_coupon_id'], 'e_coupon_id' => $user_coupon['e_coupon_id'], 'status' => StatusEnum::ENABLED, 'user_id' => $reward_user_id, 'e_coupon_name' => $coupon_info['name'], 'amount' => $coupon_code['amount'], 'mall_id' => $params['mall_id'], 'price_type' => ElectronCouponEnums::COUPON_PRICE_TYPE_SCORE, 'commission' => $reward_amount, 'clerk_user_id' => $update_code_data['clerk_user_id'], 'clerk_admin_id' => $update_code_data['clerk_admin_id'], ]; $income_log = ElectronCouponApprovalIncomeLog::setData($approval_income_log); if ($income_log == false) { throw new Exception(ElectronCouponApprovalIncomeLog::getStaticError()); } $insert_wallet[] = [ 'mall_id' => $params['mall_id'], 'user_id' => $reward_user_id, 'is_frozen' => false, 'wallet_type' => $wallet_type, 'money' => $reward_amount, 'desc' => $reward_desc, 'source_table' => self::tableName(), 'source_table_id' => $coupon_code['id'], 'from_type' => UserWalletEnum::RECHARGE, 'capital_type'=> UserWalletEnum::GIVE ]; } // 奖励佣金 if ($coupon_info['give_price'] > 0 && $params['clerk_user_id']) { $reward_user_id = $params['clerk_user_id']; $reward_amount = (float) bcmul($coupon_info['give_price'], $coupon_code['amount'], 2); $wallet_type = UserWalletService::WALLET_TYPE_COMMISSION; $reward_desc = $customize_name . '兑换佣金'; // 收益明细表 $approval_income_log = [ 'e_coupon_code_id' => $coupon_code['id'], 'user_e_coupon_id' => $coupon_code['user_e_coupon_id'], 'e_coupon_id' => $user_coupon['e_coupon_id'], 'status' => StatusEnum::ENABLED, 'user_id' => $reward_user_id, 'e_coupon_name' => $coupon_info['name'], 'amount' => $coupon_code['amount'], 'mall_id' => $params['mall_id'], 'price_type' => ElectronCouponEnums::COUPON_PRICE_TYPE_COMM, 'commission' => $reward_amount, 'clerk_user_id' => $update_code_data['clerk_user_id'], 'clerk_admin_id' => $update_code_data['clerk_admin_id'], ]; $income_log = ElectronCouponApprovalIncomeLog::setData($approval_income_log); if ($income_log == false) { throw new Exception(ElectronCouponApprovalIncomeLog::getStaticError()); } $insert_wallet[] = [ 'mall_id' => $params['mall_id'], 'user_id' => $reward_user_id, 'is_frozen' => false, 'wallet_type' => $wallet_type, 'money' => $reward_amount, 'desc' => $reward_desc, 'source_table' => self::tableName(), 'source_table_id' => $coupon_code['id'], 'from_type' => UserWalletEnum::RECHARGE, 'capital_type'=> UserWalletEnum::GIVE ]; } /** * 电子券结算至门店 * 作者:zengfanhua * 创建时间:2024/05/08 01:02:36 */ if ($coupon_info['give_store_price'] > 0 && $params['store_id']>0 && $params['clerk_user_id']>0) { //$give_store_price=(float) bcmul(bcdiv($coupon_info['give_store_price'],100,2), $coupon_info['price'], 2); $give_store_price=$coupon_info['give_store_price']; $give_store_price= bcmul($give_store_price,$coupon_code['amount'],2); $income_total_amount= bcmul($coupon_info['price'],$coupon_code['amount'],2); $paramsTO = [ 'mall_id' => $params['mall_id'], 'store_id' => $params['store_id'], 'user_id' => $user_coupon['user_id'], 'order_no' => 'user_e_coupon_id_' . $coupon_code['user_e_coupon_id'], 'amount' => $income_total_amount, 'income' => $give_store_price, 'user_e_coupon_id' => $coupon_code['user_e_coupon_id'], 'e_coupon_id' => $user_coupon['e_coupon_id'], 'e_coupon_name' => $coupon_info['name'], 'num' => $coupon_code['amount'], 'clerk_user_id' => $params['clerk_admin_id'] ?? 0, 'clerk_admin_id' => $params['clerk_admin_id'] ?? 0, 'proper_user_id' => $user_coupon['proper_id'], 'mobile' => $params['mobile'] ]; $res = StoreClerkIncome::setData($paramsTO); if (empty($res)) throw new Exception(StoreClerkIncome::getStaticError()); //更新统计表 $incomeDataModel=StoreClerkIncomeData::getOne([['mall_id'=>$params['mall_id']],['store_id'=>$params['store_id'],'status'=>1]]); if($incomeDataModel) { $incomeDataModel->total_amount+= $income_total_amount; $incomeDataModel->total_count+=1; $incomeDataModel->total_income+=$give_store_price; $res=$incomeDataModel->save(); if (empty($res)) throw new Exception(StoreClerkIncomeData::getStaticError()); } else{ $res = StoreClerkIncomeData::setData([ 'store_id' => $params['store_id'], 'mall_id' => $params['mall_id'], 'total_amount' => $income_total_amount, 'total_count' => 1, 'total_income' => $give_store_price ]); if (empty($res)) throw new Exception(StoreClerkIncomeData::getStaticError()); } } //使用后 $res = ElectronCouponGiveLogs::useAfter($user_coupon['user_id'],$coupon_code['user_e_coupon_id'],time()); if ($res == false) { throw new Exception(ElectronCouponGiveLogs::getStaticError()); } // if(!empty($coupon_info['reward_money'])&&!empty($params['clerk_user_id'])){ // $commission = bcmul($coupon_code['amount'],$coupon_info['reward_money'],2); // self::clerkReward($coupon_info['mall_id'],$params['clerk_user_id'],$commission,$insert_usage['id'],$coupon_info['name']); // //todo 核销记录 // // } //生成核销记录 if(MallAddons::isInstall($params['mall_id'],'Clerk')){ $insert = [ 'mall_id' => $params['mall_id'], 'store_id' => $params['store_id'], 'clerk_id' => $params['clerk_id'], 'user_id' => $params['user_id'] ?? 0, 'source_table_id' => $coupon_code['id'], 'source_table' => ElectronCouponCode::tableName(), 'commission' => $reward_amount ?? 0, 'money' => $coupon_info['price'] ?? 0, 'mobile' => $params['mobile'], 'title' => $coupon_info['name'], 'pic' => $coupon_info['pic'], ]; $res = ClerkLog::setData($insert); if (empty($res)) throw new Exception(ClerkLog::getStaticError()); } $store = Store::getOne([['id' => $params['store_id']]], true, [], false, 'id,user_id,balance,logo_img,store_name'); $add_clerk_log_data = [ 'mall_id' => $params['mall_id'], 'user_id' => $params['user_id'], 'mall_logo' => $store['logo_img'], 'mall_name' => $store['store_name'], 'name' => $coupon_info['name'], 'pic' => $coupon_info['pic'], 'clerk_code' => (string)$params['clerk_code'], 'type' => ClerkEnum::ELECTRON_COUPON_CLERK_CODE_PRE, 'extra' => json_encode([ 'e_coupon_id'=> $user_coupon['e_coupon_id'] ]), ]; $clerk_log_model = \common\models\common\ClerkLog::setData($add_clerk_log_data); if ($clerk_log_model == false) { throw new \Exception(\common\models\common\ClerkLog::getStaticError()); } $tran->commit(); if ($insert_wallet) { $res = UserWalletService::batchHandleByQueue($insert_wallet); if (empty($res)) throw new Exception(UserWalletService::getStaticError()); } //核销奖励 return compact( 'insert_wallet', 'coupon_info'); } catch (Exception $e) { $tran->rollBack(); Yii::error(FormatHelper::exception($e, "电子券核销出错")); self::setStaticError($e->getMessage()); return false; } } //核销奖励 public static function clerkReward($mall_id,$user_id,$money,$source_table_id,$contributor_name){ $desc = '用户(' . $user_id . '),获得电子券核销奖励,佣金:' . $money; $insert_wallet [] = [ 'mall_id' => $mall_id, 'user_id' => $user_id, 'is_frozen' => false, 'wallet_type' => 'commission', 'money' => $money, 'desc' => $desc, 'source_table' => ElectronCouponUsageLog::tableName(), 'source_table_id' => $source_table_id, 'from_type' => ElectronCouponEnums::ADDONS_NAME, 'capital_type' => UserWalletEnum::E_COUPON_CLERK, 'order_no' =>$source_table_id, 'contributor_name' =>$contributor_name, 'contributor_id' =>0, 'contributor_money' =>0, ]; $res = UserWalletService::batchHandleByQueue($insert_wallet); if (empty($res)) throw new \Exception(UserWalletService::getStaticError()); return true; } /** * 生成核销码 * @return string */ public static function createCode() { return ClerkEnum::getCode(ClerkEnum::ELECTRON_COUPON_CLERK_CODE_PRE); } public static function updateCode(){ $i = 1; $page_size = 1000; while ($list = self::find() ->andWhere(['=','status',1]) ->offset(($i - 1) * $page_size)->limit($page_size)->all()) { foreach ($list as $item) { while (true){ $code = self::createCode(); $res = self::findOne(['code'=>$code]); if(empty($res)) { break; } } $item->code = $code; $item->save(); var_dump($item->code); } $i++; } } public static function updateOldData(){ try { $mall_list = Mall::lists(['where'=>[ ['>','id',0] ]]); foreach ($mall_list as $mall) { if (!MallAddons::isInstall($mall['id'], 'Clerk')) { continue; } $i = 1; $page_size = 100; while (true) { $list = ClerkLog::find()->where(['>', 'source_table_id', 0]) ->andWhere(['mall_id' => $mall['id']]) ->offset(($i - 1) * $page_size)->limit($page_size)->all(); if (empty($list)) { break; } $clerk_ids = array_column($list, 'clerk_id'); $store_ids = array_column($list, 'store_id'); $source_table_ids = array_column($list, 'source_table_id'); $e_code_list = ElectronCouponCode::lists(['where' => [['id' => $source_table_ids]], 'index' => 'id']); $store_clerk_list = StoreClerk::lists(['where' => [['id' => $clerk_ids]], 'index' => 'id']); $store_list = Store::lists(['where' => [['id' => $store_ids]], 'index' => 'id']); foreach ($list as $item) { if (empty($store_clerk_list[$item['clerk_id']]) || empty($store_list[$item['store_id']]) || empty($e_code_list[$item['source_table_id']])) { continue; } $e_code_model = $e_code_list[$item['source_table_id']]; if (\common\models\common\ClerkLog::findOne(['clerk_code' => $e_code_model['code'], 'type' => ClerkEnum::ELECTRON_COUPON_CLERK_CODE_PRE])) { continue; } $store_clerk = $store_clerk_list[$item['clerk_id']]; $store = $store_list[$item['store_id']]; $e_coupon_user_model = ElectronCouponUserCoupon::findOne(['id' => $e_code_model['user_e_coupon_id']]); $e_coupon_model = ElectronCoupon::findOne(['id' => $e_coupon_user_model['e_coupon_id']]); $add_clerk_log_data = [ 'mall_id' => $item['mall_id'], 'user_id' => $store_clerk['user_id'], 'mall_logo' => $store['logo_img'], 'mall_name' => $store['store_name'], 'name' => $e_coupon_model['name'], 'pic' => $e_coupon_model['pic'], 'clerk_code' => (string)$e_code_model['code'], 'type' => ClerkEnum::ELECTRON_COUPON_CLERK_CODE_PRE, 'extra' => json_encode([ 'e_coupon_id' => $e_coupon_user_model['e_coupon_id'] ]), ]; \common\models\common\ClerkLog::setData($add_clerk_log_data); var_dump($item['source_table_id']); } $i++; } } }catch (\Exception $e){ var_dump($e->getMessage().$e->getFile().$e->getLine()); } } }