From 05b5cd400a17c0b13351612bd59fd8dcd4a5e739 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=A8=E5=BB=BA=E7=82=8A?= <924182103@qq.com> Date: Tue, 13 Aug 2024 18:17:03 +0800 Subject: [PATCH] =?UTF-8?q?=E9=B2=9C=E8=8A=B12.0-=E6=8E=A5=E5=8F=A3?= =?UTF-8?q?=E6=B5=8B=E8=AF=95bug=E4=BF=AE=E5=A4=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Controllers/Goods/GoodsSkusController.php | 33 ++++++---- .../Supplier/DailyStockRecordController.php | 34 ++++++++++ .../Supplier/LossRecordController.php | 12 ++++ .../Supplier/PurchaseRecordController.php | 8 ++- app/Http/Enum/CacheKeyEnum.php | 2 + app/Http/Enum/DevConfigKeyEnum.php | 4 ++ app/Imports/LossImport.php | 12 ++-- app/Imports/PurchaseImport.php | 12 ++-- app/Listeners/BusinessOrderUpdateListener.php | 10 +-- .../DeveloperConfigService.php | 11 ++++ app/Services/GoodSku/GoodSkuService.php | 63 ++++++++++++------- app/Utils/DateTimeUtils.php | 6 ++ app/Utils/GeneratorUtils.php | 19 ++++++ ...4_144851_create_purchase_records_table.php | 7 ++- ...07_24_144925_create_loss_records_table.php | 8 ++- ...4_144950_create_website_messages_table.php | 6 +- ...24_07_24_145032_create_suppliers_table.php | 2 +- ...der_total_amount_to_daily_stock_record.php | 6 +- resources/lang/zh-CN/permission.php | 39 ++++++++---- routes/api.php | 4 ++ 20 files changed, 221 insertions(+), 77 deletions(-) create mode 100644 app/Utils/GeneratorUtils.php diff --git a/app/Http/Controllers/Goods/GoodsSkusController.php b/app/Http/Controllers/Goods/GoodsSkusController.php index 028a929..6034685 100644 --- a/app/Http/Controllers/Goods/GoodsSkusController.php +++ b/app/Http/Controllers/Goods/GoodsSkusController.php @@ -17,6 +17,7 @@ use App\Models\DeveloperConfig; use App\Models\Goods; use App\Models\Log; use App\Models\Log as LogModel; +use App\Services\DeveloperConfig\DeveloperConfigService; use App\Services\GoodSku\GoodSkuService; use App\Services\Ship\WayBillService; use App\Utils\ArrayUtils; @@ -113,7 +114,8 @@ class GoodsSkusController extends Controller ->whereIn('id', $finalIds) ->orderByRaw("FIELD(id, {$idField})") ->paginate($request->get('per_page')); - $rolesName = $request->user()->getRoleNames()->toArray(); + $user = $request->user()->toArray(); + $adminRoleIds = DeveloperConfigService::getSkuAdminRoleIds(); foreach ($goodsSkus as &$sku) { $lastInventoryTime = !empty($sku['daily']['inventory_time']) ? $sku['daily']['inventory_time'] : date('Y-m-d 07:00:00'); if (isset($externals[$sku['external_sku_id']])) { @@ -123,11 +125,22 @@ class GoodsSkusController extends Controller $sku['order_detail'] = []; $sku['order_goods_num'] = 0; } - $sku['order_goods_num'] -= $sku['daily']['reissue_num']??0; + $sku['order_goods_num'] -= $sku['daily']['reissue_num'] ?? 0; $sku['inventory_time'] = $lastInventoryTime; - if ('销售' === $rolesName[0]) { + if ('销售' === ($user['roles'][0]['name'] ?? "")) { $sku['cost'] = 0; } + if (in_array($user['roles'][0]['id'] ?? 0, $adminRoleIds)) { + $sku['is_admin'] = 1; + } else { + $sku['is_admin'] = 0; + } + + if (!empty($sku['yesterday_num'])) { + $sku['sale_ratio'] = round($sku['stock'] / $sku['yesterday_num'], 2)*100; + } else { + $sku['sale_ratio'] = 0; + } } return GoodsSkuResource::collection($goodsSkus); } @@ -221,7 +234,7 @@ class GoodsSkusController extends Controller public function batchUpdate(Request $request) { $appendRules = [ - 'updateType' => ['required', 'string', Rule::in(['newest', 'inventory', 'stock', "stockManage"])], + 'updateType' => ['required', 'string', Rule::in(['newest', 'inventory', 'stock', "saleStock"])], 'skus' => ['required', 'array'], 'skus.*.id' => [ 'required', @@ -246,7 +259,7 @@ class GoodsSkusController extends Controller * @param $request * @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\Routing\ResponseFactory|\Illuminate\Http\Response */ - private function stockManage($request) + private function saleStock($request) { DB::beginTransaction(); try { @@ -260,14 +273,12 @@ class GoodsSkusController extends Controller 'user_id' => $request->user()->id ]; // 成本 - $goodsSku = GoodsSku::query()->where('id', $sku['id'])->first(['id', 'cost', 'stock', 'num']); - $costLog['target_field'] = 'cost'; - $costLog['before_update'] = $goodsSku->cost; - $goodsSku->reference_price = $sku['cost'] * 1.5; - $goodsSku->cost = $sku['cost']; + $goodsSku = GoodsSku::query()->where('id', $sku['id'])->first(['id', 'cost', 'sale_stock']); + $costLog['target_field'] = 'sale_stock'; + $costLog['before_update'] = $goodsSku->sale_stock; $goodsSku->sale_stock = $sku['sale_stock']; $goodsSku->save(); - $costLog['after_update'] = $goodsSku->cost; + $costLog['after_update'] = $goodsSku->sale_stock; $logs[] = $costLog; } $log = new LogModel(); diff --git a/app/Http/Controllers/Supplier/DailyStockRecordController.php b/app/Http/Controllers/Supplier/DailyStockRecordController.php index bcdfb9a..9990f89 100644 --- a/app/Http/Controllers/Supplier/DailyStockRecordController.php +++ b/app/Http/Controllers/Supplier/DailyStockRecordController.php @@ -13,6 +13,7 @@ use App\Models\Log as LogModel; use App\Services\GoodSku\GoodSkuService; use Illuminate\Http\Request; use Illuminate\Http\Resources\Json\JsonResource; +use Illuminate\Support\Facades\Log; use Illuminate\Support\Facades\Validator; use Illuminate\Validation\ValidationException; use Maatwebsite\Excel\Facades\Excel; @@ -77,6 +78,39 @@ class DailyStockRecordController extends Controller return response($this->res, $this->res['httpCode']); } + /** + * @param Request $request + * @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\Routing\ResponseFactory|\Illuminate\Http\Response + */ + 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()) { + //校验失败返回异常 + $this->setValidatorFailResponse($validator->getMessageBag()->getMessages()); + return response($this->res, $this->res['httpCode']); + } + $inventoryKeyByExternalSkuIdMap = collect($request->inventoryOrders)->pluck(null,"external_sku_id")->toArray(); + $goodsSkus = GoodsSku::query()->with("combinationGoods")->whereIn('external_sku_id', array_keys($inventoryKeyByExternalSkuIdMap)) + ->get()->toArray(); + $goodsSkus = collect($goodsSkus)->map(function ($v) use ($inventoryKeyByExternalSkuIdMap) { + if (!empty($inventoryKeyByExternalSkuIdMap[$v['external_sku_id']])) { + $v['inventory'] = $inventoryKeyByExternalSkuIdMap[$v['external_sku_id']]['inventory']; + return $v; + } + })->toArray(); + Log::info("goodsSkus",$goodsSkus); + $goodSkuService = new GoodSkuService(); + $goodSkuService->inventory($goodsSkus); + return response($this->res, $this->res['httpCode']); + } + public function inventoryImport(Request $request) { diff --git a/app/Http/Controllers/Supplier/LossRecordController.php b/app/Http/Controllers/Supplier/LossRecordController.php index a31cc92..deab2c5 100644 --- a/app/Http/Controllers/Supplier/LossRecordController.php +++ b/app/Http/Controllers/Supplier/LossRecordController.php @@ -15,6 +15,7 @@ use App\Models\Suppliers; use App\Models\User; use App\Services\GoodSku\GoodSkuService; use App\Utils\DateTimeUtils; +use App\Utils\GeneratorUtils; use Illuminate\Http\Request; use Illuminate\Http\Resources\Json\JsonResource; use Illuminate\Support\Facades\DB; @@ -71,6 +72,7 @@ class LossRecordController extends Controller $today = DateTimeUtils::getToday(); //保存記錄 $lossRecords = new LossRecords(); + $lossRecords->batch_number = GeneratorUtils::generateBatchNumber(); $lossRecords->external_sku_id = $allParams['external_sku_id']; $lossRecords->num = $allParams['num']; $lossRecords->cost = $allParams['cost']; @@ -78,6 +80,7 @@ class LossRecordController extends Controller $lossRecords->buyer_user_id = $allParams['buyer_user_id'] ?? ($buyerUserId ?? 0); $lossRecords->buyer_name = $allParams['buyer_name'] ?? ''; $lossRecords->reason = $allParams['reason'] ?? ''; + $lossRecords->phenomenon = $v['phenomenon'] ?? ''; $lossRecords->save(); $updateIds = GoodSkuService::computeSkuStock($goodsSku->toArray(), ['num' => 0 - $allParams['num'], "cost" => $allParams['cost']]); event(new BatchStockUpdateEvent($updateIds)); @@ -115,6 +118,7 @@ class LossRecordController extends Controller $lossRecords->buyer_name = $allParams['buyer_name'] ?? ''; $lossRecords->buyer_user_id = $allParams['buyer_user_id'] ?? 0; $lossRecords->reason = $allParams['reason'] ?? ''; + $lossRecords->phenomenon = $allParams['phenomenon'] ?? ''; $lossRecords->save(); } else { $this->res = [ @@ -130,12 +134,15 @@ class LossRecordController extends Controller public function lossBatchStore(Request $request) { + \Illuminate\Support\Facades\Log::info("test",(array)$request->all()); $validator = Validator::make($request->all(), [ 'lossOrders' => 'required|array', 'lossOrders.*.external_sku_id' => 'required|string', 'lossOrders.*.num' => 'required|integer', 'lossOrders.*.reason' => 'sometimes|string', 'lossOrders.*.buyer_name' => 'sometimes|string',//采购商 + 'lossOrders.*.phenomenon' => 'sometimes|string', + 'lossOrders.*.date' => 'sometimes|date_format:Y-m-d' ]); //参数校验 if ($validator->fails()) { @@ -152,17 +159,22 @@ class LossRecordController extends Controller } $goodsSkuMap = $goodsSku->pluck(null, 'external_sku_id')->toArray(); $updateIds = []; + $batchNumber = GeneratorUtils::generateBatchNumber(); + $today = DateTimeUtils::getToday(); //开始保存数据 foreach ($lossOrders as $v) { $goodsSkuItem = $goodsSkuMap[$v['external_sku_id']]; //保存記錄 $lossRecords = new LossRecords(); + $lossRecords->batch_number = $batchNumber; $lossRecords->external_sku_id = $v['external_sku_id']; $lossRecords->num = $v['num']; $lossRecords->cost = $v['cost']; + $lossRecords->date = $v['date'] ?? $today; $lossRecords->buyer_user_id = $v['buyer_user_id'] ?? 0; $lossRecords->buyer_name = $v['buyer_name'] ?? ''; $lossRecords->reason = $v['reason'] ?? ''; + $lossRecords->phenomenon = $v['phenomenon'] ?? ''; $lossRecords->save(); $updateIds = GoodSkuService::computeSkuStock($goodsSkuItem, ['num' => 0 - $v['num'], "cost" => $v['cost']]); diff --git a/app/Http/Controllers/Supplier/PurchaseRecordController.php b/app/Http/Controllers/Supplier/PurchaseRecordController.php index bb9f962..b99140a 100644 --- a/app/Http/Controllers/Supplier/PurchaseRecordController.php +++ b/app/Http/Controllers/Supplier/PurchaseRecordController.php @@ -17,6 +17,7 @@ use App\Models\User; use App\Services\DeveloperConfig\DeveloperConfigService; use App\Services\GoodSku\GoodSkuService; use App\Utils\DateTimeUtils; +use App\Utils\GeneratorUtils; use Carbon\Carbon; use Illuminate\Http\Request; use Illuminate\Http\Resources\Json\JsonResource; @@ -81,6 +82,7 @@ class PurchaseRecordController extends Controller //保存記錄 $purchaseRecords = new PurchaseRecords(); $purchaseRecords->external_sku_id = $allParams['external_sku_id']; + $purchaseRecords->batch_number = GeneratorUtils::generateBatchNumber(); $purchaseRecords->num = $allParams['num']; $purchaseRecords->cost = $allParams['cost']; $purchaseRecords->date = $today; @@ -180,16 +182,18 @@ class PurchaseRecordController extends Controller $updateIds = []; $expireDay = DeveloperConfigService::getDefaultExpireDay(); $today = DateTimeUtils::getToday(); + $batchNumber = GeneratorUtils::generateBatchNumber(); //开始保存数据 foreach ($purchaseOrders as $v) { $goodsSkuItem = $goodsSkuMap[$v['external_sku_id']]; //保存記錄 $purchaseRecords = new PurchaseRecords(); + $purchaseRecords->batch_number = $batchNumber; $purchaseRecords->external_sku_id = $v['external_sku_id']; $purchaseRecords->num = $v['num']; $purchaseRecords->cost = $v['cost']; - $purchaseRecords->date = $today; - $purchaseRecords->buyer_user_id = $allParams['buyer_user_id'] ?? 0; + $purchaseRecords->date = $v['date'] ?? $today; + $purchaseRecords->buyer_user_id = $v['buyer_user_id'] ?? 0; $purchaseRecords->buyer_name = $v['buyer_name'] ?? ''; $purchaseRecords->supplier_name = $v['supplier_name'] ?? ''; $purchaseRecords->supplier_id = $v['supplier_id'] ?? 0; diff --git a/app/Http/Enum/CacheKeyEnum.php b/app/Http/Enum/CacheKeyEnum.php index 4f9ba60..feb5402 100644 --- a/app/Http/Enum/CacheKeyEnum.php +++ b/app/Http/Enum/CacheKeyEnum.php @@ -11,4 +11,6 @@ class CacheKeyEnum const DEFAULT_EXPIRE_DAY = "default_expire_day"; const SPU_STATISTIC_BY_DATE = "spu_statistic_by_date"; + + const SKU_ADMIN_ROLE_IDS = "sku_admin_role_ids"; } \ No newline at end of file diff --git a/app/Http/Enum/DevConfigKeyEnum.php b/app/Http/Enum/DevConfigKeyEnum.php index 390f97c..f4f91d4 100644 --- a/app/Http/Enum/DevConfigKeyEnum.php +++ b/app/Http/Enum/DevConfigKeyEnum.php @@ -14,4 +14,8 @@ class DevConfigKeyEnum const DEFAULT_EXPIRE_DAY = 3; + const SKU_ADMIN_ROLE_IDS = "sku_admin_role_ids"; + + const DEFAULT_SKU_ADMIN_ROLE_IDS = "1,2"; + } \ No newline at end of file diff --git a/app/Imports/LossImport.php b/app/Imports/LossImport.php index df5cfdb..ec52873 100644 --- a/app/Imports/LossImport.php +++ b/app/Imports/LossImport.php @@ -12,6 +12,7 @@ use App\Models\User; use App\Services\DeveloperConfig\DeveloperConfigService; use App\Services\GoodSku\GoodSkuService; use App\Utils\DateTimeUtils; +use App\Utils\GeneratorUtils; use Exception; use Illuminate\Support\Facades\Log; use Maatwebsite\Excel\Concerns\SkipsEmptyRows; @@ -40,13 +41,14 @@ class LossImport implements ToArray, SkipsEmptyRows $updateIds = []; $hasGoodsSkus = GoodsSku::query() ->whereIn('external_sku_id', $externalSkuIds) - ->get(['id', 'status', 'external_sku_id', 'stock', "sale_stock", "cost","is_combination"]) + ->get(['id', 'status', 'external_sku_id', 'stock', "sale_stock", "cost", "is_combination"]) ->toArray(); $hasGoodsSkus = ArrayUtils::index($hasGoodsSkus, 'external_sku_id'); $buyerUserIdKeyByNameMap = User::query()->whereIn("name", $buyerNames)->get() ->pluck("id", "name")->toArray(); $today = DateTimeUtils::getToday(); - //excel字段排序 編碼 商品名稱 报损數量 成本价 采购人名称 报损原因 + $batchNumber = GeneratorUtils::generateBatchNumber("import"); + //excel字段排序 編碼 商品名稱 报损數量 成本价 采购人名称 报损现象 报损原因 报损日期 foreach ($collection as $row) { if (!isset($hasGoodsSkus[$row[0]])) { continue; @@ -55,13 +57,15 @@ class LossImport implements ToArray, SkipsEmptyRows $goodsSkuItem = $hasGoodsSkus[$row[0]]; //保存記錄 $lossRecords = new LossRecords(); + $lossRecords->batch_number = $batchNumber; $lossRecords->external_sku_id = $row[0]; $lossRecords->num = $row[2]; $lossRecords->cost = $row[3]; - $lossRecords->date = $today; $lossRecords->buyer_user_id = $buyerUserIdKeyByNameMap[$row[4]] ?? 0; $lossRecords->buyer_name = $row[4] ?? ''; - $lossRecords->reason = $row[5] ?? ''; + $lossRecords->phenomenon = $row[5] ?? ''; + $lossRecords->reason = $row[6] ?? ''; + $lossRecords->date = DateTimeUtils::validateDate($row[7] ?? '') ? $row[7] : $today; $lossRecords->save(); $updateIds = GoodSkuService::computeSkuStock($goodsSkuItem, ["num" => 0 - $row[2], 'cost' => $row[3]]); diff --git a/app/Imports/PurchaseImport.php b/app/Imports/PurchaseImport.php index 294848d..24b20e4 100644 --- a/app/Imports/PurchaseImport.php +++ b/app/Imports/PurchaseImport.php @@ -12,6 +12,7 @@ use App\Models\User; use App\Services\DeveloperConfig\DeveloperConfigService; use App\Services\GoodSku\GoodSkuService; use App\Utils\DateTimeUtils; +use App\Utils\GeneratorUtils; use Carbon\Carbon; use Exception; use Illuminate\Support\Facades\Log; @@ -43,7 +44,7 @@ class PurchaseImport implements ToArray, SkipsEmptyRows $updateIds = []; $hasGoodsSkus = GoodsSku::query() ->whereIn('external_sku_id', $externalSkuIds) - ->get(['id', 'status', 'external_sku_id', 'stock', "sale_stock", "cost","is_combination"]) + ->get(['id', 'status', 'external_sku_id', 'stock', "sale_stock", "cost", "is_combination"]) ->toArray(); $hasGoodsSkus = ArrayUtils::index($hasGoodsSkus, 'external_sku_id'); //获取供货商 @@ -53,7 +54,8 @@ class PurchaseImport implements ToArray, SkipsEmptyRows ->pluck("id", "name")->toArray(); $expireDay = DeveloperConfigService::getDefaultExpireDay(); $today = DateTimeUtils::getToday(); - //excel字段排序 編碼 商品名稱 导购數量 成本价 采购人名称 供应商名称 保质期 + $batch_number = GeneratorUtils::generateBatchNumber("import"); + //excel字段排序 編碼 商品名稱 导购數量 成本价 采购人名称 供应商名称 采购日期 foreach ($collection as $row) { if (!isset($hasGoodsSkus[$row[0]])) { continue; @@ -63,15 +65,15 @@ class PurchaseImport implements ToArray, SkipsEmptyRows //保存記錄 $purchaseRecords = new PurchaseRecords(); $purchaseRecords->external_sku_id = $row[0]; + $purchaseRecords->batch_number = $batch_number; $purchaseRecords->num = $row[2]; $purchaseRecords->cost = $row[3]; - $purchaseRecords->date = $today; + $purchaseRecords->date = DateTimeUtils::validateDate($row[6] ?? '') ? $row[6] : $today;; $purchaseRecords->buyer_user_id = $buyerUserIdKeyByNameMap[$row[4]] ?? 0; $purchaseRecords->buyer_name = $row[4] ?? ''; $purchaseRecords->supplier_name = $row[5] ?? ''; $purchaseRecords->supplier_id = $supplierIdKeyByNameMap[$row[5]] ?? 0; - $purchaseRecords->expire_time = !empty($row[6]) ? Carbon::parse($row[6])->toDateTimeString() - : Carbon::now()->addDays($expireDay)->toDateTimeString(); + $purchaseRecords->expire_time = Carbon::now()->addDays($expireDay)->toDateTimeString(); $purchaseRecords->save(); $updateIds = GoodSkuService::computeSkuStock($goodsSkuItem, ["num" => $row[2], 'cost' => $row[3]]); diff --git a/app/Listeners/BusinessOrderUpdateListener.php b/app/Listeners/BusinessOrderUpdateListener.php index 5ab8391..1dd2485 100644 --- a/app/Listeners/BusinessOrderUpdateListener.php +++ b/app/Listeners/BusinessOrderUpdateListener.php @@ -42,16 +42,10 @@ class BusinessOrderUpdateListener implements ShouldQueue public function handle(BusinessOrdersUpdate $event) { try { - if(!empty($event->goodsSku)){ //查询库存是否满足告警规则 - $skuId = $event->goodsSku->id; - $nowTime = Carbon::now()->toDateTimeString(); - //查找最后一次盘点数据 - $dailyStockRecord = DailyStockRecord::query()->where("sku_id", '=', $skuId)-> - where("inventory_time", '<', $nowTime)->orderByDesc('id')->first(); - - $inventory = $dailyStockRecord['inventory'] ?? 0; + //查找昨日统计的库存数据 + $inventory = $event->goodsSku['yesterday_num'] ?? 0; $expireTime = Carbon::now()->addMinutes(30)->toDateTimeString(); $proportion = Cache::remember(CacheKeyEnum::STOCK_RULE_PROPORTION, $expireTime, function () { $developerConfig = DeveloperConfig::query()->where("key", "=", DevConfigKeyEnum::STOCK_RULE_PROPORTION)->first(); diff --git a/app/Services/DeveloperConfig/DeveloperConfigService.php b/app/Services/DeveloperConfig/DeveloperConfigService.php index 7c1680d..a924707 100644 --- a/app/Services/DeveloperConfig/DeveloperConfigService.php +++ b/app/Services/DeveloperConfig/DeveloperConfigService.php @@ -21,4 +21,15 @@ class DeveloperConfigService }); } + public static function getSkuAdminRoleIds() + { + $expireTime = Carbon::now()->addHour(); + return Cache::remember(CacheKeyEnum::SKU_ADMIN_ROLE_IDS, $expireTime, function () { + $developerConfig = DeveloperConfig::query()->where("key", + "=", DevConfigKeyEnum::SKU_ADMIN_ROLE_IDS)->first(); + $roleIdsStr = $developerConfig['value'] ?? DevConfigKeyEnum::DEFAULT_SKU_ADMIN_ROLE_IDS; + return explode(",", $roleIdsStr) ?? []; + }); + } + } \ No newline at end of file diff --git a/app/Services/GoodSku/GoodSkuService.php b/app/Services/GoodSku/GoodSkuService.php index 4b22fca..46deaf3 100644 --- a/app/Services/GoodSku/GoodSkuService.php +++ b/app/Services/GoodSku/GoodSkuService.php @@ -8,6 +8,7 @@ use App\Models\CombinationGood; use App\Models\DailyStockRecord; use App\Models\GoodsSku; use App\Utils\DateTimeUtils; +use App\Utils\GeneratorUtils; use Carbon\Carbon; use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\Log; @@ -24,7 +25,8 @@ class GoodSkuService $skusWithCombinationGoods = $this->handleSkusWithCombinationGoods($skusWithCombinationGoods); //传进来的sku可能包含组合商品 所以这里需要事先计算好数据 $inventoryKeyBySkuIdMap = collect($skusWithCombinationGoods)->where('is_combination', "=", 0) - ->pluck("inventory", "id")->toArray(); + ->pluck("real_stock", "id")->filter()->toArray(); + Log::info("库存原始操作map", $inventoryKeyBySkuIdMap); //计算组合商品 foreach ($skusWithCombinationGoods as $sku) { @@ -36,7 +38,7 @@ class GoodSkuService ->where('id', $combinationGoods["item_id"])->pluck('stock')->first() ?? 0; } - $inventoryKeyBySkuIdMap[$combinationGoods["item_id"]] += $combinationGoods['item_num'] * $sku['inventory']; + $inventoryKeyBySkuIdMap[$combinationGoods["item_id"]] += $combinationGoods['item_num'] * $sku['real_stock']; } } } @@ -46,22 +48,34 @@ class GoodSkuService $updateIds = []; Log::info("库存盘点前完整信息", $skusWithCombinationGoods); Log::info("需要操作的库存数据", $inventoryKeyBySkuIdMap); - foreach ($inventoryKeyBySkuIdMap as $skuId => $totalInventory) { - // 更新 - $record = DailyStockRecord::query()->firstOrCreate([ - 'sku_id' => $skuId, - 'day' => $today, - ]); - $record->inventory = $totalInventory; - $record->inventory_time = $dateTime; - $record->save(); + $batchNumber = GeneratorUtils::generateBatchNumber("import"); + DB::beginTransaction(); + try { + foreach ($skusWithCombinationGoods as $sku) { + // 更新 + DailyStockRecord::query()->updateOrCreate([ + 'sku_id' => $sku['id'], + 'day' => $today, + ], [ + "inventory" => $sku['inventory'], + "inventory_time" => $dateTime, + "batch_number" => $batchNumber + ]); - //库存修改 盘点是直接覆盖 - GoodsSku::query()->where('id', $skuId)->update([ - 'stock' => $totalInventory - ]); - $updateIds[] = $skuId; + } + + foreach ($inventoryKeyBySkuIdMap as $skuId => $realStock) { + //库存修改 盘点是直接覆盖 + GoodsSku::query()->where('id', $skuId)->update([ + 'stock' => $realStock + ]); + $updateIds[] = $skuId; + } + } catch (\Exception $exception) { + DB::rollBack(); + $this->info('盘点保存失败' . $exception->getMessage()); } + // 批量更新 event(new BatchStockUpdateEvent($updateIds)); } @@ -72,7 +86,8 @@ class GoodSkuService * @param array $skusWithCombinationGoods * @return \Illuminate\Support\Collection */ - public function handleSkusWithCombinationGoods(array $skusWithCombinationGoods){ + public function handleSkusWithCombinationGoods(array $skusWithCombinationGoods) + { //查询sku当前未发货的数量 需要扣减 $externalSkuIds = collect($skusWithCombinationGoods)->pluck("external_sku_id")->toArray(); //默认只查15天内未发货的数据 @@ -83,11 +98,12 @@ class GoodSkuService ->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); + $unshippedData = collect($unshippedDataCollect)->pluck(null, "external_sku_id")->toArray(); + Log::info("15日内未发货数据", $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'] + $v['real_stock'] = $v['inventory'] ?? null; + if (!empty($unshippedData[$v['external_sku_id']]) && isset($v['inventory'])) { + $v['real_stock'] = $v['inventory'] - $unshippedData[$v['external_sku_id']]['goods_total'] + $unshippedData[$v['external_sku_id']]['cancel_total']; } @@ -106,10 +122,9 @@ class GoodSkuService $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), + 'cost' => $v['cost'], ]; - GoodsSku::query()->where('external_sku_id',"=", $goodsSkuItem['external_sku_id']) + GoodsSku::query()->where('external_sku_id', "=", $goodsSkuItem['external_sku_id']) ->update($updateParam); $updateIds[] = $goodsSkuItem['id']; $updateParams[] = $updateParam; diff --git a/app/Utils/DateTimeUtils.php b/app/Utils/DateTimeUtils.php index e80f314..0de5afa 100644 --- a/app/Utils/DateTimeUtils.php +++ b/app/Utils/DateTimeUtils.php @@ -42,4 +42,10 @@ class DateTimeUtils return (int)ceil($time); } + + + public static function validateDate($date, $format = 'Y-m-d') { + $d = \DateTime::createFromFormat($format, $date); + return $d && $d->format($format) === $date; + } } diff --git a/app/Utils/GeneratorUtils.php b/app/Utils/GeneratorUtils.php new file mode 100644 index 0000000..b258f35 --- /dev/null +++ b/app/Utils/GeneratorUtils.php @@ -0,0 +1,19 @@ +bigIncrements('id'); - $table->string('external_sku_id')->comment('唯一sku标识'); + $table->string('external_sku_id',100)->comment('唯一sku标识'); + $table->string('batch_number')->nullable()->comment('批次号'); $table->date('date')->nullable()->comment('日期');; $table->Integer('num')->default(0)->comment('采购数量'); $table->unsignedDecimal('cost')->default(0)->comment('成本'); $table->Integer('buyer_user_id')->default(0)->comment('购买人用户id');; $table->string('buyer_name')->nullable()->comment('采购人'); - $table->string('check_status')->default(0)->comment('盘点完近似状态 0未完成1已售卖完成'); + $table->Integer('check_status')->default(0)->comment('盘点完近似状态 0未完成1已售卖完成'); $table->string('expire_time')->nullable()->comment('保质期时间'); $table->string('supplier_name')->nullable()->comment('供应商名称'); $table->Integer('supplier_id')->nullable()->comment('供应商id'); // 索引 $table->index('external_sku_id'); - $table->index('check_status'); + $table->index('created_at'); $table->timestamps(); }); } diff --git a/database/migrations/2024_07_24_144925_create_loss_records_table.php b/database/migrations/2024_07_24_144925_create_loss_records_table.php index ec670c6..7f38745 100644 --- a/database/migrations/2024_07_24_144925_create_loss_records_table.php +++ b/database/migrations/2024_07_24_144925_create_loss_records_table.php @@ -15,15 +15,19 @@ class CreateLossRecordsTable extends Migration { Schema::create('loss_records', function (Blueprint $table) { $table->bigIncrements('id'); - $table->string('external_sku_id')->comment('唯一sku标识'); - $table->date('date')->nullable()->comment('日期');; + $table->string('external_sku_id',100)->comment('唯一sku标识'); + $table->string('batch_number')->nullable()->comment('批次号'); + $table->date('date')->nullable()->comment('日期'); $table->Integer('num')->default(0)->comment('报损数量'); $table->unsignedDecimal('cost')->default(0)->comment('成本'); $table->Integer('buyer_user_id')->default(0)->comment('购买人用户id');; $table->string('buyer_name')->nullable()->comment('采购人'); $table->string('reason')->nullable()->comment('报损原因'); + $table->string('phenomenon')->nullable()->comment('报损现象'); + // 索引 $table->index('external_sku_id'); + $table->index('created_at'); $table->timestamps(); }); } diff --git a/database/migrations/2024_07_24_144950_create_website_messages_table.php b/database/migrations/2024_07_24_144950_create_website_messages_table.php index 91afc79..b01f672 100644 --- a/database/migrations/2024_07_24_144950_create_website_messages_table.php +++ b/database/migrations/2024_07_24_144950_create_website_messages_table.php @@ -17,9 +17,9 @@ class CreateWebsiteMessagesTable extends Migration $table->bigIncrements('id'); $table->string('title')->comment('消息内容标题'); $table->string('content')->comment('消息内容'); - $table->string('type')->comment('消息类型'); - $table->string('unique_key')->comment('类型下唯一的key避免重复写入'); - $table->string('role_id')->nullable()->comment('角色名称'); + $table->string('type',60)->comment('消息类型'); + $table->string('unique_key',100)->comment('类型下唯一的key避免重复写入'); + $table->Integer('role_id')->nullable()->comment('角色id'); $table->Integer('uid')->nullable()->comment('用户id 存在非0值表示当前uid可见'); $table->tinyInteger('status')->default(0)->comment('消息状态 0未读 1已读'); $table->string('extend')->nullable()->comment('拓展字段 后续拓展用'); diff --git a/database/migrations/2024_07_24_145032_create_suppliers_table.php b/database/migrations/2024_07_24_145032_create_suppliers_table.php index 1022759..a809924 100644 --- a/database/migrations/2024_07_24_145032_create_suppliers_table.php +++ b/database/migrations/2024_07_24_145032_create_suppliers_table.php @@ -15,7 +15,7 @@ class CreateSuppliersTable extends Migration { Schema::create('suppliers', function (Blueprint $table) { $table->bigIncrements('id'); - $table->string('supplier_name')->comment('供应商名称'); + $table->string('supplier_name',100)->comment('供应商名称'); $table->string('company_name',100)->nullable()->comment('公司名称'); $table->string('address')->nullable()->comment('地址'); $table->string('link_tel',100)->nullable()->comment('联系方式'); diff --git a/database/migrations/2024_08_01_152352_add_order_total_amount_to_daily_stock_record.php b/database/migrations/2024_08_01_152352_add_order_total_amount_to_daily_stock_record.php index 9f1e753..7faee02 100644 --- a/database/migrations/2024_08_01_152352_add_order_total_amount_to_daily_stock_record.php +++ b/database/migrations/2024_08_01_152352_add_order_total_amount_to_daily_stock_record.php @@ -13,11 +13,12 @@ class AddOrderTotalAmountToDailyStockRecord extends Migration */ public function up() { - if (Schema::hasColumn('daily_stock_records', 'order_total_amount')) { + if (Schema::hasColumns('daily_stock_records', ['order_total_amount',"batch_number"])) { return; } Schema::table('daily_stock_records', function (Blueprint $table) { $table->decimal('order_total_amount')->default(0)->comment('订单总金额'); + $table->string('batch_number')->nullable()->comment('批次号'); }); } @@ -28,12 +29,13 @@ class AddOrderTotalAmountToDailyStockRecord extends Migration */ public function down() { - if (Schema::hasColumn('daily_stock_records', 'order_total_amount')) { + if (Schema::hasColumns('daily_stock_records', ['order_total_amount',"batch_number"])) { return; } Schema::table('daily_stock_record', function (Blueprint $table) { // $table->dropColumn('order_total_amount'); + $table->dropColumn('batch_number'); }); } } diff --git a/resources/lang/zh-CN/permission.php b/resources/lang/zh-CN/permission.php index b1235ee..bab20d1 100644 --- a/resources/lang/zh-CN/permission.php +++ b/resources/lang/zh-CN/permission.php @@ -527,28 +527,33 @@ return [ ], 'PURCHASE_RECORD' => [ 'id' => 192, - 'name' => '入库记录', + 'name' => '入库采购', 'parent_id' => 19, 'show' => 1, ], 'purchase_record.index' => [ 'id' => 1921, - 'name' => '入库记录首页', + 'name' => '入库采购首页', 'parent_id' => 192 ], 'purchase_record.update' => [ 'id' => 1922, - 'name' => '入库记录更新', + 'name' => '入库采购更新', 'parent_id' => 192 ], 'purchase_record.store' => [ 'id' => 1923, - 'name' => '入库记录新增', + 'name' => '入库采购新增', 'parent_id' => 192 ], 'purchase_record.purchase_import' => [ 'id' => 1924, - 'name' => '入库记录批量导入', + 'name' => '入库采购批量导入', + 'parent_id' => 192 + ], + 'purchase_record.purchase_batch_store' => [ + 'id' => 1925, + 'name' => '入库采购批量导入', 'parent_id' => 192 ], 'LOSS_RECORD' => [ @@ -559,24 +564,29 @@ return [ ], 'loss_record.index' => [ 'id' => 1931, - 'name' => '报损单首页', + 'name' => '报损记录首页', 'parent_id' => 193 ], 'loss_record.update' => [ 'id' => 1932, - 'name' => '报损单更新', + 'name' => '报损记录更新', 'parent_id' => 193 ], 'loss_record.store' => [ 'id' => 1933, - 'name' => '报损单新增', + 'name' => '报损记录新增', 'parent_id' => 193 ], - 'loss_record.purchase_import' => [ + 'loss_record.loss_import' => [ 'id' => 1934, 'name' => '报损单批量导入', 'parent_id' => 193 ], + 'loss_record.loss_batch_store' => [ + 'id' => 1935, + 'name' => '报损单批量导入', + 'parent_id' => 193 + ], 'DAILY_STOCK_RECORD' => [ 'id' => 194, 'name' => '盘点记录', @@ -591,12 +601,17 @@ return [ 'daily_stock_record.store' => [ 'id' => 1942, 'name' => '盘点记录新增', - 'parent_id' => 193 + 'parent_id' => 194 ], - 'daily_stock_record.purchase_import' => [ + 'daily_stock_record.inventory_import' => [ 'id' => 1943, 'name' => '盘点记录批量导入', - 'parent_id' => 193 + 'parent_id' => 194 + ], + 'daily_stock_record.inventory_batch_store' => [ + 'id' => 1944, + 'name' => '盘点记录批量导入', + 'parent_id' => 194 ], 'sale_statistics' => [ 'id' => 181, diff --git a/routes/api.php b/routes/api.php index 6ca56ae..e13513f 100644 --- a/routes/api.php +++ b/routes/api.php @@ -96,6 +96,10 @@ Route::middleware(['auth:api', 'check.permissions'])->group(function () { //获取树 Route::get('goodsTypes/tree', [GoodsTypesController::class, 'tree'])->name('goods_types.tree'); + Route::post('loss_record/loss_batch_store', [LossRecordController::class, 'lossBatchStore'])->name('loss_record.loss_batch_store'); + Route::post('purchase_record/purchase_batch_store', [PurchaseRecordController::class, 'purchaseBatchStore'])->name('purchase_record.purchase_batch_store'); + Route::post('daily_stock_record/inventory_batch_store', [DailyStockRecordController::class, 'inventoryBatchStore'])->name('daily_stock_record.inventory_batch_store'); + }); Route::get('stock/goods_skus', [GoodsSkusController::class, 'stockNum'])->middleware('auth:api'); Route::get('goods/filter/{title}', [GoodsCombinationController::class, 'goodsSkus'])->middleware('auth:api');