diff --git a/InvenTree/company/models.py b/InvenTree/company/models.py index 2531781631..b0bb8caaa5 100644 --- a/InvenTree/company/models.py +++ b/InvenTree/company/models.py @@ -501,6 +501,34 @@ class SupplierPart(models.Model): 'manufacturer_part': _("Linked manufacturer part must reference the same base part"), }) + def save(self, *args, **kwargs): + """ Overriding save method to connect an existing ManufacturerPart """ + + manufacturer_part = None + + if all(key in kwargs for key in ('manufacturer', 'MPN')): + manufacturer_name = kwargs.pop('manufacturer') + MPN = kwargs.pop('MPN') + + # Retrieve manufacturer part + try: + manufacturer_part = ManufacturerPart.objects.get(manufacturer__name=manufacturer_name, MPN=MPN) + except (ValueError, Company.DoesNotExist): + # ManufacturerPart does not exist + pass + + if manufacturer_part: + if not self.manufacturer_part: + # Connect ManufacturerPart to SupplierPart + self.manufacturer_part = manufacturer_part + else: + raise ValidationError(f'SupplierPart {self.__str__} is already linked to {self.manufacturer_part}') + + self.clean() + self.validate_unique() + + super().save(*args, **kwargs) + part = models.ForeignKey('part.Part', on_delete=models.CASCADE, related_name='supplier_parts', verbose_name=_('Base Part'), diff --git a/InvenTree/company/serializers.py b/InvenTree/company/serializers.py index e9f13d021d..a471b87a90 100644 --- a/InvenTree/company/serializers.py +++ b/InvenTree/company/serializers.py @@ -204,9 +204,9 @@ class SupplierPartSerializer(InvenTreeModelSerializer): supplier = serializers.PrimaryKeyRelatedField(queryset=Company.objects.filter(is_supplier=True)) - manufacturer = serializers.PrimaryKeyRelatedField(source='manufacturer_part.manufacturer', read_only=True) + manufacturer = serializers.CharField(read_only=True) - MPN = serializers.StringRelatedField(source='manufacturer_part.MPN') + MPN = serializers.CharField(read_only=True) manufacturer_part_detail = ManufacturerPartSerializer(source='manufacturer_part', read_only=True) @@ -231,6 +231,25 @@ class SupplierPartSerializer(InvenTreeModelSerializer): 'supplier_detail', ] + def create(self, validated_data): + """ Extract manufacturer data and process ManufacturerPart """ + + # Create SupplierPart + supplier_part = super().create(validated_data) + + # Get ManufacturerPart raw data (unvalidated) + manufacturer = self.initial_data.get('manufacturer', None) + MPN = self.initial_data.get('MPN', None) + + if manufacturer and MPN: + kwargs = { + 'manufacturer': manufacturer, + 'MPN': MPN, + } + supplier_part.save(**kwargs) + + return supplier_part + class SupplierPriceBreakSerializer(InvenTreeModelSerializer): """ Serializer for SupplierPriceBreak object """ diff --git a/InvenTree/templates/js/translated/company.js b/InvenTree/templates/js/translated/company.js index 4ecea2c595..9c67e77db7 100644 --- a/InvenTree/templates/js/translated/company.js +++ b/InvenTree/templates/js/translated/company.js @@ -744,12 +744,12 @@ function loadSupplierPartTable(table, url, options) { visible: params['manufacturer_detail'], switchable: params['manufacturer_detail'], sortable: true, - field: 'manufacturer', + field: 'manufacturer_detail.name', title: '{% trans "Manufacturer" %}', formatter: function(value, row, index, field) { if (value && row.manufacturer_detail) { - var name = row.manufacturer_detail.name; - var url = `/company/${value}/`; + var name = value; + var url = `/company/${row.manufacturer_detail.pk}/`; var html = imageHoverIcon(row.manufacturer_detail.image) + renderLink(name, url); return html; @@ -762,7 +762,7 @@ function loadSupplierPartTable(table, url, options) { visible: params['manufacturer_detail'], switchable: params['manufacturer_detail'], sortable: true, - field: 'MPN', + field: 'manufacturer_part_detail.MPN', title: '{% trans "MPN" %}', formatter: function(value, row, index, field) { if (value && row.manufacturer_part) {