pre
parent
ca9b805cb6
commit
3005f25e1d
|
|
@ -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'),
|
||||
|
|
|
|||
|
|
@ -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 . '<span class="label bg-danger">管理员</span>';
|
||||
} else if ($v instanceof \App\Models\User) {
|
||||
return $v->phone . '<span class="label bg-primary">用户</span>';
|
||||
}
|
||||
|
||||
return '未知身份';
|
||||
});
|
||||
$grid->column('remarks', '备注');
|
||||
$grid->column('created_at', '操作时间');
|
||||
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -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([
|
||||
|
|
|
|||
|
|
@ -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
|
||||
]);
|
||||
}
|
||||
}
|
||||
// 发货
|
||||
|
|
|
|||
|
|
@ -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');
|
||||
}
|
||||
|
||||
/**
|
||||
* 使用的优惠券
|
||||
*
|
||||
|
|
|
|||
|
|
@ -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');
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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
|
||||
*
|
||||
|
|
|
|||
|
|
@ -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('来源');
|
||||
|
|
|
|||
Loading…
Reference in New Issue