255], [['operator_username'], 'string', 'max' => 50], [['buyer_name'], 'string', 'max' => 100], ]; } /** * {@inheritdoc} */ public function attributeLabels() { return [ 'id' => 'ID', 'order_id' => '订单id', 'order_detail_ids' => '产品列表', 'shipping_type' => '发货方式1 快递 0其他', 'express_id' => '快递公司id', 'express_name' => '物流公司名称', 'express_no' => '运单编号', 'buyer_id' => '买家id', 'buyer_name' => '买家信息', 'operator_id' => '发货人用户id', 'operator_username' => '发货人用户名', 'memo' => '备注', 'status' => '状态[-1:删除;0:禁用;1启用]', 'created_at' => '创建时间', 'updated_at' => '更新时间', 'nums' => '发货数量', ]; } public function beforeSave($insert) { if ($this->shipping_type == StatusEnum::DISABLED) { $this->express_id = 0; $this->express_name = ''; $this->express_no = ''; } return parent::beforeSave($insert); } /** * 关联订单详情表 * @return \yii\db\ActiveQuery * @throws \yii\base\InvalidConfigException */ public function getOrderDetail() { return $this->hasMany(OrderDetail::class, ['id' => 'order_detail_id']) ->where(['status' => StatusEnum::ENABLED]); } /** * 发货 * @Author bing * @DateTime 2021-09-16 19:55:46 * @copyright: Copyright (c) 2020 广东七件事集团 * @param [type] $order_id * @param [type] $params * @param [type] $trigger_event * @return void */ public static function delivery($params,$trigger_event = true){ try{ if (empty($params['cs_order_id'])) { $order = Order::getOne([['mall_id' => $params['mall_id'], 'id' => $params['id'],'status'=>[StatusEnum::ENABLED]]]); if(empty($order)) throw new Exception('订单不存在或已删除'); if ($order->order_status == OrderStatusEnum::SHIPMENTS) throw new Exception('订单已经发货'); // 是否允许发货 $shippingValidateEventEvent = new ShippingValidateEvent($params['mall_id']); $shippingValidateEventEvent->setOrderIds([$params['id']]); Yii::$app->services->events->dispatch($shippingValidateEventEvent); ['isAllow' => $isAllow, 'reason' => $reason] = $shippingValidateEventEvent->getIsAllow($params['id']); if (!$isAllow) { throw new Exception($reason); } $params['order_id'] = $order['id']; $trans = Yii::$app->db->beginTransaction(); $params['buyer_id'] = $order['user_id']; $params['buyer_name'] = $order['receiver_name']; $orderDetailsListByIds = OrderDetail::lists([ 'where' => [ ['in', 'id', $params['order_detail_ids']], ['=', 'shipping_status', ShippingStatusEnum::UN_SHIPPED], ['mall_id' => $params['mall_id'], 'status' => StatusEnum::ENABLED, 'order_status' => OrderStatusEnum::PAY], ], 'select' => 'id, shipped_num, num, order_status, shipping_status', 'index' => 'id' ]); if (empty($orderDetailsListByIds)) { throw new Exception('参数错误'); } $params['order_detail_ids'] = array_column($orderDetailsListByIds, 'id'); $params['send_nums'] = $params['send_nums'] ?? []; $emptySendNums = true; if (!empty($params['send_nums'])) { $emptySendNums = false; $params['send_nums'] = array_column($params['send_nums'], 'num', 'id'); } foreach ($params['order_detail_ids'] as $order_detail_id) { if (!isset($orderDetailsListByIds[$order_detail_id])) { throw new Exception('参数错误'); } $orderDetail = &$orderDetailsListByIds[$order_detail_id]; $orderDetail['unshipped_num'] = $orderDetail['num'] - $orderDetail['shipped_num']; if ($orderDetail['unshipped_num'] <= 0) { throw new Exception('订单已经发货'); } if ($emptySendNums) { $params['send_nums'][$order_detail_id] = $orderDetail['unshipped_num']; } else { if (empty($params['send_nums'][$order_detail_id])) { throw new Exception('参数错误'); } if ($orderDetail['unshipped_num'] < $params['send_nums'][$order_detail_id]) { throw new Exception('发货数量大于待发货数量'); } } } } else { // 云库存 } // YT7478017428791,YT7478018128005,YT7478018445276,YT7478019373473 $express_no = $params['express_no']; if (strstr($params['express_no'], ',')) { $express_no_list = explode(",", $express_no); } else if (strstr($params['express_no'], '、')) { $express_no_list = explode("、", $express_no); } else { $express_no_list = [$express_no]; } $expressNoCount = count($express_no_list); foreach (($express_no_list ?? []) as $item) { if ($expressNoCount === 1) { // 相同订单 相同物流号合并发货信息 $orderExpress = OrderExpress::findOne([ 'order_id' => $params['order_id'], 'express_no' => $item, 'status' => StatusEnum::ENABLED ]); // 判断如果是同一运单号,则将之前已经发货的合并。增加原来数据的发货数量。 if (!empty($orderExpress)) { foreach ($params['order_detail_ids'] as $order_detail_id) { if (!in_array($order_detail_id, $orderExpress->order_detail_ids)) { $orderDetailIds = $orderExpress->order_detail_ids; $orderDetailIds[] = $order_detail_id; $orderExpress->order_detail_ids = $orderDetailIds; } $nums = $orderExpress->nums; $nums[$order_detail_id] = ($nums[$order_detail_id] ?? 0) + $params['send_nums'][$order_detail_id]; $orderExpress->nums = $nums; } $orderExpress->save(); continue; } } else { // 每个订单里面只能使用同一个快递单号一次 if (!empty(OrderExpressLog::findOne(['order_id' => $params['order_id'], 'express_no' => $item]))) continue; } $model = new OrderExpress(); $params['operator_username'] = $params['operator_name']; $params['express_no'] = $item; $params['nums'] = $params['send_nums']; if(!$model->load($params,'') || !$model->save()) throw new \Exception($model->getErrorMessage()); //保存物流轨迹记录 $params['order_express_id'] = $model->id; $res = OrderExpressLog::saveLog($params); if ($res == false) throw new Exception(OrderExpressLog::getStaticError()); } if (empty($params['cs_order_id'])) { $condition['where'] = [['in', 'id', $params['order_detail_ids']], ['is_feedback' => [OrderStatusEnum::FEEDBACKING, OrderStatusEnum::FEEDBACKED]]]; $res = OrderDetail::lists($condition); if (!empty($res)) throw new \Exception('订单申请售后中,请先处理售后问题'); // 扣待发货数量 foreach ($params['order_detail_ids'] as $order_detail_id) { $updateData = [ 'shipped_num' => new Expression('shipped_num + :num', [':num' => $params['send_nums'][$order_detail_id]]) ]; // 订单商品的物流状态改变 如果全部发完则改为已发货 if ($orderDetailsListByIds[$order_detail_id]['unshipped_num'] - $params['send_nums'][$order_detail_id] <= 0) { $updateData['order_status'] = OrderStatusEnum::SHIPMENTS; $updateData['shipping_status'] = StatusEnum::ENABLED; } OrderDetail::updateAll($updateData, ['=', 'id', $order_detail_id]); } // 自动维护订单状态 $res = Order::autoUpdateStatus($order); if ($res === false) throw new \Exception(Order::getStaticError()); if ($order->order_source === OrderSourceEnum::SOURCE_RESERVE) { // 如果为预约订单那么就需要处理 // 执行发货 $order->shipping_status = StatusEnum::ENABLED; // 全部发货状态改为已发货 // 如果是技师,那么就为已支付 $order->order_status = OrderStatusEnum::SHIPMENTS; $order->consign_time = time(); $order->save(); OrderReserve::syncOrderStatus($order, 0); } $trans->commit(); if ($trigger_event) { // 发货成功触发事件,事务提交完成后触发 $event = new OrderDeliveryEvent($params['mall_id']); $data['id'] = $model->id; $data['operator_id'] = $params['operator_id']; $data['operator_name'] = $params['operator_name']; $data['is_admin'] = (int)!empty($params['is_admin']); Yii::$app->services->events->dispatch($event, $data, $event->listeners); } }else{ // 发货成功触发事件,事务提交完成后触发 $event = new AgentOrderPaidEvent($params['mall_id']); $data['id'] = $params['cs_order_id'];; $data['operator_id'] = $params['operator_id']; $data['operator_name'] = $params['operator_name']; $data['is_admin'] = (int)!empty($params['is_admin']); Yii::$app->services->events->dispatch($event, $data, $event->listeners); } return $model; }catch(Exception $e){ if(isset($trans)) $trans->rollback(); self::$static_error = $e->getMessage(); return false; } } /** * 修改物流 * @Author lun * @DateTime 2021-09-24 19:55:46 * @copyright: Copyright (c) 2020 广东七件事集团 * @param [type] $params * @return void */ public static function shippingChange($params){ try{ $order_express = OrderExpress::findOne(['id' => $params['id']]); if (empty($order_express)) throw new Exception('物流不存在或已删除'); $trans = Yii::$app->db->beginTransaction(); if(!$order_express->load($params,'') || !$order_express->save()) throw new \Exception($order_express->getErrorMessage()); OrderExpressLog::saveLog($params,true); $trans->commit(); // 发货成功触发事件,事务提交完成后触发 $event = new OrderDeliveryEvent($params['mall_id']); $data['id'] = $params['id']; $data['operator_id'] = $params['operator_id']; $data['operator_name'] = $params['operator_name']; $data['shipping_change'] = 1; $data['is_admin'] = (int)!empty($params['is_admin']); Yii::$app->services->events->dispatch($event, $data, $event->listeners); return true; }catch(Exception $e){ if(isset($trans)) $trans->rollback(); self::$static_error = $e->getMessage(); return false; } } /** * 获取订单物流 * @Author bing * @DateTime 2021-08-26 13:00:11 * @copyright: Copyright (c) 2020 广东七件事集团 * @param array $cond * @param array $with * @param integer $is_array * @return array|null */ public static function getOrderExpresses(array $cond=[],array $with=[],bool $is_array=true,string $select='*',$index=''){ $default_cond = [['<>','status',StatusEnum::DELETE]]; $cond = array_merge($default_cond,$cond); $query = self::find()->select($select); self::paramPack(['where'=>$cond,'with'=>$with],$query); if(!empty($index)) $query->indexBy($index); $labels = $query->asArray($is_array)->all(); return $labels; } /** * @notes:取消发货删除物流信息 * @param $order_id * @return bool * @author: lun * @Time: 2022/10/27 10:33 */ public static function cancelExpress($params, $isDispatchEvent = false) { $trans = Yii::$app->db->beginTransaction(); try { $express = self::findOne(['id' => $params['id'],'order_id' => $params['order_id'], 'status' => StatusEnum::ENABLED]); if (!empty($express)) { $express->status = StatusEnum::DELETE; if (!$express->save()) throw new \yii\db\Exception($express->getErrorMessage()); // 物流轨迹修改 $express_log = OrderExpressLog::findOne(['order_express_id' => $express->id]); if (!empty($express_log)) { $express_log->status = StatusEnum::DELETE; if (!$express_log->save()) throw new \yii\db\Exception($express_log->getErrorMessage()); } // 修改订单状态 $res = Order::cancelShipment([ 'order_id' => $express->order_id, 'order_detail_ids' => $express->order_detail_ids, 'nums' => $express->nums ?? [], ]); if ($res === false) throw new Exception(Order::getStaticError()); } $trans->commit(); // 取消发货事件 if ($isDispatchEvent) { $event = new OrderCancelShipmentEvent($params['mall_id']); $data['order_id'] = $params['order_id']; $data['id'] = $params['id']; $data['operator_id'] = $params['operator_id']; $data['operator_name'] = $params['operator_name']; Yii::$app->services->events->dispatch($event, $data, $event->listeners); } return true; } catch (Exception $e) { $trans->rollBack(); self::setStaticError($e->getMessage()); return false; } } public static function setData($params) { try { if (!empty($params['id'])) { $query = self::find()->where(['id' => $params['id']])->andWhere(['<>', 'status', StatusEnum::DELETE]); $model = $query->one(); if (empty($model)) { throw new \Exception('数据不存在'); } } else { $model = new self(); $model->loadDefaultValues(); } if (!$model->load($params, '') || !$model->save()) { throw new \Exception($model->getErrorMessage()); } return $model; } catch (\Exception $e) { self::$static_error = $e->getMessage(); return false; } } }