]> gitweb.erp-flowers.ru Git - erp24_rep/yii-erp24/.git/commitdiff
Сжатие интервала актуальности для товаров origin/feature_fomichev_erp-462_cleanup_actuality_interval
authorVladimir Fomichev <vladimir.fomichev@erp-flowers.ru>
Wed, 10 Sep 2025 14:58:54 +0000 (17:58 +0300)
committerVladimir Fomichev <vladimir.fomichev@erp-flowers.ru>
Wed, 10 Sep 2025 14:58:54 +0000 (17:58 +0300)
erp24/controllers/Products1cNomenclatureActualityController.php

index 89d7caa8fb9c7bc227ec32d9b777f67b4abe9026..ec1a43d03b5b7ae137726b7a95e6cfac116244f8 100644 (file)
@@ -381,11 +381,96 @@ class Products1cNomenclatureActualityController extends Controller
                 continue;
             }
 
+            $id   = $row['id']   ?? null;
             $guid = $row['guid'];
 
             $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 Products1cNomenclatureActuality|null $master */
+                $master = Products1cNomenclatureActuality::find()
+                    ->where(['id' => $id, 'guid' => $guid])
+                    ->one();
+
+                if (!$master) {
+                    Yii::warning("GUID {$guid}: запись id={$id} не найдена, пропуск");
+                    continue;
+                }
+
+                $master->date_from  = $from;
+                $master->date_to    = $to;
+                $master->updated_at = $now;
+                $master->updated_by = $userId;
+
+                if (!$master->save()) {
+                    Yii::error("Ошибка обновления GUID={$guid}, id={$id}: " . json_encode($master->getErrors(), JSON_UNESCAPED_UNICODE));
+                    continue;
+                }
+
+                /** @var Products1cNomenclatureActuality[] $neighbors */
+                $neighbors = Products1cNomenclatureActuality::find()
+                    ->where(['guid' => $guid])
+                    ->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("Ошибка объединения GUID={$guid}, 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 = Products1cNomenclatureActuality::find()
+                        ->where(['guid' => $guid])
+                        ->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("Ошибка повторного объединения GUID={$guid}, id={$id}: " . json_encode($master->getErrors(), JSON_UNESCAPED_UNICODE));
+                        break;
+                    }
+                    foreach ($more as $nei) { $nei->delete(); }
+                }
+
+                continue;
+            }
+
             /** @var Products1cNomenclatureActuality[] $hits */
             $hits = Products1cNomenclatureActuality::find()
                 ->where(['guid' => $guid])