diff --git a/app/Http/Controllers/Goods/GoodsSkusController.php b/app/Http/Controllers/Goods/GoodsSkusController.php index 9623259..5fe60c5 100644 --- a/app/Http/Controllers/Goods/GoodsSkusController.php +++ b/app/Http/Controllers/Goods/GoodsSkusController.php @@ -343,16 +343,87 @@ class GoodsSkusController extends Controller } /** - * 库存盘点 + * 库存盘点 准备废弃中 * * @param $request * @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\Routing\ResponseFactory|\Illuminate\Http\Response */ private function inventory($request) { - $goodSkuService = new GoodSkuService(); - $goodSkuService->inventory($request->skus); + DB::beginTransaction(); + try { + $logs = []; + $requestSkus = ArrayUtils::index($request->skus, 'id'); + $skus = GoodsSku::query() + ->whereIn('id', array_keys($requestSkus)) + ->with(['goods:id,goods_code']) + ->get(['id', 'goods_id', 'sku_code']) + ->toArray(); + $today = DateTimeUtils::getToday(); + $nextDay = DateTimeUtils::getNextDay(); + $dateTime = date('Y-m-d H:i:s'); + foreach ($skus as $sku) { + if (!isset($requestSkus[$sku['id']])) { + continue; + } + // 更新今天 + $record = DailyStockRecord::query()->where('sku_id', $sku['id'])->where('day', $today)->first(); + // 日志记录 + $inventoryLog = [ + 'module' => 'goods', + 'action' => $request->getMethod(), + 'target_type' => 'goods_sku', + 'target_id' => $sku['id'], + 'user_id' => $request->user()->id, + 'target_field' => 'inventory', + 'before_update' => $record->inventory, + 'after_update' => $requestSkus[$sku['id']]['inventory'] + ]; + $externalSkuId = $sku['goods']['goods_code'] . '_' . $sku['sku_code']; + // 自上一次盘点过后有订单发生的数量(包含退单) + $lastInventoryTime = $record->inventory_time; + $addOrderGoodsNum = BusinessOrderItem::query() + ->where('external_sku_id', $externalSkuId) + ->when($lastInventoryTime, function ($query) use ($lastInventoryTime) { + $query->where('updated_at', '>', $lastInventoryTime); + }) + ->sum('goods_number'); + $reduceOrderGoodsNum = BusinessOrderItem::query() + ->where('external_sku_id', $externalSkuId) + ->when($lastInventoryTime, function ($query) use ($lastInventoryTime) { + $query->where('updated_at', '>', $lastInventoryTime); + }) + ->sum('already_cancel_number'); + $orderGoodsNum = $addOrderGoodsNum - $reduceOrderGoodsNum; + $record->inventory = $requestSkus[$sku['id']]['inventory']; + $record->inventory_time = $dateTime; + $record->order_goods_num += $orderGoodsNum; + $record->save(); + $inventoryLog['message'] = '盘点时订单商品数量: ' . $orderGoodsNum; + $logs[] = $inventoryLog; + // 更新明天 + DailyStockRecord::updateOrCreate( + ['sku_id' => $sku['id'], 'day' => $nextDay], + [ + 'inventory' => $record->inventory, + 'inventory_time' => $dateTime, + ] + ); + } + $log = new LogModel(); + $log->batchInsert($logs); + DB::commit(); + } catch (\Exception $exception) { + DB::rollBack(); + $this->res = [ + 'httpCode' => 400, + 'errorCode' => 400500, + 'errorMessage' => $exception->getMessage(), + ]; + } + return response($this->res, $this->res['httpCode']); + } /** diff --git a/app/Http/Controllers/Supplier/DailyStockRecordController.php b/app/Http/Controllers/Supplier/DailyStockRecordController.php index 4314785..a54b7f7 100644 --- a/app/Http/Controllers/Supplier/DailyStockRecordController.php +++ b/app/Http/Controllers/Supplier/DailyStockRecordController.php @@ -70,10 +70,10 @@ class DailyStockRecordController extends Controller ]; return response($this->res, $this->res['httpCode']); } - - //同一批量逻辑操作 + $goodsSkuWithInventory = array_merge($goodsSku->toArray(),["inventory"=>$request->inventory]); + //同批量逻辑操作 $goodSkuService = new GoodSkuService(); - $goodSkuService->inventory([$goodsSku]); + $goodSkuService->inventory([$goodsSkuWithInventory]); return response($this->res, $this->res['httpCode']); } diff --git a/app/Imports/InventoryImport.php b/app/Imports/InventoryImport.php index 8eb60b3..efdac1e 100644 --- a/app/Imports/InventoryImport.php +++ b/app/Imports/InventoryImport.php @@ -22,20 +22,27 @@ class InventoryImport implements ToArray, SkipsEmptyRows public function array(array $collection) { unset($collection[0]); - $externalSkuId = []; - $requestSkus = []; + $externalSkuIds = []; + $inventoryKeyByExternalSkuIdMap = []; foreach ($collection as &$row) { $row = array_map(static function ($v) { return trim($v); }, $row); - $requestSkus[] = [ - "external_sku_id" => $row[0], - "inventory" => $row[2], - ]; + $inventoryKeyByExternalSkuIdMap[$row[0]] = $row[2]; + $externalSkuIds[] = $row[0]; } unset($row); //新版盘点excel字段 编码 商品名称 盘点数 + $goodsSkus = GoodsSku::query()->with("combinationGoods")->whereIn('external_sku_id', $externalSkuIds) + ->get()->toArray(); + $goodsSkus = collect($goodsSkus)->map(function ($v) use ($inventoryKeyByExternalSkuIdMap) { + if (!empty($inventoryKeyByExternalSkuIdMap[$v['external_sku_id']])) { + $v['inventory'] = $inventoryKeyByExternalSkuIdMap[$v['external_sku_id']]; + return $v; + } + })->toArray(); + $goodSkuService = new GoodSkuService(); - $goodSkuService->inventory($requestSkus); + $goodSkuService->inventory($goodsSkus); } } diff --git a/app/Listeners/CombinationGoodsStockUpdateListener.php b/app/Listeners/CombinationGoodsStockUpdateListener.php index e705197..0c119d9 100644 --- a/app/Listeners/CombinationGoodsStockUpdateListener.php +++ b/app/Listeners/CombinationGoodsStockUpdateListener.php @@ -54,9 +54,12 @@ class CombinationGoodsStockUpdateListener implements ShouldQueue } } } - - // 减子商品库存 这咯做了调整 其他批量更新不需要同步扣减库存 - if ($combinationGoodsIds&&!empty($event->type)) { + Log::info("组合时间监听:", [ + "event" => (array)$event, + "combinationGoodsIds" => $combinationGoodsIds, + "combinationGoodsItemIds" => $combinationGoodsItemIds + ]); + if ($combinationGoodsIds) { $combinationGoods = CombinationGood::query() ->with('goodsSku:id,stock') ->whereIn('goods_sku_id', $combinationGoodsIds) @@ -84,6 +87,7 @@ class CombinationGoodsStockUpdateListener implements ShouldQueue ->with('goodsSkuItem:id,stock,sale_stock') ->where('goods_sku_id', $goodsSkuId) ->get(); + $stock = []; $saleStock = []; foreach ($combinationGoods as $goods) { diff --git a/app/Models/GoodsSku.php b/app/Models/GoodsSku.php index 860c5fd..fae4305 100644 --- a/app/Models/GoodsSku.php +++ b/app/Models/GoodsSku.php @@ -33,6 +33,7 @@ class GoodsSku extends Model 'external_sku_id', 'is_combination', 'name', + 'sale_stock', ]; protected $hidden = ['created_at']; diff --git a/app/Services/GoodSku/GoodSkuService.php b/app/Services/GoodSku/GoodSkuService.php index b58f5b6..8dbb932 100644 --- a/app/Services/GoodSku/GoodSkuService.php +++ b/app/Services/GoodSku/GoodSkuService.php @@ -11,42 +11,52 @@ use Illuminate\Support\Facades\Log; class GoodSkuService { - - public function inventory(array $skusWithCombinationGoods,$skuInventoryMapKeyByExternalSkuId) + /** + * $skusWithCombinationGoods 除了携带组合商品的字段 还拼接了盘点的具体库存值inventory + * @param array $skusWithCombinationGoods + * @return void + */ + public function inventory(array $skusWithCombinationGoods) { //传进来的sku可能包含组合商品 所以这里需要事先计算好数据 - $inventoryKeyBySkuIdMap = []; - foreach($skusWithCombinationGoods as $sku){ - if(!empty($sku['is_combination'])){ - foreach ($sku['combination_goods'] as $combinationGoods){ + $inventoryKeyBySkuIdMap = collect($skusWithCombinationGoods)->where('is_combination', "=", 0) + ->pluck("inventory", "sku_id")->toArray(); + //计算组合商品 + foreach ($skusWithCombinationGoods as $sku) { + if (!empty($sku['is_combination'])) { + foreach ($sku['combination_goods'] as $combinationGoods) { + if (empty($inventoryKeyBySkuIdMap[$combinationGoods["item_id"]])) { + //没有盘点到的sku需要在原先的sku库存 + $inventoryKeyBySkuIdMap[$combinationGoods["item_id"]] = GoodsSku::query() + ->where('id', $combinationGoods["item_id"])->pluck('stock')->first()??0; + } + $inventoryKeyBySkuIdMap[$combinationGoods["item_id"]] += $combinationGoods['item_num'] * $sku['inventory']; } } } - $skus=[]; $today = DateTimeUtils::getToday(); $dateTime = date('Y-m-d H:i:s'); $updateIds = []; - foreach ($skus as $sku) { - if (!in_array($sku['external_sku_id'], $sku)) { - continue; - } + Log::info("库存盘点前完整信息", $skusWithCombinationGoods); + Log::info("需要操作的库存数据", $inventoryKeyBySkuIdMap); + foreach ($inventoryKeyBySkuIdMap as $skuId => $totalInventory) { // 更新 - $record = DailyStockRecord::query()->where('sku_id', $sku['id'])->where('day', $today)->firstOrCreate([ - 'sku_id' => $sku['id'], + $record = DailyStockRecord::query()->firstOrCreate([ + 'sku_id' => $skuId, 'day' => $today, ]); - $record->inventory = $skuInventoryMapKeyByExternalSkuId[$sku['external_sku_id']]['inventory']; + $record->inventory = $totalInventory; $record->inventory_time = $dateTime; $record->save(); //查询sku当前未发货的数量 目前数据看着有问题暂不操作 - //库存修改 盘点是直接覆盖所以这里加个锁 - GoodsSku::query()->where('id', $sku['id'])->lockForUpdate()->update([ - 'stock' => $requestSkusMap[$sku['external_sku_id']]['inventory'] + //库存修改 盘点是直接覆盖 + GoodsSku::query()->where('id', $skuId)->update([ + 'stock' => $totalInventory ]); - $updateIds[] = $sku['id']; + $updateIds[] = $skuId; } // 批量更新 event(new BatchStockUpdateEvent($updateIds)); diff --git a/database/migrations/2024_07_24_145201_add_sale_stock_and_quality_period_to_goods_skus_table.php b/database/migrations/2024_07_24_145201_add_sale_stock_and_quality_period_to_goods_skus_table.php index 0441c0a..ca59754 100644 --- a/database/migrations/2024_07_24_145201_add_sale_stock_and_quality_period_to_goods_skus_table.php +++ b/database/migrations/2024_07_24_145201_add_sale_stock_and_quality_period_to_goods_skus_table.php @@ -18,7 +18,7 @@ class AddSaleStockAndQualityPeriodToGoodsSkusTable extends Migration } Schema::table('goods_skus', function (Blueprint $table) { // - $table->integer('sale_stock')->default(9999)->comment("在售库存数"); + $table->integer('sale_stock')->default(9000)->comment("在售库存数"); $table->integer('quality_period')->nullable()->comment("保质期时间,单位天"); });