From 258bf2933144e85ea61f93af090c51c21da0c88b Mon Sep 17 00:00:00 2001 From: Oliver Date: Fri, 19 May 2023 14:05:24 +1000 Subject: [PATCH] Migrate old units to new units, and remove old field --- InvenTree/company/api.py | 2 +- .../migrations/0060_auto_20230519_0344.py | 34 +++++++++++++++++++ .../0061_remove_supplierpart_pack_size.py | 17 ++++++++++ InvenTree/company/models.py | 22 ++++++------ InvenTree/company/serializers.py | 4 +-- InvenTree/templates/js/translated/company.js | 10 +++--- 6 files changed, 70 insertions(+), 19 deletions(-) create mode 100644 InvenTree/company/migrations/0060_auto_20230519_0344.py create mode 100644 InvenTree/company/migrations/0061_remove_supplierpart_pack_size.py diff --git a/InvenTree/company/api.py b/InvenTree/company/api.py index bd35fcc4ef..1510d9c544 100644 --- a/InvenTree/company/api.py +++ b/InvenTree/company/api.py @@ -390,7 +390,7 @@ class SupplierPartList(ListCreateDestroyAPIView): 'manufacturer', 'MPN', 'packaging', - 'pack_size', + 'pack_units', 'in_stock', 'updated', ] diff --git a/InvenTree/company/migrations/0060_auto_20230519_0344.py b/InvenTree/company/migrations/0060_auto_20230519_0344.py new file mode 100644 index 0000000000..8d3ff1aae7 --- /dev/null +++ b/InvenTree/company/migrations/0060_auto_20230519_0344.py @@ -0,0 +1,34 @@ +# Generated by Django 3.2.19 on 2023-05-19 03:44 + +from django.db import migrations + +from InvenTree.helpers import normalize + + +def update_supplier_part_units(apps, schema_editor): + """Migrate existing supplier part units to new field""" + + SupplierPart = apps.get_model('company', 'SupplierPart') + + supplier_parts = SupplierPart.objects.all() + + for sp in supplier_parts: + sp.pack_units = str(normalize(sp.pack_size)) + sp.save() + + if supplier_parts.count() > 0: + print(f"Updated {supplier_parts.count()} supplier part units") + + +class Migration(migrations.Migration): + + dependencies = [ + ('company', '0059_supplierpart_pack_units'), + ] + + operations = [ + migrations.RunPython( + code=update_supplier_part_units, + reverse_code=migrations.RunPython.noop + ) + ] diff --git a/InvenTree/company/migrations/0061_remove_supplierpart_pack_size.py b/InvenTree/company/migrations/0061_remove_supplierpart_pack_size.py new file mode 100644 index 0000000000..0ae404be05 --- /dev/null +++ b/InvenTree/company/migrations/0061_remove_supplierpart_pack_size.py @@ -0,0 +1,17 @@ +# Generated by Django 3.2.19 on 2023-05-19 04:03 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('company', '0060_auto_20230519_0344'), + ] + + operations = [ + migrations.RemoveField( + model_name='supplierpart', + name='pack_size', + ), + ] diff --git a/InvenTree/company/models.py b/InvenTree/company/models.py index c7d86499e5..d85fbb3f1b 100644 --- a/InvenTree/company/models.py +++ b/InvenTree/company/models.py @@ -19,13 +19,14 @@ from taggit.managers import TaggableManager import common.models import common.settings +import InvenTree.conversion import InvenTree.fields import InvenTree.helpers import InvenTree.ready import InvenTree.tasks import InvenTree.validators from common.settings import currency_code_default -from InvenTree.fields import InvenTreeURLField, RoundingDecimalField +from InvenTree.fields import InvenTreeURLField from InvenTree.models import (InvenTreeAttachment, InvenTreeBarcodeMixin, InvenTreeNotesMixin, MetadataMixin) from InvenTree.status_codes import PurchaseOrderStatus @@ -436,7 +437,7 @@ class SupplierPart(MetadataMixin, InvenTreeBarcodeMixin, common.models.MetaMixin multiple: Multiple that the part is provided in lead_time: Supplier lead time packaging: packaging that the part is supplied in, e.g. "Reel" - pack_size: Quantity of item supplied in a single pack (e.g. 30ml in a single tube) + pack_units: Quantity of item supplied in a single pack (e.g. 30ml in a single tube) updated: Date that the SupplierPart was last updated """ @@ -475,6 +476,15 @@ class SupplierPart(MetadataMixin, InvenTreeBarcodeMixin, common.models.MetaMixin """ super().clean() + # Validate that the UOM is compatible with the base part + if self.pack_units and self.part: + try: + InvenTree.conversion.convert_physical_value(self.pack_units, self.part.units) + except ValidationError as e: + raise ValidationError({ + 'pack_units': e.messages + }) + # Ensure that the linked manufacturer_part points to the same part! if self.manufacturer_part and self.part: @@ -568,14 +578,6 @@ class SupplierPart(MetadataMixin, InvenTreeBarcodeMixin, common.models.MetaMixin blank=True, ) - pack_size = RoundingDecimalField( - verbose_name=_('Pack Quantity'), - help_text=_('Unit quantity supplied in a single pack'), - default=1, - max_digits=15, decimal_places=5, - validators=[MinValueValidator(0.001)], - ) - multiple = models.PositiveIntegerField(default=1, validators=[MinValueValidator(1)], verbose_name=_('multiple'), help_text=_('Order multiple')) # TODO - Reimplement lead-time as a charfield with special validation (pattern matching). diff --git a/InvenTree/company/serializers.py b/InvenTree/company/serializers.py index 3835371947..168334d885 100644 --- a/InvenTree/company/serializers.py +++ b/InvenTree/company/serializers.py @@ -265,7 +265,7 @@ class SupplierPartSerializer(InvenTreeTagModelSerializer): 'pk', 'barcode_hash', 'packaging', - 'pack_size', + 'pack_units', 'part', 'part_detail', 'pretty_name', @@ -327,8 +327,6 @@ class SupplierPartSerializer(InvenTreeTagModelSerializer): pretty_name = serializers.CharField(read_only=True) - pack_size = serializers.FloatField(label=_('Pack Quantity')) - supplier = serializers.PrimaryKeyRelatedField(queryset=Company.objects.filter(is_supplier=True)) manufacturer = serializers.CharField(read_only=True) diff --git a/InvenTree/templates/js/translated/company.js b/InvenTree/templates/js/translated/company.js index 53180d26c7..350b4b3123 100644 --- a/InvenTree/templates/js/translated/company.js +++ b/InvenTree/templates/js/translated/company.js @@ -138,7 +138,7 @@ function supplierPartFields(options={}) { packaging: { icon: 'fa-box', }, - pack_size: {}, + pack_units: {}, }; if (options.part) { @@ -1242,14 +1242,14 @@ function loadSupplierPartTable(table, url, options) { sortable: true, }, { - field: 'pack_size', - title: '{% trans "Pack Quantity" %}', + field: 'pack_units', + title: '{% trans "Pack Units" %}', sortable: true, formatter: function(value, row) { - var output = `${value}`; + var output = `${formatDecimal(value)}`; if (row.part_detail && row.part_detail.units) { - output += ` ${row.part_detail.units}`; + output += ` [${row.part_detail.units}]`; } return output;