'start_time', 'end_time' => 'end_time', 'period_num' => 'period_num', 'operate_user' => 'operate_user', ]; } public function scenarios() { $parentScenarios = parent::scenarios(); $customScenarios = [ 'orderPeriodAdjustRange' => ['start_time', 'end_time', 'period_num', 'operate_user'], ]; return array_merge($parentScenarios, $customScenarios); } public function beforeValidate() { $parentValidate = parent::beforeValidate(); $this->start_timestamp = strtotime($this->start_time); $this->end_timestamp = strtotime($this->end_time); if ($this->start_timestamp === false) { $this->addError('start_time', 'start_time format is invalid'); return false; } if ($this->end_timestamp === false) { $this->addError('end_time', 'end_time format is invalid'); return false; } if ($this->start_timestamp > $this->end_timestamp) { $this->addError('end_time', 'end_time must be greater than or equal to start_time'); return false; } $period = Period::getInfoByPeriodNum($this->period_num); if (!$period) { $this->addError('period_num', Yii::t('ctx', 'invalidPcNo')); return false; } if ((int)$period['IS_SENT'] === 1) { $this->addError('period_num', Yii::t('ctx', 'orderHasBeenConnected')); return false; } return $parentValidate; } /** * Adjust orders by created_at range. * @return array|null */ public function periodAdjustRange() { if (!$this->validate()) { return null; } $this->orders = Order::find() ->select(['SN', 'PERIOD_NUM']) ->where(['IS_DELETE' => 0]) ->andWhere(['>=', 'CREATED_AT', $this->start_timestamp]) ->andWhere(['<=', 'CREATED_AT', $this->end_timestamp]) ->orderBy(['CREATED_AT' => SORT_ASC, 'ID' => SORT_ASC]) ->asArray() ->all(); $successOrderSnList = []; $failedOrderSnList = []; $skippedOrderSnList = []; $skippedDetailMap = []; $failedDetailMap = []; foreach ($this->orders as $orderRow) { $orderSn = $orderRow['SN']; $skipReason = $this->getSkipReason($orderRow); if ($skipReason !== null) { $skippedOrderSnList[] = $orderSn; $skippedDetailMap[$orderSn] = [ 'reason' => $skipReason, 'current_period' => $orderRow['PERIOD_NUM'] ?? '', 'target_period' => $this->period_num, ]; continue; } $adjustForm = new OrderPeriodAdjustForm(); $adjustForm->scenario = 'orderPeriodAdjust'; $adjustForm->orderSn = $orderSn; $adjustForm->modernPeriod = $this->period_num; $adjustForm->operateUser = $this->operate_user; $result = $adjustForm->periodAdjust(); if ($result === true) { $successOrderSnList[] = $orderSn; } else { $failedOrderSnList[] = $orderSn; $failedDetailMap[$orderSn] = $adjustForm->getErrors(); } } return [ 'start_time' => $this->start_time, 'end_time' => $this->end_time, 'period_num' => $this->period_num, 'operate_user' => $this->operate_user, 'total_count' => count($this->orders), 'success_count' => count($successOrderSnList), 'failed_count' => count($failedOrderSnList), 'skipped_count' => count($skippedOrderSnList), 'success_order_sn_list' => $successOrderSnList, 'failed_order_sn_list' => $failedOrderSnList, 'skipped_order_sn_list' => $skippedOrderSnList, 'skipped_detail_map' => $skippedDetailMap, 'failed_detail_map' => $failedDetailMap, ]; } private function getSkipReason(array $orderRow): ?string { $currentPeriodNum = (string)($orderRow['PERIOD_NUM'] ?? ''); $targetPeriodNum = (string)$this->period_num; if ($currentPeriodNum !== '' && $currentPeriodNum === $targetPeriodNum) { return '订单期数与目标期数相同'; } if ($currentPeriodNum === '') { return '订单期数为空,无法判断是否可调整'; } $currentPeriod = Period::getInfoByPeriodNum($currentPeriodNum); if (!$currentPeriod) { return Yii::t('ctx', 'invalidPcNo'); } if ((int)$currentPeriod['IS_SENT'] === 1) { return '已挂网,不可调整'; } if ($currentPeriodNum === $targetPeriodNum) { return '订单期数与目标期数相同'; } $availablePeriodList = Period::getPeriodList(+(int)$currentPeriodNum - 1); $availablePeriodNums = array_column($availablePeriodList, 'PERIOD_NUM'); if (!in_array($targetPeriodNum, $availablePeriodNums, false)) { return '不在可调整期数范围内'; } return null; } }