Merge remote-tracking branch 'inventree/master'

This commit is contained in:
Oliver Walters 2020-06-05 20:04:41 +10:00
commit 7be158722f
15 changed files with 186 additions and 11 deletions

View File

@ -102,12 +102,14 @@ class InvenTreeTree(MPTTModel):
name = models.CharField( name = models.CharField(
blank=False, blank=False,
max_length=100, max_length=100,
validators=[validate_tree_name] validators=[validate_tree_name],
help_text=_("Name"),
) )
description = models.CharField( description = models.CharField(
blank=False, blank=True,
max_length=250 max_length=250,
help_text=_("Description (optional)")
) )
# When a category is deleted, graft the children onto its parent # When a category is deleted, graft the children onto its parent

View File

@ -147,6 +147,11 @@ class SalesOrderStatus(StatusCode):
RETURNED: 'yellow', RETURNED: 'yellow',
} }
# Open orders
OPEN = [
PENDING,
]
class StockStatus(StatusCode): class StockStatus(StatusCode):

View File

@ -0,0 +1,29 @@
{% extends "company/company_base.html" %}
{% load static %}
{% load i18n %}
{% block details %}
{% include "company/tabs.html" with tab="assigned" %}
<h4>{% trans "Assigned Stock" %}</h4>
<hr>
<table class='table table-striped table-condensed' id='stock-table'></table>
{% 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 %}

View File

@ -21,6 +21,13 @@
<li{% if tab == 'co' %} class='active'{% endif %}> <li{% if tab == 'co' %} class='active'{% endif %}>
<a href="{% url 'company-detail-sales-orders' company.id %}">{% trans "Sales Orders" %} <span class='badge'>{{ company.sales_orders.count }}</span></a> <a href="{% url 'company-detail-sales-orders' company.id %}">{% trans "Sales Orders" %} <span class='badge'>{{ company.sales_orders.count }}</span></a>
</li> </li>
<li{% if tab == 'assigned' %} class='active'{% endif %}>
<a href="{% url 'company-detail-assigned-stock' company.id %}">{% trans "Assigned Stock" %}
<span class='badge'>
{{ company.assigned_stock.count }}
</span>
</a>
</li>
{% endif %} {% endif %}
<li{% if tab == 'notes' %} class='active'{% endif %}> <li{% if tab == 'notes' %} class='active'{% endif %}>
<a href="{% url 'company-notes' company.id %}">{% trans "Notes" %}{% if company.notes %} <span class='fas fa-info-circle'></span>{% endif %}</a> <a href="{% url 'company-notes' company.id %}">{% trans "Notes" %}{% if company.notes %} <span class='fas fa-info-circle'></span>{% endif %}</a>

View File

@ -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'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'^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'^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'^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'^assigned-stock/', views.CompanyDetail.as_view(template_name='company/assigned_stock.html'), name='company-detail-assigned-stock'),
url(r'notes/?', views.CompanyNotes.as_view(), name='company-notes'), 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 # Any other URL
url(r'^.*$', views.CompanyDetail.as_view(), name='company-detail'), url(r'^.*$', views.CompanyDetail.as_view(), name='company-detail'),

View File

@ -13,6 +13,7 @@ from django.conf.urls import url, include
from InvenTree.helpers import str2bool from InvenTree.helpers import str2bool
from InvenTree.api import AttachmentMixin from InvenTree.api import AttachmentMixin
from InvenTree.status_codes import PurchaseOrderStatus, SalesOrderStatus
from part.models import Part from part.models import Part
from company.models import SupplierPart from company.models import SupplierPart
@ -68,6 +69,17 @@ class POList(generics.ListCreateAPIView):
params = self.request.query_params 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 # Special filtering for 'status' field
status = params.get('status', None) status = params.get('status', None)
@ -259,6 +271,17 @@ class SOList(generics.ListCreateAPIView):
params = self.request.query_params 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) status = params.get('status', None)
if status is not None: if status is not None:

View File

@ -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]),
),
]

View File

@ -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),
),
]

View File

@ -471,6 +471,12 @@ class StockList(generics.ListCreateAPIView):
if sales_order: if sales_order:
queryset = queryset.filter(sales_order=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? # Filter by "serialized" status?
serialized = params.get('serialized', None) serialized = params.get('serialized', None)

View File

@ -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]),
),
]

View File

@ -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),
),
]

View File

@ -140,6 +140,7 @@ class StockItem(MPTTModel):
sales_order=None, sales_order=None,
build_order=None, build_order=None,
belongs_to=None, belongs_to=None,
status__in=StockStatus.AVAILABLE_CODES
) )
def save(self, *args, **kwargs): def save(self, *args, **kwargs):

View File

@ -95,6 +95,8 @@ function loadPartTable(table, url, options={}) {
field: 'pk', field: 'pk',
title: 'ID', title: 'ID',
visible: false, visible: false,
switchable: false,
searchable: false,
} }
]; ];
@ -103,9 +105,16 @@ function loadPartTable(table, url, options={}) {
checkbox: true, checkbox: true,
title: '{% trans 'Select' %}', title: '{% trans 'Select' %}',
searchable: false, searchable: false,
switchable: false,
}); });
} }
columns.push({
field: 'IPN',
title: 'IPN',
sortable: true,
}),
columns.push({ columns.push({
field: 'name', field: 'name',
title: '{% trans 'Part' %}', title: '{% trans 'Part' %}',
@ -231,6 +240,7 @@ function loadPartTable(table, url, options={}) {
original: params, original: params,
formatNoMatches: function() { return "{% trans "No parts found" %}"; }, formatNoMatches: function() { return "{% trans "No parts found" %}"; },
columns: columns, columns: columns,
showColumns: true,
}); });
if (options.buttons) { if (options.buttons) {

View File

@ -351,8 +351,6 @@ function loadStockTable(table, options) {
loc = "{% trans "Undefined location" %}"; loc = "{% trans "Undefined location" %}";
} }
console.log("Location: " + loc);
if (!locations.includes(loc)) { if (!locations.includes(loc)) {
locations.push(loc); locations.push(loc);
} }

View File

@ -78,11 +78,16 @@ function getAvailableTableFilters(tableKey) {
// Filters for the "Order" table // Filters for the "Order" table
if (tableKey == "purchaseorder") { if (tableKey == "purchaseorder") {
return { return {
status: { status: {
title: '{% trans "Order status" %}', title: '{% trans "Order status" %}',
options: purchaseOrderCodes, options: purchaseOrderCodes,
}, },
outstanding: {
type: 'bool',
title: '{% trans "Outstanding" %}',
},
}; };
} }
@ -92,6 +97,10 @@ function getAvailableTableFilters(tableKey) {
title: '{% trans "Order status" %}', title: '{% trans "Order status" %}',
options: salesOrderCodes, options: salesOrderCodes,
}, },
outstanding: {
type: 'bool',
title: '{% trans "Outstanding" %}',
},
}; };
} }