diff --git a/app/Admin/Controllers/OrderController.php b/app/Admin/Controllers/OrderController.php index 4451befd..62f951f3 100644 --- a/app/Admin/Controllers/OrderController.php +++ b/app/Admin/Controllers/OrderController.php @@ -8,8 +8,8 @@ use App\Admin\Actions\Show\OrderCreatePackage; use App\Admin\Actions\Show\OrderPay; use App\Admin\Actions\Show\OrderReduce; use App\Admin\Actions\Show\OrderRemark; +use App\Admin\Renderable\PackageProductSimpleTable; use App\Admin\Repositories\Order; -use App\Constants\OrderStatus; use App\Models\Order as OrderModel; use App\Models\OrderLog; use App\Models\OrderPackage; @@ -200,6 +200,8 @@ class OrderController extends AdminController return bcdiv($value, 100, 2); })->prepend('¥'); $grid->column('quantity'); + $grid->column('remain_quantity'); + $grid->column('product_total_amount')->display(function () { return bcdiv($this->sell_price * $this->quantity, 100, 2); })->prepend('¥'); @@ -220,7 +222,10 @@ class OrderController extends AdminController $packageGrid = Grid::make($packageBuilder, function (Grid $grid) { $grid->column('shipping_company', '物流公司'); $grid->column('shipping_number', '物流单号'); - $grid->column('packageProducts', '包裹商品')->setHeaderAttributes(['style' => 'color:#5b69bc']); + $grid->column('packageProducts', '包裹商品')->display('包裹商品')->modal(function ($modal) { + $modal->title('商品'); + return PackageProductSimpleTable::make(['id'=>$this->id]); + })->setHeaderAttributes(['style' => 'color:#5b69bc']); $grid->column('created_at', '发货时间'); $grid->column('status', '包裹状态'); $grid->model()->orderBy('created_at', 'desc'); @@ -246,7 +251,8 @@ class OrderController extends AdminController $column->row(Box::make('订单商品', $productGrid)); $packagesBox = Box::make('发货包裹', $packageGrid); //显示发货动作 - if (in_array(OrderModel::findOrFail($id)->orderStatus, [OrderStatus::PAID, OrderStatus::SHIPPING])) { + $order = OrderModel::findOrFail($id); + if ($order->isPaid() || $order->isShipping()) { $packagesBox->tool(new OrderCreatePackage(null, $id)); } diff --git a/app/Admin/Controllers/OrderPackageController.php b/app/Admin/Controllers/OrderPackageController.php index 9080de55..eb96a0d7 100644 --- a/app/Admin/Controllers/OrderPackageController.php +++ b/app/Admin/Controllers/OrderPackageController.php @@ -2,6 +2,7 @@ namespace App\Admin\Controllers; +use App\Admin\Renderable\PackageProductSimpleTable; use App\Admin\Repositories\OrderPackage; use App\Models\Order; use Dcat\Admin\Admin; @@ -28,25 +29,19 @@ class OrderPackageController extends AdminController $grid->column('order.consignee_telephone'); $grid->column('order.consignee_zone'); $grid->column('order.consignee_address'); - $grid->column('packageProduct'); + $grid->column('packageProduct')->display('包裹商品')->modal(function ($modal) { + $modal->title('商品'); + return PackageProductSimpleTable::make(['id'=>$this->id]); + })->setHeaderAttributes(['style' => 'color:#5b69bc']); $grid->column('shipping_company'); $grid->column('shipping_number'); - $grid->column('is_failed') - ->if(function () { - return Admin::user()->can('dcat.admin.order_packages.failed'); - }) - ->then(function (Column $column) { - $column->switch(); - }) - ->else(function (Column $column) { - $column->bool(); - }); + $grid->column('is_failed')->bool(); $grid->column('status'); // $grid->column('remarks'); $grid->column('created_at')->sortable(); // $grid->column('updated_at'); - $grid->model()->orderBy('ceated_at', 'desc'); + $grid->model()->orderBy('created_at', 'desc'); /** 操作 **/ //新增 // if (Admin::user()->can('dcat.admin.order_packages.create')) { diff --git a/app/Admin/Forms/OrderPackage.php b/app/Admin/Forms/OrderPackage.php index 688ceecb..3dfd6158 100644 --- a/app/Admin/Forms/OrderPackage.php +++ b/app/Admin/Forms/OrderPackage.php @@ -2,10 +2,14 @@ namespace App\Admin\Forms; +use App\Exceptions\BizException; use App\Models\Order; +use App\Services\OrderService; use Dcat\Admin\Contracts\LazyRenderable; use Dcat\Admin\Traits\LazyWidget; use Dcat\Admin\Widgets\Form; +use Illuminate\Support\Facades\DB; +use Throwable; class OrderPackage extends Form implements LazyRenderable { @@ -20,7 +24,7 @@ class OrderPackage extends Form implements LazyRenderable */ protected function authorize($user): bool { - return $user->can('dcat.admin.product_spus.add_sku'); + return $user->can('dcat.admin.orders.create_package'); } /** @@ -32,7 +36,23 @@ class OrderPackage extends Form implements LazyRenderable */ public function handle(array $input) { - dd($input); + $orderId = $this->payload['id'] ?? 0; + + $order = Order::findOrFail($orderId); + try { + DB::beginTransaction(); + $orderService = new OrderService(); + $orderService->createPackage($order, $input); + DB::commit(); + } catch (BizException $e) { + DB::rollBack(); + report($e); + throw new BizException('操作失败:'.$e->getMessage()); + } catch (Throwable $th) { + DB::rollBack(); + report($th); + throw new BizException('操作失败:'.$th->getMessage()); + } return $this->response() ->success(__('admin.update_succeeded')) ->refresh(); @@ -46,13 +66,12 @@ class OrderPackage extends Form implements LazyRenderable $orderId = $this->payload['id'] ?? 0; $order = Order::findOrFail($orderId); - $this->hidden('order_id'); - $this->text('shipping_company'); - $this->text('shipping_number'); + $this->text('shipping_company')->required(); + $this->text('shipping_number')->required(); $this->hasMany('packages', function (Form $form) use ($order) { $form->select('order_product_id')->options($order->products()->where('after_sale_state', '<>', 1)->pluck('name', 'id')); - $form->number('quantity')->min(0); + $form->number('quantity')->min(1); }); $this->disableResetButton(); diff --git a/app/Admin/Renderable/PackageProductSimpleTable.php b/app/Admin/Renderable/PackageProductSimpleTable.php new file mode 100644 index 00000000..44f762c2 --- /dev/null +++ b/app/Admin/Renderable/PackageProductSimpleTable.php @@ -0,0 +1,26 @@ +payload['id']??0; + $builder = OrderPackageProduct::query(); + $builder->with(['orderProduct'])->where('order_package_id', $packageId); + return Grid::make($builder, function (Grid $grid) { + $grid->column('orderProduct.name', '商品名称'); + $grid->column('orderProduct.cover', '商品图')->image(50, 50); + $grid->column('orderProduct.sell_price', '价格')->display(function ($value) { + return bcdiv($value, 100, 2); + })->prepend('¥'); + $grid->column('quantity', '发货数量'); + $grid->disableActions(); + }); + } +} diff --git a/app/Models/OrderPackage.php b/app/Models/OrderPackage.php index f8df8621..e949d973 100644 --- a/app/Models/OrderPackage.php +++ b/app/Models/OrderPackage.php @@ -2,12 +2,14 @@ namespace App\Models; +use Dcat\Admin\Traits\HasDateTimeFormatter; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; class OrderPackage extends Model { use HasFactory; + use HasDateTimeFormatter; protected $casts = [ 'is_failed' => 'bool', @@ -26,7 +28,6 @@ class OrderPackage extends Model /** * 货运单商品 * - * @return void */ public function packageProducts() { diff --git a/app/Models/OrderPackageProduct.php b/app/Models/OrderPackageProduct.php index 9016dc89..68c6ada8 100644 --- a/app/Models/OrderPackageProduct.php +++ b/app/Models/OrderPackageProduct.php @@ -2,12 +2,19 @@ namespace App\Models; +use Dcat\Admin\Traits\HasDateTimeFormatter; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; class OrderPackageProduct extends Model { use HasFactory; + use HasDateTimeFormatter; + + protected $fillable = [ + 'order_product_id', + 'quantity', + ]; /** * 订单商品 @@ -16,6 +23,6 @@ class OrderPackageProduct extends Model */ public function orderProduct() { - $this->belongsTo(OrderProduct::class, 'order_product_id'); + return $this->belongsTo(OrderProduct::class, 'order_product_id'); } } diff --git a/app/Services/OrderService.php b/app/Services/OrderService.php index 8a0d55c3..0b49e46d 100644 --- a/app/Services/OrderService.php +++ b/app/Services/OrderService.php @@ -11,6 +11,8 @@ use App\Helpers\Numeric; use App\Helpers\Order as OrderHelper; use App\Models\Order; use App\Models\OrderLog; +use App\Models\OrderPackage; +use App\Models\OrderPackageProduct; use App\Models\OrderProduct; use App\Models\ProductSku; use App\Models\ShippingAddress; @@ -650,4 +652,68 @@ class OrderService 'content'=> '修改订单收货信息原收货信息:'.$oldOrderConsignee, ]); } + + /** + * 创建订单发货单 + * + * @return void + */ + public function createPackage(Order $order, array $params) + { + //合并同样商品,并检验是否能发货 + $packageProducts = []; + if (count($params['packages']) <= 0) { + throw new BizException('请选择发货商品'); + } + foreach ($params['packages'] as $item) { + if ($item['quantity'] < 1) { + throw new BizException('发货数量不能小于1'); + } + if (isset($packageProducts[$item['order_product_id']])) { + $packageProducts[$item['order_product_id']]['quantity'] += $item['quantity']; + } else { + $packageProducts[$item['order_product_id']] = [ + 'order_product_id'=> $item['order_product_id'], + 'quantity' =>$item['quantity'], + ]; + } + } + foreach ($packageProducts as $product) { + $_orderProduct = OrderProduct::where('after_sale_state', '<>', 1) + ->where('remain_quantity', '>=', $product['quantity']) + ->find($product['order_product_id']); + if (is_null($_orderProduct)) { + throw new BizException('发货数量不能大于剩余数量'); + } + $_orderProduct->decrement('remain_quantity', $product['quantity']); + } + + //创建发货单数据 + $package = new OrderPackage(); + $package->order_id = $order->id; + $package->consignee_name = $order->consignee_name; + $package->consignee_telephone = $order->consignee_telephone; + $package->consignee_zone = $order->consignee_zone; + $package->consignee_address = $order->consignee_address; + + $package->shipping_company = $params['shipping_company']; + $package->shipping_number = $params['shipping_number']; + //保存发货单 + $package->save(); + //保存发货单商品 + $package->packageProducts()->saveMany(array_map(function ($value) { + return new OrderPackageProduct($value); + }, $packageProducts)); + + //更新订单状态 + if (!OrderProduct::where('order_id', $order->id)->where('remain_quantity', '>', 0)->exists()) { + $order->update([ + 'shipping_state'=>Order::SHIPPING_STATE_PROCESSED, + ]); + } elseif ($order->shipping_state == Order::SHIPPING_STATE_PENDING) { + $order->update([ + 'shipping_state'=>Order::SHIPPING_STATE_PROCESSING, + ]); + } + } } diff --git a/resources/lang/zh_CN/order.php b/resources/lang/zh_CN/order.php index 47b53bd3..9919dcbc 100644 --- a/resources/lang/zh_CN/order.php +++ b/resources/lang/zh_CN/order.php @@ -48,6 +48,7 @@ return [ 'packages'=>'包裹内容', 'order_product_id' =>'商品', 'quantity'=>'数量', + 'remain_quantity'=>'剩余', ], 'options' => [ ],