From 3005f25e1da38770dac22ab4a34db048a4c304d7 Mon Sep 17 00:00:00 2001
From: panliang <1163816051@qq.com>
Date: Wed, 18 May 2022 17:08:14 +0800
Subject: [PATCH] pre
---
.../Controllers/Store/StockController.php | 3 +-
.../Controllers/Store/StoreController.php | 12 +-
app/Admin/Forms/OrderPackage.php | 36 +++++-
app/Admin/Services/OrderPackageService.php | 7 +-
.../Controllers/Order/OrderPreController.php | 18 +--
.../Controllers/Order/UnlineController.php | 28 ++++-
app/Models/Order.php | 9 ++
app/Models/Store/Administrator.php | 2 +-
app/Models/Store/StockLog.php | 6 +-
app/Services/OrderService.php | 109 ++++++++++++++++--
.../2022_05_06_161251_create_stores_table.php | 2 +-
11 files changed, 194 insertions(+), 38 deletions(-)
diff --git a/app/Admin/Controllers/Store/StockController.php b/app/Admin/Controllers/Store/StockController.php
index e78c1e96..3d9beba0 100644
--- a/app/Admin/Controllers/Store/StockController.php
+++ b/app/Admin/Controllers/Store/StockController.php
@@ -58,7 +58,8 @@ class StockController extends Controller
'amount' => $product->pivot->amount + $amount
]);
$store->stockLogs()->create([
- 'administrator_id' => $administrator->id,
+ 'operator_type' => get_class($administrator),
+ 'operator_id' => $administrator->id,
'amount' => $request->input('amount'),
'product_sku_id' => $product->id,
'remarks' => $request->input('remarks'),
diff --git a/app/Admin/Controllers/Store/StoreController.php b/app/Admin/Controllers/Store/StoreController.php
index ae0c94d9..32d6026c 100644
--- a/app/Admin/Controllers/Store/StoreController.php
+++ b/app/Admin/Controllers/Store/StoreController.php
@@ -182,7 +182,7 @@ class StoreController extends AdminController
protected function gridStock($id)
{
- $grid = new Grid(StockLog::with(['productSku', 'administrator', 'source', 'tag']));
+ $grid = new Grid(StockLog::with(['productSku', 'operator', 'source', 'tag']));
$grid->model()->where('store_id', $id)->orderBy('created_at', 'desc');
@@ -191,7 +191,15 @@ class StoreController extends AdminController
$grid->column('productSku.name', '商品');
$grid->column('amount', '库存');
$grid->column('tag.name', '类目');
- $grid->column('administrator.name', '操作人');
+ $grid->column('operator', '操作人')->display(function ($v) {
+ if ($v instanceof \App\Models\Admin\Administrator) {
+ return $v->name . '管理员';
+ } else if ($v instanceof \App\Models\User) {
+ return $v->phone . '用户';
+ }
+
+ return '未知身份';
+ });
$grid->column('remarks', '备注');
$grid->column('created_at', '操作时间');
diff --git a/app/Admin/Forms/OrderPackage.php b/app/Admin/Forms/OrderPackage.php
index a491e16a..392bdf52 100644
--- a/app/Admin/Forms/OrderPackage.php
+++ b/app/Admin/Forms/OrderPackage.php
@@ -4,12 +4,13 @@ namespace App\Admin\Forms;
use App\Admin\Services\OrderPackageService;
use App\Exceptions\BizException;
-use App\Models\Order;
+use App\Models\{Order, Tag};
use Dcat\Admin\Contracts\LazyRenderable;
use Dcat\Admin\Traits\LazyWidget;
use Dcat\Admin\Widgets\Form;
use Illuminate\Support\Facades\DB;
use Throwable;
+use Dcat\Admin\Admin;
class OrderPackage extends Form implements LazyRenderable
{
@@ -43,6 +44,39 @@ class OrderPackage extends Form implements LazyRenderable
DB::beginTransaction();
$orderPackageService = new OrderPackageService();
$orderPackageService->createPackage($order, $input);
+ // 店铺发货, 添加出库记录
+ if ($order->store) {
+ $packageProducts = $input['packages'];
+ $operator = Admin::user();
+ $store = $order->store;
+ $tag = Tag::firstOrCreate([
+ 'type' => Tag::TYPE_STORE_STOCK,
+ 'name' => '发货'
+ ]);
+ foreach($packageProducts as $item) {
+ $order_product = $order->products()->findOrFail($item['order_product_id']);
+ $amount = $item['quantity'];
+ $sku_id = $order_product->sku_id;
+ $product = $store->productSkus()->findOrFail($sku_id);
+ if ($product->pivot->amount - $amount < 0) {
+ throw new BizException('店铺的 ' . $product->name .' 库存不足');
+ }
+
+ $store->productSkus()->updateExistingPivot($product->id, [
+ 'amount' => $product->pivot->amount - $amount
+ ]);
+ $store->stockLogs()->create([
+ 'operator_type' => get_class($operator),
+ 'operator_id' => $operator->id,
+ 'source_type' => Order::class,
+ 'source_id' => $order->id,
+ 'amount' => $amount,
+ 'product_sku_id' => $product->id,
+ 'remarks' => '后台发货',
+ 'tag_id' => $tag->id
+ ]);
+ }
+ }
DB::commit();
} catch (BizException $e) {
DB::rollBack();
diff --git a/app/Admin/Services/OrderPackageService.php b/app/Admin/Services/OrderPackageService.php
index 48a6e7ac..c43bfde8 100644
--- a/app/Admin/Services/OrderPackageService.php
+++ b/app/Admin/Services/OrderPackageService.php
@@ -6,14 +6,19 @@ use App\Exceptions\BizException;
use App\Models\Order;
use App\Models\OrderPackage;
use App\Models\OrderPackageProduct;
-use App\Models\OrderProduct;
+use App\Models\{OrderProduct, Tag};
use App\Services\Kuaidi100Service;
use Illuminate\Support\Arr;
+use Dcat\Admin\Admin;
class OrderPackageService
{
/**
* 创建订单发货单
+ *
+ * @param Order $order
+ * @param array $params {shipping_company, shipping_number, packages => {order_product_id, quantity}}
+ * @param OrderPackage $package
*
* @return void
*/
diff --git a/app/Endpoint/Api/Http/Controllers/Order/OrderPreController.php b/app/Endpoint/Api/Http/Controllers/Order/OrderPreController.php
index 5bfd67e2..9bce38ed 100644
--- a/app/Endpoint/Api/Http/Controllers/Order/OrderPreController.php
+++ b/app/Endpoint/Api/Http/Controllers/Order/OrderPreController.php
@@ -104,26 +104,10 @@ class OrderPreController extends Controller
$order_pre = OrderPre::findOrFail($id);
$user = $request->user();
- $products = [];
- foreach($order_pre->products as $item) {
- array_push($products, [
- 'sku' => ProductSku::findOrFail($item['sku_id']),
- 'quantity' => $item['quantity']
- ]);
- }
- $coupon_id = data_get($order_pre, 'others.coupon_id');
- $note = data_get($order_pre, 'others.note');
-
try {
DB::beginTransaction();
$service = new OrderService();
- $order = $service->createOrder($user, $products, null, $coupon_id, $note);
- $order->update([
- 'store_id' => $order_pre->store_id,
- 'inviter_id' => $order_pre->user_id,
- 'source_type' => OrderPre::class,
- 'source_id' => $order_pre->id,
- ]);
+ $order = $service->createOrderByPre($user, $order_pre);
DB::commit();
return response()->json([
diff --git a/app/Endpoint/Api/Http/Controllers/Order/UnlineController.php b/app/Endpoint/Api/Http/Controllers/Order/UnlineController.php
index bea873fe..3b172c2b 100644
--- a/app/Endpoint/Api/Http/Controllers/Order/UnlineController.php
+++ b/app/Endpoint/Api/Http/Controllers/Order/UnlineController.php
@@ -4,7 +4,7 @@ namespace App\Endpoint\Api\Http\Controllers\Order;
use App\Endpoint\Api\Http\Controllers\Controller;
use App\Helpers\Paginator;
-use App\Models\{Order, OrderPre};
+use App\Models\{Order, OrderPre, Tag};
use App\Endpoint\Api\Http\Resources\{OrderResource, OrderResourceCollection};
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
@@ -53,11 +53,16 @@ class UnlineController extends Controller
'products.required' => '发货商品必填',
]);
$order = Order::where('source_type', OrderPre::class)->findOrFail($id);
+ $store = $order->store;
// 订单来源为 帮客户下单 order_pres
try {
DB::beginTransaction();
$order_products = $order->products;
+ $tag = Tag::firstOrCreate([
+ 'type' => Tag::TYPE_STORE_STOCK,
+ 'name' => '提货'
+ ]);
// 根据 order_pres 发货数量, 自动发货
$service_package = new \App\Admin\Services\OrderPackageService();
// order_product_id: 订单商品ID, quantity: 发货数量
@@ -69,6 +74,27 @@ class UnlineController extends Controller
'order_product_id' => $order_product->id,
'quantity' => $item['amount'],
]);
+ // 添加出库记录
+ $amount = $item['amount'];
+ $sku_id = $order_product->sku_id;
+ $product = $store->productSkus()->findOrFail($sku_id);
+ if ($product->pivot->amount - $amount < 0) {
+ throw new BizException('店铺的 ' . $product->name .' 库存不足');
+ }
+
+ $store->productSkus()->updateExistingPivot($product->id, [
+ 'amount' => $product->pivot->amount - $amount
+ ]);
+ $store->stockLogs()->create([
+ 'operator_type' => get_class($user),
+ 'operator_id' => $user->id,
+ 'source_type' => Order::class,
+ 'source_id' => $order->id,
+ 'amount' => $amount,
+ 'product_sku_id' => $product->id,
+ 'remarks' => '店铺提货',
+ 'tag_id' => $tag->id
+ ]);
}
}
// 发货
diff --git a/app/Models/Order.php b/app/Models/Order.php
index c2bf1bde..3ad34e92 100644
--- a/app/Models/Order.php
+++ b/app/Models/Order.php
@@ -7,6 +7,7 @@ use App\Enums\PayWay;
use Dcat\Admin\Traits\HasDateTimeFormatter;
use EloquentFilter\Filterable;
use Illuminate\Database\Eloquent\Model;
+use App\Models\Store\Store;
class Order extends Model
{
@@ -141,6 +142,14 @@ class Order extends Model
return $this->belongsTo(UserInfo::class, 'user_id', 'user_id');
}
+ /**
+ * 门店
+ */
+ public function store()
+ {
+ return $this->belongsTo(Store::class, 'store_id');
+ }
+
/**
* 使用的优惠券
*
diff --git a/app/Models/Store/Administrator.php b/app/Models/Store/Administrator.php
index 359d81ae..9a6ff1ff 100644
--- a/app/Models/Store/Administrator.php
+++ b/app/Models/Store/Administrator.php
@@ -20,6 +20,6 @@ class Administrator extends Model
public function administrator()
{
- return $this->belongsTo(\Dcat\Admin\Models\Administrator::class, 'administrator_id');
+ return $this->belongsTo(\App\Models\Admin\Administrator::class, 'administrator_id');
}
}
diff --git a/app/Models/Store/StockLog.php b/app/Models/Store/StockLog.php
index 68c71271..aa49c18a 100644
--- a/app/Models/Store/StockLog.php
+++ b/app/Models/Store/StockLog.php
@@ -12,7 +12,7 @@ class StockLog extends Model
protected $table = 'store_stock_logs';
- protected $fillable = ['administrator_id', 'amount', 'product_sku_id', 'remarks', 'source_id', 'source_type', 'store_id', 'tag_id'];
+ protected $fillable = ['operator_type', 'operator_id', 'amount', 'product_sku_id', 'remarks', 'source_id', 'source_type', 'store_id', 'tag_id'];
public function store()
{
@@ -24,9 +24,9 @@ class StockLog extends Model
return $this->belongsTo(\App\Models\ProductSku::class, 'product_sku_id');
}
- public function administrator()
+ public function operator()
{
- return $this->belongsTo(\Dcat\Admin\Models\Administrator::class, 'administrator_id');
+ return $this->morphTo();
}
public function source()
diff --git a/app/Services/OrderService.php b/app/Services/OrderService.php
index e01712e0..5eb4fc3a 100644
--- a/app/Services/OrderService.php
+++ b/app/Services/OrderService.php
@@ -20,7 +20,8 @@ use App\Models\ProductPartSku;
use App\Models\ProductSku;
use App\Models\ShippingAddress;
use App\Models\SocialiteUser;
-use App\Models\User;
+use App\Models\{User, OrderPre, Tag};
+use App\Models\Store\Store;
use App\Models\UserCoupon;
use App\Services\Payment\WxpayService;
use Illuminate\Database\Eloquent\Builder;
@@ -110,13 +111,11 @@ class OrderService
?string $note = null,
?BargainOrder $bargainOrder = null,
): Order {
- if ($shippingAddressId) {
- foreach ($products as $product) {
- $sku = $product['sku'];
-
- if ($product['quantity'] > $sku->saleable_stock) {
- throw new BizException('商品库存不足');
- }
+ foreach ($products as $product) {
+ $sku = $product['sku'];
+
+ if ($product['quantity'] > $sku->saleable_stock) {
+ throw new BizException('商品库存不足');
}
}
@@ -168,6 +167,70 @@ class OrderService
return $order;
}
+ /**
+ * 添加店铺订单
+ *
+ */
+ public function createOrderByPre(User $user, OrderPre $order_pre)
+ {
+ $products = [];
+ foreach($order_pre->products as $item) {
+ array_push($products, [
+ 'sku' => ProductSku::findOrFail($item['sku_id']),
+ 'quantity' => $item['quantity']
+ ]);
+ }
+
+ $coupon_id = data_get($order_pre, 'others.coupon_id');
+ $note = data_get($order_pre, 'others.note');
+
+ // 优惠券
+ $coupon = null;
+
+ if ($coupon_id) {
+ $coupon = $user->coupons()->onlyAvailable()->lockForUpdate()->findOrFail($coupon_id);
+ }
+
+ $mapProducts = $this->mapProducts($user, $products, $coupon);
+
+ list(
+ $productsTotalAmount,
+ $vipDiscountAmount,
+ $couponDiscountAmount,
+ $salesValue
+ ) = $this->calculateFees($mapProducts);
+
+ $order = $this->storeOrder(
+ $user,
+ $productsTotalAmount,
+ $couponDiscountAmount,
+ $vipDiscountAmount,
+ 0,
+ $salesValue,
+ null,
+ $note,
+ $coupon
+ );
+ $order->update([
+ 'store_id' => $order_pre->store_id,
+ 'inviter_id' => $order_pre->user_id,
+ 'source_type' => OrderPre::class,
+ 'source_id' => $order_pre->id,
+ ]);
+ $this->storeOrderProducts($order, $mapProducts);
+
+ // 将优惠券标记为已使用
+ $coupon?->markAsUse();
+
+ if ($order->total_amount === 0) {
+ $this->pay($order, PayWay::Balance);
+
+ $order->refresh();
+ }
+
+ return $order;
+ }
+
/**
* 保存订单
*
@@ -284,7 +347,9 @@ class OrderService
];
// 扣除商品库存
- $this->deductProduct($sku, $qty);
+ if (!$order->store_id) {
+ $this->deductProduct($sku, $qty);
+ }
}
//根据订单参加的活动添加赠品;
$gifts = $this->activityGifts($order, $orderProducts);
@@ -323,6 +388,30 @@ class OrderService
// } while (true);
}
+ /**
+ * 从门店中扣除商品库存
+ */
+ protected function deductProductFromStore(Store $store, ProductSku $sku, int $amount)
+ {
+ $sku = $store->productSkus()->findOrFail($sku->id);
+
+ // 添加出库记录
+ $tag = Tag::firstOrCreate([
+ 'type' => Tag::TYPE_STORE_STOCK,
+ 'name' => '下单出库'
+ ]);
+ $store->stockLogs()->create([
+ 'amount' => 0-$amount,
+ 'product_sku_id' => $sku->id,
+ 'remarks' => '购买',
+ 'tag_id' => $tag->id
+ ]);
+
+ $store->productSkus()->updateExistingPivot($sku->id, [
+ 'amount' => $sku->pivot->amount - $amount
+ ]);
+ }
+
/**
* 扣出商品的赠品
*
@@ -691,7 +780,7 @@ class OrderService
* 准备商品信息
*
* @param \App\Models\User $user
- * @param array $products
+ * @param array $products {sku: App\Models\ProductSku, quantity: 数量}
* @param \App\Models\UserCoupon|null $coupon
* @return array
*
diff --git a/database/migrations/2022_05_06_161251_create_stores_table.php b/database/migrations/2022_05_06_161251_create_stores_table.php
index 3bfd98f8..cd381a19 100644
--- a/database/migrations/2022_05_06_161251_create_stores_table.php
+++ b/database/migrations/2022_05_06_161251_create_stores_table.php
@@ -43,7 +43,7 @@ class CreateStoresTable extends Migration
$table->unsignedBigInteger('product_sku_id');
$table->integer('amount')->comment('库存变更数量(正/负值)');
$table->unsignedBigInteger('tag_id')->comment('变更类目(tags.id)');
- $table->unsignedBigInteger('administrator_id')->nullable()->comment('操作管理员');
+ $table->nullableMorphs('operator');
$table->string('remarks')->nullable()->comment('备注');
$table->string('source_type')->nullable()->comment('来源');
$table->unsignedBigInteger('source_id')->nullable()->comment('来源');