OrderPeriodAdjustRangeForm.php 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  1. <?php
  2. namespace common\models\forms;
  3. use common\components\Model;
  4. use common\models\Order;
  5. use common\models\Period;
  6. use Yii;
  7. /**
  8. * Batch order period adjust form.
  9. */
  10. class OrderPeriodAdjustRangeForm extends Model
  11. {
  12. public $start_time;
  13. public $end_time;
  14. public $period_num;
  15. public $operate_user;
  16. public $start_timestamp;
  17. public $end_timestamp;
  18. public $orders = [];
  19. public function rules()
  20. {
  21. return [
  22. [['start_time', 'end_time', 'period_num', 'operate_user'], 'trim'],
  23. [['start_time', 'end_time', 'period_num', 'operate_user'], 'required'],
  24. ];
  25. }
  26. public function attributeLabels()
  27. {
  28. return [
  29. 'start_time' => 'start_time',
  30. 'end_time' => 'end_time',
  31. 'period_num' => 'period_num',
  32. 'operate_user' => 'operate_user',
  33. ];
  34. }
  35. public function scenarios()
  36. {
  37. $parentScenarios = parent::scenarios();
  38. $customScenarios = [
  39. 'orderPeriodAdjustRange' => ['start_time', 'end_time', 'period_num', 'operate_user'],
  40. ];
  41. return array_merge($parentScenarios, $customScenarios);
  42. }
  43. public function beforeValidate()
  44. {
  45. $parentValidate = parent::beforeValidate();
  46. $this->start_timestamp = strtotime($this->start_time);
  47. $this->end_timestamp = strtotime($this->end_time);
  48. if ($this->start_timestamp === false) {
  49. $this->addError('start_time', 'start_time format is invalid');
  50. return false;
  51. }
  52. if ($this->end_timestamp === false) {
  53. $this->addError('end_time', 'end_time format is invalid');
  54. return false;
  55. }
  56. if ($this->start_timestamp > $this->end_timestamp) {
  57. $this->addError('end_time', 'end_time must be greater than or equal to start_time');
  58. return false;
  59. }
  60. $period = Period::getInfoByPeriodNum($this->period_num);
  61. if (!$period) {
  62. $this->addError('period_num', Yii::t('ctx', 'invalidPcNo'));
  63. return false;
  64. }
  65. if ((int)$period['IS_SENT'] === 1) {
  66. $this->addError('period_num', Yii::t('ctx', 'orderHasBeenConnected'));
  67. return false;
  68. }
  69. return $parentValidate;
  70. }
  71. /**
  72. * Adjust orders by created_at range.
  73. * @return array|null
  74. */
  75. public function periodAdjustRange()
  76. {
  77. if (!$this->validate()) {
  78. return null;
  79. }
  80. $this->orders = Order::find()
  81. ->select(['SN', 'PERIOD_NUM'])
  82. ->where(['IS_DELETE' => 0])
  83. ->andWhere(['>=', 'CREATED_AT', $this->start_timestamp])
  84. ->andWhere(['<=', 'CREATED_AT', $this->end_timestamp])
  85. ->orderBy(['CREATED_AT' => SORT_ASC, 'ID' => SORT_ASC])
  86. ->asArray()
  87. ->all();
  88. $successOrderSnList = [];
  89. $failedOrderSnList = [];
  90. $skippedOrderSnList = [];
  91. $skippedDetailMap = [];
  92. $failedDetailMap = [];
  93. foreach ($this->orders as $orderRow) {
  94. $orderSn = $orderRow['SN'];
  95. $skipReason = $this->getSkipReason($orderRow);
  96. if ($skipReason !== null) {
  97. $skippedOrderSnList[] = $orderSn;
  98. $skippedDetailMap[$orderSn] = [
  99. 'reason' => $skipReason,
  100. 'current_period' => $orderRow['PERIOD_NUM'] ?? '',
  101. 'target_period' => $this->period_num,
  102. ];
  103. continue;
  104. }
  105. $adjustForm = new OrderPeriodAdjustForm();
  106. $adjustForm->scenario = 'orderPeriodAdjust';
  107. $adjustForm->orderSn = $orderSn;
  108. $adjustForm->modernPeriod = $this->period_num;
  109. $adjustForm->operateUser = $this->operate_user;
  110. $result = $adjustForm->periodAdjust();
  111. if ($result === true) {
  112. $successOrderSnList[] = $orderSn;
  113. } else {
  114. $failedOrderSnList[] = $orderSn;
  115. $failedDetailMap[$orderSn] = $adjustForm->getErrors();
  116. }
  117. }
  118. return [
  119. 'start_time' => $this->start_time,
  120. 'end_time' => $this->end_time,
  121. 'period_num' => $this->period_num,
  122. 'operate_user' => $this->operate_user,
  123. 'total_count' => count($this->orders),
  124. 'success_count' => count($successOrderSnList),
  125. 'failed_count' => count($failedOrderSnList),
  126. 'skipped_count' => count($skippedOrderSnList),
  127. 'success_order_sn_list' => $successOrderSnList,
  128. 'failed_order_sn_list' => $failedOrderSnList,
  129. 'skipped_order_sn_list' => $skippedOrderSnList,
  130. 'skipped_detail_map' => $skippedDetailMap,
  131. 'failed_detail_map' => $failedDetailMap,
  132. ];
  133. }
  134. private function getSkipReason(array $orderRow): ?string
  135. {
  136. $currentPeriodNum = (string)($orderRow['PERIOD_NUM'] ?? '');
  137. $targetPeriodNum = (string)$this->period_num;
  138. if ($currentPeriodNum !== '' && $currentPeriodNum === $targetPeriodNum) {
  139. return '订单期数与目标期数相同';
  140. }
  141. if ($currentPeriodNum === '') {
  142. return '订单期数为空,无法判断是否可调整';
  143. }
  144. $currentPeriod = Period::getInfoByPeriodNum($currentPeriodNum);
  145. if (!$currentPeriod) {
  146. return Yii::t('ctx', 'invalidPcNo');
  147. }
  148. if ((int)$currentPeriod['IS_SENT'] === 1) {
  149. return '已挂网,不可调整';
  150. }
  151. if ($currentPeriodNum === $targetPeriodNum) {
  152. return '订单期数与目标期数相同';
  153. }
  154. $availablePeriodList = Period::getPeriodList(+(int)$currentPeriodNum - 1);
  155. $availablePeriodNums = array_column($availablePeriodList, 'PERIOD_NUM');
  156. if (!in_array($targetPeriodNum, $availablePeriodNums, false)) {
  157. return '不在可调整期数范围内';
  158. }
  159. return null;
  160. }
  161. }