Refactor CancelSalesOrder form

This commit is contained in:
Oliver Walters 2022-05-04 15:55:21 +10:00
parent bf48e3204b
commit a510ca89f7
9 changed files with 74 additions and 102 deletions

View File

@ -287,6 +287,7 @@ class PurchaseOrderDetail(generics.RetrieveUpdateDestroyAPIView):
class PurchaseOrderContextMixin:
""" Mixin to add purchase order object as serializer context variable """
def get_serializer_context(self):
""" Add the PurchaseOrder object to the serializer context """
@ -871,13 +872,8 @@ class SalesOrderLineItemDetail(generics.RetrieveUpdateDestroyAPIView):
serializer_class = serializers.SalesOrderLineItemSerializer
class SalesOrderComplete(generics.CreateAPIView):
"""
API endpoint for manually marking a SalesOrder as "complete".
"""
queryset = models.SalesOrder.objects.all()
serializer_class = serializers.SalesOrderCompleteSerializer
class SalesOrderContextMixin:
""" Mixin to add sales order object as serializer context variable """
def get_serializer_context(self):
@ -893,7 +889,22 @@ class SalesOrderComplete(generics.CreateAPIView):
return ctx
class SalesOrderAllocateSerials(generics.CreateAPIView):
class SalesOrderCancel(SalesOrderContextMixin, generics.CreateAPIView):
queryset = models.SalesOrder.objects.all()
serializer_class = serializers.SalesOrderCancelSerializer
class SalesOrderComplete(SalesOrderContextMixin, generics.CreateAPIView):
"""
API endpoint for manually marking a SalesOrder as "complete".
"""
queryset = models.SalesOrder.objects.all()
serializer_class = serializers.SalesOrderCompleteSerializer
class SalesOrderAllocateSerials(SalesOrderContextMixin, generics.CreateAPIView):
"""
API endpoint to allocation stock items against a SalesOrder,
by specifying serial numbers.
@ -902,22 +913,8 @@ class SalesOrderAllocateSerials(generics.CreateAPIView):
queryset = models.SalesOrder.objects.none()
serializer_class = serializers.SalesOrderSerialAllocationSerializer
def get_serializer_context(self):
ctx = super().get_serializer_context()
# Pass through the SalesOrder object to the serializer
try:
ctx['order'] = models.SalesOrder.objects.get(pk=self.kwargs.get('pk', None))
except:
pass
ctx['request'] = self.request
return ctx
class SalesOrderAllocate(generics.CreateAPIView):
class SalesOrderAllocate(SalesOrderContextMixin, generics.CreateAPIView):
"""
API endpoint to allocate stock items against a SalesOrder
@ -928,20 +925,6 @@ class SalesOrderAllocate(generics.CreateAPIView):
queryset = models.SalesOrder.objects.none()
serializer_class = serializers.SalesOrderShipmentAllocationSerializer
def get_serializer_context(self):
ctx = super().get_serializer_context()
# Pass through the SalesOrder object to the serializer
try:
ctx['order'] = models.SalesOrder.objects.get(pk=self.kwargs.get('pk', None))
except:
pass
ctx['request'] = self.request
return ctx
class SalesOrderAllocationDetail(generics.RetrieveUpdateDestroyAPIView):
"""
@ -1183,6 +1166,7 @@ order_api_urls = [
# Sales order detail view
re_path(r'^(?P<pk>\d+)/', include([
re_path(r'^cancel/', SalesOrderCancel.as_view(), name='api-so-cancel'),
re_path(r'^complete/', SalesOrderComplete.as_view(), name='api-so-complete'),
re_path(r'^allocate/', SalesOrderAllocate.as_view(), name='api-so-allocate'),
re_path(r'^allocate-serials/', SalesOrderAllocateSerials.as_view(), name='api-so-allocate-serials'),

View File

@ -8,28 +8,12 @@ from __future__ import unicode_literals
from django import forms
from django.utils.translation import gettext_lazy as _
from InvenTree.forms import HelperForm
from InvenTree.fields import InvenTreeMoneyField
from InvenTree.helpers import clean_decimal
from common.forms import MatchItemForm
from .models import PurchaseOrder
from .models import SalesOrder
class CancelSalesOrderForm(HelperForm):
confirm = forms.BooleanField(required=True, label=_('Confirm'), help_text=_('Cancel order'))
class Meta:
model = SalesOrder
fields = [
'confirm',
]
class OrderMatchItemForm(MatchItemForm):
""" Override MatchItemForm fields """

View File

@ -1041,6 +1041,25 @@ class SalesOrderCompleteSerializer(serializers.Serializer):
order.complete_order(user)
class SalesOrderCancelSerializer(serializers.Serializer):
""" Serializer for marking a SalesOrder as cancelled
"""
def get_context_data(self):
order = self.context['order']
return {
'can_cancel': order.can_cancel(),
}
def save(self):
order = self.context['order']
order.cancel_order()
class SalesOrderSerialAllocationSerializer(serializers.Serializer):
"""
DRF serializer for allocation of serial numbers against a sales order / shipment

