Skip to content

Commit

Permalink
Currency format fix (#7398)
Browse files Browse the repository at this point in the history
* Fix for currency rendering

- Handle case where max digits less than min digits

* Add validators for settings
  • Loading branch information
SchrodingersGat authored Jun 4, 2024
1 parent 0cb762d commit a5fa5f8
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 18 deletions.
30 changes: 14 additions & 16 deletions src/backend/InvenTree/common/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@

import build.validators
import common.currency
import common.validators
import InvenTree.fields
import InvenTree.helpers
import InvenTree.models
Expand Down Expand Up @@ -1146,19 +1147,6 @@ def update_instance_name(setting):
site_obj.save()


def validate_email_domains(setting):
"""Validate the email domains setting."""
if not setting.value:
return

domains = setting.value.split(',')
for domain in domains:
if not domain:
raise ValidationError(_('An empty domain is not allowed.'))
if not re.match(r'^@[a-zA-Z0-9\.\-_]+$', domain):
raise ValidationError(_(f'Invalid domain name: {domain}'))


def reload_plugin_registry(setting):
"""When a core plugin setting is changed, reload the plugin registry."""
from plugin import registry
Expand Down Expand Up @@ -1550,15 +1538,25 @@ def save(self, *args, **kwargs):
'Minimum number of decimal places to display when rendering pricing data'
),
'default': 0,
'validator': [int, MinValueValidator(0), MaxValueValidator(4)],
'validator': [
int,
MinValueValidator(0),
MaxValueValidator(4),
common.validators.validate_decimal_places_min,
],
},
'PRICING_DECIMAL_PLACES': {
'name': _('Maximum Pricing Decimal Places'),
'description': _(
'Maximum number of decimal places to display when rendering pricing data'
),
'default': 6,
'validator': [int, MinValueValidator(2), MaxValueValidator(6)],
'validator': [
int,
MinValueValidator(2),
MaxValueValidator(6),
common.validators.validate_decimal_places_max,
],
},
'PRICING_USE_SUPPLIER_PRICING': {
'name': _('Use Supplier Pricing'),
Expand Down Expand Up @@ -1944,7 +1942,7 @@ def save(self, *args, **kwargs):
'Restrict signup to certain domains (comma-separated, starting with @)'
),
'default': '',
'before_save': validate_email_domains,
'before_save': common.validators.validate_email_domains,
},
'SIGNUP_GROUP': {
'name': _('Group on signup'),
Expand Down
45 changes: 45 additions & 0 deletions src/backend/InvenTree/common/validators.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
"""Validation helpers for common models."""

from django.core.exceptions import ValidationError
from django.utils.translation import gettext_lazy as _


def validate_decimal_places_min(value):
"""Validator for PRICING_DECIMAL_PLACES_MIN setting."""
from common.models import InvenTreeSetting

try:
value = int(value)
places_max = int(InvenTreeSetting.get_setting('PRICING_DECIMAL_PLACES'))
except Exception:
return

if value > places_max:
raise ValidationError(_('Minimum places cannot be greater than maximum places'))


def validate_decimal_places_max(value):
"""Validator for PRICING_DECIMAL_PLACES_MAX setting."""
from common.models import InvenTreeSetting

try:
value = int(value)
places_min = int(InvenTreeSetting.get_setting('PRICING_DECIMAL_PLACES_MIN'))
except Exception:
return

if value < places_min:
raise ValidationError(_('Maximum places cannot be less than minimum places'))


def validate_email_domains(setting):
"""Validate the email domains setting."""
if not setting.value:
return

domains = setting.value.split(',')
for domain in domains:
if not domain:
raise ValidationError(_('An empty domain is not allowed.'))
if not re.match(r'^@[a-zA-Z0-9\.\-_]+$', domain):
raise ValidationError(_(f'Invalid domain name: {domain}'))
4 changes: 2 additions & 2 deletions src/frontend/src/defaults/formatters.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -77,8 +77,8 @@ export function formatCurrency(
let formatter = new Intl.NumberFormat(locale, {
style: 'currency',
currency: currency,
maximumFractionDigits: maxDigits,
minimumFractionDigits: minDigits
maximumFractionDigits: Math.max(minDigits, maxDigits),
minimumFractionDigits: Math.min(minDigits, maxDigits)
});

return formatter.format(value);
Expand Down

0 comments on commit a5fa5f8

Please sign in to comment.