]> gitweb.erp-flowers.ru Git - erp24_rep/yii-erp24/.git/commitdiff
Пересечение и объединение
authorVladimir Fomichev <vladimir.fomichev@erp-flowers.ru>
Thu, 11 Sep 2025 10:15:01 +0000 (13:15 +0300)
committerVladimir Fomichev <vladimir.fomichev@erp-flowers.ru>
Thu, 11 Sep 2025 10:15:01 +0000 (13:15 +0300)
erp24/controllers/MatrixBouquetActualityController.php

index f035d2a048e289fd03583943072a1a9b3f36f117..827360c8a622a3462cb724607b437f7eea5b07b6 100644 (file)
@@ -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