diff --git a/app/Events/BusinessOrdersUpdate.php b/app/Events/BusinessOrdersUpdate.php index 1e78768..c7cff7b 100644 --- a/app/Events/BusinessOrdersUpdate.php +++ b/app/Events/BusinessOrdersUpdate.php @@ -44,24 +44,16 @@ class BusinessOrdersUpdate return false; } $stock = $this->goodsSku->stock + $this->num; - - if (0 >= $stock) { + $saleStock = $this->goodsSku->sale_stock + $this->num; + if (0 >= $saleStock) { $this->goodsSku->status = GoodsSku::$STATUS_DOWN; } else { $this->goodsSku->status = GoodsSku::$STATUS_ON_SALE; } - // 今日到货 + 1T 大于20,且当前剩余库存小于4时 直接下架 - $arrivedTodayNum = DailyStockRecord::query() - ->where('day', DateTimeUtils::getToday()) - ->where('sku_id', $this->goodsSku->id) - ->value('arrived_today_num'); - if (20 < $arrivedTodayNum + $this->goodsSku->yesterday_num && 4 > $stock) { - $this->goodsSku->status = GoodsSku::$STATUS_DOWN; - $stock = 0; - } - + $this->goodsSku->sale_stock = $saleStock; $this->goodsSku->stock = $stock; + Log::info("sku 业务订单库存更新",(array)$this->goodsSku); $this->goodsSku->save(); } diff --git a/app/Http/Controllers/Goods/GoodsSkusController.php b/app/Http/Controllers/Goods/GoodsSkusController.php index 1ad9550..bddff10 100644 --- a/app/Http/Controllers/Goods/GoodsSkusController.php +++ b/app/Http/Controllers/Goods/GoodsSkusController.php @@ -17,6 +17,8 @@ use App\Models\DeveloperConfig; use App\Models\Goods; use App\Models\Log; use App\Models\Log as LogModel; +use App\Services\GoodSku\GoodSkuService; +use App\Services\Ship\WayBillService; use App\Utils\ArrayUtils; use App\Utils\DateTimeUtils; use Carbon\Carbon; @@ -219,7 +221,7 @@ class GoodsSkusController extends Controller public function batchUpdate(Request $request) { $appendRules = [ - 'updateType' => ['required', 'string', Rule::in(['newest', 'inventory', 'stock'])], + 'updateType' => ['required', 'string', Rule::in(['newest', 'inventory', 'stock',"stockManage"])], 'skus' => ['required', 'array'], 'skus.*.id' => [ 'required', @@ -238,6 +240,52 @@ class GoodsSkusController extends Controller return $this->$function($request); } + /** + * 新版本运营管理 主要修改在线库存和成本价(修订) 看看是否需要单独提供修改 + * + * @param $request + * @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\Routing\ResponseFactory|\Illuminate\Http\Response + */ + private function stockManage($request) + { + DB::beginTransaction(); + try { + $logs = []; + foreach ($request->skus as $sku) { + $costLog = [ + 'module' => 'goods', + 'action' => $request->getMethod(), + 'target_type' => 'goods_sku', + 'target_id' => $sku['id'], + '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->sale_stock = $sku['sale_stock']; + $goodsSku->save(); + $costLog['after_update'] = $goodsSku->cost; + $logs[] = $costLog; + } + $log = new LogModel(); + $log->batchInsert($logs); + DB::commit(); + // 批量更新 + event(new BatchStockUpdateEvent(array_column($request->skus, 'id'))); + } catch (\Exception $exception) { + DB::rollBack(); + $this->res = [ + 'httpCode' => 400, + 'errorCode' => 400500, + 'errorMessage' => $exception->getMessage(), + ]; + } + + return response($this->res, $this->res['httpCode']); + } /** * 上新 * @@ -302,78 +350,8 @@ class GoodsSkusController extends Controller */ private function inventory($request) { - DB::beginTransaction(); - 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(), - ]; - } - + $goodSkuService = new GoodSkuService(); + $goodSkuService->inventory($request->skus); return response($this->res, $this->res['httpCode']); } diff --git a/app/Http/Controllers/Goods/WareHouseSkusController.php b/app/Http/Controllers/Goods/WareHouseSkusController.php index 362b980..29a8237 100644 --- a/app/Http/Controllers/Goods/WareHouseSkusController.php +++ b/app/Http/Controllers/Goods/WareHouseSkusController.php @@ -7,16 +7,20 @@ use App\Events\StockUpdateEvent; use App\Exports\GoodsSkusExport; use App\Exports\WeekDataExport; use App\Http\Controllers\Controller; +use App\Http\Enum\ExcelKeyEnum; use App\Http\Requests\GoodsRequest; use App\Http\Requests\GoodsSkuRequest; use App\Imports\InventoryImport; +use App\Imports\LossImport; use App\Imports\NewSetImport; +use App\Imports\PurchaseImport; use App\Models\BusinessOrderItem; use App\Models\DailySalesReport; use App\Models\DeveloperConfig; use App\Models\Goods; use App\Models\Log; use App\Models\Log as LogModel; +use App\Models\LossRecords; use App\Models\PurchaseRecords; use App\Utils\ArrayUtils; use App\Utils\DateTimeUtils; @@ -131,15 +135,18 @@ class WareHouseSkusController extends Controller return GoodsSkuResource::collection($goodsSkus); } - public function PurchaseBatchStore(Request $request) + /** + * 采购单后台批量存储 + * @param Request $request + * @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\Routing\ResponseFactory|\Illuminate\Http\Response|void + */ + public function purchaseBatchStore(Request $request) { $validator = Validator::make($request->all(), [ 'purchaseOrders' => 'required|array', - 'purchaseOrders.*.sku_id' => 'required|integer', 'purchaseOrders.*.external_sku_id' => 'required|string', - 'purchaseOrders.*.num' => 'required|integer', - 'purchaseOrders.*.cost' => 'required|string', - ]); + 'purchaseOrders.*.num' => 'required|integer']); + //参数校验 if ($validator->fails()) { $this->setValidatorFailResponse($validator->getMessageBag()->getMessages()); return response($this->res, $this->res['httpCode']); @@ -152,8 +159,9 @@ class WareHouseSkusController extends Controller $content .= "以上sku编码数据库中不存在"; return response($content, $this->res['httpCode']); } - $goodsSkuMap = $goodsSku->pluck('external_sku_id',null)->toArray(); - //执行库存操作 + $goodsSkuMap = $goodsSku->pluck(null, 'external_sku_id')->toArray(); + $updateIds = []; + //开始保存数据 foreach ($purchaseOrders as $v) { $goodsSkuItem = $goodsSkuMap[$v['external_sku_id']]; //保存記錄 @@ -169,102 +177,122 @@ class WareHouseSkusController extends Controller //更新库存 GoodsSku::query()->where('external_sku_id', $v['external_sku_id'])->update([ - 'stock' => $goodsSkuItem['stock']+$v['num'], - 'sale_stock' => $goodsSkuItem['sale_stock']+$v['num'], - 'cost' => $v['cost'], + '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), 'status' => 1, ]); - event(new StockUpdateEvent($goodsSkuItem)); + $updateIds[] = $goodsSkuItem['id']; + } + //如果是組合商品後續會處理组合商品库存的拆分 + event(new BatchStockUpdateEvent($updateIds)); + return response($this->res, $this->res['httpCode']); } - public function updateField($id, Request $request) + /** + * 报损单后台批量存储 + * @param Request $request + * @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\Routing\ResponseFactory|\Illuminate\Http\Response|void + */ + public function purchaseImport(Request $request) { - $rules = [ - 'updateField' => [ - 'required', - Rule::in(['reference_price', 'reserve', 'loss_num', 'status', 'goal_rate']) - ], - 'reference_price' => [ - 'sometimes', - 'numeric', - 'gt:0' - ], - 'reserve' => [ - 'sometimes', - 'integer', - ], - 'loss_num' => [ - 'sometimes', - 'integer', - ], - 'reason' => [ - 'sometimes', - 'required', - 'string' - ], - 'status' => [ - 'sometimes', - 'required', - 'integer', - Rule::in([0, 1, 2]) - ], - 'goal_rate' => [ - 'sometimes', - 'numeric', - ], - ]; - $validator = Validator::make($request->all(), $rules); - if ($validator->fails()) { - $this->setValidatorFailResponse($validator->getMessageBag()->getMessages()); - goto end; + if (!$request->hasFile(ExcelKeyEnum::PURCHASE_KEY)) { + $this->res = [ + 'httpCode' => 404, + 'errorCode' => 404404, + 'errorMessage' => 'not found purchase file', + ]; } - $updateField = \request('updateField'); - $sku = GoodsSku::query()->find($id); - if ('loss_num' === $updateField) { - $record = DailyStockRecord::query() - ->where('sku_id', $id) - ->where('day', DateTimeUtils::getToday()) - ->first(['id', 'loss_num']); - $this->log->message = $request->get('reason'); - $this->setBeforeUpdateForLog($record->loss_num); - $record->loss_num += $request->loss_num; - $record->save(); - $this->setAfterUpdateForLog($record->loss_num); - $sku->stock -= $request->loss_num; - $sku->save(); - } else { - $this->setBeforeUpdateForLog($sku->$updateField); - if ('reserve' === $updateField) { - $changeNum = $sku->reserve - $request->reserve; - if (0 > $changeNum + $sku->stock) { - $this->setValidatorFailResponse('预留量超过库存数量'); - goto end; - } - $sku->stock += $changeNum; - } - - $sku->$updateField = $request->$updateField; - $sku->save(); - $this->setAfterUpdateForLog($sku->$updateField); + try { + $import = new PurchaseImport(); + $path = $request->file(ExcelKeyEnum::PURCHASE_KEY); + Excel::import($import, $path); + $this->addLog(0, 'import', ExcelKeyEnum::PURCHASE_KEY); + } catch (ValidationException $exception) { + $this->setValidatorFailResponse($exception->validator->getMessageBag()->getMessages()); } - if (in_array($updateField, ['reserve', 'loss_num'])) { - event(new StockUpdateEvent($sku)); - } - // 更新目标去化率 - if ('goal_rate' === $updateField) { - DailySalesReport::query() - ->where('date', date('Y-m-d')) - ->where('goods_sku_id', $sku->id) - ->update([ - 'goal_rate' => $request->$updateField - ]); - } - - $this->addLog($id, $updateField); - end: return response($this->res, $this->res['httpCode']); } + + public function lossBatchStore(Request $request){ + $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',//采购商 + ]); + //参数校验 + if ($validator->fails()) { + $this->setValidatorFailResponse($validator->getMessageBag()->getMessages()); + return response($this->res, $this->res['httpCode']); + } + $lossOrders = $request->input('lossOrders') ?? []; + $externalSkuIds = collect($lossOrders)->pluck("external_sku_id")->toArray(); + $goodsSku = GoodsSku::query()->whereIn('external_sku_id', $externalSkuIds)->get(); + if ($goodsSku->pluck("external_sku_id")->diff($externalSkuIds)->isNotEmpty()) { + $content = implode(',', $goodsSku->pluck("external_sku_id")->diff($externalSkuIds)->toArray()); + $content .= "以上sku编码数据库中不存在"; + return response($content, $this->res['httpCode']); + } + $goodsSkuMap = $goodsSku->pluck(null,'external_sku_id')->toArray(); + $updateIds = []; + //开始保存数据 + foreach ($lossOrders as $v) { + $goodsSkuItem = $goodsSkuMap[$v['external_sku_id']]; + //保存記錄 + $lossRecords = new LossRecords(); + $lossRecords->sku_id = $goodsSkuItem['id'] ?? 0; + $lossRecords->external_sku_id = $v['external_sku_id']; + $lossRecords->num = $v['num']; + $lossRecords->cost = $v['cost']; + $lossRecords->buyer_name = $v['buyer_name'] ?? ''; + $lossRecords->reason = $v['reason'] ?? ''; + $lossRecords->save(); + + //更新库存 + GoodsSku::query()->where('external_sku_id', $v['external_sku_id'])->update([ + '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), + ]); + $updateIds[] = $goodsSkuItem['id']; + + } + //如果是組合商品後續會處理组合商品库存的拆分 + event(new BatchStockUpdateEvent($updateIds)); + return response($this->res, $this->res['httpCode']); + } + /** + * 报损单单后台批量导入 + * @param Request $request + * @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\Routing\ResponseFactory|\Illuminate\Http\Response|void + */ + public function lossImport(Request $request) + { + if (!$request->hasFile(ExcelKeyEnum::LOSS_KEY)) { + $this->res = [ + 'httpCode' => 404, + 'errorCode' => 404404, + 'errorMessage' => 'not found loss file', + ]; + } + try { + $import = new LossImport(); + $path = $request->file(ExcelKeyEnum::LOSS_KEY); + Excel::import($import, $path); + $this->addLog(0, 'import', ExcelKeyEnum::LOSS_KEY); + } catch (ValidationException $exception) { + $this->setValidatorFailResponse($exception->validator->getMessageBag()->getMessages()); + } + + return response($this->res, $this->res['httpCode']); + } + + } diff --git a/app/Http/Enum/ExcelKeyEnum.php b/app/Http/Enum/ExcelKeyEnum.php new file mode 100644 index 0000000..d6d1eeb --- /dev/null +++ b/app/Http/Enum/ExcelKeyEnum.php @@ -0,0 +1,12 @@ +whereIn('external_sku_id', $externalSkuId) - ->get(['id', 'status', 'external_sku_id']) - ->toArray(); - $hasGoodsSkus = ArrayUtils::index($hasGoodsSkus, 'external_sku_id'); - foreach ($collection as $row) { - if (!isset($hasGoodsSkus[$row[0]])) { - continue; - } - $goodsSku = $hasGoodsSkus[$row[0]]; - if ('下架' === $goodsSku['status']) { - GoodsSku::query()->where('id', $goodsSku['id'])->update([ - 'stock' => $row[2] + $row[3], - 'cost' => $row[4], - 'status' => 1, - ]); - } else { - GoodsSku::query()->where('id', $goodsSku['id'])->update([ - 'stock' => $row[2] + $row[3], - 'cost' => $row[4], - ]); - } - SyncCostToMiaoXuan::dispatch($row[0], $row[4]); - $updateIds[] = $goodsSku['id']; - DailyStockRecord::query()->where('sku_id', $goodsSku['id'])->where('day', $day)->update([ - 'arrived_today_num' => $row[3], - 'inventory' => $row[2], - 'inventory_time' => $dateTime - ]); - $shopPrice = []; - foreach ($row as $i => $v) { - if ($i > 4) { - $shopPrice[$header[$i]] = $v; - } - } - $todayPrice[] = [ - 'day' => $day, - 'external_sku_id' => $goodsSku['external_sku_id'], - 'shop_price' => json_encode($shopPrice, 256) + $requestSkus[] = [ + "external_sku_id" => $row[0], + "inventory" => $row[2], ]; } - if ($todayPrice) { - TodayPrice::query()->delete(); - $model = new TodayPrice(); - $model->batchInsert($todayPrice); - } - sleep(2); - $onSkuIds = GoodsSku::query() - ->where('is_combination', 0) - ->where('status', '>', 0) - ->pluck('id') - ->toArray(); - $downSkuIds = array_diff($onSkuIds, $updateIds); - if ($downSkuIds) { - $goodsSkus = GoodsSku::query()->whereIn('id', $downSkuIds) - ->get(['id', 'yesterday_num', 'stock']) - ->toArray(); - foreach ($goodsSkus as $goodsSku) { - GoodsSku::query()->where('id', $goodsSku['id'])->update([ - 'yesterday_num' => $goodsSku['yesterday_num'] - $goodsSku['stock'], - 'stock' => 0, - ]); - } - } - sleep(2); - // 批量更新 - event(new BatchStockUpdateEvent($onSkuIds)); + unset($row); + //新版盘点excel字段 编码 商品名称 盘点数 + $goodSkuService = new GoodSkuService(); + $goodSkuService->inventory($requestSkus); } } diff --git a/app/Imports/LossImport.php b/app/Imports/LossImport.php new file mode 100644 index 0000000..005b186 --- /dev/null +++ b/app/Imports/LossImport.php @@ -0,0 +1,71 @@ +whereIn('external_sku_id', $externalSkuIds) + ->get(['id', 'status', 'external_sku_id', 'stock']) + ->toArray(); + $hasGoodsSkus = ArrayUtils::index($hasGoodsSkus, 'external_sku_id'); + //excel字段排序 編碼 商品名稱 报损數量 成本价 采购人名称 报损原因 + foreach ($collection as $row) { + if (!isset($hasGoodsSkus[$row[0]])) { + continue; + } + //执行库存操作 + $goodsSkuItem = $hasGoodsSkus[$row[0]]; + //保存記錄 + $lossRecords = new LossRecords(); + $lossRecords->sku_id = $goodsSkuItem['id'] ?? 0; + $lossRecords->external_sku_id = $row[0]; + $lossRecords->num = $row[2]; + $lossRecords->cost = $row[3]; + $lossRecords->buyer_name = $row[4] ?? ''; + $lossRecords->reason = $row[5] ?? ''; + $lossRecords->save(); + + //更新库存 + GoodsSku::query()->where('external_sku_id', $row[0])->update([ + 'stock' => $goodsSkuItem['stock'] - $row[2], + 'sale_stock' => $goodsSkuItem['sale_stock'] - $row[2], + 'cost' => number_format(($goodsSkuItem['stock'] * $goodsSkuItem['cost'] - $row[3] * $row[2]) + / ($goodsSkuItem['stock'] - $row[2]), 2), + 'status' => 1, + ]); + $updateIds[] = $hasGoodsSkus['id']; + } + Log::info("报损导入内容:", $collection); + // 批量更新 + event(new BatchStockUpdateEvent($updateIds)); + } +} diff --git a/app/Imports/PurchaseImport.php b/app/Imports/PurchaseImport.php new file mode 100644 index 0000000..9c56f69 --- /dev/null +++ b/app/Imports/PurchaseImport.php @@ -0,0 +1,70 @@ +whereIn('external_sku_id', $externalSkuIds) + ->get(['id', 'status', 'external_sku_id', 'stock']) + ->toArray(); + $hasGoodsSkus = ArrayUtils::index($hasGoodsSkus, 'external_sku_id'); + //excel字段排序 編碼 商品名稱 导购數量 成本价 采购人名称 供应商名称 + foreach ($collection as $row) { + if (!isset($hasGoodsSkus[$row[0]])) { + continue; + } + //执行库存操作 + $goodsSkuItem = $hasGoodsSkus[$row[0]]; + //保存記錄 + $purchaseRecords = new PurchaseRecords(); + $purchaseRecords->sku_id = $goodsSkuItem['id'] ?? 0; + $purchaseRecords->external_sku_id = $row[0]; + $purchaseRecords->num = $row[2]; + $purchaseRecords->cost = $row[3]; + $purchaseRecords->buyer_name = $row[4] ?? ''; + $purchaseRecords->supplier_name = $row[5] ?? ''; + $purchaseRecords->save(); + + //更新库存 + GoodsSku::query()->where('external_sku_id', $row[0])->update([ + 'stock' => $goodsSkuItem['stock'] + $row[2], + 'sale_stock' => $goodsSkuItem['sale_stock'] + $row[2], + 'cost' => number_format(($goodsSkuItem['stock']*$goodsSkuItem['cost']+$row[3]*$row[2]) + /($goodsSkuItem['stock'] + $row[2]),2), + 'status' => 1, + ]); + $updateIds[] = $hasGoodsSkus['id']; + } + Log::info("采购导入内容:",$collection); + // 批量更新 + event(new BatchStockUpdateEvent($updateIds)); + } +} diff --git a/app/Listeners/CombinationGoodsStockUpdateListener.php b/app/Listeners/CombinationGoodsStockUpdateListener.php index 5443008..3ecdae9 100644 --- a/app/Listeners/CombinationGoodsStockUpdateListener.php +++ b/app/Listeners/CombinationGoodsStockUpdateListener.php @@ -9,6 +9,7 @@ use App\Utils\DateTimeUtils; use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Queue\InteractsWithQueue; use App\Events\BatchStockUpdateEvent; +use Illuminate\Support\Facades\Log; class CombinationGoodsStockUpdateListener implements ShouldQueue { @@ -62,9 +63,12 @@ class CombinationGoodsStockUpdateListener implements ShouldQueue foreach ($combinationGoods as $item) { $goodsSku = GoodsSku::query()->find($item['item_id']); $stock = $goodsSku->stock - $item['item_num']; - [$status, $stock] = $this->checkStatusAndStock($goodsSku, $stock); + //新增逻辑 在线库存同步扣减 + $saleStock = $goodsSku->sale_stock - $item['item_num']; + [$status, $stock] = $this->checkStatusAndStock($goodsSku, $stock, $saleStock); $goodsSku->status = $status; $goodsSku->stock = $stock; + $goodsSku->sale_stock = $saleStock; $goodsSku->save(); $updateIds[] = $goodsSku->id; } @@ -76,18 +80,24 @@ class CombinationGoodsStockUpdateListener implements ShouldQueue ->pluck('goods_sku_id'); foreach ($goodsSkuIds as $goodsSkuId) { $combinationGoods = CombinationGood::query() - ->with('goodsSkuItem:id,stock') + ->with('goodsSkuItem:id,stock,sale_stock') ->where('goods_sku_id', $goodsSkuId) ->get(); $stock = []; + $saleStock = []; foreach ($combinationGoods as $goods) { $stock[] = (int)($goods['goodsSkuItem']['stock'] / $goods['item_num']); + $saleStock[] = (int)($goods['goodsSkuItem']['sale_stock'] / $goods['item_num']); } + //库存和在线可售库存都是通过子商品维护的 $stock = min($stock); + $saleStock = min($saleStock); $goodsSku = GoodsSku::query()->find($goodsSkuId); - [$status, $stock] = $this->checkStatusAndStock($goodsSku, $stock); + //新增在线可售逻辑判断 前置已经完成逻辑扣减或者增加 + [$status, $stock] = $this->checkStatusAndStock($goodsSku, $stock, $saleStock); $goodsSku->status = $status; $goodsSku->stock = $stock; + $goodsSku->sale_stock = $saleStock; $goodsSku->save(); $updateIds[] = $goodsSkuId; } @@ -99,21 +109,14 @@ class CombinationGoodsStockUpdateListener implements ShouldQueue } } - private function checkStatusAndStock($goodsSku, $stock) + private function checkStatusAndStock($goodsSku, $stock, $saleStock) { - if (0 >= $stock) { + //下线库存判断以在线可售库存为准 + if (0 >= $saleStock) { $status = GoodsSku::$STATUS_DOWN; } else { $status = GoodsSku::$STATUS_ON_SALE; } - $arrivedTodayNum = DailyStockRecord::query() - ->where('day', DateTimeUtils::getToday()) - ->where('sku_id', $goodsSku->id) - ->value('arrived_today_num'); - if (20 < $arrivedTodayNum + $goodsSku->yesterday_num && 4 > $stock) { - $status = GoodsSku::$STATUS_DOWN; - $stock = 0; - } return [$status, $stock]; } diff --git a/app/Listeners/UpdateBusinessGoodsStock.php b/app/Listeners/UpdateBusinessGoodsStock.php index 5f616dc..490a767 100644 --- a/app/Listeners/UpdateBusinessGoodsStock.php +++ b/app/Listeners/UpdateBusinessGoodsStock.php @@ -60,7 +60,7 @@ class UpdateBusinessGoodsStock implements ShouldQueue } foreach ($shops as $shop) { - $num = $event->goodsSku->stock; + $num = $event->goodsSku->sale_stock;//同步三方和秒选虚拟库存 $businessGoodsSkus = BusinessGoodsSku::query() ->where('shop_id', $shop->id) ->where('is_sync', 1) diff --git a/app/Services/GoodSku/GoodSkuService.php b/app/Services/GoodSku/GoodSkuService.php new file mode 100644 index 0000000..53bd27b --- /dev/null +++ b/app/Services/GoodSku/GoodSkuService.php @@ -0,0 +1,57 @@ +pluck(null, 'external_sku_id')->toArray(); + $externalSkuIds = collect($requestSkus)->pluck('external_sku_id')->toArray(); + $skus = GoodsSku::query() + ->whereIn('external_sku_id', $externalSkuIds) + ->get(['id', 'external_sku_id']) + ->toArray(); + $today = DateTimeUtils::getToday(); + $dateTime = date('Y-m-d H:i:s'); + $updateIds = []; + foreach ($skus as $sku) { + if (!in_array($sku['external_sku_id'], $externalSkuIds)) { + continue; + } + // 更新 + $record = DailyStockRecord::query()->where('sku_id', $sku['id'])->where('day', $today)->firstOrCreate([ + 'sku_id' => $sku['id'], + 'day' => $today, + ]); + $record->inventory = $requestSkusMap[$sku['external_sku_id']]['inventory']; + $record->inventory_time = $dateTime; + $record->save(); + //查询sku当前未发货的数量 目前数据看着有问题暂不操作 + + //库存修改 + GoodsSku::query()->where('id', $sku['id'])->lockForUpdate()->update([ + 'stock' => $requestSkusMap[$sku['external_sku_id']]['inventory'] + ]); + $updateIds[] = $sku['id']; + } + // 批量更新 + event(new BatchStockUpdateEvent($updateIds)); + + } + +} diff --git a/database/migrations/2024_07_24_144851_create_purchase_records_table.php b/database/migrations/2024_07_24_144851_create_purchase_records_table.php index 830e139..33a7ed2 100644 --- a/database/migrations/2024_07_24_144851_create_purchase_records_table.php +++ b/database/migrations/2024_07_24_144851_create_purchase_records_table.php @@ -22,7 +22,7 @@ class CreatePurchaseRecordsTable extends Migration $table->string('buyer_name')->nullable()->comment('采购人'); $table->string('status')->default(0)->comment('盘点完近似状态 0未完成1已售卖完成'); $table->string('supplier_name')->nullable()->comment('供应商名称'); - $table->unsignedDecimal('supplier_id')->nullable()->comment('供应商id'); + $table->Integer('supplier_id')->nullable()->comment('供应商id'); // 索引 $table->index('sku_id'); $table->index('external_sku_id'); diff --git a/resources/lang/zh-CN/permission.php b/resources/lang/zh-CN/permission.php index 6f1b3cf..d906125 100644 --- a/resources/lang/zh-CN/permission.php +++ b/resources/lang/zh-CN/permission.php @@ -522,7 +522,38 @@ return [ ], 'website_message.update' => [ 'id' => 1912, - 'name' => '站內信', + 'name' => '更新', 'parent_id' => 191 ], + 'WARE_HOUSE' => [ + 'id' => 192, + 'name' => '仓库管理', + 'parent_id' => 19, + 'show' => 1, + ], + 'goods.ware_house.index' => [ + 'id' => 1921, + 'name' => '仓库管理首页', + 'parent_id' => 192 + ], + 'goods.ware_house.purchase_batch_store' => [ + 'id' => 1922, + 'name' => '导购单批量保存', + 'parent_id' => 192 + ], + 'goods.ware_house.loss_batch_store' => [ + 'id' => 1923, + 'name' => '报损单批量保存', + 'parent_id' => 192 + ], + 'goods.ware_house.purchase_import' => [ + 'id' => 1924, + 'name' => '导购单批量导入', + 'parent_id' => 192 + ], + 'goods.ware_house.loss_import' => [ + 'id' => 1925, + 'name' => '报损单批量导入', + 'parent_id' => 192 + ], ]; diff --git a/routes/api.php b/routes/api.php index e6ec167..3d7a0b5 100644 --- a/routes/api.php +++ b/routes/api.php @@ -12,6 +12,7 @@ use App\Http\Controllers\Group\GroupsController; use App\Http\Controllers\Business\BusinessOrderController; use App\Http\Controllers\Goods\GoodsSkuLocationController; use App\Http\Controllers\Goods\GoodsCombinationController; +use App\Http\Controllers\Goods\WareHouseSkusController; /* |-------------------------------------------------------------------------- @@ -72,9 +73,15 @@ Route::middleware(['auth:api', 'check.permissions'])->group(function () { Route::post('shop/ship/senders', [ShipController::class, 'saveSenders'])->name('shop_ship.senders.save'); // 数据中心 Route::get('data_center/sales_report', [DataCenterController::class, 'salesReport'])->name('sales_report.index'); - + //供应商 Route::resource('supplier', 'Supplier\SuppliersController', ['only' => ['index', 'update', 'store','destroy']]); + //站内信 Route::resource('website_message', 'Message\WebsiteMessageController', ['only' => ['index', 'update']]); + //仓库管理 采购和报损 + Route::get('goods/ware_house/index', [WareHouseSkusController::class, 'index'])->name('goods.ware_house.index'); + Route::post('goods/ware_house/purchase_batch_store', [WareHouseSkusController::class, 'purchaseBatchStore'])->name('goods.ware_house.purchase_batch_store'); + Route::post('goods/ware_house/loss_batch_store', [WareHouseSkusController::class, 'lossBatchStore'])->name('goods.ware_house.loss_batch_store'); + }); Route::get('stock/goods_skus', [GoodsSkusController::class, 'stockNum'])->middleware('auth:api'); Route::get('goods/filter/{title}', [GoodsCombinationController::class, 'goodsSkus'])->middleware('auth:api'); @@ -112,3 +119,9 @@ Route::post('today/price', [BusinessGoodsSkusController::class, 'todayPriceImpor Route::post('upload', [UploadController::class, 'store'])->name('upload.file'); // 商品列表 Route::get('goodsSkusList', [GoodsSkusController::class, 'goodsSkusList'])->name('goods_sku.list_for_goods_sku'); + +// 采购导入 +Route::post('goods/ware_house/purchase_import', [WareHouseSkusController::class, 'purchaseImport'])->name('goods.ware_house.purchase_import'); + +// 上新导入 +Route::post('goods/ware_house/loss_import', [WareHouseSkusController::class, 'lossImport'])->name('goods.ware_house.loss_import');