diff --git a/app/app/Services/Supplier/Import/SupplierProjectImporter.php b/app/app/Services/Supplier/Import/SupplierProjectImporter.php index 2bab067a..3aeb9f70 100644 --- a/app/app/Services/Supplier/Import/SupplierProjectImporter.php +++ b/app/app/Services/Supplier/Import/SupplierProjectImporter.php @@ -74,11 +74,19 @@ class SupplierProjectImporter ]; } + if (($row['regions_reverse'] ?? false) === true) { + $skipped[] = ['reason' => 'regions_exclude', 'label' => $identifier]; + $groups[$key]['__excluded'] = true; + } $this->accumulateRow($groups[$key], $row, $platform); } $planned = []; foreach ($groups as $g) { + if (($g['__excluded'] ?? false) === true) { + continue; + } + unset($g['__excluded']); unset($g['has_all_russia']); $g['delivery_days_mask'] = $g['workdays_mask'] === 0 ? 127 : $g['workdays_mask']; unset($g['workdays_mask']); diff --git a/app/tests/Feature/Supplier/SupplierProjectImporterTest.php b/app/tests/Feature/Supplier/SupplierProjectImporterTest.php index 22e01e9e..0f1aeaa0 100644 --- a/app/tests/Feature/Supplier/SupplierProjectImporterTest.php +++ b/app/tests/Feature/Supplier/SupplierProjectImporterTest.php @@ -63,3 +63,38 @@ test('buildPlan skips dop2 (unsupported source) and reports it', function (): vo expect($plan['planned'])->toHaveCount(0); expect(collect($plan['skipped'])->pluck('reason'))->toContain('unsupported_source'); }); + +test('buildPlan reverse-maps regions and unions across platforms', function (): void { + $tenant = Tenant::factory()->create(); + + $plan = importerWithRows([ + ['id' => '7001', 'src' => 'rt', 'type' => 'hosts', 'content' => 'okna.ru', 'tag' => 'Окна', 'lim' => '3', 'status' => true, 'regions' => '24', 'workdays' => [], 'regions_reverse' => false], + ['id' => '7002', 'src' => 'bl', 'type' => 'hosts', 'content' => 'okna.ru', 'tag' => 'Окна', 'lim' => '3', 'status' => true, 'regions' => '77', 'workdays' => [], 'regions_reverse' => false], + ['id' => '7003', 'src' => 'mt', 'type' => 'hosts', 'content' => 'okna.ru', 'tag' => 'Окна', 'lim' => '3', 'status' => true, 'regions' => '24', 'workdays' => [], 'regions_reverse' => false], + ])->buildPlan($tenant->id); + + expect($plan['planned'][0]['regions'])->toBe([29, 82]); +}); + +test('buildPlan treats any empty-regions platform as all-Russia', function (): void { + $tenant = Tenant::factory()->create(); + + $plan = importerWithRows([ + ['id' => '7101', 'src' => 'rt', 'type' => 'hosts', 'content' => 'all.ru', 'tag' => 'A', 'lim' => '3', 'status' => true, 'regions' => '24', 'workdays' => [], 'regions_reverse' => false], + ['id' => '7102', 'src' => 'bl', 'type' => 'hosts', 'content' => 'all.ru', 'tag' => 'A', 'lim' => '3', 'status' => true, 'regions' => '', 'workdays' => [], 'regions_reverse' => false], + ])->buildPlan($tenant->id); + + expect($plan['planned'][0]['regions'])->toBe([]); +}); + +test('buildPlan skips group when any active row has regions_reverse=true', function (): void { + $tenant = Tenant::factory()->create(); + + $plan = importerWithRows([ + ['id' => '7201', 'src' => 'rt', 'type' => 'hosts', 'content' => 'excl.ru', 'tag' => 'A', 'lim' => '3', 'status' => true, 'regions' => '24', 'workdays' => [], 'regions_reverse' => true], + ['id' => '7202', 'src' => 'bl', 'type' => 'hosts', 'content' => 'excl.ru', 'tag' => 'A', 'lim' => '3', 'status' => true, 'regions' => '24', 'workdays' => [], 'regions_reverse' => false], + ])->buildPlan($tenant->id); + + expect($plan['planned'])->toHaveCount(0); + expect(collect($plan['skipped'])->pluck('reason'))->toContain('regions_exclude'); +});