mirror of
https://github.com/inventree/InvenTree.git
synced 2026-07-17 20:23:50 +00:00
Fix currency choices for PartPricing model (#12336)
* Fix currency choices for PartPricing model - Remove dynamic choices from model definition - Move validation step to the serializer - Add validator to ensure only valid currencies can be used * Add regression test * Bump API version
This commit is contained in:
@@ -1,11 +1,14 @@
|
|||||||
"""InvenTree API version information."""
|
"""InvenTree API version information."""
|
||||||
|
|
||||||
# InvenTree API version
|
# 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."""
|
"""Increment this API version number whenever there is a significant change to the API that any clients need to know about."""
|
||||||
|
|
||||||
INVENTREE_API_TEXT = """
|
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
|
v516 -> 2026-07-03 : https://github.com/inventree/InvenTree/pull/12295
|
||||||
- Adds "consumable" field to the Part model and API endpoints
|
- Adds "consumable" field to the Part model and API endpoints
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
"""Tests for custom InvenTree management commands."""
|
"""Tests for custom InvenTree management commands."""
|
||||||
|
|
||||||
|
import os
|
||||||
|
import subprocess
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
@@ -15,6 +17,48 @@ from InvenTree.config import get_testfolder_dir
|
|||||||
class CommandTestCase(TestCase):
|
class CommandTestCase(TestCase):
|
||||||
"""Test case for custom management commands."""
|
"""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):
|
def test_schema(self):
|
||||||
"""Test the schema generation command."""
|
"""Test the schema generation command."""
|
||||||
output = call_command('schema', file='schema.yml', verbosity=0)
|
output = call_command('schema', file='schema.yml', verbosity=0)
|
||||||
|
|||||||
@@ -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",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
]
|
||||||
@@ -3378,7 +3378,7 @@ class PartPricing(common.models.MetaMixin):
|
|||||||
max_length=10,
|
max_length=10,
|
||||||
verbose_name=_('Currency'),
|
verbose_name=_('Currency'),
|
||||||
help_text=_('Currency used to cache pricing calculations'),
|
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)
|
scheduled_for_update = models.BooleanField(default=False)
|
||||||
|
|||||||
@@ -1429,7 +1429,9 @@ class PartPricingSerializer(InvenTree.serializers.InvenTreeModelSerializer):
|
|||||||
'update',
|
'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)
|
updated = serializers.DateTimeField(allow_null=True, read_only=True)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user