diff --git a/app/Events/BatchStockUpdateEvent.php b/app/Events/BatchStockUpdateEvent.php index a9f2778..0f56371 100644 --- a/app/Events/BatchStockUpdateEvent.php +++ b/app/Events/BatchStockUpdateEvent.php @@ -10,6 +10,7 @@ use Illuminate\Broadcasting\PrivateChannel; use Illuminate\Contracts\Broadcasting\ShouldBroadcast; use Illuminate\Foundation\Events\Dispatchable; use Illuminate\Queue\SerializesModels; +use Illuminate\Support\Facades\Log; class BatchStockUpdateEvent { diff --git a/app/Exports/GoodsSkusExport.php b/app/Exports/GoodsSkusExport.php index cc5a781..f224fab 100644 --- a/app/Exports/GoodsSkusExport.php +++ b/app/Exports/GoodsSkusExport.php @@ -2,8 +2,10 @@ namespace App\Exports; +use App\Http\Enum\TargetTypeEnum; use App\Models\DailyStockRecord; use App\Models\Log; +use App\Models\PurchaseRecords; use App\Utils\ArrayUtils; use App\Utils\DateTimeUtils; use Maatwebsite\Excel\Concerns\FromCollection; @@ -35,14 +37,12 @@ class GoodsSkusExport implements FromCollection, ShouldAutoSize $headTitle = [ '商品编码', '商品名称', - '商品种类', - '商品品牌', - '规格编码', + '商品品种', '规格名称', ]; $map = [ - 'cost' => ['成本', '更新前成本', '更新后成本'], - 'inventory' => ['库存', '盘点', '上新'], + 'cost' => ['当前成本', '更新前成本', "更新后成本"], + 'inventory' => ['当前库存', '盘点数', '采购总数'], ]; $headTitle = array_merge($headTitle, $map[$this->type]); if ('cost' === $this->type) { @@ -70,21 +70,19 @@ class GoodsSkusExport implements FromCollection, ShouldAutoSize } $bodyData = []; foreach ($data as $item) { - $arr[0] = $item['goods']['goods_code']; - $arr[1] = $item['goods']['title']; - $arr[2] = $item['goods']['type']['name']; - $arr[3] = $item['goods']['brand']['name']; - $arr[4] = $item['sku_code']; - $arr[5] = $item['title']; + $arr[0] = $item['external_sku_id']; + $arr[1] = $item['name']; + $arr[2] = !empty($item['goods']['type']['name']) ? $item['goods']['type']['name'] : ''; + $arr[3] = $item['title']; if ('cost' === $this->type) { - $arr[6] = (string)$item['cost']; - $arr[7] = (string)$update[$item['id']]['before_update']; - $arr[8] = (string)$update[$item['id']]['after_update']; + $arr[4] = (string)$item['cost']; + $arr[5] = (string)$update[$item['id']]['before_update']; + $arr[6] = (string)$update[$item['id']]['after_update']; } if ('inventory' === $this->type) { - $arr[6] = (string)$item['stock']; - $arr[7] = (string)$update[$item['id']]['inventory']; - $arr[8] = (string)$update[$item['id']]['arrived_today_num']; + $arr[4] = (string)$item['stock']; + $arr[5] = (string)$update[$item['id']]['inventory']; + $arr[6] = (string)$update[$item['id']]['arrived_today_num']; } $bodyData[] = $arr; } @@ -97,18 +95,23 @@ class GoodsSkusExport implements FromCollection, ShouldAutoSize $day = DateTimeUtils::getToday(); $logs = Log::query() ->select(['target_id', 'before_update', 'after_update']) - ->where('target_type', 'goods_sku') - ->where('target_field', 'cost') + ->where('target_type', TargetTypeEnum::PURCHASE) + ->where('target_field', 'stock') ->where('created_at', '>', $day) - ->orderBy('id', 'asc') ->get(); + $update = []; foreach ($logs as $log) { - if ($log['before_update'] !== $log['after_update'] || (int)$log['after_update']) { - if (!isset($update[$log['target_id']])) { - $update[$log['target_id']]['before_update'] = $log['before_update']; + if (!isset($update[$log['target_id']])) { + $beforeData = json_decode($log['before_update'], true); + if (!empty($beforeData['cost'])) { + $update[$log['target_id']]['before_update'] = $beforeData['cost']; } - $update[$log['target_id']]['after_update'] = $log['after_update']; + + } + $afterData = json_decode($log['after_update'], true); + if (!empty($afterData['cost']) && $afterData['cost'] != $beforeData['cost']) { + $update[$log['target_id']]['after_update'] = $afterData['cost']; } } diff --git a/app/Exports/WeekDataExport.php b/app/Exports/WeekDataExport.php index f22d8b1..7147e4b 100644 --- a/app/Exports/WeekDataExport.php +++ b/app/Exports/WeekDataExport.php @@ -33,9 +33,8 @@ class WeekDataExport implements FromCollection, ShouldAutoSize { $headTitle = [ '商品名称', - '品类', - '规格', - '品牌', + '品种', + '规格名称', '商品编码', '成本', '销售数量', @@ -51,8 +50,7 @@ class WeekDataExport implements FromCollection, ShouldAutoSize ->with([ 'goods:id,title', 'goodsType:id,name', - 'goodsSku:id,title', - 'goodsBrand:id,name', + 'goodsSku:id,title,name' ]) ->where('date', '>=', $this->startDate) ->where('date', '<=', $this->endDate) @@ -66,10 +64,9 @@ class WeekDataExport implements FromCollection, ShouldAutoSize $number = $item->total_goods_number - $item->total_cancel_number; if (!isset($arr[$item->external_sku_id])) { $arr[$item->external_sku_id] = [ - 'goodsTitle' => $item->goods->title, - 'goodsTypeName' => $item->goodsType->name, - 'goodsSkuTitle' => $item->goodsSku->title, - 'goodsBrandName' => $item->goodsBrand->name, + 'goodsTitle' => !empty($item->goodsSku) ? $item->goodsSku->name:'', + 'goodsTypeName' => !empty($item->goodsType) ? $item->goodsType->name : "", + 'goodsSkuTitle' => !empty($item->goodsSku) ? $item->goodsSku->title : "", 'external_sku_id' => $item->external_sku_id, 'cost' => [], 'number' => [], @@ -97,7 +94,6 @@ class WeekDataExport implements FromCollection, ShouldAutoSize $item['goodsTitle'], $item['goodsTypeName'], $item['goodsSkuTitle'], - $item['goodsBrandName'], $item['external_sku_id'], $cost, array_sum($item['number']), diff --git a/app/Http/Controllers/Goods/GoodsCombinationController.php b/app/Http/Controllers/Goods/GoodsCombinationController.php index 25cafa6..ec9d2bf 100644 --- a/app/Http/Controllers/Goods/GoodsCombinationController.php +++ b/app/Http/Controllers/Goods/GoodsCombinationController.php @@ -193,11 +193,8 @@ class GoodsCombinationController extends Controller public function goodsSkus(Request $request, $title) { - $goodsIds = Goods::query() - ->where('title', 'like', '%' . $title . '%') - ->pluck('id'); $skus = GoodsSku::query() - ->whereIn('goods_id', $goodsIds) + ->where('title', 'like', '%' . $title . '%') ->where('is_combination', 0) ->with('goods:id,title') ->get(['id', 'title', 'goods_id']); diff --git a/app/Http/Controllers/Supplier/DailyStockRecordController.php b/app/Http/Controllers/Supplier/DailyStockRecordController.php index 9990f89..d44c913 100644 --- a/app/Http/Controllers/Supplier/DailyStockRecordController.php +++ b/app/Http/Controllers/Supplier/DailyStockRecordController.php @@ -84,12 +84,10 @@ class DailyStockRecordController extends Controller */ public function inventoryBatchStore(Request $request) { - $validator = Validator::make($request->all(), [ 'inventoryOrders' => 'required|array', 'inventoryOrders.*.external_sku_id' => 'required|string', 'inventoryOrders.*.inventory' => 'required|integer', - ]); if ($validator->fails()) { //校验失败返回异常 diff --git a/app/Http/Controllers/Supplier/LossRecordController.php b/app/Http/Controllers/Supplier/LossRecordController.php index 70b1e77..c6ae66f 100644 --- a/app/Http/Controllers/Supplier/LossRecordController.php +++ b/app/Http/Controllers/Supplier/LossRecordController.php @@ -158,7 +158,7 @@ class LossRecordController extends Controller return response($content, $this->res['httpCode']); } $goodsSkuMap = $goodsSku->pluck(null, 'external_sku_id')->toArray(); - $updateIds = []; + $allUpdateIds = []; $batchNumber = GeneratorUtils::generateBatchNumber(); $today = DateTimeUtils::getToday(); //开始保存数据 @@ -178,10 +178,10 @@ class LossRecordController extends Controller $lossRecords->save(); $updateIds = GoodSkuService::computeSkuStock($goodsSkuItem, ['num' => 0 - $v['num'], "cost" => $v['cost']]); - + $allUpdateIds = array_merge($allUpdateIds, $updateIds); } - event(new BatchStockUpdateEvent($updateIds)); + event(new BatchStockUpdateEvent(collect($allUpdateIds)->unique()->toArray())); return response($this->res, $this->res['httpCode']); } diff --git a/app/Http/Controllers/Supplier/PurchaseRecordController.php b/app/Http/Controllers/Supplier/PurchaseRecordController.php index 6f88d1f..e964eac 100644 --- a/app/Http/Controllers/Supplier/PurchaseRecordController.php +++ b/app/Http/Controllers/Supplier/PurchaseRecordController.php @@ -99,7 +99,7 @@ class PurchaseRecordController extends Controller } $purchaseRecords->save(); - $updateIds = GoodSkuService::computeSkuStock($goodsSku->toArray(), $allParams,TargetTypeEnum::PURCHASE); + $updateIds = GoodSkuService::computeSkuStock($goodsSku->toArray(), $allParams, TargetTypeEnum::PURCHASE); event(new BatchStockUpdateEvent($updateIds)); } else { $this->res = [ @@ -180,7 +180,7 @@ class PurchaseRecordController extends Controller return response($content, $this->res['httpCode']); } $goodsSkuMap = $goodsSku->pluck(null, 'external_sku_id')->toArray(); - $updateIds = []; + $allUpdateIds = []; $expireDay = DeveloperConfigService::getDefaultExpireDay(); $today = DateTimeUtils::getToday(); $batchNumber = GeneratorUtils::generateBatchNumber(); @@ -201,11 +201,12 @@ class PurchaseRecordController extends Controller $purchaseRecords->expire_time = Carbon::now()->addDays($expireDay)->toDateTimeString(); $purchaseRecords->save(); - $updateIds = GoodSkuService::computeSkuStock($goodsSkuItem, $v,TargetTypeEnum::PURCHASE); - + $updateIds = GoodSkuService::computeSkuStock($goodsSkuItem, $v, TargetTypeEnum::PURCHASE); + $allUpdateIds = array_merge($allUpdateIds, $updateIds); } + //如果是組合商品会触发重算逻辑 - event(new BatchStockUpdateEvent($updateIds)); + event(new BatchStockUpdateEvent(collect($allUpdateIds)->unique()->toArray())); return response($this->res, $this->res['httpCode']); } diff --git a/app/Http/Enum/TargetTypeEnum.php b/app/Http/Enum/TargetTypeEnum.php index 95a1973..5f66294 100644 --- a/app/Http/Enum/TargetTypeEnum.php +++ b/app/Http/Enum/TargetTypeEnum.php @@ -6,8 +6,10 @@ namespace App\Http\Enum; class TargetTypeEnum { - const PURCHASE = "purchase"; + const PURCHASE = "sku_stock_purchase"; - const LOSS = "loss"; + const LOSS = "sku_stock_loss"; + + const INVENTORY = "sku_stock_inventory"; } \ No newline at end of file diff --git a/app/Imports/LossImport.php b/app/Imports/LossImport.php index 52a4d60..02d89c6 100644 --- a/app/Imports/LossImport.php +++ b/app/Imports/LossImport.php @@ -38,7 +38,7 @@ class LossImport implements ToArray, SkipsEmptyRows $buyerNames[] = $row[4]; } unset($row); - $updateIds = []; + $allUpdateIds = []; $hasGoodsSkus = GoodsSku::query() ->whereIn('external_sku_id', $externalSkuIds) ->get(['id', 'status', 'external_sku_id', 'stock', "sale_stock", "cost", "is_combination"]) @@ -71,11 +71,12 @@ class LossImport implements ToArray, SkipsEmptyRows } $lossRecords->save(); - $updateIds += GoodSkuService::computeSkuStock($goodsSkuItem, ["num" => 0 - $row[2], 'cost' => $row[3]]); + $updateIds = GoodSkuService::computeSkuStock($goodsSkuItem, ["num" => 0 - $row[2], 'cost' => $row[3]]); + $allUpdateIds = array_merge($allUpdateIds, $updateIds); } Log::info("报损导入内容:", $collection); // 批量更新 - event(new BatchStockUpdateEvent(collect($updateIds)->unique()->toArray())); + event(new BatchStockUpdateEvent(collect($allUpdateIds)->unique()->toArray())); } diff --git a/app/Imports/PurchaseImport.php b/app/Imports/PurchaseImport.php index c8c5954..4048d4a 100644 --- a/app/Imports/PurchaseImport.php +++ b/app/Imports/PurchaseImport.php @@ -42,7 +42,7 @@ class PurchaseImport implements ToArray, SkipsEmptyRows $supplierNames[] = $row[5]; } unset($row); - $updateIds = []; + $allUpdateIds = []; $hasGoodsSkus = GoodsSku::query() ->whereIn('external_sku_id', $externalSkuIds) ->get(['id', 'status', 'external_sku_id', 'stock', "sale_stock", "cost", "is_combination"]) @@ -80,11 +80,13 @@ class PurchaseImport implements ToArray, SkipsEmptyRows $purchaseRecords->expire_time = Carbon::now()->addDays($expireDay)->toDateTimeString(); $purchaseRecords->save(); - $updateIds += GoodSkuService::computeSkuStock($goodsSkuItem, ["num" => $row[2], 'cost' => $row[3]], TargetTypeEnum::PURCHASE); + $updateIds = GoodSkuService::computeSkuStock($goodsSkuItem, ["num" => $row[2], 'cost' => $row[3]], TargetTypeEnum::PURCHASE); + $allUpdateIds = array_merge($allUpdateIds, $updateIds); } Log::info("采购导入内容:", $collection); + Log::info("allUpdateIds:", $allUpdateIds); // 批量更新 - event(new BatchStockUpdateEvent(collect($updateIds)->unique()->toArray())); + event(new BatchStockUpdateEvent(collect($allUpdateIds)->unique()->toArray())); } } } diff --git a/app/Listeners/CombinationGoodsStockUpdateListener.php b/app/Listeners/CombinationGoodsStockUpdateListener.php index 2dd3ee3..73c714e 100644 --- a/app/Listeners/CombinationGoodsStockUpdateListener.php +++ b/app/Listeners/CombinationGoodsStockUpdateListener.php @@ -103,6 +103,7 @@ class CombinationGoodsStockUpdateListener implements ShouldQueue $updateIds[] = $goodsSkuId; } } + if ($updateIds) { $updateIds = array_unique($updateIds); // 批量更新 diff --git a/app/Services/GoodSku/GoodSkuService.php b/app/Services/GoodSku/GoodSkuService.php index edce904..23b1807 100644 --- a/app/Services/GoodSku/GoodSkuService.php +++ b/app/Services/GoodSku/GoodSkuService.php @@ -8,6 +8,7 @@ use App\Models\BusinessOrderItem; use App\Models\CombinationGood; use App\Models\DailyStockRecord; use App\Models\GoodsSku; +use App\Models\Log as LogModel; use App\Utils\DateTimeUtils; use App\Utils\GeneratorUtils; use Carbon\Carbon; @@ -52,7 +53,7 @@ class GoodSkuService DB::beginTransaction(); try { foreach ($skusWithCombinationGoods as $sku) { - // 更新 + // 更新每日数据 DailyStockRecord::query()->updateOrCreate([ 'sku_id' => $sku['id'], 'day' => $today, @@ -62,19 +63,26 @@ class GoodSkuService "batch_number" => $batchNumber ]); } - + $costLogs = []; + //更新库存并记录数据 foreach ($inventoryKeyBySkuIdMap as $skuId => $realStock) { //库存修改 盘点是直接覆盖 - GoodsSku::query()->where('id', $skuId)->update([ - 'stock' => $realStock - ]); - $updateIds[] = $skuId; + $skuData = GoodsSku::query()->where('id', $skuId)->first(); + if(!empty($skuData)){ + $costLogs[] = static::addStockLog($skuData, [] + , TargetTypeEnum::INVENTORY, ['stock' => $realStock]); + $skuData->stock = $realStock; + $skuData->save(); + $updateIds[] = $skuId; + } + } + $log = new LogModel(); + $log->batchInsert($costLogs); DB::commit(); } catch (\Exception $exception) { DB::rollBack(); Log::error("库存盘点异常", ["error" => $exception->getMessage()]); - } // 批量更新 @@ -113,39 +121,65 @@ class GoodSkuService } - public static function computeSkuStock(array $goodsSkuItem, array $v, $targetType = TargetTypeEnum::LOSS) + public static function computeSkuStock(array $goodsSkuItem, array $changeData, $targetType = TargetTypeEnum::LOSS) { $updateIds = []; Log::info("库存更新前完整商品信息", $goodsSkuItem); - Log::info("库存更新前完整请求信息", $v); + Log::info("库存更新前完整请求信息", $changeData); $updateParams = []; + //添加系统日志 + $costLogs = []; + // 成本 if (empty($goodsSkuItem['is_combination'])) { $updateParam = [ - 'stock' => $goodsSkuItem['stock'] + $v['num'], - 'sale_stock' => $goodsSkuItem['sale_stock'] + $v['num'], + 'stock' => $goodsSkuItem['stock'] + $changeData['num'], + 'sale_stock' => $goodsSkuItem['sale_stock'] + $changeData['num'], ]; if ($targetType == TargetTypeEnum::PURCHASE) { - $updateParam['cost'] = $v['cost']; + $updateParam['cost'] = $changeData['cost']; } GoodsSku::query()->where('external_sku_id', "=", $goodsSkuItem['external_sku_id']) ->update($updateParam); $updateIds[] = $goodsSkuItem['id']; $updateParams[] = $updateParam; + $costLogs[] = static::addStockLog($goodsSkuItem, $changeData, $targetType, $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'], + 'stock' => $item['goodsSkuItem']['stock'] + $changeData['num'] * $item['item_num'], + 'sale_stock' => $item['goodsSkuItem']['sale_stock'] + $changeData['num'] * $item['item_num'], ]; GoodsSku::query()->where('id', $item['goodsSkuItem']['id'])->update($updateParam); + $updateIds[] = $item['goodsSkuItem']['id']; $updateParams[] = $updateParam; + $costLogs[] = static::addStockLog($item['goodsSkuItem'], $changeData, $targetType, $updateParam); } } + $log = new LogModel(); + $log->batchInsert($costLogs); Log::info("本次请求更新参数", $updateParams); return $updateIds; } + public static function addStockLog($goodsSkuItem, $changeData, $targetType = TargetTypeEnum::LOSS, $updateParam) + { + $costLog = [ + 'module' => 'goodSkus', + 'action' => "POST", + 'target_type' => $targetType, + 'target_id' => $goodsSkuItem['id'] ?? 0, + 'user_id' => $changeData['user_id'] ?? 999, + "target_field" => "stock" + ]; + $costLog['before_update'] = json_encode($goodsSkuItem); + $costLog['after_update'] = json_encode($updateParam); + + return $costLog; + } + }