erp/app/Services/GoodSku/GoodSkuService.php

132 lines
6.0 KiB
PHP
Raw Normal View History

2024-07-26 17:48:07 +08:00
<?php
namespace App\Services\GoodSku;
use App\Events\BatchStockUpdateEvent;
use App\Models\BusinessOrderItem;
use App\Models\CombinationGood;
2024-07-26 17:48:07 +08:00
use App\Models\DailyStockRecord;
use App\Models\GoodsSku;
use App\Utils\DateTimeUtils;
use Carbon\Carbon;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
2024-07-26 17:48:07 +08:00
class GoodSkuService
{
2024-07-30 15:30:32 +08:00
/**
* $skusWithCombinationGoods 除了携带组合商品的字段 还拼接了盘点的具体库存值inventory
* @param array $skusWithCombinationGoods
* @return void
*/
public function inventory(array $skusWithCombinationGoods)
2024-07-26 17:48:07 +08:00
{
$skusWithCombinationGoods = $this->handleSkusWithCombinationGoods($skusWithCombinationGoods);
//传进来的sku可能包含组合商品 所以这里需要事先计算好数据
2024-07-30 15:30:32 +08:00
$inventoryKeyBySkuIdMap = collect($skusWithCombinationGoods)->where('is_combination', "=", 0)
->pluck("inventory", "id")->toArray();
2024-07-30 15:30:32 +08:00
//计算组合商品
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;
2024-07-30 15:30:32 +08:00
}
2024-07-30 15:30:32 +08:00
$inventoryKeyBySkuIdMap[$combinationGoods["item_id"]] += $combinationGoods['item_num'] * $sku['inventory'];
}
}
}
2024-07-26 17:48:07 +08:00
$today = DateTimeUtils::getToday();
$dateTime = date('Y-m-d H:i:s');
$updateIds = [];
2024-07-30 15:30:32 +08:00
Log::info("库存盘点前完整信息", $skusWithCombinationGoods);
Log::info("需要操作的库存数据", $inventoryKeyBySkuIdMap);
foreach ($inventoryKeyBySkuIdMap as $skuId => $totalInventory) {
2024-07-26 17:48:07 +08:00
// 更新
2024-07-30 15:30:32 +08:00
$record = DailyStockRecord::query()->firstOrCreate([
'sku_id' => $skuId,
2024-07-26 17:48:07 +08:00
'day' => $today,
]);
2024-07-30 15:30:32 +08:00
$record->inventory = $totalInventory;
2024-07-26 17:48:07 +08:00
$record->inventory_time = $dateTime;
$record->save();
2024-07-30 15:30:32 +08:00
//库存修改 盘点是直接覆盖
GoodsSku::query()->where('id', $skuId)->update([
'stock' => $totalInventory
2024-07-26 17:48:07 +08:00
]);
2024-07-30 15:30:32 +08:00
$updateIds[] = $skuId;
2024-07-26 17:48:07 +08:00
}
// 批量更新
event(new BatchStockUpdateEvent($updateIds));
}
2024-07-26 17:48:07 +08:00
/**
* 库存盘点 需要扣减未发货未取消的订单数据
* 目前只查询了7日内的数据
* @param array $skusWithCombinationGoods
* @return \Illuminate\Support\Collection
*/
public function handleSkusWithCombinationGoods(array $skusWithCombinationGoods){
//查询sku当前未发货的数量 需要扣减
$externalSkuIds = collect($skusWithCombinationGoods)->pluck("external_sku_id")->toArray();
//默认只查7天内未发货的数据
$startTime = Carbon::now()->subDays(7)->startOfDay()->toDateTimeString();
$unshippedDataCollect = BusinessOrderItem::query()
->leftJoin("business_orders as b", "business_order_id", "=", "b.id")
->select("external_sku_id", DB::raw("sum(goods_number) as goods_total"), DB::raw("sum(already_cancel_number) as cancel_total"))
->whereIn("external_sku_id", $externalSkuIds)->where("b.shipping_status", "=", 0)
->where("business_order_items.created_at", ">=", $startTime)->where("business_order_items.cancel_status", "=", 0)
->groupBy('external_sku_id')->get()->toArray();
$unshippedData = collect($unshippedDataCollect)->pluck(null,"external_sku_id")->toArray();
Log::info("7日内未发货数据", $unshippedData);
return collect($skusWithCombinationGoods)->map(function ($v) use ($unshippedData) {
if (!empty($unshippedData[$v['external_sku_id']])) {
$v['inventory'] = $v['inventory'] - $unshippedData[$v['external_sku_id']]['goods_total']
+ $unshippedData[$v['external_sku_id']]['cancel_total'];
}
return $v;
})->toArray();
}
public static function computeSkuStock(array $goodsSkuItem, array $v)
{
$updateIds = [];
Log::info("库存更新前完整商品信息", $goodsSkuItem);
Log::info("库存更新前完整请求信息", $v);
$updateParams = [];
if (empty($goodsSkuItem['is_combination'])) {
$updateParam = [
'stock' => $goodsSkuItem['stock'] + $v['num'],
'sale_stock' => $goodsSkuItem['sale_stock'] + $v['num'],
'cost' => number_format(($goodsSkuItem['stock'] * $goodsSkuItem['cost'] + $v['cost'] * $v['num'])
/ ($goodsSkuItem['stock'] + $v['num']), 2),
];
GoodsSku::query()->where('external_sku_id', $goodsSkuItem['external_sku_id'])->update($updateParams);
$updateIds[] = $goodsSkuItem['id'];
$updateParams[] = $updateParam;
} else {
//组合商品 这里需要重新获取 减少更新丢失概率
$combinationGood = CombinationGood::query()->with('goodsSkuItem:id,stock,sale_stock')
->where('goods_sku_id', $goodsSkuItem['id'])->get();
foreach ($combinationGood as $item) {
$updateParam = [
'stock' => $item['goodsSkuItem']['stock'] + $v['num'] * $item['item_num'],
'sale_stock' => $item['goodsSkuItem']['sale_stock'] + $v['num'] * $item['item_num'],
];
GoodsSku::query()->where('id', $item['goodsSkuItem']['id'])->update($updateParam);
$updateIds[] = $item['goodsSkuItem']['id'];
$updateParams[] = $updateParam;
}
}
Log::info("本次请求更新参数", $updateParams);
return $updateIds;
2024-07-26 17:48:07 +08:00
}
}