|
|
@@ -97,26 +97,26 @@ Class OwnerPriceOperationService
|
|
|
/** 参数顺序: 数量 匹配对象 列映射 货主ID 单位ID 类型 SKU .
|
|
|
* 匹配顺序: 类型 货主 策略 单位 特征 ..多对多匹配规则废弃,1对1,设单位必定为件,对应规则必然只有一项存在
|
|
|
* 单位匹配: 件,箱,单 由小到大,依次换算匹配 .
|
|
|
- * @param int $amount
|
|
|
+ *
|
|
|
+ * 2:没有总数量存在,都为子项内数量
|
|
|
+ *
|
|
|
* @param array|object $matchObject key-val
|
|
|
* @param array $columnMapping key-val
|
|
|
* @param string $owner_id
|
|
|
* @param string $type
|
|
|
* @param string $sku
|
|
|
* @return double
|
|
|
- * 错误代码: -1:非法数量 -2:无计费模型 -3:未知单位 -4:sku为空 -5:货主未找到 -6:无箱规 -7:未匹配到计费模型
|
|
|
+ * 错误代码: -1:无匹配对象 -2:无计费模型 -3:未知单位 -4:sku为空 -5:货主未找到 -6:无箱规 -7:未匹配到计费模型
|
|
|
*/
|
|
|
- public function matchRule($amount, $matchObject, $columnMapping, $owner_id, $sku = null, $type = '出库')
|
|
|
+ public function matchRule($matchObject, $columnMapping, $owner_id, $sku = null, $type = '出库')
|
|
|
{
|
|
|
- if ($amount <= 0 )return -1;
|
|
|
-
|
|
|
$unitModels = Unit::query()->whereIn("name",["件","箱","单"])->get();
|
|
|
$units = [];
|
|
|
foreach ($unitModels as $unitModel)$units[$unitModel->id] = $unitModel->name;
|
|
|
|
|
|
$withs = $type=='出库' ? ['ownerOutStorageRules'=>function($query){
|
|
|
/** @var Builder $query */
|
|
|
- $query->orderByRaw("CASE strategy WHEN '默认' THEN 1 WHEN '特征' THEN 2 WHEN '起步' THEN 3 END DESC,priority DESC");
|
|
|
+ $query->orderByRaw("CASE strategy WHEN '起步' THEN 1 WHEN '默认' THEN 2 WHEN '特征' THEN 3 END DESC,priority DESC");
|
|
|
}] : ['ownerInStorageRule'] ;
|
|
|
$rules = OwnerPriceOperation::query()->with($withs)
|
|
|
->where("operation_type",$type)
|
|
|
@@ -128,7 +128,15 @@ Class OwnerPriceOperationService
|
|
|
if (!$rules)return -2;
|
|
|
|
|
|
if ($type == '入库'){
|
|
|
- foreach ($rules as $index => $rule){
|
|
|
+ $amountColumn = $columnMapping["amount"] ?? "amount";
|
|
|
+ $packageColumn = $columnMapping["packages"] ?? "packages";
|
|
|
+ $packages = $matchObject[$packageColumn] ?? false;
|
|
|
+ if (!$packages)return -1;
|
|
|
+
|
|
|
+ $amount = 0;
|
|
|
+ foreach ($packages as $package)$amount += $package[$amountColumn] ?? 0;
|
|
|
+ if (!$amount)return -1;
|
|
|
+ foreach ($rules as $rule){
|
|
|
$sum = $amount;
|
|
|
if (!$rule->ownerInStorageRule)continue;
|
|
|
if ($rule->strategy == '特征'){
|
|
|
@@ -137,10 +145,7 @@ Class OwnerPriceOperationService
|
|
|
if (!isset($units[$rule->ownerInStorageRule->unit_id])) return -3;
|
|
|
if ($units[$rule->ownerInStorageRule->unit_id] == '箱'){ //为箱时同步商品寻找箱规
|
|
|
$sum = $this->changeUnit($sum,$owner_id,$sku);
|
|
|
- if ($sum<0){
|
|
|
- if ($index == count($rules)-1)return $sum;
|
|
|
- continue;
|
|
|
- }
|
|
|
+ if ($sum<0)return $sum;
|
|
|
}
|
|
|
if ($units[$rule->ownerInStorageRule->unit_id] == '单')$sum = 1; //为单时数量设为1;
|
|
|
return ceil($sum/$rule->ownerInStorageRule->amount)*$rule->ownerInStorageRule->unit_price;
|
|
|
@@ -149,10 +154,7 @@ Class OwnerPriceOperationService
|
|
|
if (!isset($units[$rule->ownerInStorageRule->unit_id])) return -3;
|
|
|
if ($units[$rule->ownerInStorageRule->unit_id] == '箱'){ //为箱时同步商品寻找箱规
|
|
|
$sum = $this->changeUnit($sum,$owner_id,$sku);
|
|
|
- if ($sum<0){
|
|
|
- if ($index == count($rules)-1)return $sum;
|
|
|
- continue;
|
|
|
- }
|
|
|
+ if ($sum<0)return $sum;
|
|
|
}
|
|
|
if ($units[$rule->ownerInStorageRule->unit_id] == '单')$sum = 1; //为单时数量设为1;
|
|
|
return ceil($sum/$rule->ownerInStorageRule->amount)*$rule->ownerInStorageRule->unit_price;
|
|
|
@@ -166,11 +168,11 @@ Class OwnerPriceOperationService
|
|
|
if ($rule->strategy == '特征'){
|
|
|
$bool = app("FeatureService")->matchFeature($rule->feature,$columnMapping,$matchObject);//匹配特征
|
|
|
if ($bool === true){
|
|
|
- $money = $this->matchOutStorage($amount,$rule->ownerOutStorageRules,$columnMapping,$matchObject,$units,$owner_id,$sku);
|
|
|
+ $money = $this->matchOutStorage($rule->ownerOutStorageRules,$columnMapping,$matchObject,$units,$owner_id,$sku);
|
|
|
if ($money>0)return $money;
|
|
|
};
|
|
|
}else{
|
|
|
- $money = $this->matchOutStorage($amount,$rule->ownerOutStorageRules,$columnMapping,$matchObject,$units,$owner_id,$sku);
|
|
|
+ $money = $this->matchOutStorage($rule->ownerOutStorageRules,$columnMapping,$matchObject,$units,$owner_id,$sku);
|
|
|
if ($money>0)return $money;
|
|
|
};
|
|
|
}
|
|
|
@@ -183,87 +185,93 @@ Class OwnerPriceOperationService
|
|
|
if (!$pack)return -6;
|
|
|
return ceil($amount/$pack);
|
|
|
}
|
|
|
- private function matchOutStorage($amount, $rules, $columnMapping, $matchObject, $units, $owner_id, $sku)
|
|
|
+
|
|
|
+ private function matchOutStorage($rules, $columnMapping, $matchObject, $units, $owner_id, $sku)
|
|
|
{
|
|
|
- $money = 0;
|
|
|
- foreach ($rules as $index => $rule){
|
|
|
- $sum = $amount;
|
|
|
- switch ($rule->strategy){
|
|
|
- case "起步":
|
|
|
- $money = $rule->amount * $rule->unit_price;
|
|
|
- if ($units[$rule->unit_id] == '箱') { //为箱时同步商品寻找箱规
|
|
|
- if (!$sku)return -4;
|
|
|
- $pack = app("CommodityService")->getPack($owner_id,$sku);
|
|
|
- if (!$pack)return -6;
|
|
|
- $rule->amount *= $pack;
|
|
|
- }
|
|
|
+ $amountColumn = $columnMapping["amount"] ?? "amount";
|
|
|
+ $packageColumn = $columnMapping["packages"] ?? "packages";
|
|
|
+ $packages = $matchObject[$packageColumn] ?? false;
|
|
|
+ $commodityColumn = $columnMapping["商品名称"] ?? 'commodity';
|
|
|
+ if (!$packages)return -1;
|
|
|
|
|
|
- if ($amount < $rule->amount)$amount = $rule->amount;
|
|
|
- else $amount -= $rule->amount;
|
|
|
- break;
|
|
|
+ $unitName = "";
|
|
|
+ foreach ($rules as $rule){
|
|
|
+ switch ($rule->strategy){
|
|
|
case "特征":
|
|
|
- if (app("FeatureService")->matchFeature($rule->feature,$columnMapping,$matchObject)){
|
|
|
- if (!isset($units[$rule->unit_id]) || $units[$rule->unit_id] == '单') return -3;
|
|
|
+ foreach ($packages as &$package){
|
|
|
+ if ($package["price"] ?? false)continue;
|
|
|
+ if (!app("FeatureService")->matchFeature($rule->feature,["商品名称"=>"commodity"],["commodity"=>$package[$commodityColumn] ?? ''])) 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]) || $units[$rule->unit_id] == '单')return -3;
|
|
|
if ($units[$rule->unit_id] == '箱'){ //为箱时同步商品寻找箱规
|
|
|
- $sum = $this->changeUnit($sum,$owner_id,$sku);
|
|
|
- if ($sum<0){
|
|
|
- if ($index == count($rules)-1)return $sum;
|
|
|
- break;
|
|
|
- }
|
|
|
+ $amount = $this->changeUnit($package[$amountColumn],$owner_id,$sku);
|
|
|
+ if ($amount<0)return $amount;
|
|
|
+ $package[$amountColumn] = $amount;
|
|
|
}
|
|
|
- return (ceil($sum/$rule->amount)*$rule->unit_price)+$money;
|
|
|
- };
|
|
|
+ }
|
|
|
break;
|
|
|
case "默认":
|
|
|
- if (!isset($units[$rule->unit_id]) || $units[$rule->unit_id] == '单') return -3;
|
|
|
- if ($units[$rule->unit_id] == '箱'){ //为箱时同步商品寻找箱规
|
|
|
- $sum = $this->changeUnit($sum,$owner_id,$sku);
|
|
|
- if ($sum<0){
|
|
|
- if ($index == count($rules)-1)return $sum;
|
|
|
- break;
|
|
|
+ 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]) || $units[$rule->unit_id] == '单')return -3;
|
|
|
+ if ($units[$rule->unit_id] == '箱'){ //为箱时同步商品寻找箱规
|
|
|
+ $amount = $this->changeUnit($package[$amountColumn],$owner_id,$sku);
|
|
|
+ if ($amount<0)return $amount;
|
|
|
+ $package[$amountColumn] = $amount;
|
|
|
}
|
|
|
}
|
|
|
- return (ceil($sum/$rule->amount)*$rule->unit_price)+$money;
|
|
|
break;
|
|
|
+ default:
|
|
|
+ if ($unitName && $unitName != $units[$rule->unit_id])return -3; //校验单位是否一致
|
|
|
+
|
|
|
+ $money = $rule->amount * $rule->unit_price;
|
|
|
+ $startNumber = $rule->amount;
|
|
|
+ $packages = $this->settingCount($packages,$amountColumn,$startNumber);
|
|
|
+ if ($packages){
|
|
|
+ foreach ($packages as $package){
|
|
|
+ $money += $package[$amountColumn] * $package["price"];
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return $money;
|
|
|
}
|
|
|
}
|
|
|
return -7;
|
|
|
}
|
|
|
-
|
|
|
- private function matchInStorage($amount, $matchObject, $columnMapping, $owner_id, $unit_id, $rules, $sku, $units = null, $isMatch = false)
|
|
|
+ //设置数量
|
|
|
+ private function settingCount($packages,$amountColumn,$startNumber)
|
|
|
{
|
|
|
- /*foreach ($rules as $rule){
|
|
|
- if ($unit_id != $rule->ownerInStorageRule->unit_id)continue;
|
|
|
- else{
|
|
|
- if ($rule->strategy == '特征'){
|
|
|
- $bool = app("FeatureService")->matchFeature($rule->feature,$columnMapping,$matchObject);
|
|
|
- if ($bool === true){
|
|
|
- return ceil($amount/$rule->ownerInStorageRule->amount)*$rule->ownerInStorageRule->unit_price;
|
|
|
- };
|
|
|
- }else{
|
|
|
- return ceil($amount/$rule->ownerInStorageRule->amount)*$rule->ownerInStorageRule->unit_price;
|
|
|
- };
|
|
|
+ if (!$packages) return null;
|
|
|
+ $maxPrice = 0;
|
|
|
+ $index = null;
|
|
|
+ foreach ($packages as $i => $package){
|
|
|
+ if ($package[$amountColumn] <= 0){
|
|
|
+ unset($packages[$i]);continue;
|
|
|
+ }
|
|
|
+ if ($package["price"] > $maxPrice){
|
|
|
+ $maxPrice = $package["price"];
|
|
|
+ $index = $i;
|
|
|
}
|
|
|
}
|
|
|
- //单位换算
|
|
|
- if (!$units){
|
|
|
- $unitModels = Unit::query()->whereIn("name",["件","箱","单"])->get();
|
|
|
- if (!$unitModels) return null;
|
|
|
- foreach ($unitModels as $unitModel)$units[$unitModel->name] = $unitModel->id;
|
|
|
+ if ($packages[$index][$amountColumn] >= $startNumber){
|
|
|
+ $packages[$index][$amountColumn] -= $startNumber;
|
|
|
+ return $packages;
|
|
|
+ }else{
|
|
|
+ unset($packages[$index]);
|
|
|
+ $startNumber -= $packages[$index][$amountColumn];
|
|
|
+ $this->settingCount($packages,$amountColumn,$startNumber);
|
|
|
}
|
|
|
- $name = array_search($unit_id,$units);
|
|
|
- //递归匹配
|
|
|
- switch ($name){
|
|
|
- case "件"://布尔值校验是否匹配过件来确保箱只匹配一次件
|
|
|
- return $this->matchInStorage($amount, $matchObject, $columnMapping, $owner_id, $units["箱"], $rules, $sku, $units, true);
|
|
|
- case "箱"://箱存在向下向上转换
|
|
|
- if ($isMatch){
|
|
|
- return $this->matchInStorage($amount, $matchObject, $columnMapping, $owner_id, $units["单"], $rules, $sku, $units);
|
|
|
- }else{
|
|
|
- return $this->matchInStorage($amount, $matchObject, $columnMapping, $owner_id, $units["件"], $rules, $sku, $units);
|
|
|
- }
|
|
|
- case "单"://三次匹配皆无,返回null
|
|
|
- return null;
|
|
|
- }*/
|
|
|
}
|
|
|
}
|