getOrderData(); $t = \Yii::$app->db->beginTransaction(); try { // 整理订单数据 $goodsList = $this->handleData($orderList); if(empty($goodsList)){ $t->rollBack(); return ['code'=>1,'msg'=>'没有可生成备货单的订单']; } // 生成备货单 与 备货单订单表 以及 备货单商品表 $inventoryId = $this->createInventory($orderList,$goodsList); // 生成分拣单 $this->createSorting($orderList,$inventoryId); $t->commit(); return [ 'code' => 0, 'msg' => '备货单已生成' ]; } catch (\Throwable $e) { $t->rollBack(); \Yii::error('--------create-inventory-error---- ' . $this->store_id . ' ----auto-execute-error--------' . $e->getMessage() . $e->getFile() . $e->getLine()); return [ 'code' => 0, 'msg' => $e->getMessage() ]; } } /** * 获取备货单列表 * @return array * @author: hankaige * @Time: 2024/3/27 11:13 */ public function getInventoryList() { $query = InventiryList::find()->where([ 'store_id' => $this->store_id, 'is_delete' => 0 ])->orderBy('id desc'); $result = pagination_make($query); foreach ($result['list'] as &$value) { $value['created_at'] = date('Y-m-d H:i:s',$value['created_at']); } return ['code'=>0,'data'=>$result]; } /** * 备货单详情 * @return array * @author: hankaige * @Time: 2024/3/27 11:23 */ public function getInventoryDetail() { $query = InventoryOrderGoods::find()->with(['goods'])->where([ 'inventory_id'=>$this->id, 'is_delete'=>0 ])->orderBy('id desc'); $result['list'] = $query->asArray()->all(); foreach ($result['list'] as &$value) { $value['created_at'] = date('Y-m-d H:i:s',$value['created_at']); $value['attr'] = json_decode($value['attr'],true); } return ['code'=>0,'data'=>$result]; } /** * 分拣单列表 * @return array * @author: hankaige * @Time: 2024/3/27 11:30 */ public function getSortingList() { $query = SortingList::find()->with(['md','driver'])->where([ 'store_id'=>$this->store_id, 'is_delete'=>0, 'inventory_id' => $this->inventory_id ])->orderBy('id desc'); if(!empty($thid->md_id)){ $query->andWhere(['md_id'=>$this->md_id]); } switch($this->status){ case 1: $query->andWhere(['driver_id'=>0]); break; case 2: $query->andWhere(['!=','driver_id',0]); break; default: break; } if(!empty($this->md_id)){ $query->andWhere(['md_id'=>$this->md_id]); } $result = pagination_make($query); foreach ($result['list'] as &$value) { $value['created_at'] = date('Y-m-d H:i:s',$value['created_at']); $province = District::findOne($value['md']['province']); $city = District::findOne($value['md']['city']); $district = District::findOne($value['md']['district']); if ($province && $city && $district) { $value['md']['detail_address'] = $province->name . $city->name . $district->name . $value['md']['detail_address']; } } return ['code'=>0,'data'=>$result]; } /** * 获取分拣单详情 * @return array * @author: hankaige * @Time: 2024/3/27 11:30 */ public function getSortingDetail() { $query = SortingOrderGoods::find()->with(['goods'])->where([ 'sorting_id'=>$this->id, 'is_delete'=>0 ])->orderBy('id desc'); $result = pagination_make($query,TRUE); foreach ($result['list'] as &$value) { $value['created_at'] = date('Y-m-d H:i:s',$value['created_at']); $value['attr'] = json_decode($value['attr'],true); } return ['code'=>0,'data'=>$result]; } /** * 获取备货单的所有配送单数据 * @return array * @author: hankaige * @Time: 2024/3/28 15:18 */ public function getSortingDetailAll() { $sortingList = SortingList::find()->with(['md','driver'])->where([ 'store_id'=>$this->store_id, 'is_delete'=>0, 'inventory_id' => $this->id ])->asArray()->all(); foreach($sortingList as &$item){ $detail = SortingOrderGoods::find()->with(['goods'])->where([ 'sorting_id'=>$item['id'], 'is_delete'=>0 ])->asArray()->all(); foreach ($detail as &$value) { $value['created_at'] = date('Y-m-d H:i:s',$value['created_at']); $value['attr'] = json_decode($value['attr'],true); } $item['detail'] = $detail; $province = District::findOne($item['md']['province']); $city = District::findOne($item['md']['city']); $district = District::findOne($item['md']['district']); if ($province && $city && $district) { $item['md']['detail_address'] = $province->name . $city->name . $district->name . $item['md']['detail_address']; } } return ['code'=>0,'data'=>$sortingList]; } /** * 设置配送员 * @return array * @author: hankaige * @Time: 2024/3/28 15:18 */ public function setDriver() { SortingList::updateAll(['driver_id'=>$this->driver_id],[ 'store_id'=>$this->store_id, 'is_delete'=>0, 'id' => $this->sorting_id ]); return ['code'=>0,'msg'=>'设置成功']; } public function printTicket() { $sortingList = SortingList::find()->with(['md','driver','order'])->where([ 'store_id'=>$this->store_id, 'is_delete'=>0, 'inventory_id' => $this->inventory_id ])->asArray()->all(); foreach ($sortingList as &$item){ $item['created_at'] = date('Y-m-d H:i:s',$item['created_at']); $province = District::findOne($item['md']['province']); $city = District::findOne($item['md']['city']); $district = District::findOne($item['md']['district']); if ($province && $city && $district) { $item['md']['detail_address'] = $province->name . $city->name . $district->name . $item['md']['detail_address']; } } return ['code'=>0,'data'=>$sortingList]; } /** * 根据搜索条件获取订单列表 * @return array|\yii\db\ActiveRecord[] * @author: hankaige * @Time: 2024/3/27 10:02 */ private function getOrderData(): array { // 先根据搜索条件获取订单 $orderQuery = Order::find()->alias('o') ->leftJoin(['u' => User::tableName()], 'u.id = o.user_id') ->leftJoin(['od' => OrderDetail::tableName()], 'od.order_id=o.id') ->where([ 'o.store_id' => $this->store_id, 'o.is_delete' => 0, 'o.is_offline' => 1, 'o.shop_peisong' => 0, // 没有生成过配送单的订单 ]); // 只获取选中的订单 if(!empty($this->select_order)){ $orderQuery->andWhere(['o.id'=>$this->select_order]); }else{ if (!empty($this->goods_name)) { $orderQuery->andWhere([ 'like', 'od.goods_name', $this->goods_name ]); } if ($this->cat_id > 0) { // 获取所有绑定这个分类ID的商品ID $goodsID = GoodsCat::find()->where([ 'is_delete' => 0, 'cat_id' => $this->cat_id ])->select('goods_id')->column(); if (!empty($goodsID)) { $orderQuery->andWhere(['od.goods_id' => $goodsID]); } } // 发货时间 if($this->send_time){ $orderQuery->andWhere(['o.arrival_time' => strtotime($this->send_time)]); } if (!empty($this->order_no)) { $orderQuery->andWhere([ 'like', 'o.order_no', $this->order_no ]); } if (!empty($this->md_id)) { $orderQuery->andWhere(['o.md_id' => $this->md_id]); } switch ($this->status) { case 0: $orderQuery->andWhere([ '<>', 'o.trade_status', Order::ORDER_FLOW_CANCEL ])->andWhere([ 'o.is_delete' => Order::IS_DELETE_FALSE, 'o.is_pay' => Order::IS_PAY_FALSE ]); break; case 1: $orderQuery->andWhere([ 'o.trade_status' => Order::ORDER_FLOW_NO_SEND, 'o.is_delete' => Order::IS_DELETE_FALSE ])->andWhere([ 'or', ['o.is_pay' => Order::IS_PAY_TRUE], ['o.pay_type' => Order::PAY_TYPE_COD] ]); break; case 2: $orderQuery->andWhere([ 'o.trade_status' => Order::ORDER_FLOW_SEND, 'o.is_delete' => Order::IS_DELETE_FALSE ])->andWhere([ 'or', ['o.is_pay' => Order::IS_PAY_TRUE], ['o.pay_type' => Order::PAY_TYPE_COD] ]); break; case 3: $orderQuery->andWhere([ 'o.trade_status' => Order::ORDER_FLOW_CONFIRM, 'o.is_delete' => Order::IS_DELETE_FALSE ])->andWhere([ 'or', ['o.is_pay' => Order::IS_PAY_TRUE], ['o.pay_type' => Order::PAY_TYPE_COD] ]); break; case 4: break; case 5: $orderQuery->andWhere([ 'or', ['o.trade_status' => Order::ORDER_FLOW_CANCEL], ['o.is_delete' => Order::IS_DELETE_TRUE] ]); break; case 6: $orderQuery->andWhere([ 'and', ['o.apply_delete' => Order::ORDER_APPLY_DELETE], [ '!=', 'o.trade_status', Order::ORDER_FLOW_CANCEL ] ]); break; case 7: $orderQuery->andWhere([ 'o.apply_delete' => Order::ORDER_APPLY_DELETE, 'o.trade_status' => Order::ORDER_FLOW_NO_SEND ]); break; default: if (empty($this->order_id)) { $orderQuery->andWhere([ 'o.is_delete' => Order::IS_DELETE_FALSE ]); } break; } if ($this->dateStart) { $orderQuery->andWhere([ '>=', 'o.created_at', strtotime($this->dateStart) ]); } if ($this->dateEnd) { $orderQuery->andWhere([ '<=', 'o.created_at', strtotime($this->dateEnd) ]); } } return $orderQuery->select([ 'o.*', 'u.nickname as de_name', 'u.platform', 'u.binding', 'u.avatar_url', 'od.delivery_type', 'od.attr', 'o.name user_name', 'o.mobile user_mobile', 'o.address user_address', 'od.order_transit_id' ])->all(); } /** * 更具订单信息 汇总商品信息 * @param $orderData * @return array * @author: hankaige * @Time: 2024/3/27 10:02 */ private function handleData($orderData): array { $goodsList = []; foreach ($orderData as $orderItem) { $goodsList = array_merge($goodsList, ArrayHelper::toArray($orderItem->orderDetail)); } $result = []; foreach ($goodsList as $goodsItem) { $attr = json_decode($goodsItem['attr'], TRUE); // 不存在这个商品 if (!in_array($goodsItem['goods_id'], array_column($result, 'goods_id'))) { $attrList = [ 'attr_list' => $attr, 'num' => $goodsItem['num'], // 规格对应的数量 ]; $result[] = [ 'goods_id' => $goodsItem['goods_id'], 'goods_name' => $goodsItem['goods_name'], 'num' => $goodsItem['num'], // 商品所有规格的总数量 'attr_list' => [$attrList] ]; } else { // 选中已存在的商品 foreach ($result as $key => $value) { if ($value['goods_id'] == $goodsItem['goods_id']) { $result[$key]['num'] += $goodsItem['num']; // 处理规格 $hasAttr = false; foreach ($value['attr_list'] as $attrItemKey => $attrItem) { // 已存在的规格 $oldAttrIds = array_column($attrItem['attr_list'], 'attr_id'); // 当前商品的规格 $attrIds = array_column($attr, 'attr_id'); sort($oldAttrIds); sort($attrIds); // 规格存在相同规格 if (!array_diff($oldAttrIds, $attrIds)) { $result[$key]['attr_list'][$attrItemKey]['num'] += $goodsItem['num']; $hasAttr = true; break; } } if(!$hasAttr){ $result[$key]['attr_list'][] = [ 'attr_list' => $attr, 'num' => $goodsItem['num'] ]; } } } } } return $result; } /** * 生成备货单 备货单商品 备货单订单 * @param $orderList * @param $goodsList * @return int * @throws Exception * @author: hankaige * @Time: 2024/3/27 10:03 */ private function createInventory($orderList,$goodsList): int { // 生成备货单 $inventoryModel = new InventiryList(); $inventoryModel->store_id = $this->store_id; $inventoryModel->inventory_no = $inventoryModel::createOrderNo(); $inventoryModel->goods_count = count($goodsList); $inventoryModel->order_count = count($orderList); if(!$inventoryModel->save()){ throw new Exception('生成备货单失败'); } // 生成备货商品 $inventoryOrderGoods = new InventoryOrderGoods(); foreach($goodsList as $goodsItem){ $goods = clone $inventoryOrderGoods; $goods->inventory_id = $inventoryModel->id; $goods->goods_id = $goodsItem['goods_id']; $goods->goods_name = $goodsItem['goods_name']; $goods->attr = json_encode($goodsItem['attr_list']); $goods->num = $goodsItem['num']; if(!$goods->save()){ throw new Exception('生成备货商品错误'); } } // 生成备货单订单信息 $inventoryOrder = new InventoryOrder(); foreach ($orderList as $orderItem){ $order = clone $inventoryOrder; $order->inventory_id = $inventoryModel->id; $order->order_id = $orderItem['id']; if(!$order->save()){ throw new Exception('生成备货订单关联信息失败'); } } // 返货备货单主ID return $inventoryModel->id; } /** * 处理生成分拣单 * @param $orderList * @param $inventoryId * @throws Exception * @author: hankaige * @Time: 2024/3/27 10:39 */ private function createSorting($orderList,$inventoryId) { $newOrderList = []; foreach ($orderList as $orderItem){ $newOrderList[$orderItem['md_id']][] = $orderItem; } // 循环整理后的订单信息 整理为商品的数据 $newGoodsList = []; foreach($newOrderList as $mdId => $value){ $newGoodsList[$mdId] = $this->handleData($value); } if(empty($newGoodsList)){ throw new \Exception('商品信息出错了'); } $sortingModel = new SortingList(); $sortingOrderModel = new SortingOrder(); $sortingOrderGoodsModel = new SortingOrderGoods(); foreach($newGoodsList as $mdId => $goods){ $model = clone $sortingModel; $model->store_id = $this->store_id; $model->inventory_id = $inventoryId; $model->sorting_no = $model::createOrderNo(); $model->md_id = $mdId; $model->goods_count = count($goods); $model->order_count = count($newOrderList[$mdId]); if(!$model->save()){ throw new Exception('生成分拣单失败'); } foreach($newOrderList[$mdId] as $order){ $modelOrder = clone $sortingOrderModel; $modelOrder->sorting_id = $model->id; $modelOrder->order_id = $order['id']; if(!$modelOrder->save()){ throw new Exception('分拣单订单生成失败'); } } foreach($goods as $goodsItem){ $modelOrderGoods = clone $sortingOrderGoodsModel; $modelOrderGoods->sorting_id = $model->id; $modelOrderGoods->goods_id = $goodsItem['goods_id']; $modelOrderGoods->goods_name = $goodsItem['goods_name']; $modelOrderGoods->attr = json_encode($goodsItem['attr_list']); $modelOrderGoods->num = $goodsItem['num']; if(!$modelOrderGoods->save()){ throw new Exception('分拣商品错误'); } } } } }