mirror of
https://github.com/inventree/InvenTree.git
synced 2025-04-29 20:16:44 +00:00
Merge remote-tracking branch 'inventree/master'
This commit is contained in:
commit
1eeaa17085
@ -469,6 +469,9 @@ function openModal(options) {
|
|||||||
|
|
||||||
$(modal).on('shown.bs.modal', function() {
|
$(modal).on('shown.bs.modal', function() {
|
||||||
$(modal + ' .modal-form-content').scrollTop(0);
|
$(modal + ' .modal-form-content').scrollTop(0);
|
||||||
|
if (options.focus) {
|
||||||
|
getFieldByName(modal, options.focus).focus();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Prevent 'enter' key from submitting the form using the normal method
|
// Prevent 'enter' key from submitting the form using the normal method
|
||||||
@ -745,6 +748,7 @@ function launchModalForm(url, options = {}) {
|
|||||||
* after_render - Callback function to run after form is rendered
|
* after_render - Callback function to run after form is rendered
|
||||||
* secondary - List of secondary modals to attach
|
* secondary - List of secondary modals to attach
|
||||||
* callback - List of callback functions to attach to inputs
|
* callback - List of callback functions to attach to inputs
|
||||||
|
* focus - Select which field to focus on by default
|
||||||
*/
|
*/
|
||||||
|
|
||||||
var modal = options.modal || '#modal-form';
|
var modal = options.modal || '#modal-form';
|
||||||
@ -763,6 +767,7 @@ function launchModalForm(url, options = {}) {
|
|||||||
modal: modal,
|
modal: modal,
|
||||||
submit_text: submit_text,
|
submit_text: submit_text,
|
||||||
close_text: close_text,
|
close_text: close_text,
|
||||||
|
focus: options.focus
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
success: function(response) {
|
success: function(response) {
|
||||||
|
@ -80,11 +80,28 @@ function reloadTable(table, filters) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function visibleColumnString(columns) {
|
||||||
|
/* Generate a list of "visible" columns to save to file. */
|
||||||
|
|
||||||
|
var fields = [];
|
||||||
|
|
||||||
|
columns.forEach(function(column) {
|
||||||
|
if (column.switchable && column.visible) {
|
||||||
|
fields.push(column.field);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return fields.join(',');
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Wrapper function for bootstrapTable.
|
/* Wrapper function for bootstrapTable.
|
||||||
* Sets some useful defaults, and manage persistent settings.
|
* Sets some useful defaults, and manage persistent settings.
|
||||||
*/
|
*/
|
||||||
$.fn.inventreeTable = function(options) {
|
$.fn.inventreeTable = function(options) {
|
||||||
|
|
||||||
|
var table = this;
|
||||||
|
|
||||||
var tableName = options.name || 'table';
|
var tableName = options.name || 'table';
|
||||||
|
|
||||||
var varName = tableName + '-pagesize';
|
var varName = tableName + '-pagesize';
|
||||||
@ -95,14 +112,51 @@ $.fn.inventreeTable = function(options) {
|
|||||||
options.rememberOrder = true;
|
options.rememberOrder = true;
|
||||||
options.sortable = true;
|
options.sortable = true;
|
||||||
options.search = true;
|
options.search = true;
|
||||||
|
options.showColumns = true;
|
||||||
|
|
||||||
// Callback to save pagination data
|
// Callback to save pagination data
|
||||||
options.onPageChange = function(number, size) {
|
options.onPageChange = function(number, size) {
|
||||||
inventreeSave(varName, size);
|
inventreeSave(varName, size);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Callback when a column is changed
|
||||||
|
options.onColumnSwitch = function(field, checked) {
|
||||||
|
console.log(`${field} -> ${checked}`);
|
||||||
|
|
||||||
|
var columns = table.bootstrapTable('getVisibleColumns');
|
||||||
|
|
||||||
|
var text = visibleColumnString(columns);
|
||||||
|
|
||||||
|
// Save visible columns
|
||||||
|
inventreeSave(`table_columns_${tableName}`, text);
|
||||||
|
};
|
||||||
|
|
||||||
// Standard options for all tables
|
// Standard options for all tables
|
||||||
this.bootstrapTable(options);
|
table.bootstrapTable(options);
|
||||||
|
|
||||||
|
// Load visible column list from memory
|
||||||
|
// Load visible column list
|
||||||
|
var visibleColumns = inventreeLoad(`table_columns_${tableName}`, null);
|
||||||
|
|
||||||
|
// If a set of visible columns has been saved, load!
|
||||||
|
if (visibleColumns) {
|
||||||
|
var columns = visibleColumns.split(",");
|
||||||
|
|
||||||
|
// Which columns are currently visible?
|
||||||
|
var visible = table.bootstrapTable('getVisibleColumns');
|
||||||
|
|
||||||
|
if (visible) {
|
||||||
|
visible.forEach(function(column) {
|
||||||
|
|
||||||
|
// Visible field should *not* be visible! (hide it!)
|
||||||
|
if (column.switchable && !columns.includes(column.field)) {
|
||||||
|
table.bootstrapTable('hideColumn', column.field);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
console.log('Could not get list of visible columns!');
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function customGroupSorter(sortName, sortOrder, sortData) {
|
function customGroupSorter(sortName, sortOrder, sortData) {
|
||||||
|
35
InvenTree/order/migrations/0036_auto_20200831_0912.py
Normal file
35
InvenTree/order/migrations/0036_auto_20200831_0912.py
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
# Generated by Django 3.0.7 on 2020-08-31 09:12
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
import django.db.models.deletion
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('company', '0023_auto_20200808_0715'),
|
||||||
|
('order', '0035_auto_20200513_0016'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='purchaseorder',
|
||||||
|
name='complete_date',
|
||||||
|
field=models.DateField(blank=True, help_text='Date order was completed', null=True),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='purchaseorder',
|
||||||
|
name='issue_date',
|
||||||
|
field=models.DateField(blank=True, help_text='Date order was issued', null=True),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='purchaseorder',
|
||||||
|
name='supplier',
|
||||||
|
field=models.ForeignKey(help_text='Company from which the items are being ordered', limit_choices_to={'is_supplier': True}, on_delete=django.db.models.deletion.CASCADE, related_name='purchase_orders', to='company.Company'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='salesorder',
|
||||||
|
name='customer',
|
||||||
|
field=models.ForeignKey(help_text='Company to which the items are being sold', limit_choices_to={'is_customer': True}, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='sales_orders', to='company.Company'),
|
||||||
|
),
|
||||||
|
]
|
@ -137,7 +137,7 @@ class PurchaseOrder(Order):
|
|||||||
return "PO {ref} - {company}".format(ref=self.reference, company=self.supplier.name)
|
return "PO {ref} - {company}".format(ref=self.reference, company=self.supplier.name)
|
||||||
|
|
||||||
status = models.PositiveIntegerField(default=PurchaseOrderStatus.PENDING, choices=PurchaseOrderStatus.items(),
|
status = models.PositiveIntegerField(default=PurchaseOrderStatus.PENDING, choices=PurchaseOrderStatus.items(),
|
||||||
help_text='Purchase order status')
|
help_text=_('Purchase order status'))
|
||||||
|
|
||||||
supplier = models.ForeignKey(
|
supplier = models.ForeignKey(
|
||||||
Company, on_delete=models.CASCADE,
|
Company, on_delete=models.CASCADE,
|
||||||
@ -145,7 +145,7 @@ class PurchaseOrder(Order):
|
|||||||
'is_supplier': True,
|
'is_supplier': True,
|
||||||
},
|
},
|
||||||
related_name='purchase_orders',
|
related_name='purchase_orders',
|
||||||
help_text=_('Supplier')
|
help_text=_('Company from which the items are being ordered')
|
||||||
)
|
)
|
||||||
|
|
||||||
supplier_reference = models.CharField(max_length=64, blank=True, help_text=_("Supplier order reference code"))
|
supplier_reference = models.CharField(max_length=64, blank=True, help_text=_("Supplier order reference code"))
|
||||||
@ -157,9 +157,9 @@ class PurchaseOrder(Order):
|
|||||||
related_name='+'
|
related_name='+'
|
||||||
)
|
)
|
||||||
|
|
||||||
issue_date = models.DateField(blank=True, null=True)
|
issue_date = models.DateField(blank=True, null=True, help_text=_('Date order was issued'))
|
||||||
|
|
||||||
complete_date = models.DateField(blank=True, null=True)
|
complete_date = models.DateField(blank=True, null=True, help_text=_('Date order was completed'))
|
||||||
|
|
||||||
def get_absolute_url(self):
|
def get_absolute_url(self):
|
||||||
return reverse('po-detail', kwargs={'pk': self.id})
|
return reverse('po-detail', kwargs={'pk': self.id})
|
||||||
@ -311,11 +311,11 @@ class SalesOrder(Order):
|
|||||||
null=True,
|
null=True,
|
||||||
limit_choices_to={'is_customer': True},
|
limit_choices_to={'is_customer': True},
|
||||||
related_name='sales_orders',
|
related_name='sales_orders',
|
||||||
help_text=_("Customer"),
|
help_text=_("Company to which the items are being sold"),
|
||||||
)
|
)
|
||||||
|
|
||||||
status = models.PositiveIntegerField(default=SalesOrderStatus.PENDING, choices=SalesOrderStatus.items(),
|
status = models.PositiveIntegerField(default=SalesOrderStatus.PENDING, choices=SalesOrderStatus.items(),
|
||||||
help_text='Purchase order status')
|
help_text=_('Purchase order status'))
|
||||||
|
|
||||||
customer_reference = models.CharField(max_length=64, blank=True, help_text=_("Customer order reference code"))
|
customer_reference = models.CharField(max_length=64, blank=True, help_text=_("Customer order reference code"))
|
||||||
|
|
||||||
|
@ -127,6 +127,7 @@ function setupCallbacks() {
|
|||||||
|
|
||||||
$("#po-table").inventreeTable({
|
$("#po-table").inventreeTable({
|
||||||
onPostBody: setupCallbacks,
|
onPostBody: setupCallbacks,
|
||||||
|
name: 'purchaseorder',
|
||||||
formatNoMatches: function() { return "{% trans 'No line items found' %}"; },
|
formatNoMatches: function() { return "{% trans 'No line items found' %}"; },
|
||||||
queryParams: {
|
queryParams: {
|
||||||
order: {{ order.id }},
|
order: {{ order.id }},
|
||||||
@ -138,6 +139,7 @@ $("#po-table").inventreeTable({
|
|||||||
field: 'pk',
|
field: 'pk',
|
||||||
title: 'ID',
|
title: 'ID',
|
||||||
visible: false,
|
visible: false,
|
||||||
|
switchable: false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
field: 'part',
|
field: 'part',
|
||||||
|
@ -190,6 +190,7 @@ $("#so-lines-table").inventreeTable({
|
|||||||
field: 'pk',
|
field: 'pk',
|
||||||
title: 'ID',
|
title: 'ID',
|
||||||
visible: false,
|
visible: false,
|
||||||
|
switchable: false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
sortable: true,
|
sortable: true,
|
||||||
|
@ -1080,12 +1080,21 @@ class Part(MPTTModel):
|
|||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
n = self.attachments.count()
|
return self.part_attachments.count()
|
||||||
|
|
||||||
if self.variant_of:
|
@property
|
||||||
n += self.variant_of.attachments.count()
|
def part_attachments(self):
|
||||||
|
"""
|
||||||
|
Return *all* attachments for this part,
|
||||||
|
potentially including attachments for template parts
|
||||||
|
above this one.
|
||||||
|
"""
|
||||||
|
|
||||||
return n
|
ancestors = self.get_ancestors(include_self=True)
|
||||||
|
|
||||||
|
attachments = PartAttachment.objects.filter(part__in=ancestors)
|
||||||
|
|
||||||
|
return attachments
|
||||||
|
|
||||||
def sales_orders(self):
|
def sales_orders(self):
|
||||||
""" Return a list of sales orders which reference this part """
|
""" Return a list of sales orders which reference this part """
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
|
|
||||||
<hr>
|
<hr>
|
||||||
|
|
||||||
{% include "attachment_table.html" with attachments=part.attachments.all %}
|
{% include "attachment_table.html" with attachments=part.part_attachments %}
|
||||||
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
|
@ -29,6 +29,7 @@
|
|||||||
field: 'pk',
|
field: 'pk',
|
||||||
title: 'ID',
|
title: 'ID',
|
||||||
visible: false,
|
visible: false,
|
||||||
|
switchable: false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
field: 'part_detail',
|
field: 'part_detail',
|
||||||
|
@ -127,7 +127,7 @@ class ReportTemplateBase(models.Model):
|
|||||||
except TexError:
|
except TexError:
|
||||||
return TexResponse(rendered, filename="error.tex")
|
return TexResponse(rendered, filename="error.tex")
|
||||||
else:
|
else:
|
||||||
return ValidationError("Enable LaTeX support in config.yaml")
|
raise ValidationError("Enable LaTeX support in config.yaml")
|
||||||
elif self.extension in ['.htm', '.html']:
|
elif self.extension in ['.htm', '.html']:
|
||||||
# Render HTML template to PDF
|
# Render HTML template to PDF
|
||||||
wp = WeasyprintReportMixin(request, self.template_name, **kwargs)
|
wp = WeasyprintReportMixin(request, self.template_name, **kwargs)
|
||||||
|
@ -186,7 +186,7 @@ class StockCount(StockAdjust):
|
|||||||
|
|
||||||
class StockAdd(StockAdjust):
|
class StockAdd(StockAdjust):
|
||||||
"""
|
"""
|
||||||
Endpoint for adding stock
|
Endpoint for adding a quantity of stock to an existing StockItem
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def post(self, request, *args, **kwargs):
|
def post(self, request, *args, **kwargs):
|
||||||
@ -204,7 +204,7 @@ class StockAdd(StockAdjust):
|
|||||||
|
|
||||||
class StockRemove(StockAdjust):
|
class StockRemove(StockAdjust):
|
||||||
"""
|
"""
|
||||||
Endpoint for removing stock.
|
Endpoint for removing a quantity of stock from an existing StockItem.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def post(self, request, *args, **kwargs):
|
def post(self, request, *args, **kwargs):
|
||||||
|
@ -99,26 +99,10 @@ class StockItemSerializer(InvenTreeModelSerializer):
|
|||||||
|
|
||||||
return queryset
|
return queryset
|
||||||
|
|
||||||
belongs_to = serializers.PrimaryKeyRelatedField(read_only=True)
|
|
||||||
|
|
||||||
build_order = serializers.PrimaryKeyRelatedField(read_only=True)
|
|
||||||
|
|
||||||
customer = serializers.PrimaryKeyRelatedField(read_only=True)
|
|
||||||
|
|
||||||
location = serializers.PrimaryKeyRelatedField(read_only=True)
|
|
||||||
|
|
||||||
in_stock = serializers.BooleanField(read_only=True)
|
|
||||||
|
|
||||||
sales_order = serializers.PrimaryKeyRelatedField(read_only=True)
|
|
||||||
|
|
||||||
status_text = serializers.CharField(source='get_status_display', read_only=True)
|
status_text = serializers.CharField(source='get_status_display', read_only=True)
|
||||||
|
|
||||||
supplier_part = serializers.PrimaryKeyRelatedField(read_only=True)
|
|
||||||
|
|
||||||
supplier_part_detail = SupplierPartSerializer(source='supplier_part', many=False, read_only=True)
|
supplier_part_detail = SupplierPartSerializer(source='supplier_part', many=False, read_only=True)
|
||||||
|
|
||||||
part = serializers.PrimaryKeyRelatedField(read_only=True)
|
|
||||||
|
|
||||||
part_detail = PartBriefSerializer(source='part', many=False, read_only=True)
|
part_detail = PartBriefSerializer(source='part', many=False, read_only=True)
|
||||||
|
|
||||||
location_detail = LocationBriefSerializer(source='location', many=False, read_only=True)
|
location_detail = LocationBriefSerializer(source='location', many=False, read_only=True)
|
||||||
|
@ -73,6 +73,7 @@ $("#add-test-result").click(function() {
|
|||||||
stock_item: {{ item.id }},
|
stock_item: {{ item.id }},
|
||||||
},
|
},
|
||||||
success: reloadTable,
|
success: reloadTable,
|
||||||
|
focus: 'test',
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
@ -89,6 +90,7 @@ $("#test-result-table").on('click', '.button-test-add', function() {
|
|||||||
test: test_name
|
test: test_name
|
||||||
},
|
},
|
||||||
success: reloadTable,
|
success: reloadTable,
|
||||||
|
focus: 'value',
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
@ -81,6 +81,59 @@ class StockItemTest(StockAPITestCase):
|
|||||||
response = self.client.get(self.list_url, format='json')
|
response = self.client.get(self.list_url, format='json')
|
||||||
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
||||||
|
|
||||||
|
def test_stock_item_create(self):
|
||||||
|
"""
|
||||||
|
Test creation of a StockItem via the API
|
||||||
|
"""
|
||||||
|
|
||||||
|
# POST with an empty part reference
|
||||||
|
|
||||||
|
response = self.client.post(
|
||||||
|
self.list_url,
|
||||||
|
data={
|
||||||
|
'quantity': 10,
|
||||||
|
'location': 1
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
self.assertContains(response, 'This field is required', status_code=status.HTTP_400_BAD_REQUEST)
|
||||||
|
|
||||||
|
# POST with an invalid part reference
|
||||||
|
|
||||||
|
response = self.client.post(
|
||||||
|
self.list_url,
|
||||||
|
data={
|
||||||
|
'quantity': 10,
|
||||||
|
'location': 1,
|
||||||
|
'part': 10000000,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
self.assertContains(response, 'does not exist', status_code=status.HTTP_400_BAD_REQUEST)
|
||||||
|
|
||||||
|
# POST without quantity
|
||||||
|
response = self.client.post(
|
||||||
|
self.list_url,
|
||||||
|
data={
|
||||||
|
'part': 1,
|
||||||
|
'location': 1,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
self.assertContains(response, 'This field is required', status_code=status.HTTP_400_BAD_REQUEST)
|
||||||
|
|
||||||
|
# POST with quantity and part and location
|
||||||
|
response = self.client.post(
|
||||||
|
self.list_url,
|
||||||
|
data={
|
||||||
|
'part': 1,
|
||||||
|
'location': 1,
|
||||||
|
'quantity': 10,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
self.assertEqual(response.status_code, status.HTTP_201_CREATED)
|
||||||
|
|
||||||
|
|
||||||
class StocktakeTest(StockAPITestCase):
|
class StocktakeTest(StockAPITestCase):
|
||||||
"""
|
"""
|
||||||
|
@ -37,6 +37,7 @@
|
|||||||
field: 'pk',
|
field: 'pk',
|
||||||
title: 'ID',
|
title: 'ID',
|
||||||
visible: false,
|
visible: false,
|
||||||
|
switchable: false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
field: 'symbol',
|
field: 'symbol',
|
||||||
|
@ -31,6 +31,7 @@
|
|||||||
field: 'pk',
|
field: 'pk',
|
||||||
title: 'ID',
|
title: 'ID',
|
||||||
visible: false,
|
visible: false,
|
||||||
|
switchable: false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
field: 'name',
|
field: 'name',
|
||||||
|
@ -111,6 +111,7 @@ function loadBomTable(table, options) {
|
|||||||
field: 'pk',
|
field: 'pk',
|
||||||
title: 'ID',
|
title: 'ID',
|
||||||
visible: false,
|
visible: false,
|
||||||
|
switchable: false,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
@ -320,6 +321,7 @@ function loadBomTable(table, options) {
|
|||||||
parentIdField: 'parentId',
|
parentIdField: 'parentId',
|
||||||
treeShowField: 'sub_part',
|
treeShowField: 'sub_part',
|
||||||
showColumns: true,
|
showColumns: true,
|
||||||
|
name: 'bom',
|
||||||
sortable: true,
|
sortable: true,
|
||||||
search: true,
|
search: true,
|
||||||
rowStyle: function(row, index) {
|
rowStyle: function(row, index) {
|
||||||
|
@ -21,12 +21,14 @@ function loadBuildTable(table, options) {
|
|||||||
url: options.url,
|
url: options.url,
|
||||||
queryParams: filters,
|
queryParams: filters,
|
||||||
groupBy: false,
|
groupBy: false,
|
||||||
|
name: 'builds',
|
||||||
original: params,
|
original: params,
|
||||||
columns: [
|
columns: [
|
||||||
{
|
{
|
||||||
field: 'pk',
|
field: 'pk',
|
||||||
title: 'ID',
|
title: 'ID',
|
||||||
visible: false,
|
visible: false,
|
||||||
|
switchable: false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
field: 'title',
|
field: 'title',
|
||||||
|
@ -27,16 +27,20 @@ function loadCompanyTable(table, url, options={}) {
|
|||||||
queryParams: filters,
|
queryParams: filters,
|
||||||
groupBy: false,
|
groupBy: false,
|
||||||
formatNoMatches: function() { return "{% trans "No company information found" %}"; },
|
formatNoMatches: function() { return "{% trans "No company information found" %}"; },
|
||||||
|
showColumns: true,
|
||||||
|
name: 'company',
|
||||||
columns: [
|
columns: [
|
||||||
{
|
{
|
||||||
field: 'pk',
|
field: 'pk',
|
||||||
title: 'ID',
|
title: 'ID',
|
||||||
visible: false,
|
visible: false,
|
||||||
|
switchable: false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
field: 'name',
|
field: 'name',
|
||||||
title: '{% trans "Company" %}',
|
title: '{% trans "Company" %}',
|
||||||
sortable: true,
|
sortable: true,
|
||||||
|
switchable: false,
|
||||||
formatter: function(value, row, index, field) {
|
formatter: function(value, row, index, field) {
|
||||||
var html = imageHoverIcon(row.image) + renderLink(value, row.url);
|
var html = imageHoverIcon(row.image) + renderLink(value, row.url);
|
||||||
|
|
||||||
@ -97,11 +101,13 @@ function loadSupplierPartTable(table, url, options) {
|
|||||||
url: url,
|
url: url,
|
||||||
method: 'get',
|
method: 'get',
|
||||||
queryParams: filters,
|
queryParams: filters,
|
||||||
|
name: 'supplierparts',
|
||||||
groupBy: false,
|
groupBy: false,
|
||||||
formatNoMatches: function() { return "{% trans "No supplier parts found" %}"; },
|
formatNoMatches: function() { return "{% trans "No supplier parts found" %}"; },
|
||||||
columns: [
|
columns: [
|
||||||
{
|
{
|
||||||
checkbox: true,
|
checkbox: true,
|
||||||
|
switchable: false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
sortable: true,
|
sortable: true,
|
||||||
|
@ -121,6 +121,7 @@ function loadPurchaseOrderTable(table, options) {
|
|||||||
$(table).inventreeTable({
|
$(table).inventreeTable({
|
||||||
url: options.url,
|
url: options.url,
|
||||||
queryParams: filters,
|
queryParams: filters,
|
||||||
|
name: 'purchaseorder',
|
||||||
groupBy: false,
|
groupBy: false,
|
||||||
original: options.params,
|
original: options.params,
|
||||||
formatNoMatches: function() { return "{% trans "No purchase orders found" %}"; },
|
formatNoMatches: function() { return "{% trans "No purchase orders found" %}"; },
|
||||||
@ -129,6 +130,7 @@ function loadPurchaseOrderTable(table, options) {
|
|||||||
field: 'pk',
|
field: 'pk',
|
||||||
title: 'ID',
|
title: 'ID',
|
||||||
visible: false,
|
visible: false,
|
||||||
|
switchable: false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
sortable: true,
|
sortable: true,
|
||||||
@ -194,6 +196,7 @@ function loadSalesOrderTable(table, options) {
|
|||||||
$(table).inventreeTable({
|
$(table).inventreeTable({
|
||||||
url: options.url,
|
url: options.url,
|
||||||
queryParams: filters,
|
queryParams: filters,
|
||||||
|
name: 'salesorder',
|
||||||
groupBy: false,
|
groupBy: false,
|
||||||
original: options.params,
|
original: options.params,
|
||||||
formatNoMatches: function() { return "{% trans "No sales orders found" %}"; },
|
formatNoMatches: function() { return "{% trans "No sales orders found" %}"; },
|
||||||
@ -202,6 +205,7 @@ function loadSalesOrderTable(table, options) {
|
|||||||
field: 'pk',
|
field: 'pk',
|
||||||
title: 'ID',
|
title: 'ID',
|
||||||
visible: false,
|
visible: false,
|
||||||
|
switchable: false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
sortable: true,
|
sortable: true,
|
||||||
|
@ -237,6 +237,7 @@ function loadPartTable(table, url, options={}) {
|
|||||||
method: 'get',
|
method: 'get',
|
||||||
queryParams: filters,
|
queryParams: filters,
|
||||||
groupBy: false,
|
groupBy: false,
|
||||||
|
name: 'part',
|
||||||
original: params,
|
original: params,
|
||||||
formatNoMatches: function() { return "{% trans "No parts found" %}"; },
|
formatNoMatches: function() { return "{% trans "No parts found" %}"; },
|
||||||
columns: columns,
|
columns: columns,
|
||||||
@ -338,6 +339,7 @@ function loadPartTestTemplateTable(table, options) {
|
|||||||
},
|
},
|
||||||
url: "{% url 'api-part-test-template-list' %}",
|
url: "{% url 'api-part-test-template-list' %}",
|
||||||
queryParams: filters,
|
queryParams: filters,
|
||||||
|
name: 'testtemplate',
|
||||||
original: original,
|
original: original,
|
||||||
columns: [
|
columns: [
|
||||||
{
|
{
|
||||||
|
@ -73,6 +73,7 @@ function loadStockTestResultsTable(table, options) {
|
|||||||
table.inventreeTable({
|
table.inventreeTable({
|
||||||
url: "{% url 'api-part-test-template-list' %}",
|
url: "{% url 'api-part-test-template-list' %}",
|
||||||
method: 'get',
|
method: 'get',
|
||||||
|
name: 'testresult',
|
||||||
formatNoMatches: function() {
|
formatNoMatches: function() {
|
||||||
return "{% trans 'No test results found' %}";
|
return "{% trans 'No test results found' %}";
|
||||||
},
|
},
|
||||||
@ -84,6 +85,7 @@ function loadStockTestResultsTable(table, options) {
|
|||||||
field: 'pk',
|
field: 'pk',
|
||||||
title: 'ID',
|
title: 'ID',
|
||||||
visible: false,
|
visible: false,
|
||||||
|
switchable: false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
field: 'test_name',
|
field: 'test_name',
|
||||||
@ -264,6 +266,7 @@ function loadStockTable(table, options) {
|
|||||||
queryParams: filters,
|
queryParams: filters,
|
||||||
customSort: customGroupSorter,
|
customSort: customGroupSorter,
|
||||||
groupBy: true,
|
groupBy: true,
|
||||||
|
name: 'stock',
|
||||||
original: original,
|
original: original,
|
||||||
showColumns: true,
|
showColumns: true,
|
||||||
groupByField: options.groupByField || 'part',
|
groupByField: options.groupByField || 'part',
|
||||||
@ -405,6 +408,7 @@ function loadStockTable(table, options) {
|
|||||||
checkbox: true,
|
checkbox: true,
|
||||||
title: '{% trans "Select" %}',
|
title: '{% trans "Select" %}',
|
||||||
searchable: false,
|
searchable: false,
|
||||||
|
switchable: false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
field: 'pk',
|
field: 'pk',
|
||||||
|
@ -23,4 +23,6 @@ rapidfuzz==0.7.6 # Fuzzy string matching
|
|||||||
django-stdimage==5.1.1 # Advanced ImageField management
|
django-stdimage==5.1.1 # Advanced ImageField management
|
||||||
django-tex==1.1.7 # LaTeX PDF export
|
django-tex==1.1.7 # LaTeX PDF export
|
||||||
django-weasyprint==1.0.1 # HTML PDF export
|
django-weasyprint==1.0.1 # HTML PDF export
|
||||||
django-debug-toolbar==2.2 # Debug / profiling toolbar
|
django-debug-toolbar==2.2 # Debug / profiling toolbar
|
||||||
|
|
||||||
|
inventree # Install the latest version of the InvenTree API python library
|
6
tasks.py
6
tasks.py
@ -47,7 +47,7 @@ def managePyPath():
|
|||||||
|
|
||||||
return os.path.join(managePyDir(), 'manage.py')
|
return os.path.join(managePyDir(), 'manage.py')
|
||||||
|
|
||||||
def manage(c, cmd):
|
def manage(c, cmd, pty=False):
|
||||||
"""
|
"""
|
||||||
Runs a given command against django's "manage.py" script.
|
Runs a given command against django's "manage.py" script.
|
||||||
|
|
||||||
@ -59,7 +59,7 @@ def manage(c, cmd):
|
|||||||
c.run('cd {path} && python3 manage.py {cmd}'.format(
|
c.run('cd {path} && python3 manage.py {cmd}'.format(
|
||||||
path=managePyDir(),
|
path=managePyDir(),
|
||||||
cmd=cmd
|
cmd=cmd
|
||||||
))
|
), pty=pty)
|
||||||
|
|
||||||
@task(help={'length': 'Length of secret key (default=50)'})
|
@task(help={'length': 'Length of secret key (default=50)'})
|
||||||
def key(c, length=50, force=False):
|
def key(c, length=50, force=False):
|
||||||
@ -106,7 +106,7 @@ def superuser(c):
|
|||||||
Create a superuser (admin) account for the database.
|
Create a superuser (admin) account for the database.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
manage(c, 'createsuperuser')
|
manage(c, 'createsuperuser', pty=True)
|
||||||
|
|
||||||
@task
|
@task
|
||||||
def migrate(c):
|
def migrate(c):
|
||||||
|
Loading…
x
Reference in New Issue
Block a user