扣减库存接口
/** * Notes:修改或删除库存信息 复核提交,移位完成,调拨完成 后触发 * 原始库位扣减操作 * User: sl * Date: 2023-04-11 17:31 * @param $data * @param $type 1,复核完成 2调拨出库完成后扣减 3,源库位移位完成后 * 移位不记录日志 * @return bool **************二位数组************************* * [["id"=>"库存id","reduceTotalQty"=>"减少的库存总数量"]] * * [["id"=>"1","reduceTotalQty"=>"50"]] */ public static function updateOrDelStock($operator,$type,$data=[]) { \Log::channel("stockLock")->info("---------------修改库存信息------------------"); \Log::channel("stockLock")->info(sprintf("操作人:%s",json_encode($operator,JSON_UNESCAPED_UNICODE))); \Log::channel("stockLock")->info(sprintf("参数:%s",json_encode($data))); $arr = []; foreach($data as $item){ if(!isset($arr[$item["id"]])){ $arr[$item["id"]] = 0; } $arr[$item["id"]] += $item["reduceTotalQty"]; } $stockIds = array_keys($arr); $stockList = StockModel::getStockListByids($stockIds); $stockList = arrayChangeKeyByField($stockList,"id"); try{ self::startTransaction(); foreach($stockList as $id=>$stockInfo){ $reduceQty = $arr[$id] ?? 0; if($reduceQty <= 0){ continue; } if($stockInfo["total_qty"] < $reduceQty){ throw new InvalidRequestException(sprintf("库存id:%s,扣减库存失败,扣减数量不能大于库存总数量",$id)); } if($stockInfo["useable_qty"] < $reduceQty){ throw new InvalidRequestException(sprintf("库存id:%s,扣减库存失败,扣减数量不能大于库存可用数量",$id)); } $totalQty = $stockInfo["total_qty"] - $reduceQty; $useableQty = $stockInfo["useable_qty"] - $reduceQty; //开始扣减库存 $update=[]; $update["total_qty"] = $totalQty; $update["useable_qty"] = $useableQty; $update["update_uid"] = $operator["operator_id"] ?? 0; $update["update_name"] = $operator["operator_name"] ?? ""; $update["update_time"] = time(); $update["amount"] = \DB::raw("ROUND(purchase_prices*total_qty,2)"); $update["standard_money_amount"] = \DB::raw("ROUND(standard_money_prices*total_qty,2)"); $update["purchase_withoutamount"] = \DB::raw("ROUND(purchase_without_tax_price*total_qty,2)"); StockModel::where("id",$id)->update($update); // if($totalQty == 0 && $useableQty == 0){ // //进行库存汇总 // self::updateOrCreateStockSummary([$id]); // //删除 // StockModel::where("id",$id)->delete(); // // } //进行库存汇总 self::updateOrCreateStockSummary([$id]); //删除 if($totalQty == 0 && $useableQty == 0){ StockModel::where("id",$id)->delete(); } } self::commitTransaction(); }catch (\Throwable $e){ \Log::channel("stockLock")->info(json_encode(ErrMsg::getExceptionInfo($e))); self::rollBackTransaction(); throw new InvalidRequestException($e->getMessage()); } }
上述红色代码是扣减库存,在并发或者重复请求,或者请求超时情况下会出现重复扣减库存的情况,
库存原来只有型号A 8个 现在要扣减8个库存,第一次扣减8个可能请求超时或者其他原因,扣减接口重试了一次,第二次请求又继续扣减库存,上述接口两个扣减都成功了;
修改后代码:
/** * Notes:修改或删除库存信息 复核提交,移位完成,调拨完成 后触发 * 原始库位扣减操作 * User: sl * Date: 2023-04-11 17:31 * @param $data * @param $type 1,复核完成 2调拨出库完成后扣减 3,源库位移位完成后 * 移位不记录日志 * @return bool **************二位数组************************* * [["id"=>"库存id","reduceTotalQty"=>"减少的库存总数量"]] * * [["id"=>"1","reduceTotalQty"=>"50"]] */ public static function updateOrDelStock($operator,$type,$data=[]) { \Log::channel("stockLock")->info("---------------修改库存信息------------------"); \Log::channel("stockLock")->info(sprintf("操作人:%s",json_encode($operator,JSON_UNESCAPED_UNICODE))); \Log::channel("stockLock")->info(sprintf("参数:%s",json_encode($data))); $arr = []; foreach($data as $item){ if(!isset($arr[$item["id"]])){ $arr[$item["id"]] = 0; } $arr[$item["id"]] += $item["reduceTotalQty"]; } $stockIds = array_keys($arr); $stockList = StockModel::getStockListByids($stockIds); $stockList = arrayChangeKeyByField($stockList,"id"); try{ self::startTransaction(); foreach($stockList as $id=>$stockInfo){ $reduceQty = $arr[$id] ?? 0; if($reduceQty <= 0){ continue; } if($stockInfo["total_qty"] < $reduceQty){ throw new InvalidRequestException(sprintf("库存id:%s,扣减库存失败,扣减数量不能大于库存总数量",$id)); } if($stockInfo["useable_qty"] < $reduceQty){ throw new InvalidRequestException(sprintf("库存id:%s,扣减库存失败,扣减数量不能大于库存可用数量",$id)); } $totalQty = $stockInfo["total_qty"] - $reduceQty; $useableQty = $stockInfo["useable_qty"] - $reduceQty; //开始扣减库存 $update=[]; $update["total_qty"] = \DB::raw("total_qty-{$reduceQty}"); $update["useable_qty"] = \DB::raw("useable_qty-{$reduceQty}");; $update["update_uid"] = $operator["operator_id"] ?? 0; $update["update_name"] = $operator["operator_name"] ?? ""; $update["update_time"] = time(); $update["amount"] = \DB::raw("ROUND(purchase_prices*total_qty,2)"); $update["standard_money_amount"] = \DB::raw("ROUND(standard_money_prices*total_qty,2)"); $update["purchase_withoutamount"] = \DB::raw("ROUND(purchase_without_tax_price*total_qty,2)"); $bk = StockModel::where("id",$id)->where("total_qty",$stockInfo["total_qty"])->where("useable_qty",$stockInfo["useable_qty"])->update($update); if(!$bk){ throw new InvalidRequestException(sprintf("库存id:%s,扣减库存失败:可能存在相同库存数据重复扣减或者并发扣减情况",$id)); } //进行库存汇总 self::updateOrCreateStockSummary([$id]); //删除 if($totalQty == 0 && $useableQty == 0){ StockModel::where("id",$id)->delete(); } } self::commitTransaction(); }catch (\Throwable $e){ \Log::channel("stockLock")->info(json_encode(ErrMsg::getExceptionInfo($e))); self::rollBackTransaction(); throw new InvalidRequestException($e->getMessage()); } }
标签:arr,库存,扣减,锁用,self,item,id,分布式 From: https://www.cnblogs.com/sunlong88/p/17528909.html