Coverage for src/backend/InvenTree/InvenTree/validators.py: 50%

44 statements  

« prev     ^ index     » next       coverage.py v7.15.2, created at 2026-10-07 17:47 +0000

1"""Custom field validators for InvenTree.""" 

2 

3from django.conf import settings 

4from django.core import validators 

5from django.core.exceptions import ValidationError 

6from django.utils.translation import gettext_lazy as _ 

7 

8import pint.errors 

9from moneyed import CURRENCIES 

10 

11import InvenTree.conversion 

12from common.settings import get_global_setting 

13 

14 

15def validate_physical_units(unit): 

16 """Ensure that a given unit is a valid physical unit.""" 

17 unit = unit.strip() 

18 

19 # Ignore blank units 

20 if not unit: 20 ↛ 21line 20 didn't jump to line 21 because the condition on line 20 was never true

21 return 

22 

23 ureg = InvenTree.conversion.get_unit_registry() 

24 

25 try: 

26 ureg(unit) 

27 except (AssertionError, AttributeError, pint.errors.UndefinedUnitError): 

28 raise ValidationError(_('Invalid physical unit')) 

29 

30 

31def validate_currency_code(code): 

32 """Check that a given code is a valid currency code.""" 

33 if code not in CURRENCIES: 33 ↛ 34line 33 didn't jump to line 34 because the condition on line 33 was never true

34 raise ValidationError(_('Not a valid currency code')) 

35 

36 

37def allowable_url_schemes(): 

38 """Return the list of allowable URL schemes. 

39 

40 In addition to the default schemes allowed by Django, 

41 the install configuration file (config.yaml) can specify 

42 extra schemas 

43 """ 

44 # Default schemes 

45 schemes = ['http', 'https', 'ftp', 'ftps'] 

46 

47 extra = settings.EXTRA_URL_SCHEMES 

48 

49 for e in extra: 49 ↛ 50line 49 didn't jump to line 50 because the loop on line 49 never started

50 if e.lower() not in schemes: 

51 schemes.append(e.lower()) 

52 

53 return schemes 

54 

55 

56class AllowedURLValidator(validators.URLValidator): 

57 """Custom URL validator to allow for custom schemes.""" 

58 

59 def __call__(self, value): 

60 """Validate the URL.""" 

61 self.schemes = allowable_url_schemes() 

62 

63 # Determine if 'strict' URL validation is required (i.e. if the URL must have a schema prefix) 

64 strict_urls = get_global_setting('INVENTREE_STRICT_URLS', cache=False) 

65 

66 if value is not None: 

67 value = str(value).strip() 

68 

69 if value and not strict_urls: 

70 # Allow URLs which do not have a provided schema 

71 if '://' not in value: 

72 # Validate as if it were http 

73 value = 'http://' + value 

74 

75 super().__call__(value) 

76 

77 

78def validate_purchase_order_reference(value): 

79 """Validate the 'reference' field of a PurchaseOrder.""" 

80 from order.models import PurchaseOrder 

81 

82 # If we get to here, run the "default" validation routine 

83 PurchaseOrder.validate_reference_field(value) 

84 

85 

86def validate_sales_order_reference(value): 

87 """Validate the 'reference' field of a SalesOrder.""" 

88 from order.models import SalesOrder 

89 

90 # If we get to here, run the "default" validation routine 

91 SalesOrder.validate_reference_field(value) 

92 

93 

94def validate_tree_name(value): 

95 """Placeholder for legacy function used in migrations."""