diff --git a/InvenTree/order/forms.py b/InvenTree/order/forms.py
index 56569812cd..6b4e0706ee 100644
--- a/InvenTree/order/forms.py
+++ b/InvenTree/order/forms.py
@@ -117,3 +117,19 @@ class EditPurchaseOrderLineItemForm(HelperForm):
'reference',
'notes',
]
+
+
+class EditSalesOrderLineItemForm(HelperForm):
+ """ Form for editing a SalesOrderLineItem object """
+
+ quantity = RoundingDecimalFormField(max_digits=10, decimal_places=5)
+
+ class Meta:
+ model = SalesOrderLineItem
+ fields = [
+ 'order',
+ 'part',
+ 'quantity',
+ 'reference',
+ 'notes'
+ ]
diff --git a/InvenTree/order/models.py b/InvenTree/order/models.py
index 2eb60055ca..a01ab0caed 100644
--- a/InvenTree/order/models.py
+++ b/InvenTree/order/models.py
@@ -124,6 +124,9 @@ class PurchaseOrder(Order):
ORDER_PREFIX = "PO"
+ def __str__(self):
+ return "PO {ref} - {company}".format(ref=self.reference, company=self.supplier.name)
+
supplier = models.ForeignKey(
Company, on_delete=models.CASCADE,
limit_choices_to={
@@ -255,6 +258,9 @@ class SalesOrder(Order):
customer_reference: Optional field for customer order reference code
"""
+ def __str__(self):
+ return "SO {ref} - {company}".format(ref=self.reference, company=self.customer.name)
+
def get_absolute_url(self):
return reverse('so-detail', kwargs={'pk': self.id})
diff --git a/InvenTree/order/templates/order/sales_order_detail.html b/InvenTree/order/templates/order/sales_order_detail.html
index 3fa9a918d4..52759e5b8a 100644
--- a/InvenTree/order/templates/order/sales_order_detail.html
+++ b/InvenTree/order/templates/order/sales_order_detail.html
@@ -14,9 +14,7 @@
{% trans "Sales Order Items" %}
- {% if order.status == OrderStatus.PENDING %}
-
- {% endif %}
+
@@ -28,6 +26,17 @@
{% block js_ready %}
{{ block.super }}
+$("#new-so-line").click(function() {
+ launchModalForm("{% url 'so-line-item-create' %}", {
+ reload: true,
+ data: {
+ order: {{ order.id }},
+ },
+ secondary: [
+ ]
+ });
+});
+
$("#so-lines-table").inventreeTable({
formatNoMatches: function() { return "No matching line items"; },
queryParams: {
diff --git a/InvenTree/order/views.py b/InvenTree/order/views.py
index 2aafc9a677..d9ea9d01d1 100644
--- a/InvenTree/order/views.py
+++ b/InvenTree/order/views.py
@@ -1008,7 +1008,47 @@ class POLineItemCreate(AjaxCreateView):
order = PurchaseOrder.objects.get(id=order_id)
initials['order'] = order
- except PurchaseOrder.DoesNotExist:
+ except (PurchaseOrder.DoesNotExist, ValueError):
+ pass
+
+ return initials
+
+
+class SOLineItemCreate(AjaxCreateView):
+ """ Ajax view for creating a new SalesOrderLineItem object """
+
+ model = SalesOrderLineItem
+ context_order_name = 'line'
+ form_class = order_forms.EditSalesOrderLineItemForm
+ ajax_form_title = _('Add Line Item')
+
+ def get_initial(self):
+ """
+ Extract initial data for this line item:
+
+ Options:
+ order: The SalesOrder object
+ part: The Part object
+ """
+
+ initials = super().get_initial().copy()
+
+ order_id = self.request.GET.get('order', None)
+ part_id = self.request.GET.get('part', None)
+
+ if order_id:
+ try:
+ order = SalesOrder.objects.get(id=order_id)
+ initials['order'] = order
+ except (SalesOrder.DoesNotExist, ValueError):
+ pass
+
+ if part_id:
+ try:
+ part = Part.objects.get(id=part_id)
+ if part.salable:
+ initials['part'] = part
+ except (Part.DoesNotExist, ValueError):
pass
return initials