mirror of
https://github.com/inventree/InvenTree
synced 2024-08-30 18:33:04 +00:00
Add pop-up pricing window for part
- Cost to purchase from suppliers - Cost to build from BOM
This commit is contained in:
parent
54ccf6c7b3
commit
dcf79338c1
@ -138,3 +138,19 @@ class EditBomItemForm(HelperForm):
|
|||||||
|
|
||||||
# Prevent editing of the part associated with this BomItem
|
# Prevent editing of the part associated with this BomItem
|
||||||
widgets = {'part': forms.HiddenInput()}
|
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'
|
||||||
|
]
|
||||||
|
@ -32,10 +32,13 @@
|
|||||||
<p><i>{{ part.description }}</i></p>
|
<p><i>{{ part.description }}</i></p>
|
||||||
<p>
|
<p>
|
||||||
<div class='btn-group'>
|
<div class='btn-group'>
|
||||||
{% include "qr_button.html" %}
|
|
||||||
<button type='button' class='btn btn-default btn-glyph' id='toggle-starred' title='Star this part'>
|
<button type='button' class='btn btn-default btn-glyph' id='toggle-starred' title='Star this part'>
|
||||||
<span id='part-star-icon' class='starred-part glyphicon {% if starred %}glyphicon-star{% else %}glyphicon-star-empty{% endif %}'/>
|
<span id='part-star-icon' class='starred-part glyphicon {% if starred %}glyphicon-star{% else %}glyphicon-star-empty{% endif %}'/>
|
||||||
</button>
|
</button>
|
||||||
|
{% include "qr_button.html" %}
|
||||||
|
<button type='button' class='btn btn-default btn-glyph' id='price-button' title='Show pricing information'>
|
||||||
|
<span id='part-price-icon' class='part-price glyphicon glyphicon-usd'/>
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</p>
|
</p>
|
||||||
<table class='table table-condensed'>
|
<table class='table table-condensed'>
|
||||||
@ -141,6 +144,15 @@
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
$("#price-button").click(function() {
|
||||||
|
launchModalForm(
|
||||||
|
"{% url 'part-pricing' part.id %}",
|
||||||
|
{
|
||||||
|
submit_text: 'Calculate',
|
||||||
|
}
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
$("#toggle-starred").click(function() {
|
$("#toggle-starred").click(function() {
|
||||||
toggleStar({
|
toggleStar({
|
||||||
part: {{ part.id }},
|
part: {{ part.id }},
|
||||||
|
41
InvenTree/part/templates/part/part_pricing.html
Normal file
41
InvenTree/part/templates/part/part_pricing.html
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
{% extends "modal_form.html" %}
|
||||||
|
|
||||||
|
{% block pre_form_content %}
|
||||||
|
|
||||||
|
<div class='alert alert-info alert-block'>
|
||||||
|
Calculate pricing information for {{ part }}.
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<table class='table table-striped table-condensed'>
|
||||||
|
<tr>
|
||||||
|
<td><b>Part</b></td>
|
||||||
|
<td>{{ part }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><b>Quantity</b></td>
|
||||||
|
<td>{{ quantity }}</td>
|
||||||
|
</tr>
|
||||||
|
{% if buy_price %}
|
||||||
|
<tr>
|
||||||
|
<td><b>Buy Cost</b></td>
|
||||||
|
<td>{{ buy_price }}</td>
|
||||||
|
</tr>
|
||||||
|
{% endif %}
|
||||||
|
{% if bom_price %}
|
||||||
|
<tr>
|
||||||
|
<td><b>BOM Cost</b></td>
|
||||||
|
<td>{{ bom_price }}</td>
|
||||||
|
</tr>
|
||||||
|
{% if part.has_complete_bom_pricing == false %}
|
||||||
|
<tr>
|
||||||
|
<td colspan='2'>
|
||||||
|
<span class='warning-msg'><i>BOM pricing is incomplete</i></span>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<hr>
|
||||||
|
|
||||||
|
{% endblock %}
|
@ -24,6 +24,7 @@ part_detail_urls = [
|
|||||||
url(r'^bom-export/?', views.BomDownload.as_view(), name='bom-export'),
|
url(r'^bom-export/?', views.BomDownload.as_view(), name='bom-export'),
|
||||||
url(r'^validate-bom/', views.BomValidate.as_view(), name='bom-validate'),
|
url(r'^validate-bom/', views.BomValidate.as_view(), name='bom-validate'),
|
||||||
url(r'^duplicate/', views.PartDuplicate.as_view(), name='part-duplicate'),
|
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'^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'),
|
url(r'^attachments/?', views.PartDetail.as_view(template_name='part/attachments.html'), name='part-attachments'),
|
||||||
|
@ -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):
|
class CategoryDetail(DetailView):
|
||||||
""" Detail view for PartCategory """
|
""" Detail view for PartCategory """
|
||||||
model = PartCategory
|
model = PartCategory
|
||||||
|
@ -11,7 +11,11 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.starred-part {
|
.starred-part {
|
||||||
color: #ffcc00;
|
color: #ffbb00;
|
||||||
|
}
|
||||||
|
|
||||||
|
.part-price {
|
||||||
|
color: rgb(13, 245, 25);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* CSS overrides for treeview */
|
/* CSS overrides for treeview */
|
||||||
|
Loading…
Reference in New Issue
Block a user