2
0
mirror of https://github.com/inventree/InvenTree.git synced 2026-05-23 01:25:45 +00:00
Files
InvenTree/InvenTree/plugin/samples/integration/validation_sample.py
T
Oliver 906ae218aa [Plugin] Allow custom plugins for running validation routines (#3776)
* Adds new plugin mixin for performing custom validation steps

* Adds simple test plugin for custom validation

* Run part name and IPN validators checks through loaded plugins

* Expose more validation functions to plugins:

- SalesOrder reference
- PurchaseOrder reference
- BuildOrder reference

* Remove custom validation of reference fields

- For now, this is too complex to consider given the current incrementing-reference implementation
- Might revisit this at a later stage.

* Custom validation of serial numbers:

- Replace "checkIfSerialNumberExists" method with "validate_serial_number"
- Pass serial number through to custom plugins
- General code / docstring improvements

* Update unit tests

* Update InvenTree/stock/tests.py

Co-authored-by: Matthias Mair <code@mjmair.com>

* Adds global setting to specify whether serial numbers must be unique globally

- Default is false to preserve behaviour

* Improved error message when attempting to create stock item with invalid serial numbers

* Add more detail to existing serial error message

* Add unit testing for serial number uniqueness

* Allow plugins to convert a serial number to an integer (for optimized sorting)

* Add placeholder plugin methods for incrementing and decrementing serial numbers

* Typo fix

* Add improved method for determining the "latest" serial number

* Remove calls to getLatestSerialNumber

* Update validate_serial_number method

- Add option to disable checking for duplicates
- Don't pass optional StockItem through to plugins

* Refactor serial number extraction methods

- Expose the "incrementing" portion to external plugins

* Bug fixes

* Update unit tests

* Fix for get_latest_serial_number

* Ensure custom serial integer values are clipped

* Adds a plugin for validating and generating hexadecimal serial numbers

* Update unit tests

* Add stub methods for batch code functionality

* remove "hex serials" plugin

- Was simply breaking unit tests

* Allow custom plugins to generate and validate batch codes

- Perform batch code validation when StockItem is saved
- Improve display of error message in modal forms

* Fix unit tests for stock app

* Log message if plugin has a duplicate slug

* Unit test fix

Co-authored-by: Matthias Mair <code@mjmair.com>
2022-10-18 23:50:07 +11:00

80 lines
2.6 KiB
Python

"""Sample plugin which demonstrates custom validation functionality"""
from datetime import datetime
from django.core.exceptions import ValidationError
from plugin import InvenTreePlugin
from plugin.mixins import SettingsMixin, ValidationMixin
class CustomValidationMixin(SettingsMixin, ValidationMixin, InvenTreePlugin):
"""A sample plugin class for demonstrating custom validation functions"""
NAME = "CustomValidator"
SLUG = "validator"
TITLE = "Custom Validator Plugin"
DESCRIPTION = "A sample plugin for demonstrating custom validation functionality"
VERSION = "0.1"
SETTINGS = {
'ILLEGAL_PART_CHARS': {
'name': 'Illegal Part Characters',
'description': 'Characters which are not allowed to appear in Part names',
'default': '!@#$%^&*()~`'
},
'IPN_MUST_CONTAIN_Q': {
'name': 'IPN Q Requirement',
'description': 'Part IPN field must contain the character Q',
'default': False,
'validator': bool,
},
'SERIAL_MUST_BE_PALINDROME': {
'name': 'Palindromic Serials',
'description': 'Serial numbers must be palindromic',
'default': False,
'validator': bool,
},
'BATCH_CODE_PREFIX': {
'name': 'Batch prefix',
'description': 'Required prefix for batch code',
'default': '',
}
}
def validate_part_name(self, name: str):
"""Validate part name"""
illegal_chars = self.get_setting('ILLEGAL_PART_CHARS')
for c in illegal_chars:
if c in name:
raise ValidationError(f"Illegal character in part name: '{c}'")
def validate_part_ipn(self, ipn: str):
"""Validate part IPN"""
if self.get_setting('IPN_MUST_CONTAIN_Q') and 'Q' not in ipn:
raise ValidationError("IPN must contain 'Q'")
def validate_serial_number(self, serial: str):
"""Validate serial number for a given StockItem"""
if self.get_setting('SERIAL_MUST_BE_PALINDROME'):
if serial != serial[::-1]:
raise ValidationError("Serial must be a palindrome")
def validate_batch_code(self, batch_code: str):
"""Ensure that a particular batch code meets specification"""
prefix = self.get_setting('BATCH_CODE_PREFIX')
if not batch_code.startswith(prefix):
raise ValidationError(f"Batch code must start with '{prefix}'")
def generate_batch_code(self):
"""Generate a new batch code."""
now = datetime.now()
return f"BATCH-{now.year}:{now.month}:{now.day}"