鲜花2.0-库存盘点和批量导入

This commit is contained in:
杨建炊 2024-07-30 15:30:32 +08:00
parent f9220ef396
commit 91e4e5342e
7 changed files with 128 additions and 35 deletions

View File

@ -343,16 +343,87 @@ class GoodsSkusController extends Controller
} }
/** /**
* 库存盘点 * 库存盘点 准备废弃中
* *
* @param $request * @param $request
* @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\Routing\ResponseFactory|\Illuminate\Http\Response * @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\Routing\ResponseFactory|\Illuminate\Http\Response
*/ */
private function inventory($request) private function inventory($request)
{ {
$goodSkuService = new GoodSkuService(); DB::beginTransaction();
$goodSkuService->inventory($request->skus); 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']); return response($this->res, $this->res['httpCode']);
} }
/** /**

View File

@ -70,10 +70,10 @@ class DailyStockRecordController extends Controller
]; ];
return response($this->res, $this->res['httpCode']); return response($this->res, $this->res['httpCode']);
} }
$goodsSkuWithInventory = array_merge($goodsSku->toArray(),["inventory"=>$request->inventory]);
//同批量逻辑操作 //同批量逻辑操作
$goodSkuService = new GoodSkuService(); $goodSkuService = new GoodSkuService();
$goodSkuService->inventory([$goodsSku]); $goodSkuService->inventory([$goodsSkuWithInventory]);
return response($this->res, $this->res['httpCode']); return response($this->res, $this->res['httpCode']);
} }

View File

@ -22,20 +22,27 @@ class InventoryImport implements ToArray, SkipsEmptyRows
public function array(array $collection) public function array(array $collection)
{ {
unset($collection[0]); unset($collection[0]);
$externalSkuId = []; $externalSkuIds = [];
$requestSkus = []; $inventoryKeyByExternalSkuIdMap = [];
foreach ($collection as &$row) { foreach ($collection as &$row) {
$row = array_map(static function ($v) { $row = array_map(static function ($v) {
return trim($v); return trim($v);
}, $row); }, $row);
$requestSkus[] = [ $inventoryKeyByExternalSkuIdMap[$row[0]] = $row[2];
"external_sku_id" => $row[0], $externalSkuIds[] = $row[0];
"inventory" => $row[2],
];
} }
unset($row); unset($row);
//新版盘点excel字段 编码 商品名称 盘点数 //新版盘点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 = new GoodSkuService();
$goodSkuService->inventory($requestSkus); $goodSkuService->inventory($goodsSkus);
} }
} }

View File

@ -54,9 +54,12 @@ class CombinationGoodsStockUpdateListener implements ShouldQueue
} }
} }
} }
Log::info("组合时间监听:", [
// 减子商品库存 这咯做了调整 其他批量更新不需要同步扣减库存 "event" => (array)$event,
if ($combinationGoodsIds&&!empty($event->type)) { "combinationGoodsIds" => $combinationGoodsIds,
"combinationGoodsItemIds" => $combinationGoodsItemIds
]);
if ($combinationGoodsIds) {
$combinationGoods = CombinationGood::query() $combinationGoods = CombinationGood::query()
->with('goodsSku:id,stock') ->with('goodsSku:id,stock')
->whereIn('goods_sku_id', $combinationGoodsIds) ->whereIn('goods_sku_id', $combinationGoodsIds)
@ -84,6 +87,7 @@ class CombinationGoodsStockUpdateListener implements ShouldQueue
->with('goodsSkuItem:id,stock,sale_stock') ->with('goodsSkuItem:id,stock,sale_stock')
->where('goods_sku_id', $goodsSkuId) ->where('goods_sku_id', $goodsSkuId)
->get(); ->get();
$stock = []; $stock = [];
$saleStock = []; $saleStock = [];
foreach ($combinationGoods as $goods) { foreach ($combinationGoods as $goods) {

View File

@ -33,6 +33,7 @@ class GoodsSku extends Model
'external_sku_id', 'external_sku_id',
'is_combination', 'is_combination',
'name', 'name',
'sale_stock',
]; ];
protected $hidden = ['created_at']; protected $hidden = ['created_at'];

View File

@ -11,42 +11,52 @@ use Illuminate\Support\Facades\Log;
class GoodSkuService class GoodSkuService
{ {
/**
public function inventory(array $skusWithCombinationGoods,$skuInventoryMapKeyByExternalSkuId) * $skusWithCombinationGoods 除了携带组合商品的字段 还拼接了盘点的具体库存值inventory
* @param array $skusWithCombinationGoods
* @return void
*/
public function inventory(array $skusWithCombinationGoods)
{ {
//传进来的sku可能包含组合商品 所以这里需要事先计算好数据 //传进来的sku可能包含组合商品 所以这里需要事先计算好数据
$inventoryKeyBySkuIdMap = []; $inventoryKeyBySkuIdMap = collect($skusWithCombinationGoods)->where('is_combination', "=", 0)
foreach($skusWithCombinationGoods as $sku){ ->pluck("inventory", "sku_id")->toArray();
if(!empty($sku['is_combination'])){ //计算组合商品
foreach ($sku['combination_goods'] as $combinationGoods){ 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(); $today = DateTimeUtils::getToday();
$dateTime = date('Y-m-d H:i:s'); $dateTime = date('Y-m-d H:i:s');
$updateIds = []; $updateIds = [];
foreach ($skus as $sku) { Log::info("库存盘点前完整信息", $skusWithCombinationGoods);
if (!in_array($sku['external_sku_id'], $sku)) { Log::info("需要操作的库存数据", $inventoryKeyBySkuIdMap);
continue; foreach ($inventoryKeyBySkuIdMap as $skuId => $totalInventory) {
}
// 更新 // 更新
$record = DailyStockRecord::query()->where('sku_id', $sku['id'])->where('day', $today)->firstOrCreate([ $record = DailyStockRecord::query()->firstOrCreate([
'sku_id' => $sku['id'], 'sku_id' => $skuId,
'day' => $today, 'day' => $today,
]); ]);
$record->inventory = $skuInventoryMapKeyByExternalSkuId[$sku['external_sku_id']]['inventory']; $record->inventory = $totalInventory;
$record->inventory_time = $dateTime; $record->inventory_time = $dateTime;
$record->save(); $record->save();
//查询sku当前未发货的数量 目前数据看着有问题暂不操作 //查询sku当前未发货的数量 目前数据看着有问题暂不操作
//库存修改 盘点是直接覆盖所以这里加个锁 //库存修改 盘点是直接覆盖
GoodsSku::query()->where('id', $sku['id'])->lockForUpdate()->update([ GoodsSku::query()->where('id', $skuId)->update([
'stock' => $requestSkusMap[$sku['external_sku_id']]['inventory'] 'stock' => $totalInventory
]); ]);
$updateIds[] = $sku['id']; $updateIds[] = $skuId;
} }
// 批量更新 // 批量更新
event(new BatchStockUpdateEvent($updateIds)); event(new BatchStockUpdateEvent($updateIds));

View File

@ -18,7 +18,7 @@ class AddSaleStockAndQualityPeriodToGoodsSkusTable extends Migration
} }
Schema::table('goods_skus', function (Blueprint $table) { 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("保质期时间,单位天"); $table->integer('quality_period')->nullable()->comment("保质期时间,单位天");
}); });