mirror of
https://github.com/inventree/InvenTree
synced 2024-08-30 18:33:04 +00:00
Auto-generate build outputs when a build is created
This commit is contained in:
parent
170d55d64e
commit
22a5f921b8
@ -387,7 +387,7 @@ class AjaxCreateView(AjaxMixin, CreateView):
|
||||
|
||||
self.pre_save(self.form, request)
|
||||
self.object = self.form.save()
|
||||
self.post_save(new_object=self.object, request=request)
|
||||
self.post_save(new_object=self.object, request=request, form=self.form, data=self.form.cleaned_data)
|
||||
|
||||
# Return the PK of the newly-created object
|
||||
data['pk'] = self.object.pk
|
||||
|
@ -23,6 +23,7 @@ class EditBuildForm(HelperForm):
|
||||
'reference': 'BO',
|
||||
'link': 'fa-link',
|
||||
'batch': 'fa-layer-group',
|
||||
'serial-numbers': 'fa-hashtag',
|
||||
'location': 'fa-map-marker-alt',
|
||||
}
|
||||
|
||||
@ -30,6 +31,12 @@ class EditBuildForm(HelperForm):
|
||||
'reference': _('Build Order reference')
|
||||
}
|
||||
|
||||
serial_numbers = forms.CharField(
|
||||
label=_('Serial Numbers'),
|
||||
help_text=_('Serial numbers for build outputs'),
|
||||
required=False,
|
||||
)
|
||||
|
||||
class Meta:
|
||||
model = Build
|
||||
fields = [
|
||||
@ -38,6 +45,7 @@ class EditBuildForm(HelperForm):
|
||||
'part',
|
||||
'quantity',
|
||||
'batch',
|
||||
'serial_numbers',
|
||||
'take_from',
|
||||
'destination',
|
||||
'parent',
|
||||
|
@ -24,6 +24,7 @@ from mptt.models import MPTTModel, TreeForeignKey
|
||||
|
||||
from InvenTree.status_codes import BuildStatus
|
||||
from InvenTree.helpers import increment, getSetting, normalize
|
||||
from InvenTree.helpers import ExtractSerialNumbers
|
||||
from InvenTree.validators import validate_build_order_reference
|
||||
from InvenTree.models import InvenTreeAttachment
|
||||
|
||||
@ -269,21 +270,46 @@ class Build(MPTTModel):
|
||||
|
||||
return new_ref
|
||||
|
||||
def createInitialStockItem(self, user):
|
||||
def createInitialStockItem(self, serial_numbers, user):
|
||||
"""
|
||||
Create an initial output StockItem to be completed by this build.
|
||||
"""
|
||||
|
||||
output = StockModels.StockItem.objects.create(
|
||||
part=self.part, # Link to the parent part
|
||||
location=None, # No location (yet) until it is completed
|
||||
quantity=self.quantity,
|
||||
batch='', # The 'batch' code is not set until the item is completed
|
||||
build=self, # Point back to this build
|
||||
is_building=True, # Mark this StockItem as building
|
||||
)
|
||||
if self.part.trackable:
|
||||
# Trackable part? Create individual build outputs?
|
||||
|
||||
output.save()
|
||||
# Serial numbers specified for the build?
|
||||
if serial_numbers:
|
||||
serials = ExtractSerialNumbers(serial_numbers, self.quantity)
|
||||
else:
|
||||
serials = [None] * self.quantity
|
||||
|
||||
for serial in serials:
|
||||
output = StockModels.StockItem.objects.create(
|
||||
part=self.part,
|
||||
location=self.destination,
|
||||
quantity=1,
|
||||
batch=self.batch,
|
||||
serial=serial,
|
||||
build=self,
|
||||
is_building=True
|
||||
)
|
||||
|
||||
output.save()
|
||||
|
||||
else:
|
||||
# Create a single build output
|
||||
|
||||
output = StockModels.StockItem.objects.create(
|
||||
part=self.part, # Link to the parent part
|
||||
location=None, # No location (yet) until it is completed
|
||||
quantity=self.quantity,
|
||||
batch='', # The 'batch' code is not set until the item is completed
|
||||
build=self, # Point back to this build
|
||||
is_building=True, # Mark this StockItem as building
|
||||
)
|
||||
|
||||
output.save()
|
||||
|
||||
# TODO - Add a transaction note to the new StockItem
|
||||
|
||||
|
@ -512,6 +512,18 @@ class BuildCreate(AjaxCreateView):
|
||||
ajax_template_name = 'modal_form.html'
|
||||
role_required = 'build.add'
|
||||
|
||||
def get_form(self):
|
||||
form = super().get_form()
|
||||
|
||||
if form['part'].value():
|
||||
part = Part.objects.get(pk=form['part'].value())
|
||||
|
||||
# Part is not trackable - hide serial numbers
|
||||
if not part.trackable:
|
||||
form.fields['serial_numbers'].widget = HiddenInput()
|
||||
|
||||
return form
|
||||
|
||||
def get_initial(self):
|
||||
""" Get initial parameters for Build creation.
|
||||
|
||||
@ -547,6 +559,33 @@ class BuildCreate(AjaxCreateView):
|
||||
return {
|
||||
'success': _('Created new build'),
|
||||
}
|
||||
|
||||
def validate(self, cleaned_data, **kwargs):
|
||||
"""
|
||||
Perform extra form validation.
|
||||
|
||||
- If part is trackable, check that either batch or serial numbers are calculated
|
||||
|
||||
By this point form.is_valid() has been executed
|
||||
"""
|
||||
|
||||
part = cleaned_data['part']
|
||||
|
||||
if part.trackable:
|
||||
# For a trackable part, either batch or serial nubmber must be specified
|
||||
if not cleaned_data['batch'] and not cleaned_data['serial_numbers']:
|
||||
raise ValidationError({
|
||||
'part': _('Trackable part must have either batch or serial number specified')
|
||||
})
|
||||
|
||||
# If serial numbers are set...
|
||||
serials = cleaned_data['serial_numbers']
|
||||
quantity = cleaned_data['quantity']
|
||||
|
||||
extracted = ExtractSerialNumbers(serials, quantity)
|
||||
|
||||
# Ok, no errors...
|
||||
return True
|
||||
|
||||
def post_save(self, **kwargs):
|
||||
"""
|
||||
@ -555,8 +594,11 @@ class BuildCreate(AjaxCreateView):
|
||||
|
||||
build = kwargs['new_object']
|
||||
request = kwargs['request']
|
||||
data = kwargs['data']
|
||||
|
||||
serials = data['serial_numbers']
|
||||
|
||||
build.createInitialStockItem(request.user)
|
||||
build.createInitialStockItem(serials, request.user)
|
||||
|
||||
|
||||
class BuildUpdate(AjaxUpdateView):
|
||||
|
Loading…
Reference in New Issue
Block a user