OrderMarketingLogic.php 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. <?php
  2. namespace common\logic\order;
  3. use addons\Community\common\service\HeadService;
  4. use addons\Coupon\AddonConfig;
  5. use addons\Coupon\common\models\AddonsCoupon;
  6. use backend\modules\mall\services\GiveScoreService;
  7. use common\enums\AddonsEnum;
  8. use common\enums\ShippingTypeEnum;
  9. use common\logic\order\marketing\AgentMarketing;
  10. use common\logic\order\marketing\GoodsDeductMarketing;
  11. use common\logic\order\marketing\BaseMarketing;
  12. use common\logic\order\marketing\CouponMarketing;
  13. use common\logic\order\marketing\DeductionMarketing;
  14. use common\logic\order\marketing\FreeShippingMarketing;
  15. use common\logic\order\marketing\FreightFullReduceMarketing;
  16. use common\logic\order\marketing\GiveMarketing;
  17. use common\logic\order\marketing\MemberPriceMarketing;
  18. use common\logic\order\marketing\RedeemCardMarketing;
  19. use common\logic\order\marketing\RedpackMarketing;
  20. use common\logic\order\marketing\RegionalDividendMarketing;
  21. use common\logic\order\marketing\ScoreExpansionMarketing;
  22. use common\logic\order\marketing\ScoreMarketing;
  23. use common\logic\order\marketing\FullReduceMarketing;
  24. use common\logic\order\marketing\HigoMarketing;
  25. use common\logic\order\marketing\MemberCardMarketing;
  26. use common\logic\order\marketing\RepurchaseMarketing;
  27. use common\logic\order\marketing\ConsumerCouponsMarketing;
  28. use common\models\mall\MallAddons;
  29. use common\models\order\OrderMarketing;
  30. use common\models\user\UserAddress;
  31. use common\traits\ErrorTrait;
  32. use Exception;
  33. use Yii;
  34. use yii\helpers\Json;
  35. /**
  36. * 订单优惠相关处理
  37. * @Author bing
  38. * @DateTime 2021-09-22 18:16:58
  39. * @copyright: Copyright (c) 2020 广东七件事集团
  40. */
  41. class OrderMarketingLogic extends BaseOrderMarketing
  42. {
  43. public function getHandlers() {
  44. return [
  45. RepurchaseMarketing::class, //复购价格处理
  46. MemberPriceMarketing::class, // 用户价折扣
  47. // AgentMarketing::class, // 经销商内购
  48. GoodsDeductMarketing::class,// 经销商内购
  49. FullReduceMarketing::class, // 满减减免处理
  50. ScoreMarketing::class, // 积分抵扣处理
  51. // FullReduceMarketing::class, // 满减减免处理
  52. GiveMarketing::class, // 赠送处理
  53. // AgentMarketing::class,
  54. RedpackMarketing::class,// 红包处理
  55. ConsumerCouponsMarketing::class,// 消费券处理
  56. HigoMarketing::class,// 嗨购处理
  57. MemberCardMarketing::class,// 会员卡处理
  58. // ScoreExpansionMarketing::class,//积分拓客处理 先关掉 暂时用不到
  59. RegionalDividendMarketing::class, // 区域分红 - 合伙人 - 代理价
  60. CouponMarketing::class, // 优惠券处理,必须放在最后,因为优惠券叠加要求,原价购买时才能用
  61. RedeemCardMarketing::class,
  62. FreeShippingMarketing::class, // 运费减免处理,涉及到包邮规则,必须在最后处理
  63. DeductionMarketing::class, // 会员积分抵扣
  64. ];
  65. }
  66. /**
  67. * 运行
  68. * @param $form
  69. * @param bool $isNewRecord 创建记录
  70. * @return object|mixed
  71. */
  72. public function run($form, $isNewRecord = false)
  73. {
  74. try{
  75. $extra = [];
  76. $group_order_goods = $form['group_order_goods'];
  77. $handlers =$this->getHandlers();
  78. $extra_shipping_fee = 0;
  79. if (!empty($form->process_extra_data['shipping_fee'])) {
  80. foreach ($form->process_extra_data['shipping_fee'] as $gid => $fees) {
  81. $extra_shipping_fee = array_sum($fees);
  82. }
  83. }
  84. if (empty($form->marketing['deduct']['shipping_fee']['money'])) $form->marketing['deduct']['shipping_fee']['money'] = 0;
  85. $form->marketing['deduct']['shipping_fee']['money'] += $extra_shipping_fee;
  86. // 判断是否有社区团购插件
  87. $is_install_community_addons = MallAddons::isInstall($form->mall_id, AddonsEnum::ADDONS_NAME_COMMUNITY);
  88. $is_filter_shipping = false;
  89. foreach ($group_order_goods as &$item) {
  90. // 运费减免处理
  91. foreach ($handlers as $key => $handler) {
  92. // 如果是社区团购订单,那么就不需要进行邮费处理 - 并且判断是否为送货上门/自提, 团长是否存在
  93. if ($form->is_force_free_shipping && $handler == FreeShippingMarketing::class) {
  94. continue;
  95. }
  96. /** @var BaseMarketing $class*/
  97. $item = $handler::compute($item, $form, $extra);
  98. if($item === false) throw new Exception($handler::getStaticError());
  99. }
  100. if (!$form->is_force_free_shipping) $item = FreightFullReduceMarketing::compute($item, $form);
  101. // 扩展费用
  102. if (!empty($form->process_extra_data['shipping_fee'])) {
  103. foreach ($form->process_extra_data['shipping_fee'] as $gid => $fees) {
  104. if (!empty($item['goods'][$gid])) {
  105. if (empty($item['mch_order_info']['shipping_money'])) $item['mch_order_info']['shipping_money'] = 0;
  106. $item['mch_order_info']['shipping_money'] += array_sum($fees);
  107. $item['mch_order_info']['pay_money'] += array_sum($fees);
  108. }
  109. }
  110. }
  111. $form['total_pay_money'] = round($form['total_pay_money']+$item['mch_order_info']['pay_money'],2);// 计算总额
  112. $form['total_pay_money_not_coupon'] = bcadd(
  113. $form['total_pay_money_not_coupon'], bcadd(
  114. $item['mch_order_info']['goods_price'], $item['mch_order_info']['coupon_money'] ?? 0, 2
  115. ), 2
  116. ); // 计算优惠券前金额
  117. // 计算优惠券最后一单金额
  118. $goodsNum = count($item['goods']);
  119. if (!empty($item['goods']) && $goodsNum > 1) {
  120. // 多个商品时其优惠比例计算容易出现浮点数误差,所以在计算最后一个订单优惠金额时(总金额-前面所有优惠金额)
  121. $goodsEndMoney = $this->setEndMoney($item['goods'], $item['mch_order_info']['goods_price']);
  122. $goodsKeys = array_keys($item['goods']);
  123. $lastKey = end($goodsKeys);
  124. foreach ($item['goods'] as $key => $goods) {
  125. if ($key == $lastKey) {
  126. $item['goods'][$key]['goods_price'] = $goodsEndMoney;
  127. // 因为订单详情是列表,所以需要循环设置优惠金额
  128. $detailEndMoney = $this->setEndMoney($goods['goods_details'], $item['goods'][$key]['goods_price']);
  129. $detailKeys = array_keys($goods['goods_details']);
  130. $lastKey = end($detailKeys);
  131. foreach ($goods['goods_details'] as $k => $goodsDetail) {
  132. if ($k == $lastKey) {
  133. $item['goods'][$key]['goods_details'][$k]['goods_price'] = $detailEndMoney;
  134. }
  135. }
  136. }
  137. }
  138. }
  139. }
  140. $form['group_order_goods'] = $group_order_goods;
  141. $form = AddonsCoupon::getCanUseCouponList($form, $isNewRecord);
  142. $form = GiveScoreService::setGoodsMarketing($form);
  143. return $form;
  144. }catch(Exception $e){
  145. $this->setError($e->getMessage());
  146. return false;
  147. }
  148. }
  149. /**
  150. * 设置最后一个商品的优惠金额
  151. * @param array $list
  152. * @param $money
  153. * @return string
  154. */
  155. public function setEndMoney(array $list, $money = 0)
  156. {
  157. $otherList = array_slice($list, 0 , count($list) - 1);
  158. $otherMoney = array_sum(array_column($otherList, 'goods_price'));
  159. return bcsub(round($money, 2), bcmul($otherMoney, 1, 2), 2);
  160. }
  161. }