{order_product_id, quantity}} * @param OrderPackage $package * * @return OrderPackage $package */ public function createPackage(Order $order, array $params, ?OrderPackage $package = null) { //合并同样商品,并检验是否能发货 $packageProducts = []; //待发货,发货中的可以发货 if (!($order->isWaitShipping() || $order->isShipping())) { throw new BizException('订单状态异常,无法发货'); } foreach ($params['packages'] as $item) { if (isset($item['_remove_']) && $item['_remove_']) {//如果是已被移除选项则直接移除 continue; } 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'], ]; } } if (count($packageProducts) <= 0) { throw new BizException('请选择发货商品'); } foreach ($packageProducts as $product) { $_orderProduct = OrderProduct::where('order_id', $order->id) ->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']); } if (!$package) { //创建发货单数据 $package = new OrderPackage(); $package->order_id = $order->id; $package->user_id = $order->user_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_code = Arr::get(Kuaidi100Service::$codeArr, $package->shipping_company, ''); $package->shipping_number = $params['shipping_number']; //保存发货单 $package->save(); if ($package->shipping_code && app_settings('kuaidi100.is_use')) { $kuaidi100Service = new Kuaidi100Service(); $kuaidi100Service->poll($package->shipping_number, $package->shipping_code, $package->consignee_telephone); } } else { //更新现有的包裹商品 foreach ($packageProducts as $key => $packageProduct) { //如果包裹商品已存在则更新 $_package_product = OrderPackageProduct::where([ 'order_package_id'=>$package->id, 'order_product_id'=>$packageProduct['order_product_id'], ])->first(); if ($_package_product) { $_package_product->increment('quantity', $packageProduct['quantity']); unset($packageProducts[$key]); } } } //保存新增发货单商品 if (count($packageProducts) > 0) { OrderPackageProduct::insert(array_map(function ($value) use ($package) { return array_merge($value, [ 'order_package_id' => $package->id, 'created_at' => $package->created_at, 'updated_at' => $package->created_at, ]); }, $packageProducts)); } //更新订单状态 if (!OrderProduct::where('order_id', $order->id)->where('remain_quantity', '>', 0)->exists()) { $order->update([ 'shipping_state'=> Order::SHIPPING_STATE_PROCESSED, // 订单自动完成时间 'auto_complete_at' => now()->addDays(app_settings('app.order_auto_complete_days', 7)), ]); } elseif ($order->shipping_state == Order::SHIPPING_STATE_PENDING) { $order->update([ 'shipping_state'=>Order::SHIPPING_STATE_PROCESSING, ]); } return $package; } /** * 作废发货单 * * @param OrderPackage $package * @return void */ public function failPackage(OrderPackage $package) { if ($package->is_failed) { throw new BizException('已作废的货运单不能需要再作废了'); } //如果订单完成了,不能作废货运单 if ($package->order->isCompleted()) { throw new BizException('订单已完成,无法作废该货运单'); } $changeQuantity = []; foreach ($package->packageProducts as $packageProduct) { if (isset($changeQuantity[$packageProduct->order_product_id])) { $changeQuantity[$packageProduct->order_product_id] += $packageProduct->quantity; } else { $changeQuantity[$packageProduct->order_product_id] = $packageProduct->quantity; } } //作废货运单,恢复订单商品发货数量 foreach ($package->orderProducts as $orderProduct) { $orderProduct->increment('remain_quantity', $changeQuantity[$orderProduct->id]); } $package->update([ 'is_failed'=> true, ]); //更新订单状态:如果订单是发货完成,则恢复为发货中 if ($package->order->isShipped()) { $package->order()->update([ 'shipping_state'=>Order::SHIPPING_STATE_PROCESSING, ]); } } /** * 订单全部发货 * * @param Order $order * * @return OrderPackage $package */ public function createAll(Order $order, $params = []) { $shipping_company = data_get($params, 'shipping_company', '自提'); $shipping_number = data_get($params, 'shipping_number', '0'); $products = $order->products->map(function ($item) { return [ 'order_product_id' => $item->id, 'quantity' => $item->quantity ]; }); return $this->createPackage($order, [ 'shipping_company' => $shipping_company, 'shipping_number' => $shipping_number, 'packages' => $products, ]); } }