You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
206 lines
6.9 KiB
206 lines
6.9 KiB
<?php
|
|
|
|
namespace api\logic;
|
|
|
|
|
|
use backend\modules\goods\models\ars\Goods;
|
|
use backend\modules\shop\models\ars\ExpressArea;
|
|
use backend\modules\shop\models\ars\ExpressTemplate;
|
|
use backend\modules\shop\models\ars\Order;
|
|
use backend\modules\shop\models\ars\OrderGoods;
|
|
use Yii;
|
|
use yii\base\BaseObject;
|
|
use yii\web\NotFoundHttpException;
|
|
|
|
/**
|
|
* @author iron
|
|
* @email weiriron@gmail.com
|
|
* @package api\logic
|
|
*/
|
|
class ExpressLogic extends BaseObject
|
|
{
|
|
public $viewAction = 'view';
|
|
/**
|
|
* @var Order
|
|
* 订单
|
|
*/
|
|
public $order;
|
|
|
|
/**
|
|
* @param $order
|
|
* @return float|int
|
|
* @throws NotFoundHttpException
|
|
* 计算运费
|
|
*/
|
|
public function countShippingAmount($order)
|
|
{
|
|
if ($order->shipping_type == Order::SHIPPING_TYPE_PICKED_UP) {
|
|
return 0;
|
|
}
|
|
$this->order = $order;
|
|
$allGoods = $this->findDifferentExpressTypeGoods($order);/*获取不同运费计算模式的商品*/
|
|
$uniformPostage = $this->countGoodsExpress($allGoods['uniformPostageGoods'], Goods::EXPRESS_TYPE_UNIFORM_POSTAGE);/*计算统一运费模式下所有商品运费*/
|
|
$expressTemplate = $this->countGoodsExpress($allGoods['uniformPostageGoods'], Goods::EXPRESS_TYPE_EXPRESS_TEMPLATE);/*计算运费模板模式下所有商品的运费*/
|
|
return $uniformPostage > $expressTemplate ? $uniformPostage : $expressTemplate;/*比较两种不同运费计算模式下,取金额大的值为最终收取运费*/
|
|
}
|
|
|
|
/*--------------------------------------------------------------------------------------*/
|
|
/**
|
|
* @param $order
|
|
* @return array
|
|
* @throws NotFoundHttpException
|
|
* 获取不同运费计算模式的商品
|
|
*/
|
|
private function findDifferentExpressTypeGoods($order)
|
|
{
|
|
$uniformPostage = $useTemplate = [];
|
|
$allGoods = OrderGoods::findAll(['order_id' => $order->id, 'user_id' => Yii::$app->user->getId()]);
|
|
foreach ($allGoods as $orderGoods) {
|
|
$goods = Goods::findOne(['id' => $orderGoods->goods_id, 'is_sale' => Goods::IS_SALE_YES, 'is_delete' => Goods::IS_DELETE_NO]);
|
|
if (!$goods) {
|
|
throw new NotFoundHttpException('商品未找到');
|
|
}
|
|
$goodsArr['object'] = $goods;
|
|
$goodsArr['count'] = $orderGoods->goods_count;
|
|
$goodsArr['weight'] = $orderGoods->weight;
|
|
if ($goods->is_express && $goods->express_type == Goods::EXPRESS_TYPE_UNIFORM_POSTAGE) {
|
|
$uniformPostage[] = $goodsArr;
|
|
}
|
|
if ($goods->is_express && $goods->express_type == Goods::EXPRESS_TYPE_EXPRESS_TEMPLATE) {
|
|
$useTemplate[] = $goodsArr;
|
|
}
|
|
}
|
|
return ['uniformPostageGoods' => $uniformPostage, 'useTemplateGoods' => $useTemplate];
|
|
}
|
|
|
|
/**
|
|
* @param $allGoods
|
|
* @param $type
|
|
* @return float|int
|
|
* @throws NotFoundHttpException
|
|
* 根据不同计费模式计算商品运费
|
|
*/
|
|
private function countGoodsExpress($allGoods, $type)
|
|
{
|
|
if (!$type == Goods::EXPRESS_TYPE_UNIFORM_POSTAGE) {
|
|
$amount = 0;
|
|
foreach ($allGoods['object'] as $goods) {
|
|
$amount = $goods->uniform_postage > $amount ? $goods->uniform_postage : $amount;
|
|
}
|
|
return $amount;
|
|
} else {
|
|
$extraPrice = 0;
|
|
$areasIds = [];
|
|
foreach ($allGoods['object'] as $k => $goods) {
|
|
/*计算增重运费*/
|
|
$extraPrice += $this->countExtraAmount($allGoods['count'][$k], $allGoods['weight'][$k], $goods->express_template);
|
|
$areasIds[] = $this->getAreaId($goods->express_template);
|
|
}
|
|
$basic = $this->getBasicPriceAndAreaId($areasIds);/*获取首重运费和对应的计费规则id*/
|
|
/*返回所有按运费模板计费的商品运费(基础运费 + 所有商品增重运费 - 多余的增重运费)*/
|
|
return $basic['price'] + $extraPrice - $this->countSurplusPrice($basic['id']);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @param $areaId
|
|
* @return float|int
|
|
* @throws NotFoundHttpException
|
|
* 计算多余(多算的)运费
|
|
* 选定作为基础运费的计费规则对应商品基础数量内的增重费用
|
|
*/
|
|
private function countSurplusPrice($areaId)
|
|
{
|
|
$area = $this->findArea($areaId);
|
|
return $area->extra_price * ceil($area->basic_count / $area->extra_count);
|
|
}
|
|
|
|
/**
|
|
* @param $areaIds
|
|
* @return array
|
|
* @throws NotFoundHttpException
|
|
* 获取基础运费
|
|
*/
|
|
private function getBasicPriceAndAreaId($areaIds)
|
|
{
|
|
$basePrice = $id = 0;
|
|
foreach ($areaIds as $areasId) {
|
|
$area = $this->findArea($areasId);
|
|
if (!$area->basic_price > $basePrice) {
|
|
continue;
|
|
}
|
|
$basePrice = $area->basic_price;
|
|
$id = $areasId;
|
|
}
|
|
return ['price' => $basePrice, 'id' => $id];
|
|
}
|
|
|
|
/**
|
|
* @param $count
|
|
* @param $weight
|
|
* @param $templateId
|
|
* @return float|int
|
|
* @throws NotFoundHttpException
|
|
* 计算增重运费
|
|
*/
|
|
private function countExtraAmount($count, $weight, $templateId)
|
|
{
|
|
$area = $this->findArea($this->getAreaId($templateId));
|
|
$template = $this->findTemplate($templateId);
|
|
if ($template->calculation_type == ExpressTemplate::CALCULATION_TYPE_WEIGHT) {
|
|
$amount = $area->extra_price * ceil($weight / $area->extra_count);
|
|
} else {
|
|
$amount = $area->extra_price * ceil($count / $area->extra_count);
|
|
}
|
|
return $amount;
|
|
}
|
|
|
|
/**
|
|
* @param $templateId
|
|
* @return int
|
|
* @throws NotFoundHttpException
|
|
* 根据运费模板和收货地址获取区域
|
|
*/
|
|
private function getAreaId($templateId)
|
|
{
|
|
$areas = ExpressArea::findALl(['express_template' => $templateId]);
|
|
$city = $this->order->city;
|
|
foreach ($areas as $area) {
|
|
$allCity = explode(',', $area->city);
|
|
if (in_array($city, $allCity)) {
|
|
return $area->id;
|
|
}
|
|
}
|
|
throw new NotFoundHttpException('超出配送范围(无对应地区运费计算规则)');
|
|
}
|
|
|
|
/**
|
|
* @param $areaId
|
|
* @return ExpressArea|null
|
|
* @throws NotFoundHttpException
|
|
* 获取对应区域
|
|
*/
|
|
private function findArea($areaId)
|
|
{
|
|
$area = ExpressArea::findOne($areaId);
|
|
if (!$area) {
|
|
throw new NotFoundHttpException('模板地区未找到');
|
|
}
|
|
return $area;
|
|
}
|
|
|
|
/**
|
|
* @param $templateId
|
|
* @return ExpressTemplate|null
|
|
* @throws NotFoundHttpException
|
|
* 获取运费模板
|
|
*/
|
|
private function findTemplate($templateId)
|
|
{
|
|
$template = ExpressTemplate::findOne($templateId);
|
|
if (!$template) {
|
|
throw new NotFoundHttpException('运费模板未找到');
|
|
}
|
|
return $template;
|
|
}
|
|
}
|