mirror of
https://github.com/inventree/InvenTree.git
synced 2025-06-18 13:05:42 +00:00
Merge remote-tracking branch 'inventree/master' into order-parts-wizard
# Conflicts: # InvenTree/templates/js/translated/model_renderers.js
This commit is contained in:
@ -24,6 +24,7 @@
|
||||
{% include "InvenTree/settings/setting.html" with key="ENABLE_PLUGINS_URL" icon="fa-link" %}
|
||||
{% include "InvenTree/settings/setting.html" with key="ENABLE_PLUGINS_NAVIGATION" icon="fa-sitemap" %}
|
||||
{% include "InvenTree/settings/setting.html" with key="ENABLE_PLUGINS_APP" icon="fa-rocket" %}
|
||||
{% include "InvenTree/settings/setting.html" with key="PLUGIN_ON_STARTUP" %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
@ -76,6 +77,12 @@
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
|
||||
{% if plugin.is_sample %}
|
||||
<a class='sidebar-selector' id='select-plugin-{{plugin_key}}' data-bs-parent="#sidebar">
|
||||
<span class='badge bg-info rounded-pill'>{% trans "code sample" %}</span>
|
||||
</a>
|
||||
{% endif %}
|
||||
|
||||
{% if plugin.website %}
|
||||
<a href="{{ plugin.website }}"><span class="fas fa-globe"></span></a>
|
||||
{% endif %}
|
||||
|
@ -89,7 +89,7 @@ $('table').find('.boolean-setting').change(function() {
|
||||
},
|
||||
{
|
||||
method: 'PATCH',
|
||||
onSuccess: function(data) {
|
||||
success: function(data) {
|
||||
},
|
||||
error: function(xhr) {
|
||||
showApiError(xhr, url);
|
||||
|
@ -11,6 +11,7 @@
|
||||
|
||||
<table class='table table-striped table-condensed'>
|
||||
<tbody>
|
||||
{% include "InvenTree/settings/setting.html" with key="STOCK_BATCH_CODE_TEMPLATE" icon="fa-layer-group" %}
|
||||
{% include "InvenTree/settings/setting.html" with key="STOCK_ENABLE_EXPIRY" icon="fa-stopwatch" %}
|
||||
{% include "InvenTree/settings/setting.html" with key="STOCK_STALE_DAYS" icon="fa-calendar" %}
|
||||
{% include "InvenTree/settings/setting.html" with key="STOCK_ALLOW_EXPIRED_SALE" icon="fa-truck" %}
|
||||
|
@ -48,6 +48,7 @@
|
||||
<link rel="stylesheet" href="{% static 'select2/css/select2-bootstrap-5-theme.css' %}">
|
||||
<link rel="stylesheet" href="{% static 'fullcalendar/main.css' %}">
|
||||
<link rel="stylesheet" href="{% static 'script/jquery-ui/jquery-ui.min.css' %}">
|
||||
<link rel="stylesheet" href="{% static 'easymde/easymde.min.css' %}">
|
||||
|
||||
<link rel="stylesheet" href="{% static 'css/inventree.css' %}">
|
||||
|
||||
@ -160,6 +161,7 @@
|
||||
<script type='text/javascript' src="{% static 'script/chart.js' %}"></script>
|
||||
<script type='text/javascript' src="{% static 'script/moment.js' %}"></script>
|
||||
<script type='text/javascript' src="{% static 'script/chartjs-adapter-moment.js' %}"></script>
|
||||
<script type='text/javascript' src="{% static 'easymde/easymde.min.js' %}"></script>
|
||||
|
||||
<script type='text/javascript' src="{% static 'script/clipboard.min.js' %}"></script>
|
||||
<script type='text/javascript' src="{% static 'script/randomColor.min.js' %}"></script>
|
||||
|
@ -798,17 +798,38 @@ function loadBomTable(table, options={}) {
|
||||
});
|
||||
|
||||
cols.push({
|
||||
field: 'sub_part_detail.stock',
|
||||
field: 'available_stock',
|
||||
title: '{% trans "Available" %}',
|
||||
searchable: false,
|
||||
sortable: true,
|
||||
formatter: function(value, row) {
|
||||
|
||||
var url = `/part/${row.sub_part_detail.pk}/?display=part-stock`;
|
||||
var text = value;
|
||||
|
||||
if (value == null || value <= 0) {
|
||||
text = `<span class='badge rounded-pill bg-danger'>{% trans "No Stock" %}</span>`;
|
||||
// Calculate total "available" (unallocated) quantity
|
||||
var base_stock = row.available_stock;
|
||||
var substitute_stock = row.available_substitute_stock || 0;
|
||||
var variant_stock = row.allow_variants ? (row.available_variant_stock || 0) : 0;
|
||||
|
||||
var available_stock = base_stock + substitute_stock + variant_stock;
|
||||
|
||||
var text = `${available_stock}`;
|
||||
|
||||
if (available_stock <= 0) {
|
||||
text = `<span class='badge rounded-pill bg-danger'>{% trans "No Stock Available" %}</span>`;
|
||||
} else {
|
||||
var extra = '';
|
||||
if ((substitute_stock > 0) && (variant_stock > 0)) {
|
||||
extra = '{% trans "Includes variant and substitute stock" %}';
|
||||
} else if (variant_stock > 0) {
|
||||
extra = '{% trans "Includes variant stock" %}';
|
||||
} else if (substitute_stock > 0) {
|
||||
extra = '{% trans "Includes substitute stock" %}';
|
||||
}
|
||||
|
||||
if (extra) {
|
||||
text += `<span title='${extra}' class='fas fa-info-circle float-right icon-blue'></span>`;
|
||||
}
|
||||
}
|
||||
|
||||
return renderLink(text, url);
|
||||
@ -902,8 +923,10 @@ function loadBomTable(table, options={}) {
|
||||
formatter: function(value, row) {
|
||||
var can_build = 0;
|
||||
|
||||
var available = row.available_stock + (row.available_substitute_stock || 0) + (row.available_variant_stock || 0);
|
||||
|
||||
if (row.quantity > 0) {
|
||||
can_build = row.sub_part_detail.stock / row.quantity;
|
||||
can_build = available / row.quantity;
|
||||
}
|
||||
|
||||
return +can_build.toFixed(2);
|
||||
@ -914,11 +937,11 @@ function loadBomTable(table, options={}) {
|
||||
var cb_b = 0;
|
||||
|
||||
if (rowA.quantity > 0) {
|
||||
cb_a = rowA.sub_part_detail.stock / rowA.quantity;
|
||||
cb_a = (rowA.available_stock + rowA.available_substitute_stock) / rowA.quantity;
|
||||
}
|
||||
|
||||
if (rowB.quantity > 0) {
|
||||
cb_b = rowB.sub_part_detail.stock / rowB.quantity;
|
||||
cb_b = (rowB.available_stock + rowB.available_substitute_stock) / rowB.quantity;
|
||||
}
|
||||
|
||||
return (cb_a > cb_b) ? 1 : -1;
|
||||
|
@ -1421,9 +1421,41 @@ function loadBuildOutputAllocationTable(buildInfo, output, options={}) {
|
||||
sortable: true,
|
||||
},
|
||||
{
|
||||
field: 'sub_part_detail.stock',
|
||||
field: 'available_stock',
|
||||
title: '{% trans "Available" %}',
|
||||
sortable: true,
|
||||
formatter: function(value, row) {
|
||||
|
||||
var url = `/part/${row.sub_part_detail.pk}/?display=part-stock`;
|
||||
|
||||
// Calculate total "available" (unallocated) quantity
|
||||
var base_stock = row.available_stock;
|
||||
var substitute_stock = row.available_substitute_stock || 0;
|
||||
var variant_stock = row.allow_variants ? (row.available_variant_stock || 0) : 0;
|
||||
|
||||
var available_stock = base_stock + substitute_stock + variant_stock;
|
||||
|
||||
var text = `${available_stock}`;
|
||||
|
||||
if (available_stock <= 0) {
|
||||
text = `<span class='badge rounded-pill bg-danger'>{% trans "No Stock Available" %}</span>`;
|
||||
} else {
|
||||
var extra = '';
|
||||
if ((substitute_stock > 0) && (variant_stock > 0)) {
|
||||
extra = '{% trans "Includes variant and substitute stock" %}';
|
||||
} else if (variant_stock > 0) {
|
||||
extra = '{% trans "Includes variant stock" %}';
|
||||
} else if (substitute_stock > 0) {
|
||||
extra = '{% trans "Includes substitute stock" %}';
|
||||
}
|
||||
|
||||
if (extra) {
|
||||
text += `<span title='${extra}' class='fas fa-info-circle float-right icon-blue'></span>`;
|
||||
}
|
||||
}
|
||||
|
||||
return renderLink(text, url);
|
||||
}
|
||||
},
|
||||
{
|
||||
field: 'allocated',
|
||||
|
@ -10,6 +10,7 @@
|
||||
makeProgressBar,
|
||||
renderLink,
|
||||
select2Thumbnail,
|
||||
setupNotesField,
|
||||
thumbnailImage
|
||||
yesNoLabel,
|
||||
*/
|
||||
@ -221,3 +222,93 @@ function renderLink(text, url, options={}) {
|
||||
|
||||
return `<a href="${url}">${text}</a>`;
|
||||
}
|
||||
|
||||
|
||||
function setupNotesField(element, url, options={}) {
|
||||
|
||||
var editable = options.editable || false;
|
||||
|
||||
// Read initial notes value from the URL
|
||||
var initial = null;
|
||||
|
||||
inventreeGet(url, {}, {
|
||||
async: false,
|
||||
success: function(response) {
|
||||
initial = response[options.notes_field || 'notes'];
|
||||
},
|
||||
});
|
||||
|
||||
var toolbar_icons = [
|
||||
'preview', '|',
|
||||
];
|
||||
|
||||
if (editable) {
|
||||
// Heading icons
|
||||
toolbar_icons.push('heading-1', 'heading-2', 'heading-3', '|');
|
||||
|
||||
// Font style
|
||||
toolbar_icons.push('bold', 'italic', 'strikethrough', '|');
|
||||
|
||||
// Text formatting
|
||||
toolbar_icons.push('unordered-list', 'ordered-list', 'code', 'quote', '|');
|
||||
|
||||
// Elements
|
||||
toolbar_icons.push('table', 'link', 'image');
|
||||
}
|
||||
|
||||
// Markdown syntax guide
|
||||
toolbar_icons.push('|', 'guide');
|
||||
|
||||
const mde = new EasyMDE({
|
||||
element: document.getElementById(element),
|
||||
initialValue: initial,
|
||||
toolbar: toolbar_icons,
|
||||
shortcuts: [],
|
||||
});
|
||||
|
||||
|
||||
// Hide the toolbar
|
||||
$(`#${element}`).next('.EasyMDEContainer').find('.editor-toolbar').hide();
|
||||
|
||||
if (!editable) {
|
||||
// Set readonly
|
||||
mde.codemirror.setOption('readOnly', true);
|
||||
|
||||
// Hide the "edit" and "save" buttons
|
||||
$('#edit-notes').hide();
|
||||
$('#save-notes').hide();
|
||||
|
||||
} else {
|
||||
mde.togglePreview();
|
||||
|
||||
// Add callback for "edit" button
|
||||
$('#edit-notes').click(function() {
|
||||
$('#edit-notes').hide();
|
||||
$('#save-notes').show();
|
||||
|
||||
// Show the toolbar
|
||||
$(`#${element}`).next('.EasyMDEContainer').find('.editor-toolbar').show();
|
||||
|
||||
mde.togglePreview();
|
||||
});
|
||||
|
||||
// Add callback for "save" button
|
||||
$('#save-notes').click(function() {
|
||||
|
||||
var data = {};
|
||||
|
||||
data[options.notes_field || 'notes'] = mde.value();
|
||||
|
||||
inventreePut(url, data, {
|
||||
method: 'PATCH',
|
||||
success: function(response) {
|
||||
showMessage('{% trans "Notes updated" %}', {style: 'success'});
|
||||
},
|
||||
error: function(xhr) {
|
||||
showApiError(xhr, url);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -99,14 +99,22 @@ function renderStockItem(name, data, parameters={}, options={}) {
|
||||
|
||||
var stock_detail = '';
|
||||
|
||||
if (data.serial && data.quantity == 1) {
|
||||
stock_detail = `{% trans "Serial Number" %}: ${data.serial}`;
|
||||
} else if (data.quantity == 0) {
|
||||
if (data.quantity == 0) {
|
||||
stock_detail = `<span class='badge rounded-pill bg-danger'>{% trans "No Stock"% }</span>`;
|
||||
} else {
|
||||
stock_detail = `{% trans "Quantity" %}: ${data.quantity}`;
|
||||
if (data.serial && data.quantity == 1) {
|
||||
stock_detail = `{% trans "Serial Number" %}: ${data.serial}`;
|
||||
} else {
|
||||
stock_detail = `{% trans "Quantity" %}: ${data.quantity}`;
|
||||
}
|
||||
|
||||
if (data.batch) {
|
||||
stock_detail += ` - <small>{% trans "Batch" %}: ${data.batch}</small>`;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
var html = `
|
||||
<span>
|
||||
${part_detail}
|
||||
@ -193,7 +201,7 @@ function renderPart(name, data, parameters={}, options={}) {
|
||||
<small>
|
||||
${stock_data}
|
||||
${extra}
|
||||
${renderId('{% trans "Part ID" $}', data.pk, parameters)}
|
||||
${renderId('{% trans "Part ID" %}', data.pk, parameters)}
|
||||
</small>
|
||||
</span>`;
|
||||
|
||||
|
@ -171,6 +171,9 @@ function notificationCheck(force = false) {
|
||||
{
|
||||
success: function(response) {
|
||||
updateNotificationIndicator(response.length);
|
||||
},
|
||||
error: function(xhr) {
|
||||
console.warn('Could not access server: /api/notifications');
|
||||
}
|
||||
}
|
||||
);
|
||||
|
@ -293,6 +293,7 @@ function categoryFields() {
|
||||
return {
|
||||
parent: {
|
||||
help_text: '{% trans "Parent part category" %}',
|
||||
required: false,
|
||||
},
|
||||
name: {},
|
||||
description: {},
|
||||
@ -373,6 +374,9 @@ function duplicatePart(pk, options={}) {
|
||||
|
||||
// Override the "variant_of" field
|
||||
data.variant_of = pk;
|
||||
|
||||
// By default, disable "is_template" when making a variant *of* a template
|
||||
data.is_template = false;
|
||||
}
|
||||
|
||||
constructForm('{% url "api-part-list" %}', {
|
||||
@ -668,7 +672,20 @@ function loadPartVariantTable(table, partId, options={}) {
|
||||
field: 'in_stock',
|
||||
title: '{% trans "Stock" %}',
|
||||
formatter: function(value, row) {
|
||||
return renderLink(value, `/part/${row.pk}/?display=part-stock`);
|
||||
|
||||
var base_stock = row.in_stock;
|
||||
var variant_stock = row.variant_stock || 0;
|
||||
|
||||
var total = base_stock + variant_stock;
|
||||
|
||||
var text = `${total}`;
|
||||
|
||||
if (variant_stock > 0) {
|
||||
text = `<em>${text}</em>`;
|
||||
text += `<span title='{% trans "Includes variant stock" %}' class='fas fa-info-circle float-right icon-blue'></span>`;
|
||||
}
|
||||
|
||||
return renderLink(text, `/part/${row.pk}/?display=part-stock`);
|
||||
}
|
||||
}
|
||||
];
|
||||
@ -1900,7 +1917,9 @@ function loadPriceBreakTable(table, options) {
|
||||
formatNoMatches: function() {
|
||||
return `{% trans "No ${human_name} information found" %}`;
|
||||
},
|
||||
queryParams: {part: options.part},
|
||||
queryParams: {
|
||||
part: options.part
|
||||
},
|
||||
url: options.url,
|
||||
onLoadSuccess: function(tableData) {
|
||||
if (linkedGraph) {
|
||||
@ -2006,36 +2025,45 @@ function initPriceBreakSet(table, options) {
|
||||
}
|
||||
|
||||
pb_new_btn.click(function() {
|
||||
launchModalForm(pb_new_url,
|
||||
{
|
||||
success: reloadPriceBreakTable,
|
||||
data: {
|
||||
part: part_id,
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
constructForm(pb_new_url, {
|
||||
fields: {
|
||||
part: {
|
||||
hidden: true,
|
||||
value: part_id,
|
||||
},
|
||||
quantity: {},
|
||||
price: {},
|
||||
price_currency: {},
|
||||
},
|
||||
method: 'POST',
|
||||
title: '{% trans "Add Price Break" %}',
|
||||
onSuccess: reloadPriceBreakTable,
|
||||
});
|
||||
});
|
||||
|
||||
table.on('click', `.button-${pb_url_slug}-delete`, function() {
|
||||
var pk = $(this).attr('pk');
|
||||
|
||||
launchModalForm(
|
||||
`/part/${pb_url_slug}/${pk}/delete/`,
|
||||
{
|
||||
success: reloadPriceBreakTable
|
||||
}
|
||||
);
|
||||
constructForm(`${pb_url}${pk}/`, {
|
||||
method: 'DELETE',
|
||||
title: '{% trans "Delete Price Break" %}',
|
||||
onSuccess: reloadPriceBreakTable,
|
||||
});
|
||||
});
|
||||
|
||||
table.on('click', `.button-${pb_url_slug}-edit`, function() {
|
||||
var pk = $(this).attr('pk');
|
||||
|
||||
launchModalForm(
|
||||
`/part/${pb_url_slug}/${pk}/edit/`,
|
||||
{
|
||||
success: reloadPriceBreakTable
|
||||
}
|
||||
);
|
||||
constructForm(`${pb_url}${pk}/`, {
|
||||
fields: {
|
||||
quantity: {},
|
||||
price: {},
|
||||
price_currency: {},
|
||||
},
|
||||
title: '{% trans "Edit Price Break" %}',
|
||||
onSuccess: reloadPriceBreakTable,
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -107,6 +107,7 @@ function stockLocationFields(options={}) {
|
||||
var fields = {
|
||||
parent: {
|
||||
help_text: '{% trans "Parent stock location" %}',
|
||||
required: false,
|
||||
},
|
||||
name: {},
|
||||
description: {},
|
||||
@ -240,9 +241,11 @@ function stockItemFields(options={}) {
|
||||
serial: {
|
||||
icon: 'fa-hashtag',
|
||||
},
|
||||
batch: {
|
||||
icon: 'fa-layer-group',
|
||||
},
|
||||
status: {},
|
||||
expiry_date: {},
|
||||
batch: {},
|
||||
purchase_price: {
|
||||
icon: 'fa-dollar-sign',
|
||||
},
|
||||
@ -963,6 +966,10 @@ function adjustStock(action, items, options={}) {
|
||||
quantity = `#${item.serial}`;
|
||||
}
|
||||
|
||||
if (item.batch) {
|
||||
quantity += ` - <small>{% trans "Batch" %}: ${item.batch}</small>`;
|
||||
}
|
||||
|
||||
var actionInput = '';
|
||||
|
||||
if (actionTitle != null) {
|
||||
@ -1331,14 +1338,27 @@ function loadStockTestResultsTable(table, options) {
|
||||
});
|
||||
|
||||
// Once the test template data are loaded, query for test results
|
||||
|
||||
var filters = loadTableFilters(filterKey);
|
||||
|
||||
var query_params = {
|
||||
stock_item: options.stock_item,
|
||||
user_detail: true,
|
||||
attachment_detail: true,
|
||||
ordering: '-date',
|
||||
};
|
||||
|
||||
if ('result' in filters) {
|
||||
query_params.result = filters.result;
|
||||
}
|
||||
|
||||
if ('include_installed' in filters) {
|
||||
query_params.include_installed = filters.include_installed;
|
||||
}
|
||||
|
||||
inventreeGet(
|
||||
'{% url "api-stock-test-result-list" %}',
|
||||
{
|
||||
stock_item: options.stock_item,
|
||||
user_detail: true,
|
||||
attachment_detail: true,
|
||||
ordering: '-date',
|
||||
},
|
||||
query_params,
|
||||
{
|
||||
success: function(data) {
|
||||
// Iterate through the returned test data
|
||||
@ -2301,6 +2321,23 @@ function loadStockTrackingTable(table, options) {
|
||||
|
||||
var cols = [];
|
||||
|
||||
var filterTarget = '#filter-list-stocktracking';
|
||||
|
||||
var filterKey = 'stocktracking';
|
||||
|
||||
var filters = loadTableFilters(filterKey);
|
||||
|
||||
var params = options.params;
|
||||
|
||||
var original = {};
|
||||
|
||||
for (var k in params) {
|
||||
original[k] = params[k];
|
||||
filters[k] = params[k];
|
||||
}
|
||||
|
||||
setupFilterList(filterKey, table, filterTarget);
|
||||
|
||||
// Date
|
||||
cols.push({
|
||||
field: 'date',
|
||||
@ -2338,6 +2375,19 @@ function loadStockTrackingTable(table, options) {
|
||||
return html;
|
||||
}
|
||||
|
||||
// Part information
|
||||
if (details.part) {
|
||||
html += `<tr><th>{% trans "Part" %}</th><td>`;
|
||||
|
||||
if (details.part_detail) {
|
||||
html += renderLink(details.part_detail.full_name, `/part/${details.part}/`);
|
||||
} else {
|
||||
html += `{% trans "Part information unavailable" %}`;
|
||||
}
|
||||
|
||||
html += `</td></tr>`;
|
||||
}
|
||||
|
||||
// Location information
|
||||
if (details.location) {
|
||||
|
||||
@ -2475,27 +2525,10 @@ function loadStockTrackingTable(table, options) {
|
||||
}
|
||||
});
|
||||
|
||||
/*
|
||||
// 2021-05-11 - Ability to edit or delete StockItemTracking entries is now removed
|
||||
cols.push({
|
||||
sortable: false,
|
||||
formatter: function(value, row, index, field) {
|
||||
// Manually created entries can be edited or deleted
|
||||
if (false && !row.system) {
|
||||
var bEdit = "<button title='{% trans 'Edit tracking entry' %}' class='btn btn-entry-edit btn-outline-secondary' type='button' url='/stock/track/" + row.pk + "/edit/'><span class='fas fa-edit'/></button>";
|
||||
var bDel = "<button title='{% trans 'Delete tracking entry' %}' class='btn btn-entry-delete btn-outline-secondary' type='button' url='/stock/track/" + row.pk + "/delete/'><span class='fas fa-trash-alt icon-red'/></button>";
|
||||
|
||||
return "<div class='btn-group' role='group'>" + bEdit + bDel + "</div>";
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
});
|
||||
*/
|
||||
|
||||
table.inventreeTable({
|
||||
method: 'get',
|
||||
queryParams: options.params,
|
||||
queryParams: filters,
|
||||
original: original,
|
||||
columns: cols,
|
||||
url: options.url,
|
||||
});
|
||||
@ -2626,7 +2659,8 @@ function installStockItem(stock_item_id, part_id, options={}) {
|
||||
<ul>
|
||||
<li>{% trans "The Stock Item links to a Part which is the BOM for this Stock Item" %}</li>
|
||||
<li>{% trans "The Stock Item is currently available in stock" %}</li>
|
||||
<li>{% trans "The Stock Item is serialized and does not belong to another item" %}</li>
|
||||
<li>{% trans "The Stock Item is not already installed in another item" %}</li>
|
||||
<li>{% trans "The Stock Item is tracked by either a batch code or serial number" %}</li>
|
||||
</ul>
|
||||
</div>`;
|
||||
|
||||
@ -2652,7 +2686,7 @@ function installStockItem(stock_item_id, part_id, options={}) {
|
||||
filters: {
|
||||
part_detail: true,
|
||||
in_stock: true,
|
||||
serialized: true,
|
||||
tracked: true,
|
||||
},
|
||||
adjustFilters: function(filters, opts) {
|
||||
var part = getFormFieldValue('part', {}, opts);
|
||||
|
@ -234,10 +234,19 @@ function getAvailableTableFilters(tableKey) {
|
||||
title: '{% trans "Stock status" %}',
|
||||
description: '{% trans "Stock status" %}',
|
||||
},
|
||||
has_batch: {
|
||||
title: '{% trans "Has batch code" %}',
|
||||
type: 'bool',
|
||||
},
|
||||
batch: {
|
||||
title: '{% trans "Batch" %}',
|
||||
description: '{% trans "Batch code" %}',
|
||||
},
|
||||
tracked: {
|
||||
title: '{% trans "Tracked" %}',
|
||||
description: '{% trans "Stock item is tracked by either batch code or serial number" %}',
|
||||
type: 'bool',
|
||||
},
|
||||
has_purchase_price: {
|
||||
type: 'bool',
|
||||
title: '{% trans "Has purchase price" %}',
|
||||
@ -265,7 +274,16 @@ function getAvailableTableFilters(tableKey) {
|
||||
|
||||
// Filters for the 'stock test' table
|
||||
if (tableKey == 'stocktests') {
|
||||
return {};
|
||||
return {
|
||||
result: {
|
||||
type: 'bool',
|
||||
title: '{% trans "Test Passed" %}',
|
||||
},
|
||||
include_installed: {
|
||||
type: 'bool',
|
||||
title: '{% trans "Include Installed Items" %}',
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// Filters for the 'part test template' table
|
||||
|
8
InvenTree/templates/notes_buttons.html
Normal file
8
InvenTree/templates/notes_buttons.html
Normal file
@ -0,0 +1,8 @@
|
||||
{% load i18n %}
|
||||
|
||||
<button type='button' id='edit-notes' title='{% trans "Edit" %}' class='btn btn-primary'>
|
||||
<span class='fas fa-edit'></span> {% trans "Edit" %}
|
||||
</button>
|
||||
<button type='button' id='save-notes' title='{% trans "Save" %}' class='btn btn-success' style='display: none;'>
|
||||
<span class='fas fa-save'></span> {% trans "Save" %}
|
||||
</button>
|
Reference in New Issue
Block a user