Merge remote-tracking branch 'inventree/master'

This commit is contained in:
Oliver Walters 2019-05-23 00:48:05 +10:00
commit bebf2c9bee
9 changed files with 78 additions and 25 deletions

View File

@ -81,7 +81,8 @@ class SupplierPartList(generics.ListCreateAPIView):
'part__stock_items', 'part__stock_items',
'part__bom_items', 'part__bom_items',
'part__builds', 'part__builds',
'supplier') 'supplier',
'pricebreaks')
serializer_class = SupplierPartSerializer serializer_class = SupplierPartSerializer
@ -151,7 +152,7 @@ supplier_part_api_urls = [
company_api_urls = [ company_api_urls = [
url(r'^part/', include(supplier_part_api_urls)), url(r'^part/?', include(supplier_part_api_urls)),
url(r'^price-break/?', SupplierPriceBreakList.as_view(), name='api-part-supplier-price'), url(r'^price-break/?', SupplierPriceBreakList.as_view(), name='api-part-supplier-price'),

View File

@ -239,6 +239,10 @@ class SupplierPart(models.Model):
""" Return the associated price breaks in the correct order """ """ Return the associated price breaks in the correct order """
return self.pricebreaks.order_by('quantity').all() return self.pricebreaks.order_by('quantity').all()
@property
def unit_pricing(self):
return self.get_price(1)
def get_price(self, quantity, moq=True, multiples=True): def get_price(self, quantity, moq=True, multiples=True):
""" Calculate the supplier price based on quantity price breaks. """ Calculate the supplier price based on quantity price breaks.

View File

@ -33,7 +33,7 @@ class CompanySerializer(serializers.ModelSerializer):
class Meta: class Meta:
model = Company model = Company
fields = [ fields = [
'id', 'pk',
'url', 'url',
'name', 'name',
'description', 'description',
@ -62,6 +62,8 @@ class SupplierPartSerializer(serializers.ModelSerializer):
supplier_name = serializers.CharField(source='supplier.name', read_only=True) supplier_name = serializers.CharField(source='supplier.name', read_only=True)
supplier_logo = serializers.CharField(source='supplier.get_image_url', read_only=True) supplier_logo = serializers.CharField(source='supplier.get_image_url', read_only=True)
pricing = serializers.CharField(source='unit_pricing', read_only=True)
class Meta: class Meta:
model = SupplierPart model = SupplierPart
fields = [ fields = [
@ -76,6 +78,7 @@ class SupplierPartSerializer(serializers.ModelSerializer):
'manufacturer', 'manufacturer',
'MPN', 'MPN',
'URL', 'URL',
'pricing',
] ]

View File

@ -33,33 +33,39 @@
<div class='col-sm-6'> <div class='col-sm-6'>
<table class='table table-striped'> <table class='table table-striped'>
<tr> <tr>
<td>Part name</td> <td><b>Part name</b></td>
<td>{{ part.full_name }}</td> <td>{{ part.full_name }}</td>
</tr> </tr>
{% if part.IPN %} {% if part.IPN %}
<tr> <tr>
<td>IPN</td> <td><b>IPN</b></td>
<td>{{ part.IPN }}</td> <td>{{ part.IPN }}</td>
</tr> </tr>
{% endif %} {% endif %}
{% if part.variant %}
<tr> <tr>
<td>Description</td> <td><b>Variant</b></td>
<td>{{ part.variant }}</td>
</tr>
{% endif %}
<tr>
<td><b>Description</b></td>
<td>{{ part.description }}</td> <td>{{ part.description }}</td>
</tr> </tr>
{% if part.keywords %} {% if part.keywords %}
<tr> <tr>
<td>Keywords</td> <td><b>Keywords</b></td>
<td>{{ part.keywords }}</td> <td>{{ part.keywords }}</td>
</tr> </tr>
{% endif %} {% endif %}
{% if part.URL %} {% if part.URL %}
<tr> <tr>
<td>URL</td> <td><b>URL</b></td>
<td><a href="{{ part.URL }}">{{ part.URL }}</a></td> <td><a href="{{ part.URL }}">{{ part.URL }}</a></td>
</tr> </tr>
{% endif %} {% endif %}
<tr> <tr>
<td>Category</td> <td><b>Category</b></td>
<td> <td>
{% if part.category %} {% if part.category %}
<a href="{% url 'category-detail' part.category.id %}">{{ part.category.pathstring }}</a> <a href="{% url 'category-detail' part.category.id %}">{{ part.category.pathstring }}</a>
@ -68,20 +74,20 @@
</tr> </tr>
{% if part.default_location %} {% if part.default_location %}
<tr> <tr>
<td>Default Location</td> <td><b>Default Location</b></td>
<td><a href="{% url 'stock-location-detail' part.default_location.id %}">{{ part.default_location.pathstring }}</a></td> <td><a href="{% url 'stock-location-detail' part.default_location.id %}">{{ part.default_location.pathstring }}</a></td>
</tr> </tr>
{% endif %} {% endif %}
{% if part.default_supplier %} {% if part.default_supplier %}
<tr> <tr>
<td>Default Supplier</td> <td><b>Default Supplier</b></td>
<td><a href="{% url 'supplier-part-detail' part.default_supplier.id %}"> <td><a href="{% url 'supplier-part-detail' part.default_supplier.id %}">
{{ part.default_supplier.supplier.name }} | {{ part.default_supplier.SKU }} {{ part.default_supplier.supplier.name }} | {{ part.default_supplier.SKU }}
</a></td> </a></td>
</tr> </tr>
{% endif %} {% endif %}
<tr> <tr>
<td>Units</td> <td><b>Units</b></td>
<td>{{ part.units }}</td> <td>{{ part.units }}</td>
</tr> </tr>
</table> </table>
@ -89,28 +95,28 @@
<div class='col-sm-6'> <div class='col-sm-6'>
<table class='table table-striped'> <table class='table table-striped'>
<tr> <tr>
<td>Buildable</td> <td><b>Buildable</b></td>
<td>{% include "yesnolabel.html" with value=part.buildable %}</td> <td>{% include "yesnolabel.html" with value=part.buildable %}</td>
</tr> </tr>
<tr> <tr>
<td>Consumable</td> <td><b>Consumable</b></td>
<td>{% include "yesnolabel.html" with value=part.consumable %}</td> <td>{% include "yesnolabel.html" with value=part.consumable %}</td>
</tr> </tr>
<tr> <tr>
<td>Trackable</td> <td><b>Trackable</b></td>
<td>{% include "yesnolabel.html" with value=part.trackable %}</td> <td>{% include "yesnolabel.html" with value=part.trackable %}</td>
</tr> </tr>
<tr> <tr>
<td>Purchaseable</td> <td><b>Purchaseable</b></td>
<td>{% include "yesnolabel.html" with value=part.purchaseable %}</td> <td>{% include "yesnolabel.html" with value=part.purchaseable %}</td>
</tr> </tr>
<tr> <tr>
<td>Salable</td> <td><b>Salable</b></td>
<td>{% include "yesnolabel.html" with value=part.salable %}</td> <td>{% include "yesnolabel.html" with value=part.salable %}</td>
</tr> </tr>
{% if part.minimum_stock > 0 %} {% if part.minimum_stock > 0 %}
<tr> <tr>
<td>Minimum Stock</td> <td><b>Minimum Stock</b></td>
<td>{{ part.minimum_stock }}</td> <td>{{ part.minimum_stock }}</td>
</tr> </tr>
{% endif %} {% endif %}

View File

@ -3,7 +3,8 @@
{% block pre_form_content %} {% block pre_form_content %}
<div class='alert alert-info alert-block'> <div class='alert alert-info alert-block'>
Calculate pricing information for {{ part }}. Pricing information for:<br>
{{ part }}.
</div> </div>
<h4>Quantity</h4> <h4>Quantity</h4>

View File

@ -57,6 +57,15 @@
title: 'Create New Part', title: 'Create New Part',
url: "{% url 'part-create' %}", url: "{% url 'part-create' %}",
}, },
{
field: 'supplier_part',
label: 'New Supplier Part',
title: 'Create new Supplier Part',
url: "{% url 'supplier-part-create' %}",
data: {
part: {{ part.id }}
},
},
{ {
field: 'location', field: 'location',
label: 'New Location', label: 'New Location',

View File

@ -38,11 +38,21 @@
$('#supplier-create').click(function () { $('#supplier-create').click(function () {
launchModalForm( launchModalForm(
"{% url 'supplier-part-create' %}", "{% url 'supplier-part-create' %}",
{ {
reload: true, reload: true,
data: {part: {{ part.id }} } data: {
}); part: {{ part.id }}
},
secondary: [
{
field: 'supplier',
label: 'New Supplier',
title: 'Create new supplier',
url: "{% url 'company-create' %}"
}
]
});
}); });
$("#supplier-table").bootstrapTable({ $("#supplier-table").bootstrapTable({
@ -83,6 +93,18 @@
sortable: true, sortable: true,
field: 'MPN', field: 'MPN',
title: 'MPN', title: 'MPN',
},
{
sortable: true,
field: 'pricing',
title: 'Price',
formatter: function(value, row, index, field) {
if (value) {
return value;
} else {
return "<span class='warning-msg'><i>No pricing available</i></span>";
}
},
} }
], ],
url: "{% url 'api-part-supplier-list' %}" url: "{% url 'api-part-supplier-list' %}"

View File

@ -226,6 +226,10 @@
padding-bottom: 3px; padding-bottom: 3px;
} }
.modal .btn-secondary {
background-color: #5e7d87;
}
/* The side navigation menu */ /* The side navigation menu */
.sidenav { .sidenav {
height: 100%; /* 100% Full-height */ height: 100%; /* 100% Full-height */

View File

@ -362,7 +362,7 @@ function insertNewItemButton(modal, options) {
var html = "<span style='float: right;'>"; var html = "<span style='float: right;'>";
html += "<div type='button' class='btn btn-primary'"; html += "<div type='button' class='btn btn-primary btn-secondary'";
if (options.title) { if (options.title) {
html += " title='" + options.title + "'"; html += " title='" + options.title + "'";
@ -392,6 +392,8 @@ function attachSecondaryModal(modal, options) {
// Insert the button // Insert the button
insertNewItemButton(modal, options); insertNewItemButton(modal, options);
var data = options.data || {};
// Add a callback to the button // Add a callback to the button
$(modal).find("#btn-new-" + options.field).on('click', function() { $(modal).find("#btn-new-" + options.field).on('click', function() {
@ -400,6 +402,7 @@ function attachSecondaryModal(modal, options) {
options.url, options.url,
{ {
modal: '#modal-form-secondary', modal: '#modal-form-secondary',
data: data,
success: function(response) { success: function(response) {
/* A successful object creation event should return a response which contains: /* A successful object creation event should return a response which contains: