DeductionLogic.php 71 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343
  1. <?php
  2. namespace addons\CloudStock\common\logic\deduction;
  3. use addons\CloudStock\common\enums\CloudStockEnum;
  4. use addons\CloudStock\common\events\order\FillEvent;
  5. use addons\CloudStock\common\events\order\FillEventB;
  6. use addons\CloudStock\common\logic\addons\Boss\RewardLogLogic;
  7. use addons\CloudStock\common\logic\reward\EqualReward;
  8. use addons\CloudStock\common\logic\reward\OverReward;
  9. use addons\CloudStock\common\logic\reward\PoolReward;
  10. use addons\CloudStock\common\models\CloudStockAgent;
  11. use addons\CloudStock\common\models\CloudStockAgentGoods;
  12. use addons\CloudStock\common\models\CloudStockDeductionDetail;
  13. use addons\CloudStock\common\models\CloudStockFillOrder;
  14. use addons\CloudStock\common\models\CloudStockGoods;
  15. use addons\CloudStock\common\models\CloudStockPriceDifferenceGiftPackage;
  16. use addons\CloudStock\common\models\CloudStockPriceDifferenceOrder;
  17. use addons\CloudStock\common\models\CloudStockPriceDifferenceOrderDetail;
  18. use addons\CloudStock\common\models\CloudStockPushDelayLog;
  19. use addons\CloudStock\common\services\CloudStockPriceDifferenceGiftPackageOrderService;
  20. use addons\CloudStock\common\services\CloudStockPriceDifferenceUserTeamStatisticsService;
  21. use addons\CloudStock\common\services\EqualAwardService;
  22. use addons\CloudStock\common\services\LossAmountService;
  23. use addons\CloudStock\common\services\PaymentLogService;
  24. use addons\CloudStock\common\services\PriceDifferenceProfitService;
  25. use addons\CloudStock\common\sms\SmsConfig;
  26. use addons\CloudStock\common\sms\TimeLimitFillMessage;
  27. use addons\CloudStock\common\events\order\CloudStockChangeEvent;
  28. use addons\CloudStock\common\models\CloudStockLevel;
  29. use addons\CloudStock\common\events\order\FillDeductByPlatformEvent;
  30. use common\enums\AddonsEnum;
  31. use common\enums\OrderStatusEnum;
  32. use common\enums\RabbitMqEnum;
  33. use common\enums\StatusEnum;
  34. use common\enums\UserWalletEnum;
  35. use common\helpers\BcHelper;
  36. use common\helpers\sms\Sms;
  37. use common\models\goods\Goods;
  38. use common\models\mall\MallAddons;
  39. use common\models\order\Order;
  40. use common\models\order\OrderDetail;
  41. use common\models\user\User;
  42. use common\models\user\UserPartitionRelationship;
  43. use Overtrue\EasySms\EasySms;
  44. use Overtrue\EasySms\Exceptions\NoGatewayAvailableException;
  45. use services\common\UserWalletService;
  46. use yii\db\Exception;
  47. abstract class DeductionLogic
  48. {
  49. public $order_type;//会员订单还是补货订单
  50. protected $user_id; //买货会员用户id,补货用户id
  51. protected $goods_id; //商品id
  52. protected $parent_agent; //上级代理商对象 类型:StockAgent
  53. protected $mall_id; //商城id
  54. protected $not_yet_num;//剩余未扣库存数量;
  55. protected $stock_log_id;//库存变动记录表id
  56. protected $unit_goods_price; //货款单价
  57. protected $stock_goods;//库存商品
  58. protected $order;//订单模型model
  59. protected $changes_desc;//资金变动描述
  60. protected $changes_type;//资金变动类型
  61. protected $bonus_over_changes_type; //平级奖资金变动类型
  62. protected $bonus_over_changes_desc; //平级奖资金变动描述
  63. protected $bonus_equal_changes_type; //越级奖资金变动类型
  64. protected $bonus_equal_changes_desc; //越级奖资金变动描述
  65. protected $is_frozen = 0; //收益是否结算;
  66. protected $is_time_limit_fill; //是否开启限时补货
  67. protected $fill_hour = 0; //限时补货小时数
  68. protected $time_limit_fill_user_ids = []; //执行过限时补货的代理商用户id,防止重复
  69. protected $is_job;
  70. protected $user;
  71. protected $stock_log;
  72. public $user_agent_level = null;
  73. public $fill_insert_wallet = [];
  74. public $payment_insert_wallet = [];//云仓货款
  75. public $total_price_difference = 0;
  76. public $order_no = '';
  77. public $store_id = 0;
  78. public $event_arr = [];
  79. public $recommend_reward_arr = [];
  80. public $not_get_price_difference = 0;
  81. public $not_distribute_payment_for_goods = 0;
  82. public $configs;
  83. public function __construct($user, $user_parent_agent, $stock_log, $order, $not_yet_num, $time_limit_fill_user_ids = [], $is_job = 0)
  84. {
  85. $this->user_id = $user->id;
  86. $this->parent_agent = $user_parent_agent;
  87. $this->order = $order;
  88. $this->goods_id = $order['goods_id'];
  89. $this->not_yet_num = $not_yet_num;
  90. $this->mall_id = $order['mall_id'];
  91. $this->stock_log_id = $stock_log['id'];
  92. $this->stock_log = $stock_log;
  93. $this->time_limit_fill_user_ids = $time_limit_fill_user_ids;
  94. $this->is_job = $is_job;
  95. $this->user = $user;
  96. //库存商品模型对象
  97. $this->getStockGoods();
  98. //定义资金变动类型和描述
  99. $this->getChangesType();
  100. //获取限时补货配置
  101. $this->getIsTimeLimitFill();
  102. //获取会员买货扣分润后货款商品单价
  103. $this->getUnitGoodsPrice();
  104. }
  105. /**
  106. * 获取商品货款单价
  107. * @return mixed
  108. */
  109. protected abstract function getUnitGoodsPrice();
  110. /**
  111. * 获取库存商品
  112. */
  113. protected function getStockGoods()
  114. {
  115. //库存商品奖励配置
  116. $this->stock_goods = CloudStockGoods::findOne(['goods_id' => $this->goods_id, 'mall_id' => $this->mall_id, 'status' => StatusEnum::ENABLED]);
  117. }
  118. /**
  119. * 定义资金变动类型和描述
  120. */
  121. protected function getChangesType()
  122. {
  123. if ($this->order_type == 'buying') {
  124. $this->changes_type = CloudStockEnum::STOCK_CHANGE_TYPE102;
  125. $this->changes_desc = "会员买货货款收益";
  126. $this->bonus_over_changes_type = CloudStockEnum::CHANGE_TYPE_INCREASE_GOODS_BUY_OVER_BONUS;
  127. $this->bonus_over_changes_desc = "会员买货越级奖发放";
  128. $this->bonus_equal_changes_type = CloudStockEnum::CHANGE_TYPE_INCREASE_GOODS_BUY_EQUAL_BONUS;
  129. $this->bonus_equal_changes_desc = "会员买货平级奖发放";
  130. } elseif ($this->order_type == 'fill') {
  131. $this->changes_type = CloudStockEnum::CHANGE_TYPE_INCREASE_FILL_PAYMENT;
  132. $this->changes_desc = "下级补货货款收益";
  133. $this->bonus_over_changes_type = CloudStockEnum::CHANGE_TYPE_INCREASE_FILL_OVER_BONUS;
  134. $this->bonus_over_changes_desc = "下级补货越级奖发放";
  135. $this->bonus_equal_changes_type = CloudStockEnum::CHANGE_TYPE_INCREASE_FILL_EQUAL_BONUS;
  136. $this->bonus_equal_changes_desc = "下级补货平级奖发放";
  137. }
  138. }
  139. /**
  140. * 获取限时补货配置
  141. * @return int|mixed
  142. */
  143. protected function getIsTimeLimitFill()
  144. {
  145. $configs = \Yii::$app->services->setting->addons->get($this->mall_id, AddonsEnum::ADDONS_NAME_CLOUD_STOCK, 'basic');
  146. $this->is_time_limit_fill = isset($configs['is_time_limit_fill']) ? $configs['is_time_limit_fill'] : 0;
  147. $this->fill_hour = isset($configs['fill_hour']) ? $configs['fill_hour'] : 0;
  148. }
  149. ///平一级
  150. public function equalOne($agent, $direct_agent, $stock_level, $over_desc, $equal_desc, $num, $setting = [])
  151. {
  152. switch (true) {
  153. case $agent['level'] > $direct_agent['level']:
  154. //越级奖
  155. $this->sendOverReward($direct_agent, $stock_level, 1, $over_desc, $num, !empty($setting['is_by_buy_agent_level']), $agent['level']);
  156. break;
  157. case $agent['level'] == $direct_agent['level']:
  158. //平级奖
  159. $this->sendEqualReward($direct_agent, $stock_level, 1, $equal_desc, $num);
  160. break;
  161. default:
  162. }
  163. }
  164. //发放平级奖励
  165. public function sendEqualReward($parent_user_agent, $stock_level, $equal_level, $equal_desc, $num)
  166. {
  167. //该代理商等级是否开启平级奖
  168. if (empty($stock_level['is_equal'])) return $this->unit_goods_price;
  169. $setting = \Yii::$app->services->setting->addons->get($this->mall_id, AddonsEnum::ADDONS_NAME_CLOUD_STOCK, 'basic');
  170. $is_frozen = true;
  171. if (empty($setting['settlement_cycle_of_equal_prize'])) {
  172. $is_frozen = false;//平级奖结算周期:立即结算
  173. }
  174. $obj = new EqualReward(
  175. $parent_user_agent,
  176. $this->stock_goods,
  177. $this->unit_goods_price,
  178. $this->order['id'],
  179. $num,
  180. $is_frozen,
  181. $this->bonus_equal_changes_type,
  182. $equal_desc,
  183. $this->is_job
  184. );
  185. $obj->equal_level = $equal_level;
  186. $count_bonus_money = $obj->sendReward();
  187. $this->unit_goods_price = 0;
  188. if ($count_bonus_money > 0) $this->unit_goods_price = BcHelper::floorFloat($count_bonus_money / $num);
  189. }
  190. //发放越级奖励
  191. public function sendOverReward($parent_user_agent, $stock_level, $over_level, $over_desc, $num, $is_by_buy_agent_level = false, $buy_level = 0)
  192. {
  193. if (empty($stock_level['is_over'])) return $this->unit_goods_price;
  194. $obj = new OverReward(
  195. $parent_user_agent,
  196. $this->stock_goods,
  197. $this->unit_goods_price,
  198. $this->order['id'],
  199. $num,
  200. $this->is_frozen,
  201. $this->order,
  202. $over_desc,
  203. $this->is_job
  204. );
  205. $obj->over_level = $over_level;
  206. $obj->buy_level = $buy_level;
  207. $obj->is_by_buy_agent_level = $is_by_buy_agent_level;
  208. $count_bonus_money = $obj->sendReward();
  209. $this->unit_goods_price = 0;
  210. if ($count_bonus_money > 0) $this->unit_goods_price = BcHelper::floorFloat($count_bonus_money / $this->order['num']);
  211. }
  212. /**
  213. * 价差礼包推荐奖励
  214. * @return true|void
  215. */
  216. protected function computeRecommendReward()
  217. {
  218. $obj = new CloudStockPriceDifferenceGiftPackageOrderService(['mall_id' => $this->order['mall_id'], 'user_id' => $this->order['user_id']]);
  219. $order = CloudStockPriceDifferenceOrder::getOne([['id' => $this->order['price_difference_order_id']]], true, ['detail']);
  220. if (empty($order)) {
  221. return true;
  222. }
  223. $package = CloudStockPriceDifferenceGiftPackage::find()->where(['id' => $order['price_difference_gift_package_id']])->one();
  224. $order_detail_arr = array_column($order['detail'], null, 'id');
  225. $data = [
  226. 'user_id' => $this->order['user_id'],
  227. 'mall_id' => $this->order['mall_id'],
  228. 'id' => $this->order['id'],
  229. 'order_no' => $this->order['order_no'],
  230. 'pay_money' => $order_detail_arr[$this->order['price_difference_order_detail_id']]['goods_price'] ?? 0,
  231. ];
  232. $this->recommend_reward_arr = $obj->recommendReward($data, $package);
  233. $this->not_get_price_difference = $package['not_get_price_difference'] ?? 0;
  234. $this->not_distribute_payment_for_goods = $package['not_distribute_payment_for_goods'] ?? 0;
  235. }
  236. protected function sendRecommendReward($recommend_reward_arr)
  237. {
  238. if (!empty($recommend_reward_arr)) {
  239. if (!empty($this->order['price_difference_order_detail_id'])) {
  240. $price_difference_order_detail = CloudStockPriceDifferenceOrderDetail::findOne(['id' => $this->order['price_difference_order_detail_id']]);
  241. }
  242. if ($this->not_distribute_payment_for_goods) {
  243. $res = UserWalletService::batchHandleByQueue($recommend_reward_arr);
  244. if (empty($res)) throw new \Exception(UserWalletService::getStaticError());
  245. } else {
  246. if (empty($price_difference_order_detail['is_send_recommend_reward'])) {
  247. $res = UserWalletService::batchHandleByQueue($recommend_reward_arr);
  248. if (empty($res)) throw new \Exception(UserWalletService::getStaticError());
  249. CloudStockPriceDifferenceOrderDetail::updateAll(['is_send_recommend_reward' => 1], ['id' => $this->order['price_difference_order_detail_id']]);
  250. }
  251. }
  252. // if (isset($price_difference_order_detail)) {
  253. // }
  254. }
  255. }
  256. public function deduct()
  257. {
  258. //没有上级代理商,直接扣平台的;
  259. $configs = \Yii::$app->services->setting->addons->get($this->mall_id, AddonsEnum::ADDONS_NAME_CLOUD_STOCK, 'basic');
  260. $this->configs = $configs;
  261. if ($this->order_type == 'fill' && !empty($this->order['price_difference_order_id']) && !empty($configs['fill_price_difference'])) {
  262. $this->computeRecommendReward();
  263. }
  264. if (isset($this->order['order_no']) && strpos($this->order['order_no'], 'CSFL') !== false) {
  265. $this->stock_log['changes_type'] = CloudStockEnum::STOCK_CHANGE_TYPE105;
  266. }
  267. if (empty($this->parent_agent)) {
  268. $nums = $this->not_yet_num;
  269. $params = [
  270. 'stock_log_id' => $this->stock_log_id,
  271. 'user_id' => 0,
  272. 'num' => $this->not_yet_num,
  273. 'not_yet_num' => 0,
  274. 'order_type' => $this->order_type == 'fill' ? CloudStockEnum::STOCK_ORDER_TYPE_REPLENISH : CloudStockEnum::STOCK_ORDER_TYPE_USER,
  275. 'changes_type' => $this->stock_log['changes_type'],
  276. 'order_id' => $this->stock_log['order_id'],
  277. 'goods_id' => $this->goods_id,
  278. 'mall_id' => $this->mall_id,
  279. ];
  280. $res = CloudStockDeductionDetail::setData($params);
  281. $this->not_yet_num = 0;
  282. if ($res == false) throw new \Exception(CloudStockDeductionDetail::getStaticError());
  283. $this->sendRecommendReward($this->recommend_reward_arr);
  284. //触发库存变动事件
  285. $event = new CloudStockChangeEvent($this->mall_id);
  286. $event_data = [
  287. 'id' => $res->id,
  288. 'type' => CloudStockEnum::STOCK_CHANGE_SUB,
  289. 'mall_id' => $this->mall_id,
  290. ];
  291. \Yii::$app->services->events->dispatch($event, $event_data, $event->listeners);
  292. $this->event_arr[] = [
  293. 'id' => $res->id,
  294. 'type' => CloudStockEnum::STOCK_CHANGE_SUB,
  295. 'mall_id' => $this->mall_id,
  296. ];
  297. $is_install = MallAddons::isInstall($this->mall_id, AddonsEnum::ADDONS_NAME_ACHIEVEMENT);
  298. $is_install_b = MallAddons::isInstall($this->mall_id, AddonsEnum::ADDONS_NAME_ACHIEVEMENT_B);
  299. if ($this->order_type == 'fill') {
  300. if ($is_install) $this->triggerAchievement($params);
  301. if ($is_install_b) $this->triggerAchievementB($params);
  302. $this->triggerStatistics($params);
  303. $fill_unit_price = bcdiv($this->order['pay_money'], $this->order['num'], 2);
  304. var_dump('投入分红池,进货价:' . $fill_unit_price);
  305. PoolReward::inPool($this->mall_id, $this->goods_id, $nums, $fill_unit_price);
  306. $order_type = 2;
  307. } else {
  308. $orderDetail = OrderDetail::findOne($this->order['order_detail_id']);
  309. $fill_unit_price = bcdiv($orderDetail['goods_price'], $orderDetail['num'], 2);
  310. $order_type = 1;
  311. if ($is_install) {
  312. $statisticalMethods = \Yii::$app->services->setting->addons->get($this->mall_id, AddonsEnum::ADDONS_NAME_ACHIEVEMENT, 'basic.statistical_methods', true);
  313. if ($statisticalMethods) { // 业绩奖励,业绩统计方式 = 1(支付完成),当订单支付后,直接触发
  314. $this->triggerAchievement($params);
  315. } else { // 业绩奖励,业绩统计方式 = 0 (订单完成),但订单完成后,需要判断订单是不是真的完成,才去触发
  316. if ($orderDetail['order_status'] == OrderStatusEnum::ACCOMPLISH) {
  317. $this->triggerAchievement($params);
  318. }
  319. }
  320. }
  321. var_dump($is_install_b . '========');
  322. if ($is_install_b) {
  323. $statisticalMethods = \Yii::$app->services->setting->addons->get($this->mall_id, AddonsEnum::ADDONS_NAME_ACHIEVEMENT_B, 'basic.statistical_methods', true);
  324. if ($statisticalMethods) { // 业绩奖励,业绩统计方式 = 1(支付完成),当订单支付后,直接触发
  325. $this->triggerAchievementB($params);
  326. } else { // 业绩奖励,业绩统计方式 = 0 (订单完成),但订单完成后,需要判断订单是不是真的完成,才去触发
  327. if ($orderDetail['order_status'] == OrderStatusEnum::ACCOMPLISH) {
  328. $this->triggerAchievementB($params);
  329. }
  330. }
  331. }
  332. }
  333. $fillDeductByPlatformEvent = new FillDeductByPlatformEvent($this->mall_id);
  334. $fillDeductByPlatformData = [
  335. 'order_id' => $this->order['id'],
  336. 'changes_type' => $this->stock_log['changes_type'],
  337. 'user_id' => $this->user_id,
  338. 'mall_id' => $this->mall_id,
  339. 'goods_id' => $this->goods_id,
  340. 'num' => $nums,
  341. 'fill_unit_price' => $fill_unit_price,
  342. 'order_type' => $order_type,
  343. ];
  344. \Yii::$app->services->events->dispatch($fillDeductByPlatformEvent, $fillDeductByPlatformData, $fillDeductByPlatformEvent->listeners);
  345. if (!empty($configs['is_sync_boss_bonus']) && $this->order_type == 'fill') {
  346. //云库存增加股东分红(云库存补货订单,扣平台库存)
  347. $post_data = [
  348. 'id' => $this->order['id'],
  349. 'mall_id' => $this->order['mall_id'],
  350. 'user_id' => $this->order['user_id'],
  351. 'order_no' => $this->order_no,
  352. 'goods_id' => $this->order['goods_id'],
  353. 'pay_money' => bcmul($this->unit_goods_price, $nums, 2),
  354. 'num' => $nums,
  355. ];
  356. \Yii::$app->services->rabbitMq->push(RabbitMqEnum::EXCHANGE_TASK, RabbitMqEnum::TASK_QUEUE, $post_data, RewardLogLogic::class, 'handleSync');
  357. }
  358. return true;
  359. }
  360. $parent_agent_goods = CloudStockAgentGoods::findOne(['mall_id' => $this->mall_id, 'user_id' => $this->parent_agent->user_id, 'goods_id' => $this->goods_id, 'status' => StatusEnum::ENABLED]);
  361. //如果为买货订单,开启是否跳过等级不扣库存且上级库存不为空时
  362. if ($this->order_type == 'buying' && $configs['is_jump_level'] == 1 && !empty($parent_agent_goods)) {
  363. if (!empty($configs['jump_level'])) {
  364. $configs['jump_level'] = json_decode($configs['jump_level'], true);
  365. //判断用户是否在设置的等级内,是则上级代理库存赋值为空
  366. if (in_array($this->parent_agent->level, $configs['jump_level'])) {
  367. // $parent_agent_goods = [];
  368. $agent_user_id = $this->parent_agent->user_id;
  369. $level = $this->parent_agent->level;
  370. //没有开启限时补货或者下单人的上级代理商不存在,递归往上找,直到找平台扣库存
  371. $type = 2;
  372. if ($this->order_type == 'buying') {
  373. $type = 3;
  374. }
  375. (new LossAmountService(['mall_id' => $this->mall_id]))->compute($type, $this->not_yet_num, $this->order, $this->parent_agent);//补货、会员买货触发流失金额
  376. $parent_agent = CloudStockAgent::getUserParentAgent($agent_user_id, $level);
  377. $this->parent_agent = $parent_agent;
  378. return $this->deduct();
  379. }
  380. }
  381. }
  382. //价差礼包-产生的补货单、只能扣一个上级的库存
  383. if ($this->order_type == 'fill' && !empty($this->order['price_difference_order_id'])) {
  384. if (!empty($parent_agent_goods) && $parent_agent_goods['num'] < $this->order['num']) {
  385. if ($this->order_type == 'fill' && !empty($configs['fill_price_difference'])) {
  386. $this->sendPriceDifference($configs);
  387. return true;
  388. }
  389. if ($this->order_type == 'buying' && !empty($configs['buy_price_difference'])) {
  390. $this->sendPriceDifference($configs);
  391. return true;
  392. }
  393. return $this->deductOrJob();
  394. }
  395. }
  396. //代理商没有库存商品或者商品库存为0,递归找有库存的上级供应商扣减;
  397. if (empty($parent_agent_goods) || $parent_agent_goods->num == 0) {
  398. if ($this->order_type == 'fill' && !empty($configs['fill_price_difference'])) {
  399. $this->sendPriceDifference($configs);
  400. return true;
  401. }
  402. if ($this->order_type == 'buying' && !empty($configs['buy_price_difference'])) {
  403. $this->sendPriceDifference($configs);
  404. return true;
  405. }
  406. return $this->deductOrJob();
  407. } //代理商扣减库存,返回未扣库存数
  408. $agent_goods_deduct_not_yet_num = $this->agentGoodsDeduct($parent_agent_goods, $this->stock_log_id, $this->not_yet_num);
  409. CloudStockAgent::fixStock($this->mall_id, $this->parent_agent['user_id']);
  410. if (empty($agent_goods_deduct_not_yet_num)) {
  411. //代理商上级够库存给下级扣减
  412. return true;
  413. } else {
  414. //代理商上级不够库存,给下级扣减
  415. $this->not_yet_num = $agent_goods_deduct_not_yet_num;
  416. if ($this->order_type == 'fill' && !empty($configs['fill_price_difference'])) {
  417. $this->sendPriceDifference($configs);
  418. return true;
  419. }
  420. if ($this->order_type == 'buying' && !empty($configs['buy_price_difference'])) {
  421. $this->sendPriceDifference($configs);
  422. return true;
  423. }
  424. }
  425. //未扣库存数大于0,递归找有库存的上级供应商扣减;
  426. if ($this->not_yet_num > 0) return $this->deductOrJob();
  427. return true;
  428. }
  429. protected function sendPriceDifference($configs, $diff_price = 0, $is_first = true, $price_difference = 0)
  430. {
  431. $price_difference_type = !empty($configs['price_difference_type']) ? $configs['price_difference_type'] : 0;
  432. var_dump("price_difference::{$price_difference}");
  433. $parent_agent_goods = CloudStockAgentGoods::findOne(['mall_id' => $this->mall_id, 'user_id' => $this->parent_agent->user_id, 'goods_id' => $this->goods_id, 'status' => StatusEnum::ENABLED]);
  434. if ($this->order_type == 'buying' && $configs['is_jump_level'] == 1 && !empty($parent_agent_goods)) {
  435. if (!empty($configs['jump_level'])) {
  436. if (!is_array($configs['jump_level'])) $configs['jump_level'] = json_decode($configs['jump_level'], true);
  437. //判断用户是否在设置的等级内,是则上级代理库存赋值为空
  438. if (in_array($this->parent_agent->level, $configs['jump_level'])) {
  439. $parent_agent_goods = [];
  440. }
  441. }
  442. }
  443. if ($price_difference_type == 2 && !empty($parent_agent_goods['num'])) {
  444. //需要校验,每个拿差价的库存
  445. $agent_goods_deduct_not_yet_num = $this->agentGoodsDeduct($parent_agent_goods, $this->stock_log_id, $this->not_yet_num, $price_difference, $is_first);
  446. if (empty($agent_goods_deduct_not_yet_num)) {
  447. //代理商上级够库存给下级扣减
  448. return true;
  449. }
  450. $this->not_yet_num = $agent_goods_deduct_not_yet_num;
  451. }
  452. $cloud_stock_goods = CloudStockGoods::findOne(['mall_id' => $this->mall_id, 'goods_id' => $this->goods_id, 'status' => StatusEnum::ENABLED]);
  453. if (empty($cloud_stock_goods)) return false;
  454. $agent_price_arr = json_decode($cloud_stock_goods['agent_price'], true);
  455. $price_arr = array_column($agent_price_arr, 'price', 'level');
  456. $parent_agent_level = $this->parent_agent->level;
  457. if (!isset($this->user_agent_level)) return false;
  458. $insert_wallet = [];
  459. if (empty($this->user_agent_level) || $is_first) {
  460. $user_agent_price = $this->unit_goods_price;
  461. } else {
  462. $user_agent_price = $price_arr[$this->user_agent_level] ?? 0;
  463. }
  464. // TODO: 云库存货款延时结算
  465. $commission_is_frozen = false;
  466. if (isset($configs['compute_delay_day']) && !empty($configs['compute_delay_day'])) {
  467. $commission_is_frozen = true;
  468. }
  469. if ($this->order_type == 'buying') {
  470. $source_table = OrderDetail::tableName();
  471. $source_table_id = $this->order['order_detail_id'];
  472. $desc = '会员买货时,无货拿进货差价';
  473. $capital_type = UserWalletEnum::CLOUD_STOCK_BUY_PRICE_DIFFERENCE;
  474. $is_frozen = true;
  475. // 判断结算方式,兼容无结算方式设置条件的客户,默认为"支付完成后"结算
  476. if (!$commission_is_frozen && (!isset($configs['compute_type']) || empty($configs['compute_type']))) {
  477. $commission_is_frozen = true;
  478. }
  479. } else {
  480. $source_table = CloudStockFillOrder::tableName();
  481. $source_table_id = $this->order['id'];
  482. $desc = '补货时,无货拿补货差价';
  483. $capital_type = UserWalletEnum::CLOUD_STOCK_FILL_PRICE_DIFFERENCE;
  484. $is_frozen = false;
  485. }
  486. $parent_agent_price = $price_arr[$parent_agent_level] ?? 0;
  487. $price_difference = $user_agent_price - $parent_agent_price;
  488. if ($price_difference <= 0) return false;
  489. $price_difference = $price_difference - $diff_price;
  490. if ($price_difference > 0) {
  491. $this->addPriceDifference($commission_is_frozen, $price_difference, $desc, $source_table, $source_table_id, $capital_type, $this->not_yet_num, $insert_wallet);
  492. }
  493. //差价平级奖
  494. $diff_price = 0;
  495. $stock_level = CloudStockLevel::findOne(['mall_id' => $this->mall_id, 'level' => $this->parent_agent->level, 'status' => StatusEnum::ENABLED]);
  496. if (!empty($configs['is_difference_equal']) && !empty($stock_level['is_equal'])) {
  497. $user = User::findOne($this->parent_agent->user_id);
  498. if (!empty($user['parent_id'])) {
  499. //紧凑平级奖
  500. $equal_level_list = $this->stock_goods['equal_level_list'] ? json_decode($this->stock_goods['equal_level_list'], true) : [];
  501. if (!empty($configs['is_find_equal'])) {
  502. $this->compactLevelingAward($this->parent_agent->user_id, $equal_level_list, $is_frozen, $desc, $source_table, $source_table_id, $diff_price, $insert_wallet);
  503. } else {
  504. $this->noCompactLevelingAward($user['parent_id'], $equal_level_list, $is_frozen, $desc, $source_table, $source_table_id, $diff_price, $insert_wallet);
  505. }
  506. }
  507. }
  508. if (!empty($insert_wallet)) {
  509. $res = UserWalletService::batchHandleByQueue($insert_wallet);
  510. if (!$res) return false;
  511. (new EqualAwardService(['mall_id' => $this->mall_id]))->setStatistics($insert_wallet, UserWalletEnum::EQUAL);
  512. }
  513. //所有代理拿差价
  514. if (!empty($price_difference_type)) {
  515. $agent_user_id = $this->parent_agent->user_id;
  516. $level = $this->parent_agent->level;
  517. $parent_agent = CloudStockAgent::getUserParentAgent($agent_user_id, $level);
  518. if ($parent_agent) {
  519. $this->user_agent_level = $this->parent_agent->level;
  520. $this->parent_agent = $parent_agent;
  521. $this->total_price_difference += $price_difference;
  522. $this->sendPriceDifference($configs, $diff_price, false, $this->total_price_difference);
  523. } else {
  524. $nums = $this->not_yet_num;
  525. $params = [
  526. 'stock_log_id' => $this->stock_log_id,
  527. 'user_id' => 0,
  528. 'order_type' => $this->order_type == 'fill' ? CloudStockEnum::STOCK_ORDER_TYPE_REPLENISH : CloudStockEnum::STOCK_ORDER_TYPE_USER,
  529. 'num' => $this->not_yet_num,
  530. 'not_yet_num' => 0,
  531. 'changes_type' => $this->stock_log['changes_type'],
  532. 'order_id' => $this->stock_log['order_id'],
  533. 'goods_id' => $this->goods_id,
  534. 'mall_id' => $this->mall_id,
  535. ];
  536. $res = CloudStockDeductionDetail::setData($params);
  537. $this->not_yet_num = 0;
  538. if ($res == false) throw new \Exception(CloudStockDeductionDetail::getStaticError());
  539. $is_install = MallAddons::isInstall($this->mall_id, AddonsEnum::ADDONS_NAME_ACHIEVEMENT);
  540. $is_install_b = MallAddons::isInstall($this->mall_id, AddonsEnum::ADDONS_NAME_ACHIEVEMENT_B);
  541. $params['deduction_detail_id'] = $res['id'];
  542. if ($is_install) $this->triggerAchievement($params);
  543. if ($is_install_b) $this->triggerAchievementB($params);
  544. if ($this->order_type == 'fill') {
  545. $fill_unit_price = bcdiv($this->order['pay_money'], $this->order['num'], 2);
  546. var_dump('投入分红池,进货价:' . $fill_unit_price);
  547. PoolReward::inPool($this->mall_id, $this->goods_id, $nums, $fill_unit_price);
  548. }
  549. //开启价差礼包-推荐奖励截止至货款获得者按钮
  550. if ($this->not_distribute_payment_for_goods) {
  551. foreach ($this->recommend_reward_arr as &$item) {
  552. $total_num = $this->order['num'];
  553. //重新计算佣金,当前扣除上级库存件数*每件可获取佣金
  554. $item['money'] = bcmul($item['money'] / $total_num, $params['num'], 2);
  555. $desc_array = explode(',', $item['desc']);
  556. $item['desc'] = $desc_array[0].','.$desc_array[1].','.$desc_array[2].',金额:'.$item['money'];
  557. }
  558. }
  559. $this->sendRecommendReward($this->recommend_reward_arr);
  560. return true;
  561. }
  562. }
  563. return true;
  564. }
  565. //紧凑平级奖
  566. public function compactLevelingAward($user_id, $equal_level_list, $is_frozen, $desc, $source_table, $source_table_id, &$diff_price, &$insert_wallet)
  567. {
  568. $agent = CloudStockAgent::findOne(['user_id' => $user_id, 'mall_id' => $this->mall_id, 'status' => StatusEnum::ENABLED]);
  569. $parent_id_arr = UserPartitionRelationship::getParentIdArr($user_id);
  570. $parent_id_arr = array_reverse($parent_id_arr);
  571. $is_find_equal = false;
  572. $diff_price = 0;
  573. foreach ($parent_id_arr as $pid) {
  574. $parent_agent = CloudStockAgent::findOne(['user_id' => $pid, 'mall_id' => $this->mall_id, 'status' => StatusEnum::ENABLED]);
  575. //找平级
  576. if (!empty($parent_agent) && empty($parent_agent['is_equal_award_restriction'])) {
  577. if ($parent_agent['level'] == $agent['level']) {
  578. if (!$is_find_equal) {
  579. $direct_agent_price = 0;
  580. foreach ($equal_level_list as $value) {
  581. if ($value['level'] == $parent_agent['level'] && $value['config_key'] == CloudStockEnum::CONFIG_KEY_EQUAL_LEVEL_ONE) {
  582. $direct_agent_price = !empty($value['config_value']) ? $value['config_value'] : 0;
  583. break;
  584. }
  585. }
  586. if (!empty($direct_agent_price) && $direct_agent_price > 0) {
  587. if (!empty($this->configs['difference_equal_type'])) {
  588. $diff_price += $direct_agent_price;
  589. }
  590. //发放平一级奖励
  591. $insert_wallet[] = [
  592. 'mall_id' => $this->mall_id,
  593. 'user_id' => $parent_agent['user_id'],
  594. 'is_frozen' => $is_frozen,
  595. 'wallet_type' => 'commission',
  596. 'money' => $direct_agent_price * $this->not_yet_num,
  597. 'desc' => $desc . '平一级奖励',
  598. 'source_table' => $source_table,
  599. 'source_table_id' => $source_table_id,
  600. 'from_type' => AddonsEnum::ADDONS_NAME_CLOUD_STOCK,
  601. 'capital_type' => UserWalletEnum::CLOUD_STOCK_PRICE_DIFFERENCE_EQUAL,
  602. 'order_no' => $this->order_no,
  603. ];
  604. }
  605. $is_find_equal = true;
  606. } else {
  607. foreach ($equal_level_list as $value) {
  608. if ($value['level'] == $parent_agent['level'] && $value['config_key'] == CloudStockEnum::CONFIG_KEY_EQUAL_LEVEL_TWO) {
  609. $second_parent_agent_price = !empty($value['config_value']) ? $value['config_value'] : 0;
  610. break;
  611. }
  612. }
  613. if (!empty($second_parent_agent_price) && $second_parent_agent_price > 0) {
  614. if (!empty($this->configs['difference_equal_type'])) {
  615. $diff_price += $second_parent_agent_price;
  616. }
  617. $insert_wallet[] = [
  618. 'mall_id' => $this->mall_id,
  619. 'user_id' => $parent_agent['user_id'],
  620. 'is_frozen' => $is_frozen,
  621. 'wallet_type' => 'commission',
  622. 'money' => $second_parent_agent_price * $this->not_yet_num,
  623. 'desc' => $desc . '平二级奖励',
  624. 'source_table' => $source_table,
  625. 'source_table_id' => $source_table_id,
  626. 'from_type' => AddonsEnum::ADDONS_NAME_CLOUD_STOCK,
  627. 'capital_type' => UserWalletEnum::CLOUD_STOCK_PRICE_DIFFERENCE_EQUAL,
  628. 'order_no' => $this->order_no,
  629. ];
  630. }
  631. break;
  632. }
  633. }
  634. }
  635. }
  636. }
  637. public function noCompactLevelingAward($parent_id, $equal_level_list, $is_frozen, $desc, $source_table, $source_table_id, &$diff_price, &$insert_wallet)
  638. {
  639. $direct_agent = CloudStockAgent::findOne(['user_id' => $parent_id, 'mall_id' => $this->mall_id, 'status' => StatusEnum::ENABLED]);
  640. $direct_agent_price = 0;
  641. //获取平一级代理商数据
  642. if ($direct_agent && $direct_agent['level'] == $this->parent_agent->level && !empty($equal_level_list) && empty($direct_agent['is_equal_award_restriction'])) {
  643. $config_key = CloudStockEnum::CONFIG_KEY_EQUAL_LEVEL_ONE;
  644. foreach ($equal_level_list as $value) {
  645. if ($value['level'] == $direct_agent['level'] && $value['config_key'] == $config_key) {
  646. $direct_agent_price = !empty($value['config_value']) ? $value['config_value'] : 0;
  647. break;
  648. }
  649. }
  650. if ($direct_agent_price > 0) {
  651. if (!empty($this->configs['difference_equal_type'])) {
  652. $diff_price += $direct_agent_price;
  653. }
  654. //发放平一级奖励
  655. $insert_wallet[] = [
  656. 'mall_id' => $this->mall_id,
  657. 'user_id' => $direct_agent->user_id,
  658. 'is_frozen' => $is_frozen,
  659. 'wallet_type' => 'commission',
  660. 'money' => $direct_agent_price * $this->not_yet_num,
  661. 'desc' => $desc . '平一级奖励',
  662. 'source_table' => $source_table,
  663. 'source_table_id' => $source_table_id,
  664. 'from_type' => AddonsEnum::ADDONS_NAME_CLOUD_STOCK,
  665. 'capital_type' => UserWalletEnum::CLOUD_STOCK_PRICE_DIFFERENCE_EQUAL,
  666. 'order_no' => $this->order_no
  667. ];
  668. }
  669. }
  670. //获取平二级代理商数据
  671. if (!empty($user['second_parent_id'])) {
  672. //获取平二级代理商数据
  673. $second_parent_agent = CloudStockAgent::findOne(['user_id' => $user['second_parent_id'], 'status' => StatusEnum::ENABLED, 'mall_id' => $this->mall_id]);
  674. $second_parent_agent_price = 0;
  675. if ($second_parent_agent && $second_parent_agent['level'] == $this->parent_agent->level && empty($second_parent_agent['is_equal_award_restriction'])) {
  676. $config_key = CloudStockEnum::CONFIG_KEY_EQUAL_LEVEL_TWO;
  677. foreach ($equal_level_list as $value) {
  678. if ($value['level'] == $second_parent_agent['level'] && $value['config_key'] == $config_key) {
  679. $second_parent_agent_price = !empty($value['config_value']) ? $value['config_value'] : 0;
  680. break;
  681. }
  682. }
  683. if ($second_parent_agent_price > 0) {
  684. if (!empty($this->configs['difference_equal_type'])) {
  685. $diff_price += $second_parent_agent_price;
  686. }
  687. $insert_wallet[] = [
  688. 'mall_id' => $this->mall_id,
  689. 'user_id' => $second_parent_agent->user_id,
  690. 'is_frozen' => $is_frozen,
  691. 'wallet_type' => 'commission',
  692. 'money' => $second_parent_agent_price * $this->not_yet_num,
  693. 'desc' => $desc . '平二级奖励',
  694. 'source_table' => $source_table,
  695. 'source_table_id' => $source_table_id,
  696. 'from_type' => AddonsEnum::ADDONS_NAME_CLOUD_STOCK,
  697. 'capital_type' => UserWalletEnum::CLOUD_STOCK_PRICE_DIFFERENCE_EQUAL,
  698. 'order_no' => $this->order_no,
  699. ];
  700. }
  701. }
  702. }
  703. }
  704. protected function triggerAchievement($params)
  705. {
  706. if ($this->order_type == 'fill') {
  707. try {
  708. \Yii::warning('触发业绩');
  709. $event = new FillEvent($this->mall_id);
  710. $goods_price = $this->order['pay_money'] / $this->order['num'] * $params['num'];
  711. $order_detail_list[] = [
  712. 'id' => $this->order['id'],
  713. 'goods_id' => $this->order['goods_id'],
  714. 'goods_price' => $goods_price,
  715. 'num' => $params['num'],
  716. 'user_id' => $this->user_id,
  717. ];
  718. $data = [
  719. 'id' => $this->order['id'],
  720. 'user_id' => $this->user_id,
  721. 'mall_id' => $this->mall_id,
  722. 'created_at' => $this->order['created_at'],
  723. 'is_cloud' => 1,
  724. 'goods_id_arr' => [$this->goods_id],
  725. 'order_no' => $this->order_no,
  726. 'order_detail_list' => $order_detail_list,
  727. 'type' => CloudStockEnum::STOCK_CHANGE_SUB,
  728. 'deduction_detail_id' => $params['deduction_detail_id'] ?? 0,
  729. ];
  730. var_dump($data);
  731. \Yii::$app->services->events->dispatch($event, $data, $event->listeners);
  732. } catch (\Exception $e) {
  733. \Yii::error('云库存补货订单业绩' . PHP_EOL . $e->getFile() . '(' . $e->getLine() . ')' . PHP_EOL . "message:" . $e->getMessage());
  734. }
  735. }
  736. if ($this->order_type == 'buying') {
  737. //触发业绩
  738. try {
  739. // 触发云库存订单支付事件
  740. $event = new FillEvent($this->mall_id);
  741. $order_detail_list[] = [
  742. 'id' => $this->order['id'],
  743. 'goods_id' => $this->order['goods_id'],
  744. 'goods_price' => $this->order['after_distribution_price'] / $this->order['num'] * $params['num'],
  745. 'num' => $params['num'],
  746. 'user_id' => $this->user_id,
  747. ];
  748. $data = [
  749. 'id' => $this->order['id'],
  750. 'user_id' => $this->user_id,
  751. 'mall_id' => $this->mall_id,
  752. 'created_at' => $this->order['created_at'],
  753. 'is_cloud' => 1,
  754. 'goods_id_arr' => [$this->goods_id],
  755. 'order_no' => $this->order_no,
  756. 'order_detail_list' => $order_detail_list,
  757. 'type' => CloudStockEnum::STOCK_CHANGE_SUB,
  758. 'deduction_detail_id' => $params['deduction_detail_id'] ?? 0,
  759. ];
  760. \Yii::$app->services->events->dispatch($event, $data, $event->listeners);
  761. } catch (\Exception $e) {
  762. \Yii::error('会员前端购买订单业绩' . PHP_EOL . $e->getFile() . '(' . $e->getLine() . ')' . PHP_EOL . "message:" . $e->getMessage());
  763. }
  764. }
  765. }
  766. protected function triggerStatistics($params)
  767. {
  768. //扣平台库存,统计用户上级业绩
  769. if ($this->order['price_difference_order_detail_id']) {
  770. $model = \addons\CloudStock\common\models\CloudStockPriceDifferenceOrderDetail::findOne(['id' => $this->order['price_difference_order_detail_id']]);
  771. $goods_price = $model['goods_price'] ?? 0;
  772. } else {
  773. $goods_price = $this->order['pay_money'] / $this->order['num'] * $params['num'];
  774. }
  775. $post_data = [
  776. 'mall_id' => $this->mall_id,
  777. 'goods_price' => $goods_price,
  778. 'user_id' => $this->order['user_id'],
  779. 'order_id' => $this->order['id'],
  780. ];
  781. \Yii::$app->services->rabbitMq->push(RabbitMqEnum::EXCHANGE_ORDER, RabbitMqEnum::ORDER_QUEUE, $post_data,
  782. CloudStockPriceDifferenceUserTeamStatisticsService::class, 'handleSync');
  783. }
  784. /**
  785. * 业绩奖励B
  786. * @param $params
  787. * @return void
  788. */
  789. protected function triggerAchievementB($params)
  790. {
  791. var_dump('业绩奖励B');
  792. if ($this->order_type == 'fill') {
  793. try {
  794. \Yii::warning('触发业绩B');
  795. $event = new FillEventB($this->mall_id);
  796. $order_detail_list[] = [
  797. 'id' => $this->order['id'],
  798. 'goods_id' => $this->order['goods_id'],
  799. 'goods_price' => $this->order['pay_money'] / $this->order['num'] * $params['num'],
  800. 'num' => $params['num'],
  801. 'user_id' => $this->user_id,
  802. ];
  803. $data = [
  804. 'id' => $this->order['id'],
  805. 'user_id' => $this->user_id,
  806. 'mall_id' => $this->mall_id,
  807. 'created_at' => $this->order['created_at'],
  808. 'is_cloud' => 1,
  809. 'goods_id_arr' => [$this->goods_id],
  810. 'order_no' => $this->order_no,
  811. 'order_detail_list' => $order_detail_list
  812. ];
  813. \Yii::$app->services->events->dispatch($event, $data, $event->listeners);
  814. } catch (\Exception $e) {
  815. \Yii::error('云库存补货订单业绩' . PHP_EOL . $e->getFile() . '(' . $e->getLine() . ')' . PHP_EOL . "message:" . $e->getMessage());
  816. }
  817. }
  818. if ($this->order_type == 'buying') {
  819. //触发业绩
  820. try {
  821. // 触发云库存订单支付事件
  822. $event = new FillEventB($this->mall_id);
  823. $order_detail_list[] = [
  824. 'id' => $this->order['id'],
  825. 'goods_id' => $this->order['goods_id'],
  826. 'goods_price' => $this->order['after_distribution_price'] / $this->order['num'] * $params['num'],
  827. 'num' => $params['num'],
  828. 'user_id' => $this->user_id,
  829. ];
  830. $data = [
  831. 'id' => $this->order['id'],
  832. 'user_id' => $this->user_id,
  833. 'mall_id' => $this->mall_id,
  834. 'created_at' => $this->order['created_at'],
  835. 'is_cloud' => 1,
  836. 'goods_id_arr' => [$this->goods_id],
  837. 'order_no' => $this->order_no,
  838. 'order_detail_list' => $order_detail_list
  839. ];
  840. var_dump($data);
  841. \Yii::$app->services->events->dispatch($event, $data, $event->listeners);
  842. } catch (\Exception $e) {
  843. \Yii::error('会员前端购买订单业绩' . PHP_EOL . $e->getFile() . '(' . $e->getLine() . ')' . PHP_EOL . "message:" . $e->getMessage());
  844. }
  845. }
  846. }
  847. /**
  848. * 代理商库存足够扣,扣减相应库存数,代理商库存不够扣,有多少扣多少,返回未扣库存数
  849. * 扣谁的库存,谁拿货款收益,扣多少数量库存,拿多少数量货款收益;
  850. * @param $parent_agent_goods //库存商品
  851. * @param $stock_log_id //库存变动日志id
  852. * @param $not_yet_num //剩余未扣数量
  853. * @return false|int
  854. */
  855. protected function agentGoodsDeduct($parent_agent_goods, $stock_log_id, $not_yet_num, $price_difference = 0, $is_first = true)
  856. {
  857. var_dump('减之前stock_log_id:parent_agent_goods->num' . $parent_agent_goods->num . ':user_id:' . $parent_agent_goods['user_id']);
  858. var_dump('减之前stock_log_id:not_yet_num' . $not_yet_num);
  859. var_dump($price_difference);
  860. $setting = \Yii::$app->services->setting->addons->get($this->mall_id, AddonsEnum::ADDONS_NAME_CLOUD_STOCK, 'basic');
  861. // 判断上级是否允许给下级扣库存,不允许则直接返回
  862. if (
  863. !empty($setting['is_show_setting']) &&
  864. !empty($setting['is_show_stock_permission']) &&
  865. !empty($this->parent_agent->is_stock_deducted_by_subordinate)
  866. ) {
  867. return $not_yet_num;
  868. }
  869. if ($parent_agent_goods->num >= $not_yet_num) {
  870. $parent_agent_goods->num -= $not_yet_num;//代理商库存足够扣,扣减扣库存数
  871. $num = $not_yet_num;
  872. $not_yet_num = 0;
  873. } else {
  874. $parent_agent_deduction_num = $parent_agent_goods->num;//代理商库存不足够扣,有多少扣多少
  875. $parent_agent_goods->num = 0;//代理商库存归0
  876. $not_yet_num -= $parent_agent_deduction_num; //记录此次扣的库存数剩余数量
  877. $num = $parent_agent_deduction_num;
  878. }
  879. $params = [
  880. 'stock_log_id' => $stock_log_id,
  881. 'not_yet_num' => $not_yet_num,
  882. 'num' => $num,
  883. 'user_id' => $parent_agent_goods->user_id,
  884. 'order_type' => $this->order_type == 'fill' ? CloudStockEnum::STOCK_ORDER_TYPE_REPLENISH : CloudStockEnum::STOCK_ORDER_TYPE_USER,
  885. 'changes_type' => $this->stock_log['changes_type'],
  886. 'order_id' => $this->stock_log['order_id'],
  887. 'goods_id' => $parent_agent_goods['goods_id'],
  888. 'mall_id' => $parent_agent_goods['mall_id'],
  889. ];
  890. if (!$parent_agent_goods->save()) throw new Exception($parent_agent_goods->getErrorMessage());
  891. var_dump('减之后stock_log_id:parent_agent_goods->num' . $parent_agent_goods->num . ':user_id:' . $parent_agent_goods['user_id']);
  892. $res = CloudStockDeductionDetail::setData($params);
  893. if (!$res) throw new Exception(CloudStockDeductionDetail::getStaticError());
  894. //触发库存变动事件
  895. $event = new CloudStockChangeEvent($this->mall_id);
  896. $event_data = [
  897. 'id' => $res->id,
  898. 'type' => CloudStockEnum::STOCK_CHANGE_SUB,
  899. 'mall_id' => $this->mall_id,
  900. ];
  901. \Yii::$app->services->events->dispatch($event, $event_data, $event->listeners);
  902. $this->event_arr[] = [
  903. 'id' => $res->id,
  904. 'type' => CloudStockEnum::STOCK_CHANGE_SUB,
  905. 'mall_id' => $this->mall_id,
  906. ];
  907. $is_true = false;
  908. if ($this->order_type == 'fill') {
  909. if ($setting['fill_price_difference'] && !empty($setting['price_difference_type']) && $setting['price_difference_type'] == 2) {
  910. $is_true = true;
  911. }
  912. } elseif ($this->order_type == 'buying') {
  913. if ($setting['buy_price_difference'] && !empty($setting['price_difference_type']) && $setting['price_difference_type'] == 2) {
  914. $is_true = true;
  915. }
  916. }
  917. $price_differences = 0;//扣货款者的差价
  918. if ($is_true && !empty($setting['payment_for_goods_price_difference'])) {//货款差价
  919. //货款修改为按照代理商自身等级的进货价结算
  920. //差价修改为结算货款者还可拿到差价,然后才截止
  921. if (isset($this->user_agent_level)) {
  922. $cloud_stock_goods = CloudStockGoods::findOne(['mall_id' => $this->mall_id, 'goods_id' => $this->goods_id, 'status' => StatusEnum::ENABLED]);
  923. if (empty($cloud_stock_goods)) return false;
  924. $agent_price_arr = json_decode($cloud_stock_goods['agent_price'], true);
  925. $price_arr = array_column($agent_price_arr, 'price', 'level');//代理商等级价格
  926. $parent_agent_level = $this->parent_agent->level;//代理等级
  927. $parent_agent_price = $price_arr[$parent_agent_level] ?? 0;
  928. $payment_for_goods = $parent_agent_price * $num;//货款
  929. if (empty($this->user_agent_level) || $is_first) {
  930. $user_agent_price = $this->unit_goods_price;
  931. } else {
  932. $user_agent_price = $price_arr[$this->user_agent_level] ?? 0;
  933. }
  934. $price_differences = $user_agent_price - $parent_agent_price;
  935. }
  936. } else {
  937. $payment_for_goods = ($this->unit_goods_price - $price_difference) * $num;
  938. }
  939. var_dump('单价:::' . $this->unit_goods_price);
  940. var_dump('货款:::' . $payment_for_goods);
  941. //货款收益大于0,新增货款收益记录;
  942. if ($payment_for_goods > 0) {
  943. if ($this->parent_agent) {
  944. // TODO: 云库存货款延时结算
  945. $commission_is_frozen = false;
  946. if (isset($setting['compute_delay_day']) && !empty($setting['compute_delay_day'])) {
  947. $commission_is_frozen = true;
  948. }
  949. if (empty($setting['payment_is_not_in_commission'])) {
  950. if ($this->order_type == 'buying') {
  951. $order = Order::findOne(['id' => $this->order['order_id']]);
  952. //订单完成后才结算货款
  953. $source_table = OrderDetail::tableName();
  954. $capital_type = UserWalletEnum::PAYMENT_FOR_GOODS_BUY;
  955. $source_table_id = $this->order['order_detail_id'];
  956. $desc = '';
  957. if (is_string(UserWalletEnum::getCapitalTypeMapByCommission(UserWalletEnum::PAYMENT_FOR_GOODS_BUY))) {
  958. $desc = UserWalletEnum::getCapitalTypeMapByCommission(UserWalletEnum::PAYMENT_FOR_GOODS_BUY);
  959. }
  960. // 判断结算方式,兼容无结算方式设置条件的客户,默认为"支付完成后"结算
  961. if (!$commission_is_frozen && (!isset($setting['compute_type']) || empty($setting['compute_type']))) {
  962. $commission_is_frozen = true;
  963. $orderDetail = OrderDetail::findOne($this->order['order_detail_id']);
  964. if ($orderDetail['order_status'] == -4 && $orderDetail['is_feedback'] == 2) { // 是否退款完成:订单详情已关闭 && 维权完成
  965. $commission_is_frozen = -1; // 不发佣金
  966. } else if ($order['order_status'] == 4) { // 订单已完成
  967. $commission_is_frozen = false;
  968. }
  969. }
  970. } else {
  971. $source_table = CloudStockFillOrder::tableName();
  972. $source_table_id = $this->order['id'];
  973. $capital_type = UserWalletEnum::PAYMENT_FOR_GOODS_FILL;
  974. $desc = '';
  975. if (is_string(UserWalletEnum::getCapitalTypeMapByCommission(UserWalletEnum::PAYMENT_FOR_GOODS_FILL))) {
  976. $desc = UserWalletEnum::getCapitalTypeMapByCommission(UserWalletEnum::PAYMENT_FOR_GOODS_FILL);
  977. }
  978. }
  979. if ($commission_is_frozen !== -1) {
  980. $this->fill_insert_wallet[] = $insert_wallet [] = ['mall_id' => $this->mall_id, 'user_id' => $this->parent_agent->user_id,
  981. 'is_frozen' => $commission_is_frozen, 'wallet_type' => 'commission', 'money' => $payment_for_goods,
  982. 'desc' => $desc,
  983. 'source_table' => $source_table,
  984. 'source_table_id' => $source_table_id,
  985. 'from_type' => AddonsEnum::ADDONS_NAME_CLOUD_STOCK,
  986. 'capital_type' => $capital_type,
  987. 'order_no' => $this->order_no,
  988. ];
  989. }
  990. //投递到资产队列
  991. if (!empty($insert_wallet)) {
  992. CloudStockAgent::sendUserWalletQueue($insert_wallet);
  993. }
  994. } else {
  995. //开启货款不计入佣金
  996. $order_id = $order_detail_id = 0;
  997. switch ($this->order_type) {
  998. case 'fill':
  999. $order_id = $this->order['id'];
  1000. $order_detail_id = $this->order['id'];
  1001. break;
  1002. case 'buying':
  1003. $order_id = $this->order['order_id'];
  1004. $order_detail_id = $this->order['order_detail_id'];
  1005. if (!$commission_is_frozen && (!isset($setting['compute_type']) || empty($setting['compute_type']))) {
  1006. $commission_is_frozen = true;
  1007. $orderDetail = OrderDetail::findOne($this->order['order_detail_id']);
  1008. $order = Order::findOne(['id' => $this->order['order_id']]);
  1009. if ($orderDetail['order_status'] == -4 && $orderDetail['is_feedback'] == 2) { // 是否退款完成:订单详情已关闭 && 维权完成
  1010. $commission_is_frozen = -1; // 不发货款了
  1011. } else if ($order['order_status'] == 4) { // 订单已完成
  1012. $commission_is_frozen = false;
  1013. }
  1014. }
  1015. break;
  1016. }
  1017. if ($commission_is_frozen !== -1) {
  1018. $goods = Goods::findOne(['id' => $this->order['goods_id']]);
  1019. if (empty($setting['profit_in_commission'])) {
  1020. //货款全部进入云仓货款
  1021. $add_data = [
  1022. 'mall_id' => $this->mall_id,
  1023. 'store_id' => $this->store_id,
  1024. 'type' => $this->order_type,
  1025. 'user_id' => $this->parent_agent->user_id,
  1026. 'buy_user_id' => $this->order['user_id'],
  1027. 'goods_id' => $this->order['goods_id'],
  1028. 'goods_name' => $goods['goods_name'],
  1029. 'pic_url' => $goods['cover_pic'],
  1030. 'order_id' => $order_id,
  1031. 'order_detail_id' => $order_detail_id,
  1032. 'num' => $num,
  1033. 'order_no' => $this->order_no,
  1034. 'money' => $payment_for_goods,
  1035. 'status' => $commission_is_frozen ? 0 : 1,
  1036. ];
  1037. } else {
  1038. //拿货价计入货款,差价计入佣金
  1039. $stock_goods = $this->stock_goods;
  1040. $agent_price_arr = json_decode($stock_goods['agent_price'], true);
  1041. $agent_price_arr = array_column($agent_price_arr, null, 'level');
  1042. $profit = $warehouse_payment = 0;
  1043. if (isset($agent_price_arr) && isset($agent_price_arr[$this->parent_agent['level']])) {
  1044. $agent_price = $agent_price_arr[$this->parent_agent['level']]['price'] * $num;//拿货价
  1045. if ($payment_for_goods > $agent_price) {
  1046. $profit = $payment_for_goods - $agent_price;
  1047. $warehouse_payment = $agent_price;
  1048. } else {
  1049. $warehouse_payment = $agent_price;
  1050. }
  1051. }
  1052. if ($profit > 0) {
  1053. $this->profitInCommission($commission_is_frozen, $profit);
  1054. }
  1055. if ($warehouse_payment > 0) {
  1056. $add_data = [
  1057. 'mall_id' => $this->mall_id,
  1058. 'store_id' => $this->store_id,
  1059. 'type' => $this->order_type,
  1060. 'user_id' => $this->parent_agent->user_id,
  1061. 'buy_user_id' => $this->order['user_id'],
  1062. 'goods_id' => $this->order['goods_id'],
  1063. 'goods_name' => $goods['goods_name'],
  1064. 'pic_url' => $goods['cover_pic'],
  1065. 'order_id' => $order_id,
  1066. 'order_detail_id' => $order_detail_id,
  1067. 'num' => $num,
  1068. 'order_no' => $this->order_no,
  1069. 'money' => $warehouse_payment,
  1070. 'status' => $commission_is_frozen ? 0 : 1,
  1071. ];
  1072. }
  1073. }
  1074. if ($this->order_type == 'buying') {
  1075. if (isset($add_data)) {
  1076. $this->payment_insert_wallet[] = $add_data;
  1077. }
  1078. }
  1079. (new PaymentLogService(['mall_id' => $this->mall_id, 'user_id' => $this->parent_agent->user_id]))->add($add_data);
  1080. }
  1081. }
  1082. if ($this->order_type == 'buying' && isset($commission_is_frozen) && $commission_is_frozen == false) {
  1083. $obj = new PriceDifferenceProfitService(['mall_id' => $this->mall_id]);
  1084. $obj->order_no = $this->order_no;
  1085. $obj->compute(3, $num, $this->order, $this->parent_agent);//会员买货触发差价利润金额
  1086. }
  1087. }
  1088. if (!empty($this->recommend_reward_arr)) {
  1089. if ($this->not_distribute_payment_for_goods) {
  1090. $new_recommend_reward_arr = [];
  1091. foreach ($this->recommend_reward_arr as $val) {
  1092. $total_num = $this->order->num;
  1093. //重新计算佣金,当前扣除上级库存件数*每件可获取佣金
  1094. $val['money'] = bcmul($val['money'] / $total_num, $num, 2);
  1095. $desc_array = explode(',', $val['desc']);
  1096. $val['desc'] = $desc_array[0].','.$desc_array[1].','.$desc_array[2].',金额:'.$val['money'];
  1097. $new_recommend_reward_arr[] = $val;
  1098. if ($val['user_id'] == $this->parent_agent->user_id) {
  1099. break;
  1100. }
  1101. }
  1102. } else {
  1103. $new_recommend_reward_arr = $this->recommend_reward_arr;
  1104. }
  1105. $this->sendRecommendReward($new_recommend_reward_arr);
  1106. }
  1107. }
  1108. if ($this->order_type == 'fill') {
  1109. (new PriceDifferenceProfitService(['mall_id' => $this->order['mall_id']]))->compute(2, $num, $this->order, $this->parent_agent);//补货触发差价利润金额
  1110. }
  1111. if ($price_differences > 0) {
  1112. $commission_is_frozen = false;
  1113. if (isset($setting['compute_delay_day']) && !empty($setting['compute_delay_day'])) {
  1114. $commission_is_frozen = true;
  1115. }
  1116. if ($this->order_type == 'buying') {
  1117. $source_table = OrderDetail::tableName();
  1118. $source_table_id = $this->order['order_detail_id'];
  1119. $desc = '会员买货时,结算货款者拿补货差价';
  1120. $capital_type = UserWalletEnum::CLOUD_STOCK_BUY_PRICE_DIFFERENCE;
  1121. $is_frozen = true;
  1122. // 判断结算方式,兼容无结算方式设置条件的客户,默认为"支付完成后"结算
  1123. if (!$commission_is_frozen && (!isset($setting['compute_type']) || empty($setting['compute_type']))) {
  1124. $commission_is_frozen = true;
  1125. }
  1126. } else {
  1127. $source_table = CloudStockFillOrder::tableName();
  1128. $source_table_id = $this->order['id'];
  1129. $desc = '补货时,结算货款者拿补货差价';
  1130. $capital_type = UserWalletEnum::CLOUD_STOCK_FILL_PRICE_DIFFERENCE;
  1131. $is_frozen = false;
  1132. }
  1133. $insert_wallet = [];
  1134. $this->addPriceDifference($commission_is_frozen, $price_differences, $desc, $source_table, $source_table_id, $capital_type, $num, $insert_wallet);
  1135. if (!empty($insert_wallet)) {
  1136. $res = UserWalletService::batchHandleByQueue($insert_wallet);
  1137. if (!$res) return false;
  1138. (new EqualAwardService(['mall_id' => $this->mall_id]))->setStatistics($insert_wallet, UserWalletEnum::EQUAL);
  1139. }
  1140. }
  1141. return $not_yet_num;
  1142. }
  1143. protected function addPriceDifference($commission_is_frozen, $price_difference, $desc, $source_table, $source_table_id, $capital_type, $num, &$insert_wallet)
  1144. {
  1145. if ($this->not_get_price_difference && !empty($this->recommend_reward_arr)) {
  1146. $recommend_reward_arr = array_column($this->recommend_reward_arr, null, 'user_id');
  1147. if (isset($recommend_reward_arr[$this->parent_agent->user_id])) {
  1148. return true;
  1149. }
  1150. }
  1151. $setting = \Yii::$app->services->setting->addons->get($this->mall_id, AddonsEnum::ADDONS_NAME_CLOUD_STOCK, 'basic');
  1152. if (empty($setting['payment_is_not_in_commission'])) {
  1153. $this->fill_insert_wallet[] = $insert_wallet[] = [
  1154. 'mall_id' => $this->mall_id,
  1155. 'user_id' => $this->parent_agent->user_id,
  1156. 'is_frozen' => $commission_is_frozen,
  1157. 'wallet_type' => 'commission',
  1158. 'money' => $price_difference * $num,
  1159. 'desc' => $desc,
  1160. 'source_table' => $source_table,
  1161. 'source_table_id' => $source_table_id,
  1162. 'from_type' => AddonsEnum::ADDONS_NAME_CLOUD_STOCK,
  1163. 'capital_type' => $capital_type,
  1164. 'order_no' => $this->order_no,
  1165. ];
  1166. } else {
  1167. if ($this->order_type == 'buying') {
  1168. $order_id = $this->order['order_id'];
  1169. $order_detail_id = $this->order['order_detail_id'];
  1170. } else {
  1171. $order_id = $this->order['id'];
  1172. $order_detail_id = $this->order['id'];
  1173. }
  1174. $goods = Goods::findOne(['id' => $this->order['goods_id']]);
  1175. $add_data = [
  1176. 'mall_id' => $this->mall_id,
  1177. 'store_id' => $this->store_id,
  1178. 'type' => $this->order_type,
  1179. 'user_id' => $this->parent_agent->user_id,
  1180. 'buy_user_id' => $this->order['user_id'],
  1181. 'goods_id' => $this->order['goods_id'],
  1182. 'goods_name' => $goods['goods_name'],
  1183. 'pic_url' => $goods['cover_pic'],
  1184. 'order_id' => $order_id,
  1185. 'order_detail_id' => $order_detail_id,
  1186. 'num' => $num,
  1187. 'order_no' => $this->order_no,
  1188. 'money' => $price_difference * $num,
  1189. 'status' => $commission_is_frozen ? 0 : 1,
  1190. ];
  1191. $this->payment_insert_wallet[] = $add_data;
  1192. (new PaymentLogService(['mall_id' => $this->mall_id, 'user_id' => $this->parent_agent->user_id]))->add($add_data);
  1193. }
  1194. }
  1195. protected function profitInCommission($commission_is_frozen, $profit)
  1196. {
  1197. if ($this->order_type == 'buying') {
  1198. $source_table = OrderDetail::tableName();
  1199. $capital_type = UserWalletEnum::PAYMENT_FOR_GOODS_BUY;
  1200. $source_table_id = $this->order['order_detail_id'];
  1201. $desc = '';
  1202. if (is_string(UserWalletEnum::getCapitalTypeMapByCommission(UserWalletEnum::PAYMENT_FOR_GOODS_BUY))) {
  1203. $desc = UserWalletEnum::getCapitalTypeMapByCommission(UserWalletEnum::PAYMENT_FOR_GOODS_BUY);
  1204. }
  1205. } else {
  1206. $source_table = CloudStockFillOrder::tableName();
  1207. $source_table_id = $this->order['id'];
  1208. $capital_type = UserWalletEnum::PAYMENT_FOR_GOODS_FILL;
  1209. $desc = '';
  1210. if (is_string(UserWalletEnum::getCapitalTypeMapByCommission(UserWalletEnum::PAYMENT_FOR_GOODS_FILL))) {
  1211. $desc = UserWalletEnum::getCapitalTypeMapByCommission(UserWalletEnum::PAYMENT_FOR_GOODS_FILL);
  1212. }
  1213. }
  1214. $insert_wallet = [];
  1215. $this->fill_insert_wallet[] = $insert_wallet [] = ['mall_id' => $this->mall_id, 'user_id' => $this->parent_agent->user_id,
  1216. 'is_frozen' => $commission_is_frozen, 'wallet_type' => 'commission', 'money' => $profit,
  1217. 'desc' => $desc,
  1218. 'source_table' => $source_table,
  1219. 'source_table_id' => $source_table_id,
  1220. 'from_type' => AddonsEnum::ADDONS_NAME_CLOUD_STOCK,
  1221. 'capital_type' => $capital_type,
  1222. ];
  1223. //投递到资产队列
  1224. if ($insert_wallet) {
  1225. CloudStockAgent::sendUserWalletQueue($insert_wallet);
  1226. }
  1227. }
  1228. public function deductOrJob()
  1229. {
  1230. //当前扣库存代理商
  1231. $agent_user_id = 0;
  1232. $level = 0;
  1233. if (isset($this->parent_agent)) {
  1234. $agent_user_id = $this->parent_agent->user_id;
  1235. $level = $this->parent_agent->level;
  1236. }
  1237. if (!empty($this->is_time_limit_fill) && !empty($agent_user_id)) {
  1238. //当前代理商加入过队列
  1239. if (in_array($agent_user_id, $this->time_limit_fill_user_ids)) {
  1240. //过了限时补货,而不补货,再往上找符合条件的代理商扣库存
  1241. $type = 2;
  1242. if ($this->order_type == 'buying') {
  1243. $type = 3;
  1244. }
  1245. (new LossAmountService(['mall_id' => $this->mall_id]))->compute($type, $this->not_yet_num, $this->order, $this->parent_agent);//补货、会员买货触发流失金额
  1246. $parent_agent = CloudStockAgent::getUserParentAgent($agent_user_id, $level);
  1247. $this->parent_agent = $parent_agent;
  1248. return $this->deduct();
  1249. } else {
  1250. //当前代理商没有加入过队列
  1251. //记录执行限时补货的代理商用户id
  1252. array_push($this->time_limit_fill_user_ids, $agent_user_id);
  1253. $data = [
  1254. 'user_id' => $this->user_id,
  1255. 'agent_user_id' => $agent_user_id,
  1256. 'stock_log_id' => $this->stock_log_id,
  1257. 'goods_id' => $this->goods_id,
  1258. 'order_id' => $this->order['id'],
  1259. 'not_yet_num' => $this->not_yet_num,
  1260. 'order_type' => $this->order_type,
  1261. 'mall_id' => $this->mall_id,
  1262. 'time_limit_fill_user_ids' => $this->time_limit_fill_user_ids,
  1263. ];
  1264. var_dump('订单id:' . $this->order['id'] . '触发限时补货,时间是:' . $this->fill_hour);
  1265. var_dump($data);
  1266. CloudStockPushDelayLog::setData($data);
  1267. \Yii::$app->services->rabbitMq->delay($this->fill_hour * 3600, $data, DeductionJob::class, 'handleSync');
  1268. //补货通知
  1269. try {
  1270. $SmsConfig = new Sms($this->mall_id);
  1271. $easy_sms = $SmsConfig->easySms;
  1272. $goods = Goods::findOne(['id' => $this->goods_id]);
  1273. $goods_name = $goods['goods_name'];
  1274. $goods_id = $this->goods_id;
  1275. mb_substr($goods_name, 0, 24);
  1276. $message = new TimeLimitFillMessage($this->mall_id, $this->fill_hour, $goods_id, $this->not_yet_num);
  1277. $user = User::findOne(['id' => $agent_user_id]);
  1278. $easy_sms->send($user['mobile'], $message);
  1279. } catch (NoGatewayAvailableException $e) {
  1280. $res = $e->getExceptions();
  1281. if (!empty($res)) {
  1282. foreach ($res as $exception) {
  1283. if (is_string($exception->getMessage())) {
  1284. var_dump('云库存补货通知短信发送失败:' . $exception->getMessage());
  1285. }
  1286. }
  1287. }
  1288. } catch (\Exception $e) {
  1289. var_dump('云库存补货通知短信发送失败:' . $e->getMessage());
  1290. }
  1291. return true;
  1292. }
  1293. } else {
  1294. //没有开启限时补货或者下单人的上级代理商不存在,递归往上找,直到找平台扣库存
  1295. $type = 2;
  1296. if ($this->order_type == 'buying') {
  1297. $type = 3;
  1298. }
  1299. (new LossAmountService(['mall_id' => $this->mall_id]))->compute($type, $this->not_yet_num, $this->order, $this->parent_agent);//补货、会员买货触发流失金额
  1300. $this->parent_agent = CloudStockAgent::getUserParentAgent($agent_user_id, $level);
  1301. return $this->deduct();
  1302. }
  1303. }
  1304. }