mall_id], ['status' => StatusEnum::ENABLED]]; if ($order_no) { $where[] = ['like', 'order_no', $order_no]; } if (is_numeric($buy_keyword)) { $userIds = User::find() ->where(['mall_id' => $this->mall_id]) ->andWhere(['like', 'mobile', $buy_keyword]) ->select('id') ->column(); $where[] = ['or', ['=', 'buy_user_id', $buy_keyword], ['in', 'buy_user_id', $userIds]]; } if (is_numeric($seller_keyword)) { $userIds = User::find() ->where(['mall_id' => $this->mall_id]) ->andWhere(['like', 'mobile', $seller_keyword]) ->select('id') ->column(); $where[] = ['or', ['=', 'seller_user_id', $seller_keyword], ['in', 'seller_user_id', $userIds]]; } $getListParams = [ 'with' => [ 'order' => function ($query) { $query->select('order_no, order_status'); }, 'buyUser' => function ($query) { $query->select('id, mobile, nickname, avatar_url'); }, 'sellerUser' => function ($query) { $query->select('id, mobile, nickname, avatar_url'); }, ], 'where' => $where, 'order' => 'pay_time desc, order_no desc, id desc' ]; $levelMap = AgentLevel::getLevelByColumn($this->mall_id); if ($getAll) { $list = AgentSupplierCommission::lists($getListParams); $this->formatList($list, $levelMap); } else { $list = AgentSupplierCommission::listPage($getListParams); $this->formatList($list['list'], $levelMap); } return $list; } /** * 字段修改 * * @param array $list * @param array $levelMap * * @return void */ protected function formatList(array &$list, array $levelMap) { array_walk($list, function (&$item) use ($levelMap) { $item['order']['order_status_text'] = OrderStatusEnum::getMap()[$item['order']['order_status']] ?? '-'; $item['pay_time_text'] = date('Y-m-d H:i:s', $item['pay_time']); $item['buy_level_text'] = $levelMap[$item['buy_level']] ?? '-'; $item['seller_level_text'] = $levelMap[$item['seller_level']] ?? '-'; $item['capital_type_text'] = ComputingEnum::getTypeMap()[$item['capital_type']] ?? '-'; }); } public function export(array $data): bool { $download_id = $data['download_id'] ?? 0; $download = Download::findOne(['id' => $download_id]); if (!$download) { return false; } $this->mall_id = $download->mall_id; try { $params = json_decode($download->params, true); $filename = $download->name; $type = $download->type; $list = $this->getList($params, true); $exportList = []; foreach ($list as $item) { $exportList[] = [ 'buy_user' => $item['buyUser']['mobile'] ?? '-', 'buy_level_text' => $item['buy_level_text'], 'seller_user' => $item['sellerUser']['mobile'] ?? '-', 'seller_level_text' => $item['seller_level_text'], 'profit' => $item['profit'], 'order_no' => $item['order_no'], 'payment_amount' => $item['payment_amount'], 'order_status_text' => $item['order']['order_status_text'], 'pay_time_text' => $item['pay_time_text'], 'capital_type_text' => $item['capital_type_text'], ]; } unset($list); if (!empty($exportList)) { $csv = new CsvTool(); $csv->filename = $filename; $csv->file_dirname = DownloadEnum::getTypeStorageDirMap($type); $csv->export_mode = CsvTool::EXPORT_MODE_ASYNC; $csv->header = ['买家', '身份', '卖家', '身份', '利润', '订单号', '货款金额', '订单状态', '收入时间', '奖项']; $csv->data = $exportList; $csv->export(); $csv->updateDown($download, $params['mall_id']); } } catch (Exception $e) { $download->status = 3; $download->save(); $this->setError($e->getMessage()); return false; } return true; } /** * 返回是否允许投递任务 * * @return bool */ public function allowDeliveryTask() { $status = AgentSupplierCommissionSyncLog::find() ->where(['mall_id' => $this->mall_id]) ->select('status') ->scalar(); // 未处理 或者 处理成功不允许投递 return !(is_numeric($status) && in_array($status, [StatusEnum::DISABLED, StatusEnum::ENABLED])); } /** * 同步旧数据 * * @return void */ public function syncOldData($data) { if (empty($data['mall_id'])) { Yii::$app->custom->logs('同步供应商收入数据:data为空', $data); return; } $this->mall_id = $data['mall_id']; $pendingData = AgentSupplierCommissionSyncLog::find() ->where(['mall_id' => $this->mall_id, 'status' => StatusEnum::DISABLED]) ->one(); if (!$pendingData) { Yii::$app->custom->logs('同步供应商收入数据:不存在待处理的数据', $data); return; } try { $this->insertCommission('commission', ['mall_id' => $this->mall_id, 'from_type' => 'Agent'], $this->mall_id); $this->insertCommission('commission_frozen', ['mall_id' => $this->mall_id, 'from_type' => 'Agent', 'status' => StatusEnum::DISABLED], $this->mall_id); $pendingData->status = StatusEnum::ENABLED; } catch (\Exception $e) { $pendingData->status = StatusEnum::DELETE; Yii::$app->custom->logs(FormatHelper::exception($e, '同步供应商收入数据:处理失败'), $data); } $pendingData->save(); } /** * 查询并写入 * * @param string $wallet_type * @param array $where * @param int $mallId * * @return void */ protected function insertCommission(string $wallet_type, array $where, int $mallId) { CapitalLog::$capitalType = $wallet_type; foreach (CapitalLog::find()->where($where)->batch(500) as $batch) { $batchInsertData = []; foreach ($batch as $commissionItem) { [ $payment_amount, $goods_nums, $buy_user_id, $buy_user_level, $seller_level, $order_no, $pay_time ] = self::formatData($commissionItem); $batchInsertData[] = [ 'mall_id' => $mallId, 'buy_user_id' => $buy_user_id, 'buy_level' => $buy_user_level, 'seller_user_id' => $commissionItem['user_id'], 'seller_level' => $seller_level, 'order_no' => $order_no, 'supplier_order_no' => Order::generateOrderNo('G'), 'goods_nums' => $goods_nums, 'stock_nums' => $goods_nums, 'payment_amount' => $payment_amount, 'profit' => $commissionItem['change_num'], 'pay_time' => !is_numeric($pay_time) ? 0 : $pay_time, 'capital_type' => $commissionItem['capital_type'], 'source_table' => $commissionItem['source_table'], 'source_table_id' => $commissionItem['source_table_id'], ]; } AgentSupplierCommission::insertData($batchInsertData); } } /** * 格式化数据 * @Author:hua * @Date:2024-02-23 15:07 * @Copyright:copyright(c)2024 广东七件事集团 * @param $item * @return array */ public static function formatData($item) { $payment_amount = 0; $goods_nums = 0; $buy_user_id = 0; $buy_user_level = 0; $seller_level = 0; $order_no = ''; $pay_time = ''; switch ($item['source_table']) { case 'order_detail': $order_detail = OrderDetail::findOne(['id' => $item['source_table_id']]); if ($order_detail) { $order = Order::findOne(['id' => $order_detail['order_id']]); if ($order) { $order_no = $order['order_no']; $pay_time = $order['pay_time']; $buy_user_id = $order['user_id']; } $goods_nums = $order_detail['num']; $payment_amount = $order_detail['goods_price']; } break; case 'store_cashier_order': $store_cashier_order = StoreCashierOrder::findOne(['id' => $item['source_table_id']]); if ($store_cashier_order) { $order_no = $store_cashier_order['order_no']; $pay_time = $store_cashier_order['pay_time']; $buy_user_id = $store_cashier_order['user_id']; $payment_amount = $store_cashier_order['pay_money']; } $goods_nums = 1; break; case 'store_order_detail': $store_order_detail = StoreOrderDetail::findOne(['id' => $item['source_table_id']]); if ($store_order_detail) { $store_order = StoreOrder::findOne(['id' => $store_order_detail['order_id']]); if ($store_order) { $order_no = $store_order['order_no']; $pay_time = $store_order['pay_time']; $buy_user_id = $store_order['user_id']; } $payment_amount = $store_order_detail['goods_price']; } $goods_nums = $store_order_detail['num']; break; case '{{%addons_agent_team_achievement}}': break; case '{{%addons_course_orders}}': $course_order = AddonsCourseOrders::findOne(['id' => $item['source_table_id']]); if ($course_order) { $order_no = $course_order['order_no']; $pay_time = $course_order['pay_time']; $buy_user_id = $course_order['user_id']; $goods_nums = 1; $payment_amount = $course_order['pay_money']; } break; case '{{%order}}': $order = Order::findOne(['id' => $item['source_table_id']]); if ($order) { $num = OrderDetail::find()->where(['order_id' => $order['id']])->sum('num'); $goods_price = OrderDetail::find()->where(['order_id' => $order['id']])->sum('goods_price'); if (!empty($num)) $goods_nums = $num; if (!empty($goods_price)) $payment_amount = $goods_price; $order_no = $order['order_no']; $pay_time = $order['pay_time']; $buy_user_id = $order['user_id']; } break; } // 从供应商订单找之前的等级 if (!empty($order_no)) { $levelArr = AgentSupplierOrder::find() ->where(['order_no' => $order_no]) ->asArray() ->all(); $buyUserLevelArr = array_column($levelArr, 'buy_level', 'buy_user_id'); $sellerUserLevelArr = array_column($levelArr, 'seller_level', 'seller_user_id'); } $agent_arr = Agent::find()->where(['mall_id' => $item['mall_id'], 'user_id' => [$buy_user_id, $item['user_id']], 'status' => StatusEnum::ENABLED]) ->indexBy('user_id')->all(); if (isset($buyUserLevelArr[$buy_user_id])) { $buy_user_level = $buyUserLevelArr[$buy_user_id]; }else if (isset($agent_arr[$buy_user_id])) { $buy_user_level = $agent_arr[$buy_user_id]['level']; } if (isset($sellerUserLevelArr[$item['user_id']])) { $seller_level = $sellerUserLevelArr[$item['user_id']]; }else if (isset($agent_arr[$item['user_id']])) { $seller_level = $agent_arr[$item['user_id']]['level']; } return [$payment_amount, $goods_nums, $buy_user_id, $buy_user_level, $seller_level, $order_no, $pay_time]; } /** * 重新分配佣金(数字币只验证是否已结算,不处理其他情况) * * @param array $post * * @return bool */ public function redistributeCommissions(array $post): bool { $orderDetailsIds = $post['order_details_ids']; $mallId = $this->mall_id; try { $this->redistributeCommissionsValidate($orderDetailsIds, $mallId); // 验证通过则丢队列处理 Yii::$app->services->rabbitMq->push( RabbitMqEnum::EXCHANGE_ORDER, RabbitMqEnum::ORDER_QUEUE, ['mall_id' => $this->mall_id, 'order_details_ids' => $orderDetailsIds], self::class, 'asyncRedistributeCommissions' ); return true; }catch (Exception $e) { $this->error = $e->getMessage(); return false; } } /** * 执行重新分配前数据验证 * * @param array $orderDetailsIds * @param int $mallId * * @return array */ protected function redistributeCommissionsValidate(array &$orderDetailsIds, int $mallId): array { $orderDetailList = OrderDetail::find() ->where([ 'status' => StatusEnum::ENABLED, 'id' => $orderDetailsIds, 'mall_id' => $mallId ]) ->andWhere(['not in', 'order_status', [OrderStatusEnum::REPEAL,OrderStatusEnum::ACCOMPLISH]])//已完成的订单无法重新分配 ->select('id, order_id, is_feedback') ->asArray() ->all(); if (empty($orderDetailList)) { throw new RuntimeException('订单明细不存在或已退款、已完成'); } $orderIds = array_column($orderDetailList, 'order_id'); // 验证 details_id正确 并且是 同一个订单 if (count(array_unique($orderIds)) > 1) { throw new RuntimeException('订单参数错误,存在多张订单'); } $orderDetailsIds = array_column($orderDetailList, 'id'); // 排除售后完成并且不是换货的order details id $refundOrderDetailIds = OrderRefund::find() ->where([ 'order_detail_id' => $orderDetailsIds, 'status' => StatusEnum::ENABLED, 'refund_status' => RefundStatusEnum::FINISH, 'type' => [RefundTypeEnum::MONEY, RefundTypeEnum::MONEY_AND_PRODUCT] ]) ->select('order_detail_id') ->column(); $orderDetailsIds = array_diff($orderDetailsIds, $refundOrderDetailIds); if (empty($orderDetailsIds)) { throw new RuntimeException('订单已退款'); } $order = Order::find() ->where([ 'id' => reset($orderIds), 'mall_id' => $this->mall_id, 'status' => StatusEnum::ENABLED, 'pay_status' => OrderStatusEnum::PAY, ]) ->andWhere(['not in', 'order_status', [OrderStatusEnum::REPEAL,OrderStatusEnum::ACCOMPLISH]]) ->one(); if (empty($order)) { throw new RuntimeException('订单不存在或已退款、已完成'); } $orderNo = $order['order_no']; // 验证是否可以重新分配 try { $frozenCommissionList = $this->checkCommissionOrScore($orderDetailsIds, 'commission'); $frozenScoreList = $this->checkCommissionOrScore($orderDetailsIds, 'score'); $this->checkDigital($orderDetailsIds); $orderNo && $this->checkDelayLog($orderNo); }catch (Exception $e) { throw new RuntimeException($e->getMessage()); } // 将冻结列表组装成$insert_wallet return [ 'insert_wallet' => $this->frozenDataToInsertWallet($frozenCommissionList, $frozenScoreList), 'order' => $order ]; } /** * 重新分配,异步执行 * * @param array $data * * @return false|void */ public function asyncRedistributeCommissions(array $data) { if (empty($data['mall_id']) || empty($data['order_details_ids'])) { return; } $this->mall_id = $data['mall_id']; $orderDetailsIds = $data['order_details_ids']; $validateRes = $this->redistributeCommissionsValidate($orderDetailsIds, $this->mall_id); $order = $validateRes['order']; $insertWallet = $validateRes['insert_wallet']; $t = Yii::$app->db->beginTransaction(); try { // 将供应商收入的旧数据置为失效 $this->disableAgentSupplierCommission($orderDetailsIds); // 将供应商订单的旧数据置为失效 $this->disableAgentSupplierOrder($orderDetailsIds); // $this->disableFrozenDigital($orderDetailsIds); // 不处理数字币 // 将佣金和积分的旧数据置为失效 $this->disableFrozenCommissionOrScore($orderDetailsIds, 'commission'); $this->disableFrozenCommissionOrScore($orderDetailsIds, 'score'); // 将延时任务的任务明细置为失效 $this->disableAgentDelayLog($orderDetailsIds); // 减少agent total_commission total_score字段 foreach ($insertWallet as $walletItem) { // 不处理数字币 if($walletItem['wallet_type'] === 'digital'){ continue; } if($walletItem['from_type'] === AddonsEnum::ADDONS_NAME_REGULAR_BONUS. '_'. AgentEnum::ADDONS_NAME) { continue; } $agent = Agent::findOne(['user_id' => $walletItem['user_id'],'status'=>[StatusEnum::DISABLED,StatusEnum::ENABLED], 'mall_id' => $this->mall_id]); if(empty($agent)) { continue; } $field = 'total_' . ($this->getCommissionNameMap()[$walletItem['wallet_type']] ?? $walletItem['wallet_type']); $agent->$field -= $walletItem['money']; $res = $agent->save(); if (empty($res)) { throw new RuntimeException(Agent::getStaticError()); } } $t->commit(); // 重新分配 $this->reward($order, $orderDetailsIds); }catch (Exception $e) { $t->rollBack(); Yii::$app->custom->logs(FormatHelper::exception($e, '重新分配佣金失败'), compact('data')); return false; } } /** * 检查佣金或积分是否已结算(返回待结算的数据) * * @param array $orderDetailsIds * @param string $wallet_type * * @return array */ protected function checkCommissionOrScore(array $orderDetailsIds, string $wallet_type): array { // 实际已结算的表 CapitalLog::$capitalType = $wallet_type; $where = [ 'source_table' => $this->getOrderDetailsTable(), 'source_table_id' => $orderDetailsIds, 'from_type' => AgentEnum::ADDONS_NAME ]; $sendCount = CapitalLog::find() ->where($where) ->count(); if ($sendCount) { throw new RuntimeException('当前订单已存在已结算数据,不允许重新分配'); } // 冻结表 CapitalLog::$capitalType = "{$wallet_type}_frozen"; $where['status'] = [CapitalLog::STATUS_SEND, CapitalLog::STATUS_WAIT_SEND]; $frozenList = []; $commissionFrozenList = CapitalLog::find() ->where($where) ->asArray() ->all(); foreach ($commissionFrozenList as $item) { if ($item['status'] == CapitalLog::STATUS_SEND) { throw new RuntimeException('当前订单已存在已结算数据,不允许重新分配'); } if ($item['status'] == CapitalLog::STATUS_WAIT_SEND) { $frozenList[] = $item; } } return $frozenList; } /** * 检查数字币是否已结算 * * @param array $orderDetailsIds */ protected function checkDigital(array $orderDetailsIds) { $digitalCount = DigitalLog::find() ->where([ 'source_table' => $this->getOrderDetailsTable(), 'source_table_id' => $orderDetailsIds, 'from_type' => AgentEnum::ADDONS_NAME, 'send_status' => DigitalLog::SEND_STATUS_NORMAL ]) ->count(); if ($digitalCount) { throw new RuntimeException('当前订单已存在已结算数据,不允许重新分配'); } } /** * 查看延迟结算表是否已结算,或者已经到了结算的时间 * * @param string $orderNo * * @return void */ protected function checkDelayLog(string $orderNo) { $sendCount = AgentDelayLog::find() ->where([ 'wallet_type' => ['commission', 'score', 'digital'], 'order_no' => $orderNo, 'mall_id' => $this->mall_id, 'status' => CapitalLog::STATUS_SEND ]) ->count(); if ($sendCount) { throw new RuntimeException('当前订单已存在已结算数据,不允许重新分配'); } $delayLog = AgentDelayLog::find() ->where([ 'wallet_type' => ['commission', 'score', 'digital'], 'order_no' => $orderNo, 'mall_id' => $this->mall_id ]) ->groupBy('wallet_type') ->select('min(day_num) day_num, min(created_at) created_at') ->all(); if (empty($delayLog)) { return; } foreach ($delayLog as $item) { if ($item['day_num'] * 24 * 3600 + $item['created_at'] <= time() - 60) { throw new RuntimeException('当前订单正在结算或已结算,不允许重新分配'); } } } /** * 将冻结数据置为失效(积分,佣金) * * @return void */ protected function disableFrozenCommissionOrScore(array $orderDetailsIds, string $wallet_type) { $params = [ 'where' => [ [ 'source_table' => $this->getOrderDetailsTable(), 'source_table_id' => $orderDetailsIds, 'from_type' => AgentEnum::ADDONS_NAME, 'status' => CapitalLog::STATUS_WAIT_SEND ] ] ]; CapitalLog::$capitalType = "{$wallet_type}_frozen"; $list = CapitalLog::lists($params); if ($list) { foreach ($list as $item) { UserWalletService::unfrozen($item['id'], $wallet_type, false); } } } /** * 将冻结数据置为失效(数字币) * * @return void */ protected function disableFrozenDigital(array $orderDetailsIds) { DigitalLog::updateAll( [ 'send_status' => DigitalLog::SEND_STATUS_NORMAL, 'status' => StatusEnum::DELETE, 'updated_at' => time() ], [ 'source_table' => $this->getOrderDetailsTable(), 'source_table_id' => $orderDetailsIds, 'from_type' => AgentEnum::ADDONS_NAME, 'send_status' => DigitalLog::SEND_STATUS_FROZEN ] ); } /** * 将佣金和积分禁用(不处理数字币) * * @return void */ protected function disableAgentDelayLog(array $orderDetailsIds) { AgentDelayLog::updateAll( [ 'status' => StatusEnum::DELETE, 'updated_at' => time() ], [ 'wallet_type' => ['commission', 'score'], 'mall_id' => $this->mall_id, 'status' => CapitalLog::STATUS_WAIT_SEND, 'source_table' => $this->getOrderDetailsTable(), 'source_table_id' => $orderDetailsIds, ] ); } /** * 禁用供应商收入的数据 * * @return void */ protected function disableAgentSupplierCommission(array $orderDetailsIds) { AgentSupplierCommission::updateAll( [ 'status' => StatusEnum::DELETE, 'updated_at' => time() ], [ 'mall_id' => $this->mall_id, 'status' => StatusEnum::ENABLED, 'source_table' => $this->getOrderDetailsTable(), 'source_table_id' => $orderDetailsIds, ] ); } /** * @return array */ protected function getOrderDetailsTable(): array { return ['order_detail', OrderDetail::tableName()]; } public function reward($order, $orderDetailsIds){ $mall_id = $order['mall_id']; $order_id = $order['id']; $user_id = $order['user_id']; $setting = \Yii::$app->services->setting->addons->get($mall_id, AgentEnum::ADDONS_NAME, 'basic'); if (empty($setting['is_enable'])) throw new \yii\db\Exception('没开启经销商'); $params = []; $params['where'] = [['order_id' => $order_id], ['user_id' => $user_id], ['mall_id' => $mall_id], ['id' => $orderDetailsIds]]; $order_detail_list = OrderDetail::lists($params); if (empty($order_detail_list)) throw new \yii\db\Exception('订单详情不存在'); $is_self_buy = $setting['is_self_buy'];// 经销商内购 $enable_repurchase_reward = $setting['enable_repurchase_reward'] ?? StatusEnum::DISABLED;// 复购等于报单 - 需要判断当前用户是否有支付过的订单 if ($enable_repurchase_reward) { $enable_repurchase_reward = Order::find() ->where(['user_id' => $user_id]) ->andWhere(['mall_id' => $mall_id]) ->andWhere(['<>', 'id', $order_id]) ->andWhere(['pay_status' => StatusEnum::ENABLED]) ->count() > 0 ? StatusEnum::ENABLED : StatusEnum::DISABLED; } $parent_id_arr = UserPartitionRelationship::getParentIdArr($user_id); $parent_id_arr = array_reverse($parent_id_arr); $where = ['user_id' => $parent_id_arr, 'mall_id' => $mall_id, 'status' => StatusEnum::ENABLED]; $addons_agent_list = Agent::find()->where($where)->indexBy('user_id')->all();//查询经销商列表 $agent_list = []; foreach ($parent_id_arr as $parent_id) { if (!empty($addons_agent_list[$parent_id])) $agent_list[] = $addons_agent_list[$parent_id];//按照关系排序 } $agent = Agent::findOne(['user_id' => $user_id, 'mall_id' => $mall_id, 'status' => StatusEnum::ENABLED]);// 查询购买者身份 $reward_detail = $this->unshiftAgentList($is_self_buy, $enable_repurchase_reward, $agent_list, $order_detail_list, $agent); $commission_arr = []; $is_settle_additional_score = StatusEnum::DISABLED; if (MallAddons::isInstall($mall_id, AddonsEnum::ADDONS_NAME_POINT_UPPER_LIMIT)) { $is_settle_additional_score = (new SettingService())->isEnable($mall_id); } $insert_wallet_data = []; foreach ($order_detail_list as $order_detail) { // 如果是针对商品的,那么就判断 // 检测商品是否参与了渠道分红 [$agent_list, $self_buy_user_id, $enable_repurchase_reward] = $reward_detail[$order_detail['id']]; $item_setting = AgentCommissionItemSetting::find()->select('item_id,is_participate')->where(['item_id' => $order_detail['goods_id'], 'status' => StatusEnum::ENABLED])->asArray()->one(); if (!empty($item_setting) && empty($item_setting['is_participate'])) continue; $agent_reward_obj = new AgentReward($mall_id, $user_id, $setting, $agent_list, $self_buy_user_id, $enable_repurchase_reward); $order_detail['order_no'] = $order['order_no']; $agent_reward_obj->order_detail = $order_detail; $commission_arr[$order_detail['id']][AgentEnum::ADDONS_NAME]['commission'] = $agent_reward_obj->addFrozenCommission(); $insert_wallet_data = array_merge($insert_wallet_data, $agent_reward_obj->insert_wallet); $agent_reward_obj = new AgentReward($mall_id, $user_id, $setting, $agent_list, $self_buy_user_id, $enable_repurchase_reward, 'score'); $agent_reward_obj->order_detail = $order_detail; $agent_reward_obj->addFrozenCommission(); $insert_wallet_data = array_merge($insert_wallet_data, $agent_reward_obj->insert_wallet); //数字币赠送 (数字币不处理) /*$agent_reward_obj = new AgentReward($mall_id, $user_id, $setting, $agent_list, $self_buy_user_id, $enable_repurchase_reward, 'digital'); $agent_reward_obj->order_detail = $order_detail; $agent_reward_obj->addFrozenCommission(); $insert_wallet_data = array_merge($insert_wallet_data, $agent_reward_obj->insert_wallet);*/ // 额外积分 - 需要判断是否开启 if (!empty($is_settle_additional_score)) { // 判断当前用户是否已经超出上限, 只有有额度的情况下才需要进行处理 // if ((new UserService())->getUserQuota($mall_id, $user_id) > 0) { $agent_reward_obj = new AgentReward($mall_id, $user_id, $setting, $agent_list, $self_buy_user_id, $enable_repurchase_reward, 'additional_score'); $agent_reward_obj->order_detail = $order_detail; $agent_reward_obj->addFrozenCommission(); // } } } /* * TODO: 渠道分红延时结算/解冻资产 * 结算方式为“订单完成后”并且“延时结算天数”不为0时执行延时结算 */ if (isset($setting['compute_type']) && isset($setting['compute_delay_day']) && !empty($setting['compute_type']) && !empty($setting['compute_delay_day'])) { $delay_logs_data = []; // TODO: 渠道分红延时结算 - 需要延时解冻数据 foreach ($insert_wallet_data as $item) { $delay_logs_data[] = [ 'mall_id' => $mall_id, 'user_id' => $item['user_id'], 'wallet_type' => $item['wallet_type'], 'wallet_num' => $item['money'], 'compute_type' => $setting['compute_type'], 'day_num' => $setting['compute_delay_day'], 'wallet_desc' => $item['desc'], 'order_no' => $item['order_no'], 'capital_type' => $item['capital_type'], 'contributor_name' => $item['contributor_name'], 'contributor_money' => $item['contributor_money'], 'contributor_id' => $item['contributor_id'], 'source_table' => $item['source_table'], 'source_table_id' => $item['source_table_id'], ]; } // 写入延时结算日志 AgentDelayLog::batchSave($delay_logs_data); } $this->addOrderLog($order,$commission_arr); return true; } /** * 添加订单 * * @param $order * @param $commission_arr * * @throws Exception */ public function addOrderLog($order,$commission_arr) { $total_commission = 0; foreach ($commission_arr as $order_detail_id => $commission) { $total_commission += $commission['commission'] ?? ($commission['Agent']['commission'] ?? 0); } $agent = Agent::findOne(['mall_id' => $order->mall_id,'user_id' => $order->user_id]); // 将旧的禁用 AgentCommissionDetails::updateAll( [ 'status' => StatusEnum::DELETE, 'updated_at' => time() ], [ 'mall_id' => $order->mall_id, 'order_id' => $order->id, 'user_id' => $order->user_id, 'agent_id' => $agent->id ?? 0, ] ); $data = [ 'mall_id' => $order->mall_id, 'order_id' => $order->id, 'user_id' => $order->user_id, 'agent_id' => $agent->id ?? 0, 'level' => $agent->level ?? 0, 'order_price' => $order->pay_money, 'commission' => $total_commission, 'order_source' => 'order', ]; $res = AgentCommissionDetails::setData($data); if(!$res) throw new Exception(AgentCommissionDetails::getStaticError()); } /** * 针对每一款商品的设置 * @param int $is_self_buy * @param int $enable_repurchase_reward * @param array $agent_list * @param array $orders * @param Agent|null $agent * @return array */ protected function unshiftAgentList(int $is_self_buy, int $enable_repurchase_reward, array $agent_list, array $orders, Agent $agent = null): array { $data = []; foreach ($orders as $order_detail) { // 独立设置了 $data[$order_detail['id']][0] = $agent_list; // agent_list $data[$order_detail['id']][1] = StatusEnum::DISABLED; // self_buy_user_id $data[$order_detail['id']][2] = StatusEnum::DISABLED; // enable_repurchase_reward if (!empty($agent)) { $order_detail_enable_repurchase_reward = $enable_repurchase_reward; $is_alone_setting = AgentGoodsRepurchase::isAloneSetting($order_detail['mall_id'], $order_detail['goods_id']); if ($is_alone_setting) { // 单独设置 那么就需要判断之前是否有购买过当前商品 $order_detail_enable_repurchase_reward = AgentGoodsRepurchase::isBuyCurrentGoods($order_detail['mall_id'], $order_detail['user_id'], $order_detail['order_id'], $order_detail['goods_id']) ? StatusEnum::ENABLED : StatusEnum::DISABLED; } //独立设置内购 $item_setting = AgentCommissionItemSetting::find()->select('item_id,is_participate,is_self_buy_alone,is_self_buy,enable_goods_deduct')->where(['item_id' => $order_detail['goods_id'], 'status' => StatusEnum::ENABLED])->asArray()->one(); if (!empty($item_setting) && !empty($item_setting['is_participate']) && !empty($item_setting['is_self_buy_alone'])){ $is_self_buy_detail = $item_setting['is_self_buy']; }else{ $is_self_buy_detail = $is_self_buy; } if ($is_self_buy_detail || $order_detail_enable_repurchase_reward) { array_unshift($data[$order_detail['id']][0], $agent); $data[$order_detail['id']][1] = $agent->user_id; $data[$order_detail['id']][2] = StatusEnum::ENABLED; } } } return $data; } /** * 将冻结的数据组装成$insert_wallet * * @return array */ protected function frozenDataToInsertWallet(array $frozenCommissionList, array $frozenScoreList) { foreach ($frozenCommissionList as &$item) { $item['wallet_type'] = 'commission'; $item['is_frozen'] = true; $item['money'] = $item['change_num']; } foreach ($frozenScoreList as &$item) { $item['wallet_type'] = 'score'; $item['is_frozen'] = true; $item['money'] = $item['change_num']; } return array_merge($frozenCommissionList, $frozenScoreList); } protected function getCommissionNameMap(): array { return [ 'additional_score' => 'score' ]; } /** * 将供应商订单数据扣回,因为原来写入时同一个订单是累加的,所以为了兼容纠错只选择单个order_detail的情况下只能扣回,不能将原数据删除 * * @param $orderDetailsIds * * @return void */ private function disableAgentSupplierOrder($orderDetailsIds) { $wallet_type = 'commission'; CapitalLog::$capitalType = "{$wallet_type}_frozen"; $where = [ [ 'source_table' => $this->getOrderDetailsTable(), 'source_table_id' => $orderDetailsIds, 'from_type' => AgentEnum::ADDONS_NAME, 'status' => StatusEnum::DISABLED, 'change_type' => 'add', 'mall_id' => $this->mall_id ] ]; $commissionList = CapitalLog::lists([ 'where' => $where, 'select' => 'change_num, user_id, source_table_id, order_no' ]); // 得到购买数量 $orderDetails = OrderDetail::find() ->where([ 'id' => $orderDetailsIds, 'status' => StatusEnum::ENABLED, 'mall_id' => $this->mall_id ]) ->indexBy('id') ->all(); $setting = \Yii::$app->services->setting->addons->get($this->mall_id, AgentEnum::ADDONS_NAME, 'basic'); $agent_reward_obj = new AgentReward($this->mall_id, 0, $setting, [], 0, 0, ''); foreach ($commissionList as $commissionItem) { $model = AgentSupplierOrder::find() ->where([ 'seller_user_id' => $commissionItem['user_id'], 'order_no' => $commissionItem['order_no'], 'status' => StatusEnum::ENABLED ]) ->one(); if (!$model) { continue; } if (empty($orderDetails[$commissionItem['source_table_id']])) { continue; } $agent_reward_obj->order_detail = $orderDetails[$commissionItem['source_table_id']]; ['money' => $money] = $agent_reward_obj->getRules(); $model->payment_amount -= $money; // getRule得到 $model->profit -= $commissionItem['change_num']; // 佣金 $model->goods_nums -= $orderDetails[$commissionItem['source_table_id']]->num; $model->stock_nums -= $orderDetails[$commissionItem['source_table_id']]->num; $model->payment_amount = $model->payment_amount < 0 ? 0 : $model->payment_amount; $model->profit = $model->profit < 0 ? 0 : $model->profit; $model->goods_nums = $model->goods_nums < 0 ? 0 : $model->goods_nums; $model->stock_nums = $model->stock_nums < 0 ? 0 : $model->stock_nums; if ( $model->payment_amount == 0 && $model->profit == 0 && $model->goods_nums == 0 && $model->stock_nums == 0 ) { $model->status = StatusEnum::DELETE; } $model->save(); } } }