FreeShippingMarketing.php 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. <?php
  2. namespace addons\ValetOrder\common\logic\order\marketing;
  3. use common\enums\ShippingTypeEnum;
  4. use common\models\goods\FreeShippingRules;
  5. use common\models\goods\FreightRules;
  6. use common\models\user\UserAddress;
  7. /**
  8. * 运费减免计算
  9. * @Author bing
  10. * @DateTime 2021-09-27 19:07:32
  11. * @copyright: Copyright (c) 2020 广东七件事集团
  12. */
  13. class FreeShippingMarketing extends BaseMarketing{
  14. public function execute( $form){}
  15. /**
  16. * 计算运费
  17. * @Author: lun
  18. * @DateTime: 2021/10/6 0006 10:37
  19. * @Copyright: copyright (c) 2021 广东七件事集团
  20. * @param $item
  21. * @param $form
  22. * @param $extra
  23. * @return mixed
  24. */
  25. public static function compute($item, &$form, &$extra)
  26. {
  27. $address = [
  28. 'province_id' => $form['province_id'],
  29. 'city_id' => $form['city_id'],
  30. 'district_id' => $form['district_id'],
  31. 'province' => $form['province'],
  32. 'city' => $form['city'],
  33. 'district' => $form['district'],
  34. 'town' => $form['town'] ?? '',
  35. 'town_id' => $form['town_id'] ?? 0,
  36. 'community' => $form['community'] ?? '',
  37. 'community_id' => $form['community_id'] ?? 0,
  38. 'detail' => $form['address'],
  39. 'name' => $form['name'],
  40. 'mobile' => $form['mobile'],
  41. ];
  42. // 收货地址
  43. $item['mch_order_info']['province'] = $address['province_id'];
  44. $item['mch_order_info']['city'] = $address['city_id'];
  45. $item['mch_order_info']['area'] = $address['district_id'];
  46. $item['mch_order_info']['town'] = $address['town_id'] ?? 0;
  47. $item['mch_order_info']['community'] = $address['community_id'] ?? 0;
  48. $item['mch_order_info']['region_name'] = $address['province'] .' '. $address['city'] .' '. $address['district'].' '.$address['town'].' '.$address['community'];
  49. $item['mch_order_info']['address'] = $address['detail'];
  50. $item['mch_order_info']['receiver_name'] = $address['name'];
  51. $item['mch_order_info']['mobile'] = $address['mobile'];
  52. $shipping_fee = 0;// 订单总运费初始化
  53. $group_order_fee = 0;// 单个商户订单运费
  54. $is_free = false;// 是否免邮
  55. // 获取包邮地区
  56. $feeShippingRules = FreeShippingRules::getFreeShippingRulesArea($item['mch_order_info']['mall_id'], $item['mch_order_info']['mch_id']);
  57. // 获取运费模板
  58. $freightRules = FreightRules::getFreightRulesArea($item['mch_order_info']['mall_id'], $item['mch_order_info']['mch_id']);
  59. // 包邮计算
  60. foreach ($feeShippingRules as $fee) {
  61. // 如果包邮金额<=购买商品金额,并且地区符合收货地址则免邮
  62. if ($fee['money'] <= $item['mch_order_info']['goods_price'] && self::isInArea($address, $fee['district_ids'])) {
  63. $is_free = true;
  64. continue;
  65. }
  66. }
  67. // 不免邮处理
  68. if ($is_free == false) {
  69. foreach ($item['goods'] as $good_id => $good) {
  70. $good_num = 0;// 第N个商品
  71. if ($good['num'] > 1) {
  72. $good_num+= $good['num'];
  73. } else {
  74. $good_num++;
  75. }
  76. // 物流方式
  77. if (!in_array(ShippingTypeEnum::LOGISTICS, explode(',', $form['sku'][$good_id]['goods']['freight_type']))) continue;
  78. // 计算满件包邮
  79. if ($form['sku'][$good_id]['goods']['free_shipping_num'] > 0 && $good['num'] >= $form['sku'][$good_id]['goods']['free_shipping_num']) continue;
  80. // 计算满元包邮
  81. if ($form['sku'][$good_id]['goods']['free_shipping_money'] > 0 && $good['goods_price'] >= $form['sku'][$good_id]['goods']['free_shipping_money']) continue;
  82. // 运费规则
  83. if ($form['sku'][$good_id]['goods']['freight_rules_type'] == 1) {
  84. $thisRules = $freightRules[$form['sku'][$good_id]['goods']['freight_id']];// 根据商品id获取对应的规则
  85. if(!empty($thisRules['rule'])){
  86. foreach ($thisRules['rule'] as $rule) {
  87. // 获取该模板的所有地区id
  88. $areaArr = array_column($rule['list'], 'id');
  89. // 判断收货地址是否在模板中
  90. if (self::isInArea($address, $areaArr)) {
  91. if ($thisRules['type'] == 1) {// 按重计费
  92. $new_num_weight = $form['sku'][$good_id]['weight'] * $good['num'];
  93. } else {// 按件计费
  94. $new_num_weight = $good['num'];
  95. }
  96. // 计算[首件/首重]收费
  97. if ($new_num_weight >= $rule['first']) {
  98. $group_order_fee += $rule['firstPrice'];
  99. $shipping_fee += $rule['firstPrice'];
  100. }
  101. if ($thisRules['type'] == 1) {// 计算续重收费
  102. $surplus_weight = $new_num_weight - $rule['first'];// 剩余重量 = 总重量 - 首重重量
  103. if ($surplus_weight > 0) {
  104. // 续重运费 = (剩余重量 / 续件重量)[向上取整] * 续重费用 [向下取整]
  105. if(isset($rule['second'])&&$rule['second']>0) {
  106. $fee = floor(ceil($surplus_weight / $rule['second']) * $rule['secondPrice']);
  107. $shipping_fee += $fee;
  108. $group_order_fee += $fee;
  109. }
  110. }
  111. } else {// 计算续件收费
  112. $surplus_num = $good_num - $rule['first'];// 减扣首件数量
  113. if($rule['second']>0){
  114. if ($surplus_num > 0 && $rule['second']>0 && $surplus_num % $rule['second'] == 0) {
  115. // 续费 * (减扣首件数量 / 续件数量)[向下取整]
  116. if(isset($rule['second'])&&$rule['second']>0){
  117. $fee = $rule['secondPrice'] * floor($surplus_num / $rule['second']);
  118. $shipping_fee += $fee;
  119. $group_order_fee += $fee;
  120. }
  121. }
  122. }
  123. }
  124. continue;// 已计算好运费则跳出循环
  125. }
  126. }
  127. }
  128. } else {
  129. // 自定义运费
  130. if ($form['sku'][$good_id]['goods']['shipping_fee'] >= 0) {
  131. $shipping_fee+= $form['sku'][$good_id]['goods']['shipping_fee'];
  132. $group_order_fee+= $form['sku'][$good_id]['goods']['shipping_fee'];
  133. }
  134. }
  135. }
  136. // 单个商户订单运费计算
  137. $item['mch_order_info']['shipping_type'] = $form['data']['shipping_type'] ?? ShippingTypeEnum::LOGISTICS;
  138. $item['mch_order_info']['shipping_money'] = $group_order_fee;
  139. }
  140. // 运费赋值
  141. $item['mch_order_info']['pay_money'] = $item['mch_order_info']['pay_money'] + $shipping_fee;
  142. $prev_shipping_fee = $form->marketing['deduct']['shipping_fee']['money'] ?? 0;
  143. $form->marketing['deduct']['shipping_fee'] = ['name' => '运费', 'money' => $prev_shipping_fee + $shipping_fee];
  144. return $item;
  145. }
  146. /**
  147. * 判断收货地址是否在地区中
  148. * @Author: lun
  149. * @DateTime: 2021/9/30 0030 14:45
  150. * @Copyright: copyright (c) 2021 广东七件事集团
  151. * @param $address
  152. * @param $areaArr
  153. * @return bool
  154. */
  155. private static function isInArea($address, $areaArr)
  156. {
  157. $return = false;
  158. if(in_array($address['province_id'], $areaArr) || in_array($address['city_id'], $areaArr) || in_array($address['district_id'], $areaArr)) $return = true;
  159. return $return;
  160. }
  161. }