mirror of
https://github.com/inventree/InvenTree
synced 2024-08-30 18:33:04 +00:00
Add functionality to cancel a sales order
This commit is contained in:
parent
e384f9e94c
commit
e5fa94b4f8
@ -52,6 +52,17 @@ class CancelPurchaseOrderForm(HelperForm):
|
||||
]
|
||||
|
||||
|
||||
class CancelSalesOrderForm(HelperForm):
|
||||
|
||||
confirm = forms.BooleanField(required=False, help_text=_('Cancel order'))
|
||||
|
||||
class Meta:
|
||||
model = SalesOrder
|
||||
fields = [
|
||||
'confirm',
|
||||
]
|
||||
|
||||
|
||||
class ReceivePurchaseOrderForm(HelperForm):
|
||||
|
||||
location = TreeNodeChoiceField(queryset=StockLocation.objects.all(), required=True, help_text=_('Receive parts to this location'))
|
||||
|
@ -289,6 +289,10 @@ class SalesOrder(Order):
|
||||
related_name='+'
|
||||
)
|
||||
|
||||
@property
|
||||
def is_pending(self):
|
||||
return self.status == SalesOrderStatus.PENDING
|
||||
|
||||
def is_fully_allocated(self):
|
||||
""" Return True if all line items are fully allocated """
|
||||
|
||||
@ -298,6 +302,42 @@ class SalesOrder(Order):
|
||||
|
||||
return True
|
||||
|
||||
@transaction.atomic
|
||||
def ship_order(self, user):
|
||||
""" Mark this order as 'shipped' """
|
||||
|
||||
if not self.status == SalesOrderStatus.PENDING:
|
||||
return False
|
||||
|
||||
# Ensure the order status is marked as "Shipped"
|
||||
self.status = SalesOrderStatus.SHIPPED
|
||||
self.shipment_date = datetime.now().date()
|
||||
self.shipped_by = user
|
||||
self.save()
|
||||
|
||||
return True
|
||||
|
||||
@transaction.atomic
|
||||
def cancel_order(self):
|
||||
"""
|
||||
Cancel this order (only if it is "pending")
|
||||
|
||||
- Mark the order as 'cancelled'
|
||||
- Delete any StockItems which have been allocated
|
||||
"""
|
||||
|
||||
if not self.status == SalesOrderStatus.PENDING:
|
||||
return False
|
||||
|
||||
self.status = SalesOrderStatus.CANCELLED
|
||||
self.save()
|
||||
|
||||
for line in self.lines.all():
|
||||
for allocation in line.allocations.all():
|
||||
allocation.delete()
|
||||
|
||||
return True
|
||||
|
||||
|
||||
class PurchaseOrderAttachment(InvenTreeAttachment):
|
||||
"""
|
||||
|
@ -1,7 +1,9 @@
|
||||
{% extends "modal_form.html" %}
|
||||
|
||||
{% load i18n %}
|
||||
|
||||
{% block pre_form_content %}
|
||||
|
||||
Cancelling this order means that the order will no longer be editable.
|
||||
{% trans "Cancelling this order means that the order will no longer be editable." %}
|
||||
|
||||
{% endblock %}
|
@ -27,6 +27,7 @@ src="{% static 'img/blank_image.png' %}"
|
||||
/>
|
||||
{% endblock %}
|
||||
|
||||
|
||||
{% block page_data %}
|
||||
<h3>{% trans "Sales Order" %}</h3>
|
||||
<hr>
|
||||
@ -40,6 +41,11 @@ src="{% static 'img/blank_image.png' %}"
|
||||
<button type='button' class='btn btn-default' id='packing-list' title='{% trans "Packing List" %}'>
|
||||
<span class='fas fa-clipboard-list'></span>
|
||||
</button>
|
||||
{% if order.is_pending %}
|
||||
<button type='button' class='btn btn-default' id='cancel-order' title='{% trans "Cancel order" %}'>
|
||||
<span class='fas fa-times-circle icon-red'></span>
|
||||
</button>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
@ -82,11 +88,11 @@ src="{% static 'img/blank_image.png' %}"
|
||||
<td>{% trans "Created" %}</td>
|
||||
<td>{{ order.creation_date }}<span class='badge'>{{ order.created_by }}</span></td>
|
||||
</tr>
|
||||
{% if order.issue_date %}
|
||||
{% if order.shipment_date %}
|
||||
<tr>
|
||||
<td><span class='fas fa-calendar-alt'></span></td>
|
||||
<td>{% trans "Issued" %}</td>
|
||||
<td>{{ order.issue_date }}</td>
|
||||
<td><span class='fas fa-truck'></span></td>
|
||||
<td>{% trans "Shipped" %}</td>
|
||||
<td>{{ order.shipment_date }}<span class='badge'>{{ order.shipped_by }}</span></td>
|
||||
</tr>
|
||||
{% endif %}
|
||||
{% if order.status == OrderStatus.COMPLETE %}
|
||||
@ -108,4 +114,10 @@ $("#edit-order").click(function() {
|
||||
});
|
||||
});
|
||||
|
||||
$("#cancel-order").click(function() {
|
||||
launchModalForm("{% url 'so-cancel' order.id %}", {
|
||||
reload: true,
|
||||
});
|
||||
});
|
||||
|
||||
{% endblock %}
|
9
InvenTree/order/templates/order/sales_order_cancel.html
Normal file
9
InvenTree/order/templates/order/sales_order_cancel.html
Normal file
@ -0,0 +1,9 @@
|
||||
{% extends "modal_form.html" %}
|
||||
|
||||
{% load i18n %}
|
||||
|
||||
{% block pre_form_content %}
|
||||
|
||||
{% trans "Cancelling this order means that the order will no longer be editable." %}
|
||||
|
||||
{% endblock %}
|
@ -55,6 +55,7 @@ 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'^attachments/', views.SalesOrderDetail.as_view(template_name='order/so_attachments.html'), name='so-attachments'),
|
||||
url(r'^notes/', views.SalesOrderNotes.as_view(), name='so-notes'),
|
||||
|
@ -394,6 +394,38 @@ class PurchaseOrderCancel(AjaxUpdateView):
|
||||
return self.renderJsonResponse(request, form, data)
|
||||
|
||||
|
||||
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 post(self, request, *args, **kwargs):
|
||||
|
||||
order = self.get_object()
|
||||
form = self.get_form()
|
||||
|
||||
confirm = str2bool(request.POST.get('confirm', False))
|
||||
|
||||
valid = False
|
||||
|
||||
if not confirm:
|
||||
forms.errors['confirm'] = [_('Confirm order cancellation')]
|
||||
else:
|
||||
valid = True
|
||||
|
||||
data = {
|
||||
'form_valid': valid,
|
||||
}
|
||||
|
||||
if valid:
|
||||
order.cancel_order()
|
||||
|
||||
return self.renderJsonResponse(request, form, data)
|
||||
|
||||
|
||||
class PurchaseOrderIssue(AjaxUpdateView):
|
||||
""" View for changing a purchase order from 'PENDING' to 'ISSUED' """
|
||||
|
||||
|
@ -30,16 +30,7 @@ def build_status(key, *args, **kwargs):
|
||||
return mark_safe(BuildStatus.render(key))
|
||||
|
||||
|
||||
@register.simple_tag(takes_context=True)
|
||||
def load_status_codes(context):
|
||||
"""
|
||||
Make the various StatusCodes available to the page context
|
||||
"""
|
||||
|
||||
context['purchase_order_status_codes'] = PurchaseOrderStatus.list()
|
||||
context['sales_order_status_codes'] = SalesOrderStatus.list()
|
||||
context['stock_status_codes'] = StockStatus.list()
|
||||
context['build_status_codes'] = BuildStatus.list()
|
||||
|
||||
# Need to return something as the result is rendered to the page
|
||||
return ''
|
||||
@register.simple_tag
|
||||
def sales_order_codes(*args, **kwargs):
|
||||
print("doing")
|
||||
return "hello world"
|
@ -1,8 +1,6 @@
|
||||
{% load i18n %}
|
||||
{% load status_codes %}
|
||||
|
||||
{% load_status_codes %}
|
||||
|
||||
<script type='text/javascript'>
|
||||
|
||||
{% include "status_codes.html" with label='stock' options=stock_status_codes %}
|
||||
|
Loading…
Reference in New Issue
Block a user