Repository: netbox-community/netbox

Issue:
Allow specifying Component on Inventory Item import
### NetBox version

v3.2.2

### Feature type

Change to existing functionality

### Proposed functionality

The work that was done in #7846 is really useful for tracking things like SFPs that cannot currently be modeled as modules due to lack of module nesting. Unfortunately, there does not appear to be a way to assign inventory items to components in bulk. I would propose adding something like *component* and *component_type* fields to the *Inventory Item* import form in order to facilitate this function.

### Use case

Populating inventory items for components one at a time is tedious and time-consuming. It would be nice to be able to use the existing bulk import functionality to make this task easier.

### Database changes

None

### External dependencies

None


Discussion:
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. NetBox is governed by a small group of core maintainers which means not all opened issues may receive direct feedback. **Do not** attempt to circumvent this process by "bumping" the issue; doing so will result in its immediate closure and you may be barred from participating in any future discussions. Please see our [contributing guide](https://github.com/netbox-community/netbox/blob/develop/CONTRIBUTING.md).

Resolving patch:
diff --git a/netbox/dcim/forms/bulk_import.py b/netbox/dcim/forms/bulk_import.py
--- a/netbox/dcim/forms/bulk_import.py
+++ b/netbox/dcim/forms/bulk_import.py
@@ -885,12 +885,22 @@ class InventoryItemImportForm(NetBoxModelImportForm):
         required=False,
         help_text=_('Parent inventory item')
     )
+    component_type = CSVContentTypeField(
+        queryset=ContentType.objects.all(),
+        limit_choices_to=MODULAR_COMPONENT_MODELS,
+        required=False,
+        help_text=_('Component Type')
+    )
+    component_name = forms.CharField(
+        required=False,
+        help_text=_('Component Name')
+    )
 
     class Meta:
         model = InventoryItem
         fields = (
             'device', 'name', 'label', 'role', 'manufacturer', 'part_id', 'serial', 'asset_tag', 'discovered',
-            'description', 'tags'
+            'description', 'tags', 'component_type', 'component_name',
         )
 
     def __init__(self, *args, **kwargs):
@@ -908,6 +918,24 @@ def __init__(self, *args, **kwargs):
         else:
             self.fields['parent'].queryset = InventoryItem.objects.none()
 
+    def clean_component_name(self):
+        content_type = self.cleaned_data.get('component_type')
+        component_name = self.cleaned_data.get('component_name')
+        device = self.cleaned_data.get("device")
+
+        if not device and hasattr(self, 'instance'):
+            device = self.instance.device
+
+        if not all([device, content_type, component_name]):
+            return None
+
+        model = content_type.model_class()
+        try:
+            component = model.objects.get(device=device, name=component_name)
+            self.instance.component = component
+        except ObjectDoesNotExist:
+            raise forms.ValidationError(f"Component not found: {device} - {component_name}")
+
 
 #
 # Device component roles


Test patch: