mirror of
https://gitee.com/hzchunfen/erp.git
synced 2025-12-01 06:30:49 +00:00
鲜花2.0-定时任务统计每日库存报表数据+库存扣减完成
This commit is contained in:
parent
ab03594786
commit
dba30f1168
92
app/Console/Commands/DailyStockRecordReport.php
Normal file
92
app/Console/Commands/DailyStockRecordReport.php
Normal file
@ -0,0 +1,92 @@
|
||||
<?php
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use App\Models\BusinessOrderItem;
|
||||
use App\Models\DailyReport;
|
||||
use App\Models\DailyStockRecord;
|
||||
use App\Models\GoodsSku;
|
||||
use App\Models\LossRecords;
|
||||
use App\Models\PurchaseRecords;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Console\Command;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
class DailyStockRecordReport extends Command
|
||||
{
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'daily:report:stock_record';
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = '每日商品库存记录';
|
||||
|
||||
/**
|
||||
* Create a new command instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
$date = Carbon::yesterday()->format('Y-m-d');
|
||||
$startDateTime = Carbon::parse($date)->startOfDay()->toDateTimeString();
|
||||
$endDateTime = Carbon::parse($date)->endOfDay()->toDateTimeString();
|
||||
//统计订单数量
|
||||
$orderItems = BusinessOrderItem::query()
|
||||
->leftJoin("business_orders as b", "business_order_id", "=", "b.id")
|
||||
->select("business_order_items.external_sku_id"
|
||||
, DB::raw("sum(goods_number-already_cancel_number) as goods_total"))
|
||||
->whereBetween("business_order_items.created_at", [$startDateTime, $endDateTime])
|
||||
->where("business_order_items.cancel_status", "=", 0)
|
||||
->groupBy('external_sku_id')->get()->pluck(null, "external_sku_id")->toArray();
|
||||
|
||||
//统计采购单数量
|
||||
$purchaseRecords = PurchaseRecords::query()
|
||||
->select(DB::raw("sum(num) as arrived_today_num"), "external_sku_id")
|
||||
->whereBetween("created_at", [$startDateTime, $endDateTime])
|
||||
->groupBy("external_sku_id")->get()->pluck(null, "external_sku_id")->toArray();
|
||||
//统计报损数量
|
||||
$lossRecords = LossRecords::query()
|
||||
->select(DB::raw("sum(num) as loss_num"), "external_sku_id")
|
||||
->whereBetween("created_at", [$startDateTime, $endDateTime])
|
||||
->groupBy("external_sku_id")->get()->pluck(null, "external_sku_id")->toArray();
|
||||
Log::info("{$date}每日库存记录", ["orderItems" => $orderItems
|
||||
, "purchaseRecords" => $purchaseRecords, "lossRecords" => $lossRecords]);
|
||||
$needUpdateExternalSkuIds = array_merge(array_keys($orderItems), array_keys($purchaseRecords), array_keys($lossRecords));
|
||||
//开始更新数据
|
||||
if (!empty($needUpdateExternalSkuIds)) {
|
||||
$needUpdateSkuIdsMap = GoodsSku::query()->whereIn("external_sku_id", $needUpdateExternalSkuIds)->pluck("external_sku_id", 'id')->toArray();
|
||||
collect($needUpdateSkuIdsMap)->each(function ($externalSkuId,$skuId) use ($date, $orderItems, $purchaseRecords, $lossRecords) {
|
||||
$record = DailyStockRecord::query()->firstOrNew([
|
||||
'sku_id' => $skuId,
|
||||
'day' => $date,
|
||||
]);
|
||||
$record->arrived_today_num = !empty($purchaseRecords[$externalSkuId]["arrived_today_num"])
|
||||
? $purchaseRecords[$externalSkuId]["arrived_today_num"] : 0;
|
||||
$record->loss_num = !empty($lossRecords[$externalSkuId]["loss_num"])
|
||||
? $lossRecords[$externalSkuId]["loss_num"] : 0;
|
||||
$record->order_goods_num = !empty($orderItems[$externalSkuId]["goods_total"])
|
||||
? $orderItems[$externalSkuId]["goods_total"] : 0;
|
||||
$record->save();
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -3,10 +3,16 @@
|
||||
namespace App\Http\Controllers\DataCenter;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Enum\StaticTypeEnum;
|
||||
use App\Http\Resources\DailySalesReportResource;
|
||||
use App\Models\BusinessOrderItem;
|
||||
use App\Models\DailySalesReport;
|
||||
use App\Models\GoodsSku;
|
||||
use App\Utils\FormatUtils;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
|
||||
class DataCenterController extends Controller
|
||||
{
|
||||
@ -37,4 +43,48 @@ class DataCenterController extends Controller
|
||||
|
||||
return DailySalesReportResource::collection($dailySalesReports);
|
||||
}
|
||||
|
||||
/**
|
||||
* 销售报表
|
||||
* @param Request $request
|
||||
* @return void
|
||||
*/
|
||||
public function skuSalesReport(Request $request)
|
||||
{
|
||||
//获取所有参数
|
||||
$allParams = $request->all();
|
||||
//进行校验验证
|
||||
$validator = Validator::make($allParams, [
|
||||
'type' => 'required|integer', //1表示今日
|
||||
'start_day' => 'sometimes|string',
|
||||
'end_day' => 'sometimes|string',
|
||||
'title' => 'sometimes|string'
|
||||
]);
|
||||
|
||||
if ($validator->fails()) {
|
||||
//校验失败返回异常
|
||||
$this->setValidatorFailResponse($validator->getMessageBag()->getMessages());
|
||||
return response($this->res, $this->res['httpCode']);
|
||||
}
|
||||
if (StaticTypeEnum::TODAY == $allParams->type) {
|
||||
//实时统计
|
||||
$orderItems = BusinessOrderItem::query()
|
||||
->leftJoin("business_orders as b", "business_order_id", "=", "b.id")
|
||||
->select("business_order_items.external_sku_id"
|
||||
, DB::raw("sum(CASE WHEN b.shipping_status>0 THEN goods_number-already_cancel_number ELSE 0 END) as shipping_num")
|
||||
, DB::raw("sum(CASE WHEN b.shipping_status=0 THEN goods_number-already_cancel_number ELSE 0 END) as unshipping_num")
|
||||
, DB::raw("sum(goods_number-already_cancel_number) as goods_total"))
|
||||
->where("business_order_items.created_at", ">",Carbon::now()->startOfDay()->toDateTimeString())
|
||||
->where("business_order_items.cancel_status", "=", 0)
|
||||
->groupBy('external_sku_id')
|
||||
->orderBy("goods_total","DESC")
|
||||
->paginate($request->get('per_page'));
|
||||
return $orderItems;
|
||||
} else {
|
||||
$startTime = Carbon::parse($request->input("start_day"))->toDateTimeString();
|
||||
$endTime = Carbon::parse($request->input("end_day"))->endOfDay()->toDateTimeString();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@ -63,7 +63,7 @@ class DailyStockRecordController extends Controller
|
||||
$goodsSku = GoodsSku::query()->with("combinationGoods")->where('external_sku_id', "=", $request->external_sku_id)->first();
|
||||
if (empty($goodsSku)) {
|
||||
$this->res = [
|
||||
'httpCode' => 200,
|
||||
'httpCode' => 400,
|
||||
'message' => '查询不到sku信息',
|
||||
'errorCode' => "ERP001",
|
||||
'errorMessage' => '查询不到sku信息',
|
||||
|
||||
@ -69,7 +69,7 @@ class LossRecordController extends Controller
|
||||
event(new BatchStockUpdateEvent($updateIds));
|
||||
} else {
|
||||
$this->res = [
|
||||
'httpCode' => 200,
|
||||
'httpCode' => 400,
|
||||
'message' => '查询不到sku信息',
|
||||
'errorCode' => "ERP001",
|
||||
'errorMessage' => '查询不到sku信息',
|
||||
@ -94,17 +94,15 @@ class LossRecordController extends Controller
|
||||
$this->setValidatorFailResponse($validator->getMessageBag()->getMessages());
|
||||
return response($this->res, $this->res['httpCode']);
|
||||
}
|
||||
$goodsSku = GoodsSku::query()->where('id', "=", $id)->get();
|
||||
if (!empty($goodsSku)) {
|
||||
$lossRecords = LossRecords::query()->find($id);
|
||||
if (!empty($lossRecords)) {
|
||||
//更新記錄
|
||||
$lossRecords = new LossRecords();
|
||||
$lossRecords->buyer_name = $allParams['buyer_name'] ?? '';
|
||||
$lossRecords->reason = $allParams['reason'] ?? '';
|
||||
$lossRecords->save();
|
||||
|
||||
} else {
|
||||
$this->res = [
|
||||
'httpCode' => 200,
|
||||
'httpCode' => 400,
|
||||
'message' => '查询不到sku信息',
|
||||
'errorCode' => "ERP001",
|
||||
'errorMessage' => '查询不到sku信息',
|
||||
|
||||
@ -75,7 +75,7 @@ class PurchaseRecordController extends Controller
|
||||
event(new BatchStockUpdateEvent($updateIds));
|
||||
} else {
|
||||
$this->res = [
|
||||
'httpCode' => 200,
|
||||
'httpCode' => 400,
|
||||
'message' => '查询不到sku信息',
|
||||
'errorCode' => "ERP001",
|
||||
'errorMessage' => '查询不到sku信息',
|
||||
@ -116,7 +116,7 @@ class PurchaseRecordController extends Controller
|
||||
|
||||
} else {
|
||||
$this->res = [
|
||||
'httpCode' => 200,
|
||||
'httpCode' => 400,
|
||||
'message' => '查询不到sku信息',
|
||||
'errorCode' => "ERP001",
|
||||
'errorMessage' => '查询不到sku信息',
|
||||
|
||||
11
app/Http/Enum/StaticTypeEnum.php
Normal file
11
app/Http/Enum/StaticTypeEnum.php
Normal file
@ -0,0 +1,11 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Enum;
|
||||
|
||||
|
||||
class StaticTypeEnum
|
||||
{
|
||||
|
||||
const TODAY = 1;
|
||||
|
||||
}
|
||||
@ -3,10 +3,13 @@
|
||||
namespace App\Services\GoodSku;
|
||||
|
||||
use App\Events\BatchStockUpdateEvent;
|
||||
use App\Models\BusinessOrderItem;
|
||||
use App\Models\CombinationGood;
|
||||
use App\Models\DailyStockRecord;
|
||||
use App\Models\GoodsSku;
|
||||
use App\Utils\DateTimeUtils;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
class GoodSkuService
|
||||
@ -18,9 +21,10 @@ class GoodSkuService
|
||||
*/
|
||||
public function inventory(array $skusWithCombinationGoods)
|
||||
{
|
||||
$skusWithCombinationGoods = $this->handleSkusWithCombinationGoods($skusWithCombinationGoods);
|
||||
//传进来的sku可能包含组合商品 所以这里需要事先计算好数据
|
||||
$inventoryKeyBySkuIdMap = collect($skusWithCombinationGoods)->where('is_combination', "=", 0)
|
||||
->pluck("inventory", "sku_id")->toArray();
|
||||
->pluck("inventory", "id")->toArray();
|
||||
//计算组合商品
|
||||
foreach ($skusWithCombinationGoods as $sku) {
|
||||
if (!empty($sku['is_combination'])) {
|
||||
@ -28,7 +32,7 @@ class GoodSkuService
|
||||
if (empty($inventoryKeyBySkuIdMap[$combinationGoods["item_id"]])) {
|
||||
//没有盘点到的sku需要在原先的sku库存
|
||||
$inventoryKeyBySkuIdMap[$combinationGoods["item_id"]] = GoodsSku::query()
|
||||
->where('id', $combinationGoods["item_id"])->pluck('stock')->first()??0;
|
||||
->where('id', $combinationGoods["item_id"])->pluck('stock')->first() ?? 0;
|
||||
}
|
||||
|
||||
$inventoryKeyBySkuIdMap[$combinationGoods["item_id"]] += $combinationGoods['item_num'] * $sku['inventory'];
|
||||
@ -50,7 +54,6 @@ class GoodSkuService
|
||||
$record->inventory = $totalInventory;
|
||||
$record->inventory_time = $dateTime;
|
||||
$record->save();
|
||||
//查询sku当前未发货的数量 目前数据看着有问题暂不操作
|
||||
|
||||
//库存修改 盘点是直接覆盖
|
||||
GoodsSku::query()->where('id', $skuId)->update([
|
||||
@ -62,7 +65,36 @@ class GoodSkuService
|
||||
event(new BatchStockUpdateEvent($updateIds));
|
||||
}
|
||||
|
||||
public static function computeSkuStock(array $goodsSkuItem, array $v): array
|
||||
/**
|
||||
* 库存盘点 需要扣减未发货未取消的订单数据
|
||||
* 目前只查询了7日内的数据
|
||||
* @param array $skusWithCombinationGoods
|
||||
* @return \Illuminate\Support\Collection
|
||||
*/
|
||||
public function handleSkusWithCombinationGoods(array $skusWithCombinationGoods){
|
||||
//查询sku当前未发货的数量 需要扣减
|
||||
$externalSkuIds = collect($skusWithCombinationGoods)->pluck("external_sku_id")->toArray();
|
||||
//默认只查7天内未发货的数据
|
||||
$startTime = Carbon::now()->subDays(7)->startOfDay()->toDateTimeString();
|
||||
$unshippedDataCollect = BusinessOrderItem::query()
|
||||
->leftJoin("business_orders as b", "business_order_id", "=", "b.id")
|
||||
->select("external_sku_id", DB::raw("sum(goods_number) as goods_total"), DB::raw("sum(already_cancel_number) as cancel_total"))
|
||||
->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);
|
||||
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']
|
||||
+ $unshippedData[$v['external_sku_id']]['cancel_total'];
|
||||
}
|
||||
return $v;
|
||||
})->toArray();
|
||||
}
|
||||
|
||||
|
||||
public static function computeSkuStock(array $goodsSkuItem, array $v)
|
||||
{
|
||||
$updateIds = [];
|
||||
Log::info("库存更新前完整商品信息", $goodsSkuItem);
|
||||
|
||||
@ -85,6 +85,10 @@ Route::middleware(['auth:api', 'check.permissions'])->group(function () {
|
||||
Route::resource('supplier/loss_record', 'Supplier\LossRecordController',['only' => ['index', 'store','update']]);
|
||||
//仓库管理-盘点
|
||||
Route::resource('supplier/daily_stock_record', 'Supplier\DailyStockRecordController',['only' => ['index', 'store']]);
|
||||
|
||||
// 数据中心 销售报表
|
||||
Route::get('data_center/sku_sales_report', [DataCenterController::class, 'skuSalesReport'])->name('sku_sales_report.index');
|
||||
|
||||
});
|
||||
Route::get('stock/goods_skus', [GoodsSkusController::class, 'stockNum'])->middleware('auth:api');
|
||||
Route::get('goods/filter/{title}', [GoodsCombinationController::class, 'goodsSkus'])->middleware('auth:api');
|
||||
|
||||
@ -4,6 +4,8 @@
|
||||
use App\Models\BusinessGoodsSku;
|
||||
use App\Models\BusinessOrderItem;
|
||||
use App\Models\GoodsSku;
|
||||
use App\Services\Business\BusinessFactory;
|
||||
use App\Utils\DateTimeUtils;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Tests\TestCase;
|
||||
|
||||
@ -18,7 +20,12 @@ class BusinessOrderUpdateTest extends TestCase
|
||||
*/
|
||||
public function testBasicTest()
|
||||
{
|
||||
|
||||
// $shop = new \App\Models\Shop();
|
||||
// $shop->id=19;
|
||||
// $shop->access_token="7e00e77428cf45348cb1ca190dc769670377bd0c";
|
||||
// $endTime = DateTimeUtils::getMicroTime();
|
||||
// $beginTime = $endTime - 63000;
|
||||
// BusinessFactory::init()->make("快团团")->setShop($shop)->downloadOrdersAndSave($beginTime, $endTime, 'increment');
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user