From: Vladimir Fomichev Date: Thu, 11 Sep 2025 10:15:01 +0000 (+0300) Subject: Пересечение и объединение X-Git-Url: https://gitweb.erp-flowers.ru/?a=commitdiff_plain;h=cc031bef4fa96f4738343cd6081465b13d18cb1a;p=erp24_rep%2Fyii-erp24%2F.git Пересечение и объединение --- 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