mirror of
https://gitee.com/hzchunfen/erp.git
synced 2025-11-30 22:20:45 +00:00
鲜花2.0-库存盘点和批量导入
This commit is contained in:
parent
f9220ef396
commit
91e4e5342e
@ -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']);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -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']);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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) {
|
||||||
|
|||||||
@ -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'];
|
||||||
|
|||||||
@ -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));
|
||||||
|
|||||||
@ -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("保质期时间,单位天");
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user