erp/app/Listeners/CombinationGoodsStockUpdateListener.php

136 lines
5.0 KiB
PHP
Raw Permalink Normal View History

2023-04-21 19:43:17 +08:00
<?php
namespace App\Listeners;
use App\Models\CombinationGood;
2023-11-21 16:27:14 +08:00
use App\Models\DailyStockRecord;
2023-04-21 19:43:17 +08:00
use App\Models\GoodsSku;
2023-11-21 16:27:14 +08:00
use App\Utils\DateTimeUtils;
2023-04-21 19:43:17 +08:00
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Queue\InteractsWithQueue;
2023-11-18 14:35:19 +08:00
use App\Events\BatchStockUpdateEvent;
2024-10-31 14:37:42 +08:00
use Illuminate\Support\Facades\DB;
2024-07-26 17:48:07 +08:00
use Illuminate\Support\Facades\Log;
2023-04-21 19:43:17 +08:00
2024-03-23 14:58:41 +08:00
class CombinationGoodsStockUpdateListener implements ShouldQueue
2023-04-21 19:43:17 +08:00
{
2024-03-23 14:58:41 +08:00
use InteractsWithQueue;
2023-04-21 19:43:17 +08:00
/**
* Create the event listener.
*
* @return void
*/
public function __construct()
{
//
}
/**
* Handle the event.
*
* @param $event
* @return void
*/
public function handle($event)
{
2023-11-18 14:35:19 +08:00
if (!$event->combinationGoodsUpdate) {
2023-11-21 16:27:14 +08:00
return false;
2023-04-21 19:43:17 +08:00
}
$updateIds = $combinationGoodsIds = $combinationGoodsItemIds = [];
2023-11-18 14:35:19 +08:00
if (!empty($event->goodsSku)) {
2023-04-21 19:43:17 +08:00
if ($event->goodsSku->is_combination) {
$combinationGoodsIds[] = $event->goodsSku->id;
} else {
2023-04-26 11:43:25 +08:00
$combinationGoodsItemIds[] = $event->goodsSku->id;
2023-04-21 19:43:17 +08:00
}
}
2023-11-21 16:27:14 +08:00
2023-11-18 14:35:19 +08:00
if (!empty($event->goodsSkus)) {
2023-04-21 19:43:17 +08:00
foreach ($event->goodsSkus as $sku) {
if ($sku->is_combination) {
$combinationGoodsIds[] = $sku->id;
} else {
2023-04-26 11:44:14 +08:00
$combinationGoodsItemIds[] = $sku->id;
2023-04-21 19:43:17 +08:00
}
}
}
2024-10-31 14:37:42 +08:00
$updateIds = [];
2024-10-29 16:47:05 +08:00
//拉取三分订单时可能出现组合订单的情况 需要同步扣减库存
2024-07-30 15:30:32 +08:00
if ($combinationGoodsIds) {
2023-04-21 19:43:17 +08:00
$combinationGoods = CombinationGood::query()
->with('goodsSku:id,stock')
->whereIn('goods_sku_id', $combinationGoodsIds)
->get();
2024-10-31 18:56:50 +08:00
$num = !empty($event->num) ? $event->num : -1;
2023-04-21 19:43:17 +08:00
foreach ($combinationGoods as $item) {
2024-10-31 16:33:15 +08:00
DB::transaction(function () use ($item, &$updateIds, $num) {
2024-11-11 13:35:12 +08:00
$goodsSku = GoodsSku::query()->find($item['item_id']);
2024-10-31 18:56:50 +08:00
$stock = $goodsSku->stock + $item['item_num'] * $num;
2024-10-31 14:37:42 +08:00
//新增逻辑 在线库存同步扣减
2024-10-31 18:56:50 +08:00
$saleStock = max($goodsSku->sale_stock + $item['item_num'] * $num, 0);
2024-10-31 14:37:42 +08:00
[$status, $stock] = $this->checkStatusAndStock($goodsSku, $stock, $saleStock);
$goodsSku->status = $status;
$goodsSku->stock = $stock;
$goodsSku->sale_stock = $saleStock;
$goodsSku->save();
2024-11-12 13:49:03 +08:00
Log::info("sku 业务订单库存更:{$goodsSku->id},num:{$num}", [$stock, $saleStock]);
2024-10-31 17:38:43 +08:00
$mainGoodsSku = GoodsSku::query()->find($item['goods_sku_id']);
2024-11-12 13:49:03 +08:00
$mainGoodsSku->stock = min($mainGoodsSku->stock, (int)($stock / $item['item_num']));
$mainGoodsSku->sale_stock = min($mainGoodsSku->sale_stock, (int)($saleStock / $item['item_num']));
2024-10-31 17:38:43 +08:00
$mainGoodsSku->save();
2024-10-31 14:37:42 +08:00
$updateIds[] = $goodsSku->id;
});
2023-04-21 19:43:17 +08:00
}
}
// 计算主商品库存
if ($combinationGoodsItemIds) {
2023-04-26 11:43:25 +08:00
$goodsSkuIds = CombinationGood::query()
->whereIn('item_id', $combinationGoodsItemIds)
2023-11-21 16:27:14 +08:00
->pluck('goods_sku_id');
2023-04-26 11:43:25 +08:00
foreach ($goodsSkuIds as $goodsSkuId) {
$combinationGoods = CombinationGood::query()
2024-07-26 17:48:07 +08:00
->with('goodsSkuItem:id,stock,sale_stock')
2023-04-26 11:43:25 +08:00
->where('goods_sku_id', $goodsSkuId)
->get();
2024-07-30 15:30:32 +08:00
$stock = [];
2024-07-26 17:48:07 +08:00
$saleStock = [];
2023-04-26 11:43:25 +08:00
foreach ($combinationGoods as $goods) {
$stock[] = (int)($goods['goodsSkuItem']['stock'] / $goods['item_num']);
2024-07-26 17:48:07 +08:00
$saleStock[] = (int)($goods['goodsSkuItem']['sale_stock'] / $goods['item_num']);
2023-04-21 19:43:17 +08:00
}
2024-07-26 17:48:07 +08:00
//库存和在线可售库存都是通过子商品维护的
$stock = min($stock);
2024-07-26 17:48:07 +08:00
$saleStock = min($saleStock);
2023-11-21 16:27:14 +08:00
$goodsSku = GoodsSku::query()->find($goodsSkuId);
2024-07-26 17:48:07 +08:00
//新增在线可售逻辑判断 前置已经完成逻辑扣减或者增加
[$status, $stock] = $this->checkStatusAndStock($goodsSku, $stock, $saleStock);
2023-11-21 16:27:14 +08:00
$goodsSku->status = $status;
$goodsSku->stock = $stock;
2024-07-26 17:48:07 +08:00
$goodsSku->sale_stock = $saleStock;
2023-11-21 16:27:14 +08:00
$goodsSku->save();
2023-04-26 11:43:25 +08:00
$updateIds[] = $goodsSkuId;
2023-04-21 19:43:17 +08:00
}
}
2023-04-21 19:43:17 +08:00
if ($updateIds) {
2023-04-26 10:51:15 +08:00
$updateIds = array_unique($updateIds);
2023-11-18 14:35:19 +08:00
// 批量更新
event(new BatchStockUpdateEvent($updateIds, false));
2023-04-21 19:43:17 +08:00
}
}
2023-11-21 16:27:14 +08:00
2024-07-26 17:48:07 +08:00
private function checkStatusAndStock($goodsSku, $stock, $saleStock)
2023-11-21 16:27:14 +08:00
{
2024-07-26 17:48:07 +08:00
//下线库存判断以在线可售库存为准
if (0 >= $saleStock) {
2023-11-21 16:27:14 +08:00
$status = GoodsSku::$STATUS_DOWN;
} else {
$status = GoodsSku::$STATUS_ON_SALE;
}
return [$status, $stock];
}
2023-04-21 19:43:17 +08:00
}