diff --git a/app/Importer/AssetModelImporter.php b/app/Importer/AssetModelImporter.php index 1e19dade1d..6c74a2c356 100644 --- a/app/Importer/AssetModelImporter.php +++ b/app/Importer/AssetModelImporter.php @@ -40,11 +40,32 @@ class AssetModelImporter extends ItemImporter { $editingAssetModel = false; - $assetModel = AssetModel::where('name', '=', $this->findCsvMatch($row, 'name'))->where('model_number', '=', $this->findCsvMatch($row, 'model_number'))->first(); + + /** + * This part gets a little confusing, since folks might be importing multiple models with the same name and different model numbers for the first time + * or they might be wanting to update existing models with new model numbers. + */ + + // They are not trying to update existing models, so we'll check for duplicates with model name *and* number + if (! $this->updating) { + $this->log('Finding model by name and model number: '.$this->findCsvMatch($row, 'name').' / '.$this->findCsvMatch($row, 'model_number')); + $assetModel = AssetModel::where('name', '=', $this->findCsvMatch($row, 'name'))->where('model_number', '=', $this->findCsvMatch($row, 'model_number'))->first(); + } else { + + if ($this->findCsvMatch($row, 'id')!='') { + // Override model if an ID was given + $this->log('Finding model by ID: '.$this->findCsvMatch($row, 'id')); + $assetModel = AssetModel::find($this->findCsvMatch($row, 'id')); + } else { + $this->log('Finding model by name: '.$this->findCsvMatch($row, 'name')); + $assetModel = AssetModel::where('name', '=', $this->findCsvMatch($row, 'name'))->first(); + } + } + if ($assetModel) { if (! $this->updating) { - $this->log('A matching Model '.$this->item['name'].' already exists'); + $this->log('A matching Model '.$this->item['name'].' already exists and we are not updating. Skipping.'); return; } diff --git a/app/Livewire/Importer.php b/app/Livewire/Importer.php index d86b2469c1..ee0aa4b69b 100644 --- a/app/Livewire/Importer.php +++ b/app/Livewire/Importer.php @@ -403,6 +403,7 @@ class Importer extends Component $this->assetmodels_fields = [ + 'id' => trans('general.id'), 'category' => trans('general.category'), 'eol' => trans('general.eol'), 'fieldset' => trans('admin/models/general.fieldset'), diff --git a/tests/Feature/Importing/Api/ImportAssetModelsTest.php b/tests/Feature/Importing/Api/ImportAssetModelsTest.php index a3a0a9ca4d..8ff4f8deb9 100644 --- a/tests/Feature/Importing/Api/ImportAssetModelsTest.php +++ b/tests/Feature/Importing/Api/ImportAssetModelsTest.php @@ -113,28 +113,53 @@ class ImportAssetModelsTest extends ImportDataTestCase implements TestsPermissio #[Test] public function updateAssetModelFromImport(): void { - $assetmodel = AssetModel::factory()->create()->refresh(); - $category = Category::find($assetmodel->category->name); - $importFileBuilder = ImportFileBuilder::new(['name' => $assetmodel->name, 'model_number' => Str::random(), 'category' => $category]); + $assetmodel = AssetModel::factory()->create(['model_number' => Str::random()]); + $category = Category::find($assetmodel->category_id); + $importFileBuilder = ImportFileBuilder::new(['name' => $assetmodel->name, 'model_number' => Str::random(), 'category' => $category->name]); $row = $importFileBuilder->firstRow(); $import = Import::factory()->assetmodel()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); $this->actingAsForApi(User::factory()->superuser()->create()); - $this->importFileResponse(['import' => $import->id, 'import-update' => true])->assertOk(); + $this->importFileResponse(['import' => $import->id, 'import-update' => true]) + ->assertOk() + ->assertExactJson([ + 'payload' => null, + 'status' => 'success', + 'messages' => ['redirect_url' => route('models.index')] + ]); $updatedAssetmodel = AssetModel::query()->find($assetmodel->id); - $updatedAttributes = [ - 'name', - 'model_number' - ]; $this->assertEquals($row['model_number'], $updatedAssetmodel->model_number); + $this->assertEquals($row['name'], $updatedAssetmodel->name); + + } + + #[Test] + public function updateAssetModelFromImportById(): void + { + $assetmodel = AssetModel::factory()->create(['name' => Str::random(), 'model_number' => Str::random()]); + $category = Category::find($assetmodel->category_id); + $importFileBuilder = ImportFileBuilder::new(['id' => $assetmodel->id, 'name' => Str::random(), 'model_number' => Str::random(), 'category' => $category->name]); + + $row = $importFileBuilder->firstRow(); + $import = Import::factory()->assetmodel()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); + + $this->actingAsForApi(User::factory()->superuser()->create()); + $this->importFileResponse(['import' => $import->id, 'import-update' => true]) + ->assertOk() + ->assertExactJson([ + 'payload' => null, + 'status' => 'success', + 'messages' => ['redirect_url' => route('models.index')] + ]); + + $updatedAssetmodel = AssetModel::query()->find($assetmodel->id); + + $this->assertEquals($row['model_number'], $updatedAssetmodel->model_number); + $this->assertEquals($row['name'], $updatedAssetmodel->name); - $this->assertEquals( - Arr::except($assetmodel->attributesToArray(), array_merge($updatedAttributes, $assetmodel->getDates())), - Arr::except($updatedAssetmodel->attributesToArray(), array_merge($updatedAttributes, $assetmodel->getDates())), - ); } } diff --git a/tests/Support/Importing/AssetModelsImportFileBuilder.php b/tests/Support/Importing/AssetModelsImportFileBuilder.php index 615e329e47..ee76c263f4 100644 --- a/tests/Support/Importing/AssetModelsImportFileBuilder.php +++ b/tests/Support/Importing/AssetModelsImportFileBuilder.php @@ -27,6 +27,7 @@ class AssetModelsImportFileBuilder extends FileBuilder protected function getDictionary(): array { return [ + 'id' => 'ID', 'name' => 'Name', 'category' => 'Category', 'manufacturer' => 'Manufacturer', @@ -48,6 +49,7 @@ class AssetModelsImportFileBuilder extends FileBuilder $faker = fake(); return [ + 'id' => 1, 'name' => $faker->catchPhrase, 'category' => Str::random(), 'model_number' => $faker->creditCardNumber(),