255] ]; } /** * {@inheritdoc} */ public function attributeLabels() { return [ 'id' => 'ID', 'order_id' => '主订单id', 'store_id' => '门店id', 'mall_id' => '商城ID', 'user_id' => '用户id', 'time_id' => '预约时间id', 'time_spec_id' => '预约时间id', 'reserve_date_time' => '预约时间', 'reserve_time_range_type' => '预约模式(1按天预约 2按时间段预约)', 'province_id' => '省ID', 'city_id' => '市ID', 'district_id' => '区县ID', 'detail' => '详细地址', 'lat' => '纬度', 'lng' => '经度', 'region_name' => '地区字符串', 'service_type' => '服务方式(1上门 2到店)', 'order_status' => '订单状态', 'pay_status' => '订单付款状态', 'reserve_status' => '订单预约状态', 'feedback_status' => '售后状态', 'cancel_rule' => '取消退款规则', 'cancel_type' => '取消类型(1不允许取消 2服务开始前取消 3订单类型取消)', 'reserve_code' => '预约码', 'created_at' => '创建时间', 'updated_at' => '更新时间', 'reservation_service_order_id' => 'reservation_service_order_id', ]; } /** * 预约商品订单处理 * @param [type] $order * @param [type] $form * @return void */ public static function create($order, $form) { try { $timeId = $form['data']['time_id']; $serviceType = $form['data']['service_type']; $latitude = $form['data']['latitude']; $longitude = $form['data']['longitude']; $address_id = $form['data']['address_id'] ?? 0; $timeSpecId = $form['data']['time_spec_id']; $tech_id = intval($form['data']['tech_id'] ?? 0); $orderDetail = $order->detail[0]; $goodsId = $orderDetail['goods_id']; $skuId = $orderDetail['goods_attr_id']; $num = $orderDetail['num']; if (!empty($address_id)) { $user_address = UserAddress::findOne(['id' => $address_id]); if (!empty($user_address['latitude'])) { $latitude = $user_address['latitude']; } if (!empty($user_address['longitude'])) { $longitude = $user_address['longitude']; } } // 扣减时间或时间段的库存 /** * @var $reserve GoodsReserve */ $reserve = GoodsReserve::findOne(['goods_id' => $goodsId]); if (empty($reserve)) throw new \Exception('找不到该预约商品'); $reserveSku = GoodsReserveSku::findOne(['id' => $skuId, 'goods_id' => $goodsId]); if (empty($reserveSku)) throw new \Exception('找不到该预约商品SKU'); $goods = Goods::findOne(['id' => $goodsId]); $service_start_at = 0; $service_end_at = 0; if ($reserve->reserve_type == StatusEnum::DISABLED) { // 预约模式(1按天预约 2按时间段预约) $reserveTimeRangeType = $reserveSku->reserve_time_range_type; // 预约时间处理 $time = GoodsReserveTime::findOne($timeId); if (empty($time)) throw new \Exception('找不到该预约时间日期'); $date = $time->reserve_time; // if (empty($goods->is_attr)) { // if ($time->stock < $num) throw new \Exception('该预约时间日期已超过最大预约数量'); // $time->stock -= $num; // $time->save(); // } if ($reserveTimeRangeType == 2) { $timeSpec = GoodsReserveTimeSpec::findOne(['reserve_time_id' => $timeId, 'id' => $timeSpecId]); if (empty($timeSpec)) throw new \Exception('找不到该预约时间分片'); $startHis = $timeSpec->start; $endHis = $timeSpec->end; $start = implode(' ', [$date, $startHis]); if ($timeSpec->is_next) $date = date('Y-m-d', strtotime('+1 day', strtotime($date))); $end = implode(' ', [$date, $endHis]); $reserveDateTime = implode(',', [$start, $end]); if ($timeSpec->stock < $num) throw new \Exception('该预约时间段已超过最大预约数量'); $timeSpec->stock -= $num; $timeSpec->save(); } else { $reserveDateTime = implode(',', [$date . ' 00:00:00', $date . '23:59:59']); } } else { $reserveTimeRangeType = 2; // 技师默认是按时间段预约的 $reserveDateTime = $form['data']['select_time'] ?? ''; if (!empty($reserveDateTime)) { $reserveDateTime .= ','.date('Y-m-d H:i', strtotime($reserveDateTime) + ($reserveSku->service_min * 60)); $reserve_date_time_arr = explode(',', $reserveDateTime); if (!empty($reserve_date_time_arr)) { $service_start_at = strtotime($reserve_date_time_arr[0]); $service_end_at = strtotime($reserve_date_time_arr[1]); $res = OrderReserve::find()->where(['attr_id' => $skuId, 'service_start_at' => $service_start_at]) ->andWhere(['tech_id' => $tech_id]) ->andWhere(['!=', 'order_status', -4]) ->select('tech_id')->one(); if (!empty($res)) { throw new \Exception('该技师该时间已有预约'); } } if (empty($goods->is_attr)) { // 查询今天有多少单 $reserve_max_buy = $reserve->reserve_max_buy; } else { $reserve_max_buy = $reserveSku->reserve_max_buy; } $date = date('Y-m-d', $service_start_at); $start_time = strtotime($date . ' 00:00:00'); $end_time = strtotime($date . ' 23:59:59'); if (!empty($reserve_max_buy) && $reserve_max_buy <= self::find()->where(['attr_id' => $skuId]) ->andWhere(['>=', 'service_start_at', $start_time]) ->andWhere(['<=', 'service_start_at', $end_time]) ->andWhere(['>=', 'order_status', 0])->count()) { throw new \Exception('今天已达到最大预约数'); } } // 取出商品的结束时间 } // 预约商品服务地址 // service_type服务方式(1上门 2到店 3两者都兼容) if ($serviceType == GoodsReserve::RESERVE_SERVICE_TO) { // 上门服务使用订单地址 $province = $order->province; $city = $order->city; $area = $order->area; $address = $order->address; $lat = $latitude; $lng = $longitude; $regionName = $order->region_name; } else { // 到店使用商品地址 $province = $reserve->province_id; $city = $reserve->city_id; $area = $reserve->district_id; $address = $reserve->detail; $lat = $reserve->lat; $lng = $reserve->lng; $regionName = ''; } if (empty($province) || empty($city) || empty($area) || empty($address) || empty($lat) || empty($lng)) { throw new \Exception('服务地址或定位信息错误'); } $model = new OrderReserve(); $model->loadDefaultValues(); $model->isNewRecord = true; $model->order_id = $order->id; $model->store_id = $order->store_id; $model->mall_id = $order->mall_id; $model->user_id = $order->user_id; $model->time_id = $timeId ?? 0; $model->time_spec_id = $timeSpecId ?? 0; $model->reserve_date_time = !empty($reserveDateTime) ? $reserveDateTime : ''; $model->reserve_time_range_type = !empty($reserveTimeRangeType) ? $reserveTimeRangeType : 0; $model->province_id = $province; $model->city_id = $city; $model->district_id = $area; $model->detail = $address; $model->lat = $lat; $model->lng = $lng; $model->region_name = $regionName; $model->service_type = $serviceType; $model->order_status = $order->order_status; $model->pay_status = $order->pay_status; $model->cancel_type = $reserve->cancel_type; $model->cancel_rule = $reserve->cancel_rule; $model->reserve_type = $reserve->reserve_type; $model->tech_id = $tech_id; $model->attr_id = $skuId; $model->service_start_at = $service_start_at; $model->service_end_at = $service_end_at; $model->goods_id = $goodsId; if (!$model->save()) throw new Exception($model->getErrorMessage()); return true; } catch (Exception $e) { if (isset($trans)) $trans->rollback(); self::$static_error = $e->getMessage(); return false; } } /** * 同步订单状态 * @param [type] $order * @return void */ public static function syncOrderStatus($order, $tech_id = null) { $orderDetail = $order->detail[0]; $num = $orderDetail['num']; if (empty($order['store_id'])) { $model = self::findOne(['order_id' => $order->id]); } else { $model = StoreOrderReserve::findOne(['main_order_id' => $order->id]); } $oldStatus = $model->order_status; $model->order_status = $order->order_status; $model->feedback_status = $order->is_feedback; $model->pay_status = $order->pay_status; $timeId = $model->time_id; $timeSpecId = $model->time_spec_id; $reserveTimeRangeType = $model->reserve_time_range_type; if (!empty($tech_id) && empty($model->tech_id)) $model->tech_id = $tech_id; if ($model->order_status === OrderStatusEnum::SHIPMENTS) { // 预约商品订单支付后,直接变成已发货状态 // 订单支付,时订单处于关闭状态的话,重新扣减可预约数量 // 生成预约码 // $model->reserve_code = date('YmdHis') . $model->id; if(empty($model->reserve_code)){ if($order->clerk_code){ $reserve_code = $order->clerk_code; $model->reserve_code = $reserve_code; }else{ if($order->marketing_type!='SecondaryCard' && $order->order_source=='Reserve'){ $model->reserve_code = self::getClerkCode($order['mall_id'],ClerkEnum::RESERVATION_SERVICE_CLERK_CODE_PRE); } } } if ($oldStatus === OrderStatusEnum::REPEAL) { self::handleTimeStock($timeId, $timeSpecId, $reserveTimeRangeType, $num * -1); } } if ($model->order_status === OrderStatusEnum::SING) { // 预约商品核销订单 $model->reserve_status = self::RESERVE_STATUS_PENDDING; } if ($model->order_status === OrderStatusEnum::REPEAL) { // 订单关闭,归还可预约数量 self::handleTimeStock($timeId, $timeSpecId, $reserveTimeRangeType, $num); } if ($model->order_status === OrderStatusEnum::ACCOMPLISH) { // 订单完成 $model->reserve_status = self::RESERVE_STATUS_FINISH; } if (!empty($order['store_id'])) { $where = [ ['mall_id' => $order['mall_id']], ['order_id' => $order->id], ['status' => StatusEnum::ENABLED], ['store_id' => $order['store_id']] ]; $reservation_service_order_model = ReservationServiceOrder::getOne($where); if (!empty($reservation_service_order_model)) { if (empty($reservation_service_order_model['secondary_card_id'])) { $reservation_service_order_model->server_status = ReservationServiceEnum::COMPLETED; $reservation_service_order_model->service_status = ReservationServiceEnum::RESERVE_ORDER_STATUS_FINISH; $reservation_service_order_model->save(); } else { $secondary_card_model = SecondaryCard::find()->where(['id' => $reservation_service_order_model['secondary_card_id']])->one(); if (!empty($secondary_card_model)) { if ($secondary_card_model['reservation_model'] == 2) { if (in_array($reservation_service_order_model->server_status, [ReservationServiceEnum::ARRIVED_AT_STORE, ReservationServiceEnum::ALREADY_BOOKED])) { $reservation_service_order_model->server_status = ReservationServiceEnum::TO_BE_ACCEPTED; $reservation_service_order_model->service_status = ReservationServiceEnum::RESERVE_ORDER_STATUS_UNDERWRITER; $reservation_service_order_model->save(); } elseif ($reservation_service_order_model->server_status == ReservationServiceEnum::TO_BE_ACCEPTED) { $reservation_service_order_model->server_status = ReservationServiceEnum::COMPLETED; $reservation_service_order_model->service_status = ReservationServiceEnum::RESERVE_ORDER_STATUS_FINISH; $reservation_service_order_model->save(); } } else if ($secondary_card_model['reservation_model'] == 1) { if ($reservation_service_order_model->service_status == ReservationServiceEnum::RESERVE_ORDER_STATUS_UNDERWRITER) { $reservation_service_order_model->server_status = ReservationServiceEnum::COMPLETED; $reservation_service_order_model->service_status = ReservationServiceEnum::RESERVE_ORDER_STATUS_FINISH; $reservation_service_order_model->save(); } } } } } } if (!$model->save()) throw new Exception($model->getErrorMessage()); return true; } public static function handleTimeStock($timeId, $timeSpecId, $reserveTimeRangeType, $num) { $time = GoodsReserveTime::findOne($timeId); if (empty($time)) return; $time->stock += $num; $time->save(); if ($reserveTimeRangeType == 2) { $timeSpec = GoodsReserveTimeSpec::findOne(['reserve_time_id' => $timeId, 'id' => $timeSpecId]); if (empty($timeSpec)) return; $timeSpec->stock += $num; $timeSpec->save(); } } public static function getClerkCode($mall_id,$pre) { while (true) { $clerk_code = ClerkEnum::getCode($pre); $res = self::findOne(['mall_id' => $mall_id, 'reserve_code' => $clerk_code]); if (empty($res)) break; } if (empty($clerk_code)) throw new \Exception('核销码生成失败'); return $clerk_code; } }