From 1bf49a14583f0037e064fe8e7f795ef911c64641 Mon Sep 17 00:00:00 2001 From: eeintech Date: Thu, 5 Aug 2021 14:06:31 -0400 Subject: [PATCH 1/2] Re-added ability to link manufacturer part to supplier part via API --- InvenTree/company/models.py | 53 ++++++++++++++++++++++++++++++++ InvenTree/company/serializers.py | 18 +++++++++++ 2 files changed, 71 insertions(+) diff --git a/InvenTree/company/models.py b/InvenTree/company/models.py index 3b731381b8..778e00cde1 100644 --- a/InvenTree/company/models.py +++ b/InvenTree/company/models.py @@ -9,7 +9,9 @@ import os from django.utils.translation import ugettext_lazy as _ from django.core.validators import MinValueValidator +from django.core.exceptions import ValidationError from django.db import models +from django.db.utils import IntegrityError from django.db.models import Sum, Q, UniqueConstraint from django.apps import apps @@ -473,6 +475,57 @@ class SupplierPart(models.Model): def get_absolute_url(self): return reverse('supplier-part-detail', kwargs={'pk': self.id}) + def save(self, *args, **kwargs): + """ Overriding save method to process the linked ManufacturerPart + """ + + if 'manufacturer' in kwargs: + manufacturer_id = kwargs.pop('manufacturer') + + try: + manufacturer = Company.objects.get(pk=int(manufacturer_id)) + except (ValueError, Company.DoesNotExist): + manufacturer = None + else: + manufacturer = None + if 'MPN' in kwargs: + MPN = kwargs.pop('MPN') + else: + MPN = None + + if manufacturer or MPN: + if not self.manufacturer_part: + # Create ManufacturerPart + manufacturer_part = ManufacturerPart.create(part=self.part, + manufacturer=manufacturer, + mpn=MPN, + description=self.description) + self.manufacturer_part = manufacturer_part + else: + # Update ManufacturerPart (if ID exists) + try: + manufacturer_part_id = self.manufacturer_part.id + except AttributeError: + manufacturer_part_id = None + + if manufacturer_part_id: + try: + (manufacturer_part, created) = ManufacturerPart.objects.update_or_create(part=self.part, + manufacturer=manufacturer, + MPN=MPN) + except IntegrityError: + manufacturer_part = None + raise ValidationError(f'ManufacturerPart linked to {self.part} from manufacturer {manufacturer.name}' + f'with part number {MPN} already exists!') + + if manufacturer_part: + self.manufacturer_part = manufacturer_part + + self.clean() + self.validate_unique() + + super().save(*args, **kwargs) + class Meta: unique_together = ('part', 'supplier', 'SKU') diff --git a/InvenTree/company/serializers.py b/InvenTree/company/serializers.py index e9f13d021d..6f09f13a28 100644 --- a/InvenTree/company/serializers.py +++ b/InvenTree/company/serializers.py @@ -231,6 +231,24 @@ 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_id = self.initial_data.get('manufacturer', None) + MPN = self.initial_data.get('MPN', None) + + if manufacturer_id or MPN: + kwargs = {'manufacturer': manufacturer_id, + 'MPN': MPN, + } + supplier_part.save(**kwargs) + + return supplier_part + class SupplierPriceBreakSerializer(InvenTreeModelSerializer): """ Serializer for SupplierPriceBreak object """ From 91e314ddb5ed89725619957b39c0085c7e9b5d3c Mon Sep 17 00:00:00 2001 From: eeintech Date: Wed, 11 Aug 2021 17:08:46 -0400 Subject: [PATCH 2/2] Only connect ManufacturerPart if a. it exists b. SupplierPart is not yet connected --- InvenTree/company/models.py | 52 ++++++-------------- InvenTree/company/serializers.py | 15 +++--- InvenTree/templates/js/translated/company.js | 8 +-- 3 files changed, 26 insertions(+), 49 deletions(-) diff --git a/InvenTree/company/models.py b/InvenTree/company/models.py index b4fc0a2892..b0bb8caaa5 100644 --- a/InvenTree/company/models.py +++ b/InvenTree/company/models.py @@ -12,7 +12,6 @@ from django.core.validators import MinValueValidator from django.core.exceptions import ValidationError from django.db import models -from django.db.utils import IntegrityError from django.db.models import Sum, Q, UniqueConstraint from django.apps import apps @@ -503,50 +502,27 @@ class SupplierPart(models.Model): }) def save(self, *args, **kwargs): - """ Overriding save method to process the linked ManufacturerPart - """ + """ Overriding save method to connect an existing ManufacturerPart """ - if 'manufacturer' in kwargs: - manufacturer_id = kwargs.pop('manufacturer') + manufacturer_part = None - try: - manufacturer = Company.objects.get(pk=int(manufacturer_id)) - except (ValueError, Company.DoesNotExist): - manufacturer = None - else: - manufacturer = None - if 'MPN' in kwargs: + if all(key in kwargs for key in ('manufacturer', 'MPN')): + manufacturer_name = kwargs.pop('manufacturer') MPN = kwargs.pop('MPN') - else: - MPN = None - if manufacturer or 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: - # Create ManufacturerPart - manufacturer_part = ManufacturerPart.create(part=self.part, - manufacturer=manufacturer, - mpn=MPN, - description=self.description) + # Connect ManufacturerPart to SupplierPart self.manufacturer_part = manufacturer_part else: - # Update ManufacturerPart (if ID exists) - try: - manufacturer_part_id = self.manufacturer_part.id - except AttributeError: - manufacturer_part_id = None - - if manufacturer_part_id: - try: - (manufacturer_part, created) = ManufacturerPart.objects.update_or_create(part=self.part, - manufacturer=manufacturer, - MPN=MPN) - except IntegrityError: - manufacturer_part = None - raise ValidationError(f'ManufacturerPart linked to {self.part} from manufacturer {manufacturer.name}' - f'with part number {MPN} already exists!') - - if manufacturer_part: - self.manufacturer_part = manufacturer_part + raise ValidationError(f'SupplierPart {self.__str__} is already linked to {self.manufacturer_part}') self.clean() self.validate_unique() diff --git a/InvenTree/company/serializers.py b/InvenTree/company/serializers.py index 6f09f13a28..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) @@ -238,13 +238,14 @@ class SupplierPartSerializer(InvenTreeModelSerializer): supplier_part = super().create(validated_data) # Get ManufacturerPart raw data (unvalidated) - manufacturer_id = self.initial_data.get('manufacturer', None) + manufacturer = self.initial_data.get('manufacturer', None) MPN = self.initial_data.get('MPN', None) - if manufacturer_id or MPN: - kwargs = {'manufacturer': manufacturer_id, - 'MPN': MPN, - } + if manufacturer and MPN: + kwargs = { + 'manufacturer': manufacturer, + 'MPN': MPN, + } supplier_part.save(**kwargs) return supplier_part 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) {