鲜花2.0-gmv接口开发完成+ 售后单维护

This commit is contained in:
杨建炊 2024-08-05 16:54:19 +08:00
parent dd6f9427c7
commit fdaa818c28
21 changed files with 319 additions and 28 deletions

View File

@ -47,10 +47,9 @@ class CheckPrice extends Command
//查询价格异常订单 //查询价格异常订单
$results = DB::table('business_order_items as a') $results = DB::table('business_order_items as a')
->select('c.title as cn_name', 'b.title as title', DB::raw('ROUND(a.goods_price / 100,2) AS goods_price') ->select('b.name as cn_name', 'b.title as title', DB::raw('ROUND(a.goods_price / 100,2) AS goods_price')
, 'b.cost','a.created_at','a.business_order_id') , 'b.cost','a.created_at','a.business_order_id')
->leftJoin('goods_skus as b', 'a.external_sku_id', '=', 'b.external_sku_id') ->leftJoin('goods_skus as b', 'a.external_sku_id', '=', 'b.external_sku_id')
->leftJoin('goods as c', 'b.goods_id', '=', 'c.id')
->whereBetween('a.created_at', [$startTime,$endTime]) ->whereBetween('a.created_at', [$startTime,$endTime])
->havingRaw('goods_price < cost') ->havingRaw('goods_price < cost')
->get(); ->get();

View File

@ -0,0 +1,54 @@
<?php
namespace App\Console\Commands;
use App\Models\Shop;
use App\Services\Business\BusinessFactory;
use App\Utils\DateTimeUtils;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\Log;
class KttOrderAfterSaleQuery extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'ktt:after_sale_order_query';
/**
* 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
* @throws \Exception
*/
public function handle()
{
$shops = Shop::query()->where('plat_id', Shop::$PLAT_KTT)->where('status', Shop::$STATUS_AUTHORIZED)->get();
$endTime = DateTimeUtils::getMicroTime();
$beginTime = $endTime - (15 * 60 * 1000)-1000;//售后单每15min查询一次 多查询一次
foreach ($shops as $shop) {
BusinessFactory::init()->make($shop->plat_id)->setShop($shop)->downloadAfterSaleOrdersAndSave($beginTime, $endTime);
}
Log::info('任务完成:快团团根据更新时间获取增量售后单');
}
}

View File

@ -7,6 +7,7 @@ use App\Console\Commands\CheckSkuQualityPeriod;
use App\Console\Commands\DailySalesReport; use App\Console\Commands\DailySalesReport;
use App\Console\Commands\GoodsSkuDailyReport; use App\Console\Commands\GoodsSkuDailyReport;
use App\Console\Commands\Inventory; use App\Console\Commands\Inventory;
use App\Console\Commands\KttOrderAfterSaleQuery;
use Illuminate\Console\Scheduling\Schedule; use Illuminate\Console\Scheduling\Schedule;
use Illuminate\Foundation\Console\Kernel as ConsoleKernel; use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
use App\Console\Commands\KttOrderQuery; use App\Console\Commands\KttOrderQuery;
@ -49,7 +50,10 @@ class Kernel extends ConsoleKernel
$schedule->command(DeleteKttQuery::class)->daily(); $schedule->command(DeleteKttQuery::class)->daily();
//新增价格校验 //新增价格校验
$schedule->command(CheckPrice::class)->everyFifteenMinutes(); $schedule->command(CheckPrice::class)->everyFifteenMinutes();
$schedule->command(CheckSkuQualityPeriod::class)->dailyAt('05:30');; //保质期
$schedule->command(CheckSkuQualityPeriod::class)->dailyAt('05:30');
//快团团售后单拉取
$schedule->command(KttOrderAfterSaleQuery::class)->everyFifteenMinutes();
} }

View File

