Add custom form template

This commit is contained in:
Oliver Walters 2021-03-30 00:10:28 +11:00
parent 19059ea4cf
commit 217097c9d3
4 changed files with 96 additions and 6 deletions

View File

@ -220,25 +220,34 @@ class AllocateSerialsToSalesOrderForm(forms.Form):
""" """
line = forms.ModelChoiceField( line = forms.ModelChoiceField(
queryset = SalesOrderLineItem.objects.all(), queryset=SalesOrderLineItem.objects.all(),
) )
part = forms.ModelChoiceField( part = forms.ModelChoiceField(
queryset = part.models.Part.objects.all(), queryset=part.models.Part.objects.all(),
) )
serials = forms.CharField( serials = forms.CharField(
label=_("Serial Numbers"), label=_("Serial Numbers"),
required=False, required=True,
help_text=_('Enter stock item serial numbers'), help_text=_('Enter stock item serial numbers'),
) )
quantity = forms.IntegerField(
label=_('Quantity'),
required=True,
help_text=_('Enter quantity of stock items'),
initial=1,
min_value=1
)
class Meta: class Meta:
fields = [ fields = [
'line', 'line',
'part', 'part',
'serials', 'serials',
'quantity',
] ]
@ -247,7 +256,7 @@ class CreateSalesOrderAllocationForm(HelperForm):
Form for creating a SalesOrderAllocation item. Form for creating a SalesOrderAllocation item.
""" """
quantity = RoundingDecimalFormField(max_digits = 10, decimal_places=5) quantity = RoundingDecimalFormField(max_digits=10, decimal_places=5)
class Meta: class Meta:
model = SalesOrderAllocation model = SalesOrderAllocation

View File

@ -736,7 +736,7 @@ class SalesOrderAllocation(models.Model):
if not self.item: if not self.item:
raise ValidationError({'item': _('Stock item has not been assigned')}) raise ValidationError({'item': _('Stock item has not been assigned')})
except stock_models.StockItem.DoesNotExist: except stock_models.StockItem.DoesNotExist:
raise ValidationError({'item': _('Stock item has not been assigned')}) raise ValidationError({'item': _('Stock item has not been assigned')})
try: try:
if not self.line.part == self.item.part: if not self.line.part == self.item.part:

View File

@ -0,0 +1,12 @@
{% extends "modal_form.html" %}
{% load i18n %}
{% block pre_form_content %}
<div class='alert alert-block alert-info'>
{% include "hover_image.html" with image=part.image hover=true %}{{ part }}
<hr>
{% trans "Allocate stock items by serial number" %}
</div>
{% endblock %}

View File

@ -7,6 +7,7 @@ from __future__ import unicode_literals
from django.db import transaction from django.db import transaction
from django.shortcuts import get_object_or_404 from django.shortcuts import get_object_or_404
from django.core.exceptions import ValidationError
from django.urls import reverse from django.urls import reverse
from django.utils.translation import ugettext as _ from django.utils.translation import ugettext as _
from django.views.generic import DetailView, ListView, UpdateView from django.views.generic import DetailView, ListView, UpdateView
@ -31,6 +32,7 @@ from . import forms as order_forms
from InvenTree.views import AjaxView, AjaxCreateView, AjaxUpdateView, AjaxDeleteView from InvenTree.views import AjaxView, AjaxCreateView, AjaxUpdateView, AjaxDeleteView
from InvenTree.helpers import DownloadFile, str2bool from InvenTree.helpers import DownloadFile, str2bool
from InvenTree.helpers import extract_serial_numbers
from InvenTree.views import InvenTreeRoleMixin from InvenTree.views import InvenTreeRoleMixin
from InvenTree.status_codes import PurchaseOrderStatus, SalesOrderStatus, StockStatus from InvenTree.status_codes import PurchaseOrderStatus, SalesOrderStatus, StockStatus
@ -1300,6 +1302,7 @@ class SalesOrderAssignSerials(AjaxView, FormMixin):
model = SalesOrderAllocation model = SalesOrderAllocation
role_required = 'sales_order.change' role_required = 'sales_order.change'
ajax_template_name = 'order/so_allocate_by_serial.html'
ajax_form_title = _('Allocate Serial Numbers') ajax_form_title = _('Allocate Serial Numbers')
form_class = order_forms.AllocateSerialsToSalesOrderForm form_class = order_forms.AllocateSerialsToSalesOrderForm
@ -1338,10 +1341,14 @@ class SalesOrderAssignSerials(AjaxView, FormMixin):
valid = self.form.is_valid() valid = self.form.is_valid()
if valid:
self.allocate_items()
data = { data = {
'form_valid': valid, 'form_valid': valid,
'form_errors': self.form.errors.as_json(), 'form_errors': self.form.errors.as_json(),
'non_field_errors': self.form.non_field_errors().as_json(), 'non_field_errors': self.form.non_field_errors().as_json(),
'success': _("Allocated") + f" {len(self.stock_items)} " + _("items")
} }
return self.renderJsonResponse(request, self.form, data) return self.renderJsonResponse(request, self.form, data)
@ -1364,7 +1371,69 @@ class SalesOrderAssignSerials(AjaxView, FormMixin):
else: else:
self.form.add_error('part', _('Select part')) self.form.add_error('part', _('Select part'))
self.form.add_error('serials', 'abcde') if not self.form.is_valid():
return
# Form is otherwise valid - check serial numbers
serials = data.get('serials', '')
quantity = data.get('quantity', 1)
# Save a list of serial_numbers
self.serial_numbers = None
self.stock_items = []
try:
self.serial_numbers = extract_serial_numbers(serials, quantity)
for serial in self.serial_numbers:
try:
# Find matching stock item
stock_item = StockItem.objects.get(
part=self.part,
serial=serial
)
except StockItem.DoesNotExist:
self.form.add_error(
'serials',
_('No matching item for serial') + f" '{serial}'"
)
continue
# Now we have a valid stock item - but can it be added to the sales order?
# If not in stock, cannot be added to the order
if not stock_item.in_stock:
self.form.add_error(
'serials',
f"'{serial}' " + _("is not in stock")
)
continue
# Already allocated to an order
if stock_item.is_allocated():
self.form.add_error(
'serials',
f"'{serial}' " + _("already allocated to an order")
)
continue
# Add it to the list!
self.stock_items.append(stock_item)
except ValidationError as e:
self.form.add_error('serials', e.messages)
def allocate_items(self):
"""
Create stock item allocations for each selected serial number
"""
for stock_item in self.stock_items:
SalesOrderAllocation.objects.create(
item=stock_item,
line=self.line,
quantity=1,
)
def get_form(self): def get_form(self):