View File

@ -1,7 +0,0 @@
{% extends "modal_delete_form.html" %}
{% load i18n %}
{% block pre_form_content %}
{% trans "Are you sure you want to delete this attachment?" %}
<br>
{% endblock %}

View File

@ -224,9 +224,13 @@ $("#edit-order").click(function() {
});
$("#cancel-order").click(function() {
launchModalForm("{% url 'so-cancel' order.id %}", {
reload: true,
});
cancelSalesOrder(
{{ order.pk }},
{
reload: true,
}
);
});
$("#complete-order").click(function() {

View File

@ -1,12 +0,0 @@
{% extends "modal_form.html" %}
{% load i18n %}
{% block pre_form_content %}
<div class='alert alert-block alert-warning'>
<h4>{% trans "Warning" %}</h4>
{% trans "Cancelling this order means that the order will no longer be editable." %}
</div>
{% endblock %}

View File

@ -29,7 +29,6 @@ purchase_order_urls = [
]
sales_order_detail_urls = [
re_path(r'^cancel/', views.SalesOrderCancel.as_view(), name='so-cancel'),
re_path(r'^export/', views.SalesOrderExport.as_view(), name='so-export'),
re_path(r'^.*$', views.SalesOrderDetail.as_view(), name='so-detail'),

View File

@ -87,32 +87,6 @@ class SalesOrderDetail(InvenTreeRoleMixin, DetailView):
template_name = 'order/sales_order_detail.html'
class SalesOrderCancel(AjaxUpdateView):
""" View for cancelling a sales order """
model = SalesOrder
ajax_form_title = _("Cancel sales order")
ajax_template_name = "order/sales_order_cancel.html"
form_class = order_forms.CancelSalesOrderForm
def validate(self, order, form, **kwargs):
confirm = str2bool(form.cleaned_data.get('confirm', False))
if not confirm:
form.add_error('confirm', _('Confirm order cancellation'))
if not order.can_cancel():
form.add_error(None, _('Order cannot be cancelled'))
def save(self, order, form, **kwargs):
"""
Once the form has been validated, cancel the SalesOrder
"""
order.cancel_order()
class PurchaseOrderUpload(FileManagementFormView):
''' PurchaseOrder: Upload file, match to fields and parts (using multi-Step form) '''

View File

@ -21,6 +21,7 @@
/* exported
allocateStockToSalesOrder,
cancelPurchaseOrder,
cancelSalesOrder,
completePurchaseOrder,
completeShipment,
createSalesOrder,
@ -246,6 +247,32 @@ function issuePurchaseOrder(order_id, options={}) {
}
/*
* Launches a modal form to mark a SalesOrder as "cancelled"
*/
function cancelSalesOrder(order_id, options={}) {
constructForm(
`/api/order/so/${order_id}/cancel/`,
{
method: 'POST',
title: '{% trans "Cancel Sales Order" %}',
confirm: true,
preFormContent: function(opts) {
var html = `
<div class='alert alert-block alert-warning'>
{% trans "Cancelling this order means that the order will no longer be editable." %}
</div>`;
return html;
},
onSuccess: function(response) {
handleFormSuccess(response, options);
}
}
);
}
// Open a dialog to create a new sales order shipment
function createSalesOrderShipment(options={}) {