diff --git a/InvenTree/InvenTree/models.py b/InvenTree/InvenTree/models.py
index d0ed73f27a..cffe48cc0b 100644
--- a/InvenTree/InvenTree/models.py
+++ b/InvenTree/InvenTree/models.py
@@ -102,12 +102,14 @@ class InvenTreeTree(MPTTModel):
name = models.CharField(
blank=False,
max_length=100,
- validators=[validate_tree_name]
+ validators=[validate_tree_name],
+ help_text=_("Name"),
)
description = models.CharField(
- blank=False,
- max_length=250
+ blank=True,
+ max_length=250,
+ help_text=_("Description (optional)")
)
# When a category is deleted, graft the children onto its parent
diff --git a/InvenTree/InvenTree/status_codes.py b/InvenTree/InvenTree/status_codes.py
index 2082eac70b..f8089cb5de 100644
--- a/InvenTree/InvenTree/status_codes.py
+++ b/InvenTree/InvenTree/status_codes.py
@@ -147,6 +147,11 @@ class SalesOrderStatus(StatusCode):
RETURNED: 'yellow',
}
+ # Open orders
+ OPEN = [
+ PENDING,
+ ]
+
class StockStatus(StatusCode):
diff --git a/InvenTree/company/templates/company/assigned_stock.html b/InvenTree/company/templates/company/assigned_stock.html
new file mode 100644
index 0000000000..53bc79b054
--- /dev/null
+++ b/InvenTree/company/templates/company/assigned_stock.html
@@ -0,0 +1,29 @@
+{% extends "company/company_base.html" %}
+{% load static %}
+{% load i18n %}
+
+{% block details %}
+
+{% include "company/tabs.html" with tab="assigned" %}
+
+
{% trans "Assigned Stock" %}
+
+
+
+
+{% endblock %}
+
+{% block js_ready %}
+{{ block.super }}
+
+loadStockTable($("#stock-table"), {
+ params: {
+ test: 7,
+ customer: {{ company.id }},
+ part_detail: true,
+ location_detail: true,
+ },
+ url: "{% url 'api-stock-list' %}",
+});
+
+{% endblock %}
\ No newline at end of file
diff --git a/InvenTree/company/templates/company/tabs.html b/InvenTree/company/templates/company/tabs.html
index 9fd00ceb11..ebd646b741 100644
--- a/InvenTree/company/templates/company/tabs.html
+++ b/InvenTree/company/templates/company/tabs.html
@@ -21,6 +21,13 @@
{% trans "Sales Orders" %} {{ company.sales_orders.count }}
+
+ {% trans "Assigned Stock" %}
+
+ {{ company.assigned_stock.count }}
+
+
+
{% endif %}
{% trans "Notes" %}{% if company.notes %} {% endif %}
diff --git a/InvenTree/company/urls.py b/InvenTree/company/urls.py
index af8e1846e1..f5fbeede47 100644
--- a/InvenTree/company/urls.py
+++ b/InvenTree/company/urls.py
@@ -13,13 +13,14 @@ company_detail_urls = [
# url(r'orders/?', views.CompanyDetail.as_view(template_name='company/orders.html'), name='company-detail-orders'),
- url(r'parts/', views.CompanyDetail.as_view(template_name='company/detail_part.html'), name='company-detail-parts'),
- url(r'stock/?', views.CompanyDetail.as_view(template_name='company/detail_stock.html'), name='company-detail-stock'),
- url(r'purchase-orders/?', views.CompanyDetail.as_view(template_name='company/purchase_orders.html'), name='company-detail-purchase-orders'),
- url(r'sales-orders/?', views.CompanyDetail.as_view(template_name='company/sales_orders.html'), name='company-detail-sales-orders'),
- url(r'notes/?', views.CompanyNotes.as_view(), name='company-notes'),
+ url(r'^parts/', views.CompanyDetail.as_view(template_name='company/detail_part.html'), name='company-detail-parts'),
+ url(r'^stock/', views.CompanyDetail.as_view(template_name='company/detail_stock.html'), name='company-detail-stock'),
+ url(r'^purchase-orders/', views.CompanyDetail.as_view(template_name='company/purchase_orders.html'), name='company-detail-purchase-orders'),
+ url(r'^assigned-stock/', views.CompanyDetail.as_view(template_name='company/assigned_stock.html'), name='company-detail-assigned-stock'),
+ url(r'^sales-orders/', views.CompanyDetail.as_view(template_name='company/sales_orders.html'), name='company-detail-sales-orders'),
+ url(r'^notes/', views.CompanyNotes.as_view(), name='company-notes'),
- url(r'thumbnail/?', views.CompanyImage.as_view(), name='company-image'),
+ url(r'^thumbnail/', views.CompanyImage.as_view(), name='company-image'),
# Any other URL
url(r'^.*$', views.CompanyDetail.as_view(), name='company-detail'),
diff --git a/InvenTree/order/api.py b/InvenTree/order/api.py
index dba493baab..a7915878c5 100644
--- a/InvenTree/order/api.py
+++ b/InvenTree/order/api.py
@@ -13,6 +13,7 @@ from django.conf.urls import url, include
from InvenTree.helpers import str2bool
from InvenTree.api import AttachmentMixin
+from InvenTree.status_codes import PurchaseOrderStatus, SalesOrderStatus
from part.models import Part
from company.models import SupplierPart
@@ -68,6 +69,17 @@ class POList(generics.ListCreateAPIView):
params = self.request.query_params
+ # Filter by 'outstanding' status
+ outstanding = params.get('outstanding', None)
+
+ if outstanding is not None:
+ outstanding = str2bool(outstanding)
+
+ if outstanding:
+ queryset = queryset.filter(status__in=PurchaseOrderStatus.OPEN)
+ else:
+ queryset = queryset.exclude(status__in=PurchaseOrderStatus.OPEN)
+
# Special filtering for 'status' field
status = params.get('status', None)
@@ -259,6 +271,17 @@ class SOList(generics.ListCreateAPIView):
params = self.request.query_params
+ # Filter by 'outstanding' status
+ outstanding = params.get('outstanding', None)
+
+ if outstanding is not None:
+ outstanding = str2bool(outstanding)
+
+ if outstanding:
+ queryset = queryset.filter(status__in=SalesOrderStatus.OPEN)
+ else:
+ queryset = queryset.exclude(status__in=SalesOrderStatus.OPEN)
+
status = params.get('status', None)
if status is not None:
diff --git a/InvenTree/part/migrations/0044_auto_20200605_0931.py b/InvenTree/part/migrations/0044_auto_20200605_0931.py
new file mode 100644
index 0000000000..bdce0ebc02
--- /dev/null
+++ b/InvenTree/part/migrations/0044_auto_20200605_0931.py
@@ -0,0 +1,24 @@
+# Generated by Django 3.0.5 on 2020-06-05 09:31
+
+import InvenTree.validators
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('part', '0043_auto_20200527_0005'),
+ ]
+
+ operations = [
+ migrations.AlterField(
+ model_name='partcategory',
+ name='description',
+ field=models.CharField(blank=True, help_text='Description', max_length=250),
+ ),
+ migrations.AlterField(
+ model_name='partcategory',
+ name='name',
+ field=models.CharField(help_text='Name', max_length=100, validators=[InvenTree.validators.validate_tree_name]),
+ ),
+ ]
diff --git a/InvenTree/part/migrations/0045_auto_20200605_0932.py b/InvenTree/part/migrations/0045_auto_20200605_0932.py
new file mode 100644
index 0000000000..a9be054468
--- /dev/null
+++ b/InvenTree/part/migrations/0045_auto_20200605_0932.py
@@ -0,0 +1,18 @@
+# Generated by Django 3.0.5 on 2020-06-05 09:32
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('part', '0044_auto_20200605_0931'),
+ ]
+
+ operations = [
+ migrations.AlterField(
+ model_name='partcategory',
+ name='description',
+ field=models.CharField(blank=True, help_text='Description (optional)', max_length=250),
+ ),
+ ]
diff --git a/InvenTree/stock/api.py b/InvenTree/stock/api.py
index 23d836b1e1..018b588c1f 100644
--- a/InvenTree/stock/api.py
+++ b/InvenTree/stock/api.py
@@ -471,6 +471,12 @@ class StockList(generics.ListCreateAPIView):
if sales_order:
queryset = queryset.filter(sales_order=sales_order)
+ # Filter by customer
+ customer = params.get('customer', None)
+
+ if customer:
+ queryset = queryset.filter(customer=customer)
+
# Filter by "serialized" status?
serialized = params.get('serialized', None)
diff --git a/InvenTree/stock/migrations/0046_auto_20200605_0931.py b/InvenTree/stock/migrations/0046_auto_20200605_0931.py
new file mode 100644
index 0000000000..8c37c31453
--- /dev/null
+++ b/InvenTree/stock/migrations/0046_auto_20200605_0931.py
@@ -0,0 +1,24 @@
+# Generated by Django 3.0.5 on 2020-06-05 09:31
+
+import InvenTree.validators
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('stock', '0045_stockitem_customer'),
+ ]
+
+ operations = [
+ migrations.AlterField(
+ model_name='stocklocation',
+ name='description',
+ field=models.CharField(blank=True, help_text='Description', max_length=250),
+ ),
+ migrations.AlterField(
+ model_name='stocklocation',
+ name='name',
+ field=models.CharField(help_text='Name', max_length=100, validators=[InvenTree.validators.validate_tree_name]),
+ ),
+ ]
diff --git a/InvenTree/stock/migrations/0047_auto_20200605_0932.py b/InvenTree/stock/migrations/0047_auto_20200605_0932.py
new file mode 100644
index 0000000000..5ca509f13f
--- /dev/null
+++ b/InvenTree/stock/migrations/0047_auto_20200605_0932.py
@@ -0,0 +1,18 @@
+# Generated by Django 3.0.5 on 2020-06-05 09:32
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('stock', '0046_auto_20200605_0931'),
+ ]
+
+ operations = [
+ migrations.AlterField(
+ model_name='stocklocation',
+ name='description',
+ field=models.CharField(blank=True, help_text='Description (optional)', max_length=250),
+ ),
+ ]
diff --git a/InvenTree/stock/models.py b/InvenTree/stock/models.py
index e59af0e2e9..736e2218bf 100644
--- a/InvenTree/stock/models.py
+++ b/InvenTree/stock/models.py
@@ -140,6 +140,7 @@ class StockItem(MPTTModel):
sales_order=None,
build_order=None,
belongs_to=None,
+ status__in=StockStatus.AVAILABLE_CODES
)
def save(self, *args, **kwargs):
diff --git a/InvenTree/templates/js/part.html b/InvenTree/templates/js/part.html
index 1a40c7ad84..c9901cdb68 100644
--- a/InvenTree/templates/js/part.html
+++ b/InvenTree/templates/js/part.html
@@ -95,6 +95,8 @@ function loadPartTable(table, url, options={}) {
field: 'pk',
title: 'ID',
visible: false,
+ switchable: false,
+ searchable: false,
}
];
@@ -103,9 +105,16 @@ function loadPartTable(table, url, options={}) {
checkbox: true,
title: '{% trans 'Select' %}',
searchable: false,
+ switchable: false,
});
}
+ columns.push({
+ field: 'IPN',
+ title: 'IPN',
+ sortable: true,
+ }),
+
columns.push({
field: 'name',
title: '{% trans 'Part' %}',
@@ -231,6 +240,7 @@ function loadPartTable(table, url, options={}) {
original: params,
formatNoMatches: function() { return "{% trans "No parts found" %}"; },
columns: columns,
+ showColumns: true,
});
if (options.buttons) {
diff --git a/InvenTree/templates/js/stock.html b/InvenTree/templates/js/stock.html
index c0737dc250..14be8d9afe 100644
--- a/InvenTree/templates/js/stock.html
+++ b/InvenTree/templates/js/stock.html
@@ -351,8 +351,6 @@ function loadStockTable(table, options) {
loc = "{% trans "Undefined location" %}";
}
- console.log("Location: " + loc);
-
if (!locations.includes(loc)) {
locations.push(loc);
}
diff --git a/InvenTree/templates/js/table_filters.html b/InvenTree/templates/js/table_filters.html
index 298a034517..bec29b0487 100644
--- a/InvenTree/templates/js/table_filters.html
+++ b/InvenTree/templates/js/table_filters.html
@@ -78,11 +78,16 @@ function getAvailableTableFilters(tableKey) {
// Filters for the "Order" table
if (tableKey == "purchaseorder") {
+
return {
status: {
title: '{% trans "Order status" %}',
options: purchaseOrderCodes,
},
+ outstanding: {
+ type: 'bool',
+ title: '{% trans "Outstanding" %}',
+ },
};
}
@@ -92,6 +97,10 @@ function getAvailableTableFilters(tableKey) {
title: '{% trans "Order status" %}',
options: salesOrderCodes,
},
+ outstanding: {
+ type: 'bool',
+ title: '{% trans "Outstanding" %}',
+ },
};
}