ownerGetIds($params["owner_id"]); if ($ids)$builder->whereIn("id",$ids); unset($params["owner_id"]); } $columnQueryRules = [ "name" => ["like"=>""] ]; return app(QueryService::class)->query($params, $builder, $columnQueryRules); } public function paginate(array $params, array $withs = []) { return $this->query(OwnerPriceOperation::query()->orderByDesc('id')->with($withs),$params) ->paginate($params["paginate"] ?? 50); } private function ownerGetIds(string $owner_id) { 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.")")); return array_column($arr,"id"); } public function destroy($id) { OwnerPriceOperationItem::query()->where("owner_price_operation_id",$id)->delete(); DB::table("owner_price_operation_owner")->where("owner_price_operation_id",$id)->delete(); return OwnerPriceOperation::destroy($id); } /** * @param array $params * @return Model */ public function create(array $params) { return OwnerPriceOperation::query()->create($params); } public function insertItem(array $params) { OwnerPriceOperationItem::query()->insert($params); } public function find($id, $withs = []) { $query = OwnerPriceOperation::query()->with($withs)->find($id); return $query; } public function destroyItem($id) { return OwnerPriceOperationItem::query()->where("owner_price_operation_id",$id)->delete(); } public function findUpdate(OwnerPriceOperation $model, array $params) { return $model->update($params); } /** 参数顺序: 数量 匹配对象 列映射 货主ID 单位ID 类型 SKU . * 匹配顺序: 类型 货主 策略 单位 特征 ..多对多匹配规则废弃,1对1,设单位必定为件,对应规则必然只有一项存在 * 单位匹配: 件,箱,单 由小到大,依次换算匹配 . * * 2:没有总数量存在,都为子项内数量 * * @param array|object $matchObject key-val * @param array $columnMapping key-val * @param string $owner_id * @param string $type * @return double * 错误代码: -1:无匹配对象 -2:无计费模型 -3:未知单位 -4:sku为空 -5:货主未找到 -6:无箱规 -7:未匹配到计费模型 * * 一. 2020-10-10 zzd * 二. 2021-01-08 zzd */ public function matching($matchObject, $columnMapping, $owner_id, $type = '出库') { $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 DESC"); }])->where("operation_type",$type)->whereHas("ownerPriceOperationOwners",function ($query)use($owner_id){ /** @var Builder $query */ $query->where("id",$owner_id); })->orderByRaw("strategy desc,priority desc")->get(); //货主下的全部规则 if (!$rules)return -2; /*if ($type == '入库'){ $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->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"]); } $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; }; }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; }; } return -7; }*/ //出库 foreach ($rules as $rule){ if (!$rule->ownerOutStorageRules)continue; if ($rule->strategy == '特征'){ $bool = app("FeatureService")->matchFeature($rule->feature,$columnMapping,$matchObject);//匹配特征 if ($bool === true){ $money = $this->matchItem($rule->ownerOutStorageRules,$columnMapping,$matchObject,$units,$owner_id,$type=='入库' ? true : false); if ($money>0)return $money; }; }else{ $money = $this->matchItem($rule->ownerOutStorageRules,$columnMapping,$matchObject,$units,$owner_id,$type=='入库' ? true : false); if ($money>0)return $money; }; } return -7; } private function changeUnit($amount,$owner_id,$sku) { if (!$sku)return -4; $pack = app("CommodityService")->getPack($owner_id,$sku); if (!$pack)return -6; return ceil($amount/$pack); } private function matchItem($rules, $columnMapping, $matchObject, $units, $owner_id, $isIn) { $amountColumn = $columnMapping["amount"] ?? "amount"; $packageColumn = $columnMapping["packages"] ?? "packages"; $packages = $matchObject[$packageColumn] ?? false; $commodityColumn = $columnMapping["商品名称"] ?? 'commodity'; if (!$packages)return -1; $unitName = ""; foreach ($rules as $rule){ switch ($rule->strategy){ case "特征": $inMoney = 0; foreach ($packages as &$package){ if ($package["price"] ?? false)continue; if (!app("FeatureService")->matchFeature($rule->feature,["商品名称"=>$commodityColumn],["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] == '箱'){ //为箱时同步商品寻找箱规 $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]) || $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)continue; 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 settingCount($packages,$amountColumn,$startNumber) { 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 ($packages[$index][$amountColumn] >= $startNumber){ $packages[$index][$amountColumn] -= $startNumber; return $packages; }else{ $startNumber -= $packages[$index][$amountColumn]; unset($packages[$index]); $this->settingCount($packages,$amountColumn,$startNumber); } } }