diff --git a/InvenTree/InvenTree/fields.py b/InvenTree/InvenTree/fields.py index 8d9ab77463..462d2b0e0e 100644 --- a/InvenTree/InvenTree/fields.py +++ b/InvenTree/InvenTree/fields.py @@ -14,8 +14,10 @@ from django.core import validators from django import forms from decimal import Decimal + from djmoney.models.fields import MoneyField as ModelMoneyField from djmoney.forms.fields import MoneyField +from djmoney.models.validators import MinMoneyValidator import InvenTree.helpers import common.settings @@ -47,7 +49,10 @@ def money_kwargs(): class InvenTreeModelMoneyField(ModelMoneyField): - """ custom MoneyField for clean migrations while using dynamic currency settings """ + """ + Custom MoneyField for clean migrations while using dynamic currency settings + """ + def __init__(self, **kwargs): # detect if creating migration if 'makemigrations' in sys.argv: @@ -58,6 +63,16 @@ class InvenTreeModelMoneyField(ModelMoneyField): # set defaults kwargs.update(money_kwargs()) + # Set a minimum value validator + validators = kwargs.get('validators', []) + + if len(validators) == 0: + validators.append( + MinMoneyValidator(0), + ) + + kwargs['validators'] = validators + super().__init__(**kwargs) def formfield(self, **kwargs): diff --git a/InvenTree/order/api.py b/InvenTree/order/api.py index 446b5a4313..5337676672 100644 --- a/InvenTree/order/api.py +++ b/InvenTree/order/api.py @@ -254,10 +254,12 @@ class POLineItemList(generics.ListCreateAPIView): ] -class POLineItemDetail(generics.RetrieveUpdateAPIView): - """ API endpoint for detail view of a PurchaseOrderLineItem object """ +class POLineItemDetail(generics.RetrieveUpdateDestroyAPIView): + """ + Detail API endpoint for PurchaseOrderLineItem object + """ - queryset = PurchaseOrderLineItem + queryset = PurchaseOrderLineItem.objects.all() serializer_class = POLineItemSerializer diff --git a/InvenTree/order/serializers.py b/InvenTree/order/serializers.py index e7b71e6aa0..15e9e5ef9b 100644 --- a/InvenTree/order/serializers.py +++ b/InvenTree/order/serializers.py @@ -5,13 +5,16 @@ JSON serializers for the Order API # -*- coding: utf-8 -*- from __future__ import unicode_literals -from rest_framework import serializers - -from sql_util.utils import SubqueryCount +from django.utils.translation import ugettext_lazy as _ from django.db.models import Case, When, Value from django.db.models import BooleanField +from rest_framework import serializers +from sql_util.utils import SubqueryCount + +import djmoney.settings + from InvenTree.serializers import InvenTreeModelSerializer from InvenTree.serializers import InvenTreeAttachmentSerializerField @@ -125,6 +128,11 @@ class POLineItemSerializer(InvenTreeModelSerializer): destination = LocationBriefSerializer(source='get_destination', read_only=True) + purchase_price_currency = serializers.ChoiceField( + choices=djmoney.settings.CURRENCY_CHOICES, + help_text=_('Purchase price currency'), + ) + class Meta: model = PurchaseOrderLineItem diff --git a/InvenTree/order/templates/order/po_lineitem_delete.html b/InvenTree/order/templates/order/po_lineitem_delete.html deleted file mode 100644 index 1d9f80d137..0000000000 --- a/InvenTree/order/templates/order/po_lineitem_delete.html +++ /dev/null @@ -1,6 +0,0 @@ -{% extends "modal_delete_form.html" %} -{% load i18n %} - -{% block pre_form_content %} -{% trans "Are you sure you wish to delete this line item?" %} -{% endblock %} \ No newline at end of file diff --git a/InvenTree/order/templates/order/purchase_order_detail.html b/InvenTree/order/templates/order/purchase_order_detail.html index e5542f5816..ba468301cc 100644 --- a/InvenTree/order/templates/order/purchase_order_detail.html +++ b/InvenTree/order/templates/order/purchase_order_detail.html @@ -73,16 +73,28 @@ function setupCallbacks() { table.find(".button-line-edit").click(function() { var pk = $(this).attr('pk'); - launchModalForm(`/order/purchase-order/line/${pk}/edit/`, { - success: reloadTable, + constructForm(`/api/order/po-line/${pk}/`, { + fields: { + part: {}, + quantity: {}, + reference: {}, + purchase_price: {}, + purchase_price_currency: {}, + destination: {}, + notes: {}, + }, + title: '{% trans "Edit Line Item" %}', + onSuccess: reloadTable, }); }); table.find(".button-line-delete").click(function() { var pk = $(this).attr('pk'); - launchModalForm(`/order/purchase-order/line/${pk}/delete/`, { - success: reloadTable, + constructForm(`/api/order/po-line/${pk}/`, { + method: 'DELETE', + title: '{% trans "Delete Line Item" %}', + onSuccess: reloadTable, }); }); {% endif %} diff --git a/InvenTree/order/urls.py b/InvenTree/order/urls.py index 7d474c7db2..fd1b3f89dc 100644 --- a/InvenTree/order/urls.py +++ b/InvenTree/order/urls.py @@ -36,10 +36,6 @@ purchase_order_urls = [ url(r'^line/', include([ url(r'^new/', views.POLineItemCreate.as_view(), name='po-line-item-create'), - url(r'^(?P\d+)/', include([ - url(r'^edit/', views.POLineItemEdit.as_view(), name='po-line-item-edit'), - url(r'^delete/', views.POLineItemDelete.as_view(), name='po-line-item-delete'), - ])), ])), # Display complete list of purchase orders diff --git a/InvenTree/order/views.py b/InvenTree/order/views.py index 6914b4fe19..9e4cd2f1dd 100644 --- a/InvenTree/order/views.py +++ b/InvenTree/order/views.py @@ -1213,38 +1213,6 @@ class SOLineItemEdit(AjaxUpdateView): return form -class POLineItemEdit(AjaxUpdateView): - """ View for editing a PurchaseOrderLineItem object in a modal form. - """ - - model = PurchaseOrderLineItem - form_class = order_forms.EditPurchaseOrderLineItemForm - ajax_template_name = 'modal_form.html' - ajax_form_title = _('Edit Line Item') - - def get_form(self): - form = super().get_form() - - # Prevent user from editing order once line item is assigned - form.fields['order'].widget = HiddenInput() - - return form - - -class POLineItemDelete(AjaxDeleteView): - """ View for deleting a PurchaseOrderLineItem object in a modal form - """ - - model = PurchaseOrderLineItem - ajax_form_title = _('Delete Line Item') - ajax_template_name = 'order/po_lineitem_delete.html' - - def get_data(self): - return { - 'danger': _('Deleted line item'), - } - - class SOLineItemDelete(AjaxDeleteView): model = SalesOrderLineItem diff --git a/InvenTree/templates/js/forms.js b/InvenTree/templates/js/forms.js index 5ac5dc2a38..ac3bcefd04 100644 --- a/InvenTree/templates/js/forms.js +++ b/InvenTree/templates/js/forms.js @@ -1267,7 +1267,7 @@ function constructField(name, parameters, options) { var extra = parameters.prefix != null; // Some fields can have 'clear' inputs associated with them - if (!parameters.required) { + if (!parameters.required && !parameters.read_only) { switch (parameters.type) { case 'string': case 'url':