鲜花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
* @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']);
}
/**

View File

@ -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']);
}

View File

@ -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);
}
}

View File

@ -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) {

View File

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

View File

@ -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));

View File

@ -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("保质期时间,单位天");
});