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 }}.
+
+
+
+
+ Part |
+ {{ part }} |
+
+
+ Quantity |
+ {{ quantity }} |
+
+{% if buy_price %}
+
+ Buy Cost |
+ {{ buy_price }} |
+
+{% endif %}
+{% if bom_price %}
+
+ BOM Cost |
+ {{ bom_price }} |
+
+ {% if part.has_complete_bom_pricing == false %}
+
+
+ BOM pricing is incomplete
+ |
+
+ {% endif %}
+{% endif %}
+
+
+
+
+{% 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 */