mirror of
https://github.com/inventree/InvenTree.git
synced 2025-06-18 21:15:41 +00:00
Enhance plugin SN validation (#7942)
* Update function signature for 'validate_serial_number' - Pass through stock item parameter - Required if we want to exclude a particular item from that test * Update documentation * Docs fixes * Add type annotations
This commit is contained in:
@ -4,6 +4,7 @@ from __future__ import annotations
|
||||
|
||||
import decimal
|
||||
import hashlib
|
||||
import inspect
|
||||
import logging
|
||||
import math
|
||||
import os
|
||||
@ -775,7 +776,22 @@ class Part(
|
||||
for plugin in registry.with_mixin('validation'):
|
||||
# Run the serial number through each custom validator
|
||||
# If the plugin returns 'True' we will skip any subsequent validation
|
||||
if plugin.validate_serial_number(serial, self):
|
||||
|
||||
result = False
|
||||
|
||||
if hasattr(plugin, 'validate_serial_number'):
|
||||
signature = inspect.signature(plugin.validate_serial_number)
|
||||
|
||||
if 'stock_item' in signature.parameters:
|
||||
# 2024-08-21: New method signature accepts a 'stock_item' parameter
|
||||
result = plugin.validate_serial_number(
|
||||
serial, self, stock_item=stock_item
|
||||
)
|
||||
else:
|
||||
# Old method signature - does not accept a 'stock_item' parameter
|
||||
result = plugin.validate_serial_number(serial, self)
|
||||
|
||||
if result is True:
|
||||
return True
|
||||
except ValidationError as exc:
|
||||
if raise_error:
|
||||
|
@ -63,7 +63,7 @@ class ValidationMixin:
|
||||
None: or True (refer to class docstring)
|
||||
|
||||
Raises:
|
||||
ValidationError: if the instance cannot be deleted
|
||||
ValidationError: If the instance cannot be deleted
|
||||
"""
|
||||
return None
|
||||
|
||||
@ -81,11 +81,11 @@ class ValidationMixin:
|
||||
None: or True (refer to class docstring)
|
||||
|
||||
Raises:
|
||||
ValidationError: if the instance is invalid
|
||||
ValidationError: If the instance is invalid
|
||||
"""
|
||||
return None
|
||||
|
||||
def validate_part_name(self, name: str, part: part.models.Part):
|
||||
def validate_part_name(self, name: str, part: part.models.Part) -> None:
|
||||
"""Perform validation on a proposed Part name.
|
||||
|
||||
Arguments:
|
||||
@ -96,11 +96,11 @@ class ValidationMixin:
|
||||
None or True (refer to class docstring)
|
||||
|
||||
Raises:
|
||||
ValidationError if the proposed name is objectionable
|
||||
ValidationError: If the proposed name is objectionable
|
||||
"""
|
||||
return None
|
||||
|
||||
def validate_part_ipn(self, ipn: str, part: part.models.Part):
|
||||
def validate_part_ipn(self, ipn: str, part: part.models.Part) -> None:
|
||||
"""Perform validation on a proposed Part IPN (internal part number).
|
||||
|
||||
Arguments:
|
||||
@ -111,11 +111,13 @@ class ValidationMixin:
|
||||
None or True (refer to class docstring)
|
||||
|
||||
Raises:
|
||||
ValidationError if the proposed IPN is objectionable
|
||||
ValidationError: If the proposed IPN is objectionable
|
||||
"""
|
||||
return None
|
||||
|
||||
def validate_batch_code(self, batch_code: str, item: stock.models.StockItem):
|
||||
def validate_batch_code(
|
||||
self, batch_code: str, item: stock.models.StockItem
|
||||
) -> None:
|
||||
"""Validate the supplied batch code.
|
||||
|
||||
Arguments:
|
||||
@ -126,11 +128,11 @@ class ValidationMixin:
|
||||
None or True (refer to class docstring)
|
||||
|
||||
Raises:
|
||||
ValidationError if the proposed batch code is objectionable
|
||||
ValidationError: If the proposed batch code is objectionable
|
||||
"""
|
||||
return None
|
||||
|
||||
def generate_batch_code(self, **kwargs):
|
||||
def generate_batch_code(self, **kwargs) -> str:
|
||||
"""Generate a new batch code.
|
||||
|
||||
This method is called when a new batch code is required.
|
||||
@ -143,22 +145,28 @@ class ValidationMixin:
|
||||
"""
|
||||
return None
|
||||
|
||||
def validate_serial_number(self, serial: str, part: part.models.Part):
|
||||
def validate_serial_number(
|
||||
self,
|
||||
serial: str,
|
||||
part: part.models.Part,
|
||||
stock_item: stock.models.StockItem = None,
|
||||
) -> None:
|
||||
"""Validate the supplied serial number.
|
||||
|
||||
Arguments:
|
||||
serial: The proposed serial number (string)
|
||||
part: The Part instance for which this serial number is being validated
|
||||
stock_item: The StockItem instance for which this serial number is being validated (if applicable)
|
||||
|
||||
Returns:
|
||||
None or True (refer to class docstring)
|
||||
|
||||
Raises:
|
||||
ValidationError if the proposed serial is objectionable
|
||||
ValidationError: If the proposed serial is objectionable
|
||||
"""
|
||||
return None
|
||||
|
||||
def convert_serial_to_int(self, serial: str):
|
||||
def convert_serial_to_int(self, serial: str) -> int:
|
||||
"""Convert a serial number (string) into an integer representation.
|
||||
|
||||
This integer value is used for efficient sorting based on serial numbers.
|
||||
@ -179,7 +187,7 @@ class ValidationMixin:
|
||||
"""
|
||||
return None
|
||||
|
||||
def increment_serial_number(self, serial: str):
|
||||
def increment_serial_number(self, serial: str) -> str:
|
||||
"""Return the next sequential serial based on the provided value.
|
||||
|
||||
A plugin which implements this method can either return:
|
||||
@ -189,10 +197,15 @@ class ValidationMixin:
|
||||
|
||||
Arguments:
|
||||
serial: Current serial value (string)
|
||||
|
||||
Returns:
|
||||
The next serial number in the sequence (string), or None
|
||||
"""
|
||||
return None
|
||||
|
||||
def validate_part_parameter(self, parameter, data):
|
||||
def validate_part_parameter(
|
||||
self, parameter: part.models.PartParameter, data: str
|
||||
) -> None:
|
||||
"""Validate a parameter value.
|
||||
|
||||
Arguments:
|
||||
@ -203,6 +216,6 @@ class ValidationMixin:
|
||||
None or True (refer to class docstring)
|
||||
|
||||
Raises:
|
||||
ValidationError if the proposed parameter value is objectionable
|
||||
ValidationError: If the proposed parameter value is objectionable
|
||||
"""
|
||||
pass
|
||||
|
@ -121,7 +121,7 @@ class SampleValidatorPlugin(SettingsMixin, ValidationMixin, InvenTreePlugin):
|
||||
if d >= 100:
|
||||
self.raise_error('Value must be less than 100')
|
||||
|
||||
def validate_serial_number(self, serial: str, part):
|
||||
def validate_serial_number(self, serial: str, part, stock_item=None):
|
||||
"""Validate serial number for a given StockItem.
|
||||
|
||||
These examples are silly, but serve to demonstrate how the feature could be used
|
||||
|
Reference in New Issue
Block a user