Refactor forms for sales orders

This commit is contained in:
Oliver 2021-07-03 00:14:36 +10:00
parent 984828f3bb
commit 993abd9d91
12 changed files with 132 additions and 200 deletions

View File

@ -42,15 +42,10 @@
});
$("#new-sales-order").click(function() {
launchModalForm(
"{% url 'so-create' %}",
{
data: {
customer: {{ company.id }},
},
follow: true,
},
);
createSalesOrder({
customer: {{ company.pk }},
});
});
{% endblock %}

View File

@ -12,7 +12,6 @@ from mptt.fields import TreeNodeChoiceField
from InvenTree.forms import HelperForm
from InvenTree.fields import InvenTreeMoneyField, RoundingDecimalFormField
from InvenTree.fields import DatePickerFormField
from InvenTree.helpers import clean_decimal
@ -97,41 +96,6 @@ class ReceivePurchaseOrderForm(HelperForm):
]
class EditSalesOrderForm(HelperForm):
""" Form for editing a SalesOrder object """
def __init__(self, *args, **kwargs):
self.field_prefix = {
'reference': 'SO',
'link': 'fa-link',
'target_date': 'fa-calendar-alt',
}
self.field_placeholder = {
'reference': _('Enter sales order number'),
}
super().__init__(*args, **kwargs)
target_date = DatePickerFormField(
label=_('Target Date'),
help_text=_('Target date for order completion. Order will be overdue after this date.'),
)
class Meta:
model = SalesOrder
fields = [
'reference',
'customer',
'customer_reference',
'description',
'target_date',
'link',
'responsible',
]
class EditPurchaseOrderLineItemForm(HelperForm):
""" Form for editing a PurchaseOrderLineItem object """

View File

@ -231,6 +231,7 @@ class SalesOrderSerializer(InvenTreeModelSerializer):
'notes',
'overdue',
'reference',
'responsible',
'status',
'status_text',
'shipment_date',

View File

