diff --git a/src/backend/InvenTree/InvenTree/api_version.py b/src/backend/InvenTree/InvenTree/api_version.py index a96e1e09a8..c64b88a72d 100644 --- a/src/backend/InvenTree/InvenTree/api_version.py +++ b/src/backend/InvenTree/InvenTree/api_version.py @@ -1,11 +1,14 @@ """InvenTree API version information.""" # InvenTree API version -INVENTREE_API_VERSION = 516 +INVENTREE_API_VERSION = 517 """Increment this API version number whenever there is a significant change to the API that any clients need to know about.""" INVENTREE_API_TEXT = """ +v517 -> 2026-07-08 : https://github.com/inventree/InvenTree/pull/12336 + - Fix currency code options for the PartPricing model and API endpoints + v516 -> 2026-07-03 : https://github.com/inventree/InvenTree/pull/12295 - Adds "consumable" field to the Part model and API endpoints diff --git a/src/backend/InvenTree/InvenTree/test_commands.py b/src/backend/InvenTree/InvenTree/test_commands.py index 82caec7d73..7554f16db0 100644 --- a/src/backend/InvenTree/InvenTree/test_commands.py +++ b/src/backend/InvenTree/InvenTree/test_commands.py @@ -1,5 +1,7 @@ """Tests for custom InvenTree management commands.""" +import os +import subprocess from pathlib import Path from django.conf import settings @@ -15,6 +17,48 @@ from InvenTree.config import get_testfolder_dir class CommandTestCase(TestCase): """Test case for custom management commands.""" + def test_makemigrations_currency_overrides_no_changes(self): + """Ensure currency list changes do not cause migration drift.""" + currency_sets = ['USD,EUR,GBP', 'JPY,CNY,KRW'] + + for currency_codes in currency_sets: + with self.subTest(currency_codes=currency_codes): + old_value = os.environ.get('INVENTREE_CURRENCY_CODES') + + try: + os.environ['INVENTREE_CURRENCY_CODES'] = currency_codes + project_dir = Path(__file__).resolve().parents[1] + + result = subprocess.run( + [ + 'python3', + 'manage.py', + 'makemigrations', + '--check', + '--dry-run', + '--verbosity', + '0', + ], + cwd=project_dir, + env=os.environ.copy(), + capture_output=True, + text=True, + check=False, + ) + + if result.returncode != 0: + self.fail( + 'makemigrations reported schema changes ' + f'for INVENTREE_CURRENCY_CODES={currency_codes}\n' + f'stdout:\n{result.stdout}\n' + f'stderr:\n{result.stderr}' + ) + finally: + if old_value is None: + os.environ.pop('INVENTREE_CURRENCY_CODES', None) + else: + os.environ['INVENTREE_CURRENCY_CODES'] = old_value + def test_schema(self): """Test the schema generation command.""" output = call_command('schema', file='schema.yml', verbosity=0) diff --git a/src/backend/InvenTree/part/migrations/0152_alter_partpricing_currency.py b/src/backend/InvenTree/part/migrations/0152_alter_partpricing_currency.py new file mode 100644 index 0000000000..de0f646ae9 --- /dev/null +++ b/src/backend/InvenTree/part/migrations/0152_alter_partpricing_currency.py @@ -0,0 +1,26 @@ +# Generated by Django 5.2.15 on 2026-07-08 00:00 + +import InvenTree.validators +import common.currency +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ("part", "0151_part_consumable"), + ] + + operations = [ + migrations.AlterField( + model_name="partpricing", + name="currency", + field=models.CharField( + default=common.currency.currency_code_default, + help_text="Currency used to cache pricing calculations", + max_length=10, + validators=[InvenTree.validators.validate_currency_code], + verbose_name="Currency", + ), + ), + ] diff --git a/src/backend/InvenTree/part/models.py b/src/backend/InvenTree/part/models.py index 03e0b5f138..3c89656c7e 100644 --- a/src/backend/InvenTree/part/models.py +++ b/src/backend/InvenTree/part/models.py @@ -3378,7 +3378,7 @@ class PartPricing(common.models.MetaMixin): max_length=10, verbose_name=_('Currency'), help_text=_('Currency used to cache pricing calculations'), - choices=common.currency.currency_code_mappings(), + validators=[validators.validate_currency_code], ) scheduled_for_update = models.BooleanField(default=False) diff --git a/src/backend/InvenTree/part/serializers.py b/src/backend/InvenTree/part/serializers.py index e8b2ecff29..0e62494f88 100644 --- a/src/backend/InvenTree/part/serializers.py +++ b/src/backend/InvenTree/part/serializers.py @@ -1429,7 +1429,9 @@ class PartPricingSerializer(InvenTree.serializers.InvenTreeModelSerializer): 'update', ] - currency = serializers.CharField(allow_null=True, read_only=True) + currency = InvenTree.serializers.InvenTreeCurrencySerializer( + allow_null=True, read_only=True + ) updated = serializers.DateTimeField(allow_null=True, read_only=True)