diff --git a/app/Console/Commands/InitSaleStock.php b/app/Console/Commands/InitSaleStock.php new file mode 100644 index 0000000..0394dec --- /dev/null +++ b/app/Console/Commands/InitSaleStock.php @@ -0,0 +1,54 @@ +argument('ids'); + if(!empty($ids)){ + $ids = explode(',',$ids); + } + GoodsSku::query()->where("stock",'>',0)->when($ids,function($query)use($ids){ + $query->whereIn('id',$ids); + })->update(['sale_stock' => DB::raw('stock')]); + + } +} \ No newline at end of file diff --git a/app/Console/Commands/KttOrderAfterSaleQuery.php b/app/Console/Commands/KttOrderAfterSaleQuery.php index 654429c..d6a40d9 100644 --- a/app/Console/Commands/KttOrderAfterSaleQuery.php +++ b/app/Console/Commands/KttOrderAfterSaleQuery.php @@ -49,6 +49,5 @@ class KttOrderAfterSaleQuery extends Command BusinessFactory::init()->make($shop->plat_id)->setShop($shop)->downloadAfterSaleOrdersAndSave($beginTime, $endTime); } - Log::info('任务完成:快团团根据更新时间获取增量售后单'); } } diff --git a/app/Events/BusinessOrdersUpdate.php b/app/Events/BusinessOrdersUpdate.php index 69572a2..7413c2d 100644 --- a/app/Events/BusinessOrdersUpdate.php +++ b/app/Events/BusinessOrdersUpdate.php @@ -42,6 +42,7 @@ class BusinessOrdersUpdate $updateResult = true; break; } + usleep(140); } if (!$updateResult) { Log::error("sku 业务更新失败", (array)$this->businessGoodSku); @@ -63,6 +64,7 @@ class BusinessOrdersUpdate $oldStock = $this->goodsSku->stock; $stock = $this->goodsSku->stock + $this->num; $saleStock = $this->goodsSku->sale_stock + $this->num; + $saleStock = ($saleStock > 0) ? $saleStock : 0; $updateParam = ["stock" => $stock, "sale_stock" => $saleStock]; if (0 >= $saleStock) { $updateParam['status'] = GoodsSku::$STATUS_DOWN; diff --git a/app/Http/Controllers/Goods/GoodsSkusController.php b/app/Http/Controllers/Goods/GoodsSkusController.php index e37c846..a8b96ca 100644 --- a/app/Http/Controllers/Goods/GoodsSkusController.php +++ b/app/Http/Controllers/Goods/GoodsSkusController.php @@ -259,6 +259,9 @@ class GoodsSkusController extends Controller try { $logs = []; foreach ($request->skus as $sku) { + if ($sku['sale_stock'] < 0) { + throw new \Exception("商品id{$sku['id']}在售库存数不能小于0"); + } $costLog = [ 'module' => 'goods', 'action' => $request->getMethod(), diff --git a/app/Http/Controllers/Goods/GoodsTypesController.php b/app/Http/Controllers/Goods/GoodsTypesController.php index fc51b71..10f993c 100644 --- a/app/Http/Controllers/Goods/GoodsTypesController.php +++ b/app/Http/Controllers/Goods/GoodsTypesController.php @@ -49,6 +49,11 @@ class GoodsTypesController extends Controller if ($request->parent_id) { $parentGoodsType = GoodsType::query()->where("id", "=", $request->parent_id)->get()->toArray(); $level = $parentGoodsType['level'] ?? 1 + 1; + $existTypeName = GoodsType::query()->where("parent_id", "=", $request->parent_id) + ->where("name",$request->name)->first(); + if($existTypeName){ + throw new \Exception("当前品类下该名称已存在"); + } } $goodsType = new GoodsType(); diff --git a/app/Http/Controllers/Supplier/LossRecordController.php b/app/Http/Controllers/Supplier/LossRecordController.php index 2aebe5e..dee5c4a 100644 --- a/app/Http/Controllers/Supplier/LossRecordController.php +++ b/app/Http/Controllers/Supplier/LossRecordController.php @@ -7,6 +7,7 @@ use App\Http\Controllers\Controller; use App\Http\Enum\ExcelKeyEnum; use App\Imports\LossImport; use App\Models\DailyStockRecord; +use App\Models\Goods; use App\Models\GoodsSku; use App\Models\Log; use App\Models\Log as LogModel; @@ -16,6 +17,7 @@ use App\Models\User; use App\Services\GoodSku\GoodSkuService; use App\Utils\DateTimeUtils; use App\Utils\GeneratorUtils; +use Illuminate\Database\Eloquent\Model; use Illuminate\Http\Request; use Illuminate\Http\Resources\Json\JsonResource; use Illuminate\Support\Facades\DB; @@ -70,21 +72,28 @@ class LossRecordController extends Controller $buyerUserId = User::query()->where("name", $allParams['buyer_name'] ?? '') ->pluck("id")->first(); $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']; - $lossRecords->date = $allParams['date'] ?? $today; - $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'],"user_id"=>$request->user()->id]); - event(new BatchStockUpdateEvent($updateIds)); + DB::beginTransaction(); + try { + //保存記錄 + $lossRecords = new LossRecords(); + $lossRecords->batch_number = GeneratorUtils::generateBatchNumber(); + $lossRecords->external_sku_id = $allParams['external_sku_id']; + $lossRecords->num = $allParams['num']; + $lossRecords->cost = $allParams['cost']; + $lossRecords->date = $allParams['date'] ?? $today; + $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'], "user_id" => $request->user()->id]); + DB::commit(); + event(new BatchStockUpdateEvent($updateIds)); + } catch (\Exception $exception) { + DB::rollBack(); + } + } else { $this->res = [ 'httpCode' => 400, @@ -163,23 +172,29 @@ class LossRecordController extends Controller $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(); + DB::beginTransaction(); + try { + $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'],"user_id"=>$request->user()->id]); - $allUpdateIds = array_merge($allUpdateIds, $updateIds); + $updateIds = GoodSkuService::computeSkuStock($goodsSkuItem + , ['num' => 0 - $v['num'], "cost" => $v['cost'], "user_id" => $request->user()->id]); + DB::commit(); + $allUpdateIds = array_merge($allUpdateIds, $updateIds); + } catch (\Exception $exception) { + DB::rollBack(); + } } event(new BatchStockUpdateEvent(collect($allUpdateIds)->unique()->toArray())); diff --git a/app/Imports/LossImport.php b/app/Imports/LossImport.php index 02d89c6..d9e6ae5 100644 --- a/app/Imports/LossImport.php +++ b/app/Imports/LossImport.php @@ -14,6 +14,7 @@ use App\Services\GoodSku\GoodSkuService; use App\Utils\DateTimeUtils; use App\Utils\GeneratorUtils; use Exception; +use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\Log; use Maatwebsite\Excel\Concerns\SkipsEmptyRows; use Maatwebsite\Excel\Concerns\ToArray; @@ -53,26 +54,32 @@ class LossImport implements ToArray, SkipsEmptyRows if (!isset($hasGoodsSkus[$row[0]])) { continue; } - //执行库存操作 - $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->buyer_user_id = $buyerUserIdKeyByNameMap[$row[4]] ?? 0; - $lossRecords->buyer_name = $row[4] ?? ''; - $lossRecords->phenomenon = $row[5] ?? ''; - $lossRecords->reason = $row[6] ?? ''; - $lossRecords->date = $today; - if(!empty($row[7])){ - $lossRecords->date = DateTimeUtils::excelUploadDateToString($row[7],$today); - } - $lossRecords->save(); + DB::beginTransaction(); + try { + //执行库存操作 + $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->buyer_user_id = $buyerUserIdKeyByNameMap[$row[4]] ?? 0; + $lossRecords->buyer_name = $row[4] ?? ''; + $lossRecords->phenomenon = $row[5] ?? ''; + $lossRecords->reason = $row[6] ?? ''; + $lossRecords->date = $today; + if (!empty($row[7])) { + $lossRecords->date = DateTimeUtils::excelUploadDateToString($row[7], $today); + } + $lossRecords->save(); - $updateIds = GoodSkuService::computeSkuStock($goodsSkuItem, ["num" => 0 - $row[2], 'cost' => $row[3]]); - $allUpdateIds = array_merge($allUpdateIds, $updateIds); + $updateIds = GoodSkuService::computeSkuStock($goodsSkuItem, ["num" => 0 - $row[2], 'cost' => $row[3]]); + DB::commit(); + $allUpdateIds = array_merge($allUpdateIds, $updateIds); + } catch (\Exception $exception) { + DB::rollBack(); + } } Log::info("报损导入内容:", $collection); // 批量更新 diff --git a/app/Imports/SaleStockImport.php b/app/Imports/SaleStockImport.php index 0c3fe75..30391ed 100644 --- a/app/Imports/SaleStockImport.php +++ b/app/Imports/SaleStockImport.php @@ -20,7 +20,6 @@ class SaleStockImport implements ToArray, SkipsEmptyRows */ public function array(array $collection) { - Log::info("collection",[$collection]); if (!empty($collection)) { unset($collection[0]); $externalSkuIds = []; @@ -29,6 +28,9 @@ class SaleStockImport implements ToArray, SkipsEmptyRows $row = array_map(static function ($v) { return trim($v); }, $row); + if ($row[2] < 0) { + throw new Exception("商品编码{$row[0]}在售库存数不能小于0"); + } $inventoryKeyByExternalSkuIdMap[$row[0]] = $row[2]; $externalSkuIds[] = $row[0]; } @@ -41,7 +43,7 @@ class SaleStockImport implements ToArray, SkipsEmptyRows foreach ($externalSkuIds as $externalSkuId) { // 成本 $goodsSku = GoodsSku::query()->where('external_sku_id', $externalSkuId)->first(['id', 'cost', 'sale_stock']); - Log::info("SKU",[$goodsSku]); + Log::info("SKU", [$goodsSku]); if (empty($goodsSku)) { continue; } diff --git a/app/Listeners/BatchStockUpdateListener.php b/app/Listeners/BatchStockUpdateListener.php index 5250aa4..d18fb62 100644 --- a/app/Listeners/BatchStockUpdateListener.php +++ b/app/Listeners/BatchStockUpdateListener.php @@ -40,11 +40,8 @@ class BatchStockUpdateListener implements ShouldQueue try { foreach ($shops as $shop) { foreach ($event->goodsSkus as $goodsSku) { - if ($shop['plat_id'] == "快团团") { - $num = $goodsSku->sale_stock; - } else { - $num = $goodsSku->stock; - } + //后续同步三方使用在售库存 + $num = $goodsSku->sale_stock; $businessGoodsSkus = BusinessGoodsSku::query() ->select(['goods_id', 'sku_id', 'external_sku_id']) ->where('shop_id', $shop->id) diff --git a/app/Listeners/StockUpdateListener.php b/app/Listeners/StockUpdateListener.php index 3bc4380..5073e0a 100644 --- a/app/Listeners/StockUpdateListener.php +++ b/app/Listeners/StockUpdateListener.php @@ -36,11 +36,7 @@ class StockUpdateListener implements ShouldQueue return; } foreach ($shops as $shop) { - if ($shop['plat_id'] == "快团团") { - $num = $event->goodsSku->sale_stock; - } else { - $num = $event->goodsSku->stock; - } + $num = $event->goodsSku->sale_stock; $businessGoodsSkus = BusinessGoodsSku::query() ->select(['goods_id', 'sku_id', 'external_sku_id']) ->where('shop_id', $shop->id) diff --git a/app/Listeners/UpdateBusinessGoodsStock.php b/app/Listeners/UpdateBusinessGoodsStock.php index 52c801f..937e58e 100644 --- a/app/Listeners/UpdateBusinessGoodsStock.php +++ b/app/Listeners/UpdateBusinessGoodsStock.php @@ -60,11 +60,7 @@ class UpdateBusinessGoodsStock implements ShouldQueue } foreach ($shops as $shop) { - if ($shop['plat_id'] == "快团团") { - $num = $event->goodsSku->sale_stock; - } else { - $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 index 5f1a59e..cfcbdac 100644 --- a/app/Services/GoodSku/GoodSkuService.php +++ b/app/Services/GoodSku/GoodSkuService.php @@ -126,8 +126,6 @@ class GoodSkuService public static function computeSkuStock(array $goodsSkuItem, array $changeData, $targetType = TargetTypeEnum::LOSS) { $updateIds = []; - Log::info("库存更新前完整商品信息", $goodsSkuItem); - Log::info("库存更新前完整请求信息", $changeData); $updateParams = []; //添加系统日志 $costLogs = []; @@ -135,12 +133,15 @@ class GoodSkuService if (empty($goodsSkuItem['is_combination'])) { $updateParam = [ 'stock' => $goodsSkuItem['stock'] + $changeData['num'], - 'sale_stock' => $goodsSkuItem['sale_stock'] + $changeData['num'], + 'sale_stock' => max($goodsSkuItem['sale_stock'] + $changeData['num'], 0), ]; if ($targetType == TargetTypeEnum::PURCHASE) { $updateParam['cost'] = $changeData['cost']; } + if ($updateParam['sale_stock'] <= 0) { + $updateParam['status'] = GoodsSku::$STATUS_DOWN; + } GoodsSku::query()->where('external_sku_id', "=", $goodsSkuItem['external_sku_id']) ->update($updateParam); $updateIds[] = $goodsSkuItem['id']; @@ -154,8 +155,11 @@ class GoodSkuService foreach ($combinationGood as $item) { $updateParam = [ 'stock' => $item['goodsSkuItem']['stock'] + $changeData['num'] * $item['item_num'], - 'sale_stock' => $item['goodsSkuItem']['sale_stock'] + $changeData['num'] * $item['item_num'], + 'sale_stock' => max($item['goodsSkuItem']['sale_stock'] + $changeData['num'] * $item['item_num'], 0), ]; + if ($updateParam['sale_stock'] <= 0) { + $updateParam['status'] = GoodsSku::$STATUS_DOWN; + } GoodsSku::query()->where('id', $item['goodsSkuItem']['id'])->update($updateParam); $updateIds[] = $item['goodsSkuItem']['id']; @@ -171,7 +175,7 @@ class GoodSkuService public static function addStockLog($goodsSkuItem, $targetType = TargetTypeEnum::LOSS, $updateParam) { - $userId = Auth::id(); + $userId = Auth::id(); $costLog = [ 'module' => 'goods', 'action' => "POST", diff --git a/app/Utils/RedisLockUtils.php b/app/Utils/RedisLockUtils.php new file mode 100644 index 0000000..9297380 --- /dev/null +++ b/app/Utils/RedisLockUtils.php @@ -0,0 +1,41 @@ +filter()->implode(':'); + } + + public static function getLock($lockKey, $expireSeconds = 1, $throwException = false) + { + $lock = Redis::setnx($lockKey, 1); + if (!$lock) { + if ($throwException) { + throw new ServiceException('操作频繁'); + } + + return false; + } + + Redis::expire($lockKey, $expireSeconds); + + return true; + } + + public static function deleteLock($lockKey) + { + return Redis::del($lockKey); + } +} diff --git a/database/migrations/2024_07_24_145201_add_sale_stock_and_quality_period_to_goods_skus_table.php b/database/migrations/2024_07_24_145201_add_sale_stock_and_quality_period_to_goods_skus_table.php index ca59754..f051e43 100644 --- a/database/migrations/2024_07_24_145201_add_sale_stock_and_quality_period_to_goods_skus_table.php +++ b/database/migrations/2024_07_24_145201_add_sale_stock_and_quality_period_to_goods_skus_table.php @@ -18,7 +18,7 @@ class AddSaleStockAndQualityPeriodToGoodsSkusTable extends Migration } Schema::table('goods_skus', function (Blueprint $table) { // - $table->integer('sale_stock')->default(9000)->comment("在售库存数"); + $table->integer('sale_stock')->default(0)->comment("在售库存数"); $table->integer('quality_period')->nullable()->comment("保质期时间,单位天"); });