2
0
mirror of https://github.com/inventree/InvenTree.git synced 2025-06-17 12:35:46 +00:00

Build default location (#7160)

* Set build default location on save

* Update destination location in PUI form

* Set location for generated stock outputs

* Construct buildorderoutput fieldset

* Add "location" field to BuildOrderOutput serializer

* Create new build outputs from PUI

* Refacator StockItemTable

* Support serial_numbers field

* Add new API endpoints for build order operations

* Implement "build output complete" form

* Refactor common table

* Implement ScrapBuildOutput form

* Implement BuildOutputCancel form

* Update API version
This commit is contained in:
Oliver
2024-05-05 19:34:35 +10:00
committed by GitHub
parent 3c0bb7d959
commit ecc3b25464
22 changed files with 533 additions and 58 deletions

View File

@ -1,11 +1,14 @@
"""InvenTree API version information."""
# InvenTree API version
INVENTREE_API_VERSION = 195
INVENTREE_API_VERSION = 196
"""Increment this API version number whenever there is a significant change to the API that any clients need to know about."""
INVENTREE_API_TEXT = """
v196 - 2024-05-05 : https://github.com/inventree/InvenTree/pull/7160
- Adds "location" field to BuildOutputComplete API endpoint
v195 - 2024-05-03 : https://github.com/inventree/InvenTree/pull/7153
- Fixes bug in BuildOrderCancel API endpoint

View File

@ -109,6 +109,12 @@ class Build(InvenTree.models.InvenTreeBarcodeMixin, InvenTree.models.InvenTreeNo
self.validate_reference_field(self.reference)
self.reference_int = self.rebuild_reference_field(self.reference)
# On first save (i.e. creation), run some extra checks
if self.pk is None:
# Set the destination location (if not specified)
if not self.destination:
self.destination = self.part.get_default_location()
try:
super().save(*args, **kwargs)
except InvalidMove:
@ -682,10 +688,13 @@ class Build(InvenTree.models.InvenTreeBarcodeMixin, InvenTree.models.InvenTreeNo
"""
user = kwargs.get('user', None)
batch = kwargs.get('batch', self.batch)
location = kwargs.get('location', self.destination)
location = kwargs.get('location', None)
serials = kwargs.get('serials', None)
auto_allocate = kwargs.get('auto_allocate', False)
if location is None:
location = self.destination or self.part.get_default_location()
"""
Determine if we can create a single output (with quantity > 0),
or multiple outputs (with quantity = 1)

View File

@ -286,6 +286,13 @@ class BuildOutputCreateSerializer(serializers.Serializer):
help_text=_('Enter serial numbers for build outputs'),
)
location = serializers.PrimaryKeyRelatedField(
queryset=StockLocation.objects.all(),
label=_('Location'),
help_text=_('Stock location for build output'),
required=False, allow_null=True
)
def validate_serial_numbers(self, serial_numbers):
"""Clean the provided serial number string"""
serial_numbers = serial_numbers.strip()
@ -310,6 +317,11 @@ class BuildOutputCreateSerializer(serializers.Serializer):
quantity = data['quantity']
serial_numbers = data.get('serial_numbers', '')
if part.trackable and not serial_numbers:
raise ValidationError({
'serial_numbers': _('Serial numbers must be provided for trackable parts')
})
if serial_numbers:
try:
@ -346,19 +358,15 @@ class BuildOutputCreateSerializer(serializers.Serializer):
"""Generate the new build output(s)"""
data = self.validated_data
quantity = data['quantity']
batch_code = data.get('batch_code', '')
auto_allocate = data.get('auto_allocate', False)
build = self.get_build()
user = self.context['request'].user
build.create_build_output(
quantity,
data['quantity'],
serials=self.serials,
batch=batch_code,
auto_allocate=auto_allocate,
user=user,
batch=data.get('batch_code', ''),
location=data.get('location', None),
auto_allocate=data.get('auto_allocate', False),
user=self.context['request'].user,
)