Repository: netbox-community/netbox

Issue:
Possibility to change device when editing inventory item.
### NetBox version

v3.3.4

### Feature type

Change to existing functionality

### Proposed functionality

Return ability to change device when editing inventory item.

### Use case

We are using inventory items to account transceivers. When transceiver is moved to another device it should be reflected in netbox. [Here](https://github.com/netbox-community/netbox/issues/10437) it is said that this "feature" was removed for some reason, but if we have to recreate items we will lose history and the hole process of moving items becomes very burdensome.

![inventory_item](https://user-images.githubusercontent.com/3961842/191916313-f35d3259-1d09-4bd9-a475-f3b33a3430f4.png)


### Database changes

_No response_

### External dependencies

_No response_


Discussion:
Only Inventory items would require this ability to be reassigned, right ?
Sorry, I did not quite understand what you mean by "only". Things like device modules should also be able to be reassigned. Or I got you wrong? 
Argh. Did this functionality go away?  Perhaps as part of some larger change to standardise a bunch of forms?

I currently use inventory items to track line cards etc and until I'm able to migrate to using Modules, will continue to do so. Line cards move between devices from time to time and not having the ability to make this change without deleting and re-creating the inventory item is going to pain me greatly.
> Argh. Did this functionality go away? Perhaps as part of some larger change to standardise a bunch of forms?
> 
> I currently use inventory items to track line cards etc and until I'm able to migrate to using Modules, will continue to do so. Line cards move between devices from time to time and not having the ability to make this change without deleting and re-creating the inventory item is going to pain me greatly.

Yes it was removed. Besides the pain we will lose all history for the item. So we will not be to track them.
We also made extensive use of this feature until it was removed.  It would help a lot to have it added back. 
Is there a reason that this was removed? With an inventory tracking program, the ability to track device history across locations is heavily desired.
It's still possible to change the device id via. the API. At the very least we should align the UI and API.

See also: #9898
> It's still possible to change the device id via. the API. At the very least we should align the UI and API.
> 
> See also: #9898

Thanks for the link. So moving inventory item was disabled due to this bug?
If we align UI and API we will not be able to move items with api also?
I updated yesterday from version 3.3.2 to 3.3.8 and I see this issue too. 
Interesting thing is if you want to change it by bulk edit button, then it works.

Resolving patch:
diff --git a/netbox/dcim/forms/models.py b/netbox/dcim/forms/models.py
--- a/netbox/dcim/forms/models.py
+++ b/netbox/dcim/forms/models.py
@@ -1610,6 +1610,13 @@ class InventoryItemForm(DeviceComponentForm):
         ('Hardware', ('manufacturer', 'part_id', 'serial', 'asset_tag')),
     )
 
+    def __init__(self, *args, **kwargs):
+        super().__init__(*args, **kwargs)
+
+        # Specifically allow editing the device of IntentoryItems
+        if self.instance.pk:
+            self.fields['device'].disabled = False
+
     class Meta:
         model = InventoryItem
         fields = [
diff --git a/netbox/dcim/models/device_components.py b/netbox/dcim/models/device_components.py
--- a/netbox/dcim/models/device_components.py
+++ b/netbox/dcim/models/device_components.py
@@ -1153,3 +1153,20 @@ def clean(self):
             raise ValidationError({
                 "parent": "Cannot assign self as parent."
             })
+
+        # Validation for moving InventoryItems
+        if self.pk:
+            # Cannot move an InventoryItem to another device if it has a parent
+            if self.parent and self.parent.device != self.device:
+                raise ValidationError({
+                    "parent": "Parent inventory item does not belong to the same device."
+                })
+
+            # Prevent moving InventoryItems with children
+            first_child = self.get_children().first()
+            if first_child and first_child.device != self.device:
+                raise ValidationError("Cannot move an inventory item with dependent children")
+
+            # When moving an InventoryItem to another device, remove any associated component
+            if self.component and self.component.device != self.device:
+                self.component = None


Test patch: