|
|
@@ -2,12 +2,14 @@
|
|
|
|
|
|
namespace App\Services;
|
|
|
|
|
|
+use App\OwnerFeeDetail;
|
|
|
use App\OwnerPriceOperation;
|
|
|
use App\OwnerPriceOperationItem;
|
|
|
use App\Services\common\QueryService;
|
|
|
use App\Unit;
|
|
|
use Illuminate\Database\Eloquent\Builder;
|
|
|
use Illuminate\Database\Eloquent\Model;
|
|
|
+use Illuminate\Support\Facades\Cache;
|
|
|
use Illuminate\Support\Facades\DB;
|
|
|
use App\Traits\ServiceAppAop;
|
|
|
|
|
|
@@ -86,7 +88,7 @@ Class OwnerPriceOperationService
|
|
|
|
|
|
/** 参数顺序: 数量 匹配对象 列映射 货主ID 单位ID 类型 SKU .
|
|
|
* 匹配顺序: 类型 货主 策略 单位 特征 ..多对多匹配规则废弃,1对1,设单位必定为件,对应规则必然只有一项存在
|
|
|
- * 单位匹配: 件,箱,单 由小到大,依次换算匹配 .
|
|
|
+ * 单位匹配: 件,箱 由小到大,依次换算匹配 .
|
|
|
*
|
|
|
* 2:没有总数量存在,都为子项内数量
|
|
|
*
|
|
|
@@ -94,15 +96,18 @@ Class OwnerPriceOperationService
|
|
|
* @param array $columnMapping key-val
|
|
|
* @param string $owner_id
|
|
|
* @param string $type
|
|
|
- * @return double
|
|
|
+ * @return double|array
|
|
|
* 错误代码: -1:无匹配对象 -2:无计费模型 -3:未知单位 -4:sku为空 -5:货主未找到 -6:无箱规 -7:未匹配到计费模型
|
|
|
*
|
|
|
* 一. 2020-10-10 zzd
|
|
|
* 二. 2021-01-08 zzd
|
|
|
+ * 三. 2021-01-28 zzd
|
|
|
+ * 增加满减策略:子策略匹配时不再考虑单,仅件箱换算,满减满足后标记模型修改历史对账单
|
|
|
+ * 增加按订单计价策略:主匹配模型增加字段量价,该字段存在时视为按单计价,价格为该值
|
|
|
*/
|
|
|
public function matching($matchObject, $columnMapping, $owner_id, $type = '出库')
|
|
|
{
|
|
|
- $unitModels = Unit::query()->whereIn("name",["件","箱","单"])->get();
|
|
|
+ $unitModels = Unit::query()->whereIn("name",["件","箱"])->get();
|
|
|
$units = [];
|
|
|
foreach ($unitModels as $unitModel)$units[$unitModel->id] = $unitModel->name;
|
|
|
|
|
|
@@ -114,69 +119,80 @@ Class OwnerPriceOperationService
|
|
|
$query->where("id",$owner_id);
|
|
|
})->orderByRaw("strategy desc,priority desc")->get(); //货主下的全部规则
|
|
|
|
|
|
- if (!$rules)return -2;
|
|
|
+ if (!$rules)return -2; //规则不存在跳出
|
|
|
|
|
|
- /*if ($type == '入库'){
|
|
|
- $amountColumn = $columnMapping["amount"] ?? "amount";
|
|
|
- $packageColumn = $columnMapping["packages"] ?? "packages";
|
|
|
- $packages = $matchObject[$packageColumn] ?? false;
|
|
|
- if (!$packages)return -1;
|
|
|
+ $total = Cache::get(date("Y-m")."_".$matchObject["owner_id"]); //获取该货主本月单量
|
|
|
+ foreach ($rules as $rule){
|
|
|
+ if (!$rule->items)continue; //不存在子规则跳出
|
|
|
+ $isDiscount = false; //是否存在满减
|
|
|
+ if ($type=='出库' && $rule->discount_count > 0 && $total >= $rule->discount_count)$isDiscount = true;//满足满减条件
|
|
|
+ //满减存在且未被标记过处理时间或处理时间不为本月,处理历史即时账单
|
|
|
+ if ($isDiscount && (!$rule->discount_date || substr($rule->discount_date,0,7)!=date("Y-m"))){
|
|
|
+ try{
|
|
|
+ DB::beginTransaction();
|
|
|
+ $month = date("Y-m");
|
|
|
+ $day = date("t",strtotime($month));
|
|
|
+ foreach (OwnerFeeDetail::query()->with(["order.logistic","order.shop","order.packages.commodities.commodity"])
|
|
|
+ ->where("owner_id",$owner_id)
|
|
|
+ ->whereBetween("worked_at",[$month."-01",$month."-".$day])->get() as $detail){
|
|
|
+ $order = $detail->order;
|
|
|
|
|
|
- $amount = 0;
|
|
|
- foreach ($packages as $package)$amount += $package[$amountColumn] ?? 0;
|
|
|
- if (!$amount)return -1;
|
|
|
- foreach ($rules as $rule){
|
|
|
- $sum = $amount;
|
|
|
- if (!$rule->in)continue;
|
|
|
- if ($rule->strategy == '特征'){
|
|
|
- $bool = app("FeatureService")->matchFeature($rule->feature,$columnMapping,$matchObject);
|
|
|
- if ($bool === true){
|
|
|
- if (!isset($units[$rule->in->unit_id])) return -3;
|
|
|
- if ($units[$rule->in->unit_id] == '箱'){ //为箱时同步商品寻找箱规
|
|
|
- $sumTemp = 0;
|
|
|
- $packageColumn = $columnMapping["packages"] ?? "packages";
|
|
|
- foreach ($matchObject[$packageColumn] as $commodity){
|
|
|
- $sumTemp += $this->changeUnit($sum,$owner_id,$commodity["sku"]);
|
|
|
+ $logistic_fee = 0;
|
|
|
+ $commodities = [];
|
|
|
+ foreach ($order->packages as &$package){
|
|
|
+ // 四维转二维
|
|
|
+ foreach($package->commodities as &$commodity){
|
|
|
+ $commodity["commodity_name"] = $commodity->commodity ? $commodity->commodity->name : '';
|
|
|
+ $commodity["sku"] = $commodity->commodity ? $commodity->commodity->sku : '';
|
|
|
}
|
|
|
- $sum = $sumTemp;
|
|
|
- if ($sum<0)return $sum;
|
|
|
+ $commodities = array_merge($commodities,$package->commodities->toArray());
|
|
|
}
|
|
|
- if ($units[$rule->in->unit_id] == '单')$sum = 1; //为单时数量设为1;
|
|
|
- return ceil($sum/$rule->in->amount)*$rule->in->unit_price;
|
|
|
+ if ($logistic_fee!==null && $logistic_fee<0)$logistic_fee = null;
|
|
|
+
|
|
|
+ $object = ["commodities"=>$commodities,
|
|
|
+ "logistic_name"=>($order->logistic ? $order->logistic->name : ''),
|
|
|
+ "shop_name"=>($order->shop ? $order->shop->name : ''),
|
|
|
+ "order_type"=>$order->order_type,
|
|
|
+ "owner_id"=>$order->owner_id];
|
|
|
+ $mapping = ["packages"=>"commodities","商品名称"=>"commodity_name",
|
|
|
+ "承运商"=>"logistic_name", "店铺类型"=>"shop_name",
|
|
|
+ "订单类型"=>"order_type","订单数"=>"amount"];
|
|
|
+ $money = $this->matchItem($rule->items,$mapping,$object,$units,$owner_id,'出库',$isDiscount);
|
|
|
+ if ($money>0)$detail->update(["work_fee"=>$money]);
|
|
|
+ else LogService::log(__CLASS__,"处理历史即时账单时发生匹配错误","账单主键:".$detail->id."; 错误代码".$money);
|
|
|
};
|
|
|
- }else{
|
|
|
- if (!isset($units[$rule->in->unit_id])) return -3;
|
|
|
- if ($units[$rule->in->unit_id] == '箱'){ //为箱时同步商品寻找箱规
|
|
|
- $sumTemp = 0;
|
|
|
- $packageColumn = $columnMapping["packages"] ?? "packages";
|
|
|
- foreach ($matchObject[$packageColumn] as $commodity){
|
|
|
- $sumTemp += $this->changeUnit($sum,$owner_id,$commodity["sku"]);
|
|
|
- }
|
|
|
- $sum = $sumTemp;
|
|
|
- if ($sum<0)return $sum;
|
|
|
- }
|
|
|
- if ($units[$rule->in->unit_id] == '单')$sum = 1; //为单时数量设为1;
|
|
|
- return ceil($sum/$rule->in->amount)*$rule->in->unit_price;
|
|
|
- };
|
|
|
+ $rule->update(["discount_date"=>date("Y-m-d")]);
|
|
|
+ DB::commit();
|
|
|
+ }catch (\Exception $e){
|
|
|
+ DB::rollBack();
|
|
|
+ LogService::log(__CLASS__,"处理历史即时账单时发生系统错误","计费模型主键:".$rule->id."; 错误信息".$e->getMessage());
|
|
|
+ }
|
|
|
}
|
|
|
- return -7;
|
|
|
- }*/
|
|
|
- foreach ($rules as $rule){
|
|
|
-
|
|
|
- if (!$rule->items)continue;
|
|
|
- if ($rule->strategy == '特征'){
|
|
|
+ if ($rule->strategy == '特征'){//特征策略匹配
|
|
|
$bool = app("FeatureService")->matchFeature($rule->feature,$columnMapping,$matchObject);
|
|
|
if ($bool === true){
|
|
|
- $money = $this->matchItem($rule->items,$columnMapping,$matchObject,$units,$owner_id,$type=='入库' ? true : false);
|
|
|
- if ($money>0)return $money;
|
|
|
+ if ($rule->total_price)return $isDiscount ? $rule->total_discount_price : $rule->total_price; //按单计价存在,直接返回单总价或减免总价
|
|
|
+ $money = $this->matchItem($rule->items,$columnMapping,$matchObject,$units,$owner_id,$type=='入库' ? true : false,$isDiscount);
|
|
|
+ if ($money>0)return ["id"=>$rule->id,"money"=>$money];
|
|
|
};
|
|
|
- }else{
|
|
|
- $money = $this->matchItem($rule->items,$columnMapping,$matchObject,$units,$owner_id,$type=='入库' ? true : false);
|
|
|
- if ($money>0)return $money;
|
|
|
+ }else{//默认策略匹配
|
|
|
+ if ($rule->total_price)return $isDiscount ? $rule->total_discount_price : $rule->total_price; //按单计价存在,直接返回单总价或减免总价
|
|
|
+ $money = $this->matchItem($rule->items,$columnMapping,$matchObject,$units,$owner_id,$type=='入库' ? true : false,$isDiscount);
|
|
|
+ if ($money>0)return ["id"=>$rule->id,"money"=>$money];
|
|
|
};
|
|
|
}
|
|
|
return $money ?? -7;
|
|
|
}
|
|
|
+ /**
|
|
|
+ * 根据货主 sku寻找箱规并将指定数量切换为箱
|
|
|
+ * 不满一箱视为一箱
|
|
|
+ *
|
|
|
+ * @param integer $amount
|
|
|
+ * @param integer $owner_id
|
|
|
+ * @param string $sku
|
|
|
+ *
|
|
|
+ * @return int
|
|
|
+ */
|
|
|
private function changeUnit($amount,$owner_id,$sku)
|
|
|
{
|
|
|
if (!$sku)return -4;
|
|
|
@@ -185,7 +201,20 @@ Class OwnerPriceOperationService
|
|
|
return ceil($amount/$pack);
|
|
|
}
|
|
|
|
|
|
- private function matchItem($rules, $columnMapping, $matchObject, $units, $owner_id, $isIn)
|
|
|
+ /**
|
|
|
+ * 匹配子策略
|
|
|
+ *
|
|
|
+ * @param array $rules 策略对象组
|
|
|
+ * @param array $columnMapping 映射对象
|
|
|
+ * @param array $matchObject 被匹配对象
|
|
|
+ * @param array $units 单位集
|
|
|
+ * @param integer $owner_id 货主ID
|
|
|
+ * @param bool $isIn 是否为入库单
|
|
|
+ * @param bool $isDiscount 是否为满减单
|
|
|
+ *
|
|
|
+ * @return double
|
|
|
+ */
|
|
|
+ private function matchItem($rules, $columnMapping, $matchObject, $units, $owner_id, $isIn, $isDiscount)
|
|
|
{
|
|
|
$amountColumn = $columnMapping["amount"] ?? "amount";
|
|
|
$packageColumn = $columnMapping["packages"] ?? "packages";
|
|
|
@@ -195,6 +224,7 @@ Class OwnerPriceOperationService
|
|
|
|
|
|
$unitName = "";
|
|
|
foreach ($rules as $rule){
|
|
|
+ if ($isDiscount)$rule->unit_price = $rule->discount_price; //满足满减条件,单价调整为满减单价
|
|
|
switch ($rule->strategy){
|
|
|
case "特征":
|
|
|
$inMoney = 0;
|
|
|
@@ -208,7 +238,7 @@ Class OwnerPriceOperationService
|
|
|
return -3;
|
|
|
}
|
|
|
$package["price"] = $rule->unit_price;
|
|
|
- if (!isset($units[$rule->unit_id]) || $units[$rule->unit_id] == '单')return -3;
|
|
|
+ if (!isset($units[$rule->unit_id]))return -3;
|
|
|
if ($units[$rule->unit_id] == '箱'){ //为箱时同步商品寻找箱规
|
|
|
$sumTemp = 0;
|
|
|
$packageColumn = $columnMapping["packages"] ?? "packages";
|
|
|
@@ -236,7 +266,7 @@ Class OwnerPriceOperationService
|
|
|
}
|
|
|
|
|
|
$package["price"] = $rule->unit_price;
|
|
|
- if (!isset($units[$rule->unit_id]) || $units[$rule->unit_id] == '单')return -3;
|
|
|
+ if (!isset($units[$rule->unit_id]))return -3;
|
|
|
if ($units[$rule->unit_id] == '箱'){ //为箱时同步商品寻找箱规
|
|
|
$sumTemp = 0;
|
|
|
$packageColumn = $columnMapping["packages"] ?? "packages";
|
|
|
@@ -281,7 +311,7 @@ Class OwnerPriceOperationService
|
|
|
}
|
|
|
return -7;
|
|
|
}
|
|
|
- //设置数量
|
|
|
+ //递归式重新设置数量
|
|
|
private function settingCount($packages,$amountColumn,$startNumber)
|
|
|
{
|
|
|
if (!$packages) return null;
|