From cc031bef4fa96f4738343cd6081465b13d18cb1a Mon Sep 17 00:00:00 2001 From: Vladimir Fomichev Date: Thu, 11 Sep 2025 13:15:01 +0300 Subject: [PATCH] =?utf8?q?=D0=9F=D0=B5=D1=80=D0=B5=D1=81=D0=B5=D1=87=D0=B5?= =?utf8?q?=D0=BD=D0=B8=D0=B5=20=D0=B8=20=D0=BE=D0=B1=D1=8A=D0=B5=D0=B4?= =?utf8?q?=D0=B8=D0=BD=D0=B5=D0=BD=D0=B8=D0=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit --- .../MatrixBouquetActualityController.php | 127 ++++++++++++++++++ 1 file changed, 127 insertions(+) diff --git a/erp24/controllers/MatrixBouquetActualityController.php b/erp24/controllers/MatrixBouquetActualityController.php index f035d2a0..827360c8 100644 --- a/erp24/controllers/MatrixBouquetActualityController.php +++ b/erp24/controllers/MatrixBouquetActualityController.php @@ -325,11 +325,96 @@ class MatrixBouquetActualityController extends Controller $guid = $row['guid']; $bouquetId = $row['bouquet_id']; + $id = $row['id'] ?? null; $fromAdj = (clone $fromDate)->modify('-1 second')->format('Y-m-d H:i:s'); $toAdj = (clone $toDate)->modify('+1 second')->format('Y-m-d H:i:s'); + if ($id) { + /** @var MatrixBouquetActuality|null $master */ + $master = MatrixBouquetActuality::find() + ->where(['id' => $id, 'bouquet_id' => $bouquetId]) + ->one(); + + if (!$master) { + Yii::warning("Букет {$bouquetId}: запись id={$id} не найдена, пропуск"); + continue; + } + + $master->date_from = $from; + $master->date_to = $to; + $master->updated_at = $now; + $master->updated_by = $userId; + + if (!$master->save()) { + Yii::error("Ошибка обновления bouquet_id={$bouquetId}, id={$id}: " . json_encode($master->getErrors(), JSON_UNESCAPED_UNICODE)); + continue; + } + + /** @var MatrixBouquetActuality[] $neighbors */ + $neighbors = MatrixBouquetActuality::find() + ->where(['bouquet_id' => $bouquetId]) + ->andWhere(['<>', 'id', $master->id]) + ->andWhere('date_to >= :fromAdj', [':fromAdj' => $fromAdj]) + ->andWhere('date_from <= :toAdj', [':toAdj' => $toAdj]) + ->orderBy(['date_from' => SORT_ASC]) + ->all(); + + if (empty($neighbors)) { + continue; + } + + $minFrom = $master->date_from; + $maxTo = $master->date_to; + + foreach ($neighbors as $nei) { + if ($nei->date_from < $minFrom) $minFrom = $nei->date_from; + if ($nei->date_to > $maxTo) $maxTo = $nei->date_to; + } + + $master->date_from = $minFrom; + $master->date_to = $maxTo; + $master->updated_at = $now; + $master->updated_by = $userId; + + if (!$master->save()) { + Yii::error("Ошибка объединения bouquet_id={$bouquetId}, id={$id}: " . json_encode($master->getErrors(), JSON_UNESCAPED_UNICODE)); + continue; + } + + foreach ($neighbors as $nei) { $nei->delete(); } + + while (true) { + $leftBound = (new \DateTime($master->date_from))->modify('-1 second')->format('Y-m-d H:i:s'); + $rightBound = (new \DateTime($master->date_to))->modify('+1 second')->format('Y-m-d H:i:s'); + + $more = MatrixBouquetActuality::find() + ->where(['bouquet_id' => $bouquetId]) + ->andWhere(['<>', 'id', $master->id]) + ->andWhere('date_to >= :leftBound', [':leftBound' => $leftBound]) + ->andWhere('date_from <= :rightBound', [':rightBound' => $rightBound]) + ->orderBy(['date_from' => SORT_ASC]) + ->all(); + + if (empty($more)) break; + + foreach ($more as $nei) { + if ($nei->date_from < $master->date_from) $master->date_from = $nei->date_from; + if ($nei->date_to > $master->date_to) $master->date_to = $nei->date_to; + } + $master->updated_at = $now; + $master->updated_by = $userId; + if (!$master->save()) { + Yii::error("Ошибка повторного объединения bouquet_id={$bouquetId}, id={$id}: " . json_encode($master->getErrors(), JSON_UNESCAPED_UNICODE)); + break; + } + foreach ($more as $nei) { $nei->delete(); } + } + + continue; + } + /** @var MatrixBouquetActuality[] $actualities */ $actualities = MatrixBouquetActuality::find() ->where(['bouquet_id' => $bouquetId]) @@ -368,8 +453,50 @@ class MatrixBouquetActualityController extends Controller /** @var MatrixBouquetActuality $actuality */ $actuality->delete(); } + + while (true) { + $leftBound = (new \DateTime($master->date_from))->modify('-1 second')->format('Y-m-d H:i:s'); + $rightBound = (new \DateTime($master->date_to))->modify('+1 second')->format('Y-m-d H:i:s'); + + /** @var MatrixBouquetActuality[] $neighbors */ + $neighbors = MatrixBouquetActuality::find() + ->where(['bouquet_id' => $bouquetId]) + ->andWhere(['<>', 'id', $master->id]) + ->andWhere('date_to >= :leftBound', [':leftBound' => $leftBound]) + ->andWhere('date_from <= :rightBound', [':rightBound' => $rightBound]) + ->orderBy(['date_from' => SORT_ASC]) + ->all(); + + if (empty($neighbors)) { + break; + } + + foreach ($neighbors as $nei) { + if ($nei->date_from < $master->date_from) + { + $master->date_from = $nei->date_from; + } + if ($nei->date_to > $master->date_to) + { + $master->date_to = $nei->date_to; + } + } + $master->updated_at = $now; + $master->updated_by = $userId; + + if (!$master->save()) { + Yii::error("Ошибка повторного обновления bouquet_id={$bouquetId}: " . json_encode($master->getErrors(), JSON_UNESCAPED_UNICODE)); + break; + } + + foreach ($neighbors as $nei) { + $nei->delete(); + } + } } } + + /** * Displays a single MatrixBouquetActuality model. * @param int $id ID -- 2.39.5