mirror of
https://gitee.com/hzchunfen/erp.git
synced 2025-11-30 22:20:45 +00:00
鲜花2.0-采购单导入
This commit is contained in:
parent
3ac66d6d63
commit
3b61176cda
@ -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();
|
||||
}
|
||||
|
||||
|
||||
@ -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']);
|
||||
}
|
||||
|
||||
|
||||
@ -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']);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
12
app/Http/Enum/ExcelKeyEnum.php
Normal file
12
app/Http/Enum/ExcelKeyEnum.php
Normal file
@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Enum;
|
||||
|
||||
|
||||
class ExcelKeyEnum
|
||||
{
|
||||
const PURCHASE_KEY = "purchaseFile";
|
||||
|
||||
const LOSS_KEY = "lossFile";
|
||||
|
||||
}
|
||||
@ -7,6 +7,7 @@ use App\Jobs\SyncCostToMiaoXuan;
|
||||
use App\Models\DailyStockRecord;
|
||||
use App\Models\GoodsSku;
|
||||
use App\Models\TodayPrice;
|
||||
use App\Services\GoodSku\GoodSkuService;
|
||||
use App\Utils\DateTimeUtils;
|
||||
use Exception;
|
||||
use Maatwebsite\Excel\Concerns\SkipsEmptyRows;
|
||||
@ -20,85 +21,21 @@ class InventoryImport implements ToArray, SkipsEmptyRows
|
||||
*/
|
||||
public function array(array $collection)
|
||||
{
|
||||
$header = $collection[0];
|
||||
unset($collection[0]);
|
||||
$externalSkuId = [];
|
||||
$requestSkus = [];
|
||||
foreach ($collection as &$row) {
|
||||
$row = array_map(static function ($v) {
|
||||
return trim($v);
|
||||
}, $row);
|
||||
$externalSkuId[] = $row[0];
|
||||
}
|
||||
unset($row);
|
||||
$updateIds = $todayPrice = [];
|
||||
$day = DateTimeUtils::getToday();
|
||||
$dateTime = date('Y-m-d H:i:s');
|
||||
$hasGoodsSkus = GoodsSku::query()
|
||||
->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);
|
||||
}
|
||||
}
|
||||
|
||||
71
app/Imports/LossImport.php
Normal file
71
app/Imports/LossImport.php
Normal file
@ -0,0 +1,71 @@
|
||||
<?php
|
||||
|
||||
namespace App\Imports;
|
||||
|
||||
use App\Events\BatchStockUpdateEvent;
|
||||
use App\Jobs\SyncCostToMiaoXuan;
|
||||
use App\Models\DailyStockRecord;
|
||||
use App\Models\GoodsSku;
|
||||
use App\Models\LossRecords;
|
||||
use App\Models\PurchaseRecords;
|
||||
use App\Utils\DateTimeUtils;
|
||||
use Exception;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Maatwebsite\Excel\Concerns\SkipsEmptyRows;
|
||||
use Maatwebsite\Excel\Concerns\ToArray;
|
||||
use App\Utils\ArrayUtils;
|
||||
|
||||
class LossImport implements ToArray, SkipsEmptyRows
|
||||
{
|
||||
/**
|
||||
* @throws Exception
|
||||
*/
|
||||
public function array(array $collection)
|
||||
{
|
||||
unset($collection[0]);
|
||||
$externalSkuIds = [];
|
||||
foreach ($collection as &$row) {
|
||||
$row = array_map(static function ($v) {
|
||||
return trim($v);
|
||||
}, $row);
|
||||
$externalSkuIds[] = $row[0];
|
||||
}
|
||||
unset($row);
|
||||
$updateIds = [];
|
||||
$hasGoodsSkus = GoodsSku::query()
|
||||
->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));
|
||||
}
|
||||
}
|
||||
70
app/Imports/PurchaseImport.php
Normal file
70
app/Imports/PurchaseImport.php
Normal file
@ -0,0 +1,70 @@
|
||||
<?php
|
||||
|
||||
namespace App\Imports;
|
||||
|
||||
use App\Events\BatchStockUpdateEvent;
|
||||
use App\Jobs\SyncCostToMiaoXuan;
|
||||
use App\Models\DailyStockRecord;
|
||||
use App\Models\GoodsSku;
|
||||
use App\Models\PurchaseRecords;
|
||||
use App\Utils\DateTimeUtils;
|
||||
use Exception;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Maatwebsite\Excel\Concerns\SkipsEmptyRows;
|
||||
use Maatwebsite\Excel\Concerns\ToArray;
|
||||
use App\Utils\ArrayUtils;
|
||||
|
||||
class PurchaseImport implements ToArray, SkipsEmptyRows
|
||||
{
|
||||
/**
|
||||
* @throws Exception
|
||||
*/
|
||||
public function array(array $collection)
|
||||
{
|
||||
unset($collection[0]);
|
||||
$externalSkuIds = [];
|
||||
foreach ($collection as &$row) {
|
||||
$row = array_map(static function ($v) {
|
||||
return trim($v);
|
||||
}, $row);
|
||||
$externalSkuIds[] = $row[0];
|
||||
}
|
||||
unset($row);
|
||||
$updateIds = [];
|
||||
$hasGoodsSkus = GoodsSku::query()
|
||||
->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));
|
||||
}
|
||||
}
|
||||
@ -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];
|
||||
}
|
||||
|
||||
@ -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)
|
||||
|
||||
57
app/Services/GoodSku/GoodSkuService.php
Normal file
57
app/Services/GoodSku/GoodSkuService.php
Normal file
@ -0,0 +1,57 @@
|
||||
<?php
|
||||
|
||||
namespace App\Services\GoodSku;
|
||||
|
||||
use App\Events\BatchStockUpdateEvent;
|
||||
use App\Events\CreateLogisticEvent;
|
||||
use App\Models\BusinessOrderItem;
|
||||
use App\Models\DailyStockRecord;
|
||||
use App\Models\GoodsSku;
|
||||
use App\Models\Log as LogModel;
|
||||
use App\Models\ShopShip;
|
||||
use App\Models\Waybill;
|
||||
use App\Services\Business\KuaiTuanTuan\FaceSheet;
|
||||
use App\Utils\ArrayUtils;
|
||||
use App\Utils\DateTimeUtils;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
class GoodSkuService
|
||||
{
|
||||
|
||||
public function inventory(array $requestSkus)
|
||||
{
|
||||
$requestSkusMap = collect($requestSkus)->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));
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@ -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');
|
||||
|
||||
@ -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
|
||||
],
|
||||
];
|
||||
|
||||
@ -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');
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user