diff --git a/InvenTree/InvenTree/models.py b/InvenTree/InvenTree/models.py
index d5259b2acc..a60935b4b6 100644
--- a/InvenTree/InvenTree/models.py
+++ b/InvenTree/InvenTree/models.py
@@ -29,6 +29,8 @@ class InvenTreeTree(MPTTModel):
class Meta:
abstract = True
+
+ # Names must be unique at any given level in the tree
unique_together = ('name', 'parent')
class MPTTMeta:
@@ -37,7 +39,6 @@ class InvenTreeTree(MPTTModel):
name = models.CharField(
blank=False,
max_length=100,
- unique=True,
validators=[validate_tree_name]
)
diff --git a/InvenTree/InvenTree/static/script/inventree/inventree.js b/InvenTree/InvenTree/static/script/inventree/inventree.js
index 90dbacbe35..04539c6d96 100644
--- a/InvenTree/InvenTree/static/script/inventree/inventree.js
+++ b/InvenTree/InvenTree/static/script/inventree/inventree.js
@@ -41,6 +41,13 @@ function inventreeDocReady() {
modal.modal('show');
});
+
+ // Callback to launch the 'Database Stats' window
+ $('#launch-stats').click(function() {
+ launchModalForm("/stats/", {
+ no_post: true,
+ });
+ });
}
function isFileTransfer(transfer) {
diff --git a/InvenTree/InvenTree/urls.py b/InvenTree/InvenTree/urls.py
index 31b498ea2b..4b18916828 100644
--- a/InvenTree/InvenTree/urls.py
+++ b/InvenTree/InvenTree/urls.py
@@ -33,7 +33,8 @@ from django.conf.urls.static import static
from django.views.generic.base import RedirectView
from rest_framework.documentation import include_docs_urls
-from .views import IndexView, SearchView, SettingsView, EditUserView, SetPasswordView
+from .views import IndexView, SearchView, DatabaseStatsView
+from .views import SettingsView, EditUserView, SetPasswordView
from .views import InfoView
from users.urls import user_urls
@@ -97,6 +98,7 @@ urlpatterns = [
url(r'^index/', IndexView.as_view(), name='index'),
url(r'^search/', SearchView.as_view(), name='search'),
+ url(r'^stats/', DatabaseStatsView.as_view(), name='stats'),
url(r'^api/', include(apipatterns)),
url(r'^api-doc/', include_docs_urls(title='InvenTree API')),
diff --git a/InvenTree/InvenTree/views.py b/InvenTree/InvenTree/views.py
index 95ad33cba1..5121b1bad9 100644
--- a/InvenTree/InvenTree/views.py
+++ b/InvenTree/InvenTree/views.py
@@ -8,6 +8,7 @@ as JSON objects and passing them to modal forms (using jQuery / bootstrap).
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
+from django.utils.translation import gettext_lazy as _
from django.template.loader import render_to_string
from django.http import JsonResponse, HttpResponseRedirect
@@ -15,7 +16,8 @@ from django.views import View
from django.views.generic import UpdateView, CreateView
from django.views.generic.base import TemplateView
-from part.models import Part
+from part.models import Part, PartCategory
+from stock.models import StockLocation, StockItem
from common.models import InvenTreeSetting
from .forms import DeleteForm, EditUserForm, SetPasswordForm
@@ -537,3 +539,33 @@ class SettingsView(TemplateView):
ctx['settings'] = InvenTreeSetting.objects.all().order_by('key')
return ctx
+
+
+class DatabaseStatsView(AjaxView):
+ """ View for displaying database statistics """
+
+ ajax_template_name = "stats.html"
+ ajax_form_title = _("Database Statistics")
+
+ def get_context_data(self, **kwargs):
+
+ ctx = {}
+
+ # Part stats
+ ctx['part_count'] = Part.objects.count()
+ ctx['part_cat_count'] = PartCategory.objects.count()
+
+ # Stock stats
+ ctx['stock_item_count'] = StockItem.objects.count()
+ ctx['stock_loc_count'] = StockLocation.objects.count()
+
+ """
+ TODO: Other ideas for database metrics
+
+ - "Popular" parts (used to make other parts?)
+ - Most ordered part
+ - Most sold part
+ - etc etc etc
+ """
+
+ return ctx
diff --git a/InvenTree/company/templates/company/company_base.html b/InvenTree/company/templates/company/company_base.html
index 1063f967f5..1080f01445 100644
--- a/InvenTree/company/templates/company/company_base.html
+++ b/InvenTree/company/templates/company/company_base.html
@@ -1,9 +1,10 @@
{% extends "base.html" %}
{% load static %}
+{% load i18n %}
{% block page_title %}
-InvenTree | Company - {{ company.name }}
+InvenTree | {% trans "Company" %} - {{ company.name }}
{% endblock %}
{% block content %}
@@ -44,27 +45,27 @@ InvenTree | Company - {{ company.name }}
{% if company.website %}
- Website | {{ company.website }} |
+ {% trans "Website" %} | {{ company.website }} |
{% endif %}
{% if company.address %}
- Address | {{ company.address }} |
+ {% trans "Address" %} | {{ company.address }} |
{% endif %}
{% if company.phone %}
- Phone | {{ company.phone }} |
+ {% trans "Phone" %} | {{ company.phone }} |
{% endif %}
{% if company.email %}
- Email | {{ company.email }} |
+ {% trans "Email" %} | {{ company.email }} |
{% endif %}
{% if company.contact %}
- Contact | {{ company.contact }} |
+ {% trans "Contact" %} | {{ company.contact }} |
{% endif %}
diff --git a/InvenTree/company/templates/company/detail.html b/InvenTree/company/templates/company/detail.html
index 872d7f675e..93e9e5bbb9 100644
--- a/InvenTree/company/templates/company/detail.html
+++ b/InvenTree/company/templates/company/detail.html
@@ -1,19 +1,20 @@
{% extends "company/company_base.html" %}
{% load static %}
+{% load i18n %}}
{% block details %}
{% include 'company/tabs.html' with tab='details' %}
-Company Details
+{% trans "Company Details" %}
- Customer |
+ {% trans "Customer" %} |
{% include 'yesnolabel.html' with value=company.is_customer %} |
- Supplier |
+ {% trans "Supplier" %} |
{% include 'yesnolabel.html' with value=company.is_supplier %} |
diff --git a/InvenTree/company/templates/company/detail_part.html b/InvenTree/company/templates/company/detail_part.html
index f1e5ab8632..7eac2b7bfe 100644
--- a/InvenTree/company/templates/company/detail_part.html
+++ b/InvenTree/company/templates/company/detail_part.html
@@ -1,21 +1,22 @@
{% extends "company/company_base.html" %}
{% load static %}
{% block details %}
+{% load i18n %}
{% include 'company/tabs.html' with tab='parts' %}
-Supplier Parts
+{% trans "Supplier Parts" %}
@@ -61,7 +62,7 @@
{
sortable: true,
field: 'part_detail.full_name',
- title: 'Part',
+ title: '{% trans "Part" %}',
formatter: function(value, row, index, field) {
return imageHoverIcon(row.part_detail.image_url) + renderLink(value, '/part/' + row.part + '/suppliers/');
}
@@ -69,7 +70,7 @@
{
sortable: true,
field: 'SKU',
- title: 'SKU',
+ title: '{% trans "SKU" %}',
formatter: function(value, row, index, field) {
return renderLink(value, row.url);
}
@@ -77,7 +78,7 @@
{
sortable: true,
field: 'manufacturer',
- title: 'Manufacturer',
+ title: '{% trans "Manufacturer" %}',
},
{
sortable: true,
@@ -86,7 +87,7 @@
},
{
field: 'URL',
- title: 'URL',
+ title: '{% trans "URL" %}',
formatter: function(value, row, index, field) {
if (value) {
return renderLink(value, value);
diff --git a/InvenTree/company/templates/company/detail_purchase_orders.html b/InvenTree/company/templates/company/detail_purchase_orders.html
index b2eabc129d..fcba26e2af 100644
--- a/InvenTree/company/templates/company/detail_purchase_orders.html
+++ b/InvenTree/company/templates/company/detail_purchase_orders.html
@@ -1,15 +1,16 @@
{% extends "company/company_base.html" %}
{% load static %}
{% block details %}
+{% load i18n %}
{% include 'company/tabs.html' with tab='po' %}
-Open Purchase Orders
+{% trans "Purchase Orders" %}
diff --git a/InvenTree/company/templates/company/detail_stock.html b/InvenTree/company/templates/company/detail_stock.html
index 43966810b8..4acf783729 100644
--- a/InvenTree/company/templates/company/detail_stock.html
+++ b/InvenTree/company/templates/company/detail_stock.html
@@ -1,11 +1,12 @@
{% extends "company/company_base.html" %}
{% load static %}
+{% load i18n %}
{% block details %}
{% include "company/tabs.html" with tab='stock' %}
-Supplier Stock
+{% trans "Supplier Stock" %}
@@ -29,7 +30,7 @@
$("#stock-export").click(function() {
launchModalForm("{% url 'stock-export-options' %}", {
- submit_text: "Export",
+ submit_text: '{% trans "Export" %}',
success: function(response) {
var url = "{% url 'stock-export' %}";
diff --git a/InvenTree/company/templates/company/index.html b/InvenTree/company/templates/company/index.html
index 711ed8eb37..0c5e3a6931 100644
--- a/InvenTree/company/templates/company/index.html
+++ b/InvenTree/company/templates/company/index.html
@@ -1,19 +1,20 @@
{% extends "base.html" %}
{% load static %}
+{% load i18n %}
{% block page_title %}
-InvenTree | Supplier List
+InvenTree | {% trans "Supplier List" %}
{% endblock %}
{% block content %}
-Supplier List
+{% trans "Supplier List" %}
@@ -37,12 +38,12 @@ InvenTree | Supplier List
columns: [
{
field: 'pk',
- title: 'ID',
+ title: '{% trans "ID" %}',
visible: false,
},
{
field: 'name',
- title: 'Supplier',
+ title: '{% trans "Supplier" %}',
sortable: true,
formatter: function(value, row, index, field) {
return imageHoverIcon(row.image) + renderLink(value, row.url);
@@ -50,12 +51,12 @@ InvenTree | Supplier List
},
{
field: 'description',
- title: 'Description',
+ title: '{% trans "Description" %}',
sortable: true,
},
{
field: 'website',
- title: 'Website',
+ title: '{% trans "Website" %}',
formatter: function(value, row, index, field) {
if (value) {
return renderLink(value, value);
@@ -65,7 +66,7 @@ InvenTree | Supplier List
},
{
field: 'part_count',
- title: 'Parts',
+ title: '{% trans "Parts" %}',
sortable: true,
formatter: function(value, row, index, field) {
return renderLink(value, row.url + 'parts/');
diff --git a/InvenTree/company/templates/company/order_detail.html b/InvenTree/company/templates/company/order_detail.html
deleted file mode 100644
index 34c9071e38..0000000000
--- a/InvenTree/company/templates/company/order_detail.html
+++ /dev/null
@@ -1,49 +0,0 @@
-{% extends "base.html" %}
-
-{% block content %}
-
-Supplier Order Details
-
-
-
- Reference |
- {{ order.internal_ref }} |
-
-
- Supplier |
-
- {% if order.supplier %}
- {{ order.supplier.name }}
- {% endif %}
- |
-
-
- Status |
- {% include "supplier/order_status.html" with order=order %} |
-
-
- Created Date |
- {{ order.created_date }} |
-
-
- Issued Date |
- {{ order.issued_date }} |
-
-
- Delivered Date |
- {{ order.delivery_date }} |
-
-
-
-
-{% if order.notes %}
-
-
Notes
-
{{ order.notes }}
-
-{% endif %}
-
-TODO
-Here we list all the line ites which exist under this order...
-
-{% endblock %}
\ No newline at end of file
diff --git a/InvenTree/company/templates/company/partdetail.html b/InvenTree/company/templates/company/partdetail.html
index b6b12b114d..1b101ec48e 100644
--- a/InvenTree/company/templates/company/partdetail.html
+++ b/InvenTree/company/templates/company/partdetail.html
@@ -1,15 +1,16 @@
{% extends "base.html" %}
{% load static %}
+{% load i18n %}
{% block page_title %}
-InvenTree | {{ company.name }} - Parts
+InvenTree | {{ company.name }} - {% trans "Parts" %}
{% endblock %}
{% block content %}
-
Supplier Part
+
{% trans "Supplier Part" %}