| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259 |
- <?php
- namespace addons\UpgradeGift\common\logic\order\marketing;
- use common\enums\GoodsTypeEnum;
- use common\enums\ShippingTypeEnum;
- use common\models\goods\FreeShippingRules;
- use common\models\goods\FreightRules;
- use common\models\goods\Goods;
- use common\models\user\UserAddress;
- use Yii;
- use yii\helpers\Json;
- /**
- * 运费减免计算
- * @Author bing
- * @DateTime 2021-09-27 19:07:32
- * @copyright: Copyright (c) 2020 广东七件事集团
- */
- class FreeShippingMarketing extends BaseMarketing{
- public function execute( $form){}
- /**
- * 计算运费
- * @Author: lun
- * @DateTime: 2021/10/6 0006 10:37
- * @Copyright: copyright (c) 2021 广东七件事集团
- * @param $item
- * @param $form
- * @param $extra
- * @return mixed
- */
- public static function compute($item, &$form, &$extra)
- {
- if (isset($form->data['shipping_type']) && $form->data['shipping_type']==ShippingTypeEnum::PICKUP){
- return $item;
- }
- // 获取用户收货地址信息
- if (empty($extra['address'])) {
- $address = UserAddress::getOne([['id' => $form['address_id']], ['user_id' => $form['user_id']]], true);
- $extra['address'] = $address;
- } else {
- $address = $extra['address'];
- }
- // 收货地址
- if(empty($address)){
- $address['province_id'] = $address['city_id'] = $address['district_id'] = $address['town_id'] = $address['community_id'] = 0;
- $address['province'] = $address['city'] = $address['district'] = $address['town'] = $address['community'] = $address['detail'] = $address['name'] = $address['mobile'] ='';
- }
- // 收货地址
- $item['mch_order_info']['province'] = $address['province_id'];
- $item['mch_order_info']['city'] = $address['city_id'];
- $item['mch_order_info']['area'] = $address['district_id'];
- $item['mch_order_info']['town'] = $address['town_id'];
- $item['mch_order_info']['community'] = $address['community_id'];
- $item['mch_order_info']['region_name'] = $address['province'] .' '. $address['city'] .' '. $address['district'].' '.$address['town'].' '.$address['community'];
- $item['mch_order_info']['address'] = $address['detail'];
- $item['mch_order_info']['receiver_name'] = $address['name'];
- $item['mch_order_info']['mobile'] = $address['mobile'];
- $shipping_fee = 0;// 订单总运费初始化
- $group_order_fee = 0;// 单个商户订单运费
- $is_free = false;// 是否免邮
- $compute_shipping = [];// 运费计算,配合运费规则compute_type == 2使用
- // 获取包邮地区
- $feeShippingRules = FreeShippingRules::getFreeShippingRulesArea($item['mch_order_info']['mall_id'], $item['mch_order_info']['mch_id']);
- // 获取运费模板
- $freightRules = FreightRules::getFreightRulesArea($item['mch_order_info']['mall_id'], $item['mch_order_info']['mch_id']);
- // 包邮计算
- foreach ($feeShippingRules as $fee) {
- // 如果包邮金额<=购买商品金额,并且地区符合收货地址则免邮
- if ($fee['money'] <= $item['mch_order_info']['goods_price'] && self::isInArea($address, $fee['district_ids'])) {
- $is_free = true;
- continue;
- }
- }
- // 不免邮处理
- if ($is_free == false) {
- foreach ($item['goods'] as $good_id => $good) {
- $good_info = Goods::findOne(['id' => $good_id]);
- if($good_info['goods_type'] == GoodsTypeEnum::GoodsTypeVirtual) continue;
- $good_num = 0;// 第N个商品
- if ($good['num'] > 1) {
- $good_num+= $good['num'];
- } else {
- $good_num++;
- }
- // 物流方式
- if (!in_array(ShippingTypeEnum::LOGISTICS, explode(',', $form['sku'][$good_id]['goods']['freight_type']))) continue;
- // 计算满件包邮
- if ($form['sku'][$good_id]['goods']['free_shipping_num'] > 0 && $good['num'] >= $form['sku'][$good_id]['goods']['free_shipping_num']) continue;
- // 计算满元包邮
- if ($form['sku'][$good_id]['goods']['free_shipping_money'] > 0 && $good['goods_price'] >= $form['sku'][$good_id]['goods']['free_shipping_money']) continue;
- // 运费规则
- if ($form['sku'][$good_id]['goods']['freight_rules_type'] == 1) {
- // 根据商品id获取对应的规则
- $thisRules = isset($freightRules[$form['sku'][$good_id]['goods']['freight_id']])
- ? $freightRules[$form['sku'][$good_id]['goods']['freight_id']]
- : [];
- // 运费模板ID
- $rule_id = $thisRules['id'] ?? 0;
- if(!empty($thisRules['rule'])){
- foreach ($thisRules['rule'] as $rule) {
- // 获取该模板的所有地区id
- $areaArr = array_column($rule['list'], 'id');
- // 判断收货地址是否在模板中
- if (self::isInArea($address, $areaArr)) {
- if ($thisRules['type'] == 1) {// 按重计费
- $new_num_weight = $form['sku'][$good_id]['weight'] * $good['num'];
- } else {// 按件计费
- $new_num_weight = $good['num'];
- }
- // 计算[首件/首重]收费,只要商品有重量并且运费有首重设置就需要给运费
- if ($new_num_weight > 0 && $rule['first'] > 0) {
- if ($thisRules['compute_type'] == 1) {
- $group_order_fee += $rule['firstPrice'];
- $shipping_fee += $rule['firstPrice'];
- }
- }
- if ($thisRules['type'] == 1) {// 计算续重收费
- if ($thisRules['compute_type'] == 2) {// 按同件商品计算,扣除首重后,剩余不同商品都按续重计算
- self::getShopFee($rule_id, $thisRules['type'], $rule, $new_num_weight, $compute_shipping);
- } else {
- $surplus_weight = $new_num_weight - $rule['first'];// 剩余重量 = 总重量 - 首重重量
- // 续重运费 = (剩余重量 / 续件重量)[向上取整] * 续重费用 [向下取整]
- if($surplus_weight > 0 && isset($rule['second'])&&$rule['second']>0) {
- $fee = floor(ceil($surplus_weight / $rule['second']) * $rule['secondPrice']);
- $shipping_fee += $fee;
- $group_order_fee += $fee;
- }
- }
- } else {// 计算续件收费
- if ($thisRules['compute_type'] == 2) {// 按同件商品计算,扣除首件后,剩余不同商品都按续件计算
- self::getShopFee($rule_id, $thisRules['type'], $rule, $new_num_weight, $compute_shipping);
- } else {
- $surplus_num = $good_num - $rule['first'];// 减扣首件数量
- if ($surplus_num > 0 && $rule['second'] > 0) {
- // 续费 * (减扣首件数量 / 续件数量)[向下取整]
- if(isset($rule['second']) && $rule['second'] > 0){
- $fee = $rule['secondPrice'] * floor($surplus_num / $rule['second']);
- $shipping_fee += $fee;
- $group_order_fee += $fee;
- }
- }
- }
- }
- continue;// 已计算好运费则跳出循环
- }
- }
- }
- } else {
- // 自定义运费
- if ($form['sku'][$good_id]['goods']['shipping_fee'] >= 0) {
- $shipping_fee+= $form['sku'][$good_id]['goods']['shipping_fee'];
- $group_order_fee+= $form['sku'][$good_id]['goods']['shipping_fee'];
- }
- }
- }
- // 按同件商品运费计算
- if ($compute_shipping) {
- $shop_fee_assignment = self::shopFeeAssignment($compute_shipping);
- $shipping_fee += $shop_fee_assignment['shipping_fee'] ?? 0;
- $group_order_fee += $shop_fee_assignment['group_order_fee'] ?? 0;
- }
- // 单个商户订单运费计算
- $item['mch_order_info']['shipping_type'] = $form['data']['shipping_type'] ?? ShippingTypeEnum::LOGISTICS;
- $item['mch_order_info']['shipping_money'] = $group_order_fee;
- }
- // 运费赋值
- $item['mch_order_info']['pay_money'] = $item['mch_order_info']['pay_money'] + $shipping_fee;
- $prev_shipping_fee = $form->marketing['deduct']['shipping_fee']['money'] ?? 0;
- $form->marketing['deduct']['shipping_fee'] = ['name' => '运费', 'money' => $prev_shipping_fee + $shipping_fee];
- return $item;
- }
- /**
- * 判断收货地址是否在地区中
- * @Author: lun
- * @DateTime: 2021/9/30 0030 14:45
- * @Copyright: copyright (c) 2021 广东七件事集团
- * @param $address
- * @param $areaArr
- * @return bool
- */
- private static function isInArea($address, $areaArr)
- {
- $return = false;
- if(in_array($address['province_id'], $areaArr) || in_array($address['city_id'], $areaArr) || in_array($address['district_id'], $areaArr)) $return = true;
- return $return;
- }
- /**
- * 运费模板为:按同件商品计算
- * 目的:不同商品使用不同的模板情况下的混合计算,主要算出:首件/重 + 续件/重 运费费用
- * @Author: lun
- * @DateTime: 2023/8/12 0012 17:11
- * @Copyright: copyright (c) 2021 广东七件事集团
- * @param $rule_id
- * @param $rule
- * @param $goods_weight_or_num
- * @param array $data
- */
- private static function getShopFee($rule_id, $type, $rule, $goods_weight_or_num, &$data = [])
- {
- $data[$rule_id]['total_weight_or_num'] = empty($data[$rule_id]['total_weight_or_num']) ? $goods_weight_or_num : $data[$rule_id]['total_weight_or_num'] + $goods_weight_or_num;
- if (empty($data[$rule_id]['first_fee'])) $data[$rule_id]['first_fee'] = $rule['firstPrice'];// 首重/件 费用
- if (empty($data[$rule_id]['group_first_fee'])) $data[$rule_id]['group_first_fee'] = $rule['firstPrice'];// 首重/件 费用
- if (empty($data[$rule_id]['first_weight_or_num'])) $data[$rule_id]['first_weight_or_num'] = $rule['first'];// 同模板商品首重
- if (empty($data[$rule_id]['renew_price'])) $data[$rule_id]['renew_price'] = 0;// 续重/件 费用
- $surplus_weight_or_num = $data[$rule_id]['total_weight_or_num'] - $data[$rule_id]['first_weight_or_num'];// 总重量/总数量 - 首重/件 = 续重/件
- // 续重/件运费 = (剩余重量 / 续件重量)[向上取整] * 续重费用 [向下取整]
- if($surplus_weight_or_num > 0 && isset($rule['second']) && $rule['second'] > 0) {
- if ($type == 2) {// 按件计费
- $fee = $rule['secondPrice'] * floor($surplus_weight_or_num / $rule['second']);
- } else {// 按重计费
- $fee = floor(ceil($surplus_weight_or_num / $rule['second']) * $rule['secondPrice']);
- }
- $data[$rule_id]['renew_price'] = $fee;// 每次都覆盖之前的值,为了重新算出最后的续重/件费用
- }
- }
- /**
- * 将计算好的不同运费模板运费加起来
- * @Author: lun
- * @DateTime: 2023/8/12 0012 17:13
- * @Copyright: copyright (c) 2021 广东七件事集团
- * @param $shopFeeList
- * @return array
- */
- private static function shopFeeAssignment($shopFeeList)
- {
- $shop_fee = 0;
- $group_order_fee = 0;
- foreach ($shopFeeList as $item) {
- $shop_fee += $item['first_fee'] + $item['renew_price'];
- $group_order_fee += $item['group_first_fee'] + $item['renew_price'];
- }
- return ['shipping_fee' => $shop_fee, 'group_order_fee' => $group_order_fee];
- }
- }
|