diff --git a/app/Http/Controllers/Api/ImportController.php b/app/Http/Controllers/Api/ImportController.php index 3b8205ea4d..69703770f3 100644 --- a/app/Http/Controllers/Api/ImportController.php +++ b/app/Http/Controllers/Api/ImportController.php @@ -69,7 +69,7 @@ class ImportController extends Controller if (function_exists('iconv')) { $file_contents = $file->getContent(); //TODO - this *does* load the whole file in RAM, but we need that to be able to 'iconv' it? $encoding = $detector->getEncoding($file_contents); - \Log::warning("Discovered encoding: $encoding in uploaded CSV"); + \Log::debug("Discovered encoding: $encoding in uploaded CSV"); $reader = null; if (strcasecmp($encoding, 'UTF-8') != 0) { $transliterated = false; @@ -103,7 +103,7 @@ class ImportController extends Controller $reader = Reader::createFromFileObject($file->openFile('r')); //file pointer leak? try { - $import->header_row = $reader->fetchOne(0); + $import->header_row = $reader->nth(0); } catch (JsonEncodingException $e) { return response()->json( Helper::formatStandardApiResponse( diff --git a/app/Importer/AssetModelImporter.php b/app/Importer/AssetModelImporter.php index b60ad1d0fb..b458742313 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'))->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 58da61a3bf..dd80eec2cc 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..d79062b2f6 100644 --- a/tests/Feature/Importing/Api/ImportAssetModelsTest.php +++ b/tests/Feature/Importing/Api/ImportAssetModelsTest.php @@ -113,28 +113,28 @@ 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(); + $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); - $this->assertEquals( - Arr::except($assetmodel->attributesToArray(), array_merge($updatedAttributes, $assetmodel->getDates())), - Arr::except($updatedAssetmodel->attributesToArray(), array_merge($updatedAttributes, $assetmodel->getDates())), - ); } + }