|
|
@@ -2,12 +2,13 @@
|
|
|
|
|
|
namespace App\Services;
|
|
|
|
|
|
+use App\Feature;
|
|
|
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\Collection;
|
|
|
use Illuminate\Database\Eloquent\Model;
|
|
|
use Illuminate\Support\Facades\Cache;
|
|
|
use Illuminate\Support\Facades\DB;
|
|
|
@@ -43,10 +44,10 @@ class OwnerPriceOperationService
|
|
|
}
|
|
|
|
|
|
|
|
|
- private function ownerGetIds(string $owner_id)
|
|
|
+ private function ownerGetIds(string $ownerId)
|
|
|
{
|
|
|
- if (!$owner_id)return [];
|
|
|
- $arr = DB::select(DB::raw("SELECT owner_price_operation_id AS id FROM owner_price_operation_owner WHERE owner_id in (".$owner_id.")"));
|
|
|
+ if (!$ownerId)return [];
|
|
|
+ $arr = DB::select(DB::raw("SELECT owner_price_operation_id AS id FROM owner_price_operation_owner WHERE owner_id in (".$ownerId.")"));
|
|
|
return array_column($arr,"id");
|
|
|
}
|
|
|
|
|
|
@@ -99,9 +100,16 @@ class OwnerPriceOperationService
|
|
|
}
|
|
|
}else{
|
|
|
foreach ($items as $item){
|
|
|
- $item["owner_price_operation_id"] = $copyModel->id;
|
|
|
- $item["discount_price"] = implode(",",($item["discount_price"] ? $item["discount_price"] : [])) ?? null;
|
|
|
- $insert[] = $item;
|
|
|
+ $arr = [];
|
|
|
+ $arr["owner_price_operation_id"] = $copyModel->id;
|
|
|
+ $arr["strategy"] = $item["strategy"];
|
|
|
+ $arr["amount"] = $item["amount"] ?? null;
|
|
|
+ $arr["unit_id"] = $item["unit_id"];
|
|
|
+ $arr["unit_price"] = $item["unit_price"];
|
|
|
+ $arr["feature"] = $item["feature"] ?? null;
|
|
|
+ $arr["priority"] = $item["priority"] ?? 0;
|
|
|
+ $arr["discount_price"] = isset($item["discount_price"]) ? (is_array($item["discount_price"]) ? implode(",",$item["discount_price"]) : $item["discount_price"]) : null;
|
|
|
+ $insert[] = $arr;
|
|
|
}
|
|
|
}
|
|
|
if ($insert)OwnerPriceOperationItem::query()->insert($insert);
|
|
|
@@ -121,6 +129,8 @@ class OwnerPriceOperationService
|
|
|
$result = app(QueryService::class)->priceModelAuditOrRecoverQuery($isAudit,OwnerPriceOperation::query(),$ownerId,$ids);
|
|
|
if ($result["delete"])$this->destroy($result["delete"]);
|
|
|
if ($result["update"])OwnerPriceOperation::query()->whereIn("id",$result["update"])->update(["operation"=>null,"target_id"=>null]);
|
|
|
+ if (!is_array($ownerId))$ownerId = [$ownerId];
|
|
|
+ foreach ($ownerId as $ow)Cache::tags("operationFeeOwner:".$ow)->flush();
|
|
|
}
|
|
|
|
|
|
public function destroy($id)
|
|
|
@@ -180,6 +190,97 @@ class OwnerPriceOperationService
|
|
|
return $model->update($params);
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * 获取计费模型缓存
|
|
|
+ *
|
|
|
+ * @param integer $owner
|
|
|
+ * @param string $type
|
|
|
+ * @param int|null $typeMark
|
|
|
+ *
|
|
|
+ * @return array|Collection
|
|
|
+ *
|
|
|
+ */
|
|
|
+ public function getOwnerPriceOperation($owner, $type, $typeMark)
|
|
|
+ {
|
|
|
+ return Cache::tags("operationFeeOwner:".$owner)->remember("operationFee:".$owner.$type.$typeMark,config("cache.expirations.rarelyChange"),
|
|
|
+ function ()use($owner,$type,$typeMark){
|
|
|
+ $query = OwnerPriceOperation::query()->with(["items"=>function($query){
|
|
|
+ /** @var Builder $query */
|
|
|
+ $query->orderByRaw("CASE strategy WHEN '起步' THEN 1 WHEN '默认' THEN 2 WHEN '特征' THEN 3 END DESC,priority");
|
|
|
+ }])->where("operation_type",$type)->whereHas("owners",function ($query)use($owner){
|
|
|
+ /** @var Builder $query */
|
|
|
+ $query->where("id",$owner);
|
|
|
+ })->where(function(Builder $query){
|
|
|
+ $query->whereNull("operation")->orWhere("operation","");
|
|
|
+ })->orderByRaw("strategy desc,priority desc");
|
|
|
+
|
|
|
+ if ($typeMark!==null)$query->where("type_mark",$typeMark);
|
|
|
+ else $query->whereNull("type_mark");
|
|
|
+
|
|
|
+ return $query->get();
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取满减信息
|
|
|
+ *
|
|
|
+ * @param null|string $discount
|
|
|
+ * @param integer $total
|
|
|
+ *
|
|
|
+ * @return bool|array
|
|
|
+ */
|
|
|
+ public function getDiscount($discount, $total)
|
|
|
+ {
|
|
|
+ if ($discount){
|
|
|
+ foreach (array_reverse(explode(",",$discount),true) as $index=>$discount){
|
|
|
+ if ($total >= $discount)return [$index=>$discount];
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 处理折扣单
|
|
|
+ *
|
|
|
+ * @param object $rule
|
|
|
+ * @param integer $owner
|
|
|
+ * @param bool|array $result
|
|
|
+ */
|
|
|
+ public function handleDiscount($rule, $owner, $result)
|
|
|
+ {
|
|
|
+ $sign = false;
|
|
|
+ //入口仅在此处存在 缓存1000s
|
|
|
+ $key = "pivot_".$rule->id."_".$owner;
|
|
|
+ $discountIndex = key($result);
|
|
|
+ $targetValue = $result[$discountIndex];
|
|
|
+ $pivot = app(CacheService::class)->getOrExecute($key,function ()use($key,$targetValue,&$sign,$rule,$owner){
|
|
|
+ try{
|
|
|
+ DB::beginTransaction();
|
|
|
+ //此处暂时未使用cache的互斥锁 使用sql行锁代替下 防止缓存击穿
|
|
|
+ $pivot = DB::selectOne(DB::raw("SELECT * FROM owner_price_operation_owner WHERE owner_price_operation_id = ? AND owner_id = ? for update"),[$rule->id,$owner]);
|
|
|
+ if ($pivot && (!$pivot->discount_date || substr($pivot->discount_date,0,7)!=date("Y-m") || $pivot->target_value < $targetValue)){
|
|
|
+ //未被标记过处理时间或处理时间不为本月,或上次处理值过期,处理历史即时账单
|
|
|
+ $sign = true;
|
|
|
+ }
|
|
|
+ if ($sign){
|
|
|
+ //先标记成功 这将在后续推进历史单处理流程,防止程序在此堵塞
|
|
|
+ DB::update(DB::raw("UPDATE owner_price_operation_owner SET discount_date = ?,target_value = ? WHERE owner_price_operation_id = ? AND owner_id = ?"),
|
|
|
+ [date("Y-m-d"),$targetValue,$rule->id,$owner]);
|
|
|
+ $pivot->discount_date = date("Y-m-d");
|
|
|
+ $pivot->target_value = $targetValue;
|
|
|
+ Cache::put($key,$pivot,1000);
|
|
|
+ }
|
|
|
+ DB::commit();
|
|
|
+ }catch (\Exception $exception){
|
|
|
+ DB::rollBack();
|
|
|
+ LogService::log(__CLASS__,"即时账单满减处理失败",$exception->getMessage());
|
|
|
+ }
|
|
|
+ return $pivot ?? null;
|
|
|
+ },1000);
|
|
|
+ //进入历史单处理
|
|
|
+ if ($pivot && $sign)$this->handlePastBill($rule,$owner,$discountIndex,$pivot);
|
|
|
+ }
|
|
|
+
|
|
|
/** 参数顺序: 数量 匹配对象 列映射 货主ID 单位ID 类型 SKU .
|
|
|
* 匹配顺序: 类型 货主 策略 单位 特征 ..多对多匹配规则废弃,1对1,设单位必定为件,对应规则必然只有一项存在
|
|
|
* 单位匹配: 件,箱 由小到大,依次换算匹配 .
|
|
|
@@ -188,8 +289,10 @@ class OwnerPriceOperationService
|
|
|
*
|
|
|
* @param array|object $matchObject key-val
|
|
|
* @param array $columnMapping key-val
|
|
|
- * @param string $owner_id
|
|
|
+ * @param string $ownerId
|
|
|
* @param string $type
|
|
|
+ * @param int|null $typeMark
|
|
|
+ *
|
|
|
* @return double|array
|
|
|
* 错误代码: -1:无匹配对象 -2:无计费模型 -3:未知单位 -4:sku为空 -5:货主未找到 -6:无箱规 -7:未匹配到计费模型
|
|
|
*
|
|
|
@@ -200,83 +303,32 @@ class OwnerPriceOperationService
|
|
|
* 增加按订单计价策略:主匹配模型增加字段量价,该字段存在时视为按单计价,价格为该值
|
|
|
* 四. 2021-02-18 zzd
|
|
|
* 满减多阶段匹配 满减字段由单值改为字符串多值 匹配时转数组寻找最相近
|
|
|
+ * 五. 2021-03-18 zzd
|
|
|
+ * 区分单据类型,增加字段
|
|
|
+ * 六. 2021-03-23 zzd
|
|
|
+ * 不严格区分入库出库差异 统一模型
|
|
|
*/
|
|
|
- public function matching($matchObject, $columnMapping, $owner_id, $type = '出库')
|
|
|
+ public function matching($matchObject, $columnMapping, $ownerId, $type = '出库', $typeMark = null)
|
|
|
{
|
|
|
- $unitModels = Unit::query()->whereIn("name",["件","箱"])->get();
|
|
|
- $units = [];
|
|
|
- foreach ($unitModels as $unitModel)$units[$unitModel->id] = $unitModel->name;
|
|
|
-
|
|
|
- $rules = OwnerPriceOperation::query()->with(["items"=>function($query){
|
|
|
- /** @var Builder $query */
|
|
|
- $query->orderByRaw("CASE strategy WHEN '起步' THEN 1 WHEN '默认' THEN 2 WHEN '特征' THEN 3 END DESC,priority");
|
|
|
- }])->where("operation_type",$type)->whereHas("owners",function ($query)use($owner_id){
|
|
|
- /** @var Builder $query */
|
|
|
- $query->where("id",$owner_id);
|
|
|
- })->where(function(Builder $query){
|
|
|
- $query->whereNull("operation")->orWhere("operation","");
|
|
|
- })->orderByRaw("strategy desc,priority desc")->get(); //货主下的全部规则
|
|
|
-
|
|
|
+ $units = app("UnitService")->getUnitMapping(["件","箱"]); //获取单位映射集
|
|
|
+ $rules = $this->getOwnerPriceOperation($ownerId,$type,$typeMark);//货主下的全部规则
|
|
|
if (!$rules)return -2; //规则不存在跳出
|
|
|
-
|
|
|
- $total = app("OrderService")->getOrderQuantity($owner_id);//获取该货主本月C端单量
|
|
|
+ $total = app("OrderService")->getOrderQuantity($ownerId);//获取该货主本月C端单量
|
|
|
foreach ($rules as $rule){
|
|
|
if (!$rule->items)continue; //不存在子规则跳出
|
|
|
- $isDiscount = false; //是否存在满减
|
|
|
- $discountIndex = 0;
|
|
|
- $targetValue = 0;
|
|
|
- if ($type=='出库' && $rule->discount_count){
|
|
|
- foreach (array_reverse(explode(",",$rule->discount_count),true) as $index=>$discount){
|
|
|
- if ($total >= $discount){
|
|
|
- $isDiscount = true; //第一个满足满减条件
|
|
|
- $discountIndex = $index;
|
|
|
- $targetValue = $discount;
|
|
|
- break;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- //满减存在
|
|
|
- if ($isDiscount){
|
|
|
- $sign = false;
|
|
|
- //入口仅在此处存在 缓存1000s
|
|
|
- $key = "pivot_".$rule->id."_".$owner_id;
|
|
|
- $pivot = app(CacheService::class)->getOrExecute($key,function ()use($key,$targetValue,&$sign,$rule,$owner_id){
|
|
|
- try{
|
|
|
- DB::beginTransaction();
|
|
|
- //此处暂时未使用cache的互斥锁 使用sql行锁代替下 防止缓存击穿
|
|
|
- $pivot = DB::selectOne(DB::raw("SELECT * FROM owner_price_operation_owner WHERE owner_price_operation_id = ? AND owner_id = ? for update"),[$rule->id,$owner_id]);
|
|
|
- if ($pivot && (!$pivot->discount_date || substr($pivot->discount_date,0,7)!=date("Y-m") || $pivot->target_value < $targetValue)){
|
|
|
- //未被标记过处理时间或处理时间不为本月,或上次处理值过期,处理历史即时账单
|
|
|
- $sign = true;
|
|
|
- }
|
|
|
- if ($sign){
|
|
|
- //先标记成功 这将在后续推进历史单处理流程,防止程序在此堵塞
|
|
|
- DB::update(DB::raw("UPDATE owner_price_operation_owner SET discount_date = ?,target_value = ? WHERE owner_price_operation_id = ? AND owner_id = ?"),
|
|
|
- [date("Y-m-d"),$targetValue,$rule->id,$owner_id]);
|
|
|
- $pivot->discount_date = date("Y-m-d");
|
|
|
- $pivot->target_value = $targetValue;
|
|
|
- Cache::put($key,$pivot,1000);
|
|
|
- }
|
|
|
- DB::commit();
|
|
|
- }catch (\Exception $exception){
|
|
|
- DB::rollBack();
|
|
|
- LogService::log(__CLASS__,"即时账单满减处理失败",$exception->getMessage());
|
|
|
- }
|
|
|
- return $pivot ?? null;
|
|
|
- },1000);
|
|
|
- //进入历史单处理
|
|
|
- if ($pivot && $sign)$this->handlePastBill($rule,$owner_id,$units,$discountIndex,$pivot);
|
|
|
- }
|
|
|
- if ($rule->strategy == '特征'){//特征策略匹配
|
|
|
- $bool = app("FeatureService")->matchFeature($rule->feature,$columnMapping,$matchObject);
|
|
|
- if ($bool === true){
|
|
|
- if ($rule->total_price)return ["id"=>$rule->id,"money"=>$isDiscount ? explode(",",$rule->total_discount_price)[$discountIndex] : $rule->total_price]; //按单计价存在,直接返回单总价或减免总价
|
|
|
- $money = $this->matchItem($rule->items,$columnMapping,$matchObject,$units,$owner_id,$type=='入库' ? true : false,$isDiscount,$discountIndex);
|
|
|
+
|
|
|
+ $result = $this->getDiscount($rule->discount_count,$total); //满减信息
|
|
|
+ if ($result)$this->handleDiscount($rule,$ownerId,$result);//满减存在
|
|
|
+
|
|
|
+ if ($rule->strategy == '特征'){
|
|
|
+ if (app("FeatureService")->matchFeature($rule->feature,$columnMapping,$matchObject)){
|
|
|
+ if ($rule->total_price)return ["id"=>$rule->id,"money"=>$result ? explode(",",$rule->total_discount_price)[key($result)] : $rule->total_price];//按单计价存在,直接返回单总价或减免总价
|
|
|
+ $money = $this->matchItem($rule->items,$columnMapping,$matchObject,$units,$ownerId,$result);
|
|
|
if ($money>0)return ["id"=>$rule->id,"money"=>$money];
|
|
|
};
|
|
|
- }else{//默认策略匹配
|
|
|
- if ($rule->total_price)return ["id"=>$rule->id,"money"=>$isDiscount ? explode(",",$rule->total_discount_price)[$discountIndex] : $rule->total_price]; //按单计价存在,直接返回单总价或减免总价
|
|
|
- $money = $this->matchItem($rule->items,$columnMapping,$matchObject,$units,$owner_id,$type=='入库' ? true : false,$isDiscount,$discountIndex);
|
|
|
+ }else{
|
|
|
+ if ($rule->total_price)return ["id"=>$rule->id,"money"=>$result ? explode(",",$rule->total_discount_price)[key($result)] : $rule->total_price]; //按单计价存在,直接返回单总价或减免总价
|
|
|
+ $money = $this->matchItem($rule->items,$columnMapping,$matchObject,$units,$ownerId,$result);
|
|
|
if ($money>0)return ["id"=>$rule->id,"money"=>$money];
|
|
|
};
|
|
|
}
|
|
|
@@ -287,19 +339,48 @@ class OwnerPriceOperationService
|
|
|
* 不满一箱视为一箱
|
|
|
*
|
|
|
* @param integer $amount
|
|
|
- * @param integer $owner_id
|
|
|
- * @param string $sku
|
|
|
+ * @param integer $ownerId
|
|
|
+ * @param null|object $commodity
|
|
|
*
|
|
|
* @return int
|
|
|
*/
|
|
|
- private function changeUnit($amount,$owner_id,$sku)
|
|
|
+ private function changeUnit($amount,$ownerId,$commodity)
|
|
|
{
|
|
|
- if (!$sku)return -4;
|
|
|
- $pack = app("CommodityService")->getPack($owner_id,$sku);
|
|
|
+ if (!$commodity)return -4;
|
|
|
+ if ($commodity->pack_spec)return ceil($amount/$commodity->pack_spec);
|
|
|
+ $pack = app("CommodityService")->getPack($ownerId,$commodity->sku);
|
|
|
if (!$pack)return -6;
|
|
|
return ceil($amount/$pack);
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * 重置子节点的映射对象 将无限极数组扁平化为二维 以Feature中定义的8:商品数量 key为基准
|
|
|
+ *
|
|
|
+ * @param object|array $matchObject
|
|
|
+ * @param array $columnMapping
|
|
|
+ *
|
|
|
+ * @return array
|
|
|
+ */
|
|
|
+ private function resetChildNodeMapping($matchObject,&$columnMapping)
|
|
|
+ {
|
|
|
+ $need = "";
|
|
|
+ foreach (Feature::TYPE_NODE as $index){
|
|
|
+ if (!$need)$need=strstr($columnMapping[$index],".",true);
|
|
|
+ $columnMapping[$index] = ltrim(strstr($columnMapping[$index],"."),".");
|
|
|
+ }
|
|
|
+ $nextObj = strstr($columnMapping[8],".",true);
|
|
|
+ $first = $matchObject[$need] ?? false;
|
|
|
+ if ($first && is_array($first))$first = reset($first);
|
|
|
+ else return $matchObject;
|
|
|
+ if (!$first)return $matchObject;
|
|
|
+ if (is_array($first[$nextObj])){
|
|
|
+ $result = [];
|
|
|
+ foreach ($matchObject[$need] as $arr)$result = array_merge($result,$arr[$nextObj]);
|
|
|
+ return $this->resetChildNodeMapping($result,$columnMapping);
|
|
|
+ }
|
|
|
+ return $matchObject[$need];
|
|
|
+ }
|
|
|
+
|
|
|
/**
|
|
|
* 匹配子策略
|
|
|
*
|
|
|
@@ -307,108 +388,50 @@ class OwnerPriceOperationService
|
|
|
* @param array $columnMapping 映射对象
|
|
|
* @param array $matchObject 被匹配对象
|
|
|
* @param array $units 单位集
|
|
|
- * @param integer $owner_id 货主ID
|
|
|
- * @param bool $isIn 是否为入库单
|
|
|
- * @param bool $isDiscount 是否为满减单
|
|
|
- * @param int $discountIndex 阶梯满减所处下标 满减价格此处应为 1,2,3 解析为数组后根据此下标寻找对应值
|
|
|
+ * @param integer $ownerId 货主ID
|
|
|
+ * @param bool|array $result 满减信息
|
|
|
*
|
|
|
* @return double
|
|
|
*/
|
|
|
- private function matchItem($rules, $columnMapping, $matchObject, $units, $owner_id, $isIn, $isDiscount, $discountIndex)
|
|
|
+ private function matchItem($rules, $columnMapping, $matchObject, $units, $ownerId, $result)
|
|
|
{
|
|
|
- $amountColumn = $columnMapping["amount"] ?? "amount";
|
|
|
- $packageColumn = $columnMapping["packages"] ?? "packages";
|
|
|
- $packages = $matchObject[$packageColumn] ?? false;
|
|
|
- $commodityColumn = $columnMapping["商品名称"] ?? 'commodity';
|
|
|
- if (!$packages)return -1;
|
|
|
+ /** @var Collection $matchObject */
|
|
|
+ $matchObject = $this->resetChildNodeMapping($matchObject->toArray(),$columnMapping);
|
|
|
+ if (!$matchObject)return -1;
|
|
|
|
|
|
$unitName = "";
|
|
|
foreach ($rules as $rule){
|
|
|
- if ($isDiscount)$rule->unit_price = explode(",",$rule->discount_price)[$discountIndex]; //满足满减条件,单价调整为满减单价
|
|
|
- switch ($rule->strategy){
|
|
|
- case "特征":
|
|
|
- $inMoney = 0;
|
|
|
- foreach ($packages as &$package){
|
|
|
- if ($package["price"] ?? false)continue;
|
|
|
- if (!app("FeatureService")->matchFeature($rule->feature,["商品名称"=>$commodityColumn],$package)) continue;
|
|
|
-
|
|
|
- if (!$unitName)$unitName = $units[$rule->unit_id];
|
|
|
- else {
|
|
|
- if ($unitName != $units[$rule->unit_id]) return -3;
|
|
|
- }
|
|
|
- $package["price"] = $rule->unit_price;
|
|
|
- if (!isset($units[$rule->unit_id]))return -3;
|
|
|
- if ($units[$rule->unit_id] == '箱'){ //为箱时同步商品寻找箱规
|
|
|
- $sumTemp = 0;
|
|
|
- $packageColumn = $columnMapping["packages"] ?? "packages";
|
|
|
- foreach ($matchObject[$packageColumn] as $commodity){
|
|
|
- $sumTemp += $this->changeUnit($package[$amountColumn],$owner_id,$commodity["sku"]);
|
|
|
- }
|
|
|
- $amount = $sumTemp;
|
|
|
- if ($amount<0)return $amount;
|
|
|
- $package[$amountColumn] = $amount;
|
|
|
- }
|
|
|
- $inMoney += $package[$amountColumn] * $package["price"];
|
|
|
- }
|
|
|
- if ($isIn && $inMoney !== 0){
|
|
|
- return $inMoney;
|
|
|
- }
|
|
|
- break;
|
|
|
- case "默认":
|
|
|
- $inMoney = 0;
|
|
|
- foreach ($packages as &$package){
|
|
|
- if ($package["price"] ?? false)continue; //校验是否已匹配到
|
|
|
- if (!$unitName)$unitName = $units[$rule->unit_id]; //校验单位是否一致
|
|
|
- else {
|
|
|
- if ($unitName != $units[$rule->unit_id])
|
|
|
- return -3;
|
|
|
- }
|
|
|
-
|
|
|
- $package["price"] = $rule->unit_price;
|
|
|
- if (!isset($units[$rule->unit_id]))return -3;
|
|
|
- if ($units[$rule->unit_id] == '箱'){ //为箱时同步商品寻找箱规
|
|
|
- $sumTemp = 0;
|
|
|
- $packageColumn = $columnMapping["packages"] ?? "packages";
|
|
|
- foreach ($matchObject[$packageColumn] as $commodity){
|
|
|
- $sumTemp += $this->changeUnit($package[$amountColumn],$owner_id,$commodity["sku"]);
|
|
|
- }
|
|
|
- $amount = $sumTemp;
|
|
|
- if ($amount<0)return $amount;
|
|
|
- $package[$amountColumn] = $amount;
|
|
|
- }
|
|
|
- $inMoney += $package[$amountColumn] * $package["price"];
|
|
|
- }
|
|
|
- if ($isIn && $inMoney !== 0){
|
|
|
- return $inMoney;
|
|
|
- }
|
|
|
- break;
|
|
|
- default:
|
|
|
- if ($isIn)break; //入库不计算起步
|
|
|
-
|
|
|
- if ($rule->amount){ //起步数+起步费
|
|
|
- if ($unitName && $unitName != $units[$rule->unit_id])return -3; //校验单位是否一致
|
|
|
-
|
|
|
- $money = $rule->unit_price;
|
|
|
- $startNumber = $rule->amount;
|
|
|
- $packages = $this->settingCount($packages,$amountColumn,$startNumber);
|
|
|
- if ($packages){
|
|
|
- foreach ($packages as $package){
|
|
|
- $money += $package[$amountColumn] * $package["price"];
|
|
|
- }
|
|
|
- }
|
|
|
- }else{//单起步费
|
|
|
- $money = 0;
|
|
|
- if ($packages){
|
|
|
- foreach ($packages as $package){
|
|
|
- $money += $package[$amountColumn] * $package["price"];
|
|
|
- }
|
|
|
- }
|
|
|
- if ($money<$rule->unit_price)$money = $rule->unit_price;
|
|
|
- }
|
|
|
- return $money;
|
|
|
+ if ($result)$rule->unit_price = explode(",",$rule->discount_price)[key($result)]; //满足满减条件,单价调整为满减单价
|
|
|
+
|
|
|
+ if ($rule->strategy=='起步'){
|
|
|
+ if ($unitName && $unitName != $units[$rule->unit_id])return -3; //校验单位是否一致
|
|
|
+ $money = $rule->unit_price;
|
|
|
+ $startNumber = $rule->amount;
|
|
|
+ if ($startNumber)$matchObject=$this->settingCount($matchObject,$columnMapping[8],$startNumber);
|
|
|
+ if ($matchObject)foreach ($matchObject as $package)$money += $package[$columnMapping[8]] * $package["price"];
|
|
|
+ if (!$startNumber && $money<$rule->unit_price)$money = $rule->unit_price;
|
|
|
+ return $money;
|
|
|
+ }
|
|
|
+ foreach ($matchObject as &$package){
|
|
|
+ if ($package["price"] ?? false)continue;
|
|
|
+ if (!isset($units[$rule->unit_id]))return -3;
|
|
|
+ if (!$unitName)$unitName = $units[$rule->unit_id];
|
|
|
+ else if ($unitName != $units[$rule->unit_id]) return -3;
|
|
|
+ if ($rule->strategy=='特征')if (!app("FeatureService")->matchFeature($rule->feature,$columnMapping,$package)) continue;
|
|
|
+ $package["price"] = $rule->unit_price;
|
|
|
}
|
|
|
+ if ($units[$rule->unit_id] == '箱'){ //为箱时同步商品寻找箱规
|
|
|
+ $amount = 0;
|
|
|
+ foreach ($matchObject as $commodity)$amount += $this->changeUnit($commodity[$columnMapping[8]],$ownerId,$commodity[$columnMapping[9]]);
|
|
|
+ if ($amount<0)return $amount;
|
|
|
+ $package[$columnMapping[8]] = $amount;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if ($matchObject){
|
|
|
+ $money = 0;
|
|
|
+ foreach ($matchObject as $package)if ($package["price"])$money += $package[$columnMapping[8]] * $package["price"];
|
|
|
}
|
|
|
- return -7;
|
|
|
+ return $money ?? -7;
|
|
|
}
|
|
|
//递归式重新设置数量
|
|
|
private function settingCount($packages,$amountColumn,$startNumber)
|
|
|
@@ -439,44 +462,26 @@ class OwnerPriceOperationService
|
|
|
* 处理历史账单
|
|
|
*
|
|
|
* @param object $rule
|
|
|
- * @param int $owner_id
|
|
|
- * @param array $units
|
|
|
+ * @param int $owner
|
|
|
* @param int $discountIndex
|
|
|
* @param object $pivot
|
|
|
*/
|
|
|
- public function handlePastBill($rule, $owner_id, $units, $discountIndex, $pivot)
|
|
|
+ public function handlePastBill($rule, $owner, $discountIndex, $pivot)
|
|
|
{
|
|
|
try{
|
|
|
DB::beginTransaction();
|
|
|
$month = date("Y-m");
|
|
|
$day = date("t",strtotime($month));
|
|
|
+ $units = app("UnitService")->getUnitMapping(["件","箱"]); //获取单位映射集
|
|
|
foreach (OwnerFeeDetail::query()->with(["order.logistic","order.shop","order.packages.commodities.commodity","order.batch"])
|
|
|
- ->where("owner_id",$owner_id)
|
|
|
+ ->where("owner_id",$owner)
|
|
|
->whereBetween("worked_at",[$month."-01",$month."-".$day])->get() as $detail){
|
|
|
$order = $detail->order;
|
|
|
|
|
|
$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 : '';
|
|
|
- }
|
|
|
- $commodities = array_merge($commodities,$package->commodities->toArray());
|
|
|
- }
|
|
|
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,
|
|
|
- "batch_type" => $order->batch ? $order->batch->wms_type : '',
|
|
|
- "owner_id"=>$order->owner_id];
|
|
|
- $mapping = ["packages"=>"commodities","商品名称"=>"commodity_name",
|
|
|
- "承运商"=>"logistic_name", "店铺类型"=>"shop_name",
|
|
|
- "订单类型"=>"order_type","波次类型"=>"batch_type"];
|
|
|
- $money = $this->matchItem($rule->items,$mapping,$object,$units,$owner_id,false,true,$discountIndex);
|
|
|
+ $money = $this->matchItem($rule->items,Feature::MAPPING["order"],$order,$units,$owner,[$discountIndex=>true]);
|
|
|
if ($money>0)$detail->update(["work_fee"=>$money]);
|
|
|
else LogService::log(__CLASS__,"处理历史即时账单时发生匹配错误","账单主键:".$detail->id."; 错误代码".$money);
|
|
|
};
|
|
|
@@ -485,7 +490,7 @@ class OwnerPriceOperationService
|
|
|
DB::rollBack();
|
|
|
//处理失败回退标记
|
|
|
DB::update(DB::raw("UPDATE owner_price_operation_owner SET discount_date = ?,target_value = ? WHERE owner_price_operation_id = ? AND owner_id = ?"),
|
|
|
- [$pivot->discount_date,$pivot->target_value,$rule->id,$owner_id]);
|
|
|
+ [$pivot->discount_date,$pivot->target_value,$rule->id,$owner]);
|
|
|
LogService::log(__CLASS__,"处理历史即时账单时发生系统错误","计费模型主键:".$rule->id."; 错误信息".$e->getMessage());
|
|
|
}
|
|
|
}
|