diff --git a/InvenTree/company/templates/company/sales_orders.html b/InvenTree/company/templates/company/sales_orders.html index e8585e2caa..c21a9afc21 100644 --- a/InvenTree/company/templates/company/sales_orders.html +++ b/InvenTree/company/templates/company/sales_orders.html @@ -42,15 +42,10 @@ }); $("#new-sales-order").click(function() { - launchModalForm( - "{% url 'so-create' %}", - { - data: { - customer: {{ company.id }}, - }, - follow: true, - }, - ); + + createSalesOrder({ + customer: {{ company.pk }}, + }); }); {% endblock %} \ No newline at end of file diff --git a/InvenTree/order/forms.py b/InvenTree/order/forms.py index 86b1ac5076..60837b6cf6 100644 --- a/InvenTree/order/forms.py +++ b/InvenTree/order/forms.py @@ -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 """ diff --git a/InvenTree/order/serializers.py b/InvenTree/order/serializers.py index 83eb01ea99..e7b71e6aa0 100644 --- a/InvenTree/order/serializers.py +++ b/InvenTree/order/serializers.py @@ -231,6 +231,7 @@ class SalesOrderSerializer(InvenTreeModelSerializer): 'notes', 'overdue', 'reference', + 'responsible', 'status', 'status_text', 'shipment_date', diff --git a/InvenTree/order/templates/order/sales_order_base.html b/InvenTree/order/templates/order/sales_order_base.html index b342cefe66..7a2c63c5a6 100644 --- a/InvenTree/order/templates/order/sales_order_base.html +++ b/InvenTree/order/templates/order/sales_order_base.html @@ -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, }); }); diff --git a/InvenTree/order/templates/order/sales_orders.html b/InvenTree/order/templates/order/sales_orders.html index bfa6d85a9d..d4ebbd4ca8 100644 --- a/InvenTree/order/templates/order/sales_orders.html +++ b/InvenTree/order/templates/order/sales_orders.html @@ -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 %} \ No newline at end of file diff --git a/InvenTree/order/test_views.py b/InvenTree/order/test_views.py index 22f193b0ff..4cd0705f7e 100644 --- a/InvenTree/order/test_views.py +++ b/InvenTree/order/test_views.py @@ -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 """ diff --git a/InvenTree/order/urls.py b/InvenTree/order/urls.py index 8cbd99911a..7d474c7db2 100644 --- a/InvenTree/order/urls.py +++ b/InvenTree/order/urls.py @@ -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\d+)/', include([ diff --git a/InvenTree/order/views.py b/InvenTree/order/views.py index 83a7fe12f8..6914b4fe19 100644 --- a/InvenTree/order/views.py +++ b/InvenTree/order/views.py @@ -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 """ diff --git a/InvenTree/part/templates/part/part_base.html b/InvenTree/part/templates/part/part_base.html index 922ff01912..ee9d541762 100644 --- a/InvenTree/part/templates/part/part_base.html +++ b/InvenTree/part/templates/part/part_base.html @@ -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 %}", { diff --git a/InvenTree/templates/js/order.js b/InvenTree/templates/js/order.js index 16d21a33ac..5cb286e970 100644 --- a/InvenTree/templates/js/order.js +++ b/InvenTree/templates/js/order.js @@ -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" %}', { diff --git a/InvenTree/users/api.py b/InvenTree/users/api.py index 7efb0ad51c..240d6aabc0 100644 --- a/InvenTree/users/api.py +++ b/InvenTree/users/api.py @@ -146,4 +146,4 @@ user_urls = [ url(r'^(?P[0-9]+)/?$', UserDetail.as_view(), name='user-detail'), url(r'^$', UserList.as_view()), -] \ No newline at end of file +] diff --git a/InvenTree/users/urls.py b/InvenTree/users/urls.py index 7c68785e9d..40a96afc6f 100644 --- a/InvenTree/users/urls.py +++ b/InvenTree/users/urls.py @@ -1 +1 @@ -# -*- coding: utf-8 -*- \ No newline at end of file +# -*- coding: utf-8 -*-