mirror of
https://github.com/inventree/InvenTree.git
synced 2025-04-29 12:06:44 +00:00
Merge pull request #2859 from SchrodingersGat/ipn-validator-fix
IPN validator fix
This commit is contained in:
commit
adfcd42e09
@ -546,11 +546,19 @@ if "sqlite" in db_engine:
|
|||||||
# Provide OPTIONS dict back to the database configuration dict
|
# Provide OPTIONS dict back to the database configuration dict
|
||||||
db_config['OPTIONS'] = db_options
|
db_config['OPTIONS'] = db_options
|
||||||
|
|
||||||
|
# Set testing options for the database
|
||||||
|
db_config['TEST'] = {
|
||||||
|
'CHARSET': 'utf8',
|
||||||
|
}
|
||||||
|
|
||||||
|
# Set collation option for mysql test database
|
||||||
|
if 'mysql' in db_engine:
|
||||||
|
db_config['TEST']['COLLATION'] = 'utf8_general_ci'
|
||||||
|
|
||||||
DATABASES = {
|
DATABASES = {
|
||||||
'default': db_config
|
'default': db_config
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
_cache_config = CONFIG.get("cache", {})
|
_cache_config = CONFIG.get("cache", {})
|
||||||
_cache_host = _cache_config.get("host", os.getenv("INVENTREE_CACHE_HOST"))
|
_cache_host = _cache_config.get("host", os.getenv("INVENTREE_CACHE_HOST"))
|
||||||
_cache_port = _cache_config.get(
|
_cache_port = _cache_config.get(
|
||||||
|
@ -777,7 +777,8 @@ class Part(MPTTModel):
|
|||||||
# User can decide whether duplicate IPN (Internal Part Number) values are allowed
|
# User can decide whether duplicate IPN (Internal Part Number) values are allowed
|
||||||
allow_duplicate_ipn = common.models.InvenTreeSetting.get_setting('PART_ALLOW_DUPLICATE_IPN')
|
allow_duplicate_ipn = common.models.InvenTreeSetting.get_setting('PART_ALLOW_DUPLICATE_IPN')
|
||||||
|
|
||||||
if self.IPN is not None and not allow_duplicate_ipn:
|
# Raise an error if an IPN is set, and it is a duplicate
|
||||||
|
if self.IPN and not allow_duplicate_ipn:
|
||||||
parts = Part.objects.filter(IPN__iexact=self.IPN)
|
parts = Part.objects.filter(IPN__iexact=self.IPN)
|
||||||
parts = parts.exclude(pk=self.pk)
|
parts = parts.exclude(pk=self.pk)
|
||||||
|
|
||||||
@ -798,6 +799,10 @@ class Part(MPTTModel):
|
|||||||
|
|
||||||
super().clean()
|
super().clean()
|
||||||
|
|
||||||
|
# Strip IPN field
|
||||||
|
if type(self.IPN) is str:
|
||||||
|
self.IPN = self.IPN.strip()
|
||||||
|
|
||||||
if self.trackable:
|
if self.trackable:
|
||||||
for part in self.get_used_in().all():
|
for part in self.get_used_in().all():
|
||||||
|
|
||||||
|
@ -349,6 +349,26 @@ class PartSettingsTest(TestCase):
|
|||||||
part = Part(name='Hello', description='A thing', IPN='IPN123', revision='C')
|
part = Part(name='Hello', description='A thing', IPN='IPN123', revision='C')
|
||||||
part.full_clean()
|
part.full_clean()
|
||||||
|
|
||||||
|
# Any duplicate IPN should raise an error
|
||||||
|
Part.objects.create(name='xyz', revision='1', description='A part', IPN='UNIQUE')
|
||||||
|
|
||||||
|
# Case insensitive, so variations on spelling should throw an error
|
||||||
|
for ipn in ['UNiquE', 'uniQuE', 'unique']:
|
||||||
|
with self.assertRaises(ValidationError):
|
||||||
|
Part.objects.create(name='xyz', revision='2', description='A part', IPN=ipn)
|
||||||
|
|
||||||
|
with self.assertRaises(ValidationError):
|
||||||
|
Part.objects.create(name='zyx', description='A part', IPN='UNIQUE')
|
||||||
|
|
||||||
|
# However, *blank* / empty IPN values should be allowed, even if duplicates are not
|
||||||
|
# Note that leading / trailling whitespace characters are trimmed, too
|
||||||
|
Part.objects.create(name='abc', revision='1', description='A part', IPN=None)
|
||||||
|
Part.objects.create(name='abc', revision='2', description='A part', IPN='')
|
||||||
|
Part.objects.create(name='abc', revision='3', description='A part', IPN=None)
|
||||||
|
Part.objects.create(name='abc', revision='4', description='A part', IPN=' ')
|
||||||
|
Part.objects.create(name='abc', revision='5', description='A part', IPN=' ')
|
||||||
|
Part.objects.create(name='abc', revision='6', description='A part', IPN=' ')
|
||||||
|
|
||||||
|
|
||||||
class PartSubscriptionTests(TestCase):
|
class PartSubscriptionTests(TestCase):
|
||||||
|
|
||||||
|
@ -453,10 +453,12 @@ class StockItem(MPTTModel):
|
|||||||
|
|
||||||
super().clean()
|
super().clean()
|
||||||
|
|
||||||
if self.serial is not None and type(self.serial) is str:
|
# Strip serial number field
|
||||||
|
if type(self.serial) is str:
|
||||||
self.serial = self.serial.strip()
|
self.serial = self.serial.strip()
|
||||||
|
|
||||||
if self.batch is not None and type(self.batch) is str:
|
# Strip batch code field
|
||||||
|
if type(self.batch) is str:
|
||||||
self.batch = self.batch.strip()
|
self.batch = self.batch.strip()
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user