From dcf79338c1e7df4bf54a69ec5727fe17f36c1bed Mon Sep 17 00:00:00 2001 From: Oliver Walters Date: Sat, 18 May 2019 22:58:11 +1000 Subject: [PATCH] Add pop-up pricing window for part - Cost to purchase from suppliers - Cost to build from BOM --- InvenTree/part/forms.py | 16 ++++++ InvenTree/part/templates/part/part_base.html | 14 ++++- .../part/templates/part/part_pricing.html | 41 ++++++++++++++ InvenTree/part/urls.py | 1 + InvenTree/part/views.py | 56 +++++++++++++++++++ InvenTree/static/css/inventree.css | 6 +- 6 files changed, 132 insertions(+), 2 deletions(-) create mode 100644 InvenTree/part/templates/part/part_pricing.html diff --git a/InvenTree/part/forms.py b/InvenTree/part/forms.py index 7f8854489c..e069df6ed6 100644 --- a/InvenTree/part/forms.py +++ b/InvenTree/part/forms.py @@ -138,3 +138,19 @@ class EditBomItemForm(HelperForm): # Prevent editing of the part associated with this BomItem widgets = {'part': forms.HiddenInput()} + + +class PartPriceForm(forms.Form): + """ Simple form for viewing part pricing information """ + + quantity = forms.IntegerField( + required=True, + initial=1, + help_text='Input quantity for price calculation' + ) + + class Meta: + model = Part + fields = [ + 'quantity' + ] diff --git a/InvenTree/part/templates/part/part_base.html b/InvenTree/part/templates/part/part_base.html index 405556bdfa..5e4f85d238 100644 --- a/InvenTree/part/templates/part/part_base.html +++ b/InvenTree/part/templates/part/part_base.html @@ -32,10 +32,13 @@

{{ part.description }}

- {% include "qr_button.html" %} + {% include "qr_button.html" %} +

@@ -141,6 +144,15 @@ ); }); + $("#price-button").click(function() { + launchModalForm( + "{% url 'part-pricing' part.id %}", + { + submit_text: 'Calculate', + } + ); + }); + $("#toggle-starred").click(function() { toggleStar({ part: {{ part.id }}, diff --git a/InvenTree/part/templates/part/part_pricing.html b/InvenTree/part/templates/part/part_pricing.html new file mode 100644 index 0000000000..2930d56ed0 --- /dev/null +++ b/InvenTree/part/templates/part/part_pricing.html @@ -0,0 +1,41 @@ +{% extends "modal_form.html" %} + +{% block pre_form_content %} + +
+Calculate pricing information for {{ part }}. +
+ +
+ + + + + + + + +{% if buy_price %} + + + + +{% endif %} +{% if bom_price %} + + + + + {% if part.has_complete_bom_pricing == false %} + + + + {% endif %} +{% endif %} +
Part{{ part }}
Quantity{{ quantity }}
Buy Cost{{ buy_price }}
BOM Cost{{ bom_price }}
+ BOM pricing is incomplete +
+ +
+ +{% endblock %} \ No newline at end of file diff --git a/InvenTree/part/urls.py b/InvenTree/part/urls.py index 89453c63f9..900ebe8127 100644 --- a/InvenTree/part/urls.py +++ b/InvenTree/part/urls.py @@ -24,6 +24,7 @@ part_detail_urls = [ url(r'^bom-export/?', views.BomDownload.as_view(), name='bom-export'), url(r'^validate-bom/', views.BomValidate.as_view(), name='bom-validate'), url(r'^duplicate/', views.PartDuplicate.as_view(), name='part-duplicate'), + url(r'^pricing/', views.PartPricing.as_view(), name='part-pricing'), url(r'^track/?', views.PartDetail.as_view(template_name='part/track.html'), name='part-track'), url(r'^attachments/?', views.PartDetail.as_view(template_name='part/attachments.html'), name='part-attachments'), diff --git a/InvenTree/part/views.py b/InvenTree/part/views.py index 1cdb4acf2d..7a7a85ae2d 100644 --- a/InvenTree/part/views.py +++ b/InvenTree/part/views.py @@ -551,6 +551,62 @@ class PartDelete(AjaxDeleteView): } +class PartPricing(AjaxView): + """ View for inspecting part pricing information """ + + model = Part + ajax_template_name = "part/part_pricing.html" + ajax_form_title = "Part Pricing" + form_class = part_forms.PartPriceForm + + def get_part(self): + try: + return Part.objects.get(id=self.kwargs['pk']) + except Part.DoesNotExist: + return None + + def get_pricing(self, quantity=1): + + part = self.get_part() + + ctx = { + 'part': part, + 'quantity': quantity + } + + if part is None: + return ctx + + buy_price = part.get_price_info(quantity, bom=False) + bom_price = part.get_price_info(quantity, buy=False) + + if buy_price: + ctx['buy_price'] = buy_price + + if bom_price: + ctx['bom_price'] = bom_price + + return ctx + + def get(self, request, *args, **kwargs): + + return self.renderJsonResponse(request, self.form_class(), context=self.get_pricing()) + + def post(self, request, *args, **kwargs): + + try: + quantity = int(self.request.POST.get('quantity', 1)) + except ValueError: + quantity = 1 + + # Always mark the form as 'invalid' (the user may wish to keep getting pricing data) + data = { + 'form_valid': False, + } + + return self.renderJsonResponse(request, self.form_class(), data=data, context=self.get_pricing(quantity)) + + class CategoryDetail(DetailView): """ Detail view for PartCategory """ model = PartCategory diff --git a/InvenTree/static/css/inventree.css b/InvenTree/static/css/inventree.css index 4ef4f8789c..ff7ac4e98b 100644 --- a/InvenTree/static/css/inventree.css +++ b/InvenTree/static/css/inventree.css @@ -11,7 +11,11 @@ } .starred-part { - color: #ffcc00; + color: #ffbb00; +} + +.part-price { + color: rgb(13, 245, 25); } /* CSS overrides for treeview */