| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212 |
- <?php
- declare(strict_types=1);
- namespace Tests\Unit\Services\Import;
- use App\Models\Import;
- use App\Models\Role;
- use App\Models\User;
- use App\Services\Export\ExportCommonCatalogService;
- use App\Services\Import\ImportCommonCatalogService;
- use Illuminate\Foundation\Testing\RefreshDatabase;
- use Illuminate\Http\UploadedFile;
- use Illuminate\Support\Facades\Storage;
- use PhpOffice\PhpSpreadsheet\Cell\DataType;
- use PhpOffice\PhpSpreadsheet\Cell\Coordinate;
- use PhpOffice\PhpSpreadsheet\Spreadsheet;
- use PhpOffice\PhpSpreadsheet\Worksheet\Drawing;
- use PhpOffice\PhpSpreadsheet\Writer\Xlsx;
- use RuntimeException;
- use Tests\TestCase;
- class ImportCommonCatalogServiceTest extends TestCase
- {
- use RefreshDatabase;
- protected bool $seed = true;
- public function test_import_creates_and_updates_by_article_while_preserving_leading_zeroes(): void
- {
- Storage::fake('upload');
- Storage::fake('public');
- $user = User::factory()->create(['role' => Role::ADMIN]);
- $import = $this->createImport($user, 'Оборудование для благоустройства', withImage: true);
- $this->assertTrue((new ImportCommonCatalogService($import, $user->id))->handle());
- $this->assertDatabaseHas('common_catalog_items', [
- 'article' => '0254',
- 'calculator_name' => 'Оборудование для благоустройства',
- 'places' => 38,
- 'builders_price' => 141850000,
- 'recommended_plus_10_price' => 188802350,
- ]);
- $item = \App\Models\CommonCatalogItem::query()->firstOrFail();
- $this->assertNotNull($item->imageFile);
- Storage::disk('public')->assertExists($item->imageFile->path);
- $secondImport = $this->createImport($user, 'Обновлённое наименование');
- $this->assertTrue((new ImportCommonCatalogService($secondImport, $user->id))->handle());
- $this->assertDatabaseCount('common_catalog_items', 1);
- $this->assertDatabaseHas('common_catalog_items', [
- 'article' => '0254',
- 'calculator_name' => 'Обновлённое наименование',
- ]);
- }
- public function test_import_accepts_template_header_with_line_break(): void
- {
- Storage::fake('upload');
- $user = User::factory()->create(['role' => Role::ADMIN]);
- $import = $this->createImport($user, 'Тест', "Единица измерения\nгабаритов");
- $this->assertTrue((new ImportCommonCatalogService($import, $user->id))->handle());
- $this->assertSame('DONE', $import->refresh()->status);
- }
- public function test_import_accepts_real_catalog_row_without_calculator_name(): void
- {
- Storage::fake('upload');
- $user = User::factory()->create(['role' => Role::ADMIN]);
- $import = $this->createImport($user, null);
- $this->assertTrue((new ImportCommonCatalogService($import, $user->id))->handle());
- $this->assertDatabaseHas('common_catalog_items', [
- 'article' => '0254',
- 'calculator_name' => null,
- ]);
- $this->assertStringContainsString('ошибок: 0', (string) $import->refresh()->result);
- }
- public function test_import_does_not_change_prices_without_field_permission(): void
- {
- Storage::fake('upload');
- $user = User::factory()->create(['role' => Role::ASSISTANT_HEAD]);
- $item = \App\Models\CommonCatalogItem::factory()->create([
- 'article' => '0254',
- 'calculator_name' => 'Старое наименование',
- 'builders_price' => 100,
- ]);
- $import = $this->createImport($user, 'Новое наименование');
- $this->assertTrue((new ImportCommonCatalogService($import, $user->id))->handle());
- $item->refresh();
- $this->assertSame('Новое наименование', $item->calculator_name);
- $this->assertSame(100.0, $item->builders_price);
- }
- public function test_import_preserves_rows_with_same_article_as_named_variants(): void
- {
- Storage::fake('upload');
- $user = User::factory()->create(['role' => Role::ADMIN]);
- $import = $this->createImport(
- $user,
- 'Оборудование игровой площадки',
- duplicateVariant: true,
- );
- $this->assertTrue((new ImportCommonCatalogService($import, $user->id))->handle());
- $this->assertDatabaseCount('common_catalog_items', 2);
- $this->assertDatabaseHas('common_catalog_items', [
- 'article' => '0254',
- 'calculator_name' => 'Оборудование игровой площадки',
- 'builders_price' => 141850000,
- ]);
- $this->assertDatabaseHas('common_catalog_items', [
- 'article' => '0254',
- 'calculator_name' => 'Оборудование игровой площадки (Цинк)',
- 'builders_price' => 162280000,
- ]);
- }
- public function test_import_rejects_wrong_headers_with_clear_error(): void
- {
- Storage::fake('upload');
- $user = User::factory()->create(['role' => Role::ADMIN]);
- $import = $this->createImport($user, 'Тест', 'Неверный заголовок');
- $this->expectException(RuntimeException::class);
- $this->expectExceptionMessage('Некорректные заголовки');
- try {
- (new ImportCommonCatalogService($import, $user->id))->handle();
- } finally {
- $this->assertSame('ERROR', $import->refresh()->status);
- }
- }
- private function createImport(
- User $user,
- ?string $calculatorName,
- string $dimensionHeader = "Единица измерения\nгабаритов",
- bool $withImage = false,
- bool $duplicateVariant = false,
- ): Import {
- $spreadsheet = new Spreadsheet;
- $sheet = $spreadsheet->getActiveSheet();
- $headers = ExportCommonCatalogService::HEADERS;
- $headers[10] = $dimensionHeader;
- $sheet->fromArray($headers, null, 'A1');
- $sheet->fromArray(ExportCommonCatalogService::SUBHEADERS, null, 'A2');
- $sheet->setCellValueExplicit('A3', '0254', DataType::TYPE_STRING);
- $sheet->setCellValue('B3', $calculatorName);
- $sheet->setCellValue('C3', 'Теневой навес');
- $sheet->setCellValue('D3', 'от 180');
- $sheet->setCellValue('E3', '1,37-1,55');
- $sheet->setCellValue('F3', 3.43);
- $sheet->setCellValue('G3', 9.15);
- $sheet->setCellValue('H3', 3.46);
- $sheet->setCellValue('I3', 0);
- $sheet->setCellValue('K3', 'м');
- $sheet->setCellValue('L3', 2153.84);
- $sheet->setCellValue('M3', 7.93);
- $sheet->setCellValue('N3', 38);
- $sheet->setCellValue('P3', '0+');
- $sheet->setCellValue('Q3', 10);
- $sheet->setCellValue('R3', 'шт.');
- $sheet->setCellValue('T3', 'Теневые навесы');
- $sheet->setCellValue('U3', 'Наш Двор');
- $sheet->setCellValue('V3', 'да');
- $sheet->setCellValue('W3', 1418500);
- $sheet->setCellValue('X3', 1489425);
- $sheet->setCellValue('Y3', 1560350);
- $sheet->setCellValue('Z3', 2127750);
- $sheet->setCellValue('AA3', 2837000);
- $sheet->setCellValue('AB3', 3404400);
- $sheet->setCellValue('AC3', 1560350);
- $sheet->setCellValue('AD3', 1888023.50);
- if ($duplicateVariant) {
- for ($index = 1; $index <= 30; $index++) {
- $column = Coordinate::stringFromColumnIndex($index);
- $sheet->setCellValue("{$column}4", $sheet->getCell("{$column}3")->getValue());
- }
- $sheet->setCellValue('B4', $calculatorName.' (Цинк)');
- $sheet->setCellValue('V4', 'нет');
- $sheet->setCellValue('W4', 1622800);
- }
- if ($withImage) {
- $image = UploadedFile::fake()->image('catalog-item.png', 100, 100);
- $drawing = new Drawing;
- $drawing->setPath($image->getPathname());
- $drawing->setCoordinates('S3');
- $drawing->setWorksheet($sheet);
- }
- $filename = 'common_catalog_'.uniqid().'.xlsx';
- $path = Storage::disk('upload')->path($filename);
- (new Xlsx($spreadsheet))->save($path);
- return Import::query()->create([
- 'type' => 'common_catalog',
- 'filename' => $filename,
- 'status' => 'new',
- 'user_id' => $user->id,
- ]);
- }
- }
|