<?php
namespace app\common\service\delivery;
use app\common\library\helper;
use app\common\model\Setting as SettingModel;
use app\common\enum\OrderType as OrderTypeEnum;
class Express
{
private $wxappId; private $cityId; private $goodsList; private $orderType;
public function __construct(
$wxappId,
$cityId,
$goodsList,
$orderType = OrderTypeEnum::MASTER
)
{
$this->wxappId = $wxappId;
$this->cityId = $cityId;
$this->goodsList = $goodsList;
$this->orderType = $orderType;
}
public function getNotInRuleGoods()
{
if ($this->cityId) {
foreach ($this->goodsList as &$goods) {
$cityIds = [];
foreach ($goods['delivery']['rule'] as $item)
$cityIds = array_merge($cityIds, $item['region_data']);
if (!in_array($this->cityId, $cityIds))
return $goods;
}
}
return false;
}
public function setExpressPrice()
{
$orderTotalPrice = helper::getArrayColumnSum($this->goodsList, 'total_price');
foreach ($this->goodsList as &$goods) {
$goods['express_price'] = $this->onCalcGoodsfreight($goods, $orderTotalPrice);
}
return true;
}
public function getTotalFreight()
{
if (empty($this->goodsList)) {
return 0.00;
}
$expressPriceArr = helper::getArrayColumn($this->goodsList, 'express_price');
if (empty($expressPriceArr)) {
return 0.00;
}
return $this->freightRule($expressPriceArr);
}
private function onCalcGoodsfreight(&$goods, $orderTotalPrice)
{
if ($this->isFullFree($goods['goods_id'], $orderTotalPrice)) {
return 0.00;
}
$rule = $this->getCityDeliveryRule($goods);
$totalWeight = helper::bcmul($goods['goods_sku']['goods_weight'], $goods['total_num']);
$total = $goods['delivery']['method']['value'] == 10 ? $goods['total_num'] : $totalWeight;
if ($total <= $rule['first']) {
return helper::number2($rule['first_fee']);
}
$additional = $total - $rule['first'];
if ($additional <= $rule['additional']) {
return helper::number2(helper::bcadd($rule['first_fee'], $rule['additional_fee']));
}
if ($rule['additional'] < 1) {
$additionalFee = 0.00;
} else {
$additionalFee = helper::bcdiv($rule['additional_fee'], $rule['additional']) * $additional;
}
return helper::number2(helper::bcadd($rule['first_fee'], $additionalFee));
}
private function isFullFree($goodsId, $orderTotalPrice)
{
if ($this->orderType !== OrderTypeEnum::MASTER) {
return false;
}
$options = SettingModel::getItem('full_free', $this->wxappId);
if (
$options['is_open'] == false
|| $orderTotalPrice < $options['money']
|| in_array($goodsId, $options['notin_goods'])
|| in_array($this->cityId, $options['notin_region']['citys'])
) {
return false;
}
return true;
}
private function getCityDeliveryRule(&$goods)
{
foreach ($goods['delivery']['rule'] as $item) {
if (in_array($this->cityId, $item['region_data'])) {
return $item;
}
}
return false;
}
private function freightRule($expressPriceArr)
{
$expressPrice = 0.00;
switch (SettingModel::getItem('trade', $this->wxappId)['freight_rule']) {
case '10': $expressPrice = array_sum($expressPriceArr);
break;
case '20': $expressPrice = min($expressPriceArr);
break;
case '30': $expressPrice = max($expressPriceArr);
break;
}
return $expressPrice;
}
}