public static function SaveResult($selfCostProduct)
{
foreach ($selfCostProduct as $row) {
- // Ищем существующие записи с теми же параметрами (product_guid, store_id, price)
- $existingRecord = SelfCostProductDynamic::find()
+ // Ищем ВСЕ существующие записи с теми же параметрами (product_guid, store_id, price)
+ $existingRecords = SelfCostProductDynamic::find()
->where([
'product_guid' => $row['product_guid'],
'store_id' => $row['store_id'],
'price' => $row['price']
])
- ->one();
-
- if (!empty($existingRecord)) {
- // Запись найдена - проверяем пересечение или примыкание интервалов
- $existingDateFrom = strtotime($existingRecord->date_from);
- $existingDateTo = strtotime($existingRecord->date_to);
- $newDateFrom = strtotime($row['date_from']);
- $newDateTo = strtotime($row['date_to']);
-
- // Проверяем, примыкают ли интервалы (разница <= 1 день) или пересекаются
- $daysBetween = min(
- abs($newDateFrom - $existingDateTo) / 86400,
- abs($existingDateFrom - $newDateTo) / 86400
- );
-
- if ($daysBetween <= 1 ||
- ($newDateFrom <= $existingDateTo && $newDateTo >= $existingDateFrom)) {
- // Вычисляем новые границы интервала
- $newCalculatedDateFrom = date('Y-m-d', min($existingDateFrom, $newDateFrom));
- $newCalculatedDateTo = date('Y-m-d', max($existingDateTo, $newDateTo));
-
- // Проверяем, изменились ли даты
- if ($existingRecord->date_from !== $newCalculatedDateFrom ||
- $existingRecord->date_to !== $newCalculatedDateTo) {
- // Расширяем интервал только если данные изменились
- $existingRecord->date_from = $newCalculatedDateFrom;
- $existingRecord->date_to = $newCalculatedDateTo;
- $existingRecord->updated_at = date('Y-m-d H:i:s');
+ ->orderBy(['date_from' => SORT_ASC])
+ ->all();
+
+ $newDateFrom = strtotime($row['date_from']);
+ $newDateTo = strtotime($row['date_to']);
+ $recordUpdated = false;
+
+ if (!empty($existingRecords)) {
+ // Проверяем каждый существующий интервал
+ foreach ($existingRecords as $existingRecord) {
+ $existingDateFrom = strtotime($existingRecord->date_from);
+ $existingDateTo = strtotime($existingRecord->date_to);
+
+ // Проверяем, примыкают ли интервалы (разница <= 1 день) или пересекаются
+ $daysBetween = min(
+ abs($newDateFrom - $existingDateTo) / 86400,
+ abs($existingDateFrom - $newDateTo) / 86400
+ );
+
+ if ($daysBetween <= 1 ||
+ ($newDateFrom <= $existingDateTo && $newDateTo >= $existingDateFrom)) {
+ // Вычисляем новые границы интервала
+ $newCalculatedDateFrom = date('Y-m-d', min($existingDateFrom, $newDateFrom));
+ $newCalculatedDateTo = date('Y-m-d', max($existingDateTo, $newDateTo));
- if ($existingRecord->validate()) {
- $existingRecord->save();
+ // Проверяем, изменились ли даты
+ if ($existingRecord->date_from !== $newCalculatedDateFrom ||
+ $existingRecord->date_to !== $newCalculatedDateTo) {
+ // Расширяем интервал только если данные изменились
+ $existingRecord->date_from = $newCalculatedDateFrom;
+ $existingRecord->date_to = $newCalculatedDateTo;
+ $existingRecord->updated_at = date('Y-m-d H:i:s');
+
+ if ($existingRecord->validate()) {
+ $existingRecord->save();
+ }
}
- }
- } else {
- // Интервалы не примыкают - создаем новую запись
- $rowSelfCost = new SelfCostProductDynamic();
- $rowSelfCost->product_guid = $row['product_guid'];
- $rowSelfCost->store_id = $row['store_id'];
- $rowSelfCost->price = $row['price'];
- $rowSelfCost->date_from = $row['date_from'];
- $rowSelfCost->date_to = $row['date_to'];
- $rowSelfCost->updated_at = date('Y-m-d H:i:s');
-
- if ($rowSelfCost->validate()) {
- $rowSelfCost->save();
+
+ $recordUpdated = true;
+ break; // Нашли подходящий интервал, выходим из цикла
}
}
- } else {
- // Записи нет - создаем новую
+ }
+
+ // Если не удалось обновить ни одну запись - создаем новую
+ if (!$recordUpdated) {
$rowSelfCost = new SelfCostProductDynamic();
$rowSelfCost->product_guid = $row['product_guid'];
$rowSelfCost->store_id = $row['store_id'];
public static function UpdateResult($values)
{
foreach ($values as $row) {
- // Ищем существующие записи с теми же параметрами (product_guid, store_id, price)
- $existingRecord = SelfCostProductDynamic::find()
+ // Ищем ВСЕ существующие записи с теми же параметрами (product_guid, store_id, price)
+ $existingRecords = SelfCostProductDynamic::find()
->where([
'product_guid' => $row['product_guid'],
'store_id' => $row['store_id'],
'price' => $row['price']
])
- ->one();
-
- if (!empty($existingRecord)) {
- // Запись найдена - проверяем, примыкает ли новая дата к интервалу
- $existingDateFrom = strtotime($existingRecord->date_from);
- $existingDateTo = strtotime($existingRecord->date_to);
- $newDate = strtotime($row['date']);
-
- // Проверяем, примыкает ли новая дата (±1 день от границ интервала)
- $dayBeforeDateFrom = strtotime('-1 day', $existingDateFrom);
- $dayAfterDateTo = strtotime('+1 day', $existingDateTo);
-
- if ($newDate >= $dayBeforeDateFrom && $newDate <= $dayAfterDateTo) {
- // Новая дата примыкает к интервалу или находится внутри него
- $newCalculatedDateFrom = date('Y-m-d', min($existingDateFrom, $newDate));
- $newCalculatedDateTo = date('Y-m-d', max($existingDateTo, $newDate));
-
- // Проверяем, изменились ли даты
- if ($existingRecord->date_from !== $newCalculatedDateFrom ||
- $existingRecord->date_to !== $newCalculatedDateTo) {
- // Расширяем интервал только если данные изменились
- $existingRecord->date_from = $newCalculatedDateFrom;
- $existingRecord->date_to = $newCalculatedDateTo;
- $existingRecord->updated_at = $row['updated_at'];
-
- if ($existingRecord->validate()) {
- $existingRecord->save();
+ ->orderBy(['date_from' => SORT_ASC])
+ ->all();
+
+ $newDate = strtotime($row['date']);
+ $recordUpdated = false;
+
+ if (!empty($existingRecords)) {
+ // Проверяем каждый существующий интервал
+ foreach ($existingRecords as $existingRecord) {
+ $existingDateFrom = strtotime($existingRecord->date_from);
+ $existingDateTo = strtotime($existingRecord->date_to);
+
+ // Проверяем, примыкает ли новая дата (±1 день от границ интервала) или находится внутри
+ $dayBeforeDateFrom = strtotime('-1 day', $existingDateFrom);
+ $dayAfterDateTo = strtotime('+1 day', $existingDateTo);
+
+ if ($newDate >= $dayBeforeDateFrom && $newDate <= $dayAfterDateTo) {
+ // Новая дата примыкает к интервалу или находится внутри него
+ $newCalculatedDateFrom = date('Y-m-d', min($existingDateFrom, $newDate));
+ $newCalculatedDateTo = date('Y-m-d', max($existingDateTo, $newDate));
+
+ // Проверяем, изменились ли даты
+ if ($existingRecord->date_from !== $newCalculatedDateFrom ||
+ $existingRecord->date_to !== $newCalculatedDateTo) {
+ // Расширяем интервал только если данные изменились
+ $existingRecord->date_from = $newCalculatedDateFrom;
+ $existingRecord->date_to = $newCalculatedDateTo;
+ $existingRecord->updated_at = $row['updated_at'];
+
+ if ($existingRecord->validate()) {
+ $existingRecord->save();
+ }
}
- }
- } else {
- // Дата не примыкает к интервалу - создаем новую запись
- $newRecord = new SelfCostProductDynamic();
- $newRecord->product_guid = $row['product_guid'];
- $newRecord->store_id = $row['store_id'];
- $newRecord->price = $row['price'];
- $newRecord->date_from = $row['date'];
- $newRecord->date_to = $row['date'];
- $newRecord->updated_at = $row['updated_at'];
-
- if ($newRecord->validate()) {
- $newRecord->save();
+
+ $recordUpdated = true;
+ break; // Нашли подходящий интервал, выходим из цикла
}
}
- } else {
- // Записи нет - создаем новую
+ }
+
+ // Если не удалось обновить ни одну запись - создаем новую
+ if (!$recordUpdated) {
$newRecord = new SelfCostProductDynamic();
$newRecord->product_guid = $row['product_guid'];
$newRecord->store_id = $row['store_id'];
}
}
}
+
+ /**
+ * Объединяет дублирующиеся записи с одинаковыми параметрами в единые интервалы
+ * Используется для очистки дублей, созданных старой версией UpdateResult
+ */
+ public static function MergeDuplicates()
+ {
+ // Находим все уникальные комбинации product_guid, store_id, price
+ $uniqueCombinations = SelfCostProductDynamic::find()
+ ->select(['product_guid', 'store_id', 'price'])
+ ->distinct()
+ ->asArray()
+ ->all();
+
+ foreach ($uniqueCombinations as $combination) {
+ // Получаем все записи для этой комбинации, отсортированные по дате
+ $records = SelfCostProductDynamic::find()
+ ->where([
+ 'product_guid' => $combination['product_guid'],
+ 'store_id' => $combination['store_id'],
+ 'price' => $combination['price']
+ ])
+ ->orderBy(['date_from' => SORT_ASC])
+ ->all();
+
+ if (count($records) <= 1) {
+ continue; // Нет дублей, переходим к следующей комбинации
+ }
+
+ // Объединяем интервалы
+ $mergedIntervals = [];
+ $currentInterval = null;
+
+ foreach ($records as $record) {
+ $dateFrom = strtotime($record->date_from);
+ $dateTo = strtotime($record->date_to);
+
+ if ($currentInterval === null) {
+ // Первый интервал
+ $currentInterval = [
+ 'date_from' => $dateFrom,
+ 'date_to' => $dateTo,
+ 'record' => $record
+ ];
+ } else {
+ // Проверяем, примыкает ли или пересекается ли с текущим интервалом
+ $dayAfterCurrentEnd = strtotime('+1 day', $currentInterval['date_to']);
+
+ if ($dateFrom <= $dayAfterCurrentEnd) {
+ // Интервалы примыкают или пересекаются - объединяем
+ $currentInterval['date_to'] = max($currentInterval['date_to'], $dateTo);
+ } else {
+ // Интервалы не примыкают - сохраняем текущий и начинаем новый
+ $mergedIntervals[] = $currentInterval;
+ $currentInterval = [
+ 'date_from' => $dateFrom,
+ 'date_to' => $dateTo,
+ 'record' => $record
+ ];
+ }
+ }
+ }
+
+ // Добавляем последний интервал
+ if ($currentInterval !== null) {
+ $mergedIntervals[] = $currentInterval;
+ }
+
+ // Обновляем базу данных: оставляем только объединенные интервалы
+ // Первый интервал обновляем, остальные записи удаляем
+ $keepIds = [];
+ foreach ($mergedIntervals as $interval) {
+ $record = $interval['record'];
+ $record->date_from = date('Y-m-d', $interval['date_from']);
+ $record->date_to = date('Y-m-d', $interval['date_to']);
+ $record->updated_at = date('Y-m-d H:i:s');
+
+ if ($record->validate()) {
+ $record->save();
+ }
+ $keepIds[] = $record->id;
+ }
+
+ // Удаляем все остальные записи для этой комбинации
+ SelfCostProductDynamic::deleteAll([
+ 'and',
+ [
+ 'product_guid' => $combination['product_guid'],
+ 'store_id' => $combination['store_id'],
+ 'price' => $combination['price']
+ ],
+ ['not in', 'id', $keepIds]
+ ]);
+ }
+ }