From 0b4144a6203fcb7672a748ceafcfd3fc0c378fe2 Mon Sep 17 00:00:00 2001 From: Oliver Walters Date: Fri, 19 Jun 2026 07:06:23 +0000 Subject: [PATCH] Add new global setting to control currency locale in reports --- docs/docs/settings/global.md | 1 + src/backend/InvenTree/common/setting/system.py | 8 ++++++++ src/backend/InvenTree/common/validators.py | 15 +++++++++++++++ .../src/pages/Index/Settings/SystemSettings.tsx | 1 + 4 files changed, 25 insertions(+) diff --git a/docs/docs/settings/global.md b/docs/docs/settings/global.md index 2e22defb8e..244eb48e19 100644 --- a/docs/docs/settings/global.md +++ b/docs/docs/settings/global.md @@ -142,6 +142,7 @@ Configuration of report generation: | Name | Description | Default | Units | | ---- | ----------- | ------- | ----- | {{ globalsetting("REPORT_ENABLE") }} +{{ globalsetting("REPORT_CURRENCY_LOCALE") }} {{ globalsetting("REPORT_DEFAULT_PAGE_SIZE") }} {{ globalsetting("REPORT_DEBUG_MODE") }} {{ globalsetting("REPORT_FETCH_URLS") }} diff --git a/src/backend/InvenTree/common/setting/system.py b/src/backend/InvenTree/common/setting/system.py index d6fe3e3a6b..f17b99e930 100644 --- a/src/backend/InvenTree/common/setting/system.py +++ b/src/backend/InvenTree/common/setting/system.py @@ -671,6 +671,14 @@ SYSTEM_SETTINGS: dict[str, InvenTreeSettingsKeyType] = { 'default': False, 'validator': bool, }, + 'REPORT_CURRENCY_LOCALE': { + 'name': _('Report Currency Locale'), + 'description': _( + 'Locale to use when rendering currency values in reports (e.g. en-US, fr-FR). Leave blank to use the system locale setting.' + ), + 'default': '', + 'validator': common.validators.validate_locale, + }, 'REPORT_DEBUG_MODE': { 'name': _('Debug Mode'), 'description': _('Generate reports in debug mode (HTML output)'), diff --git a/src/backend/InvenTree/common/validators.py b/src/backend/InvenTree/common/validators.py index 226a42b7d2..d1d9e63ebf 100644 --- a/src/backend/InvenTree/common/validators.py +++ b/src/backend/InvenTree/common/validators.py @@ -4,6 +4,7 @@ import re from django.core.exceptions import SuspiciousFileOperation, ValidationError from django.core.files.storage import default_storage +from django.utils import translation from django.utils.translation import gettext_lazy as _ import common.icons @@ -171,3 +172,17 @@ def validate_variable_string(value: str): """The passed value must be a valid variable identifier string.""" if not re.match(r'^[a-zA-Z_][a-zA-Z0-9_]*$', value): raise ValidationError(_('Value must be a valid variable identifier')) + + +def validate_locale(value: str): + """Validate that the provided value is a valid locale string.""" + from babel import Locale + from babel.core import UnknownLocaleError + + if not value: + return + + try: + Locale.parse(translation.to_locale(value)) + except (UnknownLocaleError, ValueError) as e: + raise ValidationError(f"Invalid locale value: '{value}' - {e}") diff --git a/src/frontend/src/pages/Index/Settings/SystemSettings.tsx b/src/frontend/src/pages/Index/Settings/SystemSettings.tsx index c272fddaed..85facf5e55 100644 --- a/src/frontend/src/pages/Index/Settings/SystemSettings.tsx +++ b/src/frontend/src/pages/Index/Settings/SystemSettings.tsx @@ -197,6 +197,7 @@ export default function SystemSettings() {