@ -153,7 +153,28 @@ enableNavbar({
});
$("#edit-order").click(function() {
launchModalForm("{% url 'so-edit' order.id %}", {
constructForm('{% url "api-so-detail" order.pk %}', {
fields: {
reference: {
prefix: "{% settings_value 'SALESORDER_REFERENCE_PREFIX' %}",
},
{% if order.lines.count == 0 and order.status == SalesOrderStatus.PENDING %}
customer: {
},
{% endif %}
description: {},
target_date: {
icon: 'fa-calendar-alt',
},
link: {
icon: 'fa-link',
},
responsible: {
icon: 'fa-user',
},
},
title: '{% trans "Edit Sales Order" %}',
reload: true,
});
});

View File

@ -178,18 +178,7 @@ $("#order-print").click(function() {
})
$("#so-create").click(function() {
launchModalForm("{% url 'so-create' %}",
{
follow: true,
secondary: [
{
field: 'customer',
label: '{% trans "New Customer" %}',
title: '{% trans "Create new Customer" %}',
}
]
}
);
createSalesOrder();
});
{% endblock %}

View File

@ -11,7 +11,6 @@ from django.contrib.auth.models import Group
from InvenTree.status_codes import PurchaseOrderStatus
from .models import PurchaseOrder, PurchaseOrderLineItem
from .models import SalesOrder
import json
@ -60,88 +59,6 @@ class OrderListTest(OrderViewTestCase):
self.assertEqual(response.status_code, 200)
class SalesOrderCreate(OrderViewTestCase):
"""
Create a SalesOrder using the form view
"""
URL = reverse('so-create')
def test_create_view(self):
"""
Retrieve the view for creating a sales order'
"""
response = self.client.get(self.URL, HTTP_X_REQUESTED_WITH='XMLHttpRequest')
self.assertEqual(response.status_code, 200)
def post(self, data, **kwargs):
return self.client.post(self.URL, data, HTTP_X_REQUESTED_WITH='XMLHttpRequest', **kwargs)
def test_post_error(self):
"""
POST with errors
"""
n = SalesOrder.objects.count()
data = {
'reference': '12345678',
}
response = self.post(data)
data = json.loads(response.content)
self.assertIn('form_valid', data.keys())
# Customer is not specified - should return False
self.assertFalse(data['form_valid'])
errors = json.loads(data['form_errors'])
self.assertIn('customer', errors.keys())
self.assertIn('description', errors.keys())
# No new SalesOrder objects should have been created
self.assertEqual(SalesOrder.objects.count(), n)
def test_post_valid(self):
"""
POST a valid SalesOrder
"""
n = SalesOrder.objects.count()
data = {
'reference': '12345678',
'customer': 4,
'description': 'A description',
}
response = self.post(data)
json_data = json.loads(response.content)
self.assertTrue(json_data['form_valid'])
# Create another SalesOrder, this time with a target date
data = {
'reference': '12345679',
'customer': 4,
'description': 'Another order, this one with a target date!',
'target_date': '2020-12-25',
}
response = self.post(data)
json_data = json.loads(response.content)
self.assertEqual(SalesOrder.objects.count(), n + 2)
class POTests(OrderViewTestCase):
""" Tests for PurchaseOrder views """

View File

@ -47,8 +47,6 @@ purchase_order_urls = [
]
sales_order_detail_urls = [
url(r'^edit/', views.SalesOrderEdit.as_view(), name='so-edit'),
url(r'^cancel/', views.SalesOrderCancel.as_view(), name='so-cancel'),
url(r'^ship/', views.SalesOrderShip.as_view(), name='so-ship'),
@ -61,8 +59,6 @@ sales_order_detail_urls = [
sales_order_urls = [
url(r'^new/', views.SalesOrderCreate.as_view(), name='so-create'),
url(r'^line/', include([
url(r'^new/', views.SOLineItemCreate.as_view(), name='so-line-item-create'),
url(r'^(?P<pk>\d+)/', include([

View File

@ -42,7 +42,8 @@ from InvenTree.helpers import DownloadFile, str2bool
from InvenTree.helpers import extract_serial_numbers
from InvenTree.views import InvenTreeRoleMixin
from InvenTree.status_codes import PurchaseOrderStatus, SalesOrderStatus, StockStatus
from InvenTree.status_codes import PurchaseOrderStatus, StockStatus
logger = logging.getLogger("inventree")
@ -143,57 +144,6 @@ class SalesOrderNotes(InvenTreeRoleMixin, UpdateView):
return ctx
class SalesOrderCreate(AjaxCreateView):
""" View for creating a new SalesOrder object """
model = SalesOrder
ajax_form_title = _("Create Sales Order")
form_class = order_forms.EditSalesOrderForm
def get_initial(self):
initials = super().get_initial().copy()
initials['reference'] = SalesOrder.getNextOrderNumber()
initials['status'] = SalesOrderStatus.PENDING
customer_id = self.request.GET.get('customer', None)
if customer_id is not None:
try:
customer = Company.objects.get(id=customer_id)
initials['customer'] = customer
except (Company.DoesNotExist, ValueError):
pass
return initials
def save(self, form, **kwargs):
"""
Record the user who created this SalesOrder
"""
order = form.save(commit=False)
order.created_by = self.request.user
return super().save(form)
class SalesOrderEdit(AjaxUpdateView):
""" View for editing a SalesOrder """
model = SalesOrder
ajax_form_title = _('Edit Sales Order')
form_class = order_forms.EditSalesOrderForm
def get_form(self):
form = super().get_form()
# Prevent user from editing customer
form.fields['customer'].widget = HiddenInput()
return form
class PurchaseOrderCancel(AjaxUpdateView):
""" View for cancelling a purchase order """

View File

@ -369,6 +369,75 @@
});
$("#part-edit").click(function() {
constructForm('{% url "api-part-detail" part.id %}', {
focus: 'name',
fields: {
category: {
secondary: {
label: '{% trans "New Category" %}',
title: '{% trans "Create New Part Category" %}',
api_url: '{% url "api-part-category-list" %}',
method: 'POST',
fields: {
name: {},
description: {},
parent: {
secondary: {
title: '{% trans "New Parent" %}',
api_url: '{% url "api-part-category-list" %}',
method: 'POST',
fields: {
name: {},
description: {},
parent: {},
}
}
},
}
},
},
name: {
placeholder: 'part name',
},
IPN: {},
description: {},
revision: {},
keywords: {
icon: 'fa-key',
},
variant_of: {},
link: {
icon: 'fa-link',
},
default_location: {
secondary: {
label: '{% trans "New Location" %}',
title: '{% trans "Create new stock location" %}',
},
},
default_supplier: {
filters: {
part: {{ part.pk }},
part_detail: true,
manufacturer_detail: true,
supplier_detail: true,
},
secondary: {
label: '{% trans "New Supplier Part" %}',
title: '{% trans "Create new supplier part" %}',
}
},
units: {},
minimum_stock: {},
},
title: '{% trans "Edit Part" %}',
reload: true,
});
return;
launchModalForm(
"{% url 'part-edit' part.id %}",
{

View File

@ -2,7 +2,37 @@
{% load inventree_extras %}
// Create a new purchase order
// Create a new SalesOrder
function createSalesOrder(options={}) {
constructForm('{% url "api-so-list" %}', {
method: 'POST',
fields: {
reference: {
prefix: '{% settings_value "SALESORDER_REFERENCE_PREFIX" %}',
},
customer: {
value: options.customer,
},
description: {},
target_date: {
icon: 'fa-calendar-alt',
},
link: {
icon: 'fa-link',
},
responsible: {
icon: 'fa-user',
}
},
onSuccess: function(data) {
location.href = `/order/sales-order/${data.pk}/`;
},
title: '{% trans "Create Sales Order" %}',
});
}
// Create a new PurchaseOrder
function createPurchaseOrder(options={}) {
constructForm('{% url "api-po-list" %}', {

View File

@ -146,4 +146,4 @@ user_urls = [
url(r'^(?P<pk>[0-9]+)/?$', UserDetail.as_view(), name='user-detail'),
url(r'^$', UserList.as_view()),
]
]

View File

@ -1 +1 @@
# -*- coding: utf-8 -*-
# -*- coding: utf-8 -*-