diff --git a/InvenTree/InvenTree/static/script/inventree/bom.js b/InvenTree/InvenTree/static/script/inventree/bom.js
index e62c8c22f4..8d0accb83b 100644
--- a/InvenTree/InvenTree/static/script/inventree/bom.js
+++ b/InvenTree/InvenTree/static/script/inventree/bom.js
@@ -282,7 +282,6 @@ function loadBomTable(table, options) {
},
formatNoMatches: function() { return "No BOM items found"; },
clickToSelect: true,
- showFooter: true,
queryParams: function(p) {
return params;
},
diff --git a/InvenTree/InvenTree/static/script/inventree/order.js b/InvenTree/InvenTree/static/script/inventree/order.js
index 818596f7c9..d811cc5ea1 100644
--- a/InvenTree/InvenTree/static/script/inventree/order.js
+++ b/InvenTree/InvenTree/static/script/inventree/order.js
@@ -98,4 +98,96 @@ function removePurchaseOrderLineItem(e) {
launchModalForm(url, {
reload: true,
});
+}
+
+
+function loadPurchaseOrderTable(table, options) {
+ /* Create a purchase-order table */
+
+ table.inventreeTable({
+ url: options.url,
+ formatNoMatches: function() { return "No purchase orders found"; },
+ columns: [
+ {
+ field: 'pk',
+ title: 'ID',
+ visible: false,
+ },
+ {
+ sortable: true,
+ field: 'supplier',
+ title: 'Supplier',
+ formatter: function(value, row, index, field) {
+ return imageHoverIcon(row.supplier__image) + renderLink(row.supplier__name, '/company/' + value + '/purchase-orders/');
+ }
+ },
+ {
+ sortable: true,
+ field: 'reference',
+ title: 'Reference',
+ formatter: function(value, row, index, field) {
+ return renderLink(value, "/order/purchase-order/" + row.pk + "/");
+ }
+ },
+ {
+ sortable: true,
+ field: 'creation_date',
+ title: 'Date',
+ },
+ {
+ sortable: true,
+ field: 'description',
+ title: 'Description',
+ },
+ {
+ sortable: true,
+ field: 'status',
+ title: 'Status',
+ formatter: function(value, row, index, field) {
+ return orderStatusLabel(row.status, row.status_text);
+ }
+ },
+ {
+ sortable: true,
+ field: 'lines',
+ title: 'Items'
+ },
+ ],
+ });
+}
+
+
+function orderStatusLabel(code, label) {
+ /* Render a purchase-order status label. */
+
+ var html = "";
+ html += label;
+ html += "";
+
+ console.log(html);
+
+ return html;
}
\ No newline at end of file
diff --git a/InvenTree/InvenTree/status_codes.py b/InvenTree/InvenTree/status_codes.py
index f772943ef0..e49f9a9824 100644
--- a/InvenTree/InvenTree/status_codes.py
+++ b/InvenTree/InvenTree/status_codes.py
@@ -12,6 +12,15 @@ class StatusCode:
""" Return the status code label associated with the provided value """
return cls.options.get(value, value)
+ @classmethod
+ def value(cls, label):
+ """ Return the value associated with the provided label """
+ for k in cls.options.keys():
+ if cls.options[k].lower() == label.lower():
+ return k
+
+ raise ValueError("Label not found")
+
class OrderStatus(StatusCode):
diff --git a/InvenTree/company/api.py b/InvenTree/company/api.py
index e1b02a76fa..8b777dd947 100644
--- a/InvenTree/company/api.py
+++ b/InvenTree/company/api.py
@@ -31,6 +31,7 @@ class CompanyList(generics.ListCreateAPIView):
serializer_class = CompanySerializer
queryset = Company.objects.all()
+
permission_classes = [
permissions.IsAuthenticated,
]
diff --git a/InvenTree/company/models.py b/InvenTree/company/models.py
index 2df314fb27..c072abab1c 100644
--- a/InvenTree/company/models.py
+++ b/InvenTree/company/models.py
@@ -17,7 +17,6 @@ from django.db.models import Sum
from django.apps import apps
from django.urls import reverse
from django.conf import settings
-from django.conf.urls.static import static
from InvenTree.fields import InvenTreeURLField
from InvenTree.status_codes import OrderStatus
@@ -110,7 +109,7 @@ class Company(models.Model):
if self.image:
return os.path.join(settings.MEDIA_URL, str(self.image.url))
else:
- return static('/img/blank_image.png')
+ return os.path.join(settings.STATIC_URL, 'img/blank_image.png')
@property
def part_count(self):
diff --git a/InvenTree/company/templates/company/detail_purchase_orders.html b/InvenTree/company/templates/company/detail_purchase_orders.html
index 8c299cbd4e..b2eabc129d 100644
--- a/InvenTree/company/templates/company/detail_purchase_orders.html
+++ b/InvenTree/company/templates/company/detail_purchase_orders.html
@@ -13,17 +13,19 @@
-{% include "order/po_table.html" with orders=company.outstanding_purchase_orders.all toolbar='#button-bar' %}
-
-{% if company.closed_purchase_orders.count > 0 %}
-{% include "order/po_table_collapse.html" with title="Closed Orders" orders=company.closed_purchase_orders.all %}
-{% endif %}
+
{% endblock %}
{% block js_ready %}
{{ block.super }}
+ loadPurchaseOrderTable($("#purchase-order-table"), {
+ url: "{% url 'api-po-list' %}?supplier={{ company.id }}",
+ });
+
+
function newOrder() {
launchModalForm("{% url 'purchase-order-create' %}",
{
diff --git a/InvenTree/locale/de/LC_MESSAGES/django.po b/InvenTree/locale/de/LC_MESSAGES/django.po
index 0128f4edb9..7ed7357117 100644
--- a/InvenTree/locale/de/LC_MESSAGES/django.po
+++ b/InvenTree/locale/de/LC_MESSAGES/django.po
@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2019-12-04 23:28+0000\n"
+"POT-Creation-Date: 2019-12-09 11:16+0000\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME \n"
"Language-Team: LANGUAGE \n"
@@ -62,47 +62,47 @@ msgstr ""
msgid "Polish"
msgstr ""
-#: InvenTree/status_codes.py:27 InvenTree/status_codes.py:82
+#: InvenTree/status_codes.py:36 InvenTree/status_codes.py:91
msgid "Pending"
msgstr ""
-#: InvenTree/status_codes.py:28
+#: InvenTree/status_codes.py:37
msgid "Placed"
msgstr ""
-#: InvenTree/status_codes.py:29 InvenTree/status_codes.py:85
+#: InvenTree/status_codes.py:38 InvenTree/status_codes.py:94
msgid "Complete"
msgstr ""
-#: InvenTree/status_codes.py:30 InvenTree/status_codes.py:84
+#: InvenTree/status_codes.py:39 InvenTree/status_codes.py:93
msgid "Cancelled"
msgstr ""
-#: InvenTree/status_codes.py:31 InvenTree/status_codes.py:62
+#: InvenTree/status_codes.py:40 InvenTree/status_codes.py:71
msgid "Lost"
msgstr ""
-#: InvenTree/status_codes.py:32
+#: InvenTree/status_codes.py:41
msgid "Returned"
msgstr ""
-#: InvenTree/status_codes.py:58
+#: InvenTree/status_codes.py:67
msgid "OK"
msgstr ""
-#: InvenTree/status_codes.py:59
+#: InvenTree/status_codes.py:68
msgid "Attention needed"
msgstr ""
-#: InvenTree/status_codes.py:60
+#: InvenTree/status_codes.py:69
msgid "Damaged"
msgstr ""
-#: InvenTree/status_codes.py:61
+#: InvenTree/status_codes.py:70
msgid "Destroyed"
msgstr ""
-#: InvenTree/status_codes.py:83 build/templates/build/allocate_edit.html:28
+#: InvenTree/status_codes.py:92 build/templates/build/allocate_edit.html:28
#: build/templates/build/allocate_view.html:21
#: part/templates/part/part_base.html:116 part/templates/part/tabs.html:21
msgid "Allocated"
@@ -481,175 +481,175 @@ msgstr ""
msgid "Select currency for price calculation"
msgstr ""
-#: part/models.py:56
+#: part/models.py:55
msgid "Default location for parts in this category"
msgstr ""
-#: part/models.py:59
+#: part/models.py:58
msgid "Default keywords for parts in this category"
msgstr ""
-#: part/models.py:308
+#: part/models.py:307
msgid "Part must be unique for name, IPN and revision"
msgstr ""
-#: part/models.py:322
+#: part/models.py:321
msgid "Part cannot be a template part if it is a variant of another part"
msgstr ""
-#: part/models.py:323
+#: part/models.py:322
msgid "Part cannot be a variant of another part if it is already a template"
msgstr ""
-#: part/models.py:327 part/templates/part/detail.html:17
+#: part/models.py:326 part/templates/part/detail.html:17
msgid "Part name"
msgstr ""
-#: part/models.py:331
+#: part/models.py:330
msgid "Is this part a template part?"
msgstr ""
-#: part/models.py:340
+#: part/models.py:339
msgid "Is this part a variant of another part?"
msgstr ""
-#: part/models.py:342
+#: part/models.py:341
msgid "Part description"
msgstr ""
-#: part/models.py:344
+#: part/models.py:343
msgid "Part keywords to improve visibility in search results"
msgstr ""
-#: part/models.py:349
+#: part/models.py:348
msgid "Part category"
msgstr ""
-#: part/models.py:351
+#: part/models.py:350
msgid "Internal Part Number"
msgstr ""
-#: part/models.py:353
+#: part/models.py:352
msgid "Part revision or version number"
msgstr ""
-#: part/models.py:355
+#: part/models.py:354
msgid "Link to extenal URL"
msgstr ""
-#: part/models.py:361
+#: part/models.py:360
msgid "Where is this item normally stored?"
msgstr ""
-#: part/models.py:405
+#: part/models.py:404
msgid "Default supplier part"
msgstr ""
-#: part/models.py:408
+#: part/models.py:407
msgid "Minimum allowed stock level"
msgstr ""
-#: part/models.py:410
+#: part/models.py:409
msgid "Stock keeping units for this part"
msgstr ""
-#: part/models.py:412
+#: part/models.py:411
msgid "Can this part be built from other parts?"
msgstr ""
-#: part/models.py:414
+#: part/models.py:413
msgid "Can this part be used to build other parts?"
msgstr ""
-#: part/models.py:416
+#: part/models.py:415
msgid "Does this part have tracking for unique items?"
msgstr ""
-#: part/models.py:418
+#: part/models.py:417
msgid "Can this part be purchased from external suppliers?"
msgstr ""
-#: part/models.py:420
+#: part/models.py:419
msgid "Can this part be sold to customers?"
msgstr ""
-#: part/models.py:422
+#: part/models.py:421
msgid "Is this part active?"
msgstr ""
-#: part/models.py:424
+#: part/models.py:423
msgid "Is this a virtual part, such as a software product or license?"
msgstr ""
-#: part/models.py:428
+#: part/models.py:427
msgid "Stored BOM checksum"
msgstr ""
-#: part/models.py:935
+#: part/models.py:934
msgid "Select file to attach"
msgstr ""
-#: part/models.py:937
+#: part/models.py:936
msgid "File comment"
msgstr ""
-#: part/models.py:992
+#: part/models.py:991
msgid "Parameter template name must be unique"
msgstr ""
-#: part/models.py:997
+#: part/models.py:996
msgid "Parameter Name"
msgstr ""
-#: part/models.py:999
+#: part/models.py:998
msgid "Parameter Units"
msgstr ""
-#: part/models.py:1025
+#: part/models.py:1024
msgid "Parent Part"
msgstr ""
-#: part/models.py:1027
+#: part/models.py:1026
msgid "Parameter Template"
msgstr ""
-#: part/models.py:1029
+#: part/models.py:1028
msgid "Parameter Value"
msgstr ""
-#: part/models.py:1053
+#: part/models.py:1052
msgid "Select parent part"
msgstr ""
-#: part/models.py:1061
+#: part/models.py:1060
msgid "Select part to be used in BOM"
msgstr ""
-#: part/models.py:1067
+#: part/models.py:1066
msgid "BOM quantity for this BOM item"
msgstr ""
-#: part/models.py:1070
+#: part/models.py:1069
msgid "Estimated build wastage quantity (absolute or percentage)"
msgstr ""
-#: part/models.py:1073
+#: part/models.py:1072
msgid "BOM item reference"
msgstr ""
-#: part/models.py:1076
+#: part/models.py:1075
msgid "BOM item notes"
msgstr ""
-#: part/models.py:1078
+#: part/models.py:1077
msgid "BOM line checksum"
msgstr ""
-#: part/models.py:1141
+#: part/models.py:1140
msgid "Part cannot be added to its own Bill of Materials"
msgstr ""
-#: part/models.py:1148
+#: part/models.py:1147
#, python-brace-format
msgid "Part '{p1}' is used in BOM for '{p2}' (recursive)"
msgstr ""
diff --git a/InvenTree/locale/en/LC_MESSAGES/django.po b/InvenTree/locale/en/LC_MESSAGES/django.po
index 0128f4edb9..7ed7357117 100644
--- a/InvenTree/locale/en/LC_MESSAGES/django.po
+++ b/InvenTree/locale/en/LC_MESSAGES/django.po
@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2019-12-04 23:28+0000\n"
+"POT-Creation-Date: 2019-12-09 11:16+0000\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME \n"
"Language-Team: LANGUAGE \n"
@@ -62,47 +62,47 @@ msgstr ""
msgid "Polish"
msgstr ""
-#: InvenTree/status_codes.py:27 InvenTree/status_codes.py:82
+#: InvenTree/status_codes.py:36 InvenTree/status_codes.py:91
msgid "Pending"
msgstr ""
-#: InvenTree/status_codes.py:28
+#: InvenTree/status_codes.py:37
msgid "Placed"
msgstr ""
-#: InvenTree/status_codes.py:29 InvenTree/status_codes.py:85
+#: InvenTree/status_codes.py:38 InvenTree/status_codes.py:94
msgid "Complete"
msgstr ""
-#: InvenTree/status_codes.py:30 InvenTree/status_codes.py:84
+#: InvenTree/status_codes.py:39 InvenTree/status_codes.py:93
msgid "Cancelled"
msgstr ""
-#: InvenTree/status_codes.py:31 InvenTree/status_codes.py:62
+#: InvenTree/status_codes.py:40 InvenTree/status_codes.py:71
msgid "Lost"
msgstr ""
-#: InvenTree/status_codes.py:32
+#: InvenTree/status_codes.py:41
msgid "Returned"
msgstr ""
-#: InvenTree/status_codes.py:58
+#: InvenTree/status_codes.py:67
msgid "OK"
msgstr ""
-#: InvenTree/status_codes.py:59
+#: InvenTree/status_codes.py:68
msgid "Attention needed"
msgstr ""
-#: InvenTree/status_codes.py:60
+#: InvenTree/status_codes.py:69
msgid "Damaged"
msgstr ""
-#: InvenTree/status_codes.py:61
+#: InvenTree/status_codes.py:70
msgid "Destroyed"
msgstr ""
-#: InvenTree/status_codes.py:83 build/templates/build/allocate_edit.html:28
+#: InvenTree/status_codes.py:92 build/templates/build/allocate_edit.html:28
#: build/templates/build/allocate_view.html:21
#: part/templates/part/part_base.html:116 part/templates/part/tabs.html:21
msgid "Allocated"
@@ -481,175 +481,175 @@ msgstr ""
msgid "Select currency for price calculation"
msgstr ""
-#: part/models.py:56
+#: part/models.py:55
msgid "Default location for parts in this category"
msgstr ""
-#: part/models.py:59
+#: part/models.py:58
msgid "Default keywords for parts in this category"
msgstr ""
-#: part/models.py:308
+#: part/models.py:307
msgid "Part must be unique for name, IPN and revision"
msgstr ""
-#: part/models.py:322
+#: part/models.py:321
msgid "Part cannot be a template part if it is a variant of another part"
msgstr ""
-#: part/models.py:323
+#: part/models.py:322
msgid "Part cannot be a variant of another part if it is already a template"
msgstr ""
-#: part/models.py:327 part/templates/part/detail.html:17
+#: part/models.py:326 part/templates/part/detail.html:17
msgid "Part name"
msgstr ""
-#: part/models.py:331
+#: part/models.py:330
msgid "Is this part a template part?"
msgstr ""
-#: part/models.py:340
+#: part/models.py:339
msgid "Is this part a variant of another part?"
msgstr ""
-#: part/models.py:342
+#: part/models.py:341
msgid "Part description"
msgstr ""
-#: part/models.py:344
+#: part/models.py:343
msgid "Part keywords to improve visibility in search results"
msgstr ""
-#: part/models.py:349
+#: part/models.py:348
msgid "Part category"
msgstr ""
-#: part/models.py:351
+#: part/models.py:350
msgid "Internal Part Number"
msgstr ""
-#: part/models.py:353
+#: part/models.py:352
msgid "Part revision or version number"
msgstr ""
-#: part/models.py:355
+#: part/models.py:354
msgid "Link to extenal URL"
msgstr ""
-#: part/models.py:361
+#: part/models.py:360
msgid "Where is this item normally stored?"
msgstr ""
-#: part/models.py:405
+#: part/models.py:404
msgid "Default supplier part"
msgstr ""
-#: part/models.py:408
+#: part/models.py:407
msgid "Minimum allowed stock level"
msgstr ""
-#: part/models.py:410
+#: part/models.py:409
msgid "Stock keeping units for this part"
msgstr ""
-#: part/models.py:412
+#: part/models.py:411
msgid "Can this part be built from other parts?"
msgstr ""
-#: part/models.py:414
+#: part/models.py:413
msgid "Can this part be used to build other parts?"
msgstr ""
-#: part/models.py:416
+#: part/models.py:415
msgid "Does this part have tracking for unique items?"
msgstr ""
-#: part/models.py:418
+#: part/models.py:417
msgid "Can this part be purchased from external suppliers?"
msgstr ""
-#: part/models.py:420
+#: part/models.py:419
msgid "Can this part be sold to customers?"
msgstr ""
-#: part/models.py:422
+#: part/models.py:421
msgid "Is this part active?"
msgstr ""
-#: part/models.py:424
+#: part/models.py:423
msgid "Is this a virtual part, such as a software product or license?"
msgstr ""
-#: part/models.py:428
+#: part/models.py:427
msgid "Stored BOM checksum"
msgstr ""
-#: part/models.py:935
+#: part/models.py:934
msgid "Select file to attach"
msgstr ""
-#: part/models.py:937
+#: part/models.py:936
msgid "File comment"
msgstr ""
-#: part/models.py:992
+#: part/models.py:991
msgid "Parameter template name must be unique"
msgstr ""
-#: part/models.py:997
+#: part/models.py:996
msgid "Parameter Name"
msgstr ""
-#: part/models.py:999
+#: part/models.py:998
msgid "Parameter Units"
msgstr ""
-#: part/models.py:1025
+#: part/models.py:1024
msgid "Parent Part"
msgstr ""
-#: part/models.py:1027
+#: part/models.py:1026
msgid "Parameter Template"
msgstr ""
-#: part/models.py:1029
+#: part/models.py:1028
msgid "Parameter Value"
msgstr ""
-#: part/models.py:1053
+#: part/models.py:1052
msgid "Select parent part"
msgstr ""
-#: part/models.py:1061
+#: part/models.py:1060
msgid "Select part to be used in BOM"
msgstr ""
-#: part/models.py:1067
+#: part/models.py:1066
msgid "BOM quantity for this BOM item"
msgstr ""
-#: part/models.py:1070
+#: part/models.py:1069
msgid "Estimated build wastage quantity (absolute or percentage)"
msgstr ""
-#: part/models.py:1073
+#: part/models.py:1072
msgid "BOM item reference"
msgstr ""
-#: part/models.py:1076
+#: part/models.py:1075
msgid "BOM item notes"
msgstr ""
-#: part/models.py:1078
+#: part/models.py:1077
msgid "BOM line checksum"
msgstr ""
-#: part/models.py:1141
+#: part/models.py:1140
msgid "Part cannot be added to its own Bill of Materials"
msgstr ""
-#: part/models.py:1148
+#: part/models.py:1147
#, python-brace-format
msgid "Part '{p1}' is used in BOM for '{p2}' (recursive)"
msgstr ""
diff --git a/InvenTree/locale/es/LC_MESSAGES/django.po b/InvenTree/locale/es/LC_MESSAGES/django.po
index 0128f4edb9..7ed7357117 100644
--- a/InvenTree/locale/es/LC_MESSAGES/django.po
+++ b/InvenTree/locale/es/LC_MESSAGES/django.po
@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2019-12-04 23:28+0000\n"
+"POT-Creation-Date: 2019-12-09 11:16+0000\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME \n"
"Language-Team: LANGUAGE \n"
@@ -62,47 +62,47 @@ msgstr ""
msgid "Polish"
msgstr ""
-#: InvenTree/status_codes.py:27 InvenTree/status_codes.py:82
+#: InvenTree/status_codes.py:36 InvenTree/status_codes.py:91
msgid "Pending"
msgstr ""
-#: InvenTree/status_codes.py:28
+#: InvenTree/status_codes.py:37
msgid "Placed"
msgstr ""
-#: InvenTree/status_codes.py:29 InvenTree/status_codes.py:85
+#: InvenTree/status_codes.py:38 InvenTree/status_codes.py:94
msgid "Complete"
msgstr ""
-#: InvenTree/status_codes.py:30 InvenTree/status_codes.py:84
+#: InvenTree/status_codes.py:39 InvenTree/status_codes.py:93
msgid "Cancelled"
msgstr ""
-#: InvenTree/status_codes.py:31 InvenTree/status_codes.py:62
+#: InvenTree/status_codes.py:40 InvenTree/status_codes.py:71
msgid "Lost"
msgstr ""
-#: InvenTree/status_codes.py:32
+#: InvenTree/status_codes.py:41
msgid "Returned"
msgstr ""
-#: InvenTree/status_codes.py:58
+#: InvenTree/status_codes.py:67
msgid "OK"
msgstr ""
-#: InvenTree/status_codes.py:59
+#: InvenTree/status_codes.py:68
msgid "Attention needed"
msgstr ""
-#: InvenTree/status_codes.py:60
+#: InvenTree/status_codes.py:69
msgid "Damaged"
msgstr ""
-#: InvenTree/status_codes.py:61
+#: InvenTree/status_codes.py:70
msgid "Destroyed"
msgstr ""
-#: InvenTree/status_codes.py:83 build/templates/build/allocate_edit.html:28
+#: InvenTree/status_codes.py:92 build/templates/build/allocate_edit.html:28
#: build/templates/build/allocate_view.html:21
#: part/templates/part/part_base.html:116 part/templates/part/tabs.html:21
msgid "Allocated"
@@ -481,175 +481,175 @@ msgstr ""
msgid "Select currency for price calculation"
msgstr ""
-#: part/models.py:56
+#: part/models.py:55
msgid "Default location for parts in this category"
msgstr ""
-#: part/models.py:59
+#: part/models.py:58
msgid "Default keywords for parts in this category"
msgstr ""
-#: part/models.py:308
+#: part/models.py:307
msgid "Part must be unique for name, IPN and revision"
msgstr ""
-#: part/models.py:322
+#: part/models.py:321
msgid "Part cannot be a template part if it is a variant of another part"
msgstr ""
-#: part/models.py:323
+#: part/models.py:322
msgid "Part cannot be a variant of another part if it is already a template"
msgstr ""
-#: part/models.py:327 part/templates/part/detail.html:17
+#: part/models.py:326 part/templates/part/detail.html:17
msgid "Part name"
msgstr ""
-#: part/models.py:331
+#: part/models.py:330
msgid "Is this part a template part?"
msgstr ""
-#: part/models.py:340
+#: part/models.py:339
msgid "Is this part a variant of another part?"
msgstr ""
-#: part/models.py:342
+#: part/models.py:341
msgid "Part description"
msgstr ""
-#: part/models.py:344
+#: part/models.py:343
msgid "Part keywords to improve visibility in search results"
msgstr ""
-#: part/models.py:349
+#: part/models.py:348
msgid "Part category"
msgstr ""
-#: part/models.py:351
+#: part/models.py:350
msgid "Internal Part Number"
msgstr ""
-#: part/models.py:353
+#: part/models.py:352
msgid "Part revision or version number"
msgstr ""
-#: part/models.py:355
+#: part/models.py:354
msgid "Link to extenal URL"
msgstr ""
-#: part/models.py:361
+#: part/models.py:360
msgid "Where is this item normally stored?"
msgstr ""
-#: part/models.py:405
+#: part/models.py:404
msgid "Default supplier part"
msgstr ""
-#: part/models.py:408
+#: part/models.py:407
msgid "Minimum allowed stock level"
msgstr ""
-#: part/models.py:410
+#: part/models.py:409
msgid "Stock keeping units for this part"
msgstr ""
-#: part/models.py:412
+#: part/models.py:411
msgid "Can this part be built from other parts?"
msgstr ""
-#: part/models.py:414
+#: part/models.py:413
msgid "Can this part be used to build other parts?"
msgstr ""
-#: part/models.py:416
+#: part/models.py:415
msgid "Does this part have tracking for unique items?"
msgstr ""
-#: part/models.py:418
+#: part/models.py:417
msgid "Can this part be purchased from external suppliers?"
msgstr ""
-#: part/models.py:420
+#: part/models.py:419
msgid "Can this part be sold to customers?"
msgstr ""
-#: part/models.py:422
+#: part/models.py:421
msgid "Is this part active?"
msgstr ""
-#: part/models.py:424
+#: part/models.py:423
msgid "Is this a virtual part, such as a software product or license?"
msgstr ""
-#: part/models.py:428
+#: part/models.py:427
msgid "Stored BOM checksum"
msgstr ""
-#: part/models.py:935
+#: part/models.py:934
msgid "Select file to attach"
msgstr ""
-#: part/models.py:937
+#: part/models.py:936
msgid "File comment"
msgstr ""
-#: part/models.py:992
+#: part/models.py:991
msgid "Parameter template name must be unique"
msgstr ""
-#: part/models.py:997
+#: part/models.py:996
msgid "Parameter Name"
msgstr ""
-#: part/models.py:999
+#: part/models.py:998
msgid "Parameter Units"
msgstr ""
-#: part/models.py:1025
+#: part/models.py:1024
msgid "Parent Part"
msgstr ""
-#: part/models.py:1027
+#: part/models.py:1026
msgid "Parameter Template"
msgstr ""
-#: part/models.py:1029
+#: part/models.py:1028
msgid "Parameter Value"
msgstr ""
-#: part/models.py:1053
+#: part/models.py:1052
msgid "Select parent part"
msgstr ""
-#: part/models.py:1061
+#: part/models.py:1060
msgid "Select part to be used in BOM"
msgstr ""
-#: part/models.py:1067
+#: part/models.py:1066
msgid "BOM quantity for this BOM item"
msgstr ""
-#: part/models.py:1070
+#: part/models.py:1069
msgid "Estimated build wastage quantity (absolute or percentage)"
msgstr ""
-#: part/models.py:1073
+#: part/models.py:1072
msgid "BOM item reference"
msgstr ""
-#: part/models.py:1076
+#: part/models.py:1075
msgid "BOM item notes"
msgstr ""
-#: part/models.py:1078
+#: part/models.py:1077
msgid "BOM line checksum"
msgstr ""
-#: part/models.py:1141
+#: part/models.py:1140
msgid "Part cannot be added to its own Bill of Materials"
msgstr ""
-#: part/models.py:1148
+#: part/models.py:1147
#, python-brace-format
msgid "Part '{p1}' is used in BOM for '{p2}' (recursive)"
msgstr ""
diff --git a/InvenTree/order/api.py b/InvenTree/order/api.py
index e1396cb54c..69580c3bb2 100644
--- a/InvenTree/order/api.py
+++ b/InvenTree/order/api.py
@@ -7,9 +7,18 @@ from __future__ import unicode_literals
from django_filters.rest_framework import DjangoFilterBackend
from rest_framework import generics, permissions
+from rest_framework import filters
+from rest_framework.response import Response
+from django.conf import settings
from django.conf.urls import url
+from InvenTree.status_codes import OrderStatus
+
+import os
+
+from part.models import Part
+
from .models import PurchaseOrder, PurchaseOrderLineItem
from .serializers import POSerializer, POLineItemSerializer
@@ -24,18 +33,79 @@ class POList(generics.ListCreateAPIView):
queryset = PurchaseOrder.objects.all()
serializer_class = POSerializer
+ def list(self, request, *args, **kwargs):
+
+ queryset = self.get_queryset().prefetch_related('supplier', 'lines')
+
+ queryset = self.filter_queryset(queryset)
+
+ # Special filtering for 'status' field
+ if 'status' in request.GET:
+ status = request.GET['status']
+
+ # First attempt to filter by integer value
+ try:
+ status = int(status)
+ queryset = queryset.filter(status=status)
+ except ValueError:
+ try:
+ value = OrderStatus.value(status)
+ queryset = queryset.filter(status=value)
+ except ValueError:
+ pass
+
+ # Attempt to filter by part
+ if 'part' in request.GET:
+ try:
+ part = Part.objects.get(pk=request.GET['part'])
+ queryset = queryset.filter(id__in=[p.id for p in part.purchase_orders()])
+ except (Part.DoesNotExist, ValueError):
+ pass
+
+ data = queryset.values(
+ 'pk',
+ 'supplier',
+ 'supplier__name',
+ 'supplier__image',
+ 'reference',
+ 'description',
+ 'URL',
+ 'status',
+ 'notes',
+ 'creation_date',
+ )
+
+ for item in data:
+
+ order = queryset.get(pk=item['pk'])
+
+ item['supplier__image'] = os.path.join(settings.MEDIA_URL, item['supplier__image'])
+ item['status_text'] = OrderStatus.label(item['status'])
+ item['lines'] = order.lines.count()
+
+ return Response(data)
+
permission_classes = [
permissions.IsAuthenticated,
]
filter_backends = [
DjangoFilterBackend,
+ filters.SearchFilter,
+ filters.OrderingFilter,
]
filter_fields = [
'supplier',
]
+ ordering_fields = [
+ 'creation_date',
+ 'reference',
+ ]
+
+ ordering = '-creation_date'
+
class PODetail(generics.RetrieveUpdateAPIView):
""" API endpoint for detail view of a PurchaseOrder object """
diff --git a/InvenTree/order/templates/order/po_table_collapse.html b/InvenTree/order/templates/order/po_table_collapse.html
deleted file mode 100644
index 886e14ce97..0000000000
--- a/InvenTree/order/templates/order/po_table_collapse.html
+++ /dev/null
@@ -1,11 +0,0 @@
-{% extends "collapse.html" %}
-
-{% load static %}
-
-{% block collapse_title %}
-{{ title }}
-{% endblock %}
-
-{% block collapse_content %}
-{% include "order/po_table.html" %}
-{% endblock %}
\ No newline at end of file
diff --git a/InvenTree/order/templates/order/purchase_orders.html b/InvenTree/order/templates/order/purchase_orders.html
index 6e6e45cdfd..17f3115c75 100644
--- a/InvenTree/order/templates/order/purchase_orders.html
+++ b/InvenTree/order/templates/order/purchase_orders.html
@@ -1,6 +1,7 @@
{% extends "base.html" %}
{% load static %}
+{% load i18n %}
{% block page_title %}
InvenTree | Purchase Orders
@@ -17,7 +18,8 @@ InvenTree | Purchase Orders
-{% include "order/po_table.html" with toolbar='#table-buttons' %}
+
{% endblock %}
@@ -35,4 +37,8 @@ $("#po-create").click(function() {
$("#po-table").inventreeTable({
});
+loadPurchaseOrderTable($("#purchase-order-table"), {
+ url: "{% url 'api-po-list' %}",
+});
+
{% endblock %}
\ No newline at end of file
diff --git a/InvenTree/part/models.py b/InvenTree/part/models.py
index e265755778..386bf3e2c9 100644
--- a/InvenTree/part/models.py
+++ b/InvenTree/part/models.py
@@ -18,7 +18,6 @@ from django.db.models import Sum
from django.db.models import prefetch_related_objects
from django.core.validators import MinValueValidator
-from django.conf.urls.static import static
from django.contrib.auth.models import User
from django.db.models.signals import pre_delete
from django.dispatch import receiver
@@ -281,7 +280,7 @@ class Part(models.Model):
if self.image:
return os.path.join(settings.MEDIA_URL, str(self.image.url))
else:
- return static('/img/blank_image.png')
+ return os.path.join(settings.STATIC_URL, 'img/blank_image.png')
def validate_unique(self, exclude=None):
""" Validate that a part is 'unique'.
@@ -1230,6 +1229,10 @@ class BomItem(models.Model):
pmin, pmax = prange
+ # remove trailing zeros
+ pmin = pmin.normalize()
+ pmax = pmax.normalize()
+
if pmin == pmax:
return str(pmin)
diff --git a/InvenTree/part/templates/part/orders.html b/InvenTree/part/templates/part/orders.html
index b3f84735f3..fbb0413e34 100644
--- a/InvenTree/part/templates/part/orders.html
+++ b/InvenTree/part/templates/part/orders.html
@@ -14,19 +14,17 @@
-{% include "order/po_table.html" with orders=part.open_purchase_orders toolbar='#button-bar' %}
+
-{% if part.closed_purchase_orders|length > 0 %}
-Closed Orders
-{% include "order/po_table.html" with orders=part.closed_purchase_orders %}
-{% endif %}
{% endblock %}
{% block js_ready %}
{{ block.super }}
-$("#po-table").inventreeTable({
+loadPurchaseOrderTable($("#purchase-order-table"), {
+ url: "{% url 'api-po-list' %}?part={{ part.id }}",
});
$("#part-order2").click(function() {
diff --git a/docs/start.rst b/docs/start.rst
index 65fbf7b1ec..2cac8c6a95 100644
--- a/docs/start.rst
+++ b/docs/start.rst
@@ -31,12 +31,14 @@ To configure Inventree inside a virtual environment, ``cd`` into the inventree b
``apt-get install python3-venv``
-``source inventree/bin/activate``
+``python3 -m venv inventree-env``
+
+``source inventree-env/bin/activate``
This will place the current shell session inside a virtual environment - the terminal should display the ``(inventree)`` prefix.
.. note::
- Remember to run ``source inventree/bin/activate`` when starting each shell session, before running Inventree commands. This will ensure that the correct environment is being used.
+ Remember to run ``source inventree-env/bin/activate`` when starting each shell session, before running Inventree commands. This will ensure that the correct environment is being used.
Installation