@ -0,0 +1,42 @@
<?php
namespace App\Http\Controllers\Business;
use App\Exports\OrderBlankExport;
use App\Http\Controllers\Controller;
use App\Models\BusinessAfterSaleOrder;
use App\Models\BusinessOrder;
use App\Models\BusinessOrderItem;
use App\Models\GoodsSku;
use App\Models\Shop;
use App\Services\Ship\WayBillService;
use App\Utils\DateTimeUtils;
use Carbon\Carbon;
use Illuminate\Http\Request;
use App\Http\Resources\BusinessOrderResource;
use Illuminate\Http\Resources\Json\JsonResource;
use Illuminate\Support\Facades\DB;
use Maatwebsite\Excel\Facades\Excel;
class BusinessAfterSaleOrderController extends Controller
{
public function index(Request $request)
{
$shopIds = Shop::query()
->where('plat_id', Shop::$PLAT_KTT)
->pluck('id');
$builder = BusinessAfterSaleOrder::query()
->whereIn('shop_id', $shopIds)
->filter();
if (!empty($request->created_at_start) & !empty($request->created_at_end)) {
$builder = $builder->whereBetween("after_sale_created_at"
, [$request->created_at_start, $request->created_at_end]);
}
$businessOrders = $builder->orderByDesc('after_sale_created_at')
->paginate($request->get('per_page'));
return JsonResource::collection($businessOrders);
}
}

View File

@ -63,7 +63,7 @@ class Controller extends BaseController
"success" => false, "success" => false,
"msg" => $msg, "msg" => $msg,
"errorCode" => $errorCode, "errorCode" => $errorCode,
"data"=>[] "data" => []
]; ];
} }
} }

View File

@ -112,14 +112,19 @@ class GoodsCombinationController extends Controller
$itemIds = array_column($combinationGoods, 'item_id'); $itemIds = array_column($combinationGoods, 'item_id');
$skus = GoodsSku::query() $skus = GoodsSku::query()
->whereIn('id', $itemIds) ->whereIn('id', $itemIds)
->pluck('stock', 'id') ->pluck(null, 'id')
->toArray(); ->toArray();
$stock = []; $stock = [];
$saleStock = [];
foreach ($combinationGoods as $item) { foreach ($combinationGoods as $item) {
$stock[] = (int)($skus[$item['item_id']] / $item['item_num']); $stock[] = (int)($skus[$item['item_id']]['stock'] / $item['item_num']);
$saleStock[] = (int)($skus[$item['item_id']]['sale_stock'] / $item['item_num']);
} }
$stock = min($stock); $stock = min($stock);
$status = $stock ? (5 < $stock ? 1 : 2) : 0; $saleStock = min($saleStock);
$status = $saleStock ? (5 < $saleStock ? 1 : 2) : 0;
if ($id = $request->input('id')) { if ($id = $request->input('id')) {
$sku = GoodsSku::query()->findOrFail($id); $sku = GoodsSku::query()->findOrFail($id);
} else { } else {
@ -132,6 +137,7 @@ class GoodsCombinationController extends Controller
$sku->sku_code = $request->input('external_sku_id'); $sku->sku_code = $request->input('external_sku_id');
$sku->external_sku_id = $request->input('external_sku_id'); $sku->external_sku_id = $request->input('external_sku_id');
$sku->stock = $stock; $sku->stock = $stock;
$sku->sale_stock = $saleStock;
$sku->save(); $sku->save();
CombinationGood::query() CombinationGood::query()
->where('goods_sku_id', $sku->id) ->where('goods_sku_id', $sku->id)

View File

@ -30,7 +30,7 @@ class DailyStockRecordController extends Controller
public function index(Request $request) public function index(Request $request)
{ {
$build = DailyStockRecord::query()->filter()->with("goodsSku:id,name,title"); $build = DailyStockRecord::query()->filter()->with("goodsSku:id,name,title,external_sku_id");
if (!empty($request->title)) { if (!empty($request->title)) {
$build->whereHas('goodsSku', function ($query) use ($request) { $build->whereHas('goodsSku', function ($query) use ($request) {
$query->where('name', 'like', '%' . $request->title . '%'); $query->where('name', 'like', '%' . $request->title . '%');

View File

@ -110,7 +110,7 @@ class PurchaseRecordController extends Controller
$goodsSku = GoodsSku::query()->where('id', "=", $id)->get(); $goodsSku = GoodsSku::query()->where('id', "=", $id)->get();
if (!empty($goodsSku)) { if (!empty($goodsSku)) {
//可以修改的記錄 //可以修改的記錄
$purchaseRecords = new PurchaseRecords(); $purchaseRecords = PurchaseRecords::query()->find($id);
$purchaseRecords->buyer_name = $allParams['buyer_name'] ?? ''; $purchaseRecords->buyer_name = $allParams['buyer_name'] ?? '';
$purchaseRecords->supplier_name = $allParams['supplier_name'] ?? ''; $purchaseRecords->supplier_name = $allParams['supplier_name'] ?? '';
$purchaseRecords->supplier_id = $allParams['supplier_id'] ?? 0; $purchaseRecords->supplier_id = $allParams['supplier_id'] ?? 0;

View File

@ -27,7 +27,7 @@ class MessageService
foreach ($roleIds as $v) { foreach ($roleIds as $v) {
$arr['title'] = "订单价格异常告警"; $arr['title'] = "订单价格异常告警";
$arr['role_id'] = $v; $arr['role_id'] = $v;
$arr['unique_key'] = $date."-".$businessOrderId; $arr['unique_key'] = $date . "-" . $businessOrderId . "-" . $v;
$arr['type'] = MessageTypeEnum::PRICE_EXCEPTION_NOTICE; $arr['type'] = MessageTypeEnum::PRICE_EXCEPTION_NOTICE;
$arr['content'] = $date . "订单号:{$businessOrderId}-商品{$productName} $arr['content'] = $date . "订单号:{$businessOrderId}-商品{$productName}
规格{$skuName}价格有异常,当前售价{$goodsPrice}/支,当前成本价{$cost}/"; 规格{$skuName}价格有异常,当前售价{$goodsPrice}/支,当前成本价{$cost}/";
@ -42,7 +42,7 @@ class MessageService
* @param $goodsSku * @param $goodsSku
* @return void * @return void
*/ */
public function createLowerStockNoticeMessage($inventory,$goodsSku) public function createLowerStockNoticeMessage($inventory, $goodsSku)
{ {
$roleIds = $this->roleIdsMapKeyByNoticeType[MessageTypeEnum::LOW_STOCK_NOTICE] ?? []; $roleIds = $this->roleIdsMapKeyByNoticeType[MessageTypeEnum::LOW_STOCK_NOTICE] ?? [];
if (empty($roleIds)) { if (empty($roleIds)) {
@ -52,7 +52,7 @@ class MessageService
foreach ($roleIds as $v) { foreach ($roleIds as $v) {
$arr['title'] = "订单库存不足告警"; $arr['title'] = "订单库存不足告警";
$arr['role_id'] = $v; $arr['role_id'] = $v;
$arr['unique_key'] = $date."-".$goodsSku['id']; $arr['unique_key'] = $date . "-" . $goodsSku['id'] . "-" . $v;
$arr['type'] = MessageTypeEnum::LOW_STOCK_NOTICE; $arr['type'] = MessageTypeEnum::LOW_STOCK_NOTICE;
$arr['content'] = $date . "规格{$goodsSku['title']}库存可能需要补货,当前实际库存{$goodsSku['stock']},上次库存盘点数{$inventory}"; $arr['content'] = $date . "规格{$goodsSku['title']}库存可能需要补货,当前实际库存{$goodsSku['stock']},上次库存盘点数{$inventory}";
$this->saveWebsiteMessages($arr); $this->saveWebsiteMessages($arr);
@ -74,7 +74,7 @@ class MessageService
foreach ($roleIds as $v) { foreach ($roleIds as $v) {
$arr['title'] = "订单库存不足告警"; $arr['title'] = "订单库存不足告警";
$arr['role_id'] = $v; $arr['role_id'] = $v;
$arr['unique_key'] = $date."-".$goodsSku['id'];//这个场景下实际是采购单的id $arr['unique_key'] = $date . "-" . $goodsSku['id'] . "-" . $v;//这个场景下实际是采购单的id
$arr['type'] = MessageTypeEnum::QUALITY_PERIOD_EXPIRE_NOTICE; $arr['type'] = MessageTypeEnum::QUALITY_PERIOD_EXPIRE_NOTICE;
$arr['content'] = $date . "规格{$goodsSku['title']},即将过期,实际库存{$goodsSku['stock']} $arr['content'] = $date . "规格{$goodsSku['title']},即将过期,实际库存{$goodsSku['stock']}
,当时采购数量为{$goodsSku['num']},录入采购时间为{$goodsSku['created_at']}"; ,当时采购数量为{$goodsSku['num']},录入采购时间为{$goodsSku['created_at']}";
@ -86,6 +86,12 @@ class MessageService
public function saveWebsiteMessages($arr) public function saveWebsiteMessages($arr)
{ {
$hasMessage = WebsiteMessages::query()->where("type", "=", $arr['type'])
->where("unique_key", "=", $arr['unique_key'])->first();
if (!empty($hasMessage)) {
//已经写入过了
return true;
}
$websiteMessages = new WebsiteMessages(); $websiteMessages = new WebsiteMessages();
$websiteMessages->title = $arr['title']; $websiteMessages->title = $arr['title'];
$websiteMessages->type = $arr['type']; $websiteMessages->type = $arr['type'];
@ -95,7 +101,7 @@ class MessageService
if (!empty($arr['uid'])) { if (!empty($arr['uid'])) {
$websiteMessages->uid = $arr['uid']; $websiteMessages->uid = $arr['uid'];
} }
Log::info("站内消息保存",(array)$arr); Log::info("站内消息保存", (array)$arr);
return $websiteMessages->save($arr); return $websiteMessages->save($arr);
} }

View File

@ -6,6 +6,7 @@ use App\Models\CombinationGood;
use App\Models\GoodsSku; use App\Models\GoodsSku;
use App\Utils\ArrayUtils; use App\Utils\ArrayUtils;
use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Maatwebsite\Excel\Concerns\SkipsEmptyRows; use Maatwebsite\Excel\Concerns\SkipsEmptyRows;
use Maatwebsite\Excel\Concerns\ToArray; use Maatwebsite\Excel\Concerns\ToArray;
use Maatwebsite\Excel\Concerns\WithStartRow; use Maatwebsite\Excel\Concerns\WithStartRow;
@ -50,18 +51,23 @@ class CombinationGoodsImport implements ToArray, SkipsEmptyRows, WithStartRow
$itemCodes = array_column($info['item'], 'item_code'); $itemCodes = array_column($info['item'], 'item_code');
$skus = GoodsSku::query() $skus = GoodsSku::query()
->whereIn('external_sku_id', $itemCodes) ->whereIn('external_sku_id', $itemCodes)
->get(['id', 'external_sku_id', 'stock']) ->get(['id', 'external_sku_id', 'stock', "sale_stock"])
->toArray(); ->toArray();
$skus = ArrayUtils::index($skus, 'external_sku_id'); $skus = ArrayUtils::index($skus, 'external_sku_id');
$stock = []; $stock = [];
$saleStock = [];
foreach ($info['item'] as $item) { foreach ($info['item'] as $item) {
$stock[] = (int)($skus[$item['item_code']]['stock'] / $item['item_num']); $stock[] = (int)($skus[$item['item_code']]['stock'] / $item['item_num']);
$saleStock[] = (int)($skus[$item['item_code']]['sale_stock'] / $item['item_num']);
} }
$stock = min($stock); $stock = min($stock);
$status = $stock ? (5 < $stock ? 1 : 2) : 0; $saleStock = min($saleStock);
$status = $saleStock ? (5 < $saleStock ? 1 : 2) : 0;
$sku = GoodsSku::query()->updateOrCreate( $sku = GoodsSku::query()->updateOrCreate(
['external_sku_id' => $info['external_sku_id'], 'is_combination' => 1], ['external_sku_id' => $info['external_sku_id'], 'is_combination' => 1],
['title' => $info['title'], 'goods_id' => 0, 'sku_code' => $info['external_sku_id'], 'stock' => $stock, 'status' => $status] ['title' => $info['title'], 'goods_id' => 0, 'sku_code' => $info['external_sku_id']
, 'stock' => $stock, "sale_stock" => $saleStock, 'status' => $status]
); );
CombinationGood::query() CombinationGood::query()
->where('goods_sku_id', $sku->id) ->where('goods_sku_id', $sku->id)

View File

@ -47,7 +47,7 @@ class BusinessOrderUpdateListener implements ShouldQueue
$nowTime = Carbon::now()->toDateTimeString(); $nowTime = Carbon::now()->toDateTimeString();
//查找最后一次盘点数据 //查找最后一次盘点数据
$dailyStockRecord = DailyStockRecord::query()->where("sku_id", '=', $skuId)-> $dailyStockRecord = DailyStockRecord::query()->where("sku_id", '=', $skuId)->
where("inventory_time", '<', $nowTime)->orderByDesc('inventory_time')->first(); where("inventory_time", '<', $nowTime)->orderByDesc('id')->first();
$inventory = $dailyStockRecord['inventory'] ?? 0; $inventory = $dailyStockRecord['inventory'] ?? 0;
$expireTime = Carbon::now()->addMinutes(30)->toDateTimeString(); $expireTime = Carbon::now()->addMinutes(30)->toDateTimeString();
$proportion = Cache::remember(CacheKeyEnum::STOCK_RULE_PROPORTION, $expireTime, function () { $proportion = Cache::remember(CacheKeyEnum::STOCK_RULE_PROPORTION, $expireTime, function () {

View File

@ -0,0 +1,33 @@
<?php
namespace App\Models;
use App\Models\traits\Filter;
class BusinessAfterSaleOrder extends Model
{
use Filter;
protected $table = 'business_after_sale_orders';
protected $fillable = [
'after_sales_biz_sn',
];
public $fieldSearchable = [
'after_sales_status',
"shop_id",
"order_sn",
"after_sales_biz_sn"
];
public function getImageListAttribute($value)
{
return !empty($value) ? json_decode($value, true) : $value;
}
public function getSubExtensionsAttribute($value)
{
return !empty($value) ? json_decode($value, true) : $value;
}
}

View File

@ -38,6 +38,8 @@ abstract class BusinessClient
abstract public function downloadOrdersAndSave($beginTime, $endTime, $downloadType = 'default', $page = 1); abstract public function downloadOrdersAndSave($beginTime, $endTime, $downloadType = 'default', $page = 1);
abstract public function downloadAfterSaleOrdersAndSave($beginTime, $endTime, $page = 1);
public function saveOrders($orders) public function saveOrders($orders)
{ {
$shopId = $this->getShop()->id; $shopId = $this->getShop()->id;
@ -156,7 +158,7 @@ abstract class BusinessClient
if (strlen($paramsJson) > 1024) { if (strlen($paramsJson) > 1024) {
$paramsJson = ''; $paramsJson = '';
} }
if (!in_array($params['type'], ['pdd.ktt.increment.order.query', 'pdd.ktt.order.list'], true)) { if (!in_array($params['type'], ['pdd.ktt.increment.order.query', 'pdd.ktt.order.list',"pdd.ktt.after.sales.increment.list"], true)) {
$log = new Log(); $log = new Log();
$log->module = 'plat'; $log->module = 'plat';
$log->action = $method; $log->action = $method;
@ -171,7 +173,7 @@ abstract class BusinessClient
} }
$log->save(); $log->save();
} }
if (in_array($params['type'], ['pdd.ktt.increment.order.query', 'pdd.ktt.order.list'], true)) { if (in_array($params['type'], ['pdd.ktt.increment.order.query', 'pdd.ktt.order.list',"pdd.ktt.after.sales.increment.list"], true)) {
LogFile::info('快团团请求: ' . $paramsJson); LogFile::info('快团团请求: ' . $paramsJson);
LogFile::info('快团团返回: ' . json_encode($res, 256)); LogFile::info('快团团返回: ' . json_encode($res, 256));
} }

View File

@ -2,6 +2,7 @@
namespace App\Services\Business\KuaiTuanTuan; namespace App\Services\Business\KuaiTuanTuan;
use App\Models\BusinessAfterSaleOrder;
use App\Models\BusinessGoodsSku; use App\Models\BusinessGoodsSku;
use App\Models\GoodsSku; use App\Models\GoodsSku;
use App\Models\GroupGoods; use App\Models\GroupGoods;
@ -9,6 +10,7 @@ use App\Models\Shop;
use App\Models\ShopShip; use App\Models\ShopShip;
use App\Services\Business\BusinessClient; use App\Services\Business\BusinessClient;
use App\Models\Groups as GroupsModel; use App\Models\Groups as GroupsModel;
use Carbon\Carbon;
use Illuminate\Support\Facades\Log; use Illuminate\Support\Facades\Log;
class KuaiTuanTuan extends BusinessClient class KuaiTuanTuan extends BusinessClient
@ -123,6 +125,56 @@ class KuaiTuanTuan extends BusinessClient
} }
} }
public function downloadAfterSaleOrdersAndSave($beginTime, $endTime, $page = 1)
{
[$type, $appendParams] = Order::downloadIncrementAfterSaleOrders($beginTime, $endTime, $page);
$responseName = 'ktt_after_sales_incermet_list_response';
$res = $this->doRequest($type, $appendParams);
if (!isset($res[$responseName])) {
return;
}
$this->saveAfterSaleOrdersServer($res[$responseName]['list']);
if ($res[$responseName]['has_next'] == false) {
return;
}
$pageNum = ceil($res[$responseName]['total_count'] / $appendParams['page_size']);
if ($pageNum > $page && 30 >= $page) {
$this->downloadAfterSaleOrdersAndSave($beginTime, $endTime, $page + 1);
}
}
public function saveAfterSaleOrdersServer($orders)
{
$shopId = $this->getShop()->id;
$now = Carbon::now()->toDateTimeString();
foreach ($orders as $k => $v) {
$model = BusinessAfterSaleOrder::query()->where("shop_id","=",$shopId)
->where("after_sales_biz_sn", "=", $v['after_sales_biz_sn'])->first();
if (empty($model)) {
$model = new BusinessAfterSaleOrder();
}else{
$model->updated_at = $now;
}
$model->shop_id = $shopId;
$model->refund_amount = $v['apply_extension']['refund_amount'];
$model->refund_shipping_amount = $v['apply_extension']['refund_shipping_amount'];
$model->description = $v['apply_extension']['description'] ?? '';
$model->reason = $v['apply_extension']['reason'] ?? '';
$model->sub_extensions = isset($v['apply_extension']['sub_extensions']) ? json_encode($v['apply_extension']['sub_extensions']) : null;
$model->return_goods_extension = isset($v['return_goods_extension']) ? json_encode($v['return_goods_extension']) : null;
$model->image_list = isset($v['apply_extension']['image_list']) ? json_encode($v['apply_extension']['image_list']) : null;
$model->apply_type = $v['apply_type'];
$model->order_sn = $v['order_sn'];
$model->after_sales_biz_sn = $v['after_sales_biz_sn'];
$model->after_sales_status = $v['after_sales_status'];
$model->after_sale_created_at = !empty($v['created_at']) ? Carbon::createFromTimestamp($v['created_at'] / 1000)->toDateTimeString() : "";
$model->after_sale_updated_at = !empty($v['updated_at']) ? Carbon::createFromTimestamp($v['created_at'] / 1000)->toDateTimeString() : "";
$model->save();
}
}
public function getOrderInfo($orderSn) public function getOrderInfo($orderSn)
{ {
[$type, $appendParams] = Order::getOrderInfo($orderSn); [$type, $appendParams] = Order::getOrderInfo($orderSn);

View File

@ -92,5 +92,21 @@ class Order
return [$type, $appendParams]; return [$type, $appendParams];
} }
/**
* 快团团增量查售后单订单
*/
public static function downloadIncrementAfterSaleOrders($beginTime, $endTime, $page = 1)
{
$type = 'pdd.ktt.after.sales.increment.list';
$appendParams = [
'start_updated_at' => $beginTime, // 更新起始时间
'end_updated_at' => $endTime, // 更新结束时间
'page_number' => $page, // 页码
'page_size' => 100, // 数量
];
return [$type, $appendParams];
}
} }

View File

@ -25,11 +25,12 @@ class GoodSkuService
//传进来的sku可能包含组合商品 所以这里需要事先计算好数据 //传进来的sku可能包含组合商品 所以这里需要事先计算好数据
$inventoryKeyBySkuIdMap = collect($skusWithCombinationGoods)->where('is_combination', "=", 0) $inventoryKeyBySkuIdMap = collect($skusWithCombinationGoods)->where('is_combination', "=", 0)
->pluck("inventory", "id")->toArray(); ->pluck("inventory", "id")->toArray();
Log::info("库存原始操作map", $inventoryKeyBySkuIdMap);
//计算组合商品 //计算组合商品
foreach ($skusWithCombinationGoods as $sku) { foreach ($skusWithCombinationGoods as $sku) {
if (!empty($sku['is_combination'])) { if (!empty($sku['is_combination'])) {
foreach ($sku['combination_goods'] as $combinationGoods) { foreach ($sku['combination_goods'] as $combinationGoods) {
if (empty($inventoryKeyBySkuIdMap[$combinationGoods["item_id"]])) { if (!isset($inventoryKeyBySkuIdMap[$combinationGoods["item_id"]])) {
//没有盘点到的sku需要在原先的sku库存 //没有盘点到的sku需要在原先的sku库存
$inventoryKeyBySkuIdMap[$combinationGoods["item_id"]] = GoodsSku::query() $inventoryKeyBySkuIdMap[$combinationGoods["item_id"]] = GoodsSku::query()
->where('id', $combinationGoods["item_id"])->pluck('stock')->first() ?? 0; ->where('id', $combinationGoods["item_id"])->pluck('stock')->first() ?? 0;

View File

@ -153,7 +153,7 @@ class SaleDataService
, DB::raw("sum(CASE WHEN b.shipping_status=0 THEN goods_number-already_cancel_number ELSE 0 END) as unshipping_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") , DB::raw("sum(goods_number-already_cancel_number) as goods_total")
, DB::raw("ROUND(sum(goods_amount) / 100,2) as goods_total_amount")) , DB::raw("ROUND(sum(goods_amount) / 100,2) as goods_total_amount"))
->where("business_order_items.created_at", ">", Carbon::now()->subDays(3)->startOfDay()->toDateTimeString()) ->where("business_order_items.created_at", ">", Carbon::now()->startOfDay()->toDateTimeString())
->where("business_order_items.cancel_status", "=", 0) ->where("business_order_items.cancel_status", "=", 0)
->groupBy('external_sku_id')->get()->toArray(); ->groupBy('external_sku_id')->get()->toArray();
$externalSkuIds = collect($orderItems)->pluck("external_sku_id")->toArray(); $externalSkuIds = collect($orderItems)->pluck("external_sku_id")->toArray();

View File

@ -0,0 +1,52 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateBusinessAfterSaleOrders extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('business_after_sale_orders', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('after_sales_biz_sn')->comment('售后单编号');
$table->string('order_sn')->comment('父单编号');
$table->integer('shop_id')->comment('门店id');
$table->integer('after_sales_status')->default(0)->comment('售后单状态
0-未发起售后 1-退款中 2-退款成功 3-待处理 4-拒绝退款 6-(顾客)退货 7-(团长)确认退货 8-(顾客)撤销 9-(系统)关闭');
$table->bigInteger('refund_amount')->default(0)->comment('退款金额');
$table->bigInteger('refund_shipping_amount')->default(0)->comment('用户申请退运费金额');
$table->string('description')->nullable()->comment('描述');
$table->string('reason')->nullable()->comment('原因');
$table->json('sub_extensions')->nullable()->comment('子单信息');
$table->json('image_list')->nullable()->comment('图片列表');
$table->json('return_goods_extension')->nullable()->comment('退款物流信息');
$table->integer('apply_type')->default(0)->comment('售后单类型 0-仅退款 1-退货退款');
$table->string('after_sale_created_at')->nullable()->comment('售后单三方创建时间');
$table->string('after_sale_updated_at')->nullable()->comment('售后单三方更新时间');
$table->unique(["shop_id",'order_sn']);
$table->index('order_sn');
$table->index('after_sales_biz_sn');
$table->index(['after_sales_biz_sn',"apply_type"]);
$table->index('after_sale_created_at');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('business_after_sale_orders');
}
}

View File

@ -631,4 +631,16 @@ return [
'name' => 'gmv统计', 'name' => 'gmv统计',
'parent_id' => 18, 'parent_id' => 18,
], ],
// 订单列表
'PLAT_AFTER_SALE_ORDER_LIST' => [
'id' => 141,
'name' => '售后单列表',
'parent_id' => 12,
'show' => 1,
],
'plat_after_sale_orders.index' => [
'id' => 1411,
'name' => '售后单列表-接口查询',
'parent_id' => 141,
],
]; ];

View File

@ -15,6 +15,7 @@ use App\Http\Controllers\Goods\GoodsCombinationController;
use App\Http\Controllers\Supplier\DailyStockRecordController; use App\Http\Controllers\Supplier\DailyStockRecordController;
use App\Http\Controllers\Supplier\LossRecordController; use App\Http\Controllers\Supplier\LossRecordController;
use App\Http\Controllers\Supplier\PurchaseRecordController; use App\Http\Controllers\Supplier\PurchaseRecordController;
use App\Http\Controllers\Business\BusinessAfterSaleOrderController;
/* /*
|-------------------------------------------------------------------------- |--------------------------------------------------------------------------
@ -90,6 +91,9 @@ Route::middleware(['auth:api', 'check.permissions'])->group(function () {
Route::get('data_center/sale_statistics', [DataCenterController::class, 'saleStatistics'])->name('data_center.sale_statistics'); Route::get('data_center/sale_statistics', [DataCenterController::class, 'saleStatistics'])->name('data_center.sale_statistics');
Route::get('data_center/spu_sale_statistics', [DataCenterController::class, 'spuSaleStatistics'])->name('data_center.spu_sale_statistics'); Route::get('data_center/spu_sale_statistics', [DataCenterController::class, 'spuSaleStatistics'])->name('data_center.spu_sale_statistics');
Route::get('data_center/gmv_statistics', [DataCenterController::class, 'gmvStatistics'])->name('data_center.gmv_statistics'); Route::get('data_center/gmv_statistics', [DataCenterController::class, 'gmvStatistics'])->name('data_center.gmv_statistics');
Route::get('plat_after_sale_orders', [BusinessAfterSaleOrderController::class, 'index'])->name('plat_after_sale_orders.index');
}); });
Route::get('stock/goods_skus', [GoodsSkusController::class, 'stockNum'])->middleware('auth:api'); Route::get('stock/goods_skus', [GoodsSkusController::class, 'stockNum'])->middleware('auth:api');
Route::get('goods/filter/{title}', [GoodsCombinationController::class, 'goodsSkus'])->middleware('auth:api'); Route::get('goods/filter/{title}', [GoodsCombinationController::class, 'goodsSkus'])->middleware('auth:api');

View File

@ -20,12 +20,14 @@ class BusinessOrderUpdateTest extends TestCase
*/ */
public function testBasicTest() public function testBasicTest()
{ {
// $shop = new \App\Models\Shop(); /* $shop = new \App\Models\Shop();
// $shop->id=19; $shop->id = 19;
// $shop->access_token="7e00e77428cf45348cb1ca190dc769670377bd0c"; $shop->plat_id = 1;
// $endTime = DateTimeUtils::getMicroTime(); $shop->name = "test";
// $beginTime = $endTime - 63000; $shop->access_token = "7e00e77428cf45348cb1ca190dc769670377bd0c";
// BusinessFactory::init()->make("快团团")->setShop($shop)->downloadOrdersAndSave($beginTime, $endTime, 'increment'); $endTime = DateTimeUtils::getMicroTime();
$beginTime = $endTime - 2*60*60*1000;
BusinessFactory::init()->make("快团团")->setShop($shop)->downloadAfterSaleOrdersAndSave($beginTime, $endTime, 1);*/
} }
} }