2
0
mirror of https://github.com/inventree/InvenTree.git synced 2025-04-28 11:36:44 +00:00

JS translation fix (#6288) (#6289)

* Implement {% jstrans %} template

- Forces string escaping in translated text
- Required for js written in templates

* Fix part_base.html

* Update .html files

- Change any templated javascript code to use {% jstrans %}

* Update .js files

- Explicitly use {% jstrans %}

* Update CI checks
This commit is contained in:
Oliver 2024-01-19 13:37:48 +11:00 committed by GitHub
parent 3a37947dbb
commit 774d0f50fd
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
49 changed files with 1690 additions and 1664 deletions

View File

@ -270,7 +270,7 @@ src="{% static 'img/blank_image.png' %}"
'{% url "api-build-detail" build.pk %}', '{% url "api-build-detail" build.pk %}',
{ {
method: 'DELETE', method: 'DELETE',
title: '{% trans "Delete Build Order" %}', title: '{% jstrans "Delete Build Order" %}',
redirect: "{% url 'build-index' %}", redirect: "{% url 'build-index' %}",
} }
); );
@ -280,7 +280,7 @@ src="{% static 'img/blank_image.png' %}"
<!-- Barcode functionality callbacks --> <!-- Barcode functionality callbacks -->
$('#show-qr-code').click(function() { $('#show-qr-code').click(function() {
showQRDialog( showQRDialog(
'{% trans "Build Order QR Code" %}', '{% jstrans "Build Order QR Code" %}',
'{"build": {{ build.pk }} }' '{"build": {{ build.pk }} }'
); );
}); });
@ -292,7 +292,7 @@ src="{% static 'img/blank_image.png' %}"
build: {{ build.pk }}, build: {{ build.pk }},
}, },
{ {
title: '{% trans "Link Barcode to Build Order" %}', title: '{% jstrans "Link Barcode to Build Order" %}',
} }
); );
}); });

View File

@ -419,8 +419,8 @@ function allocateSelectedLines() {
if (unallocated_lines.length == 0) { if (unallocated_lines.length == 0) {
showAlertDialog( showAlertDialog(
'{% trans "Allocation Complete" %}', '{% jstrans "Allocation Complete" %}',
'{% trans "All lines have been fully allocated" %}', '{% jstrans "All lines have been fully allocated" %}',
); );
} else { } else {

View File

@ -159,7 +159,7 @@
$('#company-delete').click(function() { $('#company-delete').click(function() {
constructForm('{% url "api-company-detail" company.pk %}', { constructForm('{% url "api-company-detail" company.pk %}', {
method: 'DELETE', method: 'DELETE',
title: '{% trans "Delete Company" %}', title: '{% jstrans "Delete Company" %}',
redirect: '{% url "company-index" %}', redirect: '{% url "company-index" %}',
}); });
}); });
@ -202,10 +202,10 @@
$('#company-image-delete').click(function(event) { $('#company-image-delete').click(function(event) {
event.stopPropagation(); event.stopPropagation();
showQuestionDialog( showQuestionDialog(
'{% trans "Remove Image" %}', '{% jstrans "Remove Image" %}',
'{% trans "Remove associated image from this company" %}', '{% jstrans "Remove associated image from this company" %}',
{ {
accept_text: '{% trans "Remove" %}', accept_text: '{% jstrans "Remove" %}',
submitClass: 'danger', submitClass: 'danger',
accept: function() { accept: function() {
inventreePut( inventreePut(
@ -234,7 +234,7 @@
fields: { fields: {
image: {}, image: {},
}, },
title: '{% trans "Upload Image" %}', title: '{% jstrans "Upload Image" %}',
onSuccess: function(data) { onSuccess: function(data) {
reloadImage(data); reloadImage(data);
} }
@ -249,7 +249,7 @@
'{% url "api-company-detail" company.pk %}', '{% url "api-company-detail" company.pk %}',
{ {
method: 'PATCH', method: 'PATCH',
title: '{% trans "Download Image" %}', title: '{% jstrans "Download Image" %}',
fields: { fields: {
remote_image: {}, remote_image: {},
}, },

View File

@ -203,7 +203,7 @@ $('#parameter-create').click(function() {
hidden: true, hidden: true,
} }
}, },
title: '{% trans "Add Parameter" %}', title: '{% jstrans "Add Parameter" %}',
refreshTable: '#parameter-table', refreshTable: '#parameter-table',
}); });
}); });

View File

@ -273,7 +273,7 @@ src="{% static 'img/blank_image.png' %}"
$("#show-qr-code").click(function() { $("#show-qr-code").click(function() {
showQRDialog( showQRDialog(
'{% trans "Supplier Part QR Code" %}', '{% jstrans "Supplier Part QR Code" %}',
'{"supplierpart": {{ part.pk }} }' '{"supplierpart": {{ part.pk }} }'
); );
}); });
@ -284,7 +284,7 @@ $("#barcode-link").click(function() {
supplierpart: {{ part.pk }}, supplierpart: {{ part.pk }},
}, },
{ {
title: '{% trans "Link Barcode to Supplier Part" %}', title: '{% jstrans "Link Barcode to Supplier Part" %}',
} }
); );
}); });
@ -356,7 +356,7 @@ $('#update-part-availability').click(function() {
fields: { fields: {
available: {}, available: {},
}, },
title: '{% trans "Update Part Availability" %}', title: '{% jstrans "Update Part Availability" %}',
onSuccess: function() { onSuccess: function() {
location.reload(); location.reload();
} }

View File

@ -315,7 +315,7 @@ $("#export-order").click(function() {
<!-- Barcode functionality callbacks --> <!-- Barcode functionality callbacks -->
$('#show-qr-code').click(function() { $('#show-qr-code').click(function() {
showQRDialog( showQRDialog(
'{% trans "Purchase Order QR Code" %}', '{% jstrans "Purchase Order QR Code" %}',
'{"purchaseorder": {{ order.pk }} }' '{"purchaseorder": {{ order.pk }} }'
); );
}); });
@ -327,7 +327,7 @@ $("#barcode-link").click(function() {
purchaseorder: {{ order.pk }}, purchaseorder: {{ order.pk }},
}, },
{ {
title: '{% trans "Link Barcode to Purchase Order" %}', title: '{% jstrans "Link Barcode to Purchase Order" %}',
} }
); );
}); });

View File

@ -260,7 +260,7 @@ $('#print-order-report').click(function() {
<!-- Barcode functionality callbacks --> <!-- Barcode functionality callbacks -->
$('#show-qr-code').click(function() { $('#show-qr-code').click(function() {
showQRDialog( showQRDialog(
'{% trans "Return Order QR Code" %}', '{% jstrans "Return Order QR Code" %}',
'{"returnorder": {{ order.pk }} }' '{"returnorder": {{ order.pk }} }'
); );
}); });
@ -272,7 +272,7 @@ $("#barcode-link").click(function() {
returnorder: {{ order.pk }}, returnorder: {{ order.pk }},
}, },
{ {
title: '{% trans "Link Barcode to Return Order" %}', title: '{% jstrans "Link Barcode to Return Order" %}',
} }
); );
}); });

View File

@ -309,7 +309,7 @@ $('#print-order-report').click(function() {
<!-- Barcode functionality callbacks --> <!-- Barcode functionality callbacks -->
$('#show-qr-code').click(function() { $('#show-qr-code').click(function() {
showQRDialog( showQRDialog(
'{% trans "Sales Order QR Code" %}', '{% jstrans "Sales Order QR Code" %}',
'{"salesorder": {{ order.pk }} }' '{"salesorder": {{ order.pk }} }'
); );
}); });
@ -321,7 +321,7 @@ $("#barcode-link").click(function() {
salesorder: {{ order.pk }}, salesorder: {{ order.pk }},
}, },
{ {
title: '{% trans "Link Barcode to Sales Order" %}', title: '{% jstrans "Link Barcode to Sales Order" %}',
} }
); );
}); });

View File

@ -656,7 +656,7 @@
value: {{ part.pk }}, value: {{ part.pk }},
}, },
part_2: { part_2: {
label: '{% trans "Related Part" %}', label: '{% jstrans "Related Part" %}',
filters: { filters: {
exclude_id: {{ part.pk }}, exclude_id: {{ part.pk }},
exclude_related: {{ part.pk }}, exclude_related: {{ part.pk }},
@ -664,7 +664,7 @@
} }
}, },
focus: 'part_2', focus: 'part_2',
title: '{% trans "Add Related Part" %}', title: '{% jstrans "Add Related Part" %}',
refreshTable: '#related-parts-table', refreshTable: '#related-parts-table',
}); });
}); });
@ -749,7 +749,7 @@
fields: partTestTemplateFields({ fields: partTestTemplateFields({
part: {{ part.pk }} part: {{ part.pk }}
}), }),
title: '{% trans "Add Test Result Template" %}', title: '{% jstrans "Add Test Result Template" %}',
refreshTable: '#test-template-table', refreshTable: '#test-template-table',
}); });
}); });

View File

@ -441,7 +441,7 @@
{% if barcodes %} {% if barcodes %}
$("#show-qr-code").click(function() { $("#show-qr-code").click(function() {
showQRDialog( showQRDialog(
'{% trans "Part QR Code" %}', '{% jstrans "Part QR Code" %}',
'{"part": {{ part.pk }} }', '{"part": {{ part.pk }} }',
); );
}); });
@ -458,7 +458,7 @@
part: {{ part.pk }}, part: {{ part.pk }},
}, },
{ {
title: '{% trans "Link Barcode to Part" %}', title: '{% jstrans "Link Barcode to Part" %}',
} }
); );
}); });
@ -469,7 +469,7 @@
printLabels({ printLabels({
items: [{{ part.pk }}], items: [{{ part.pk }}],
key: 'part', key: 'part',
singular_name: '{% trans "part" %}', singular_name: 'part',
url: '{% url "api-part-label-list" %}', url: '{% url "api-part-label-list" %}',
}); });
}); });
@ -509,7 +509,7 @@
launchModalForm( launchModalForm(
"{% url 'part-pricing' part.id %}", "{% url 'part-pricing' part.id %}",
{ {
submit_text: '{% trans "Calculate" %}', submit_text: '{% jstrans "Calculate" %}',
hideErrorMessage: true, hideErrorMessage: true,
} }
); );
@ -525,10 +525,10 @@
$('#part-image-delete').click(function(event) { $('#part-image-delete').click(function(event) {
event.stopPropagation(); event.stopPropagation();
showQuestionDialog( showQuestionDialog(
'{% trans "Remove Image" %}', '{% jstrans "Remove Image" %}',
'{% trans "Remove associated image from this part" %}', '{% jstrans "Remove associated image from this part" %}',
{ {
accept_text: '{% trans "Remove" %}', accept_text: '{% jstrans "Remove" %}',
submitClass: 'danger', submitClass: 'danger',
accept: function() { accept: function() {
inventreePut( inventreePut(
@ -557,7 +557,7 @@
fields: { fields: {
image: {}, image: {},
}, },
title: '{% trans "Upload Image" %}', title: '{% jstrans "Upload Image" %}',
onSuccess: function(data) { onSuccess: function(data) {
reloadImage(data); reloadImage(data);
} }
@ -577,7 +577,7 @@
sidePagination: 'server', sidePagination: 'server',
singleSelect: true, singleSelect: true,
formatNoMatches: function() { formatNoMatches: function() {
return '{% trans "No matching images found" %}'; return '{% jstrans "No matching images found" %}';
}, },
columns: [ columns: [
{ {
@ -611,7 +611,7 @@
'{% url "api-part-detail" part.pk %}', '{% url "api-part-detail" part.pk %}',
{ {
method: 'PATCH', method: 'PATCH',
title: '{% trans "Download Image" %}', title: '{% jstrans "Download Image" %}',
fields: { fields: {
remote_image: {}, remote_image: {},
}, },
@ -673,13 +673,13 @@
// Callback function when the "part details" panel is shown // Callback function when the "part details" panel is shown
$('#collapse-part-details').on('show.bs.collapse', function() { $('#collapse-part-details').on('show.bs.collapse', function() {
$('#toggle-details-button').html('{% trans "Hide Part Details" %}'); $('#toggle-details-button').html('{% jstrans "Hide Part Details" %}');
inventreeSave('show-part-details', true); inventreeSave('show-part-details', true);
}); });
// Callback function when the "part details" panel is hidden // Callback function when the "part details" panel is hidden
$('#collapse-part-details').on('hide.bs.collapse', function() { $('#collapse-part-details').on('hide.bs.collapse', function() {
$('#toggle-details-button').html('{% trans "Show Part Details" %}'); $('#toggle-details-button').html('{% jstrans "Show Part Details" %}');
inventreeSave('show-part-details', false); inventreeSave('show-part-details', false);
}); });

View File

@ -21,7 +21,7 @@ $('#part-pricing-refresh').click(function() {
$('#part-pricing-edit').click(function() { $('#part-pricing-edit').click(function() {
constructForm('{% url "api-part-pricing" part.pk %}', { constructForm('{% url "api-part-pricing" part.pk %}', {
title: '{% trans "Update Pricing" %}', title: '{% jstrans "Update Pricing" %}',
fields: { fields: {
override_min: {}, override_min: {},
override_min_currency: {}, override_min_currency: {},

View File

@ -27,6 +27,14 @@ def translation_stats(lang_code):
class CustomTranslateNode(TranslateNode): class CustomTranslateNode(TranslateNode):
"""Custom translation node class, which sanitizes the translated strings for javascript use""" """Custom translation node class, which sanitizes the translated strings for javascript use"""
def __init__(self, filter_expression, noop, asvar, message_context, escape=False):
"""Custom constructor for TranslateNode class.
- Adds an 'escape' argument, which is passed to the render function
"""
super().__init__(filter_expression, noop, asvar, message_context)
self.escape = escape
def render(self, context): def render(self, context):
"""Custom render function overrides / extends default behaviour""" """Custom render function overrides / extends default behaviour"""
result = super().render(context) result = super().render(context)
@ -41,18 +49,21 @@ class CustomTranslateNode(TranslateNode):
for c in ['\\', '`', ';', '|', '&']: for c in ['\\', '`', ';', '|', '&']:
result = result.replace(c, '') result = result.replace(c, '')
# Escape any quotes contained in the string # Escape any quotes contained in the string, if the request is for a javascript file
result = result.replace("'", r"\'") request = context.get('request', None)
if self.escape or (request and request.path.endswith('.js')):
result = result.replace("'", r'\'')
result = result.replace('"', r'\"') result = result.replace('"', r'\"')
# Return the 'clean' resulting string # Return the 'clean' resulting string
return result return result
@register.tag("translate") @register.tag('translate')
@register.tag("trans") @register.tag('trans')
def do_translate(parser, token): def do_translate(parser, token, escape=False):
"""Custom translation function, lifted from https://github.com/django/django/blob/main/django/templatetags/i18n.py """Custom translation function.
The only difference is that we pass this to our custom rendering node class The only difference is that we pass this to our custom rendering node class
""" """
@ -109,7 +120,21 @@ def do_translate(parser, token):
) )
seen.add(option) seen.add(option)
return CustomTranslateNode(message_string, noop, asvar, message_context) return CustomTranslateNode(
message_string, noop, asvar, message_context, escape=escape
)
@register.tag('jstrans')
def do_jstrans(parser, token):
"""Custom translation function for javascript strings.
- Usage: {% jstrans "String to translate" %}
- Performs the same function as the 'trans' tag, but also escapes the translated string.
- Explicitly required for javascript code within a .html template
- Note: Any {% trans %} tag is automatically escaped in a .js file
"""
return do_translate(parser, token, escape=True)
# Re-register tags which we have not explicitly overridden # Re-register tags which we have not explicitly overridden

View File

@ -276,7 +276,7 @@
}, },
multi_delete: true, multi_delete: true,
method: 'DELETE', method: 'DELETE',
title: '{% trans "Delete Test Data" %}', title: '{% jstrans "Delete Test Data" %}',
preFormContent: html, preFormContent: html,
refreshTable: '#test-result-table', refreshTable: '#test-result-table',
}); });
@ -293,7 +293,7 @@
fields: stockItemTestResultFields({ fields: stockItemTestResultFields({
stock_item: {{ item.pk }}, stock_item: {{ item.pk }},
}), }),
title: '{% trans "Add Test Result" %}', title: '{% jstrans "Add Test Result" %}',
refreshTable: '#test-result-table', refreshTable: '#test-result-table',
}); });
}); });

View File

@ -504,7 +504,7 @@ $("#stock-test-report").click(function() {
$("#print-label").click(function() { $("#print-label").click(function() {
printLabels({ printLabels({
items: [{{ item.pk }}], items: [{{ item.pk }}],
singular_name: '{% trans "stock item" %}', singular_name: '{% jstrans "stock item" %}',
url: '{% url "api-stockitem-label-list" %}', url: '{% url "api-stockitem-label-list" %}',
key: 'item', key: 'item',
}); });
@ -529,7 +529,7 @@ $('#stock-edit-status').click(function () {
status: {}, status: {},
}, },
reload: true, reload: true,
title: '{% trans "Edit Stock Status" %}', title: '{% jstrans "Edit Stock Status" %}',
}); });
}); });
@ -538,7 +538,7 @@ $('#stock-edit-status').click(function () {
{% if barcodes %} {% if barcodes %}
$("#show-qr-code").click(function() { $("#show-qr-code").click(function() {
showQRDialog( showQRDialog(
'{% trans "Stock Item QR Code" %}', '{% jstrans "Stock Item QR Code" %}',
'{"stockitem": {{ item.pk }} }', '{"stockitem": {{ item.pk }} }',
); );
}); });
@ -549,7 +549,7 @@ $("#barcode-link").click(function() {
stockitem: {{ item.pk }}, stockitem: {{ item.pk }},
}, },
{ {
title: '{% trans "Link Barcode to Stock Item" %}', title: '{% jstrans "Link Barcode to Stock Item" %}',
} }
); );
}); });
@ -625,7 +625,7 @@ $("#stock-convert").click(function() {
'{% url "api-stock-item-convert" item.pk %}', '{% url "api-stock-item-convert" item.pk %}',
{ {
method: 'POST', method: 'POST',
title: '{% trans "Convert Stock Item" %}', title: '{% jstrans "Convert Stock Item" %}',
preFormContent: html, preFormContent: html,
reload: true, reload: true,
fields: { fields: {
@ -659,7 +659,7 @@ $("#stock-return-from-customer").click(function() {
}, },
}, },
method: 'POST', method: 'POST',
title: '{% trans "Return to Stock" %}', title: '{% jstrans "Return to Stock" %}',
reload: true, reload: true,
}); });

View File

@ -286,7 +286,7 @@
printLabels({ printLabels({
items: locs, items: locs,
singular_name: '{% trans "stock location" %}', singular_name: '{% jstrans "stock location" %}',
key: 'location', key: 'location',
url: '{% url "api-stocklocation-label-list" %}', url: '{% url "api-stocklocation-label-list" %}',
}); });
@ -314,7 +314,7 @@
{ {
onSuccess: function() { onSuccess: function() {
showMessage( showMessage(
'{% trans "Scanned stock container into this location" %}', '{% jstrans "Scanned stock container into this location" %}',
{ {
style: 'success', style: 'success',
} }
@ -387,7 +387,7 @@
{% if barcodes %} {% if barcodes %}
$('#show-qr-code').click(function() { $('#show-qr-code').click(function() {
showQRDialog( showQRDialog(
'{% trans "Stock Location QR Code" %}', '{% jstrans "Stock Location QR Code" %}',
'{"stocklocation": {{ location.pk }} }' '{"stocklocation": {{ location.pk }} }'
); );
}); });
@ -398,7 +398,7 @@
stocklocation: {{ location.pk }}, stocklocation: {{ location.pk }},
}, },
{ {
title: '{% trans "Link Barcode to Stock Location" %}', title: '{% jstrans "Link Barcode to Stock Location" %}',
} }
); );
}); });

View File

@ -33,10 +33,10 @@
{% to_list setting_part_starred setting_part_latest setting_bom_validation as settings_list_part %} {% to_list setting_part_starred setting_part_latest setting_bom_validation as settings_list_part %}
{% if roles.part.view and True in settings_list_part %} {% if roles.part.view and True in settings_list_part %}
addHeaderTitle('{% trans "Parts" %}'); addHeaderTitle('{% jstrans "Parts" %}');
{% if setting_part_starred %} {% if setting_part_starred %}
addHeaderAction('starred-parts', '{% trans "Subscribed Parts" %}', 'fa-bell'); addHeaderAction('starred-parts', '{% jstrans "Subscribed Parts" %}', 'fa-bell');
loadSimplePartTable("#table-starred-parts", "{% url 'api-part-list' %}", { loadSimplePartTable("#table-starred-parts", "{% url 'api-part-list' %}", {
name: 'starred-parts', name: 'starred-parts',
params: { params: {
@ -49,7 +49,7 @@ loadSimplePartTable("#table-starred-parts", "{% url 'api-part-list' %}", {
{% endif %} {% endif %}
{% if setting_category_starred %} {% if setting_category_starred %}
addHeaderAction('starred-categories', '{% trans "Subscribed Categories" %}', 'fa-bell'); addHeaderAction('starred-categories', '{% jstrans "Subscribed Categories" %}', 'fa-bell');
loadPartCategoryTable($('#table-starred-categories'), { loadPartCategoryTable($('#table-starred-categories'), {
params: { params: {
starred: true, starred: true,
@ -59,7 +59,7 @@ loadPartCategoryTable($('#table-starred-categories'), {
{% endif %} {% endif %}
{% if setting_part_latest %} {% if setting_part_latest %}
addHeaderAction('latest-parts', '{% trans "Latest Parts" %}', 'fa-newspaper'); addHeaderAction('latest-parts', '{% jstrans "Latest Parts" %}', 'fa-newspaper');
loadSimplePartTable("#table-latest-parts", "{% url 'api-part-list' %}", { loadSimplePartTable("#table-latest-parts", "{% url 'api-part-list' %}", {
name: 'latest-parts', name: 'latest-parts',
params: { params: {
@ -74,7 +74,7 @@ loadSimplePartTable("#table-latest-parts", "{% url 'api-part-list' %}", {
{% endif %} {% endif %}
{% if setting_bom_validation %} {% if setting_bom_validation %}
addHeaderAction('bom-validation', '{% trans "BOM Waiting Validation" %}', 'fa-times-circle'); addHeaderAction('bom-validation', '{% jstrans "BOM Waiting Validation" %}', 'fa-times-circle');
loadSimplePartTable("#table-bom-validation", "{% url 'api-part-list' %}", { loadSimplePartTable("#table-bom-validation", "{% url 'api-part-list' %}", {
name: 'parts-invalid-bom', name: 'parts-invalid-bom',
params: { params: {
@ -103,7 +103,7 @@ loadSimplePartTable("#table-bom-validation", "{% url 'api-part-list' %}", {
{% if roles.stock.view %} {% if roles.stock.view %}
{% if setting_stock_recent %} {% if setting_stock_recent %}
addHeaderAction('recently-updated-stock', '{% trans "Recently Updated" %}', 'fa-clock'); addHeaderAction('recently-updated-stock', '{% jstrans "Recently Updated" %}', 'fa-clock');
loadStockTable($('#table-recently-updated-stock'), { loadStockTable($('#table-recently-updated-stock'), {
disableFilters: true, disableFilters: true,
params: { params: {
@ -117,7 +117,7 @@ loadStockTable($('#table-recently-updated-stock'), {
{% endif %} {% endif %}
{% if setting_stock_low %} {% if setting_stock_low %}
addHeaderAction('low-stock', '{% trans "Low Stock" %}', 'fa-flag'); addHeaderAction('low-stock', '{% jstrans "Low Stock" %}', 'fa-flag');
loadSimplePartTable("#table-low-stock", "{% url 'api-part-list' %}", { loadSimplePartTable("#table-low-stock", "{% url 'api-part-list' %}", {
name: 'parts-low-stock', name: 'parts-low-stock',
params: { params: {
@ -131,7 +131,7 @@ loadSimplePartTable("#table-low-stock", "{% url 'api-part-list' %}", {
{% endif %} {% endif %}
{% if setting_stock_depleted %} {% if setting_stock_depleted %}
addHeaderAction('depleted-stock', '{% trans "Depleted Stock" %}', 'fa-times'); addHeaderAction('depleted-stock', '{% jstrans "Depleted Stock" %}', 'fa-times');
loadSimplePartTable("#table-depleted-stock", "{% url 'api-part-list' %}", { loadSimplePartTable("#table-depleted-stock", "{% url 'api-part-list' %}", {
name: 'parts-depleted-stock', name: 'parts-depleted-stock',
params: { params: {
@ -145,7 +145,7 @@ loadSimplePartTable("#table-depleted-stock", "{% url 'api-part-list' %}", {
{% endif %} {% endif %}
{% if setting_stock_needed %} {% if setting_stock_needed %}
addHeaderAction('stock-to-build', '{% trans "Required for Build Orders" %}', 'fa-bullhorn'); addHeaderAction('stock-to-build', '{% jstrans "Required for Build Orders" %}', 'fa-bullhorn');
loadRequiredForBuildsPartsTable("#table-stock-to-build", {}); loadRequiredForBuildsPartsTable("#table-stock-to-build", {});
{% endif %} {% endif %}
@ -153,7 +153,7 @@ loadRequiredForBuildsPartsTable("#table-stock-to-build", {});
{% if expiry %} {% if expiry %}
{% if setting_stock_expired %} {% if setting_stock_expired %}
addHeaderAction('expired-stock', '{% trans "Expired Stock" %}', 'fa-calendar-times'); addHeaderAction('expired-stock', '{% jstrans "Expired Stock" %}', 'fa-calendar-times');
loadStockTable($("#table-expired-stock"), { loadStockTable($("#table-expired-stock"), {
disableFilters: true, disableFilters: true,
params: { params: {
@ -169,7 +169,7 @@ loadStockTable($("#table-expired-stock"), {
{% endif %} {% endif %}
{% if setting_stock_stale %} {% if setting_stock_stale %}
addHeaderAction('stale-stock', '{% trans "Stale Stock" %}', 'fa-stopwatch'); addHeaderAction('stale-stock', '{% jstrans "Stale Stock" %}', 'fa-stopwatch');
loadStockTable($("#table-stale-stock"), { loadStockTable($("#table-stale-stock"), {
disableFilters: true, disableFilters: true,
params: { params: {
@ -193,10 +193,10 @@ loadStockTable($("#table-stale-stock"), {
{% to_list setting_build_pending setting_build_overdue as settings_list_build %} {% to_list setting_build_pending setting_build_overdue as settings_list_build %}
{% if roles.build.view and True in settings_list_build %} {% if roles.build.view and True in settings_list_build %}
addHeaderTitle('{% trans "Build Orders" %}'); addHeaderTitle('{% jstrans "Build Orders" %}');
{% if setting_build_pending %} {% if setting_build_pending %}
addHeaderAction('build-pending', '{% trans "Build Orders In Progress" %}', 'fa-cogs'); addHeaderAction('build-pending', '{% jstrans "Build Orders In Progress" %}', 'fa-cogs');
loadBuildTable("#table-build-pending", { loadBuildTable("#table-build-pending", {
locale: '{{ request.LANGUAGE_CODE }}', locale: '{{ request.LANGUAGE_CODE }}',
params: { params: {
@ -207,7 +207,7 @@ loadBuildTable("#table-build-pending", {
{% endif %} {% endif %}
{% if setting_build_overdue %} {% if setting_build_overdue %}
addHeaderAction('build-overdue', '{% trans "Overdue Build Orders" %}', 'fa-calendar-times'); addHeaderAction('build-overdue', '{% jstrans "Overdue Build Orders" %}', 'fa-calendar-times');
loadBuildTable("#table-build-overdue", { loadBuildTable("#table-build-overdue", {
locale: '{{ request.LANGUAGE_CODE }}', locale: '{{ request.LANGUAGE_CODE }}',
params: { params: {
@ -224,10 +224,10 @@ loadBuildTable("#table-build-overdue", {
{% to_list setting_po_outstanding setting_po_overdue as settings_list_po %} {% to_list setting_po_outstanding setting_po_overdue as settings_list_po %}
{% if roles.purchase_order.view and True in settings_list_po %} {% if roles.purchase_order.view and True in settings_list_po %}
addHeaderTitle('{% trans "Purchase Orders" %}'); addHeaderTitle('{% jstrans "Purchase Orders" %}');
{% if setting_po_outstanding %} {% if setting_po_outstanding %}
addHeaderAction('po-outstanding', '{% trans "Outstanding Purchase Orders" %}', 'fa-sign-in-alt'); addHeaderAction('po-outstanding', '{% jstrans "Outstanding Purchase Orders" %}', 'fa-sign-in-alt');
loadPurchaseOrderTable("#table-po-outstanding", { loadPurchaseOrderTable("#table-po-outstanding", {
url: "{% url 'api-po-list' %}", url: "{% url 'api-po-list' %}",
params: { params: {
@ -238,7 +238,7 @@ loadPurchaseOrderTable("#table-po-outstanding", {
{% endif %} {% endif %}
{% if setting_po_overdue %} {% if setting_po_overdue %}
addHeaderAction('po-overdue', '{% trans "Overdue Purchase Orders" %}', 'fa-calendar-times'); addHeaderAction('po-overdue', '{% jstrans "Overdue Purchase Orders" %}', 'fa-calendar-times');
loadPurchaseOrderTable("#table-po-overdue", { loadPurchaseOrderTable("#table-po-overdue", {
url: "{% url 'api-po-list' %}", url: "{% url 'api-po-list' %}",
params: { params: {
@ -256,10 +256,10 @@ loadPurchaseOrderTable("#table-po-overdue", {
{% to_list setting_so_outstanding setting_so_overdue setting_so_shipments_pending as settings_list_so %} {% to_list setting_so_outstanding setting_so_overdue setting_so_shipments_pending as settings_list_so %}
{% if roles.sales_order.view and True in settings_list_so %} {% if roles.sales_order.view and True in settings_list_so %}
addHeaderTitle('{% trans "Sales Orders" %}'); addHeaderTitle('{% jstrans "Sales Orders" %}');
{% if setting_so_outstanding %} {% if setting_so_outstanding %}
addHeaderAction('so-outstanding', '{% trans "Outstanding Sales Orders" %}', 'fa-sign-out-alt'); addHeaderAction('so-outstanding', '{% jstrans "Outstanding Sales Orders" %}', 'fa-sign-out-alt');
loadSalesOrderTable("#table-so-outstanding", { loadSalesOrderTable("#table-so-outstanding", {
url: "{% url 'api-so-list' %}", url: "{% url 'api-so-list' %}",
params: { params: {
@ -270,7 +270,7 @@ loadSalesOrderTable("#table-so-outstanding", {
{% endif %} {% endif %}
{% if setting_so_overdue %} {% if setting_so_overdue %}
addHeaderAction('so-overdue', '{% trans "Overdue Sales Orders" %}', 'fa-calendar-times'); addHeaderAction('so-overdue', '{% jstrans "Overdue Sales Orders" %}', 'fa-calendar-times');
loadSalesOrderTable("#table-so-overdue", { loadSalesOrderTable("#table-so-overdue", {
url: "{% url 'api-so-list' %}", url: "{% url 'api-so-list' %}",
params: { params: {
@ -281,7 +281,7 @@ loadSalesOrderTable("#table-so-overdue", {
{% endif %} {% endif %}
{% if setting_so_shipments_pending %} {% if setting_so_shipments_pending %}
addHeaderAction('so-shipments', '{% trans "Pending Shipments" %}', 'fa-truck-loading'); addHeaderAction('so-shipments', '{% jstrans "Pending Shipments" %}', 'fa-truck-loading');
loadSalesOrderShipmentTable("#table-so-shipments", { loadSalesOrderShipmentTable("#table-so-shipments", {
url: "{% url 'api-so-shipment-list' %}", url: "{% url 'api-so-shipment-list' %}",
params: { params: {
@ -296,9 +296,9 @@ loadSalesOrderShipmentTable("#table-so-shipments", {
{% settings_value 'HOMEPAGE_NEWS' user=request.user as setting_news %} {% settings_value 'HOMEPAGE_NEWS' user=request.user as setting_news %}
{% if setting_news and user.is_staff %} {% if setting_news and user.is_staff %}
addHeaderTitle('{% trans "InvenTree News" %}'); addHeaderTitle('{% jstrans "InvenTree News" %}');
addHeaderAction('news', '{% trans "Current News" %}', 'fa-newspaper'); addHeaderAction('news', '{% jstrans "Current News" %}', 'fa-newspaper');
loadNewsFeedTable("#table-news", { loadNewsFeedTable("#table-news", {
url: "{% url 'api-news-list' %}", url: "{% url 'api-news-list' %}",
}); });

View File

@ -35,7 +35,7 @@ loadNotificationTable("#inbox-table", {
params: { params: {
read: false, read: false,
}, },
no_matches: function() { return '{% trans "No unread notifications found" %}'; }, no_matches: function() { return '{% jstrans "No unread notifications found" %}'; },
}); });
$("#mark-all").on('click', function() { $("#mark-all").on('click', function() {
@ -55,7 +55,7 @@ $("#mark-all").on('click', function() {
loadNotificationTable("#history-table", { loadNotificationTable("#history-table", {
name: 'history', name: 'history',
url: '{% url 'api-notifications-list' %}', url: '{% url 'api-notifications-list' %}',
no_matches: function() { return '{% trans "No notification history found" %}'; }, no_matches: function() { return '{% jstrans "No notification history found" %}'; },
}, true); }, true);
$('#history-delete').click(function() { $('#history-delete').click(function() {
@ -72,7 +72,7 @@ $('#history-delete').click(function() {
method: 'DELETE', method: 'DELETE',
multi_delete: true, multi_delete: true,
preFormContent: html, preFormContent: html,
title: '{% trans "Delete Notifications" %}', title: '{% jstrans "Delete Notifications" %}',
refreshTable: '#history-table', refreshTable: '#history-table',
form_data: { form_data: {
filters: { filters: {
@ -86,7 +86,7 @@ $('#history-delete').click(function() {
$("#history-table").on('click', '.notification-delete', function() { $("#history-table").on('click', '.notification-delete', function() {
constructForm(`{% url "api-notifications-list" %}${$(this).attr('pk')}/`, { constructForm(`{% url "api-notifications-list" %}${$(this).attr('pk')}/`, {
method: 'DELETE', method: 'DELETE',
title: '{% trans "Delete Notification" %}', title: '{% jstrans "Delete Notification" %}',
onSuccess: function(data) { onSuccess: function(data) {
updateNotificationTables(); updateNotificationTables();
} }

View File

@ -79,9 +79,9 @@
} }
{% if roles.part.view %} {% if roles.part.view %}
addItemTitle('{% trans "Part" %}'); addItemTitle('{% jstrans "Part" %}');
addItem('part', '{% trans "Parts" %}', 'fa-shapes'); addItem('part', '{% jstrans "Parts" %}', 'fa-shapes');
loadPartTable("#table-part", loadPartTable("#table-part",
"{% url 'api-part-list' %}", "{% url 'api-part-list' %}",
@ -94,7 +94,7 @@
} }
); );
addItem('category', '{% trans "Part Categories" %}', 'fa-sitemap'); addItem('category', '{% jstrans "Part Categories" %}', 'fa-sitemap');
loadPartCategoryTable($("#table-category"), { loadPartCategoryTable($("#table-category"), {
params: { params: {
@ -102,7 +102,7 @@
} }
}); });
addItem('manufacturer-part', '{% trans "Manufacturer Parts" %}', 'fa-toolbox'); addItem('manufacturer-part', '{% jstrans "Manufacturer Parts" %}', 'fa-toolbox');
loadManufacturerPartTable( loadManufacturerPartTable(
"#table-manufacturer-part", "#table-manufacturer-part",
@ -117,7 +117,7 @@
} }
); );
addItem('supplier-part', '{% trans "Supplier Parts" %}', 'fa-pallet'); addItem('supplier-part', '{% jstrans "Supplier Parts" %}', 'fa-pallet');
loadSupplierPartTable( loadSupplierPartTable(
"#table-supplier-part", "#table-supplier-part",
@ -136,9 +136,9 @@
{% if roles.build.view %} {% if roles.build.view %}
addItemTitle('{% trans "Build" %}'); addItemTitle('{% jstrans "Build" %}');
addItem('build-order', '{% trans "Build Orders" %}', 'fa-tools'); addItem('build-order', '{% jstrans "Build Orders" %}', 'fa-tools');
loadBuildTable('#table-build-order', { loadBuildTable('#table-build-order', {
locale: '{{ request.LANGUAGE_CODE }}', locale: '{{ request.LANGUAGE_CODE }}',
@ -150,9 +150,9 @@
{% endif %} {% endif %}
{% if roles.stock.view %} {% if roles.stock.view %}
addItemTitle('{% trans "Stock" %}'); addItemTitle('{% jstrans "Stock" %}');
addItem('stock', '{% trans "Stock Items" %}', 'fa-boxes'); addItem('stock', '{% jstrans "Stock Items" %}', 'fa-boxes');
loadStockTable($('#table-stock'), { loadStockTable($('#table-stock'), {
filterKey: 'stocksearch', filterKey: 'stocksearch',
@ -163,7 +163,7 @@
} }
}); });
addItem('location', '{% trans "Stock Locations" %}', 'fa-map-marker-alt'); addItem('location', '{% jstrans "Stock Locations" %}', 'fa-map-marker-alt');
loadStockLocationTable($("#table-location"), { loadStockLocationTable($("#table-location"), {
filterKey: 'locationsearch', filterKey: 'locationsearch',
@ -175,9 +175,9 @@
{% endif %} {% endif %}
{% if roles.purchase_order.view or roles.sales_order.view %} {% if roles.purchase_order.view or roles.sales_order.view %}
addItemTitle('{% trans "Company" %}'); addItemTitle('{% jstrans "Company" %}');
addItem('manufacturer', '{% trans "Manufacturers" %}', 'fa-industry'); addItem('manufacturer', '{% jstrans "Manufacturers" %}', 'fa-industry');
loadCompanyTable('#table-manufacturer', "{% url 'api-company-list' %}", { loadCompanyTable('#table-manufacturer', "{% url 'api-company-list' %}", {
params: { params: {
@ -187,7 +187,7 @@
}); });
{% if roles.purchase_order.view %} {% if roles.purchase_order.view %}
addItem('supplier', '{% trans "Suppliers" %}', 'fa-building'); addItem('supplier', '{% jstrans "Suppliers" %}', 'fa-building');
loadCompanyTable('#table-supplier', "{% url 'api-company-list' %}", { loadCompanyTable('#table-supplier', "{% url 'api-company-list' %}", {
params: { params: {
@ -196,7 +196,7 @@
} }
}); });
addItem('purchase-order', '{% trans "Purchase Orders" %}', 'fa-shopping-cart'); addItem('purchase-order', '{% jstrans "Purchase Orders" %}', 'fa-shopping-cart');
loadPurchaseOrderTable('#table-purchase-order', { loadPurchaseOrderTable('#table-purchase-order', {
params: { params: {
@ -207,7 +207,7 @@
{% endif %} {% endif %}
{% if roles.sales_order.view %} {% if roles.sales_order.view %}
addItem('customer', '{% trans "Customers" %}', 'fa-user-tie'); addItem('customer', '{% jstrans "Customers" %}', 'fa-user-tie');
loadCompanyTable('#table-customer', "{% url 'api-company-list' %}", { loadCompanyTable('#table-customer', "{% url 'api-company-list' %}", {
params: { params: {
@ -216,7 +216,7 @@
} }
}); });
addItem('sales-orders', '{% trans "Sales Orders" %}', 'fa-truck'); addItem('sales-orders', '{% jstrans "Sales Orders" %}', 'fa-truck');
loadSalesOrderTable('#table-sales-orders', { loadSalesOrderTable('#table-sales-orders', {
params: { params: {

View File

@ -55,14 +55,14 @@ $('table').find('.btn-edit-setting').click(function() {
var title = ''; var title = '';
if (plugin != null) { if (plugin != null) {
title = '{% trans "Edit Plugin Setting" %}'; title = '{% jstrans "Edit Plugin Setting" %}';
} else if (notification) { } else if (notification) {
title = '{% trans "Edit Notification Setting" %}'; title = '{% jstrans "Edit Notification Setting" %}';
setting = $(this).attr('pk'); setting = $(this).attr('pk');
} else if (is_global) { } else if (is_global) {
title = '{% trans "Edit Global Setting" %}'; title = '{% jstrans "Edit Global Setting" %}';
} else { } else {
title = '{% trans "Edit User Setting" %}'; title = '{% jstrans "Edit User Setting" %}';
} }
editSetting(setting, { editSetting(setting, {

View File

@ -41,12 +41,12 @@ onPanelLoad('pricing', function() {
{ {
field: 'currency', field: 'currency',
sortable: true, sortable: true,
title: '{% trans "Currency" %}', title: '{% jstrans "Currency" %}',
}, },
{ {
field: 'rate', field: 'rate',
sortable: true, sortable: true,
title: '{% trans "Rate" %}', title: '{% jstrans "Rate" %}',
} }
] ]
}); });
@ -64,21 +64,21 @@ onPanelLoad('units', function() {
columns: [ columns: [
{ {
field: 'name', field: 'name',
title: '{% trans "Name" %}', title: '{% jstrans "Name" %}',
}, },
{ {
field: 'definition', field: 'definition',
title: '{% trans "Definition" %}', title: '{% jstrans "Definition" %}',
}, },
{ {
field: 'symbol', field: 'symbol',
title: '{% trans "Symbol" %}', title: '{% jstrans "Symbol" %}',
formatter: function(value, row) { formatter: function(value, row) {
let html = value; let html = value;
let buttons = ''; let buttons = '';
buttons += makeEditButton('button-units-edit', row.pk, '{% trans "Edit" %}'); buttons += makeEditButton('button-units-edit', row.pk, '{% jstrans "Edit" %}');
buttons += makeDeleteButton('button-units-delete', row.pk, '{% trans "Delete" %}'); buttons += makeDeleteButton('button-units-delete', row.pk, '{% jstrans "Delete" %}');
html += wrapButtons(buttons); html += wrapButtons(buttons);
return html; return html;
@ -92,7 +92,7 @@ onPanelLoad('units', function() {
let pk = $(this).attr('pk'); let pk = $(this).attr('pk');
constructForm(`{% url "api-custom-unit-list" %}${pk}/`, { constructForm(`{% url "api-custom-unit-list" %}${pk}/`, {
title: '{% trans "Edit Custom Unit" %}', title: '{% jstrans "Edit Custom Unit" %}',
fields: { fields: {
name: {}, name: {},
definition: {}, definition: {},
@ -107,7 +107,7 @@ onPanelLoad('units', function() {
let pk = $(this).attr('pk'); let pk = $(this).attr('pk');
constructForm(`{% url "api-custom-unit-list" %}${pk}/`, { constructForm(`{% url "api-custom-unit-list" %}${pk}/`, {
title: '{% trans "Delete Custom Unit" %}', title: '{% jstrans "Delete Custom Unit" %}',
method: 'DELETE', method: 'DELETE',
refreshTable: '#physical-units-table', refreshTable: '#physical-units-table',
}); });
@ -121,7 +121,7 @@ onPanelLoad('units', function() {
definition: {}, definition: {},
symbol: {}, symbol: {},
}, },
title: '{% trans "New Custom Unit" %}', title: '{% jstrans "New Custom Unit" %}',
method: 'POST', method: 'POST',
refreshTable: '#physical-units-table', refreshTable: '#physical-units-table',
}); });
@ -137,17 +137,17 @@ onPanelLoad('project-codes', function() {
search: true, search: true,
sortable: true, sortable: true,
formatNoMatches: function() { formatNoMatches: function() {
return '{% trans "No project codes found" %}'; return '{% jstrans "No project codes found" %}';
}, },
columns: [ columns: [
{ {
field: 'code', field: 'code',
sortable: true, sortable: true,
title: '{% trans "Project Code" %}', title: '{% jstrans "Project Code" %}',
}, },
{ {
field: 'responsible', field: 'responsible',
title: '{% trans "Responsible" %}', title: '{% jstrans "Responsible" %}',
formatter: function(value, row) { formatter: function(value, row) {
if (!row.responsible_detail) { if (!row.responsible_detail) {
return '-'; return '-';
@ -155,7 +155,7 @@ onPanelLoad('project-codes', function() {
var html = row.responsible_detail.name; var html = row.responsible_detail.name;
if (row.responsible_detail.label == '{% trans "group" %}') { if (row.responsible_detail.label == '{% jstrans "group" %}') {
html += `<span class='float-right fas fa-users'></span>`; html += `<span class='float-right fas fa-users'></span>`;
} else { } else {
html += `<span class='float-right fas fa-user'></span>`; html += `<span class='float-right fas fa-user'></span>`;
@ -167,13 +167,13 @@ onPanelLoad('project-codes', function() {
{ {
field: 'description', field: 'description',
sortable: false, sortable: false,
title: '{% trans "Description" %}', title: '{% jstrans "Description" %}',
formatter: function(value, row) { formatter: function(value, row) {
let html = value; let html = value;
let buttons = ''; let buttons = '';
buttons += makeEditButton('button-project-code-edit', row.pk, '{% trans "Edit Project Code" %}'); buttons += makeEditButton('button-project-code-edit', row.pk, '{% jstrans "Edit Project Code" %}');
buttons += makeDeleteButton('button-project-code-delete', row.pk, '{% trans "Delete Project Code" %}'); buttons += makeDeleteButton('button-project-code-delete', row.pk, '{% jstrans "Delete Project Code" %}');
html += wrapButtons(buttons); html += wrapButtons(buttons);
return html; return html;
@ -186,7 +186,7 @@ onPanelLoad('project-codes', function() {
let pk = $(this).attr('pk'); let pk = $(this).attr('pk');
constructForm(`{% url "api-project-code-list" %}${pk}/`, { constructForm(`{% url "api-project-code-list" %}${pk}/`, {
title: '{% trans "Edit Project Code" %}', title: '{% jstrans "Edit Project Code" %}',
fields: { fields: {
code: {}, code: {},
description: {}, description: {},
@ -200,7 +200,7 @@ onPanelLoad('project-codes', function() {
let pk = $(this).attr('pk'); let pk = $(this).attr('pk');
constructForm(`{% url "api-project-code-list" %}${pk}/`, { constructForm(`{% url "api-project-code-list" %}${pk}/`, {
title: '{% trans "Delete Project Code" %}', title: '{% jstrans "Delete Project Code" %}',
method: 'DELETE', method: 'DELETE',
refreshTable: '#project-code-table', refreshTable: '#project-code-table',
}); });
@ -213,7 +213,7 @@ onPanelLoad('project-codes', function() {
code: {}, code: {},
description: {}, description: {},
}, },
title: '{% trans "New Project Code" %}', title: '{% jstrans "New Project Code" %}',
method: 'POST', method: 'POST',
refreshTable: '#project-code-table', refreshTable: '#project-code-table',
}); });
@ -282,7 +282,7 @@ onPanelLoad('category', function() {
}); });
$('#cat-param-table').inventreeTable({ $('#cat-param-table').inventreeTable({
formatNoMatches: function() { return '{% trans "No category parameter templates found" %}'; }, formatNoMatches: function() { return '{% jstrans "No category parameter templates found" %}'; },
columns: [ columns: [
{ {
field: 'pk', field: 'pk',
@ -292,21 +292,21 @@ onPanelLoad('category', function() {
}, },
{ {
field: 'parameter_template_detail.name', field: 'parameter_template_detail.name',
title: '{% trans "Parameter Template" %}', title: '{% jstrans "Parameter Template" %}',
sortable: 'true', sortable: 'true',
}, },
{ {
field: 'category_detail.pathstring', field: 'category_detail.pathstring',
title: '{% trans "Category" %}', title: '{% jstrans "Category" %}',
}, },
{ {
field: 'default_value', field: 'default_value',
title: '{% trans "Default Value" %}', title: '{% jstrans "Default Value" %}',
sortable: 'true', sortable: 'true',
formatter: function(value, row, index, field) { formatter: function(value, row, index, field) {
let buttons = ''; let buttons = '';
buttons += makeEditButton('template-edit', row.pk, '{% trans "Edit Template" %}'); buttons += makeEditButton('template-edit', row.pk, '{% jstrans "Edit Template" %}');
buttons += makeDeleteButton('template-delete', row.pk, '{% trans "Delete Template" %}'); buttons += makeDeleteButton('template-delete', row.pk, '{% jstrans "Delete Template" %}');
let html = value let html = value
html += wrapButtons(buttons); html += wrapButtons(buttons);
@ -323,7 +323,7 @@ onPanelLoad('category', function() {
var pk = $(this).attr('pk'); var pk = $(this).attr('pk');
constructForm(`/api/part/category/parameters/${pk}/`, { constructForm(`/api/part/category/parameters/${pk}/`, {
title: '{% trans "Edit Category Parameter Template" %}', title: '{% jstrans "Edit Category Parameter Template" %}',
fields: { fields: {
parameter_template: {}, parameter_template: {},
category: { category: {
@ -350,7 +350,7 @@ onPanelLoad('category', function() {
constructForm(`/api/part/category/parameters/${pk}/`, { constructForm(`/api/part/category/parameters/${pk}/`, {
method: 'DELETE', method: 'DELETE',
title: '{% trans "Delete Category Parameter Template" %}', title: '{% jstrans "Delete Category Parameter Template" %}',
onSuccess: function() { onSuccess: function() {
loadTemplateTable(pk); loadTemplateTable(pk);
} }
@ -385,7 +385,7 @@ onPanelLoad('category', function() {
var pk = $('#category-select').val(); var pk = $('#category-select').val();
constructForm('{% url "api-part-category-parameter-list" %}', { constructForm('{% url "api-part-category-parameter-list" %}', {
title: '{% trans "Create Category Parameter Template" %}', title: '{% jstrans "Create Category Parameter Template" %}',
method: 'POST', method: 'POST',
fields: { fields: {
parameter_template: {}, parameter_template: {},
@ -415,7 +415,7 @@ onPanelLoad('part-parameters', function() {
constructForm('{% url "api-part-parameter-template-list" %}', { constructForm('{% url "api-part-parameter-template-list" %}', {
fields: partParameterTemplateFields(), fields: partParameterTemplateFields(),
method: 'POST', method: 'POST',
title: '{% trans "Create Part Parameter Template" %}', title: '{% jstrans "Create Part Parameter Template" %}',
refreshTable: '#param-table', refreshTable: '#param-table',
}); });
}); });
@ -437,34 +437,34 @@ onPanelLoad("stock", function() {
search: true, search: true,
sortable: true, sortable: true,
formatNoMatches: function() { formatNoMatches: function() {
return '{% trans "No stock location types found" %}'; return '{% jstrans "No stock location types found" %}';
}, },
columns: [ columns: [
{ {
field: 'name', field: 'name',
sortable: true, sortable: true,
title: '{% trans "Name" %}', title: '{% jstrans "Name" %}',
}, },
{ {
field: 'description', field: 'description',
sortable: false, sortable: false,
title: '{% trans "Description" %}', title: '{% jstrans "Description" %}',
}, },
{ {
field: 'icon', field: 'icon',
sortable: true, sortable: true,
title: '{% trans "Icon" %}', title: '{% jstrans "Icon" %}',
}, },
{ {
field: 'location_count', field: 'location_count',
sortable: true, sortable: true,
title: '{% trans "Location count" %}', title: '{% jstrans "Location count" %}',
formatter: function(value, row) { formatter: function(value, row) {
let html = value; let html = value;
let buttons = ''; let buttons = '';
buttons += makeEditButton('button-location-type-edit', row.pk, '{% trans "Edit Location Type" %}'); buttons += makeEditButton('button-location-type-edit', row.pk, '{% jstrans "Edit Location Type" %}');
buttons += makeDeleteButton('button-location-type-delete', row.pk, '{% trans "Delete Location type" %}'); buttons += makeDeleteButton('button-location-type-delete', row.pk, '{% jstrans "Delete Location type" %}');
html += wrapButtons(buttons); html += wrapButtons(buttons);
return html; return html;
@ -477,7 +477,7 @@ onPanelLoad("stock", function() {
let pk = $(this).attr('pk'); let pk = $(this).attr('pk');
constructForm(`{% url "api-location-type-list" %}${pk}/`, { constructForm(`{% url "api-location-type-list" %}${pk}/`, {
title: '{% trans "Edit Location Type" %}', title: '{% jstrans "Edit Location Type" %}',
fields: stockLocationTypeFields(), fields: stockLocationTypeFields(),
refreshTable: '#location-type-table', refreshTable: '#location-type-table',
}); });
@ -487,7 +487,7 @@ onPanelLoad("stock", function() {
let pk = $(this).attr('pk'); let pk = $(this).attr('pk');
constructForm(`{% url "api-location-type-list" %}${pk}/`, { constructForm(`{% url "api-location-type-list" %}${pk}/`, {
title: '{% trans "Delete Location Type" %}', title: '{% jstrans "Delete Location Type" %}',
method: 'DELETE', method: 'DELETE',
refreshTable: '#location-type-table', refreshTable: '#location-type-table',
}); });
@ -497,7 +497,7 @@ onPanelLoad("stock", function() {
// Construct a new location type // Construct a new location type
constructForm('{% url "api-location-type-list" %}', { constructForm('{% url "api-location-type-list" %}', {
fields: stockLocationTypeFields(), fields: stockLocationTypeFields(),
title: '{% trans "New Location Type" %}', title: '{% jstrans "New Location Type" %}',
method: 'POST', method: 'POST',
refreshTable: '#location-type-table', refreshTable: '#location-type-table',
}); });
@ -526,18 +526,18 @@ onPanelLoad('stocktake', function() {
columns: [ columns: [
{ {
field: 'report', field: 'report',
title: '{% trans "Report" %}', title: '{% jstrans "Report" %}',
formatter: function(value, row) { formatter: function(value, row) {
return attachmentLink(value); return attachmentLink(value);
} }
}, },
{ {
field: 'part_count', field: 'part_count',
title: '{% trans "Part Count" %}', title: '{% jstrans "Part Count" %}',
}, },
{ {
field: 'date', field: 'date',
title: '{% trans "Date" %}', title: '{% jstrans "Date" %}',
sortable: true, sortable: true,
formatter: function(value, row) { formatter: function(value, row) {
let html = renderDate(value); let html = renderDate(value);

View File

@ -215,7 +215,7 @@
{% block js_ready %} {% block js_ready %}
(function() { (function() {
var message = "{% trans 'Do you really want to remove the selected email address?' %}"; var message = "{% jstrans 'Do you really want to remove the selected email address?' %}";
var actions = document.getElementsByName('action_remove'); var actions = document.getElementsByName('action_remove');
if (actions.length) { if (actions.length) {
actions[0].addEventListener("click", function(e) { actions[0].addEventListener("click", function(e) {

View File

@ -222,48 +222,48 @@ function showApiError(xhr, url) {
switch (xhr.status || 0) { switch (xhr.status || 0) {
// No response // No response
case 0: case 0:
title = '{% trans "No Response" %}'; title = '{% jstrans "No Response" %}';
message = '{% trans "No response from the InvenTree server" %}'; message = '{% jstrans "No response from the InvenTree server" %}';
break; break;
// Bad request // Bad request
case 400: case 400:
// Note: Normally error code 400 is handled separately, // Note: Normally error code 400 is handled separately,
// and should now be shown here! // and should now be shown here!
title = '{% trans "Error 400: Bad request" %}'; title = '{% jstrans "Error 400: Bad request" %}';
message = '{% trans "API request returned error code 400" %}'; message = '{% jstrans "API request returned error code 400" %}';
break; break;
// Not authenticated // Not authenticated
case 401: case 401:
title = '{% trans "Error 401: Not Authenticated" %}'; title = '{% jstrans "Error 401: Not Authenticated" %}';
message = '{% trans "Authentication credentials not supplied" %}'; message = '{% jstrans "Authentication credentials not supplied" %}';
break; break;
// Permission denied // Permission denied
case 403: case 403:
title = '{% trans "Error 403: Permission Denied" %}'; title = '{% jstrans "Error 403: Permission Denied" %}';
message = '{% trans "You do not have the required permissions to access this function" %}'; message = '{% jstrans "You do not have the required permissions to access this function" %}';
break; break;
// Resource not found // Resource not found
case 404: case 404:
title = '{% trans "Error 404: Resource Not Found" %}'; title = '{% jstrans "Error 404: Resource Not Found" %}';
message = '{% trans "The requested resource could not be located on the server" %}'; message = '{% jstrans "The requested resource could not be located on the server" %}';
break; break;
// Method not allowed // Method not allowed
case 405: case 405:
title = '{% trans "Error 405: Method Not Allowed" %}'; title = '{% jstrans "Error 405: Method Not Allowed" %}';
message = '{% trans "HTTP method not allowed at URL" %}'; message = '{% jstrans "HTTP method not allowed at URL" %}';
break; break;
// Timeout // Timeout
case 408: case 408:
title = '{% trans "Error 408: Timeout" %}'; title = '{% jstrans "Error 408: Timeout" %}';
message = '{% trans "Connection timeout while requesting data from server" %}'; message = '{% jstrans "Connection timeout while requesting data from server" %}';
break; break;
case 503: case 503:
title = '{% trans "Error 503: Service Unavailable" %}'; title = '{% jstrans "Error 503: Service Unavailable" %}';
message = '{% trans "The server is currently unavailable" %}'; message = '{% jstrans "The server is currently unavailable" %}';
break; break;
default: default:
title = '{% trans "Unhandled Error Code" %}'; title = '{% jstrans "Unhandled Error Code" %}';
message = `{% trans "Error code" %}: ${xhr.status}`; message = `{% jstrans "Error code" %}: ${xhr.status}`;
var response = xhr.responseJSON; var response = xhr.responseJSON;

View File

@ -45,7 +45,7 @@ function addAttachmentButtonCallbacks(url, fields={}) {
fields: file_fields, fields: file_fields,
method: 'POST', method: 'POST',
refreshTable: '#attachment-table', refreshTable: '#attachment-table',
title: '{% trans "Add Attachment" %}', title: '{% jstrans "Add Attachment" %}',
}); });
}); });
@ -67,7 +67,7 @@ function addAttachmentButtonCallbacks(url, fields={}) {
fields: link_fields, fields: link_fields,
method: 'POST', method: 'POST',
refreshTable: '#attachment-table', refreshTable: '#attachment-table',
title: '{% trans "Add Link" %}', title: '{% jstrans "Add Link" %}',
}); });
}); });
} }
@ -111,13 +111,13 @@ function deleteAttachments(attachments, url, options={}) {
var html = ` var html = `
<div class='alert alert-block alert-danger'> <div class='alert alert-block alert-danger'>
{% trans "All selected attachments will be deleted" %} {% jstrans "All selected attachments will be deleted" %}
</div> </div>
<table class='table table-striped table-condensed'> <table class='table table-striped table-condensed'>
<tr> <tr>
<th></th> <th></th>
<th>{% trans "Attachment" %}</th> <th>{% jstrans "Attachment" %}</th>
<th>{% trans "Comment" %}</th> <th>{% jstrans "Comment" %}</th>
</tr> </tr>
${rows} ${rows}
</table> </table>
@ -126,7 +126,7 @@ function deleteAttachments(attachments, url, options={}) {
constructForm(url, { constructForm(url, {
method: 'DELETE', method: 'DELETE',
multi_delete: true, multi_delete: true,
title: '{% trans "Delete Attachments" %}', title: '{% jstrans "Delete Attachments" %}',
preFormContent: html, preFormContent: html,
form_data: { form_data: {
items: ids, items: ids,
@ -202,7 +202,7 @@ function makeAttachmentActions(permissions, options) {
actions.push({ actions.push({
label: 'delete', label: 'delete',
icon: 'fa-trash-alt icon-red', icon: 'fa-trash-alt icon-red',
title: '{% trans "Delete attachments" %}', title: '{% jstrans "Delete attachments" %}',
callback: options.callback, callback: options.callback,
}); });
} }
@ -250,7 +250,7 @@ function loadAttachmentTable(url, options) {
{ {
label: 'attachments', label: 'attachments',
icon: 'fa-tools', icon: 'fa-tools',
title: '{% trans "Attachment actions" %}', title: '{% jstrans "Attachment actions" %}',
actions: makeAttachmentActions(permissions, { actions: makeAttachmentActions(permissions, {
callback: function(attachments) { callback: function(attachments) {
deleteAttachments(attachments, url, options); deleteAttachments(attachments, url, options);
@ -272,7 +272,7 @@ function loadAttachmentTable(url, options) {
url: url, url: url,
name: options.name || 'attachments', name: options.name || 'attachments',
formatNoMatches: function() { formatNoMatches: function() {
return '{% trans "No attachments found" %}'; return '{% jstrans "No attachments found" %}';
}, },
sortable: true, sortable: true,
search: true, search: true,
@ -312,7 +312,7 @@ function loadAttachmentTable(url, options) {
} }
}, },
refreshTable: '#attachment-table', refreshTable: '#attachment-table',
title: '{% trans "Edit Attachment" %}', title: '{% jstrans "Edit Attachment" %}',
}); });
}); });
} }
@ -323,7 +323,7 @@ function loadAttachmentTable(url, options) {
}, },
{ {
field: 'attachment', field: 'attachment',
title: '{% trans "Attachment" %}', title: '{% jstrans "Attachment" %}',
formatter: function(value, row) { formatter: function(value, row) {
if (row.attachment) { if (row.attachment) {
@ -338,12 +338,12 @@ function loadAttachmentTable(url, options) {
}, },
{ {
field: 'comment', field: 'comment',
title: '{% trans "Comment" %}', title: '{% jstrans "Comment" %}',
}, },
{ {
field: 'upload_date', field: 'upload_date',
sortable: true, sortable: true,
title: '{% trans "Upload Date" %}', title: '{% jstrans "Upload Date" %}',
formatter: function(value, row) { formatter: function(value, row) {
var html = renderDate(value); var html = renderDate(value);
@ -363,7 +363,7 @@ function loadAttachmentTable(url, options) {
buttons += makeEditButton( buttons += makeEditButton(
'button-attachment-edit', 'button-attachment-edit',
row.pk, row.pk,
'{% trans "Edit attachment" %}', '{% jstrans "Edit attachment" %}',
); );
} }
@ -371,7 +371,7 @@ function loadAttachmentTable(url, options) {
buttons += makeDeleteButton( buttons += makeDeleteButton(
'button-attachment-delete', 'button-attachment-delete',
row.pk, row.pk,
'{% trans "Delete attachment" %}', '{% jstrans "Delete attachment" %}',
); );
} }

View File

@ -40,23 +40,23 @@ var barcodeInputTimer = null;
*/ */
function makeBarcodeInput(placeholderText='', hintText='') { function makeBarcodeInput(placeholderText='', hintText='') {
placeholderText = placeholderText || '{% trans "Scan barcode data here using barcode scanner" %}'; placeholderText = placeholderText || '{% jstrans "Scan barcode data here using barcode scanner" %}';
hintText = hintText || '{% trans "Enter barcode data" %}'; hintText = hintText || '{% jstrans "Enter barcode data" %}';
var html = ` var html = `
<div id='barcode_scan_video_container' class="mx-auto" style='width: 100%; max-width: 240px; display: none;'> <div id='barcode_scan_video_container' class="mx-auto" style='width: 100%; max-width: 240px; display: none;'>
<div id="barcode_scan_video"></div> <div id="barcode_scan_video"></div>
</div> </div>
<div class='form-group'> <div class='form-group'>
<label class='control-label' for='barcode'>{% trans "Barcode" %}</label> <label class='control-label' for='barcode'>{% jstrans "Barcode" %}</label>
<div class='controls'> <div class='controls'>
<div class='input-group'> <div class='input-group'>
<span class='input-group-text'> <span class='input-group-text'>
${makeIcon('fa-qrcode')} ${makeIcon('fa-qrcode')}
</span> </span>
<input id='barcode' class='textinput textInput form-control' type='text' name='barcode' placeholder='${placeholderText}'> <input id='barcode' class='textinput textInput form-control' type='text' name='barcode' placeholder='${placeholderText}'>
<button title='{% trans "Scan barcode using connected webcam" %}' id='barcode_scan_btn' type='button' class='btn btn-secondary' onclick='onBarcodeScanClicked()' style='display: none;'> <button title='{% jstrans "Scan barcode using connected webcam" %}' id='barcode_scan_btn' type='button' class='btn btn-secondary' onclick='onBarcodeScanClicked()' style='display: none;'>
${makeIcon('fa-camera')} ${makeIcon('fa-camera')}
</button> </button>
</div> </div>
@ -135,12 +135,12 @@ function onBarcodeScanCompleted(result, options) {
*/ */
function makeNotesField(options={}) { function makeNotesField(options={}) {
var tooltip = options.tooltip || '{% trans "Enter optional notes for stock transfer" %}'; var tooltip = options.tooltip || '{% jstrans "Enter optional notes for stock transfer" %}';
var placeholder = options.placeholder || '{% trans "Enter notes" %}'; var placeholder = options.placeholder || '{% jstrans "Enter notes" %}';
return ` return `
<div class='form-group'> <div class='form-group'>
<label class='control-label' for='notes'>{% trans "Notes" %}</label> <label class='control-label' for='notes'>{% jstrans "Notes" %}</label>
<div class='controls'> <div class='controls'>
<div class='input-group'> <div class='input-group'>
<span class='input-group-text'> <span class='input-group-text'>
@ -185,7 +185,7 @@ function postBarcodeData(barcode_data, options={}) {
} else { } else {
console.error(xhr); console.error(xhr);
data = xhr.responseJSON || {}; data = xhr.responseJSON || {};
showBarcodeMessage(modal, data.error || '{% trans "Server error" %}'); showBarcodeMessage(modal, data.error || '{% jstrans "Server error" %}');
} }
break; break;
default: default:
@ -214,7 +214,7 @@ function postBarcodeData(barcode_data, options={}) {
} else { } else {
showBarcodeMessage( showBarcodeMessage(
modal, modal,
'{% trans "Unknown response from server" %}', '{% jstrans "Unknown response from server" %}',
'warning' 'warning'
); );
} }
@ -249,7 +249,7 @@ function showBarcodeMessage(modal, message, style='danger') {
function showInvalidResponseError(modal, response, status) { function showInvalidResponseError(modal, response, status) {
showBarcodeMessage( showBarcodeMessage(
modal, modal,
`{% trans "Invalid server response" %}<br>{% trans "Status" %}: '${status}'` `{% jstrans "Invalid server response" %}<br>{% jstrans "Status" %}: '${status}'`
); );
} }
@ -369,7 +369,7 @@ function barcodeDialog(title, options={}) {
modalShowSubmitButton(modal, false); modalShowSubmitButton(modal, false);
} }
var details = options.details || '{% trans "Scan barcode data" %}'; var details = options.details || '{% jstrans "Scan barcode data" %}';
var content = ''; var content = '';
@ -417,7 +417,7 @@ function barcodeDialog(title, options={}) {
function barcodeScanDialog(options={}) { function barcodeScanDialog(options={}) {
let modal = options.modal || createNewModal(); let modal = options.modal || createNewModal();
let title = options.title || '{% trans "Scan Barcode" %}'; let title = options.title || '{% jstrans "Scan Barcode" %}';
const matching_models = [ const matching_models = [
'build', 'build',
@ -455,7 +455,7 @@ function barcodeScanDialog(options={}) {
// No match // No match
showBarcodeMessage( showBarcodeMessage(
modal, modal,
'{% trans "No URL in response" %}', '{% jstrans "No URL in response" %}',
'warning' 'warning'
); );
} }
@ -493,15 +493,15 @@ function linkBarcodeDialog(data, options={}) {
*/ */
function unlinkBarcode(data, options={}) { function unlinkBarcode(data, options={}) {
var html = `<b>{% trans "Unlink Barcode" %}</b><br>`; var html = `<b>{% jstrans "Unlink Barcode" %}</b><br>`;
html += '{% trans "This will remove the link to the associated barcode" %}'; html += '{% jstrans "This will remove the link to the associated barcode" %}';
showQuestionDialog( showQuestionDialog(
'{% trans "Unlink Barcode" %}', '{% jstrans "Unlink Barcode" %}',
html, html,
{ {
accept_text: '{% trans "Unlink" %}', accept_text: '{% jstrans "Unlink" %}',
accept: function() { accept: function() {
inventreePut( inventreePut(
'{% url "api-barcode-unlink" %}', '{% url "api-barcode-unlink" %}',
@ -543,9 +543,9 @@ function barcodeCheckInStockItems(location_id, options={}) {
<table class='table table-condensed table-striped' id='items-table'> <table class='table table-condensed table-striped' id='items-table'>
<thead> <thead>
<tr> <tr>
<th>{% trans "Part" %}</th> <th>{% jstrans "Part" %}</th>
<th>{% trans "Location" %}</th> <th>{% jstrans "Location" %}</th>
<th>{% trans "Quantity" %}</th> <th>{% jstrans "Quantity" %}</th>
<th></th> <th></th>
</tr> </tr>
</thead> </thead>
@ -564,7 +564,7 @@ function barcodeCheckInStockItems(location_id, options={}) {
<td>${imageHoverIcon(item.part_detail.thumbnail)} ${item.part_detail.name}</td> <td>${imageHoverIcon(item.part_detail.thumbnail)} ${item.part_detail.name}</td>
<td>${location_info}</td> <td>${location_info}</td>
<td>${item.quantity}</td> <td>${item.quantity}</td>
<td>${makeRemoveButton('button-item-remove', item.pk, '{% trans "Remove stock item" %}')}</td> <td>${makeRemoveButton('button-item-remove', item.pk, '{% jstrans "Remove stock item" %}')}</td>
</tr>`; </tr>`;
}); });
@ -607,12 +607,12 @@ function barcodeCheckInStockItems(location_id, options={}) {
var extra = makeNotesField(); var extra = makeNotesField();
barcodeDialog( barcodeDialog(
'{% trans "Scan Stock Items Into Location" %}', '{% jstrans "Scan Stock Items Into Location" %}',
{ {
details: '{% trans "Scan stock item barcode to check in to this location" %}', details: '{% jstrans "Scan stock item barcode to check in to this location" %}',
headerContent: table, headerContent: table,
preShow: function() { preShow: function() {
modalSetSubmitText(modal, '{% trans "Check In" %}'); modalSetSubmitText(modal, '{% jstrans "Check In" %}');
modalEnable(modal, false); modalEnable(modal, false);
reloadTable(); reloadTable();
}, },
@ -644,7 +644,7 @@ function barcodeCheckInStockItems(location_id, options={}) {
// Prevent submission without any entries // Prevent submission without any entries
if (entries.length == 0) { if (entries.length == 0) {
showBarcodeMessage(modal, '{% trans "No barcode provided" %}', 'warning'); showBarcodeMessage(modal, '{% jstrans "No barcode provided" %}', 'warning');
return; return;
} }
@ -684,18 +684,18 @@ function barcodeCheckInStockItems(location_id, options={}) {
}); });
if (duplicate) { if (duplicate) {
showBarcodeMessage(modal, '{% trans "Stock Item already scanned" %}', 'warning'); showBarcodeMessage(modal, '{% jstrans "Stock Item already scanned" %}', 'warning');
} else { } else {
if (stockitem.location == location_id) { if (stockitem.location == location_id) {
showBarcodeMessage(modal, '{% trans "Stock Item already in this location" %}'); showBarcodeMessage(modal, '{% jstrans "Stock Item already in this location" %}');
return; return;
} }
// Add this stock item to the list // Add this stock item to the list
items.push(stockitem); items.push(stockitem);
showBarcodeMessage(modal, '{% trans "Added stock item" %}', 'success'); showBarcodeMessage(modal, '{% jstrans "Added stock item" %}', 'success');
reloadTable(); reloadTable();
} }
@ -704,7 +704,7 @@ function barcodeCheckInStockItems(location_id, options={}) {
); );
} else { } else {
// Barcode does not match a stock item // Barcode does not match a stock item
showBarcodeMessage(modal, '{% trans "Barcode does not match valid stock item" %}', 'warning'); showBarcodeMessage(modal, '{% jstrans "Barcode does not match valid stock item" %}', 'warning');
} }
}, },
} }
@ -723,9 +723,9 @@ function barcodeCheckInStockLocations(location_id, options={}) {
var header = ''; var header = '';
barcodeDialog( barcodeDialog(
'{% trans "Scan Stock Container Into Location" %}', '{% jstrans "Scan Stock Container Into Location" %}',
{ {
details: '{% trans "Scan stock container barcode to check in to this location" %}', details: '{% jstrans "Scan stock container barcode to check in to this location" %}',
headerContent: header, headerContent: header,
preShow: function() { preShow: function() {
modalEnable(modal, false); modalEnable(modal, false);
@ -759,7 +759,7 @@ function barcodeCheckInStockLocations(location_id, options={}) {
); );
} else { } else {
// Barcode does not match a valid stock location // Barcode does not match a valid stock location
showBarcodeMessage(modal, '{% trans "Barcode does not match valid stock location" %}', 'warning'); showBarcodeMessage(modal, '{% jstrans "Barcode does not match valid stock location" %}', 'warning');
} }
} }
} }
@ -792,7 +792,7 @@ function scanItemsIntoLocation(item_list, options={}) {
if (location && location.pk) { if (location && location.pk) {
div.html(` div.html(`
<div class='alert alert-block alert-info'> <div class='alert alert-block alert-info'>
<b>{% trans "Location" %}</b></br> <b>{% jstrans "Location" %}</b></br>
${location.name}<br> ${location.name}<br>
<i>${location.description}</i> <i>${location.description}</i>
</div> </div>
@ -803,13 +803,13 @@ function scanItemsIntoLocation(item_list, options={}) {
} }
barcodeDialog( barcodeDialog(
'{% trans "Check Into Location" %}', '{% jstrans "Check Into Location" %}',
{ {
headerContent: header, headerContent: header,
extraFields: extra, extraFields: extra,
modal: modal, modal: modal,
preShow: function() { preShow: function() {
modalSetSubmitText(modal, '{% trans "Check In" %}'); modalSetSubmitText(modal, '{% jstrans "Check In" %}');
modalEnable(modal, false); modalEnable(modal, false);
}, },
onShow: function() { onShow: function() {
@ -872,7 +872,7 @@ function scanItemsIntoLocation(item_list, options={}) {
// Barcode does *NOT* correspond to a StockLocation // Barcode does *NOT* correspond to a StockLocation
showBarcodeMessage( showBarcodeMessage(
modal, modal,
'{% trans "Barcode does not match a valid location" %}', '{% jstrans "Barcode does not match a valid location" %}',
'warning', 'warning',
); );
} }
@ -881,7 +881,7 @@ function scanItemsIntoLocation(item_list, options={}) {
// Barcode does *NOT* correspond to a StockLocation // Barcode does *NOT* correspond to a StockLocation
showBarcodeMessage( showBarcodeMessage(
modal, modal,
'{% trans "Barcode does not match a valid location" %}', '{% jstrans "Barcode does not match a valid location" %}',
'warning', 'warning',
); );
} }

View File

@ -75,7 +75,7 @@ function addBomItem(part_id, options={}) {
constructForm('{% url "api-bom-list" %}', { constructForm('{% url "api-bom-list" %}', {
fields: fields, fields: fields,
method: 'POST', method: 'POST',
title: '{% trans "Create BOM Item" %}', title: '{% jstrans "Create BOM Item" %}',
focus: 'sub_part', focus: 'sub_part',
onSuccess: function(response) { onSuccess: function(response) {
handleFormSuccess(response, options); handleFormSuccess(response, options);
@ -129,8 +129,8 @@ function constructBomUploadTable(data, options={}) {
let buttons = ''; let buttons = '';
buttons += makeInfoButton('button-row-data', idx, '{% trans "Display row data" %}'); buttons += makeInfoButton('button-row-data', idx, '{% jstrans "Display row data" %}');
buttons += makeRemoveButton('button-row-remove', idx, '{% trans "Remove row" %}'); buttons += makeRemoveButton('button-row-remove', idx, '{% jstrans "Remove row" %}');
buttons = wrapButtons(buttons); buttons = wrapButtons(buttons);
@ -185,8 +185,8 @@ function constructBomUploadTable(data, options={}) {
$(`#button-row-data-${idx}`).click(function() { $(`#button-row-data-${idx}`).click(function() {
var modal = createNewModal({ var modal = createNewModal({
title: '{% trans "Row Data" %}', title: '{% jstrans "Row Data" %}',
closeText: '{% trans "Close" %}', closeText: '{% jstrans "Close" %}',
hideSubmitButton: true hideSubmitButton: true
}); });
@ -303,11 +303,11 @@ function downloadBomTemplate(options={}) {
} }
constructFormBody({}, { constructFormBody({}, {
title: '{% trans "Download BOM Template" %}', title: '{% jstrans "Download BOM Template" %}',
fields: { fields: {
format: { format: {
label: '{% trans "Format" %}', label: '{% jstrans "Format" %}',
help_text: '{% trans "Select file format" %}', help_text: '{% jstrans "Select file format" %}',
required: true, required: true,
type: 'choice', type: 'choice',
value: format, value: format,
@ -337,63 +337,63 @@ function downloadBomTemplate(options={}) {
function exportBom(part_id, options={}) { function exportBom(part_id, options={}) {
constructFormBody({}, { constructFormBody({}, {
title: '{% trans "Export BOM" %}', title: '{% jstrans "Export BOM" %}',
fields: { fields: {
format: { format: {
label: '{% trans "Format" %}', label: '{% jstrans "Format" %}',
help_text: '{% trans "Select file format" %}', help_text: '{% jstrans "Select file format" %}',
required: true, required: true,
type: 'choice', type: 'choice',
value: inventreeLoad('bom-export-format', 'csv'), value: inventreeLoad('bom-export-format', 'csv'),
choices: exportFormatOptions(), choices: exportFormatOptions(),
}, },
cascade: { cascade: {
label: '{% trans "Multi Level BOM" %}', label: '{% jstrans "Multi Level BOM" %}',
help_text: '{% trans "Include BOM data for subassemblies" %}', help_text: '{% jstrans "Include BOM data for subassemblies" %}',
type: 'boolean', type: 'boolean',
value: inventreeLoad('bom-export-cascading', true), value: inventreeLoad('bom-export-cascading', true),
}, },
levels: { levels: {
label: '{% trans "Levels" %}', label: '{% jstrans "Levels" %}',
help_text: '{% trans "Select maximum number of BOM levels to export (0 = all levels)" %}', help_text: '{% jstrans "Select maximum number of BOM levels to export (0 = all levels)" %}',
type: 'integer', type: 'integer',
value: 0, value: 0,
required: true, required: true,
min_value: 0, min_value: 0,
}, },
substitute_part_data: { substitute_part_data: {
label: '{% trans "Include Alternative Parts" %}', label: '{% jstrans "Include Alternative Parts" %}',
help_text: '{% trans "Include alternative parts in exported BOM" %}', help_text: '{% jstrans "Include alternative parts in exported BOM" %}',
type: 'boolean', type: 'boolean',
value: inventreeLoad('bom-export-substitute_part_data', false), value: inventreeLoad('bom-export-substitute_part_data', false),
}, },
parameter_data: { parameter_data: {
label: '{% trans "Include Parameter Data" %}', label: '{% jstrans "Include Parameter Data" %}',
help_text: '{% trans "Include part parameter data in exported BOM" %}', help_text: '{% jstrans "Include part parameter data in exported BOM" %}',
type: 'boolean', type: 'boolean',
value: inventreeLoad('bom-export-parameter_data', false), value: inventreeLoad('bom-export-parameter_data', false),
}, },
stock_data: { stock_data: {
label: '{% trans "Include Stock Data" %}', label: '{% jstrans "Include Stock Data" %}',
help_text: '{% trans "Include part stock data in exported BOM" %}', help_text: '{% jstrans "Include part stock data in exported BOM" %}',
type: 'boolean', type: 'boolean',
value: inventreeLoad('bom-export-stock_data', false), value: inventreeLoad('bom-export-stock_data', false),
}, },
manufacturer_data: { manufacturer_data: {
label: '{% trans "Include Manufacturer Data" %}', label: '{% jstrans "Include Manufacturer Data" %}',
help_text: '{% trans "Include part manufacturer data in exported BOM" %}', help_text: '{% jstrans "Include part manufacturer data in exported BOM" %}',
type: 'boolean', type: 'boolean',
value: inventreeLoad('bom-export-manufacturer_data', false), value: inventreeLoad('bom-export-manufacturer_data', false),
}, },
supplier_data: { supplier_data: {
label: '{% trans "Include Supplier Data" %}', label: '{% jstrans "Include Supplier Data" %}',
help_text: '{% trans "Include part supplier data in exported BOM" %}', help_text: '{% jstrans "Include part supplier data in exported BOM" %}',
type: 'boolean', type: 'boolean',
value: inventreeLoad('bom-export-supplier_data', false), value: inventreeLoad('bom-export-supplier_data', false),
}, },
pricing_data: { pricing_data: {
label: '{% trans "Include Pricing Data" %}', label: '{% jstrans "Include Pricing Data" %}',
help_text: '{% trans "Include part pricing data in exported BOM" %}', help_text: '{% jstrans "Include part pricing data in exported BOM" %}',
type: 'boolean', type: 'boolean',
value: inventreeLoad('bom-export-pricing_data', false), value: inventreeLoad('bom-export-pricing_data', false),
} }
@ -441,7 +441,7 @@ function bomItemFields() {
sub_part: { sub_part: {
icon: 'fa-shapes', icon: 'fa-shapes',
secondary: { secondary: {
title: '{% trans "New Part" %}', title: '{% jstrans "New Part" %}',
fields: function() { fields: function() {
var fields = partFields(); var fields = partFields();
@ -588,7 +588,7 @@ function bomSubstitutesDialog(bom_item_id, substitutes, options={}) {
var buttons = ''; var buttons = '';
buttons += makeRemoveButton('button-row-remove', pk, '{% trans "Remove substitute part" %}'); buttons += makeRemoveButton('button-row-remove', pk, '{% jstrans "Remove substitute part" %}');
// Render a single row // Render a single row
var html = ` var html = `
@ -619,7 +619,7 @@ function bomSubstitutesDialog(bom_item_id, substitutes, options={}) {
var html = ` var html = `
<div class='alert alert-block'> <div class='alert alert-block'>
<strong>{% trans "Base Part" %}</strong><hr> <strong>{% jstrans "Base Part" %}</strong><hr>
${part_thumb} ${part_name} - <em>${part_desc}</em> ${part_thumb} ${part_name} - <em>${part_desc}</em>
</div> </div>
`; `;
@ -629,8 +629,8 @@ function bomSubstitutesDialog(bom_item_id, substitutes, options={}) {
<table class='table table-striped table-condensed' id='substitute-table'> <table class='table table-striped table-condensed' id='substitute-table'>
<thead> <thead>
<tr> <tr>
<th>{% trans "Part" %}</th> <th>{% jstrans "Part" %}</th>
<th>{% trans "Description" %}</th> <th>{% jstrans "Description" %}</th>
<th><!-- Actions --></th> <th><!-- Actions --></th>
</tr> </tr>
</thead> </thead>
@ -642,7 +642,7 @@ function bomSubstitutesDialog(bom_item_id, substitutes, options={}) {
html += ` html += `
<div class='alert alert-success alert-block'> <div class='alert alert-success alert-block'>
{% trans "Select and add a new substitute part using the input below" %} {% jstrans "Select and add a new substitute part using the input below" %}
</div> </div>
`; `;
@ -653,13 +653,13 @@ function bomSubstitutesDialog(bom_item_id, substitutes, options={}) {
var pre = ` var pre = `
<div class='alert alert-block alert-warning'> <div class='alert alert-block alert-warning'>
{% trans "Are you sure you wish to remove this substitute part link?" %} {% jstrans "Are you sure you wish to remove this substitute part link?" %}
</div> </div>
`; `;
constructForm(`{% url "api-bom-substitute-list" %}${pk}/`, { constructForm(`{% url "api-bom-substitute-list" %}${pk}/`, {
method: 'DELETE', method: 'DELETE',
title: '{% trans "Remove Substitute Part" %}', title: '{% jstrans "Remove Substitute Part" %}',
preFormContent: pre, preFormContent: pre,
confirm: true, confirm: true,
onSuccess: function() { onSuccess: function() {
@ -697,9 +697,9 @@ function bomSubstitutesDialog(bom_item_id, substitutes, options={}) {
}, },
}, },
preFormContent: html, preFormContent: html,
closeText: '{% trans "Close" %}', closeText: '{% jstrans "Close" %}',
submitText: '{% trans "Add Substitute" %}', submitText: '{% jstrans "Add Substitute" %}',
title: '{% trans "Edit BOM Item Substitutes" %}', title: '{% jstrans "Edit BOM Item Substitutes" %}',
afterRender: function(fields, opts) { afterRender: function(fields, opts) {
addRemoveCallback(opts.modal, '.button-row-remove'); addRemoveCallback(opts.modal, '.button-row-remove');
}, },
@ -761,14 +761,14 @@ function deleteBomItems(items, options={}) {
var html = ` var html = `
<div class='alert alert-block alert-danger'> <div class='alert alert-block alert-danger'>
{% trans "All selected BOM items will be deleted" %} {% jstrans "All selected BOM items will be deleted" %}
</div> </div>
<table class='table table-striped table-condensed'> <table class='table table-striped table-condensed'>
<tr> <tr>
<th>{% trans "Part" %}</th> <th>{% jstrans "Part" %}</th>
<th>{% trans "Reference" %}</th> <th>{% jstrans "Reference" %}</th>
<th>{% trans "Quantity" %}</th> <th>{% jstrans "Quantity" %}</th>
</tr> </tr>
${rows} ${rows}
</table> </table>
@ -777,7 +777,7 @@ function deleteBomItems(items, options={}) {
constructForm('{% url "api-bom-list" %}', { constructForm('{% url "api-bom-list" %}', {
method: 'DELETE', method: 'DELETE',
multi_delete: true, multi_delete: true,
title: '{% trans "Delete selected BOM items?" %}', title: '{% jstrans "Delete selected BOM items?" %}',
form_data: { form_data: {
items: ids, items: ids,
}, },
@ -823,7 +823,7 @@ function loadBomTable(table, options={}) {
label: 'actions', label: 'actions',
actions: [{ actions: [{
label: 'delete', label: 'delete',
title: '{% trans "Delete items" %}', title: '{% jstrans "Delete items" %}',
icon: 'fa-trash-alt icon-red', icon: 'fa-trash-alt icon-red',
permission: 'part.change', permission: 'part.change',
callback: function(data) { callback: function(data) {
@ -902,7 +902,7 @@ function loadBomTable(table, options={}) {
cols.push( cols.push(
{ {
field: 'sub_part', field: 'sub_part',
title: '{% trans "Part" %}', title: '{% jstrans "Part" %}',
sortable: true, sortable: true,
switchable: false, switchable: false,
sorter: function(_valA, _valB, rowA, rowB) { sorter: function(_valA, _valB, rowA, rowB) {
@ -933,7 +933,7 @@ function loadBomTable(table, options={}) {
} else { } else {
html += ` html += `
<a href='#' pk='${row.pk}' class='load-sub-assembly' id='load-sub-assembly-${row.pk}'> <a href='#' pk='${row.pk}' class='load-sub-assembly' id='load-sub-assembly-${row.pk}'>
<span class='fas fa-sync-alt' title='{% trans "Load BOM for subassembly" %}'></span> <span class='fas fa-sync-alt' title='{% jstrans "Load BOM for subassembly" %}'></span>
</a> `; </a> `;
} }
} }
@ -943,11 +943,11 @@ function loadBomTable(table, options={}) {
html += makePartIcons(sub_part); html += makePartIcons(sub_part);
if (row.substitutes && row.substitutes.length > 0) { if (row.substitutes && row.substitutes.length > 0) {
html += makeIconBadge('fa-exchange-alt', '{% trans "Substitutes Available" %}'); html += makeIconBadge('fa-exchange-alt', '{% jstrans "Substitutes Available" %}');
} }
if (row.allow_variants) { if (row.allow_variants) {
html += makeIconBadge('fa-sitemap', '{% trans "Variant stock allowed" %}'); html += makeIconBadge('fa-sitemap', '{% jstrans "Variant stock allowed" %}');
} }
return html; return html;
@ -960,7 +960,7 @@ function loadBomTable(table, options={}) {
cols.push( cols.push(
{ {
field: 'sub_part_detail.description', field: 'sub_part_detail.description',
title: '{% trans "Description" %}', title: '{% jstrans "Description" %}',
formatter: function(value) { formatter: function(value) {
return withTitle(shortenString(value), value); return withTitle(shortenString(value), value);
} }
@ -970,7 +970,7 @@ function loadBomTable(table, options={}) {
// Part reference // Part reference
cols.push({ cols.push({
field: 'reference', field: 'reference',
title: '{% trans "Reference" %}', title: '{% jstrans "Reference" %}',
searchable: true, searchable: true,
sortable: true, sortable: true,
}); });
@ -978,7 +978,7 @@ function loadBomTable(table, options={}) {
// Part quantity // Part quantity
cols.push({ cols.push({
field: 'quantity', field: 'quantity',
title: '{% trans "Quantity" %}', title: '{% jstrans "Quantity" %}',
searchable: false, searchable: false,
sortable: true, sortable: true,
switchable: false, switchable: false,
@ -994,11 +994,11 @@ function loadBomTable(table, options={}) {
} }
if (row.consumable) { if (row.consumable) {
text += ` <small>({% trans "Consumable" %})</small>`; text += ` <small>({% jstrans "Consumable" %})</small>`;
} }
if (row.optional) { if (row.optional) {
text += ' <small>({% trans "Optional" %})</small>'; text += ' <small>({% jstrans "Optional" %})</small>';
} }
if (row.overage) { if (row.overage) {
@ -1011,7 +1011,7 @@ function loadBomTable(table, options={}) {
cols.push({ cols.push({
field: 'substitutes', field: 'substitutes',
title: '{% trans "Substitutes" %}', title: '{% jstrans "Substitutes" %}',
searchable: false, searchable: false,
sortable: true, sortable: true,
formatter: function(value, row) { formatter: function(value, row) {
@ -1025,7 +1025,7 @@ function loadBomTable(table, options={}) {
cols.push({ cols.push({
field: 'optional', field: 'optional',
title: '{% trans "Optional" %}', title: '{% jstrans "Optional" %}',
searchable: false, searchable: false,
formatter: function(value) { formatter: function(value) {
return yesNoLabel(value); return yesNoLabel(value);
@ -1034,7 +1034,7 @@ function loadBomTable(table, options={}) {
cols.push({ cols.push({
field: 'consumable', field: 'consumable',
title: '{% trans "Consumable" %}', title: '{% jstrans "Consumable" %}',
searchable: false, searchable: false,
formatter: function(value) { formatter: function(value) {
return yesNoLabel(value); return yesNoLabel(value);
@ -1043,7 +1043,7 @@ function loadBomTable(table, options={}) {
cols.push({ cols.push({
field: 'allow_variants', field: 'allow_variants',
title: '{% trans "Allow Variants" %}', title: '{% jstrans "Allow Variants" %}',
formatter: function(value) { formatter: function(value) {
return yesNoLabel(value); return yesNoLabel(value);
} }
@ -1051,7 +1051,7 @@ function loadBomTable(table, options={}) {
cols.push({ cols.push({
field: 'inherited', field: 'inherited',
title: '{% trans "Gets inherited" %}', title: '{% jstrans "Gets inherited" %}',
searchable: false, searchable: false,
formatter: function(value, row) { formatter: function(value, row) {
// This BOM item *is* inheritable, but is defined for this BOM // This BOM item *is* inheritable, but is defined for this BOM
@ -1068,7 +1068,7 @@ function loadBomTable(table, options={}) {
cols.push({ cols.push({
field: 'pricing', field: 'pricing',
title: '{% trans "Price Range" %}', title: '{% jstrans "Price Range" %}',
sortable: true, sortable: true,
sorter: function(valA, valB, rowA, rowB) { sorter: function(valA, valB, rowA, rowB) {
var a = rowA.pricing_min || rowA.pricing_max; var a = rowA.pricing_min || rowA.pricing_max;
@ -1136,19 +1136,19 @@ function loadBomTable(table, options={}) {
if (complete_pricing) { if (complete_pricing) {
html += makeIconBadge( html += makeIconBadge(
'fa-check-circle icon-green', 'fa-check-circle icon-green',
'{% trans "BOM pricing is complete" %}', '{% jstrans "BOM pricing is complete" %}',
); );
} else { } else {
html += makeIconBadge( html += makeIconBadge(
'fa-exclamation-circle icon-yellow', 'fa-exclamation-circle icon-yellow',
'{% trans "BOM pricing is incomplete" %}', '{% jstrans "BOM pricing is incomplete" %}',
); );
} }
return html; return html;
} else { } else {
let html = '<em>{% trans "No pricing available" %}</em>'; let html = '<em>{% jstrans "No pricing available" %}</em>';
html += makeIconBadge('fa-times-circle icon-red'); html += makeIconBadge('fa-times-circle icon-red');
return html; return html;
@ -1159,7 +1159,7 @@ function loadBomTable(table, options={}) {
cols.push({ cols.push({
field: 'available_stock', field: 'available_stock',
title: '{% trans "Available" %}', title: '{% jstrans "Available" %}',
searchable: false, searchable: false,
sortable: true, sortable: true,
formatter: function(value, row) { formatter: function(value, row) {
@ -1179,16 +1179,16 @@ function loadBomTable(table, options={}) {
} }
if (available_stock <= 0) { if (available_stock <= 0) {
text += makeIconBadge('fa-times-circle icon-red', '{% trans "No Stock Available" %}'); text += makeIconBadge('fa-times-circle icon-red', '{% jstrans "No Stock Available" %}');
} else { } else {
var extra = ''; var extra = '';
if ((substitute_stock > 0) && (variant_stock > 0)) { if ((substitute_stock > 0) && (variant_stock > 0)) {
extra = '{% trans "Includes variant and substitute stock" %}'; extra = '{% jstrans "Includes variant and substitute stock" %}';
} else if (variant_stock > 0) { } else if (variant_stock > 0) {
extra = '{% trans "Includes variant stock" %}'; extra = '{% jstrans "Includes variant stock" %}';
} else if (substitute_stock > 0) { } else if (substitute_stock > 0) {
extra = '{% trans "Includes substitute stock" %}'; extra = '{% jstrans "Includes substitute stock" %}';
} }
if (extra) { if (extra) {
@ -1199,7 +1199,7 @@ function loadBomTable(table, options={}) {
if (row.on_order && row.on_order > 0) { if (row.on_order && row.on_order > 0) {
text += makeIconBadge( text += makeIconBadge(
'fa-shopping-cart', 'fa-shopping-cart',
`{% trans "On Order" %}: ${row.on_order}`, `{% jstrans "On Order" %}: ${row.on_order}`,
); );
} }
@ -1210,13 +1210,13 @@ function loadBomTable(table, options={}) {
cols.push( cols.push(
{ {
field: 'can_build', field: 'can_build',
title: '{% trans "Can Build" %}', title: '{% jstrans "Can Build" %}',
sortable: true, sortable: true,
formatter: function(value, row) { formatter: function(value, row) {
// "Consumable" parts are not tracked in the build // "Consumable" parts are not tracked in the build
if (row.consumable) { if (row.consumable) {
return `<em>{% trans "Consumable item" %}</em>`; return `<em>{% jstrans "Consumable item" %}</em>`;
} }
var can_build = canBuildQuantity(row); var can_build = canBuildQuantity(row);
@ -1256,7 +1256,7 @@ function loadBomTable(table, options={}) {
cols.push( cols.push(
{ {
field: 'note', field: 'note',
title: '{% trans "Notes" %}', title: '{% jstrans "Notes" %}',
searchable: true, searchable: true,
sortable: true, sortable: true,
formatter: function(value) { formatter: function(value) {
@ -1268,7 +1268,7 @@ function loadBomTable(table, options={}) {
if (options.editable) { if (options.editable) {
cols.push({ cols.push({
title: '{% trans "Actions" %}', title: '{% jstrans "Actions" %}',
switchable: false, switchable: false,
field: 'pk', field: 'pk',
visible: true, visible: true,
@ -1276,15 +1276,15 @@ function loadBomTable(table, options={}) {
if (row.part == options.parent_id) { if (row.part == options.parent_id) {
var bValidate = makeIconButton('fa-check-circle icon-green', 'bom-validate-button', row.pk, '{% trans "Validate BOM Item" %}'); var bValidate = makeIconButton('fa-check-circle icon-green', 'bom-validate-button', row.pk, '{% jstrans "Validate BOM Item" %}');
var bValid = makeIconButton('fa-check-double icon-green', 'bom-valid-button', row.pk, '{% trans "This line has been validated" %}', {disabled: true}); var bValid = makeIconButton('fa-check-double icon-green', 'bom-valid-button', row.pk, '{% jstrans "This line has been validated" %}', {disabled: true});
var bSubs = makeIconButton('fa-exchange-alt icon-blue', 'bom-substitutes-button', row.pk, '{% trans "Edit substitute parts" %}'); var bSubs = makeIconButton('fa-exchange-alt icon-blue', 'bom-substitutes-button', row.pk, '{% jstrans "Edit substitute parts" %}');
var bEdit = makeEditButton('bom-edit-button', row.pk, '{% trans "Edit BOM Item" %}'); var bEdit = makeEditButton('bom-edit-button', row.pk, '{% jstrans "Edit BOM Item" %}');
var bDelt = makeDeleteButton('bom-delete-button', row.pk, '{% trans "Delete BOM Item" %}'); var bDelt = makeDeleteButton('bom-delete-button', row.pk, '{% jstrans "Delete BOM Item" %}');
let buttons = ''; let buttons = '';
@ -1304,15 +1304,15 @@ function loadBomTable(table, options={}) {
// Return a link to the external BOM // Return a link to the external BOM
return renderLink( return renderLink(
'{% trans "View BOM" %}', '{% jstrans "View BOM" %}',
`/part/${row.part}/bom/` `/part/${row.part}/bom/`
); );
} }
}, },
footerFormatter: function(data) { footerFormatter: function(data) {
return ` return `
<button class='btn btn-success float-right' type='button' title='{% trans "Add BOM Item" %}' id='bom-item-new-footer'> <button class='btn btn-success float-right' type='button' title='{% jstrans "Add BOM Item" %}' id='bom-item-new-footer'>
${makeIcon('fa-plus-circle')} {% trans "Add BOM Item" %} ${makeIcon('fa-plus-circle')} {% jstrans "Add BOM Item" %}
</button> </button>
`; `;
} }
@ -1388,7 +1388,7 @@ function loadBomTable(table, options={}) {
}, },
formatNoMatches: function() { formatNoMatches: function() {
return '{% trans "No BOM items found" %}'; return '{% jstrans "No BOM items found" %}';
}, },
queryParams: filters, queryParams: filters,
original: params, original: params,
@ -1477,7 +1477,7 @@ function loadBomTable(table, options={}) {
constructForm(`{% url "api-bom-list" %}${pk}/`, { constructForm(`{% url "api-bom-list" %}${pk}/`, {
fields: fields, fields: fields,
title: '{% trans "Edit BOM Item" %}', title: '{% jstrans "Edit BOM Item" %}',
focus: 'sub_part', focus: 'sub_part',
onSuccess: function() { onSuccess: function() {
reloadBomTable(table); reloadBomTable(table);
@ -1630,7 +1630,7 @@ function loadUsedInTable(table, part_id, options={}) {
}, },
{ {
field: 'part', field: 'part',
title: '{% trans "Assembly" %}', title: '{% jstrans "Assembly" %}',
switchable: false, switchable: false,
sortable: true, sortable: true,
formatter: function(value, row) { formatter: function(value, row) {
@ -1648,7 +1648,7 @@ function loadUsedInTable(table, part_id, options={}) {
}, },
{ {
field: 'sub_part', field: 'sub_part',
title: '{% trans "Required Part" %}', title: '{% jstrans "Required Part" %}',
sortable: true, sortable: true,
formatter: function(value, row) { formatter: function(value, row) {
var url = `/part/${value}/`; var url = `/part/${value}/`;
@ -1665,7 +1665,7 @@ function loadUsedInTable(table, part_id, options={}) {
}, },
{ {
field: 'quantity', field: 'quantity',
title: '{% trans "Required Quantity" %}', title: '{% jstrans "Required Quantity" %}',
formatter: function(value, row) { formatter: function(value, row) {
var html = value; var html = value;
@ -1674,7 +1674,7 @@ function loadUsedInTable(table, part_id, options={}) {
} }
if (row.parent && row.parent != 'top-level-item') { if (row.parent && row.parent != 'top-level-item') {
html += ` <em>({% trans "Inherited from parent BOM" %})</em>`; html += ` <em>({% jstrans "Inherited from parent BOM" %})</em>`;
} }
return html; return html;

View File

@ -139,7 +139,7 @@ function editBuildOrder(pk) {
constructForm(`{% url "api-build-list" %}${pk}/`, { constructForm(`{% url "api-build-list" %}${pk}/`, {
fields: fields, fields: fields,
reload: true, reload: true,
title: '{% trans "Edit Build Order" %}', title: '{% jstrans "Edit Build Order" %}',
}); });
} }
@ -182,7 +182,7 @@ function newBuildOrder(options={}) {
data: options.data, data: options.data,
follow: true, follow: true,
method: 'POST', method: 'POST',
title: '{% trans "Create Build Order" %}', title: '{% jstrans "Create Build Order" %}',
onSuccess: options.onSuccess, onSuccess: options.onSuccess,
}); });
} }
@ -214,7 +214,7 @@ function cancelBuildOrder(build_id, options={}) {
`{% url "api-build-list" %}${build_id}/cancel/`, `{% url "api-build-list" %}${build_id}/cancel/`,
{ {
method: 'POST', method: 'POST',
title: '{% trans "Cancel Build Order" %}', title: '{% jstrans "Cancel Build Order" %}',
confirm: true, confirm: true,
fields: { fields: {
remove_allocated_stock: {}, remove_allocated_stock: {},
@ -223,20 +223,20 @@ function cancelBuildOrder(build_id, options={}) {
preFormContent: function(opts) { preFormContent: function(opts) {
var html = ` var html = `
<div class='alert alert-block alert-info'> <div class='alert alert-block alert-info'>
{% trans "Are you sure you wish to cancel this build?" %} {% jstrans "Are you sure you wish to cancel this build?" %}
</div>`; </div>`;
if (opts.context.has_allocated_stock) { if (opts.context.has_allocated_stock) {
html += ` html += `
<div class='alert alert-block alert-warning'> <div class='alert alert-block alert-warning'>
{% trans "Stock items have been allocated to this build order" %} {% jstrans "Stock items have been allocated to this build order" %}
</div>`; </div>`;
} }
if (opts.context.incomplete_outputs) { if (opts.context.incomplete_outputs) {
html += ` html += `
<div class='alert alert-block alert-warning'> <div class='alert alert-block alert-warning'>
{% trans "There are incomplete outputs remaining for this build order" %} {% jstrans "There are incomplete outputs remaining for this build order" %}
</div>`; </div>`;
} }
@ -288,30 +288,30 @@ function completeBuildOrder(build_id, options={}) {
if (ctx.allocated && ctx.remaining == 0 && ctx.incomplete == 0) { if (ctx.allocated && ctx.remaining == 0 && ctx.incomplete == 0) {
html += ` html += `
<div class='alert alert-block alert-success'> <div class='alert alert-block alert-success'>
{% trans "Build order is ready to be completed" %}' {% jstrans "Build order is ready to be completed" %}'
</div>`; </div>`;
} else { } else {
if (ctx.incomplete > 0) { if (ctx.incomplete > 0) {
html += ` html += `
<div class='alert alert-block alert-danger'> <div class='alert alert-block alert-danger'>
<strong>{% trans "Build order has incomplete outputs" %}</strong><br> <strong>{% jstrans "Build order has incomplete outputs" %}</strong><br>
{% trans "This build order cannot be completed as there are incomplete outputs" %} {% jstrans "This build order cannot be completed as there are incomplete outputs" %}
</div>`; </div>`;
} else { } else {
html += ` html += `
<div class='alert alert-block alert-danger'> <div class='alert alert-block alert-danger'>
<strong>{% trans "Build Order is incomplete" %}</strong> <strong>{% jstrans "Build Order is incomplete" %}</strong>
</div> </div>
`; `;
} }
if (!ctx.allocated) { if (!ctx.allocated) {
html += `<div class='alert alert-block alert-warning'>{% trans "Required stock has not been fully allocated" %}</div>`; html += `<div class='alert alert-block alert-warning'>{% jstrans "Required stock has not been fully allocated" %}</div>`;
} }
if (ctx.remaining > 0) { if (ctx.remaining > 0) {
html += `<div class='alert alert-block alert-warning'>{% trans "Required build quantity has not been completed" %}</div>`; html += `<div class='alert alert-block alert-warning'>{% jstrans "Required build quantity has not been completed" %}</div>`;
} }
} }
@ -319,7 +319,7 @@ function completeBuildOrder(build_id, options={}) {
}, },
reload: true, reload: true,
confirm: true, confirm: true,
title: '{% trans "Complete Build Order" %}', title: '{% jstrans "Complete Build Order" %}',
method: 'POST', method: 'POST',
}); });
} }
@ -360,9 +360,9 @@ function createBuildOutput(build_id, options) {
inventreeGet(`{% url "api-part-list" %}${build.part}/serial-numbers/`, {}, { inventreeGet(`{% url "api-part-list" %}${build.part}/serial-numbers/`, {}, {
success: function(data) { success: function(data) {
if (data.next) { if (data.next) {
fields.serial_numbers.placeholder = `{% trans "Next available serial number" %}: ${data.next}`; fields.serial_numbers.placeholder = `{% jstrans "Next available serial number" %}: ${data.next}`;
} else if (data.latest) { } else if (data.latest) {
fields.serial_numbers.placeholder = `{% trans "Latest serial number" %}: ${data.latest}`; fields.serial_numbers.placeholder = `{% jstrans "Latest serial number" %}: ${data.latest}`;
} }
}, },
async: false, async: false,
@ -371,8 +371,8 @@ function createBuildOutput(build_id, options) {
if (options.trackable_parts) { if (options.trackable_parts) {
html += ` html += `
<div class='alert alert-block alert-info'> <div class='alert alert-block alert-info'>
{% trans "The Bill of Materials contains trackable parts" %}.<br> {% jstrans "The Bill of Materials contains trackable parts" %}.<br>
{% trans "Build outputs must be generated individually" %}. {% jstrans "Build outputs must be generated individually" %}.
</div> </div>
`; `;
} }
@ -380,15 +380,15 @@ function createBuildOutput(build_id, options) {
if (trackable) { if (trackable) {
html += ` html += `
<div class='alert alert-block alert-info'> <div class='alert alert-block alert-info'>
{% trans "Trackable parts can have serial numbers specified" %}<br> {% jstrans "Trackable parts can have serial numbers specified" %}<br>
{% trans "Enter serial numbers to generate multiple single build outputs" %} {% jstrans "Enter serial numbers to generate multiple single build outputs" %}
</div> </div>
`; `;
} }
constructForm(`{% url "api-build-list" %}${build_id}/create-output/`, { constructForm(`{% url "api-build-list" %}${build_id}/create-output/`, {
method: 'POST', method: 'POST',
title: '{% trans "Create Build Output" %}', title: '{% jstrans "Create Build Output" %}',
confirm: true, confirm: true,
fields: fields, fields: fields,
preFormContent: html, preFormContent: html,
@ -419,7 +419,7 @@ function makeBuildOutputButtons(output_id, build_info, options={}) {
'fa-sign-in-alt icon-blue', 'fa-sign-in-alt icon-blue',
'button-output-allocate', 'button-output-allocate',
output_id, output_id,
'{% trans "Allocate stock items to this build output" %}', '{% jstrans "Allocate stock items to this build output" %}',
); );
// Add a button to deallocate stock from this build output // Add a button to deallocate stock from this build output
@ -427,7 +427,7 @@ function makeBuildOutputButtons(output_id, build_info, options={}) {
'fa-minus-circle icon-red', 'fa-minus-circle icon-red',
'button-output-deallocate', 'button-output-deallocate',
output_id, output_id,
'{% trans "Deallocate stock from build output" %}', '{% jstrans "Deallocate stock from build output" %}',
); );
} }
@ -436,7 +436,7 @@ function makeBuildOutputButtons(output_id, build_info, options={}) {
'fa-check-circle icon-green', 'fa-check-circle icon-green',
'button-output-complete', 'button-output-complete',
output_id, output_id,
'{% trans "Complete build output" %}', '{% jstrans "Complete build output" %}',
); );
// Add a button to "scrap" the build output // Add a button to "scrap" the build output
@ -444,14 +444,14 @@ function makeBuildOutputButtons(output_id, build_info, options={}) {
'fa-times-circle icon-red', 'fa-times-circle icon-red',
'button-output-scrap', 'button-output-scrap',
output_id, output_id,
'{% trans "Scrap build output" %}', '{% jstrans "Scrap build output" %}',
); );
// Add a button to "remove" this build output // Add a button to "remove" this build output
html += makeDeleteButton( html += makeDeleteButton(
'button-output-remove', 'button-output-remove',
output_id, output_id,
'{% trans "Delete build output" %}', '{% jstrans "Delete build output" %}',
); );
return wrapButtons(html); return wrapButtons(html);
@ -471,7 +471,7 @@ function deallocateStock(build_id, options={}) {
var html = ` var html = `
<div class='alert alert-block alert-warning'> <div class='alert alert-block alert-warning'>
{% trans "Are you sure you wish to deallocate the selected stock items from this build?" %} {% jstrans "Are you sure you wish to deallocate the selected stock items from this build?" %}
</dvi> </dvi>
`; `;
@ -489,7 +489,7 @@ function deallocateStock(build_id, options={}) {
value: options.build_line, value: options.build_line,
}, },
}, },
title: '{% trans "Deallocate Stock Items" %}', title: '{% jstrans "Deallocate Stock Items" %}',
onSuccess: function(response, opts) { onSuccess: function(response, opts) {
if (options.onSuccess) { if (options.onSuccess) {
options.onSuccess(response, opts); options.onSuccess(response, opts);
@ -511,9 +511,9 @@ function renderBuildOutput(output, options={}) {
let output_html = imageHoverIcon(output.part_detail.thumbnail); let output_html = imageHoverIcon(output.part_detail.thumbnail);
if (output.quantity == 1 && output.serial) { if (output.quantity == 1 && output.serial) {
output_html += `{% trans "Serial Number" %}: ${output.serial}`; output_html += `{% jstrans "Serial Number" %}: ${output.serial}`;
} else { } else {
output_html += `{% trans "Quantity" %}: ${output.quantity}`; output_html += `{% jstrans "Quantity" %}: ${output.quantity}`;
if (output.part_detail && output.part_detail.units) { if (output.part_detail && output.part_detail.units) {
output_html += ` ${output.part_detail.units} `; output_html += ` ${output.part_detail.units} `;
} }
@ -521,7 +521,7 @@ function renderBuildOutput(output, options={}) {
let buttons = `<div class='btn-group float-right' role='group'>`; let buttons = `<div class='btn-group float-right' role='group'>`;
buttons += makeRemoveButton('button-row-remove', pk, '{% trans "Remove row" %}'); buttons += makeRemoveButton('button-row-remove', pk, '{% jstrans "Remove row" %}');
buttons += '</div>'; buttons += '</div>';
@ -575,8 +575,8 @@ function completeBuildOutputs(build_id, outputs, options={}) {
if (outputs.length == 0) { if (outputs.length == 0) {
showAlertDialog( showAlertDialog(
'{% trans "Select Build Outputs" %}', '{% jstrans "Select Build Outputs" %}',
'{% trans "At least one build output must be selected" %}', '{% jstrans "At least one build output must be selected" %}',
); );
return; return;
} }
@ -590,11 +590,11 @@ function completeBuildOutputs(build_id, outputs, options={}) {
var html = ` var html = `
<div class='alert alert-block alert-success'> <div class='alert alert-block alert-success'>
{% trans "Selected build outputs will be marked as complete" %} {% jstrans "Selected build outputs will be marked as complete" %}
</div> </div>
<table class='table table-striped table-condensed' id='build-complete-table'> <table class='table table-striped table-condensed' id='build-complete-table'>
<thead> <thead>
<th colspan='2'>{% trans "Output" %}</th> <th colspan='2'>{% jstrans "Output" %}</th>
<th><!-- Actions --></th> <th><!-- Actions --></th>
</thead> </thead>
<tbody> <tbody>
@ -622,7 +622,7 @@ function completeBuildOutputs(build_id, outputs, options={}) {
accept_incomplete_allocation: {}, accept_incomplete_allocation: {},
}, },
confirm: true, confirm: true,
title: '{% trans "Complete Build Outputs" %}', title: '{% jstrans "Complete Build Outputs" %}',
afterRender: function(fields, opts) { afterRender: function(fields, opts) {
// Setup callbacks to remove outputs // Setup callbacks to remove outputs
$(opts.modal).find('.button-row-remove').click(function() { $(opts.modal).find('.button-row-remove').click(function() {
@ -703,8 +703,8 @@ function scrapBuildOutputs(build_id, outputs, options={}) {
if (outputs.length == 0) { if (outputs.length == 0) {
showAlertDialog( showAlertDialog(
'{% trans "Select Build Outputs" %}', '{% jstrans "Select Build Outputs" %}',
'{% trans "At least one build output must be selected" %}', '{% jstrans "At least one build output must be selected" %}',
); );
return; return;
} }
@ -719,17 +719,17 @@ function scrapBuildOutputs(build_id, outputs, options={}) {
var html = ` var html = `
<div class='alert alert-block alert-danger'> <div class='alert alert-block alert-danger'>
{% trans "Selected build outputs will be marked as scrapped" %} {% jstrans "Selected build outputs will be marked as scrapped" %}
<ul> <ul>
<li>{% trans "Scrapped output are marked as rejected" %}</li> <li>{% jstrans "Scrapped output are marked as rejected" %}</li>
<li>{% trans "Allocated stock items will no longer be available" %}</li> <li>{% jstrans "Allocated stock items will no longer be available" %}</li>
<li>{% trans "The completion status of the build order will not be adjusted" %}</li> <li>{% jstrans "The completion status of the build order will not be adjusted" %}</li>
</ul> </ul>
</div> </div>
<table class='table table-striped table-condensed' id='build-scrap-table'> <table class='table table-striped table-condensed' id='build-scrap-table'>
<thead> <thead>
<th colspan='2'>{% trans "Output" %}</th> <th colspan='2'>{% jstrans "Output" %}</th>
<th>{% trans "Quantity" %}</th> <th>{% jstrans "Quantity" %}</th>
<th><!-- Actions --></th> <th><!-- Actions --></th>
</thead> </thead>
<tbody> <tbody>
@ -754,7 +754,7 @@ function scrapBuildOutputs(build_id, outputs, options={}) {
discard_allocations: {}, discard_allocations: {},
}, },
confirm: true, confirm: true,
title: '{% trans "Scrap Build Outputs" %}', title: '{% jstrans "Scrap Build Outputs" %}',
afterRender: function(fields, opts) { afterRender: function(fields, opts) {
// Setup callbacks to remove outputs // Setup callbacks to remove outputs
$(opts.modal).find('.button-row-remove').click(function() { $(opts.modal).find('.button-row-remove').click(function() {
@ -829,8 +829,8 @@ function deleteBuildOutputs(build_id, outputs, options={}) {
if (outputs.length == 0) { if (outputs.length == 0) {
showAlertDialog( showAlertDialog(
'{% trans "Select Build Outputs" %}', '{% jstrans "Select Build Outputs" %}',
'{% trans "At least one build output must be selected" %}', '{% jstrans "At least one build output must be selected" %}',
); );
return; return;
} }
@ -844,15 +844,15 @@ function deleteBuildOutputs(build_id, outputs, options={}) {
var html = ` var html = `
<div class='alert alert-block alert-danger'> <div class='alert alert-block alert-danger'>
{% trans "Selected build outputs will be deleted" %} {% jstrans "Selected build outputs will be deleted" %}
<ul> <ul>
<li>{% trans "Build output data will be permanently deleted" %}</li> <li>{% jstrans "Build output data will be permanently deleted" %}</li>
<li>{% trans "Allocated stock items will be returned to stock" %}</li> <li>{% jstrans "Allocated stock items will be returned to stock" %}</li>
</ul> </ul>
</div> </div>
<table class='table table-striped table-condensed' id='build-complete-table'> <table class='table table-striped table-condensed' id='build-complete-table'>
<thead> <thead>
<th colspan='2'>{% trans "Output" %}</th> <th colspan='2'>{% jstrans "Output" %}</th>
<th><!-- Actions --></th> <th><!-- Actions --></th>
</thead> </thead>
<tbody> <tbody>
@ -865,7 +865,7 @@ function deleteBuildOutputs(build_id, outputs, options={}) {
preFormContent: html, preFormContent: html,
fields: {}, fields: {},
confirm: true, confirm: true,
title: '{% trans "Delete Build Outputs" %}', title: '{% jstrans "Delete Build Outputs" %}',
afterRender: function(fields, opts) { afterRender: function(fields, opts) {
// Setup callbacks to remove outputs // Setup callbacks to remove outputs
$(opts.modal).find('.button-row-remove').click(function() { $(opts.modal).find('.button-row-remove').click(function() {
@ -952,7 +952,7 @@ function loadBuildOrderAllocationTable(table, options={}) {
paginationVAlign: 'bottom', paginationVAlign: 'bottom',
original: options.params, original: options.params,
formatNoMatches: function() { formatNoMatches: function() {
return '{% trans "No build order allocations found" %}'; return '{% jstrans "No build order allocations found" %}';
}, },
columns: [ columns: [
{ {
@ -964,7 +964,7 @@ function loadBuildOrderAllocationTable(table, options={}) {
field: 'build', field: 'build',
sortable: true, sortable: true,
switchable: false, switchable: false,
title: '{% trans "Build Order" %}', title: '{% jstrans "Build Order" %}',
formatter: function(value, row) { formatter: function(value, row) {
let ref = `${row.build_detail.reference}`; let ref = `${row.build_detail.reference}`;
let html = renderLink(ref, `/build/${row.build}/`); let html = renderLink(ref, `/build/${row.build}/`);
@ -981,7 +981,7 @@ function loadBuildOrderAllocationTable(table, options={}) {
{ {
field: 'quantity', field: 'quantity',
sortable: true, sortable: true,
title: '{% trans "Allocated Quantity" %}', title: '{% jstrans "Allocated Quantity" %}',
formatter: function(value, row) { formatter: function(value, row) {
let link = `/stock/item/${row.stock_item}/`; let link = `/stock/item/${row.stock_item}/`;
let text = formatDecimal(value); let text = formatDecimal(value);
@ -991,11 +991,11 @@ function loadBuildOrderAllocationTable(table, options={}) {
}, },
{ {
field: 'location_detail', field: 'location_detail',
title: '{% trans "Location" %}', title: '{% jstrans "Location" %}',
formatter: function(value, row) { formatter: function(value, row) {
if (!value) { if (!value) {
return '{% trans "Location not specified" %}'; return '{% jstrans "Location not specified" %}';
} }
let item = row.stock_item_detail; let item = row.stock_item_detail;
@ -1017,7 +1017,7 @@ function makeBuildOutputActions(build_info) {
return [ return [
{ {
label: 'complete', label: 'complete',
title: '{% trans "Complete outputs" %}', title: '{% jstrans "Complete outputs" %}',
icon: 'fa-check-circle icon-green', icon: 'fa-check-circle icon-green',
permission: 'build.add', permission: 'build.add',
callback: function(data) { callback: function(data) {
@ -1035,7 +1035,7 @@ function makeBuildOutputActions(build_info) {
}, },
{ {
label: 'scrap', label: 'scrap',
title: '{% trans "Scrap outputs" %}', title: '{% jstrans "Scrap outputs" %}',
icon: 'fa-times-circle icon-red', icon: 'fa-times-circle icon-red',
permission: 'build.change', permission: 'build.change',
callback: function(data) { callback: function(data) {
@ -1053,7 +1053,7 @@ function makeBuildOutputActions(build_info) {
}, },
{ {
label: 'delete', label: 'delete',
title: '{% trans "Delete outputs" %}', title: '{% jstrans "Delete outputs" %}',
icon: 'fa-trash-alt icon-red', icon: 'fa-trash-alt icon-red',
permission: 'build.delete', permission: 'build.delete',
callback: function(data) { callback: function(data) {
@ -1107,12 +1107,12 @@ function loadBuildOutputTable(build_info, options={}) {
url: '{% url "api-stockitem-label-list" %}', url: '{% url "api-stockitem-label-list" %}',
key: 'item', key: 'item',
}, },
singular_name: '{% trans "build output" %}', singular_name: '{% jstrans "build output" %}',
plural_name: '{% trans "build outputs" %}', plural_name: '{% jstrans "build outputs" %}',
custom_actions: [{ custom_actions: [{
label: 'buildoutput', label: 'buildoutput',
icon: 'fa-tools', icon: 'fa-tools',
title: '{% trans "Build output actions" %}', title: '{% jstrans "Build output actions" %}',
actions: makeBuildOutputActions(build_info), actions: makeBuildOutputActions(build_info),
}] }]
}); });
@ -1281,7 +1281,7 @@ function loadBuildOutputTable(build_info, options={}) {
return constructOutputSubTable(index, row, element); return constructOutputSubTable(index, row, element);
}, },
formatNoMatches: function() { formatNoMatches: function() {
return '{% trans "No active build outputs found" %}'; return '{% jstrans "No active build outputs found" %}';
}, },
onLoadSuccess: function() { onLoadSuccess: function() {
reloadOutputAllocations(); reloadOutputAllocations();
@ -1296,7 +1296,7 @@ function loadBuildOutputTable(build_info, options={}) {
}, },
{ {
field: 'part', field: 'part',
title: '{% trans "Part" %}', title: '{% jstrans "Part" %}',
switchable: false, switchable: false,
formatter: function(value, row) { formatter: function(value, row) {
return imageHoverIcon(row.part_detail.thumbnail) + return imageHoverIcon(row.part_detail.thumbnail) +
@ -1306,7 +1306,7 @@ function loadBuildOutputTable(build_info, options={}) {
}, },
{ {
field: 'quantity', field: 'quantity',
title: '{% trans "Build Output" %}', title: '{% jstrans "Build Output" %}',
switchable: false, switchable: false,
sortable: true, sortable: true,
sorter: function(fieldA, fieldB, rowA, rowB) { sorter: function(fieldA, fieldB, rowA, rowB) {
@ -1351,9 +1351,9 @@ function loadBuildOutputTable(build_info, options={}) {
let text = ''; let text = '';
if (row.serial && row.quantity == 1) { if (row.serial && row.quantity == 1) {
text = `{% trans "Serial Number" %}: ${row.serial}`; text = `{% jstrans "Serial Number" %}: ${row.serial}`;
} else { } else {
text = `{% trans "Quantity" %}: ${row.quantity}`; text = `{% jstrans "Quantity" %}: ${row.quantity}`;
} }
@ -1364,7 +1364,7 @@ function loadBuildOutputTable(build_info, options={}) {
} }
if (row.batch) { if (row.batch) {
text += ` <small>({% trans "Batch" %}: ${row.batch})</small>`; text += ` <small>({% jstrans "Batch" %}: ${row.batch})</small>`;
} }
text += stockStatusDisplay(row.status, {classes: 'float-right'}); text += stockStatusDisplay(row.status, {classes: 'float-right'});
@ -1374,7 +1374,7 @@ function loadBuildOutputTable(build_info, options={}) {
}, },
{ {
field: 'fully_allocated', field: 'fully_allocated',
title: '{% trans "Allocated Lines" %}', title: '{% jstrans "Allocated Lines" %}',
visible: false, visible: false,
sortable: true, sortable: true,
switchable: false, switchable: false,
@ -1388,7 +1388,7 @@ function loadBuildOutputTable(build_info, options={}) {
}, },
{ {
field: 'tests', field: 'tests',
title: '{% trans "Required Tests" %}', title: '{% jstrans "Required Tests" %}',
visible: test_templates.length > 0, visible: test_templates.length > 0,
switchable: true, switchable: true,
sortable: true, sortable: true,
@ -1560,8 +1560,8 @@ function allocateStockToBuild(build_id, line_items, options={}) {
if (line_items.length == 0) { if (line_items.length == 0) {
showAlertDialog( showAlertDialog(
'{% trans "Select Parts" %}', '{% jstrans "Select Parts" %}',
'{% trans "You must select at least one part to allocate" %}', '{% jstrans "You must select at least one part to allocate" %}',
); );
return; return;
@ -1613,7 +1613,7 @@ function allocateStockToBuild(build_id, line_items, options={}) {
delete_button += makeRemoveButton( delete_button += makeRemoveButton(
'button-row-remove', 'button-row-remove',
pk, pk,
'{% trans "Remove row" %}', '{% jstrans "Remove row" %}',
); );
delete_button += `</div>`; delete_button += `</div>`;
@ -1624,7 +1624,7 @@ function allocateStockToBuild(build_id, line_items, options={}) {
type: 'decimal', type: 'decimal',
min_value: 0, min_value: 0,
value: quantity || 0, value: quantity || 0,
title: '{% trans "Specify stock allocation quantity" %}', title: '{% jstrans "Specify stock allocation quantity" %}',
required: true, required: true,
}, },
{ {
@ -1701,8 +1701,8 @@ function allocateStockToBuild(build_id, line_items, options={}) {
if (table_entries.length == 0) { if (table_entries.length == 0) {
showAlertDialog( showAlertDialog(
'{% trans "All Parts Allocated" %}', '{% jstrans "All Parts Allocated" %}',
'{% trans "All selected parts have been fully allocated" %}', '{% jstrans "All selected parts have been fully allocated" %}',
); );
return; return;
@ -1715,8 +1715,8 @@ function allocateStockToBuild(build_id, line_items, options={}) {
'take_from', 'take_from',
{ {
type: 'related field', type: 'related field',
label: '{% trans "Source Location" %}', label: '{% jstrans "Source Location" %}',
help_text: '{% trans "Select source location (leave blank to take from all locations)" %}', help_text: '{% jstrans "Select source location (leave blank to take from all locations)" %}',
required: false, required: false,
}, },
{}, {},
@ -1727,10 +1727,10 @@ function allocateStockToBuild(build_id, line_items, options={}) {
<table class='table table-striped table-condensed' id='stock-allocation-table'> <table class='table table-striped table-condensed' id='stock-allocation-table'>
<thead> <thead>
<tr> <tr>
<th>{% trans "Part" %}</th> <th>{% jstrans "Part" %}</th>
<th>{% trans "Allocated" %}</th> <th>{% jstrans "Allocated" %}</th>
<th style='min-width: 250px;'>{% trans "Stock Item" %}</th> <th style='min-width: 250px;'>{% jstrans "Stock Item" %}</th>
<th>{% trans "Quantity" %}</th> <th>{% jstrans "Quantity" %}</th>
<th></th> <th></th>
</tr> </tr>
</thead> </thead>
@ -1744,7 +1744,7 @@ function allocateStockToBuild(build_id, line_items, options={}) {
method: 'POST', method: 'POST',
fields: {}, fields: {},
preFormContent: html, preFormContent: html,
title: '{% trans "Allocate Stock Items to Build Order" %}', title: '{% jstrans "Allocate Stock Items to Build Order" %}',
afterRender: function(fields, options) { afterRender: function(fields, options) {
var take_from_field = { var take_from_field = {
@ -1755,7 +1755,7 @@ function allocateStockToBuild(build_id, line_items, options={}) {
type: 'related field', type: 'related field',
value: source_location, value: source_location,
noResults: function(query) { noResults: function(query) {
return '{% trans "No matching stock locations" %}'; return '{% jstrans "No matching stock locations" %}';
}, },
}; };
@ -1828,7 +1828,7 @@ function allocateStockToBuild(build_id, line_items, options={}) {
return filters; return filters;
}, },
noResults: function(query) { noResults: function(query) {
return '{% trans "No matching stock items" %}'; return '{% jstrans "No matching stock items" %}';
} }
}, },
null, null,
@ -1925,12 +1925,12 @@ function autoAllocateStockToBuild(build_id, bom_items=[], options={}) {
var html = ` var html = `
<div class='alert alert-block alert-info'> <div class='alert alert-block alert-info'>
<strong>{% trans "Automatic Stock Allocation" %}</strong><br> <strong>{% jstrans "Automatic Stock Allocation" %}</strong><br>
{% trans "Stock items will be automatically allocated to this build order, according to the provided guidelines" %}: {% jstrans "Stock items will be automatically allocated to this build order, according to the provided guidelines" %}:
<ul> <ul>
<li>{% trans "If a location is specified, stock will only be allocated from that location" %}</li> <li>{% jstrans "If a location is specified, stock will only be allocated from that location" %}</li>
<li>{% trans "If stock is considered interchangeable, it will be allocated from the first location it is found" %}</li> <li>{% jstrans "If stock is considered interchangeable, it will be allocated from the first location it is found" %}</li>
<li>{% trans "If substitute stock is allowed, it will be used where stock of the primary part cannot be found" %}</li> <li>{% jstrans "If substitute stock is allowed, it will be used where stock of the primary part cannot be found" %}</li>
</ul> </ul>
</div> </div>
`; `;
@ -1961,7 +1961,7 @@ function autoAllocateStockToBuild(build_id, bom_items=[], options={}) {
constructForm(`{% url "api-build-list" %}${build_id}/auto-allocate/`, { constructForm(`{% url "api-build-list" %}${build_id}/auto-allocate/`, {
method: 'POST', method: 'POST',
fields: fields, fields: fields,
title: '{% trans "Allocate Stock Items" %}', title: '{% jstrans "Allocate Stock Items" %}',
confirm: true, confirm: true,
preFormContent: html, preFormContent: html,
onSuccess: function(response) { onSuccess: function(response) {
@ -2067,7 +2067,7 @@ function loadBuildTable(table, options) {
$(table).inventreeTable({ $(table).inventreeTable({
method: 'get', method: 'get',
formatNoMatches: function() { formatNoMatches: function() {
return '{% trans "No builds matching query" %}'; return '{% jstrans "No builds matching query" %}';
}, },
url: '{% url "api-build-list" %}', url: '{% url "api-build-list" %}',
queryParams: filters, queryParams: filters,
@ -2102,13 +2102,13 @@ function loadBuildTable(table, options) {
}, },
{ {
checkbox: true, checkbox: true,
title: '{% trans "Select" %}', title: '{% jstrans "Select" %}',
searchable: false, searchable: false,
switchable: false, switchable: false,
}, },
{ {
field: 'reference', field: 'reference',
title: '{% trans "Build" %}', title: '{% jstrans "Build" %}',
sortable: true, sortable: true,
switchable: true, switchable: true,
formatter: function(value, row) { formatter: function(value, row) {
@ -2116,7 +2116,7 @@ function loadBuildTable(table, options) {
var html = renderLink(value, '/build/' + row.pk + '/'); var html = renderLink(value, '/build/' + row.pk + '/');
if (row.overdue) { if (row.overdue) {
html += makeIconBadge('fa-calendar-times icon-red', '{% trans "Build order is overdue" %}'); html += makeIconBadge('fa-calendar-times icon-red', '{% jstrans "Build order is overdue" %}');
} }
return html; return html;
@ -2124,12 +2124,12 @@ function loadBuildTable(table, options) {
}, },
{ {
field: 'title', field: 'title',
title: '{% trans "Description" %}', title: '{% jstrans "Description" %}',
switchable: true, switchable: true,
}, },
{ {
field: 'project_code', field: 'project_code',
title: '{% trans "Project Code" %}', title: '{% jstrans "Project Code" %}',
sortable: true, sortable: true,
switchable: global_settings.PROJECT_CODES_ENABLED, switchable: global_settings.PROJECT_CODES_ENABLED,
visible: global_settings.PROJECT_CODES_ENABLED, visible: global_settings.PROJECT_CODES_ENABLED,
@ -2141,13 +2141,13 @@ function loadBuildTable(table, options) {
}, },
{ {
field: 'priority', field: 'priority',
title: '{% trans "Priority" %}', title: '{% jstrans "Priority" %}',
switchable: true, switchable: true,
sortable: true, sortable: true,
}, },
{ {
field: 'part', field: 'part',
title: '{% trans "Part" %}', title: '{% jstrans "Part" %}',
sortable: true, sortable: true,
sortName: 'part__name', sortName: 'part__name',
formatter: function(value, row) { formatter: function(value, row) {
@ -2162,7 +2162,7 @@ function loadBuildTable(table, options) {
}, },
{ {
field: 'completed', field: 'completed',
title: '{% trans "Progress" %}', title: '{% jstrans "Progress" %}',
sortable: true, sortable: true,
formatter: function(value, row) { formatter: function(value, row) {
return makeProgressBar( return makeProgressBar(
@ -2176,7 +2176,7 @@ function loadBuildTable(table, options) {
}, },
{ {
field: 'status', field: 'status',
title: '{% trans "Status" %}', title: '{% jstrans "Status" %}',
sortable: true, sortable: true,
formatter: function(value) { formatter: function(value) {
return buildStatusDisplay(value); return buildStatusDisplay(value);
@ -2184,7 +2184,7 @@ function loadBuildTable(table, options) {
}, },
{ {
field: 'creation_date', field: 'creation_date',
title: '{% trans "Created" %}', title: '{% jstrans "Created" %}',
sortable: true, sortable: true,
formatter: function(value) { formatter: function(value) {
return renderDate(value); return renderDate(value);
@ -2192,19 +2192,19 @@ function loadBuildTable(table, options) {
}, },
{ {
field: 'issued_by', field: 'issued_by',
title: '{% trans "Issued by" %}', title: '{% jstrans "Issued by" %}',
sortable: true, sortable: true,
formatter: function(value, row) { formatter: function(value, row) {
if (value) { if (value) {
return row.issued_by_detail.username; return row.issued_by_detail.username;
} else { } else {
return `<i>{% trans "No user information" %}</i>`; return `<i>{% jstrans "No user information" %}</i>`;
} }
} }
}, },
{ {
field: 'responsible', field: 'responsible',
title: '{% trans "Responsible" %}', title: '{% jstrans "Responsible" %}',
sortable: true, sortable: true,
formatter: function(value, row) { formatter: function(value, row) {
if (!row.responsible_detail) { if (!row.responsible_detail) {
@ -2213,7 +2213,7 @@ function loadBuildTable(table, options) {
var html = row.responsible_detail.name; var html = row.responsible_detail.name;
if (row.responsible_detail.label == '{% trans "group" %}') { if (row.responsible_detail.label == '{% jstrans "group" %}') {
html += `<span class='float-right fas fa-users'></span>`; html += `<span class='float-right fas fa-users'></span>`;
} else { } else {
html += `<span class='float-right fas fa-user'></span>`; html += `<span class='float-right fas fa-user'></span>`;
@ -2224,7 +2224,7 @@ function loadBuildTable(table, options) {
}, },
{ {
field: 'target_date', field: 'target_date',
title: '{% trans "Target Date" %}', title: '{% jstrans "Target Date" %}',
sortable: true, sortable: true,
formatter: function(value) { formatter: function(value) {
return renderDate(value); return renderDate(value);
@ -2232,7 +2232,7 @@ function loadBuildTable(table, options) {
}, },
{ {
field: 'completion_date', field: 'completion_date',
title: '{% trans "Completion Date" %}', title: '{% jstrans "Completion Date" %}',
sortable: true, sortable: true,
formatter: function(value) { formatter: function(value) {
return renderDate(value); return renderDate(value);
@ -2320,7 +2320,7 @@ function renderBuildLineAllocationTable(element, build_line, options={}) {
columns: [ columns: [
{ {
field: 'part', field: 'part',
title: '{% trans "Part" %}', title: '{% jstrans "Part" %}',
formatter: function(_value, row) { formatter: function(_value, row) {
let html = imageHoverIcon(row.part_detail.thumbnail); let html = imageHoverIcon(row.part_detail.thumbnail);
html += renderLink(row.part_detail.full_name, `/part/${row.part_detail.pk}/`); html += renderLink(row.part_detail.full_name, `/part/${row.part_detail.pk}/`);
@ -2329,7 +2329,7 @@ function renderBuildLineAllocationTable(element, build_line, options={}) {
}, },
{ {
field: 'quantity', field: 'quantity',
title: '{% trans "Allocated Quantity" %}', title: '{% jstrans "Allocated Quantity" %}',
formatter: function(_value, row) { formatter: function(_value, row) {
let text = ''; let text = '';
let url = ''; let url = '';
@ -2340,9 +2340,9 @@ function renderBuildLineAllocationTable(element, build_line, options={}) {
} }
if (serial && row.quantity == 1) { if (serial && row.quantity == 1) {
text = `{% trans "Serial Number" %}: ${serial}`; text = `{% jstrans "Serial Number" %}: ${serial}`;
} else { } else {
text = `{% trans "Quantity" %}: ${row.quantity}`; text = `{% jstrans "Quantity" %}: ${row.quantity}`;
if (row.part_detail && row.part_detail.units) { if (row.part_detail && row.part_detail.units) {
text += ` <small>${row.part_detail.units}</small>`; text += ` <small>${row.part_detail.units}</small>`;
} }
@ -2357,7 +2357,7 @@ function renderBuildLineAllocationTable(element, build_line, options={}) {
}, },
{ {
field: 'location', field: 'location',
title: '{% trans "Location" %}', title: '{% jstrans "Location" %}',
formatter: function(value, row) { formatter: function(value, row) {
if (row.location_detail) { if (row.location_detail) {
let text = shortenString(row.location_detail.pathstring); let text = shortenString(row.location_detail.pathstring);
@ -2365,7 +2365,7 @@ function renderBuildLineAllocationTable(element, build_line, options={}) {
return renderLink(text, url); return renderLink(text, url);
} else { } else {
return '<i>{% trans "No location set" %}</i>'; return '<i>{% jstrans "No location set" %}</i>';
} }
} }
}, },
@ -2374,8 +2374,8 @@ function renderBuildLineAllocationTable(element, build_line, options={}) {
title: '', title: '',
formatter: function(value, row) { formatter: function(value, row) {
let buttons = ''; let buttons = '';
buttons += makeEditButton('button-allocation-edit', row.pk, '{% trans "Edit stock allocation" %}'); buttons += makeEditButton('button-allocation-edit', row.pk, '{% jstrans "Edit stock allocation" %}');
buttons += makeDeleteButton('button-allocation-delete', row.pk, '{% trans "Delete stock allocation" %}'); buttons += makeDeleteButton('button-allocation-delete', row.pk, '{% jstrans "Delete stock allocation" %}');
return wrapButtons(buttons); return wrapButtons(buttons);
} }
} }
@ -2390,7 +2390,7 @@ function renderBuildLineAllocationTable(element, build_line, options={}) {
fields: { fields: {
quantity: {}, quantity: {},
}, },
title: '{% trans "Edit Allocation" %}', title: '{% jstrans "Edit Allocation" %}',
onSuccess: function() { onSuccess: function() {
$(options.parent_table).bootstrapTable('refresh'); $(options.parent_table).bootstrapTable('refresh');
}, },
@ -2402,7 +2402,7 @@ function renderBuildLineAllocationTable(element, build_line, options={}) {
constructForm(`{% url "api-build-item-list" %}${pk}/`, { constructForm(`{% url "api-build-item-list" %}${pk}/`, {
method: 'DELETE', method: 'DELETE',
title: '{% trans "Remove Allocation" %}', title: '{% jstrans "Remove Allocation" %}',
onSuccess: function() { onSuccess: function() {
$(options.parent_table).bootstrapTable('refresh'); $(options.parent_table).bootstrapTable('refresh');
}, },
@ -2443,8 +2443,8 @@ function loadBuildLineTable(table, build_id, options={}) {
url: '{% url "api-buildline-label-list" %}', url: '{% url "api-buildline-label-list" %}',
key: 'line', key: 'line',
}, },
singular_name: '{% trans "build line" %}', singular_name: '{% jstrans "build line" %}',
plural_name: '{% trans "build lines" %}', plural_name: '{% jstrans "build lines" %}',
}); });
} }
@ -2462,18 +2462,18 @@ function loadBuildLineTable(table, build_id, options={}) {
}); });
}, },
formatNoMatches: function() { formatNoMatches: function() {
return '{% trans "No build lines found" %}'; return '{% jstrans "No build lines found" %}';
}, },
columns: [ columns: [
{ {
checkbox: true, checkbox: true,
title: '{% trans "Select" %}', title: '{% jstrans "Select" %}',
searchable: false, searchable: false,
switchable: false, switchable: false,
}, },
{ {
field: 'bom_item', field: 'bom_item',
title: '{% trans "Required Part" %}', title: '{% jstrans "Required Part" %}',
switchable: false, switchable: false,
sortable: true, sortable: true,
sortName: 'part', sortName: 'part',
@ -2488,11 +2488,11 @@ function loadBuildLineTable(table, build_id, options={}) {
html += imageHoverIcon(row.part_detail.thumbnail) + renderLink(row.part_detail.full_name, `/part/${row.part_detail.pk}/`); html += imageHoverIcon(row.part_detail.thumbnail) + renderLink(row.part_detail.full_name, `/part/${row.part_detail.pk}/`);
if (row.bom_item_detail.allow_variants) { if (row.bom_item_detail.allow_variants) {
html += makeIconBadge('fa-sitemap', '{% trans "Variant stock allowed" %}'); html += makeIconBadge('fa-sitemap', '{% jstrans "Variant stock allowed" %}');
} }
if (row.part_detail.trackable) { if (row.part_detail.trackable) {
html += makeIconBadge('fa-directions', '{% trans "Trackable part" %}'); html += makeIconBadge('fa-directions', '{% jstrans "Trackable part" %}');
} }
return html; return html;
@ -2500,7 +2500,7 @@ function loadBuildLineTable(table, build_id, options={}) {
}, },
{ {
field: 'reference', field: 'reference',
title: '{% trans "Reference" %}', title: '{% jstrans "Reference" %}',
sortable: true, sortable: true,
formatter: function(value, row) { formatter: function(value, row) {
return row.bom_item_detail.reference; return row.bom_item_detail.reference;
@ -2508,7 +2508,7 @@ function loadBuildLineTable(table, build_id, options={}) {
}, },
{ {
field: 'consumable', field: 'consumable',
title: '{% trans "Consumable" %}', title: '{% jstrans "Consumable" %}',
sortable: true, sortable: true,
switchable: true, switchable: true,
formatter: function(value, row) { formatter: function(value, row) {
@ -2517,7 +2517,7 @@ function loadBuildLineTable(table, build_id, options={}) {
}, },
{ {
field: 'optional', field: 'optional',
title: '{% trans "Optional" %}', title: '{% jstrans "Optional" %}',
sortable: true, sortable: true,
switchable: true, switchable: true,
formatter: function(value, row) { formatter: function(value, row) {
@ -2527,7 +2527,7 @@ function loadBuildLineTable(table, build_id, options={}) {
{ {
field: 'unit_quantity', field: 'unit_quantity',
sortable: true, sortable: true,
title: '{% trans "Unit Quantity" %}', title: '{% jstrans "Unit Quantity" %}',
formatter: function(value, row) { formatter: function(value, row) {
let text = row.bom_item_detail.quantity; let text = row.bom_item_detail.quantity;
@ -2544,12 +2544,12 @@ function loadBuildLineTable(table, build_id, options={}) {
}, },
{ {
field: 'quantity', field: 'quantity',
title: '{% trans "Required Quantity" %}', title: '{% jstrans "Required Quantity" %}',
sortable: true, sortable: true,
}, },
{ {
field: 'available_stock', field: 'available_stock',
title: '{% trans "Available" %}', title: '{% jstrans "Available" %}',
sortable: true, sortable: true,
formatter: function(value, row) { formatter: function(value, row) {
var url = `/part/${row.part_detail.pk}/?display=part-stock`; var url = `/part/${row.part_detail.pk}/?display=part-stock`;
@ -2573,24 +2573,24 @@ function loadBuildLineTable(table, build_id, options={}) {
let icons = ''; let icons = '';
if (row.bom_item_detail.consumable) { if (row.bom_item_detail.consumable) {
icons += `<span class='fas fa-info-circle icon-blue float-right' title='{% trans "Consumable item" %}'></span>`; icons += `<span class='fas fa-info-circle icon-blue float-right' title='{% jstrans "Consumable item" %}'></span>`;
} else { } else {
if (available < (row.quantity - row.allocated)) { if (available < (row.quantity - row.allocated)) {
icons += makeIconBadge('fa-times-circle icon-red', '{% trans "Insufficient stock available" %}'); icons += makeIconBadge('fa-times-circle icon-red', '{% jstrans "Insufficient stock available" %}');
} else { } else {
icons += makeIconBadge('fa-check-circle icon-green', '{% trans "Sufficient stock available" %}'); icons += makeIconBadge('fa-check-circle icon-green', '{% jstrans "Sufficient stock available" %}');
} }
if (available <= 0) { if (available <= 0) {
icons += `<span class='badge rounded-pill bg-danger'>{% trans "No Stock Available" %}</span>`; icons += `<span class='badge rounded-pill bg-danger'>{% jstrans "No Stock Available" %}</span>`;
} else { } else {
let extra = ''; let extra = '';
if ((row.available_substitute_stock > 0) && (row.available_variant_stock > 0)) { if ((row.available_substitute_stock > 0) && (row.available_variant_stock > 0)) {
extra = '{% trans "Includes variant and substitute stock" %}'; extra = '{% jstrans "Includes variant and substitute stock" %}';
} else if (row.available_variant_stock > 0) { } else if (row.available_variant_stock > 0) {
extra = '{% trans "Includes variant stock" %}'; extra = '{% jstrans "Includes variant stock" %}';
} else if (row.available_substitute_stock > 0) { } else if (row.available_substitute_stock > 0) {
extra = '{% trans "Includes substitute stock" %}'; extra = '{% jstrans "Includes substitute stock" %}';
} }
if (extra) { if (extra) {
@ -2600,7 +2600,7 @@ function loadBuildLineTable(table, build_id, options={}) {
} }
if (row.on_order && row.on_order > 0) { if (row.on_order && row.on_order > 0) {
icons += makeIconBadge('fa-shopping-cart', `{% trans "On Order" %}: ${formatDecimal(row.on_order)}`); icons += makeIconBadge('fa-shopping-cart', `{% jstrans "On Order" %}: ${formatDecimal(row.on_order)}`);
} }
return renderLink(text, url) + icons; return renderLink(text, url) + icons;
@ -2608,7 +2608,7 @@ function loadBuildLineTable(table, build_id, options={}) {
}, },
{ {
field: 'allocated', field: 'allocated',
title: '{% trans "Allocated" %}', title: '{% jstrans "Allocated" %}',
sortable: true, sortable: true,
formatter: function(value, row) { formatter: function(value, row) {
return makeProgressBar(row.allocated, row.quantity); return makeProgressBar(row.allocated, row.quantity);
@ -2625,32 +2625,32 @@ function loadBuildLineTable(table, build_id, options={}) {
// Consumable items do not need to be allocated // Consumable items do not need to be allocated
if (row.bom_item_detail.consumable) { if (row.bom_item_detail.consumable) {
return `<em>{% trans "Consumable Item" %}</em>`; return `<em>{% jstrans "Consumable Item" %}</em>`;
} }
if (row.part_detail.trackable && !options.output) { if (row.part_detail.trackable && !options.output) {
// Tracked parts must be allocated to a specific build output // Tracked parts must be allocated to a specific build output
return `<em>{% trans "Tracked item" %}</em>`; return `<em>{% jstrans "Tracked item" %}</em>`;
} }
if (row.allocated < row.quantity) { if (row.allocated < row.quantity) {
// Add a button to "build" stock for this line // Add a button to "build" stock for this line
if (row.part_detail.assembly) { if (row.part_detail.assembly) {
buttons += makeIconButton('fa-tools icon-blue', 'button-build', pk, '{% trans "Build stock" %}'); buttons += makeIconButton('fa-tools icon-blue', 'button-build', pk, '{% jstrans "Build stock" %}');
} }
// Add a button to "purchase" stock for this line // Add a button to "purchase" stock for this line
if (row.part_detail.purchaseable) { if (row.part_detail.purchaseable) {
buttons += makeIconButton('fa-shopping-cart icon-blue', 'button-buy', pk, '{% trans "Order stock" %}'); buttons += makeIconButton('fa-shopping-cart icon-blue', 'button-buy', pk, '{% jstrans "Order stock" %}');
} }
// Add a button to "allocate" stock for this line // Add a button to "allocate" stock for this line
buttons += makeIconButton('fa-sign-in-alt icon-green', 'button-allocate', pk, '{% trans "Allocate stock" %}'); buttons += makeIconButton('fa-sign-in-alt icon-green', 'button-allocate', pk, '{% jstrans "Allocate stock" %}');
} }
if (row.allocated > 0) { if (row.allocated > 0) {
buttons += makeRemoveButton('button-unallocate', pk, '{% trans "Remove stock allocation" %}'); buttons += makeRemoveButton('button-unallocate', pk, '{% jstrans "Remove stock allocation" %}');
} }
return wrapButtons(buttons); return wrapButtons(buttons);

View File

@ -95,7 +95,7 @@ function createManufacturerPart(options={}) {
} }
fields.manufacturer.secondary = { fields.manufacturer.secondary = {
title: '{% trans "Add Manufacturer" %}', title: '{% jstrans "Add Manufacturer" %}',
fields: function() { fields: function() {
var company_fields = companyFormFields(); var company_fields = companyFormFields();
@ -108,7 +108,7 @@ function createManufacturerPart(options={}) {
constructForm('{% url "api-manufacturer-part-list" %}', { constructForm('{% url "api-manufacturer-part-list" %}', {
fields: fields, fields: fields,
method: 'POST', method: 'POST',
title: '{% trans "Add Manufacturer Part" %}', title: '{% jstrans "Add Manufacturer Part" %}',
onSuccess: options.onSuccess onSuccess: options.onSuccess
}); });
} }
@ -129,7 +129,7 @@ function editManufacturerPart(part, options={}) {
constructForm(url, { constructForm(url, {
fields: fields, fields: fields,
title: '{% trans "Edit Manufacturer Part" %}', title: '{% jstrans "Edit Manufacturer Part" %}',
onSuccess: options.onSuccess onSuccess: options.onSuccess
}); });
} }
@ -198,7 +198,7 @@ function createSupplierPart(options={}) {
// Add a secondary modal for the supplier // Add a secondary modal for the supplier
fields.supplier.secondary = { fields.supplier.secondary = {
title: '{% trans "Add Supplier" %}', title: '{% jstrans "Add Supplier" %}',
fields: function() { fields: function() {
var company_fields = companyFormFields(); var company_fields = companyFormFields();
@ -210,7 +210,7 @@ function createSupplierPart(options={}) {
// Add a secondary modal for the manufacturer part // Add a secondary modal for the manufacturer part
fields.manufacturer_part.secondary = { fields.manufacturer_part.secondary = {
title: '{% trans "Add Manufacturer Part" %}', title: '{% jstrans "Add Manufacturer Part" %}',
fields: function(data) { fields: function(data) {
var mp_fields = manufacturerPartFields(); var mp_fields = manufacturerPartFields();
@ -240,7 +240,7 @@ function createSupplierPart(options={}) {
constructForm('{% url "api-supplier-part-list" %}', { constructForm('{% url "api-supplier-part-list" %}', {
fields: fields, fields: fields,
method: 'POST', method: 'POST',
title: '{% trans "Add Supplier Part" %}', title: '{% jstrans "Add Supplier Part" %}',
onSuccess: options.onSuccess, onSuccess: options.onSuccess,
header_html: header, header_html: header,
}); });
@ -266,7 +266,7 @@ function duplicateSupplierPart(part, options={}) {
constructForm('{% url "api-supplier-part-list" %}', { constructForm('{% url "api-supplier-part-list" %}', {
method: 'POST', method: 'POST',
fields: fields, fields: fields,
title: '{% trans "Duplicate Supplier Part" %}', title: '{% jstrans "Duplicate Supplier Part" %}',
data: data, data: data,
onSuccess: function(response) { onSuccess: function(response) {
handleFormSuccess(response, options); handleFormSuccess(response, options);
@ -291,7 +291,7 @@ function editSupplierPart(part, options={}) {
constructForm(`{% url "api-supplier-part-list" %}${part}/`, { constructForm(`{% url "api-supplier-part-list" %}${part}/`, {
fields: fields, fields: fields,
title: options.title || '{% trans "Edit Supplier Part" %}', title: options.title || '{% jstrans "Edit Supplier Part" %}',
onSuccess: options.onSuccess onSuccess: options.onSuccess
}); });
} }
@ -341,14 +341,14 @@ function deleteSupplierParts(parts, options={}) {
var html = ` var html = `
<div class='alert alert-block alert-danger'> <div class='alert alert-block alert-danger'>
{% trans "All selected supplier parts will be deleted" %} {% jstrans "All selected supplier parts will be deleted" %}
</div> </div>
<table class='table table-striped table-condensed'> <table class='table table-striped table-condensed'>
<tr> <tr>
<th>{% trans "Part" %}</th> <th>{% jstrans "Part" %}</th>
<th>{% trans "SKU" %}</th> <th>{% jstrans "SKU" %}</th>
<th>{% trans "Supplier" %}</th> <th>{% jstrans "Supplier" %}</th>
<th>{% trans "MPN" %}</th> <th>{% jstrans "MPN" %}</th>
</tr> </tr>
${rows} ${rows}
</table> </table>
@ -357,7 +357,7 @@ function deleteSupplierParts(parts, options={}) {
constructForm('{% url "api-supplier-part-list" %}', { constructForm('{% url "api-supplier-part-list" %}', {
method: 'DELETE', method: 'DELETE',
multi_delete: true, multi_delete: true,
title: '{% trans "Delete Supplier Parts" %}', title: '{% jstrans "Delete Supplier Parts" %}',
preFormContent: html, preFormContent: html,
form_data: { form_data: {
items: ids, items: ids,
@ -395,7 +395,7 @@ function createSupplierPartPriceBreak(part_id, options={}) {
constructForm('{% url "api-part-supplier-price-list" %}', { constructForm('{% url "api-part-supplier-price-list" %}', {
fields: fields, fields: fields,
method: 'POST', method: 'POST',
title: '{% trans "Add Price Break" %}', title: '{% jstrans "Add Price Break" %}',
onSuccess: function(response) { onSuccess: function(response) {
handleFormSuccess(response, options); handleFormSuccess(response, options);
} }
@ -441,7 +441,7 @@ function editCompany(pk, options={}) {
method: 'PATCH', method: 'PATCH',
fields: fields, fields: fields,
reload: true, reload: true,
title: '{% trans "Edit Company" %}', title: '{% jstrans "Edit Company" %}',
} }
); );
} }
@ -462,7 +462,7 @@ function createCompany(options={}) {
method: 'POST', method: 'POST',
fields: fields, fields: fields,
follow: true, follow: true,
title: '{% trans "Add new Company" %}', title: '{% jstrans "Add new Company" %}',
} }
); );
} }
@ -492,22 +492,22 @@ function loadCompanyTable(table, url, options={}) {
}, },
{ {
field: 'name', field: 'name',
title: '{% trans "Company" %}', title: '{% jstrans "Company" %}',
sortable: true, sortable: true,
switchable: false, switchable: false,
formatter: function(value, row) { formatter: function(value, row) {
var html = imageHoverIcon(row.image) + renderLink(value, row.url); var html = imageHoverIcon(row.image) + renderLink(value, row.url);
if (row.is_customer) { if (row.is_customer) {
html += `<span title='{% trans "Customer" %}' class='fas fa-user-tie float-right'></span>`; html += `<span title='{% jstrans "Customer" %}' class='fas fa-user-tie float-right'></span>`;
} }
if (row.is_manufacturer) { if (row.is_manufacturer) {
html += `<span title='{% trans "Manufacturer" %}' class='fas fa-industry float-right'></span>`; html += `<span title='{% jstrans "Manufacturer" %}' class='fas fa-industry float-right'></span>`;
} }
if (row.is_supplier) { if (row.is_supplier) {
html += `<span title='{% trans "Supplier" %}' class='fas fa-building float-right'></span>`; html += `<span title='{% jstrans "Supplier" %}' class='fas fa-building float-right'></span>`;
} }
return html; return html;
@ -515,11 +515,11 @@ function loadCompanyTable(table, url, options={}) {
}, },
{ {
field: 'description', field: 'description',
title: '{% trans "Description" %}', title: '{% jstrans "Description" %}',
}, },
{ {
field: 'website', field: 'website',
title: '{% trans "Website" %}', title: '{% jstrans "Website" %}',
formatter: function(value) { formatter: function(value) {
if (value) { if (value) {
return renderLink(value, value); return renderLink(value, value);
@ -533,7 +533,7 @@ function loadCompanyTable(table, url, options={}) {
columns.push({ columns.push({
sortable: true, sortable: true,
field: 'parts_supplied', field: 'parts_supplied',
title: '{% trans "Parts Supplied" %}', title: '{% jstrans "Parts Supplied" %}',
formatter: function(value, row) { formatter: function(value, row) {
return renderLink(value, `/company/${row.pk}/?display=supplier-parts`); return renderLink(value, `/company/${row.pk}/?display=supplier-parts`);
} }
@ -542,7 +542,7 @@ function loadCompanyTable(table, url, options={}) {
columns.push({ columns.push({
sortable: true, sortable: true,
field: 'parts_manufactured', field: 'parts_manufactured',
title: '{% trans "Parts Manufactured" %}', title: '{% jstrans "Parts Manufactured" %}',
formatter: function(value, row) { formatter: function(value, row) {
return renderLink(value, `/company/${row.pk}/?display=manufacturer-parts`); return renderLink(value, `/company/${row.pk}/?display=manufacturer-parts`);
} }
@ -557,7 +557,7 @@ function loadCompanyTable(table, url, options={}) {
groupBy: false, groupBy: false,
sidePagination: 'server', sidePagination: 'server',
formatNoMatches: function() { formatNoMatches: function() {
return '{% trans "No company information found" %}'; return '{% jstrans "No company information found" %}';
}, },
showColumns: true, showColumns: true,
name: options.pagetype || 'company', name: options.pagetype || 'company',
@ -606,7 +606,7 @@ function createContact(options={}) {
constructForm('{% url "api-contact-list" %}', { constructForm('{% url "api-contact-list" %}', {
method: 'POST', method: 'POST',
fields: fields, fields: fields,
title: '{% trans "Create New Contact" %}', title: '{% jstrans "Create New Contact" %}',
onSuccess: function(response) { onSuccess: function(response) {
handleFormSuccess(response, options); handleFormSuccess(response, options);
} }
@ -622,7 +622,7 @@ function editContact(pk, options={}) {
constructForm(`{% url "api-contact-list" %}${pk}/`, { constructForm(`{% url "api-contact-list" %}${pk}/`, {
fields: fields, fields: fields,
title: '{% trans "Edit Contact" %}', title: '{% jstrans "Edit Contact" %}',
onSuccess: function(response) { onSuccess: function(response) {
handleFormSuccess(response, options); handleFormSuccess(response, options);
} }
@ -659,13 +659,13 @@ function deleteContacts(contacts, options={}) {
// eslint-disable-next-line no-useless-escape // eslint-disable-next-line no-useless-escape
let html = ` let html = `
<div class='alert alert-block alert-danger'> <div class='alert alert-block alert-danger'>
{% trans "All selected contacts will be deleted" %} {% jstrans "All selected contacts will be deleted" %}
</div> </div>
<table class='table table-striped table-condensed'> <table class='table table-striped table-condensed'>
<tr> <tr>
<th>{% trans "Name" %}</th> <th>{% jstrans "Name" %}</th>
<th>{% trans "Email" %}</th> <th>{% jstrans "Email" %}</th>
<th>{% trans "Role" %}</th> <th>{% jstrans "Role" %}</th>
</tr> </tr>
${rows} ${rows}
</table>`; </table>`;
@ -673,7 +673,7 @@ function deleteContacts(contacts, options={}) {
constructForm('{% url "api-contact-list" %}', { constructForm('{% url "api-contact-list" %}', {
method: 'DELETE', method: 'DELETE',
multi_delete: true, multi_delete: true,
title: '{% trans "Delete Contacts" %}', title: '{% jstrans "Delete Contacts" %}',
preFormContent: html, preFormContent: html,
form_data: { form_data: {
items: ids, items: ids,
@ -704,32 +704,32 @@ function loadContactTable(table, options={}) {
uniqueId: 'pk', uniqueId: 'pk',
sidePagination: 'server', sidePagination: 'server',
formatNoMatches: function() { formatNoMatches: function() {
return '{% trans "No contacts found" %}'; return '{% jstrans "No contacts found" %}';
}, },
showColumns: true, showColumns: true,
name: 'contacts', name: 'contacts',
columns: [ columns: [
{ {
field: 'name', field: 'name',
title: '{% trans "Name" %}', title: '{% jstrans "Name" %}',
sortable: true, sortable: true,
switchable: false, switchable: false,
}, },
{ {
field: 'phone', field: 'phone',
title: '{% trans "Phone Number" %}', title: '{% jstrans "Phone Number" %}',
sortable: false, sortable: false,
switchable: true, switchable: true,
}, },
{ {
field: 'email', field: 'email',
title: '{% trans "Email Address" %}', title: '{% jstrans "Email Address" %}',
sortable: false, sortable: false,
switchable: true, switchable: true,
}, },
{ {
field: 'role', field: 'role',
title: '{% trans "Role" %}', title: '{% jstrans "Role" %}',
sortable: false, sortable: false,
switchable: false, switchable: false,
}, },
@ -745,11 +745,11 @@ function loadContactTable(table, options={}) {
let html = ''; let html = '';
if (options.allow_edit) { if (options.allow_edit) {
html += makeEditButton('btn-contact-edit', pk, '{% trans "Edit Contact" %}'); html += makeEditButton('btn-contact-edit', pk, '{% jstrans "Edit Contact" %}');
} }
if (options.allow_delete) { if (options.allow_delete) {
html += makeDeleteButton('btn-contact-delete', pk, '{% trans "Delete Contact" %}'); html += makeDeleteButton('btn-contact-delete', pk, '{% jstrans "Delete Contact" %}');
} }
return wrapButtons(html); return wrapButtons(html);
@ -846,7 +846,7 @@ function createAddress(options={}) {
constructForm('{% url "api-address-list" %}', { constructForm('{% url "api-address-list" %}', {
method: 'POST', method: 'POST',
fields: fields, fields: fields,
title: '{% trans "Create New Address" %}', title: '{% jstrans "Create New Address" %}',
onSuccess: function(response) { onSuccess: function(response) {
handleFormSuccess(response, options); handleFormSuccess(response, options);
} }
@ -861,7 +861,7 @@ function editAddress(pk, options={}) {
constructForm(`{% url "api-address-list" %}${pk}/`, { constructForm(`{% url "api-address-list" %}${pk}/`, {
fields: fields, fields: fields,
title: '{% trans "Edit Address" %}', title: '{% jstrans "Edit Address" %}',
onSuccess: function(response) { onSuccess: function(response) {
handleFormSuccess(response, options); handleFormSuccess(response, options);
} }
@ -896,13 +896,13 @@ function deleteAddress(addresses, options={}) {
let html = ` let html = `
<div class='alert alert-block alert-danger'> <div class='alert alert-block alert-danger'>
{% trans "All selected addresses will be deleted" %} {% jstrans "All selected addresses will be deleted" %}
</div> </div>
<table class='table table-striped table-condensed'> <table class='table table-striped table-condensed'>
<tr> <tr>
<th>{% trans "Name" %}</th> <th>{% jstrans "Name" %}</th>
<th>{% trans "Line 1" %}</th> <th>{% jstrans "Line 1" %}</th>
<th>{% trans "Line 2" %}</th> <th>{% jstrans "Line 2" %}</th>
</tr> </tr>
${rows} ${rows}
</table>`; </table>`;
@ -910,7 +910,7 @@ function deleteAddress(addresses, options={}) {
constructForm('{% url "api-address-list" %}', { constructForm('{% url "api-address-list" %}', {
method: 'DELETE', method: 'DELETE',
multi_delete: true, multi_delete: true,
title: '{% trans "Delete Addresses" %}', title: '{% jstrans "Delete Addresses" %}',
preFormContent: html, preFormContent: html,
form_data: { form_data: {
items: ids, items: ids,
@ -937,14 +937,14 @@ function loadAddressTable(table, options={}) {
sidePagination: 'server', sidePagination: 'server',
sortable: true, sortable: true,
formatNoMatches: function() { formatNoMatches: function() {
return '{% trans "No addresses found" %}'; return '{% jstrans "No addresses found" %}';
}, },
showColumns: true, showColumns: true,
name: 'addresses', name: 'addresses',
columns: [ columns: [
{ {
field: 'primary', field: 'primary',
title: '{% trans "Primary" %}', title: '{% jstrans "Primary" %}',
switchable: false, switchable: false,
formatter: function(value) { formatter: function(value) {
return yesNoLabel(value); return yesNoLabel(value);
@ -952,61 +952,61 @@ function loadAddressTable(table, options={}) {
}, },
{ {
field: 'title', field: 'title',
title: '{% trans "Title" %}', title: '{% jstrans "Title" %}',
sortable: true, sortable: true,
switchable: false, switchable: false,
}, },
{ {
field: 'line1', field: 'line1',
title: '{% trans "Line 1" %}', title: '{% jstrans "Line 1" %}',
sortable: false, sortable: false,
switchable: false, switchable: false,
}, },
{ {
field: 'line2', field: 'line2',
title: '{% trans "Line 2" %}', title: '{% jstrans "Line 2" %}',
sortable: false, sortable: false,
switchable: false, switchable: false,
}, },
{ {
field: 'postal_code', field: 'postal_code',
title: '{% trans "Postal code" %}', title: '{% jstrans "Postal code" %}',
sortable: false, sortable: false,
switchable: false, switchable: false,
}, },
{ {
field: 'postal_city', field: 'postal_city',
title: '{% trans "Postal city" %}', title: '{% jstrans "Postal city" %}',
sortable: false, sortable: false,
switchable: false, switchable: false,
}, },
{ {
field: 'province', field: 'province',
title: '{% trans "State/province" %}', title: '{% jstrans "State/province" %}',
sortable: false, sortable: false,
switchable: false, switchable: false,
}, },
{ {
field: 'country', field: 'country',
title: '{% trans "Country" %}', title: '{% jstrans "Country" %}',
sortable: false, sortable: false,
switchable: false, switchable: false,
}, },
{ {
field: 'shipping_notes', field: 'shipping_notes',
title: '{% trans "Courier notes" %}', title: '{% jstrans "Courier notes" %}',
sortable: false, sortable: false,
switchable: true, switchable: true,
}, },
{ {
field: 'internal_shipping_notes', field: 'internal_shipping_notes',
title: '{% trans "Internal notes" %}', title: '{% jstrans "Internal notes" %}',
sortable: false, sortable: false,
switchable: true, switchable: true,
}, },
{ {
field: 'link', field: 'link',
title: '{% trans "External Link" %}', title: '{% jstrans "External Link" %}',
sortable: false, sortable: false,
switchable: true, switchable: true,
}, },
@ -1022,11 +1022,11 @@ function loadAddressTable(table, options={}) {
let html = ''; let html = '';
if (options.allow_edit) { if (options.allow_edit) {
html += makeEditButton('btn-address-edit', pk, '{% trans "Edit Address" %}'); html += makeEditButton('btn-address-edit', pk, '{% jstrans "Edit Address" %}');
} }
if (options.allow_delete) { if (options.allow_delete) {
html += makeDeleteButton('btn-address-delete', pk, '{% trans "Delete Address" %}'); html += makeDeleteButton('btn-address-delete', pk, '{% jstrans "Delete Address" %}');
} }
return wrapButtons(html); return wrapButtons(html);
@ -1099,13 +1099,13 @@ function deleteManufacturerParts(selections, options={}) {
var html = ` var html = `
<div class='alert alert-block alert-danger'> <div class='alert alert-block alert-danger'>
{% trans "All selected manufacturer parts will be deleted" %} {% jstrans "All selected manufacturer parts will be deleted" %}
</div> </div>
<table class='table table-striped table-condensed'> <table class='table table-striped table-condensed'>
<tr> <tr>
<th>{% trans "Part" %}</th> <th>{% jstrans "Part" %}</th>
<th>{% trans "MPN" %}</th> <th>{% jstrans "MPN" %}</th>
<th>{% trans "Manufacturer" %}</th> <th>{% jstrans "Manufacturer" %}</th>
</tr> </tr>
${rows} ${rows}
</table> </table>
@ -1114,7 +1114,7 @@ function deleteManufacturerParts(selections, options={}) {
constructForm('{% url "api-manufacturer-part-list" %}', { constructForm('{% url "api-manufacturer-part-list" %}', {
method: 'DELETE', method: 'DELETE',
multi_delete: true, multi_delete: true,
title: '{% trans "Delete Manufacturer Parts" %}', title: '{% jstrans "Delete Manufacturer Parts" %}',
preFormContent: html, preFormContent: html,
form_data: { form_data: {
items: ids, items: ids,
@ -1148,12 +1148,12 @@ function deleteManufacturerPartParameters(selections, options={}) {
var html = ` var html = `
<div class='alert alert-block alert-danger'> <div class='alert alert-block alert-danger'>
{% trans "All selected parameters will be deleted" %} {% jstrans "All selected parameters will be deleted" %}
</div> </div>
<table class='table table-striped table-condensed'> <table class='table table-striped table-condensed'>
<tr> <tr>
<th>{% trans "Name" %}</th> <th>{% jstrans "Name" %}</th>
<th>{% trans "Value" %}</th> <th>{% jstrans "Value" %}</th>
</tr> </tr>
${rows} ${rows}
</table> </table>
@ -1162,7 +1162,7 @@ function deleteManufacturerPartParameters(selections, options={}) {
constructForm('{% url "api-manufacturer-part-parameter-list" %}', { constructForm('{% url "api-manufacturer-part-parameter-list" %}', {
method: 'DELETE', method: 'DELETE',
multi_delete: true, multi_delete: true,
title: '{% trans "Delete Parameters" %}', title: '{% jstrans "Delete Parameters" %}',
preFormContent: html, preFormContent: html,
form_data: { form_data: {
items: ids, items: ids,
@ -1178,7 +1178,7 @@ function makeManufacturerPartActions(options={}) {
return [ return [
{ {
label: 'order', label: 'order',
title: '{% trans "Order parts" %}', title: '{% jstrans "Order parts" %}',
icon: 'fa-shopping-cart', icon: 'fa-shopping-cart',
permission: 'purchase_order.add', permission: 'purchase_order.add',
callback: function(data) { callback: function(data) {
@ -1195,7 +1195,7 @@ function makeManufacturerPartActions(options={}) {
}, },
{ {
label: 'delete', label: 'delete',
title: '{% trans "Delete manufacturer parts" %}', title: '{% jstrans "Delete manufacturer parts" %}',
icon: 'fa-trash-alt icon-red', icon: 'fa-trash-alt icon-red',
permission: 'purchase_order.delete', permission: 'purchase_order.delete',
callback: function(data) { callback: function(data) {
@ -1227,7 +1227,7 @@ function loadManufacturerPartTable(table, url, options) {
custom_actions: [ custom_actions: [
{ {
label: 'manufacturer-part', label: 'manufacturer-part',
title: '{% trans "Manufacturer part actions" %}', title: '{% jstrans "Manufacturer part actions" %}',
icon: 'fa-tools', icon: 'fa-tools',
actions: makeManufacturerPartActions({ actions: makeManufacturerPartActions({
manufacturer_id: options.params.manufacturer, manufacturer_id: options.params.manufacturer,
@ -1246,7 +1246,7 @@ function loadManufacturerPartTable(table, url, options) {
name: 'manufacturerparts', name: 'manufacturerparts',
groupBy: false, groupBy: false,
formatNoMatches: function() { formatNoMatches: function() {
return '{% trans "No manufacturer parts found" %}'; return '{% jstrans "No manufacturer parts found" %}';
}, },
columns: [ columns: [
{ {
@ -1258,7 +1258,7 @@ function loadManufacturerPartTable(table, url, options) {
switchable: params['part_detail'], switchable: params['part_detail'],
sortable: true, sortable: true,
field: 'part_detail.full_name', field: 'part_detail.full_name',
title: '{% trans "Part" %}', title: '{% jstrans "Part" %}',
formatter: function(value, row) { formatter: function(value, row) {
var url = `/part/${row.part}/`; var url = `/part/${row.part}/`;
@ -1266,15 +1266,15 @@ function loadManufacturerPartTable(table, url, options) {
var html = imageHoverIcon(row.part_detail.thumbnail) + renderLink(value, url); var html = imageHoverIcon(row.part_detail.thumbnail) + renderLink(value, url);
if (row.part_detail.is_template) { if (row.part_detail.is_template) {
html += makeIconBadge('fa-clone', '{% trans "Template part" %}'); html += makeIconBadge('fa-clone', '{% jstrans "Template part" %}');
} }
if (row.part_detail.assembly) { if (row.part_detail.assembly) {
html += makeIconBadge('fa-tools', '{% trans "Assembled part" %}'); html += makeIconBadge('fa-tools', '{% jstrans "Assembled part" %}');
} }
if (!row.part_detail.active) { if (!row.part_detail.active) {
html += `<span class='badge badge-right rounded-pill bg-warning'>{% trans "Inactive" %}</span>`; html += `<span class='badge badge-right rounded-pill bg-warning'>{% jstrans "Inactive" %}</span>`;
} }
return html; return html;
@ -1283,7 +1283,7 @@ function loadManufacturerPartTable(table, url, options) {
{ {
sortable: true, sortable: true,
field: 'manufacturer', field: 'manufacturer',
title: '{% trans "Manufacturer" %}', title: '{% jstrans "Manufacturer" %}',
formatter: function(value, row) { formatter: function(value, row) {
if (value && row.manufacturer_detail) { if (value && row.manufacturer_detail) {
var name = row.manufacturer_detail.name; var name = row.manufacturer_detail.name;
@ -1299,14 +1299,14 @@ function loadManufacturerPartTable(table, url, options) {
{ {
sortable: true, sortable: true,
field: 'MPN', field: 'MPN',
title: '{% trans "MPN" %}', title: '{% jstrans "MPN" %}',
formatter: function(value, row) { formatter: function(value, row) {
return renderClipboard(renderLink(value, `/manufacturer-part/${row.pk}/`)); return renderClipboard(renderLink(value, `/manufacturer-part/${row.pk}/`));
} }
}, },
{ {
field: 'link', field: 'link',
title: '{% trans "Link" %}', title: '{% jstrans "Link" %}',
formatter: function(value) { formatter: function(value) {
if (value) { if (value) {
return renderLink(value, value, {external: true}); return renderLink(value, value, {external: true});
@ -1317,7 +1317,7 @@ function loadManufacturerPartTable(table, url, options) {
}, },
{ {
field: 'description', field: 'description',
title: '{% trans "Description" %}', title: '{% jstrans "Description" %}',
sortable: false, sortable: false,
switchable: true, switchable: true,
}, },
@ -1330,8 +1330,8 @@ function loadManufacturerPartTable(table, url, options) {
let pk = row.pk; let pk = row.pk;
let html = ''; let html = '';
html += makeEditButton('button-manufacturer-part-edit', pk, '{% trans "Edit manufacturer part" %}'); html += makeEditButton('button-manufacturer-part-edit', pk, '{% jstrans "Edit manufacturer part" %}');
html += makeDeleteButton('button-manufacturer-part-delete', pk, '{% trans "Delete manufacturer part" %}'); html += makeDeleteButton('button-manufacturer-part-delete', pk, '{% jstrans "Delete manufacturer part" %}');
return wrapButtons(html); return wrapButtons(html);
} }
@ -1390,7 +1390,7 @@ function loadManufacturerPartParameterTable(table, url, options) {
name: 'manufacturerpartparameters', name: 'manufacturerpartparameters',
groupBy: false, groupBy: false,
formatNoMatches: function() { formatNoMatches: function() {
return '{% trans "No parameters found" %}'; return '{% jstrans "No parameters found" %}';
}, },
columns: [ columns: [
{ {
@ -1400,19 +1400,19 @@ function loadManufacturerPartParameterTable(table, url, options) {
}, },
{ {
field: 'name', field: 'name',
title: '{% trans "Name" %}', title: '{% jstrans "Name" %}',
switchable: false, switchable: false,
sortable: true, sortable: true,
}, },
{ {
field: 'value', field: 'value',
title: '{% trans "Value" %}', title: '{% jstrans "Value" %}',
switchable: false, switchable: false,
sortable: true, sortable: true,
}, },
{ {
field: 'units', field: 'units',
title: '{% trans "Units" %}', title: '{% jstrans "Units" %}',
switchable: true, switchable: true,
sortable: true, sortable: true,
}, },
@ -1425,8 +1425,8 @@ function loadManufacturerPartParameterTable(table, url, options) {
let pk = row.pk; let pk = row.pk;
let html = ''; let html = '';
html += makeEditButton('button-parameter-edit', pk, '{% trans "Edit parameter" %}'); html += makeEditButton('button-parameter-edit', pk, '{% jstrans "Edit parameter" %}');
html += makeDeleteButton('button-parameter-delete', pk, '{% trans "Delete parameter" %}'); html += makeDeleteButton('button-parameter-delete', pk, '{% jstrans "Delete parameter" %}');
return wrapButtons(html); return wrapButtons(html);
} }
@ -1443,7 +1443,7 @@ function loadManufacturerPartParameterTable(table, url, options) {
value: {}, value: {},
units: {}, units: {},
}, },
title: '{% trans "Edit Parameter" %}', title: '{% jstrans "Edit Parameter" %}',
refreshTable: table, refreshTable: table,
}); });
}); });
@ -1452,7 +1452,7 @@ function loadManufacturerPartParameterTable(table, url, options) {
constructForm(`{% url "api-manufacturer-part-parameter-list" %}${pk}/`, { constructForm(`{% url "api-manufacturer-part-parameter-list" %}${pk}/`, {
method: 'DELETE', method: 'DELETE',
title: '{% trans "Delete Parameter" %}', title: '{% jstrans "Delete Parameter" %}',
refreshTable: table, refreshTable: table,
}); });
}); });
@ -1466,7 +1466,7 @@ function makeSupplierPartActions(options={}) {
return [ return [
{ {
label: 'order', label: 'order',
title: '{% trans "Order parts" %}', title: '{% jstrans "Order parts" %}',
icon: 'fa-shopping-cart', icon: 'fa-shopping-cart',
permission: 'purchase_order.add', permission: 'purchase_order.add',
callback: function(data) { callback: function(data) {
@ -1483,7 +1483,7 @@ function makeSupplierPartActions(options={}) {
}, },
{ {
label: 'delete', label: 'delete',
title: '{% trans "Delete supplier parts" %}', title: '{% jstrans "Delete supplier parts" %}',
icon: 'fa-trash-alt icon-red', icon: 'fa-trash-alt icon-red',
permission: 'purchase_order.delete', permission: 'purchase_order.delete',
callback: function(data) { callback: function(data) {
@ -1513,7 +1513,7 @@ function loadSupplierPartTable(table, url, options) {
custom_actions: [ custom_actions: [
{ {
label: 'supplier-part', label: 'supplier-part',
title: '{% trans "Supplier part actions" %}', title: '{% jstrans "Supplier part actions" %}',
icon: 'fa-tools', icon: 'fa-tools',
actions: makeSupplierPartActions({ actions: makeSupplierPartActions({
supplier_id: options.params.supplier, supplier_id: options.params.supplier,
@ -1533,7 +1533,7 @@ function loadSupplierPartTable(table, url, options) {
groupBy: false, groupBy: false,
sortable: true, sortable: true,
formatNoMatches: function() { formatNoMatches: function() {
return '{% trans "No supplier parts found" %}'; return '{% jstrans "No supplier parts found" %}';
}, },
columns: [ columns: [
{ {
@ -1546,7 +1546,7 @@ function loadSupplierPartTable(table, url, options) {
sortable: true, sortable: true,
field: 'part_detail.full_name', field: 'part_detail.full_name',
sortName: 'part', sortName: 'part',
title: '{% trans "Part" %}', title: '{% jstrans "Part" %}',
formatter: function(value, row) { formatter: function(value, row) {
var url = `/part/${row.part}/`; var url = `/part/${row.part}/`;
@ -1554,15 +1554,15 @@ function loadSupplierPartTable(table, url, options) {
var html = imageHoverIcon(row.part_detail.thumbnail) + renderLink(value, url); var html = imageHoverIcon(row.part_detail.thumbnail) + renderLink(value, url);
if (row.part_detail.is_template) { if (row.part_detail.is_template) {
html += makeIconBadge('fa-clone', '{% trans "Template part" %}'); html += makeIconBadge('fa-clone', '{% jstrans "Template part" %}');
} }
if (row.part_detail.assembly) { if (row.part_detail.assembly) {
html += makeIconBadge('fa-tools', '{% trans "Assembled part" %}'); html += makeIconBadge('fa-tools', '{% jstrans "Assembled part" %}');
} }
if (!row.part_detail.active) { if (!row.part_detail.active) {
html += `<span class='badge badge-right rounded-pill bg-warning'>{% trans "Inactive" %}</span>`; html += `<span class='badge badge-right rounded-pill bg-warning'>{% jstrans "Inactive" %}</span>`;
} }
return html; return html;
@ -1571,7 +1571,7 @@ function loadSupplierPartTable(table, url, options) {
{ {
sortable: true, sortable: true,
field: 'supplier', field: 'supplier',
title: '{% trans "Supplier" %}', title: '{% jstrans "Supplier" %}',
formatter: function(value, row) { formatter: function(value, row) {
if (value) { if (value) {
var name = row.supplier_detail.name; var name = row.supplier_detail.name;
@ -1587,7 +1587,7 @@ function loadSupplierPartTable(table, url, options) {
{ {
sortable: true, sortable: true,
field: 'SKU', field: 'SKU',
title: '{% trans "Supplier Part" %}', title: '{% jstrans "Supplier Part" %}',
formatter: function(value, row) { formatter: function(value, row) {
return renderClipboard(renderLink(value, `/supplier-part/${row.pk}/`)); return renderClipboard(renderLink(value, `/supplier-part/${row.pk}/`));
} }
@ -1598,7 +1598,7 @@ function loadSupplierPartTable(table, url, options) {
sortable: true, sortable: true,
sortName: 'manufacturer', sortName: 'manufacturer',
field: 'manufacturer_detail.name', field: 'manufacturer_detail.name',
title: '{% trans "Manufacturer" %}', title: '{% jstrans "Manufacturer" %}',
formatter: function(value, row) { formatter: function(value, row) {
if (value && row.manufacturer_detail) { if (value && row.manufacturer_detail) {
var name = value; var name = value;
@ -1617,7 +1617,7 @@ function loadSupplierPartTable(table, url, options) {
sortable: true, sortable: true,
sortName: 'MPN', sortName: 'MPN',
field: 'manufacturer_part_detail.MPN', field: 'manufacturer_part_detail.MPN',
title: '{% trans "MPN" %}', title: '{% jstrans "MPN" %}',
formatter: function(value, row) { formatter: function(value, row) {
if (value && row.manufacturer_part) { if (value && row.manufacturer_part) {
return renderClipboard(renderLink(value, `/manufacturer-part/${row.manufacturer_part}/`)); return renderClipboard(renderLink(value, `/manufacturer-part/${row.manufacturer_part}/`));
@ -1628,17 +1628,17 @@ function loadSupplierPartTable(table, url, options) {
}, },
{ {
field: 'description', field: 'description',
title: '{% trans "Description" %}', title: '{% jstrans "Description" %}',
sortable: false, sortable: false,
}, },
{ {
field: 'packaging', field: 'packaging',
title: '{% trans "Packaging" %}', title: '{% jstrans "Packaging" %}',
sortable: true, sortable: true,
}, },
{ {
field: 'pack_quantity', field: 'pack_quantity',
title: '{% trans "Pack Quantity" %}', title: '{% jstrans "Pack Quantity" %}',
sortable: true, sortable: true,
formatter: function(value, row) { formatter: function(value, row) {
@ -1651,7 +1651,7 @@ function loadSupplierPartTable(table, url, options) {
} }
if (row.part_detail && row.part_detail.units) { if (row.part_detail && row.part_detail.units) {
html += `<span class='fas fa-info-circle float-right' title='{% trans "Base Units" %}: ${row.part_detail.units}'></span>`; html += `<span class='fas fa-info-circle float-right' title='{% jstrans "Base Units" %}: ${row.part_detail.units}'></span>`;
} }
return html; return html;
@ -1660,7 +1660,7 @@ function loadSupplierPartTable(table, url, options) {
{ {
field: 'link', field: 'link',
sortable: false, sortable: false,
title: '{% trans "Link" %}', title: '{% jstrans "Link" %}',
formatter: function(value) { formatter: function(value) {
if (value) { if (value) {
return renderLink(value, value, {external: true}); return renderLink(value, value, {external: true});
@ -1671,17 +1671,17 @@ function loadSupplierPartTable(table, url, options) {
}, },
{ {
field: 'note', field: 'note',
title: '{% trans "Notes" %}', title: '{% jstrans "Notes" %}',
sortable: false, sortable: false,
}, },
{ {
field: 'in_stock', field: 'in_stock',
title: '{% trans "In Stock" %}', title: '{% jstrans "In Stock" %}',
sortable: true, sortable: true,
}, },
{ {
field: 'available', field: 'available',
title: '{% trans "Availability" %}', title: '{% jstrans "Availability" %}',
sortable: true, sortable: true,
formatter: function(value, row) { formatter: function(value, row) {
if (row.availability_updated) { if (row.availability_updated) {
@ -1690,7 +1690,7 @@ function loadSupplierPartTable(table, url, options) {
html += makeIconBadge( html += makeIconBadge(
'fa-info-circle', 'fa-info-circle',
`{% trans "Last Updated" %}: ${date}` `{% jstrans "Last Updated" %}: ${date}`
); );
return html; return html;
} else { } else {
@ -1700,7 +1700,7 @@ function loadSupplierPartTable(table, url, options) {
}, },
{ {
field: 'updated', field: 'updated',
title: '{% trans "Last Updated" %}', title: '{% jstrans "Last Updated" %}',
sortable: true, sortable: true,
}, },
{ {
@ -1712,8 +1712,8 @@ function loadSupplierPartTable(table, url, options) {
let pk = row.pk; let pk = row.pk;
let html = ''; let html = '';
html += makeEditButton('button-supplier-part-edit', pk, '{% trans "Edit supplier part" %}'); html += makeEditButton('button-supplier-part-edit', pk, '{% jstrans "Edit supplier part" %}');
html += makeDeleteButton('button-supplier-part-delete', pk, '{% trans "Delete supplier part" %}'); html += makeDeleteButton('button-supplier-part-delete', pk, '{% jstrans "Delete supplier part" %}');
return wrapButtons(html); return wrapButtons(html);
} }
@ -1766,7 +1766,7 @@ function loadSupplierPriceBreakTable(options={}) {
constructForm(`{% url "api-part-supplier-price-list" %}${pk}/`, { constructForm(`{% url "api-part-supplier-price-list" %}${pk}/`, {
method: 'DELETE', method: 'DELETE',
title: '{% trans "Delete Price Break" %}', title: '{% jstrans "Delete Price Break" %}',
refreshTable: table, refreshTable: table,
}); });
}); });
@ -1776,7 +1776,7 @@ function loadSupplierPriceBreakTable(options={}) {
constructForm(`{% url "api-part-supplier-price-list" %}${pk}/`, { constructForm(`{% url "api-part-supplier-price-list" %}${pk}/`, {
fields: supplierPartPriceBreakFields(), fields: supplierPartPriceBreakFields(),
title: '{% trans "Edit Price Break" %}', title: '{% jstrans "Edit Price Break" %}',
refreshTable: table, refreshTable: table,
}); });
}); });
@ -1791,7 +1791,7 @@ function loadSupplierPriceBreakTable(options={}) {
part: options.part, part: options.part,
}, },
formatNoMatches: function() { formatNoMatches: function() {
return '{% trans "No price break information found" %}'; return '{% jstrans "No price break information found" %}';
}, },
onPostBody: function() { onPostBody: function() {
setupCallbacks(); setupCallbacks();
@ -1805,12 +1805,12 @@ function loadSupplierPriceBreakTable(options={}) {
}, },
{ {
field: 'quantity', field: 'quantity',
title: '{% trans "Quantity" %}', title: '{% jstrans "Quantity" %}',
sortable: true, sortable: true,
}, },
{ {
field: 'price', field: 'price',
title: '{% trans "Price" %}', title: '{% jstrans "Price" %}',
sortable: true, sortable: true,
formatter: function(value, row, index) { formatter: function(value, row, index) {
return formatCurrency(value, { return formatCurrency(value, {
@ -1820,15 +1820,15 @@ function loadSupplierPriceBreakTable(options={}) {
}, },
{ {
field: 'updated', field: 'updated',
title: '{% trans "Last updated" %}', title: '{% jstrans "Last updated" %}',
sortable: true, sortable: true,
formatter: function(value, row) { formatter: function(value, row) {
var html = renderDate(value); var html = renderDate(value);
let buttons = ''; let buttons = '';
buttons += makeEditButton('button-price-break-edit', row.pk, '{% trans "Edit price break" %}'); buttons += makeEditButton('button-price-break-edit', row.pk, '{% jstrans "Edit price break" %}');
buttons += makeDeleteButton('button-price-break-delete', row.pk, '{% trans "Delete price break" %}'); buttons += makeDeleteButton('button-price-break-delete', row.pk, '{% jstrans "Delete price break" %}');
html += wrapButtons(buttons); html += wrapButtons(buttons);

View File

@ -183,11 +183,11 @@ function getFilterOptionList(tableKey, filterKey) {
return { return {
'1': { '1': {
key: '1', key: '1',
value: '{% trans "true" %}', value: '{% jstrans "true" %}',
}, },
'0': { '0': {
key: '0', key: '0',
value: '{% trans "false" %}', value: '{% jstrans "false" %}',
}, },
}; };
} else if (settings.type == 'date') { } else if (settings.type == 'date') {
@ -211,7 +211,7 @@ function generateAvailableFilterList(tableKey) {
var html = `<select class='form-control filter-input' id='${id}' name='tag'>`; var html = `<select class='form-control filter-input' id='${id}' name='tag'>`;
html += `<option value=''>{% trans 'Select filter' %}</option>`; html += `<option value=''>{% jstrans 'Select filter' %}</option>`;
for (var opt in remaining) { for (var opt in remaining) {
var title = getFilterTitle(tableKey, opt); var title = getFilterTitle(tableKey, opt);
@ -293,7 +293,7 @@ function makeCustomActionGroup(action_group, table) {
let buttons = []; let buttons = [];
let label = action_group.label || 'actions'; let label = action_group.label || 'actions';
let title = action_group.title || '{% trans "Actions" %}'; let title = action_group.title || '{% jstrans "Actions" %}';
let icon = action_group.icon || 'fa-tools'; let icon = action_group.icon || 'fa-tools';
// Construct the HTML for each button // Construct the HTML for each button
@ -332,7 +332,7 @@ function makeBarcodeActions(barcode_actions, table) {
let html = ` let html = `
<div class='btn-group' role='group'> <div class='btn-group' role='group'>
<button id='barcode-actions' title='{% trans "Barcode actions" %}' class='btn btn-outline-secondary dropdown-toggle' type='button' data-bs-toggle='dropdown'> <button id='barcode-actions' title='{% jstrans "Barcode actions" %}' class='btn btn-outline-secondary dropdown-toggle' type='button' data-bs-toggle='dropdown'>
<span class='fas fa-qrcode'></span> <span class='fas fa-qrcode'></span>
</button> </button>
<ul class='dropdown-menu' role='menu'> <ul class='dropdown-menu' role='menu'>
@ -428,17 +428,17 @@ function setupFilterList(tableKey, table, target, options={}) {
if (report_button || labels_button) { if (report_button || labels_button) {
let print_buttons = ` let print_buttons = `
<div class='btn-group' role='group'> <div class='btn-group' role='group'>
<button id='printing-options' title='{% trans "Printing actions" %}' class='btn btn-outline-secondary dropdown-toggle' type='button' data-bs-toggle='dropdown'> <button id='printing-options' title='{% jstrans "Printing actions" %}' class='btn btn-outline-secondary dropdown-toggle' type='button' data-bs-toggle='dropdown'>
<span class='fas fa-print'></span> <span class='caret'></span> <span class='fas fa-print'></span> <span class='caret'></span>
</button> </button>
<ul class='dropdown-menu' role='menu'>`; <ul class='dropdown-menu' role='menu'>`;
if (labels_button) { if (labels_button) {
print_buttons += `<li><a class='dropdown-item' href='#' id='print-labels-${tableKey}'><span class='fas fa-tag'></span> {% trans "Print Labels" %}</a></li>`; print_buttons += `<li><a class='dropdown-item' href='#' id='print-labels-${tableKey}'><span class='fas fa-tag'></span> {% jstrans "Print Labels" %}</a></li>`;
} }
if (report_button) { if (report_button) {
print_buttons += `<li><a class='dropdown-item' href='#' id='print-report-${tableKey}'><span class='fas fa-file-pdf'></span> {% trans "Print Reports" %}</a></li>`; print_buttons += `<li><a class='dropdown-item' href='#' id='print-report-${tableKey}'><span class='fas fa-file-pdf'></span> {% jstrans "Print Reports" %}</a></li>`;
} }
print_buttons += `</ul></div>`; print_buttons += `</ul></div>`;
@ -450,14 +450,14 @@ function setupFilterList(tableKey, table, target, options={}) {
if (options.download) { if (options.download) {
buttons += makeFilterButton({ buttons += makeFilterButton({
id: `download-${tableKey}`, id: `download-${tableKey}`,
title: '{% trans "Download table data" %}', title: '{% jstrans "Download table data" %}',
icon: 'fa-download', icon: 'fa-download',
}); });
} }
buttons += makeFilterButton({ buttons += makeFilterButton({
id: `reload-${tableKey}`, id: `reload-${tableKey}`,
title: '{% trans "Reload table data" %}', title: '{% jstrans "Reload table data" %}',
icon: 'fa-redo-alt', icon: 'fa-redo-alt',
}); });
@ -466,7 +466,7 @@ function setupFilterList(tableKey, table, target, options={}) {
buttons += makeFilterButton({ buttons += makeFilterButton({
id: add, id: add,
title: '{% trans "Add new filter" %}', title: '{% jstrans "Add new filter" %}',
icon: 'fa-filter', icon: 'fa-filter',
}); });
@ -474,7 +474,7 @@ function setupFilterList(tableKey, table, target, options={}) {
if (Object.keys(filters).length > 0) { if (Object.keys(filters).length > 0) {
buttons += makeFilterButton({ buttons += makeFilterButton({
id: clear, id: clear,
title: '{% trans "Clear all filters" %}', title: '{% jstrans "Clear all filters" %}',
icon: 'fa-backspace icon-red', icon: 'fa-backspace icon-red',
}); });
} }
@ -579,7 +579,7 @@ function setupFilterList(tableKey, table, target, options={}) {
html += generateAvailableFilterList(tableKey); html += generateAvailableFilterList(tableKey);
html += generateFilterInput(tableKey); html += generateFilterInput(tableKey);
html += `<button title='{% trans "Create filter" %}' class='btn btn-outline-secondary filter-button' id='${make}'><span class='fas fa-plus'></span></button>`; html += `<button title='{% jstrans "Create filter" %}' class='btn btn-outline-secondary filter-button' id='${make}'><span class='fas fa-plus'></span></button>`;
html += `</div>`; html += `</div>`;
element.append(html); element.append(html);
@ -669,8 +669,8 @@ function getFilterOptionValue(tableKey, filterKey, valueKey) {
// Lookup for boolean options // Lookup for boolean options
if (filter.type == 'bool') { if (filter.type == 'bool') {
if (value == '1') return '{% trans "true" %}'; if (value == '1') return '{% jstrans "true" %}';
if (value == '0') return '{% trans "false" %}'; if (value == '0') return '{% jstrans "false" %}';
return value; return value;
} }

View File

@ -371,9 +371,9 @@ function constructForm(url, options={}) {
constructCreateForm(OPTIONS.actions.POST, options); constructCreateForm(OPTIONS.actions.POST, options);
} else { } else {
// User does not have permission to POST to the endpoint // User does not have permission to POST to the endpoint
showMessage('{% trans "Action Prohibited" %}', { showMessage('{% jstrans "Action Prohibited" %}', {
style: 'danger', style: 'danger',
details: '{% trans "Create operation not allowed" %}', details: '{% jstrans "Create operation not allowed" %}',
icon: 'fas fa-user-times', icon: 'fas fa-user-times',
}); });
@ -386,9 +386,9 @@ function constructForm(url, options={}) {
constructChangeForm(OPTIONS.actions.PUT, options); constructChangeForm(OPTIONS.actions.PUT, options);
} else { } else {
// User does not have permission to PUT/PATCH to the endpoint // User does not have permission to PUT/PATCH to the endpoint
showMessage('{% trans "Action Prohibited" %}', { showMessage('{% jstrans "Action Prohibited" %}', {
style: 'danger', style: 'danger',
details: '{% trans "Update operation not allowed" %}', details: '{% jstrans "Update operation not allowed" %}',
icon: 'fas fa-user-times', icon: 'fas fa-user-times',
}); });
@ -400,9 +400,9 @@ function constructForm(url, options={}) {
constructDeleteForm(OPTIONS.actions.DELETE, options); constructDeleteForm(OPTIONS.actions.DELETE, options);
} else { } else {
// User does not have permission to DELETE to the endpoint // User does not have permission to DELETE to the endpoint
showMessage('{% trans "Action Prohibited" %}', { showMessage('{% jstrans "Action Prohibited" %}', {
style: 'danger', style: 'danger',
details: '{% trans "Delete operation not allowed" %}', details: '{% jstrans "Delete operation not allowed" %}',
icon: 'fas fa-user-times', icon: 'fas fa-user-times',
}); });
@ -414,9 +414,9 @@ function constructForm(url, options={}) {
// TODO? // TODO?
} else { } else {
// User does not have permission to GET to the endpoint // User does not have permission to GET to the endpoint
showMessage('{% trans "Action Prohibited" %}', { showMessage('{% jstrans "Action Prohibited" %}', {
style: 'danger', style: 'danger',
details: '{% trans "View operation not allowed" %}', details: '{% jstrans "View operation not allowed" %}',
icon: 'fas fa-user-times', icon: 'fas fa-user-times',
}); });
@ -540,7 +540,7 @@ function constructFormBody(fields, options) {
} }
if (!('submitText' in options)) { if (!('submitText' in options)) {
options.submitText = '{% trans "Delete" %}'; options.submitText = '{% jstrans "Delete" %}';
} }
} }
@ -767,7 +767,7 @@ function updateForm(options) {
// The "submit" button will be disabled unless "confirm" is checked // The "submit" button will be disabled unless "confirm" is checked
function insertConfirmButton(options) { function insertConfirmButton(options) {
var message = options.confirmMessage || '{% trans "Confirm" %}'; var message = options.confirmMessage || '{% jstrans "Confirm" %}';
var html = ` var html = `
<div class="form-check form-switch"> <div class="form-check form-switch">
@ -793,7 +793,7 @@ function insertConfirmButton(options) {
/* Add a checkbox to select if the modal will stay open after success */ /* Add a checkbox to select if the modal will stay open after success */
function insertPersistButton(options) { function insertPersistButton(options) {
var message = options.persistMessage || '{% trans "Keep this form open" %}'; var message = options.persistMessage || '{% jstrans "Keep this form open" %}';
var html = ` var html = `
<div class="form-check form-switch"> <div class="form-check form-switch">
@ -896,7 +896,7 @@ function submitFormData(fields, options) {
if (!validateFormField(name, options)) { if (!validateFormField(name, options)) {
data_valid = false; data_valid = false;
data_errors[name] = ['{% trans "Enter a valid number" %}']; data_errors[name] = ['{% jstrans "Enter a valid number" %}'];
} }
break; break;
default: default:
@ -1466,7 +1466,7 @@ function handleFormErrors(errors, fields={}, options={}) {
// TODO: Display the JSON error text when hovering over the "info" icon // TODO: Display the JSON error text when hovering over the "info" icon
non_field_errors.append( non_field_errors.append(
`<div class='alert alert-block alert-danger'> `<div class='alert alert-block alert-danger'>
<b>{% trans "Form errors exist" %}</b> <b>{% jstrans "Form errors exist" %}</b>
<span id='form-errors-info' class='float-right fas fa-info-circle icon-red'> <span id='form-errors-info' class='float-right fas fa-info-circle icon-red'>
</span> </span>
</div>` </div>`
@ -1964,7 +1964,7 @@ function initializeRelatedField(field, fields, options={}) {
if (field.noResults) { if (field.noResults) {
return field.noResults(query); return field.noResults(query);
} else { } else {
return '{% trans "No results found" %}'; return '{% jstrans "No results found" %}';
} }
} }
}, },
@ -2148,11 +2148,11 @@ function initializeRelatedField(field, fields, options={}) {
button.on("click", () => { button.on("click", () => {
const tree_id = `${name}_tree`; const tree_id = `${name}_tree`;
const title = '{% trans "Select" %}' + " " + options.actions[name].label; const title = '{% jstrans "Select" %}' + " " + options.actions[name].label;
const content = ` const content = `
<div class="mb-1"> <div class="mb-1">
<div class="input-group mb-2"> <div class="input-group mb-2">
<input class="form-control" type="text" id="${name}_tree_search" placeholder="{% trans "Search" %} ${options.actions[name].label}..." /> <input class="form-control" type="text" id="${name}_tree_search" placeholder="{% jstrans "Search" %} ${options.actions[name].label}..." />
<button class="input-group-text" id="${name}_tree_search_btn"><i class="fas fa-search"></i></button> <button class="input-group-text" id="${name}_tree_search_btn"><i class="fas fa-search"></i></button>
</div> </div>
@ -2164,7 +2164,7 @@ function initializeRelatedField(field, fields, options={}) {
</div> </div>
`; `;
showQuestionDialog(title, content, { showQuestionDialog(title, content, {
accept_text: '{% trans "Select" %}', accept_text: '{% jstrans "Select" %}',
accept: () => { accept: () => {
const selectedNode = $(`#${tree_id}`).treeview('getSelected'); const selectedNode = $(`#${tree_id}`).treeview('getSelected');
if(selectedNode.length > 0) { if(selectedNode.length > 0) {
@ -2268,7 +2268,7 @@ function initializeChoiceField(field, fields, options) {
// Render a 'no results' element // Render a 'no results' element
function searching() { function searching() {
return `<span>{% trans "Searching" %}...</span>`; return `<span>{% jstrans "Searching" %}...</span>`;
} }
/* /*
@ -2482,7 +2482,7 @@ function constructField(name, parameters, options={}) {
if (!parameters.required && !options.hideClearButton) { if (!parameters.required && !options.hideClearButton) {
html += ` html += `
<button class='input-group-text form-clear' id='clear_${field_name}' title='{% trans "Clear input" %}'> <button class='input-group-text form-clear' id='clear_${field_name}' title='{% jstrans "Clear input" %}'>
<span class='icon-red fas fa-backspace'></span> <span class='icon-red fas fa-backspace'></span>
</button>`; </button>`;
} }
@ -3068,7 +3068,7 @@ function selectImportFields(url, data={}, options={}) {
rows += `<tr><td><em>${field_name}</em></td><td>${choice_input}</td></tr>`; rows += `<tr><td><em>${field_name}</em></td><td>${choice_input}</td></tr>`;
} }
var headers = `<tr><th>{% trans "File Column" %}</th><th>{% trans "Field Name" %}</th></tr>`; var headers = `<tr><th>{% jstrans "File Column" %}</th><th>{% jstrans "Field Name" %}</th></tr>`;
var html = ''; var html = '';
@ -3080,7 +3080,7 @@ function selectImportFields(url, data={}, options={}) {
constructForm(url, { constructForm(url, {
method: 'POST', method: 'POST',
title: '{% trans "Select Columns" %}', title: '{% jstrans "Select Columns" %}',
fields: {}, fields: {},
preFormContent: html, preFormContent: html,
onSubmit: function(fields, opts) { onSubmit: function(fields, opts) {

View File

@ -74,10 +74,10 @@ function yesNoLabel(value, options={}) {
let color = ''; let color = '';
if (toBool(value)) { if (toBool(value)) {
text = options.pass || '{% trans "YES" %}'; text = options.pass || '{% jstrans "YES" %}';
color = 'bg-success'; color = 'bg-success';
} else { } else {
text = options.fail || '{% trans "NO" %}'; text = options.fail || '{% jstrans "NO" %}';
color = 'bg-warning'; color = 'bg-warning';
} }
@ -90,19 +90,19 @@ function yesNoLabel(value, options={}) {
function trueFalseLabel(value, options={}) { function trueFalseLabel(value, options={}) {
options.pass = '{% trans "True" %}'; options.pass = '{% jstrans "True" %}';
options.fail = '{% trans "False" %}'; options.fail = '{% jstrans "False" %}';
return yesNoLabel(value, options); return yesNoLabel(value, options);
} }
function editButton(url, text='{% trans "Edit" %}') { function editButton(url, text='{% jstrans "Edit" %}') {
return `<button class='btn btn-success edit-button btn-sm' type='button' url='${url}'>${text}</button>`; return `<button class='btn btn-success edit-button btn-sm' type='button' url='${url}'>${text}</button>`;
} }
function deleteButton(url, text='{% trans "Delete" %}') { function deleteButton(url, text='{% jstrans "Delete" %}') {
return `<button class='btn btn-danger delete-button btn-sm' type='button' url='${url}'>${text}</button>`; return `<button class='btn btn-danger delete-button btn-sm' type='button' url='${url}'>${text}</button>`;
} }
@ -582,7 +582,7 @@ function renderClipboard(s, prepend=false) {
return s; return s;
} }
let clipString = `<span class="d-none d-xl-inline"><button class="btn clip-btn" type="button" data-bs-toggle='tooltip' title='{% trans "copy to clipboard" %}'><em class="fas fa-copy"></em></button></span>`; let clipString = `<span class="d-none d-xl-inline"><button class="btn clip-btn" type="button" data-bs-toggle='tooltip' title='{% jstrans "copy to clipboard" %}'><em class="fas fa-copy"></em></button></span>`;
if (prepend === true) { if (prepend === true) {
return `<div class="flex-cell">${clipString+s}</div>`; return `<div class="flex-cell">${clipString+s}</div>`;

View File

@ -101,12 +101,12 @@ function loadRequiredForBuildsPartsTable(table, options={}) {
search: false, search: false,
sortable: false, sortable: false,
formatNoMatches: function() { formatNoMatches: function() {
return '{% trans "No parts required for builds" %}'; return '{% jstrans "No parts required for builds" %}';
}, },
columns: [ columns: [
{ {
field: 'name', field: 'name',
title: '{% trans "Part" %}', title: '{% jstrans "Part" %}',
formatter: function(value, row) { formatter: function(value, row) {
let name = shortenString(row.full_name); let name = shortenString(row.full_name);
let display= imageHoverIcon(row.thumbnail) + renderLink(name, `/part/${row.pk}/`); let display= imageHoverIcon(row.thumbnail) + renderLink(name, `/part/${row.pk}/`);
@ -116,18 +116,18 @@ function loadRequiredForBuildsPartsTable(table, options={}) {
}, },
{ {
field: 'description', field: 'description',
title: '{% trans "Description" %}', title: '{% jstrans "Description" %}',
}, },
{ {
field: 'total_in_stock', field: 'total_in_stock',
title: '{% trans "Available" %}', title: '{% jstrans "Available" %}',
formatter: function(value, row) { formatter: function(value, row) {
return value; return value;
} }
}, },
{ {
field: 'allocated_to_build_orders', field: 'allocated_to_build_orders',
title: '{% trans "Allocated Stock" %}', title: '{% jstrans "Allocated Stock" %}',
formatter: function(_value, row) { formatter: function(_value, row) {
return makeProgressBar( return makeProgressBar(
row.allocated_to_build_orders, row.allocated_to_build_orders,

View File

@ -50,8 +50,8 @@ function printLabels(options) {
if (!options.items || options.items.length == 0) { if (!options.items || options.items.length == 0) {
showAlertDialog( showAlertDialog(
'{% trans "Select Items" %}', '{% jstrans "Select Items" %}',
'{% trans "No items selected for printing" %}', '{% jstrans "No items selected for printing" %}',
); );
return; return;
} }
@ -69,8 +69,8 @@ function printLabels(options) {
success: function (response) { success: function (response) {
if (response.length == 0) { if (response.length == 0) {
showAlertDialog( showAlertDialog(
'{% trans "No Labels Found" %}', '{% jstrans "No Labels Found" %}',
'{% trans "No label templates found which match the selected items" %}', '{% jstrans "No label templates found which match the selected items" %}',
); );
return; return;
} }
@ -94,7 +94,7 @@ function printLabels(options) {
if (options.items.length > 1) { if (options.items.length > 1) {
header_html += ` header_html += `
<div class='alert alert-block alert-info'> <div class='alert alert-block alert-info'>
${options.items.length} ${options.plural_name} {% trans "selected" %} ${options.items.length} ${options.plural_name} {% jstrans "selected" %}
</div> </div>
`; `;
} }
@ -130,7 +130,7 @@ function printLabels(options) {
if (Object.keys(printingOptions).length > 0) { if (Object.keys(printingOptions).length > 0) {
formOptions.fields = { formOptions.fields = {
...formOptions.fields, ...formOptions.fields,
divider: { type: "candy", html: `<hr/><h5>{% trans "Printing Options" %}</h5>` }, divider: { type: "candy", html: `<hr/><h5>{% jstrans "Printing Options" %}</h5>` },
...printingOptions, ...printingOptions,
}; };
} }
@ -145,14 +145,14 @@ function printLabels(options) {
} }
const printingFormOptions = { const printingFormOptions = {
title: options.items.length === 1 ? `{% trans "Print label" %}` : `{% trans "Print labels" %}`, title: options.items.length === 1 ? `{% jstrans "Print label" %}` : `{% jstrans "Print labels" %}`,
submitText: `{% trans "Print" %}`, submitText: `{% jstrans "Print" %}`,
method: "POST", method: "POST",
disableSuccessMessage: true, disableSuccessMessage: true,
header_html, header_html,
fields: { fields: {
_label_template: { _label_template: {
label: `{% trans "Select label template" %}`, label: `{% jstrans "Select label template" %}`,
type: "choice", type: "choice",
localOnly: true, localOnly: true,
value: defaultLabelTemplates[options.key], value: defaultLabelTemplates[options.key],
@ -165,7 +165,7 @@ function printLabels(options) {
} }
}, },
_plugin: { _plugin: {
label: `{% trans "Select plugin" %}`, label: `{% jstrans "Select plugin" %}`,
type: "choice", type: "choice",
localOnly: true, localOnly: true,
value: user_settings.LABEL_DEFAULT_PRINTER || plugins[0].key, value: user_settings.LABEL_DEFAULT_PRINTER || plugins[0].key,
@ -184,7 +184,7 @@ function printLabels(options) {
// Download the generated file // Download the generated file
window.open(response.file); window.open(response.file);
} else { } else {
showMessage('{% trans "Labels sent to printer" %}', { showMessage('{% jstrans "Labels sent to printer" %}', {
style: 'success', style: 'success',
}); });
} }

View File

@ -55,12 +55,12 @@ function createNewModal(options={}) {
// Add in a "close" button // Add in a "close" button
if (!options.hideCloseButton) { if (!options.hideCloseButton) {
buttons += `<button type='button' class='btn btn-secondary' id='modal-form-close' data-bs-dismiss='modal'>{% trans "Cancel" %}</button>`; buttons += `<button type='button' class='btn btn-secondary' id='modal-form-close' data-bs-dismiss='modal'>{% jstrans "Cancel" %}</button>`;
} }
// Add in a "submit" button // Add in a "submit" button
if (!options.hideSubmitButton) { if (!options.hideSubmitButton) {
buttons += `<button type='button' class='btn btn-${submitClass}' id='modal-form-submit'>{% trans "Submit" %}</button>`; buttons += `<button type='button' class='btn btn-${submitClass}' id='modal-form-submit'>{% jstrans "Submit" %}</button>`;
} }
var html = ` var html = `
@ -71,7 +71,7 @@ function createNewModal(options={}) {
<h4 id='modal-title' class='modal-title'> <h4 id='modal-title' class='modal-title'>
<!-- Form title to be injected here --> <!-- Form title to be injected here -->
</h4> </h4>
<button type='button' class='btn-close' data-bs-dismiss='modal' aria-label='{% trans "Close" %}'></button> <button type='button' class='btn-close' data-bs-dismiss='modal' aria-label='{% jstrans "Close" %}'></button>
</div> </div>
<div class='modal-body modal-form-content-wrapper'> <div class='modal-body modal-form-content-wrapper'>
<div id='non-field-errors'> <div id='non-field-errors'>
@ -153,9 +153,9 @@ function createNewModal(options={}) {
}); });
// Set labels based on supplied options // Set labels based on supplied options
modalSetTitle(modal_name, options.title || '{% trans "Form Title" %}'); modalSetTitle(modal_name, options.title || '{% jstrans "Form Title" %}');
modalSetSubmitText(modal_name, options.submitText || '{% trans "Submit" %}'); modalSetSubmitText(modal_name, options.submitText || '{% jstrans "Submit" %}');
modalSetCloseText(modal_name, options.closeText || '{% trans "Cancel" %}'); modalSetCloseText(modal_name, options.closeText || '{% jstrans "Cancel" %}');
// Return the "name" of the modal // Return the "name" of the modal
return modal_name; return modal_name;
@ -442,7 +442,7 @@ function attachBootstrapCheckbox(modal) {
function loadingMessageContent() { function loadingMessageContent() {
// TODO - This can be made a lot better // TODO - This can be made a lot better
return `<span class='glyphicon glyphicon-refresh glyphicon-refresh-animate'></span> {% trans 'Waiting for server...' %}`; return `<span class='glyphicon glyphicon-refresh glyphicon-refresh-animate'></span> {% jstrans 'Waiting for server...' %}`;
} }
@ -593,7 +593,7 @@ function renderErrorMessage(xhr) {
<div class='panel'> <div class='panel'>
<div class='panel panel-heading'> <div class='panel panel-heading'>
<div class='panel-title'> <div class='panel-title'>
<a data-bs-toggle='collapse' href="#collapse-error-info">{% trans "Show Error Information" %}</a> <a data-bs-toggle='collapse' href="#collapse-error-info">{% jstrans "Show Error Information" %}</a>
</div> </div>
</div> </div>
<div class='panel-collapse collapse' id='collapse-error-info'> <div class='panel-collapse collapse' id='collapse-error-info'>
@ -625,7 +625,7 @@ function showAlertDialog(title, content, options={}) {
var modal = createNewModal({ var modal = createNewModal({
title: title, title: title,
closeText: '{% trans "Close" %}', closeText: '{% jstrans "Close" %}',
hideSubmitButton: true, hideSubmitButton: true,
}); });
@ -679,8 +679,8 @@ function showQuestionDialog(title, content, options={}) {
*/ */
options.title = title; options.title = title;
options.submitText = options.accept_text || '{% trans "Accept" %}'; options.submitText = options.accept_text || '{% jstrans "Accept" %}';
options.closeText = options.cancel_text || '{% trans "Cancel" %}'; options.closeText = options.cancel_text || '{% jstrans "Cancel" %}';
var modal = createNewModal(options); var modal = createNewModal(options);
@ -737,7 +737,7 @@ function openModal(options) {
if (options.title) { if (options.title) {
modalSetTitle(modal, options.title); modalSetTitle(modal, options.title);
} else { } else {
modalSetTitle(modal, '{% trans "Loading Data" %}...'); modalSetTitle(modal, '{% jstrans "Loading Data" %}...');
} }
// Unless the content is explicitly set, display loading message // Unless the content is explicitly set, display loading message
@ -748,8 +748,8 @@ function openModal(options) {
} }
// Default labels for 'Submit' and 'Close' buttons in the form // Default labels for 'Submit' and 'Close' buttons in the form
var submit_text = options.submit_text || '{% trans "Submit" %}'; var submit_text = options.submit_text || '{% jstrans "Submit" %}';
var close_text = options.close_text || '{% trans "Close" %}'; var close_text = options.close_text || '{% jstrans "Close" %}';
modalSetButtonText(modal, submit_text, close_text); modalSetButtonText(modal, submit_text, close_text);
@ -1008,7 +1008,7 @@ function handleModalForm(url, options) {
} }
} else { } else {
$(modal).modal('hide'); $(modal).modal('hide');
showAlertDialog('{% trans "Invalid response from server" %}', '{% trans "Form data missing from server response" %}'); showAlertDialog('{% jstrans "Invalid response from server" %}', '{% jstrans "Form data missing from server response" %}');
} }
} }
} else { } else {
@ -1020,7 +1020,7 @@ function handleModalForm(url, options) {
// There was an error submitting form data via POST // There was an error submitting form data via POST
$(modal).modal('hide'); $(modal).modal('hide');
showAlertDialog('{% trans "Error posting form data" %}', renderErrorMessage(xhr)); showAlertDialog('{% jstrans "Error posting form data" %}', renderErrorMessage(xhr));
}, },
complete: function() { complete: function() {
// TODO // TODO
@ -1056,8 +1056,8 @@ function launchModalForm(url, options = {}) {
var modal = options.modal || '#modal-form'; var modal = options.modal || '#modal-form';
// Default labels for 'Submit' and 'Close' buttons in the form // Default labels for 'Submit' and 'Close' buttons in the form
var submit_text = options.submit_text || '{% trans "Submit" %}'; var submit_text = options.submit_text || '{% jstrans "Submit" %}';
var close_text = options.close_text || '{% trans "Close" %}'; var close_text = options.close_text || '{% jstrans "Close" %}';
// Clean custom action buttons // Clean custom action buttons
$(modal).find('#modal-footer-buttons').html(''); $(modal).find('#modal-footer-buttons').html('');
@ -1117,7 +1117,7 @@ function launchModalForm(url, options = {}) {
} else { } else {
$(modal).modal('hide'); $(modal).modal('hide');
showAlertDialog('{% trans "Invalid server response" %}', '{% trans "JSON response missing form data" %}'); showAlertDialog('{% jstrans "Invalid server response" %}', '{% jstrans "JSON response missing form data" %}');
} }
}, },
error: function(xhr) { error: function(xhr) {
@ -1127,36 +1127,36 @@ function launchModalForm(url, options = {}) {
if (xhr.status == 0) { if (xhr.status == 0) {
// No response from the server // No response from the server
showAlertDialog( showAlertDialog(
'{% trans "No Response" %}', '{% jstrans "No Response" %}',
'{% trans "No response from the InvenTree server" %}', '{% jstrans "No response from the InvenTree server" %}',
); );
} else if (xhr.status == 400) { } else if (xhr.status == 400) {
showAlertDialog( showAlertDialog(
'{% trans "Error 400: Bad Request" %}', '{% jstrans "Error 400: Bad Request" %}',
'{% trans "Server returned error code 400" %}', '{% jstrans "Server returned error code 400" %}',
); );
} else if (xhr.status == 401) { } else if (xhr.status == 401) {
showAlertDialog( showAlertDialog(
'{% trans "Error 401: Not Authenticated" %}', '{% jstrans "Error 401: Not Authenticated" %}',
'{% trans "Authentication credentials not supplied" %}', '{% jstrans "Authentication credentials not supplied" %}',
); );
} else if (xhr.status == 403) { } else if (xhr.status == 403) {
showAlertDialog( showAlertDialog(
'{% trans "Error 403: Permission Denied" %}', '{% jstrans "Error 403: Permission Denied" %}',
'{% trans "You do not have the required permissions to access this function" %}', '{% jstrans "You do not have the required permissions to access this function" %}',
); );
} else if (xhr.status == 404) { } else if (xhr.status == 404) {
showAlertDialog( showAlertDialog(
'{% trans "Error 404: Resource Not Found" %}', '{% jstrans "Error 404: Resource Not Found" %}',
'{% trans "The requested resource could not be located on the server" %}', '{% jstrans "The requested resource could not be located on the server" %}',
); );
} else if (xhr.status == 408) { } else if (xhr.status == 408) {
showAlertDialog( showAlertDialog(
'{% trans "Error 408: Timeout" %}', '{% jstrans "Error 408: Timeout" %}',
'{% trans "Connection timeout while requesting data from server" %}', '{% jstrans "Connection timeout while requesting data from server" %}',
); );
} else { } else {
showAlertDialog('{% trans "Error requesting form data" %}', renderErrorMessage(xhr)); showAlertDialog('{% jstrans "Error requesting form data" %}', renderErrorMessage(xhr));
} }
console.error('Modal form error: ' + xhr.status); console.error('Modal form error: ' + xhr.status);

View File

@ -216,21 +216,21 @@ function renderStockItem(data, parameters={}) {
} }
if (data.quantity == 0) { if (data.quantity == 0) {
stock_detail = `<span class='badge rounded-pill bg-danger'>{% trans "No Stock"% }</span>`; stock_detail = `<span class='badge rounded-pill bg-danger'>{% jstrans "No Stock"% }</span>`;
} else { } else {
if (data.serial && data.quantity == 1) { if (data.serial && data.quantity == 1) {
stock_detail = `{% trans "Serial Number" %}: ${data.serial}`; stock_detail = `{% jstrans "Serial Number" %}: ${data.serial}`;
} else { } else {
if (render_available_quantity) { if (render_available_quantity) {
var available = data.quantity - data.allocated; var available = data.quantity - data.allocated;
stock_detail = `{% trans "Available" %}: ${available}`; stock_detail = `{% jstrans "Available" %}: ${available}`;
} else { } else {
stock_detail = `{% trans "Quantity" %}: ${data.quantity}`; stock_detail = `{% jstrans "Quantity" %}: ${data.quantity}`;
} }
} }
if (data.batch) { if (data.batch) {
stock_detail += ` - <small>{% trans "Batch" %}: ${data.batch}</small>`; stock_detail += ` - <small>{% jstrans "Batch" %}: ${data.batch}</small>`;
} }
} }
@ -301,7 +301,7 @@ function renderPart(data, parameters={}) {
labels = partStockLabel(data); labels = partStockLabel(data);
if (!data.active) { if (!data.active) {
labels += `<span class='badge badge-right rounded-pill bg-danger'>{% trans "Inactive" %}</span>`; labels += `<span class='badge badge-right rounded-pill bg-danger'>{% jstrans "Inactive" %}</span>`;
} }
} }
@ -443,7 +443,7 @@ function renderSalesOrderShipment(data, parameters={}) {
return renderModel( return renderModel(
{ {
text: data.order_detail.reference, text: data.order_detail.reference,
textSecondary: `{% trans "Shipment" %} ${data.reference}`, textSecondary: `{% jstrans "Shipment" %} ${data.reference}`,
}, },
parameters parameters
); );

View File

@ -30,18 +30,18 @@ function loadNewsFeedTable(table, options={}, enableDelete=false) {
}, },
paginationVAlign: 'bottom', paginationVAlign: 'bottom',
formatNoMatches: function() { formatNoMatches: function() {
return '{% trans "No news found" %}'; return '{% jstrans "No news found" %}';
}, },
columns: [ columns: [
{ {
field: 'pk', field: 'pk',
title: '{% trans "ID" %}', title: '{% jstrans "ID" %}',
visible: false, visible: false,
switchable: false, switchable: false,
}, },
{ {
field: 'title', field: 'title',
title: '{% trans "Title" %}', title: '{% jstrans "Title" %}',
sortable: 'true', sortable: 'true',
formatter: function(value, row) { formatter: function(value, row) {
return `<a href="` + row.link + `">` + value + `</a>`; return `<a href="` + row.link + `">` + value + `</a>`;
@ -49,15 +49,15 @@ function loadNewsFeedTable(table, options={}, enableDelete=false) {
}, },
{ {
field: 'summary', field: 'summary',
title: '{% trans "Summary" %}', title: '{% jstrans "Summary" %}',
}, },
{ {
field: 'author', field: 'author',
title: '{% trans "Author" %}', title: '{% jstrans "Author" %}',
}, },
{ {
field: 'published', field: 'published',
title: '{% trans "Published" %}', title: '{% jstrans "Published" %}',
sortable: 'true', sortable: 'true',
formatter: function(value, row) { formatter: function(value, row) {
var html = renderDate(value); var html = renderDate(value);

View File

@ -43,13 +43,13 @@ function loadNotificationTable(table, options={}, enableDelete=false) {
columns: [ columns: [
{ {
field: 'pk', field: 'pk',
title: '{% trans "ID" %}', title: '{% jstrans "ID" %}',
visible: false, visible: false,
switchable: false, switchable: false,
}, },
{ {
field: 'age', field: 'age',
title: '{% trans "Age" %}', title: '{% jstrans "Age" %}',
sortable: 'true', sortable: 'true',
formatter: function(value, row) { formatter: function(value, row) {
return row.age_human; return row.age_human;
@ -57,12 +57,12 @@ function loadNotificationTable(table, options={}, enableDelete=false) {
}, },
{ {
field: 'category', field: 'category',
title: '{% trans "Category" %}', title: '{% jstrans "Category" %}',
sortable: 'true', sortable: 'true',
}, },
{ {
field: 'name', field: 'name',
title: '{% trans "Notification" %}', title: '{% jstrans "Notification" %}',
formatter: function(value, row) { formatter: function(value, row) {
if (row.target && row.target.link) { if (row.target && row.target.link) {
return renderLink(value, row.target.link); return renderLink(value, row.target.link);
@ -73,7 +73,7 @@ function loadNotificationTable(table, options={}, enableDelete=false) {
}, },
{ {
field: 'message', field: 'message',
title: '{% trans "Message" %}', title: '{% jstrans "Message" %}',
}, },
{ {
formatter: function(value, row, index, field) { formatter: function(value, row, index, field) {
@ -82,7 +82,7 @@ function loadNotificationTable(table, options={}, enableDelete=false) {
let bDel = ''; let bDel = '';
if (enableDelete) { if (enableDelete) {
bDel = `<button title='{% trans "Delete Notification" %}' class='notification-delete btn btn-outline-secondary' type='button' pk='${row.pk}'><span class='fas fa-trash-alt icon-red'></span></button>`; bDel = `<button title='{% jstrans "Delete Notification" %}' class='notification-delete btn btn-outline-secondary' type='button' pk='${row.pk}'><span class='fas fa-trash-alt icon-red'></span></button>`;
} }
var html = `<div class='btn-group float-right' role='group'>${bRead}${bDel}</div>`; var html = `<div class='btn-group float-right' role='group'>${bRead}${bDel}</div>`;
@ -221,11 +221,11 @@ function getReadEditButton(pk, state, small=false) {
let bReadTarget = ''; let bReadTarget = '';
if (state) { if (state) {
bReadText = '{% trans "Mark as unread" %}'; bReadText = '{% jstrans "Mark as unread" %}';
bReadIcon = 'fas fa-bookmark icon-red'; bReadIcon = 'fas fa-bookmark icon-red';
bReadTarget = 'unread'; bReadTarget = 'unread';
} else { } else {
bReadText = '{% trans "Mark as read" %}'; bReadText = '{% jstrans "Mark as read" %}';
bReadIcon = 'far fa-bookmark icon-green'; bReadIcon = 'far fa-bookmark icon-green';
bReadTarget = 'read'; bReadTarget = 'read';
} }
@ -251,7 +251,7 @@ function openNotificationPanel() {
{ {
success: function(response) { success: function(response) {
if (response.length == 0) { if (response.length == 0) {
html = `<p class='text-muted'><em>{% trans "No unread notifications" %}</em><span class='fas fa-check-circle icon-green float-right'></span></p>`; html = `<p class='text-muted'><em>{% jstrans "No unread notifications" %}</em><span class='fas fa-check-circle icon-green float-right'></span></p>`;
} else { } else {
// build up items // build up items
response.forEach(function(item, index) { response.forEach(function(item, index) {
@ -293,7 +293,7 @@ function openNotificationPanel() {
* clears the notification panel when closed * clears the notification panel when closed
**/ **/
function closeNotificationPanel() { function closeNotificationPanel() {
$('#notification-center').html(`<p class='text-muted'>{% trans "Notifications will load here" %}</p>`); $('#notification-center').html(`<p class='text-muted'>{% jstrans "Notifications will load here" %}</p>`);
} }
/** /**

View File

@ -86,7 +86,7 @@ function createExtraLineItem(options={}) {
constructForm(options.url, { constructForm(options.url, {
fields: fields, fields: fields,
method: 'POST', method: 'POST',
title: '{% trans "Add Extra Line Item" %}', title: '{% jstrans "Add Extra Line Item" %}',
onSuccess: function(response) { onSuccess: function(response) {
if (options.table) { if (options.table) {
reloadBootstrapTable(options.table); reloadBootstrapTable(options.table);
@ -123,11 +123,11 @@ function exportOrder(redirect_url, options={}) {
} }
constructFormBody({}, { constructFormBody({}, {
title: '{% trans "Export Order" %}', title: '{% jstrans "Export Order" %}',
fields: { fields: {
format: { format: {
label: '{% trans "Format" %}', label: '{% jstrans "Format" %}',
help_text: '{% trans "Select file format" %}', help_text: '{% jstrans "Select file format" %}',
required: true, required: true,
type: 'choice', type: 'choice',
value: format, value: format,
@ -238,7 +238,7 @@ function loadExtraLineTable(options={}) {
method: 'POST', method: 'POST',
fields: fields, fields: fields,
data: data, data: data,
title: '{% trans "Duplicate Line" %}', title: '{% jstrans "Duplicate Line" %}',
onSuccess: reloadExtraLineTable, onSuccess: reloadExtraLineTable,
}); });
} }
@ -252,7 +252,7 @@ function loadExtraLineTable(options={}) {
constructForm(`${options.url}${pk}/`, { constructForm(`${options.url}${pk}/`, {
fields: extraLineFields(), fields: extraLineFields(),
title: '{% trans "Edit Line" %}', title: '{% jstrans "Edit Line" %}',
onSuccess: reloadExtraLineTable, onSuccess: reloadExtraLineTable,
}); });
}); });
@ -265,7 +265,7 @@ function loadExtraLineTable(options={}) {
constructForm(`${options.url}${pk}/`, { constructForm(`${options.url}${pk}/`, {
method: 'DELETE', method: 'DELETE',
title: '{% trans "Delete Line" %}', title: '{% jstrans "Delete Line" %}',
onSuccess: reloadExtraLineTable, onSuccess: reloadExtraLineTable,
}); });
}); });
@ -278,7 +278,7 @@ function loadExtraLineTable(options={}) {
sidePagination: 'server', sidePagination: 'server',
onPostBody: setupCallbacks, onPostBody: setupCallbacks,
formatNoMatches: function() { formatNoMatches: function() {
return '{% trans "No line items found" %}'; return '{% jstrans "No line items found" %}';
}, },
queryParams: filters, queryParams: filters,
original: options.params, original: options.params,
@ -288,20 +288,20 @@ function loadExtraLineTable(options={}) {
{ {
sortable: true, sortable: true,
field: 'reference', field: 'reference',
title: '{% trans "Reference" %}', title: '{% jstrans "Reference" %}',
switchable: false, switchable: false,
}, },
{ {
sortable: false, sortable: false,
switchable: true, switchable: true,
field: 'description', field: 'description',
title: '{% trans "Description" %}', title: '{% jstrans "Description" %}',
}, },
{ {
sortable: true, sortable: true,
switchable: false, switchable: false,
field: 'quantity', field: 'quantity',
title: '{% trans "Quantity" %}', title: '{% jstrans "Quantity" %}',
footerFormatter: function(data) { footerFormatter: function(data) {
return data.map(function(row) { return data.map(function(row) {
return +row['quantity']; return +row['quantity'];
@ -313,7 +313,7 @@ function loadExtraLineTable(options={}) {
{ {
sortable: true, sortable: true,
field: 'price', field: 'price',
title: '{% trans "Unit Price" %}', title: '{% jstrans "Unit Price" %}',
formatter: function(value, row) { formatter: function(value, row) {
return formatCurrency(row.price, { return formatCurrency(row.price, {
currency: row.price_currency, currency: row.price_currency,
@ -324,7 +324,7 @@ function loadExtraLineTable(options={}) {
field: 'total_price', field: 'total_price',
sortable: true, sortable: true,
switchable: true, switchable: true,
title: '{% trans "Total Price" %}', title: '{% jstrans "Total Price" %}',
formatter: function(value, row) { formatter: function(value, row) {
return formatCurrency(row.price * row.quantity, { return formatCurrency(row.price * row.quantity, {
currency: row.price_currency, currency: row.price_currency,
@ -344,11 +344,11 @@ function loadExtraLineTable(options={}) {
}, },
{ {
field: 'notes', field: 'notes',
title: '{% trans "Notes" %}', title: '{% jstrans "Notes" %}',
}, },
{ {
field: 'link', field: 'link',
title: '{% trans "Link" %}', title: '{% jstrans "Link" %}',
formatter: function(value) { formatter: function(value) {
if (value) { if (value) {
return renderLink(value, value); return renderLink(value, value);
@ -366,12 +366,12 @@ function loadExtraLineTable(options={}) {
var pk = row.pk; var pk = row.pk;
if (options.allow_edit) { if (options.allow_edit) {
html += makeCopyButton('button-duplicate', pk, '{% trans "Duplicate line" %}'); html += makeCopyButton('button-duplicate', pk, '{% jstrans "Duplicate line" %}');
html += makeEditButton('button-edit', pk, '{% trans "Edit line" %}'); html += makeEditButton('button-edit', pk, '{% jstrans "Edit line" %}');
} }
if (options.allow_delete) { if (options.allow_delete) {
html += makeDeleteButton('button-delete', pk, '{% trans "Delete line" %}', ); html += makeDeleteButton('button-delete', pk, '{% jstrans "Delete line" %}', );
} }
} }

File diff suppressed because it is too large Load Diff

View File

@ -43,33 +43,33 @@ function loadPluginTable(table, options={}) {
queryParams: filters, queryParams: filters,
sortable: true, sortable: true,
formatNoMatches: function() { formatNoMatches: function() {
return '{% trans "No plugins found" %}'; return '{% jstrans "No plugins found" %}';
}, },
columns: [ columns: [
{ {
field: 'name', field: 'name',
title: '{% trans "Plugin" %}', title: '{% jstrans "Plugin" %}',
sortable: true, sortable: true,
switchable: false, switchable: false,
formatter: function(value, row) { formatter: function(value, row) {
let html = ''; let html = '';
if (!row.is_installed) { if (!row.is_installed) {
html += `<span class='fa fa-question-circle' title='{% trans "This plugin is no longer installed" %}'></span>`; html += `<span class='fa fa-question-circle' title='{% jstrans "This plugin is no longer installed" %}'></span>`;
} else if (row.active) { } else if (row.active) {
html += `<span class='fa fa-check-circle icon-green' title='{% trans "This plugin is active" %}'></span>`; html += `<span class='fa fa-check-circle icon-green' title='{% jstrans "This plugin is active" %}'></span>`;
} else { } else {
html += `<span class='fa fa-times-circle icon-red' title ='{% trans "This plugin is installed but not active" %}'></span>`; html += `<span class='fa fa-times-circle icon-red' title ='{% jstrans "This plugin is installed but not active" %}'></span>`;
} }
html += `&nbsp;<span>${value}</span>`; html += `&nbsp;<span>${value}</span>`;
if (row.is_builtin) { if (row.is_builtin) {
html += `<span class='badge bg-success rounded-pill badge-right'>{% trans "Builtin" %}</span>`; html += `<span class='badge bg-success rounded-pill badge-right'>{% jstrans "Builtin" %}</span>`;
} }
if (row.is_sample) { if (row.is_sample) {
html += `<span class='badge bg-info rounded-pill badge-right'>{% trans "Sample" %}</span>`; html += `<span class='badge bg-info rounded-pill badge-right'>{% jstrans "Sample" %}</span>`;
} }
return html; return html;
@ -77,13 +77,13 @@ function loadPluginTable(table, options={}) {
}, },
{ {
field: 'meta.description', field: 'meta.description',
title: '{% trans "Description" %}', title: '{% jstrans "Description" %}',
sortable: false, sortable: false,
switchable: true, switchable: true,
}, },
{ {
field: 'meta.version', field: 'meta.version',
title: '{% trans "Version" %}', title: '{% jstrans "Version" %}',
formatter: function(value, row) { formatter: function(value, row) {
if (value) { if (value) {
let html = value; let html = value;
@ -100,7 +100,7 @@ function loadPluginTable(table, options={}) {
}, },
{ {
field: 'meta.author', field: 'meta.author',
title: '{% trans "Author" %}', title: '{% jstrans "Author" %}',
sortable: false, sortable: false,
}, },
{ {
@ -114,9 +114,9 @@ function loadPluginTable(table, options={}) {
// Check if custom plugins are enabled for this instance // Check if custom plugins are enabled for this instance
if (options.custom && !row.is_builtin && row.is_installed) { if (options.custom && !row.is_builtin && row.is_installed) {
if (row.active) { if (row.active) {
buttons += makeIconButton('fa-stop-circle icon-red', 'btn-plugin-disable', row.pk, '{% trans "Disable Plugin" %}'); buttons += makeIconButton('fa-stop-circle icon-red', 'btn-plugin-disable', row.pk, '{% jstrans "Disable Plugin" %}');
} else { } else {
buttons += makeIconButton('fa-play-circle icon-green', 'btn-plugin-enable', row.pk, '{% trans "Enable Plugin" %}'); buttons += makeIconButton('fa-play-circle icon-green', 'btn-plugin-enable', row.pk, '{% jstrans "Enable Plugin" %}');
} }
} }
@ -148,14 +148,14 @@ function loadPluginTable(table, options={}) {
function installPlugin() { function installPlugin() {
constructForm(`/api/plugins/install/`, { constructForm(`/api/plugins/install/`, {
method: 'POST', method: 'POST',
title: '{% trans "Install Plugin" %}', title: '{% jstrans "Install Plugin" %}',
fields: { fields: {
packagename: {}, packagename: {},
url: {}, url: {},
confirm: {}, confirm: {},
}, },
onSuccess: function(data) { onSuccess: function(data) {
let msg = '{% trans "The Plugin was installed" %}'; let msg = '{% jstrans "The Plugin was installed" %}';
showMessage(msg, {style: 'success', details: data.result, timeout: 30000}); showMessage(msg, {style: 'success', details: data.result, timeout: 30000});
// Reload the plugin table // Reload the plugin table
@ -174,19 +174,19 @@ function activatePlugin(plugin_id, active=true) {
let html = active ? ` let html = active ? `
<span class='alert alert-block alert-info'> <span class='alert alert-block alert-info'>
{% trans "Are you sure you want to enable this plugin?" %} {% jstrans "Are you sure you want to enable this plugin?" %}
</span> </span>
` : ` ` : `
<span class='alert alert-block alert-danger'> <span class='alert alert-block alert-danger'>
{% trans "Are you sure you want to disable this plugin?" %} {% jstrans "Are you sure you want to disable this plugin?" %}
</span> </span>
`; `;
constructForm(null, { constructForm(null, {
title: active ? '{% trans "Enable Plugin" %}' : '{% trans "Disable Plugin" %}', title: active ? '{% jstrans "Enable Plugin" %}' : '{% jstrans "Disable Plugin" %}',
preFormContent: html, preFormContent: html,
confirm: true, confirm: true,
submitText: active ? '{% trans "Enable" %}' : '{% trans "Disable" %}', submitText: active ? '{% jstrans "Enable" %}' : '{% jstrans "Disable" %}',
submitClass: active ? 'success' : 'danger', submitClass: active ? 'success' : 'danger',
onSubmit: function(_fields, opts) { onSubmit: function(_fields, opts) {
showModalSpinner(opts.modal); showModalSpinner(opts.modal);
@ -200,7 +200,7 @@ function activatePlugin(plugin_id, active=true) {
method: 'PATCH', method: 'PATCH',
success: function() { success: function() {
$(opts.modal).modal('hide'); $(opts.modal).modal('hide');
addCachedAlert('{% trans "Plugin updated" %}', {style: 'success'}); addCachedAlert('{% jstrans "Plugin updated" %}', {style: 'success'});
location.reload(); location.reload();
}, },
error: function(xhr) { error: function(xhr) {
@ -221,7 +221,7 @@ function reloadPlugins() {
let url = '{% url "api-plugin-reload" %}'; let url = '{% url "api-plugin-reload" %}';
constructForm(url, { constructForm(url, {
title: '{% trans "Reload Plugins" %}', title: '{% jstrans "Reload Plugins" %}',
method: 'POST', method: 'POST',
confirm: true, confirm: true,
fields: { fields: {

View File

@ -156,7 +156,7 @@ function calculateTotalPrice(dataset, value_func, currency_func, options={}) {
if (!rates) { if (!rates) {
console.error('Could not retrieve currency conversion information from the server'); console.error('Could not retrieve currency conversion information from the server');
return `<span class='icon-red fas fa-exclamation-circle' title='{% trans "Error fetching currency data" %}'></span>`; return `<span class='icon-red fas fa-exclamation-circle' title='{% jstrans "Error fetching currency data" %}'></span>`;
} }
if (!currency) { if (!currency) {
@ -318,7 +318,7 @@ function loadBomPricingChart(options={}) {
search: false, search: false,
showColumns: false, showColumns: false,
formatNoMatches: function() { formatNoMatches: function() {
return '{% trans "No BOM data available" %}'; return '{% jstrans "No BOM data available" %}';
}, },
onLoadSuccess: function(data) { onLoadSuccess: function(data) {
// Construct BOM pricing chart // Construct BOM pricing chart
@ -350,12 +350,12 @@ function loadBomPricingChart(options={}) {
labels: graphLabels, labels: graphLabels,
datasets: [ datasets: [
{ {
label: '{% trans "Maximum Price" %}', label: '{% jstrans "Maximum Price" %}',
data: maxValues, data: maxValues,
backgroundColor: colors, backgroundColor: colors,
}, },
{ {
label: '{% trans "Minimum Price" %}', label: '{% jstrans "Minimum Price" %}',
data: minValues, data: minValues,
backgroundColor: colors, backgroundColor: colors,
}, },
@ -366,7 +366,7 @@ function loadBomPricingChart(options={}) {
columns: [ columns: [
{ {
field: 'sub_part', field: 'sub_part',
title: '{% trans "Part" %}', title: '{% jstrans "Part" %}',
sortable: true, sortable: true,
formatter: function(value, row) { formatter: function(value, row) {
var url = `/part/${row.sub_part}/`; var url = `/part/${row.sub_part}/`;
@ -378,17 +378,17 @@ function loadBomPricingChart(options={}) {
}, },
{ {
field: 'quantity', field: 'quantity',
title: '{% trans "Quantity" %}', title: '{% jstrans "Quantity" %}',
sortable: true, sortable: true,
}, },
{ {
field: 'reference', field: 'reference',
title: '{% trans "Reference" %}', title: '{% jstrans "Reference" %}',
sortable: true, sortable: true,
}, },
{ {
field: 'pricing', field: 'pricing',
title: '{% trans "Price Range" %}', title: '{% jstrans "Price Range" %}',
sortable: false, sortable: false,
formatter: function(value, row) { formatter: function(value, row) {
var min_price = row.pricing_min; var min_price = row.pricing_min;
@ -460,7 +460,7 @@ function loadPartSupplierPricingTable(options={}) {
search: false, search: false,
showColumns: false, showColumns: false,
formatNoMatches: function() { formatNoMatches: function() {
return '{% trans "No supplier pricing data available" %}'; return '{% jstrans "No supplier pricing data available" %}';
}, },
onLoadSuccess: function(data) { onLoadSuccess: function(data) {
// Update supplier pricing chart // Update supplier pricing chart
@ -471,7 +471,7 @@ function loadPartSupplierPricingTable(options={}) {
// Sort in increasing order of quantity // Sort in increasing order of quantity
data = data.sort((a, b) => (a.quantity - b.quantity)); data = data.sort((a, b) => (a.quantity - b.quantity));
var graphLabels = Array.from(data, (x) => (`${x.part_detail.SKU} - {% trans "Quantity" %} ${x.quantity}`)); var graphLabels = Array.from(data, (x) => (`${x.part_detail.SKU} - {% jstrans "Quantity" %} ${x.quantity}`));
var graphValues = Array.from(data, (x) => (x.price / x.part_detail.pack_quantity_native)); var graphValues = Array.from(data, (x) => (x.price / x.part_detail.pack_quantity_native));
if (chart) { if (chart) {
@ -482,7 +482,7 @@ function loadPartSupplierPricingTable(options={}) {
labels: graphLabels, labels: graphLabels,
datasets: [ datasets: [
{ {
label: '{% trans "Supplier Pricing" %}', label: '{% jstrans "Supplier Pricing" %}',
data: graphValues, data: graphValues,
backgroundColor: 'rgba(255, 206, 86, 0.2)', backgroundColor: 'rgba(255, 206, 86, 0.2)',
borderColor: 'rgb(255, 206, 86)', borderColor: 'rgb(255, 206, 86)',
@ -495,7 +495,7 @@ function loadPartSupplierPricingTable(options={}) {
columns: [ columns: [
{ {
field: 'supplier', field: 'supplier',
title: '{% trans "Supplier" %}', title: '{% jstrans "Supplier" %}',
formatter: function(value, row) { formatter: function(value, row) {
var html = ''; var html = '';
@ -507,7 +507,7 @@ function loadPartSupplierPricingTable(options={}) {
}, },
{ {
field: 'sku', field: 'sku',
title: '{% trans "SKU" %}', title: '{% jstrans "SKU" %}',
sortable: true, sortable: true,
formatter: function(value, row) { formatter: function(value, row) {
return renderLink( return renderLink(
@ -519,12 +519,12 @@ function loadPartSupplierPricingTable(options={}) {
{ {
sortable: true, sortable: true,
field: 'quantity', field: 'quantity',
title: '{% trans "Quantity" %}', title: '{% jstrans "Quantity" %}',
}, },
{ {
sortable: true, sortable: true,
field: 'price', field: 'price',
title: '{% trans "Unit Price" %}', title: '{% jstrans "Unit Price" %}',
formatter: function(value, row) { formatter: function(value, row) {
if (row.price == null) { if (row.price == null) {
@ -569,7 +569,7 @@ function loadPriceBreakTable(table, options={}) {
pageSize: 10, pageSize: 10,
method: 'get', method: 'get',
formatNoMatches: function() { formatNoMatches: function() {
return `{% trans "No price break data available" %}`; return `{% jstrans "No price break data available" %}`;
}, },
queryParams: { queryParams: {
part: options.part part: options.part
@ -593,7 +593,7 @@ function loadPriceBreakTable(table, options={}) {
labels: graphLabels, labels: graphLabels,
datasets: [ datasets: [
{ {
label: '{% trans "Unit Price" %}', label: '{% jstrans "Unit Price" %}',
data: graphData, data: graphData,
backgroundColor: 'rgba(255, 206, 86, 0.2)', backgroundColor: 'rgba(255, 206, 86, 0.2)',
borderColor: 'rgb(255, 206, 86)', borderColor: 'rgb(255, 206, 86)',
@ -613,20 +613,20 @@ function loadPriceBreakTable(table, options={}) {
}, },
{ {
field: 'quantity', field: 'quantity',
title: '{% trans "Quantity" %}', title: '{% jstrans "Quantity" %}',
sortable: true, sortable: true,
}, },
{ {
field: 'price', field: 'price',
title: '{% trans "Price" %}', title: '{% jstrans "Price" %}',
sortable: true, sortable: true,
formatter: function(value, row) { formatter: function(value, row) {
let html = formatCurrency(value, {currency: row.price_currency}); let html = formatCurrency(value, {currency: row.price_currency});
let buttons = ''; let buttons = '';
buttons += makeEditButton(`button-${name}-edit`, row.pk, `{% trans "Edit" %} ${human_name}`); buttons += makeEditButton(`button-${name}-edit`, row.pk, `{% jstrans "Edit" %} ${human_name}`);
buttons += makeDeleteButton(`button-${name}-delete`, row.pk, `{% trans "Delete" %} ${human_name}"`); buttons += makeDeleteButton(`button-${name}-delete`, row.pk, `{% jstrans "Delete" %} ${human_name}"`);
html += wrapButtons(buttons); html += wrapButtons(buttons);
@ -681,7 +681,7 @@ function initPriceBreakSet(table, options) {
}, },
}, },
method: 'POST', method: 'POST',
title: '{% trans "Add Price Break" %}', title: '{% jstrans "Add Price Break" %}',
onSuccess: reloadPriceBreakTable, onSuccess: reloadPriceBreakTable,
}); });
}); });
@ -691,7 +691,7 @@ function initPriceBreakSet(table, options) {
constructForm(`${pb_url}${pk}/`, { constructForm(`${pb_url}${pk}/`, {
method: 'DELETE', method: 'DELETE',
title: '{% trans "Delete Price Break" %}', title: '{% jstrans "Delete Price Break" %}',
onSuccess: reloadPriceBreakTable, onSuccess: reloadPriceBreakTable,
}); });
}); });
@ -709,7 +709,7 @@ function initPriceBreakSet(table, options) {
icon: 'fa-coins', icon: 'fa-coins',
}, },
}, },
title: '{% trans "Edit Price Break" %}', title: '{% jstrans "Edit Price Break" %}',
onSuccess: reloadPriceBreakTable, onSuccess: reloadPriceBreakTable,
}); });
}); });
@ -752,7 +752,7 @@ function loadPurchasePriceHistoryTable(options={}) {
search: false, search: false,
showColumns: false, showColumns: false,
formatNoMatches: function() { formatNoMatches: function() {
return '{% trans "No purchase history data available" %}'; return '{% jstrans "No purchase history data available" %}';
}, },
onLoadSuccess: function(data) { onLoadSuccess: function(data) {
// Update purchase price history chart // Update purchase price history chart
@ -788,7 +788,7 @@ function loadPurchasePriceHistoryTable(options={}) {
labels: graphLabels, labels: graphLabels,
datasets: [ datasets: [
{ {
label: '{% trans "Purchase Price History" %}', label: '{% jstrans "Purchase Price History" %}',
data: graphValues, data: graphValues,
backgroundColor: 'rgba(255, 206, 86, 0.2)', backgroundColor: 'rgba(255, 206, 86, 0.2)',
borderColor: 'rgb(255, 206, 86)', borderColor: 'rgb(255, 206, 86)',
@ -801,7 +801,7 @@ function loadPurchasePriceHistoryTable(options={}) {
columns: [ columns: [
{ {
field: 'order', field: 'order',
title: '{% trans "Purchase Order" %}', title: '{% jstrans "Purchase Order" %}',
sortable: true, sortable: true,
formatter: function(value, row) { formatter: function(value, row) {
var order = row.order_detail; var order = row.order_detail;
@ -823,7 +823,7 @@ function loadPurchasePriceHistoryTable(options={}) {
}, },
{ {
field: 'order_detail.complete_date', field: 'order_detail.complete_date',
title: '{% trans "Date" %}', title: '{% jstrans "Date" %}',
sortable: true, sortable: true,
formatter: function(value) { formatter: function(value) {
return renderDate(value); return renderDate(value);
@ -831,7 +831,7 @@ function loadPurchasePriceHistoryTable(options={}) {
}, },
{ {
field: 'purchase_price', field: 'purchase_price',
title: '{% trans "Unit Price" %}', title: '{% jstrans "Unit Price" %}',
sortable: true, sortable: true,
formatter: function(value, row) { formatter: function(value, row) {
@ -891,7 +891,7 @@ function loadSalesPriceHistoryTable(options={}) {
search: false, search: false,
showColumns: false, showColumns: false,
formatNoMatches: function() { formatNoMatches: function() {
return '{% trans "No sales history data available" %}'; return '{% jstrans "No sales history data available" %}';
}, },
onLoadSuccess: function(data) { onLoadSuccess: function(data) {
// Update sales price history chart // Update sales price history chart
@ -913,7 +913,7 @@ function loadSalesPriceHistoryTable(options={}) {
labels: graphLabels, labels: graphLabels,
datasets: [ datasets: [
{ {
label: '{% trans "Sale Price History" %}', label: '{% jstrans "Sale Price History" %}',
data: graphValues, data: graphValues,
backgroundColor: 'rgba(255, 206, 86, 0.2)', backgroundColor: 'rgba(255, 206, 86, 0.2)',
borderColor: 'rgb(255, 206, 86)', borderColor: 'rgb(255, 206, 86)',
@ -926,7 +926,7 @@ function loadSalesPriceHistoryTable(options={}) {
columns: [ columns: [
{ {
field: 'order', field: 'order',
title: '{% trans "Sales Order" %}', title: '{% jstrans "Sales Order" %}',
formatter: function(value, row) { formatter: function(value, row) {
var order = row.order_detail; var order = row.order_detail;
var customer = row.customer_detail; var customer = row.customer_detail;
@ -947,14 +947,14 @@ function loadSalesPriceHistoryTable(options={}) {
}, },
{ {
field: 'shipment_date', field: 'shipment_date',
title: '{% trans "Date" %}', title: '{% jstrans "Date" %}',
formatter: function(value, row) { formatter: function(value, row) {
return renderDate(row.order_detail.shipment_date); return renderDate(row.order_detail.shipment_date);
} }
}, },
{ {
field: 'sale_price', field: 'sale_price',
title: '{% trans "Sale Price" %}', title: '{% jstrans "Sale Price" %}',
formatter: function(value, row) { formatter: function(value, row) {
return formatCurrency(value, { return formatCurrency(value, {
currency: row.sale_price_currency currency: row.sale_price_currency
@ -1002,7 +1002,7 @@ function loadVariantPricingChart(options={}) {
search: false, search: false,
showColumns: false, showColumns: false,
formatNoMatches: function() { formatNoMatches: function() {
return '{% trans "No variant data available" %}'; return '{% jstrans "No variant data available" %}';
}, },
onLoadSuccess: function(data) { onLoadSuccess: function(data) {
// Construct variant pricing chart // Construct variant pricing chart
@ -1021,7 +1021,7 @@ function loadVariantPricingChart(options={}) {
labels: graphLabels, labels: graphLabels,
datasets: [ datasets: [
{ {
label: '{% trans "Minimum Price" %}', label: '{% jstrans "Minimum Price" %}',
data: minValues, data: minValues,
backgroundColor: 'rgba(200, 250, 200, 0.75)', backgroundColor: 'rgba(200, 250, 200, 0.75)',
borderColor: 'rgba(200, 250, 200)', borderColor: 'rgba(200, 250, 200)',
@ -1029,7 +1029,7 @@ function loadVariantPricingChart(options={}) {
fill: true, fill: true,
}, },
{ {
label: '{% trans "Maximum Price" %}', label: '{% jstrans "Maximum Price" %}',
data: maxValues, data: maxValues,
backgroundColor: 'rgba(250, 220, 220, 0.75)', backgroundColor: 'rgba(250, 220, 220, 0.75)',
borderColor: 'rgba(250, 220, 220)', borderColor: 'rgba(250, 220, 220)',
@ -1042,7 +1042,7 @@ function loadVariantPricingChart(options={}) {
columns: [ columns: [
{ {
field: 'part', field: 'part',
title: '{% trans "Variant Part" %}', title: '{% jstrans "Variant Part" %}',
formatter: function(value, row) { formatter: function(value, row) {
var name = shortenString(row.full_name); var name = shortenString(row.full_name);
var display = imageHoverIcon(row.thumbnail) + renderLink(name, `/part/${row.pk}/`); var display = imageHoverIcon(row.thumbnail) + renderLink(name, `/part/${row.pk}/`);
@ -1051,7 +1051,7 @@ function loadVariantPricingChart(options={}) {
}, },
{ {
field: 'pricing', field: 'pricing',
title: '{% trans "Price Range" %}', title: '{% jstrans "Price Range" %}',
formatter: function(value, row) { formatter: function(value, row) {
var min_price = row.pricing_min; var min_price = row.pricing_min;
var max_price = row.pricing_max; var max_price = row.pricing_max;

View File

@ -90,7 +90,7 @@ function purchaseOrderFields(options={}) {
supplier: { supplier: {
icon: 'fa-building', icon: 'fa-building',
secondary: { secondary: {
title: '{% trans "Add Supplier" %}', title: '{% jstrans "Add Supplier" %}',
fields: function() { fields: function() {
var fields = companyFormFields(); var fields = companyFormFields();
@ -165,24 +165,24 @@ function purchaseOrderFields(options={}) {
supplier_detail: true, supplier_detail: true,
}, },
api_url: '{% url "api-po-list" %}', api_url: '{% url "api-po-list" %}',
label: '{% trans "Purchase Order" %}', label: '{% jstrans "Purchase Order" %}',
help_text: '{% trans "Select purchase order to duplicate" %}', help_text: '{% jstrans "Select purchase order to duplicate" %}',
}; };
fields.duplicate_line_items = { fields.duplicate_line_items = {
value: true, value: true,
group: 'duplicate', group: 'duplicate',
type: 'boolean', type: 'boolean',
label: '{% trans "Duplicate Line Items" %}', label: '{% jstrans "Duplicate Line Items" %}',
help_text: '{% trans "Duplicate all line items from the selected order" %}', help_text: '{% jstrans "Duplicate all line items from the selected order" %}',
}; };
fields.duplicate_extra_lines = { fields.duplicate_extra_lines = {
value: true, value: true,
group: 'duplicate', group: 'duplicate',
type: 'boolean', type: 'boolean',
label: '{% trans "Duplicate Extra Lines" %}', label: '{% jstrans "Duplicate Extra Lines" %}',
help_text: '{% trans "Duplicate extra line items from the selected order" %}', help_text: '{% jstrans "Duplicate extra line items from the selected order" %}',
}; };
} }
@ -203,7 +203,7 @@ function editPurchaseOrder(pk, options={}) {
constructForm(`{% url "api-po-list" %}${pk}/`, { constructForm(`{% url "api-po-list" %}${pk}/`, {
fields: fields, fields: fields,
title: '{% trans "Edit Purchase Order" %}', title: '{% jstrans "Edit Purchase Order" %}',
onSuccess: function(response) { onSuccess: function(response) {
handleFormSuccess(response, options); handleFormSuccess(response, options);
} }
@ -220,7 +220,7 @@ function createPurchaseOrder(options={}) {
if (options.duplicate_order) { if (options.duplicate_order) {
groups.duplicate = { groups.duplicate = {
title: '{% trans "Duplication Options" %}', title: '{% jstrans "Duplication Options" %}',
collapsible: false, collapsible: false,
}; };
} }
@ -239,7 +239,7 @@ function createPurchaseOrder(options={}) {
location.href = `/order/purchase-order/${data.pk}/`; location.href = `/order/purchase-order/${data.pk}/`;
} }
}, },
title: options.title || '{% trans "Create Purchase Order" %}', title: options.title || '{% jstrans "Create Purchase Order" %}',
}); });
} }
@ -311,7 +311,7 @@ function poLineItemFields(options={}) {
).then(function() { ).then(function() {
// Update pack size information // Update pack size information
if (pack_quantity != 1) { if (pack_quantity != 1) {
var txt = `<span class='fas fa-info-circle icon-blue'></span> {% trans "Pack Quantity" %}: ${formatDecimal(pack_quantity)} ${units}`; var txt = `<span class='fas fa-info-circle icon-blue'></span> {% jstrans "Pack Quantity" %}: ${formatDecimal(pack_quantity)} ${units}`;
$(opts.modal).find('#hint_id_quantity').after(`<div class='form-info-message' id='info-pack-size'>${txt}</div>`); $(opts.modal).find('#hint_id_quantity').after(`<div class='form-info-message' id='info-pack-size'>${txt}</div>`);
} }
}).then(function() { }).then(function() {
@ -349,7 +349,7 @@ function poLineItemFields(options={}) {
}, },
secondary: { secondary: {
method: 'POST', method: 'POST',
title: '{% trans "Add Supplier Part" %}', title: '{% jstrans "Add Supplier Part" %}',
fields: function(data) { fields: function(data) {
var fields = supplierPartFields({ var fields = supplierPartFields({
part: data.part, part: data.part,
@ -430,7 +430,7 @@ function createPurchaseOrderLineItem(order, options={}) {
constructForm('{% url "api-po-line-list" %}', { constructForm('{% url "api-po-line-list" %}', {
fields: fields, fields: fields,
method: 'POST', method: 'POST',
title: '{% trans "Add Line Item" %}', title: '{% jstrans "Add Line Item" %}',
onSuccess: function(response) { onSuccess: function(response) {
handleFormSuccess(response, options); handleFormSuccess(response, options);
} }
@ -447,7 +447,7 @@ function completePurchaseOrder(order_id, options={}) {
`/api/order/po/${order_id}/complete/`, `/api/order/po/${order_id}/complete/`,
{ {
method: 'POST', method: 'POST',
title: '{% trans "Complete Purchase Order" %}', title: '{% jstrans "Complete Purchase Order" %}',
confirm: true, confirm: true,
fieldsFunction: function(opts) { fieldsFunction: function(opts) {
var fields = { var fields = {
@ -464,19 +464,19 @@ function completePurchaseOrder(order_id, options={}) {
var html = ` var html = `
<div class='alert alert-block alert-info'> <div class='alert alert-block alert-info'>
{% trans "Mark this order as complete?" %} {% jstrans "Mark this order as complete?" %}
</div>`; </div>`;
if (opts.context.is_complete) { if (opts.context.is_complete) {
html += ` html += `
<div class='alert alert-block alert-success'> <div class='alert alert-block alert-success'>
{% trans "All line items have been received" %} {% jstrans "All line items have been received" %}
</div>`; </div>`;
} else { } else {
html += ` html += `
<div class='alert alert-block alert-warning'> <div class='alert alert-block alert-warning'>
{% trans 'This order has line items which have not been marked as received.' %}</br> {% jstrans 'This order has line items which have not been marked as received.' %}</br>
{% trans 'Completing this order means that the order and line items will no longer be editable.' %} {% jstrans 'Completing this order means that the order and line items will no longer be editable.' %}
</div>`; </div>`;
} }
@ -499,18 +499,18 @@ function cancelPurchaseOrder(order_id, options={}) {
`/api/order/po/${order_id}/cancel/`, `/api/order/po/${order_id}/cancel/`,
{ {
method: 'POST', method: 'POST',
title: '{% trans "Cancel Purchase Order" %}', title: '{% jstrans "Cancel Purchase Order" %}',
confirm: true, confirm: true,
preFormContent: function(opts) { preFormContent: function(opts) {
var html = ` var html = `
<div class='alert alert-info alert-block'> <div class='alert alert-info alert-block'>
{% trans "Are you sure you wish to cancel this purchase order?" %} {% jstrans "Are you sure you wish to cancel this purchase order?" %}
</div>`; </div>`;
if (!opts.context.can_cancel) { if (!opts.context.can_cancel) {
html += ` html += `
<div class='alert alert-danger alert-block'> <div class='alert alert-danger alert-block'>
{% trans "This purchase order can not be cancelled" %} {% jstrans "This purchase order can not be cancelled" %}
</div>`; </div>`;
} }
@ -531,12 +531,12 @@ function issuePurchaseOrder(order_id, options={}) {
let html = ` let html = `
<div class='alert alert-block alert-warning'> <div class='alert alert-block alert-warning'>
{% trans 'After placing this order, line items will no longer be editable.' %} {% jstrans 'After placing this order, line items will no longer be editable.' %}
</div>`; </div>`;
constructForm(`{% url "api-po-list" %}${order_id}/issue/`, { constructForm(`{% url "api-po-list" %}${order_id}/issue/`, {
method: 'POST', method: 'POST',
title: '{% trans "Issue Purchase Order" %}', title: '{% jstrans "Issue Purchase Order" %}',
confirm: true, confirm: true,
preFormContent: html, preFormContent: html,
onSuccess: function(response) { onSuccess: function(response) {
@ -627,8 +627,8 @@ function orderParts(parts_list, options={}) {
if (parts.length == 0) { if (parts.length == 0) {
showAlertDialog( showAlertDialog(
'{% trans "Select Parts" %}', '{% jstrans "Select Parts" %}',
'{% trans "At least one purchaseable part must be selected" %}', '{% jstrans "At least one purchaseable part must be selected" %}',
); );
return; return;
} }
@ -653,7 +653,7 @@ function orderParts(parts_list, options={}) {
type: 'decimal', type: 'decimal',
min_value: 0, min_value: 0,
value: quantity, value: quantity,
title: '{% trans "Quantity to order" %}', title: '{% jstrans "Quantity to order" %}',
required: true, required: true,
}, },
{ {
@ -662,7 +662,7 @@ function orderParts(parts_list, options={}) {
); );
var supplier_part_prefix = ` var supplier_part_prefix = `
<button type='button' class='input-group-text button-row-new-sp' pk='${pk}' title='{% trans "New supplier part" %}'> <button type='button' class='input-group-text button-row-new-sp' pk='${pk}' title='{% jstrans "New supplier part" %}'>
<span class='fas fa-plus-circle icon-green'></span> <span class='fas fa-plus-circle icon-green'></span>
</button> </button>
`; `;
@ -680,7 +680,7 @@ function orderParts(parts_list, options={}) {
); );
var purchase_order_prefix = ` var purchase_order_prefix = `
<button type='button' class='input-group-text button-row-new-po' pk='${pk}' title='{% trans "New purchase order" %}'> <button type='button' class='input-group-text button-row-new-po' pk='${pk}' title='{% jstrans "New purchase order" %}'>
<span class='fas fa-plus-circle icon-green'></span> <span class='fas fa-plus-circle icon-green'></span>
</button> </button>
`; `;
@ -703,7 +703,7 @@ function orderParts(parts_list, options={}) {
buttons += makeRemoveButton( buttons += makeRemoveButton(
'button-row-remove', 'button-row-remove',
pk, pk,
'{% trans "Remove row" %}', '{% jstrans "Remove row" %}',
); );
} }
@ -712,7 +712,7 @@ function orderParts(parts_list, options={}) {
'fa-shopping-cart icon-blue', 'fa-shopping-cart icon-blue',
'button-row-add', 'button-row-add',
pk, pk,
'{% trans "Add to purchase order" %}', '{% jstrans "Add to purchase order" %}',
); );
buttons = wrapButtons(buttons); buttons = wrapButtons(buttons);
@ -757,10 +757,10 @@ function orderParts(parts_list, options={}) {
<table class='table table-striped table-condensed' id='order-parts-table'> <table class='table table-striped table-condensed' id='order-parts-table'>
<thead> <thead>
<tr> <tr>
<th>{% trans "Part" %}</th> <th>{% jstrans "Part" %}</th>
<th style='min-width: 300px;'>{% trans "Supplier Part" %}</th> <th style='min-width: 300px;'>{% jstrans "Supplier Part" %}</th>
<th style='min-width: 300px;'>{% trans "Purchase Order" %}</th> <th style='min-width: 300px;'>{% jstrans "Purchase Order" %}</th>
<th style='min-width: 50px;'>{% trans "Quantity" %}</th> <th style='min-width: 50px;'>{% jstrans "Quantity" %}</th>
<th><!-- Actions --></th> <th><!-- Actions --></th>
</tr> </tr>
</thead> </thead>
@ -800,9 +800,9 @@ function orderParts(parts_list, options={}) {
constructFormBody({}, { constructFormBody({}, {
preFormContent: html, preFormContent: html,
title: '{% trans "Order Parts" %}', title: '{% jstrans "Order Parts" %}',
hideSubmitButton: true, hideSubmitButton: true,
closeText: '{% trans "Close" %}', closeText: '{% jstrans "Close" %}',
afterRender: function(fields, opts) { afterRender: function(fields, opts) {
parts.forEach(function(part) { parts.forEach(function(part) {
@ -842,7 +842,7 @@ function orderParts(parts_list, options={}) {
} }
).then(function() { ).then(function() {
if (pack_quantity != 1) { if (pack_quantity != 1) {
var txt = `<span class='fas fa-info-circle icon-blue'></span> {% trans "Pack Quantity" %}: ${pack_quantity} ${units}`; var txt = `<span class='fas fa-info-circle icon-blue'></span> {% jstrans "Pack Quantity" %}: ${pack_quantity} ${units}`;
$(opts.modal).find(`#id_quantity_${pk}`).after(`<div class='form-info-message' id='info-pack-size-${pk}'>${txt}</div>`); $(opts.modal).find(`#id_quantity_${pk}`).after(`<div class='form-info-message' id='info-pack-size-${pk}'>${txt}</div>`);
} }
}); });
@ -860,7 +860,7 @@ function orderParts(parts_list, options={}) {
filters: supplier_part_filters, filters: supplier_part_filters,
onEdit: onSupplierPartChanged, onEdit: onSupplierPartChanged,
noResults: function(query) { noResults: function(query) {
return '{% trans "No matching supplier parts" %}'; return '{% jstrans "No matching supplier parts" %}';
} }
}; };
@ -879,7 +879,7 @@ function orderParts(parts_list, options={}) {
value: options.order, value: options.order,
filters: order_filters, filters: order_filters,
noResults: function(query) { noResults: function(query) {
return '{% trans "No matching purchase orders" %}'; return '{% jstrans "No matching purchase orders" %}';
} }
}, null, opts); }, null, opts);
@ -1066,8 +1066,8 @@ function receivePurchaseOrderItems(order_id, line_items, options={}) {
if (line_items.length == 0) { if (line_items.length == 0) {
showAlertDialog( showAlertDialog(
'{% trans "Select Line Items" %}', '{% jstrans "Select Line Items" %}',
'{% trans "At least one line item must be selected" %}', '{% jstrans "At least one line item must be selected" %}',
); );
return; return;
} }
@ -1096,8 +1096,8 @@ function receivePurchaseOrderItems(order_id, line_items, options={}) {
if (native_pack_quantity != 1) { if (native_pack_quantity != 1) {
pack_size_div = ` pack_size_div = `
<div class='alert alert-small alert-block alert-info'> <div class='alert alert-small alert-block alert-info'>
{% trans "Pack Quantity" %}: ${pack_quantity}<br> {% jstrans "Pack Quantity" %}: ${pack_quantity}<br>
{% trans "Received Quantity" %}: <span class='pack_received_quantity' id='items_received_quantity_${pk}'>${received}</span> ${units} {% jstrans "Received Quantity" %}: <span class='pack_received_quantity' id='items_received_quantity_${pk}'>${received}</span> ${units}
</div>`; </div>`;
} }
@ -1108,7 +1108,7 @@ function receivePurchaseOrderItems(order_id, line_items, options={}) {
type: 'decimal', type: 'decimal',
min_value: 0, min_value: 0,
value: quantity, value: quantity,
title: '{% trans "Quantity to receive" %}', title: '{% jstrans "Quantity to receive" %}',
required: true, required: true,
}, },
{ {
@ -1122,8 +1122,8 @@ function receivePurchaseOrderItems(order_id, line_items, options={}) {
{ {
type: 'string', type: 'string',
required: false, required: false,
label: '{% trans "Batch Code" %}', label: '{% jstrans "Batch Code" %}',
help_text: '{% trans "Enter batch code for incoming stock items" %}', help_text: '{% jstrans "Enter batch code for incoming stock items" %}',
icon: 'fa-layer-group', icon: 'fa-layer-group',
}, },
{ {
@ -1146,8 +1146,8 @@ function receivePurchaseOrderItems(order_id, line_items, options={}) {
{ {
type: 'string', type: 'string',
required: false, required: false,
label: '{% trans "Serial Numbers" %}', label: '{% jstrans "Serial Numbers" %}',
help_text: '{% trans "Enter serial numbers for incoming stock items" %}', help_text: '{% jstrans "Enter serial numbers for incoming stock items" %}',
icon: 'fa-hashtag', icon: 'fa-hashtag',
}, },
{ {
@ -1171,7 +1171,7 @@ function receivePurchaseOrderItems(order_id, line_items, options={}) {
`items_location_${pk}`, `items_location_${pk}`,
{ {
type: 'related field', type: 'related field',
label: '{% trans "Location" %}', label: '{% jstrans "Location" %}',
required: false, required: false,
icon: 'fa-sitemap', icon: 'fa-sitemap',
}, },
@ -1184,7 +1184,7 @@ function receivePurchaseOrderItems(order_id, line_items, options={}) {
`items_status_${pk}`, `items_status_${pk}`,
{ {
type: 'choice', type: 'choice',
label: '{% trans "Stock Status" %}', label: '{% jstrans "Stock Status" %}',
required: true, required: true,
choices: choices, choices: choices,
value: 10, // OK value: 10, // OK
@ -1198,11 +1198,11 @@ function receivePurchaseOrderItems(order_id, line_items, options={}) {
let buttons = ''; let buttons = '';
if (global_settings.BARCODE_ENABLE) { if (global_settings.BARCODE_ENABLE) {
buttons += makeIconButton('fa-qrcode', 'button-row-add-barcode', pk, '{% trans "Add barcode" %}'); buttons += makeIconButton('fa-qrcode', 'button-row-add-barcode', pk, '{% jstrans "Add barcode" %}');
buttons += makeIconButton('fa-unlink icon-red', 'button-row-remove-barcode', pk, '{% trans "Remove barcode" %}', {hidden: true}); buttons += makeIconButton('fa-unlink icon-red', 'button-row-remove-barcode', pk, '{% jstrans "Remove barcode" %}', {hidden: true});
} }
buttons += makeIconButton('fa-sitemap', 'button-row-add-location', pk, '{% trans "Specify location" %}', { buttons += makeIconButton('fa-sitemap', 'button-row-add-location', pk, '{% jstrans "Specify location" %}', {
collapseTarget: `row-destination-${pk}` collapseTarget: `row-destination-${pk}`
}); });
@ -1210,7 +1210,7 @@ function receivePurchaseOrderItems(order_id, line_items, options={}) {
'fa-layer-group', 'fa-layer-group',
'button-row-add-batch', 'button-row-add-batch',
pk, pk,
'{% trans "Add batch code" %}', '{% jstrans "Add batch code" %}',
{ {
collapseTarget: `row-batch-${pk}` collapseTarget: `row-batch-${pk}`
} }
@ -1221,7 +1221,7 @@ function receivePurchaseOrderItems(order_id, line_items, options={}) {
'fa-hashtag', 'fa-hashtag',
'button-row-add-serials', 'button-row-add-serials',
pk, pk,
'{% trans "Add serial numbers" %}', '{% jstrans "Add serial numbers" %}',
{ {
collapseTarget: `row-serials-${pk}`, collapseTarget: `row-serials-${pk}`,
} }
@ -1229,7 +1229,7 @@ function receivePurchaseOrderItems(order_id, line_items, options={}) {
} }
if (line_items.length > 1) { if (line_items.length > 1) {
buttons += makeRemoveButton('button-row-remove', pk, '{% trans "Remove row" %}'); buttons += makeRemoveButton('button-row-remove', pk, '{% jstrans "Remove row" %}');
} }
buttons = wrapButtons(buttons); buttons = wrapButtons(buttons);
@ -1261,19 +1261,19 @@ function receivePurchaseOrderItems(order_id, line_items, options={}) {
<!-- Hidden rows for extra data entry --> <!-- Hidden rows for extra data entry -->
<tr id='row-destination-${pk}' class='collapse'> <tr id='row-destination-${pk}' class='collapse'>
<td colspan='2'></td> <td colspan='2'></td>
<th>{% trans "Location" %}</th> <th>{% jstrans "Location" %}</th>
<td colspan='2'>${destination_input}</td> <td colspan='2'>${destination_input}</td>
<td></td> <td></td>
</tr> </tr>
<tr id='row-batch-${pk}' class='collapse'> <tr id='row-batch-${pk}' class='collapse'>
<td colspan='2'></td> <td colspan='2'></td>
<th>{% trans "Batch" %}</th> <th>{% jstrans "Batch" %}</th>
<td colspan='2'>${batch_input}</td> <td colspan='2'>${batch_input}</td>
<td></td> <td></td>
</tr> </tr>
<tr id='row-serials-${pk}' class='collapse'> <tr id='row-serials-${pk}' class='collapse'>
<td colspan='2'></td> <td colspan='2'></td>
<th>{% trans "Serials" %}</th> <th>{% jstrans "Serials" %}</th>
<td colspan=2'>${sn_input}</td> <td colspan=2'>${sn_input}</td>
<td></td> <td></td>
</tr> </tr>
@ -1297,11 +1297,11 @@ function receivePurchaseOrderItems(order_id, line_items, options={}) {
<table class='table table-condensed' id='order-receive-table'> <table class='table table-condensed' id='order-receive-table'>
<thead> <thead>
<tr> <tr>
<th>{% trans "Part" %}</th> <th>{% jstrans "Part" %}</th>
<th>{% trans "Order Code" %}</th> <th>{% jstrans "Order Code" %}</th>
<th>{% trans "Received" %}</th> <th>{% jstrans "Received" %}</th>
<th style='min-width: 50px;'>{% trans "Quantity to Receive" %}</th> <th style='min-width: 50px;'>{% jstrans "Quantity to Receive" %}</th>
<th style='min-width: 150px;'>{% trans "Status" %}</th> <th style='min-width: 150px;'>{% jstrans "Status" %}</th>
<th></th> <th></th>
</tr> </tr>
</thead> </thead>
@ -1326,8 +1326,8 @@ function receivePurchaseOrderItems(order_id, line_items, options={}) {
}, },
preFormContent: html, preFormContent: html,
confirm: true, confirm: true,
confirmMessage: '{% trans "Confirm receipt of items" %}', confirmMessage: '{% jstrans "Confirm receipt of items" %}',
title: '{% trans "Receive Purchase Order Items" %}', title: '{% jstrans "Receive Purchase Order Items" %}',
afterRender: function(fields, opts) { afterRender: function(fields, opts) {
// Run initialization routines for each line in the form // Run initialization routines for each line in the form
@ -1395,11 +1395,11 @@ function receivePurchaseOrderItems(order_id, line_items, options={}) {
let pk = btn.attr('pk'); let pk = btn.attr('pk');
// Scan to see if the barcode matches an existing StockItem // Scan to see if the barcode matches an existing StockItem
barcodeDialog('{% trans "Scan Item Barcode" %}', { barcodeDialog('{% jstrans "Scan Item Barcode" %}', {
details: '{% trans "Scan barcode on incoming item (must not match any existing stock items)" %}', details: '{% jstrans "Scan barcode on incoming item (must not match any existing stock items)" %}',
onScan: function(response, barcode_options) { onScan: function(response, barcode_options) {
// A 'success' result means that the barcode matches something existing in the database // A 'success' result means that the barcode matches something existing in the database
showBarcodeMessage(barcode_options.modal, '{% trans "Barcode matches existing item" %}'); showBarcodeMessage(barcode_options.modal, '{% jstrans "Barcode matches existing item" %}');
}, },
onError400: function(response, barcode_options) { onError400: function(response, barcode_options) {
if (response.barcode_data && response.barcode_hash) { if (response.barcode_data && response.barcode_hash) {
@ -1410,7 +1410,7 @@ function receivePurchaseOrderItems(order_id, line_items, options={}) {
$(opts.modal).find(`#button-row-remove-barcode-${pk}`).show(); $(opts.modal).find(`#button-row-remove-barcode-${pk}`).show();
updateFieldValue(`items_barcode_${pk}`, response.barcode_data, {}, opts); updateFieldValue(`items_barcode_${pk}`, response.barcode_data, {}, opts);
} else { } else {
showBarcodeMessage(barcode_options.modal, '{% trans "Invalid barcode data" %}'); showBarcodeMessage(barcode_options.modal, '{% jstrans "Invalid barcode data" %}');
} }
} }
}); });
@ -1645,7 +1645,7 @@ function loadPurchaseOrderTable(table, options) {
showCustomView: display_mode == 'calendar', showCustomView: display_mode == 'calendar',
search: display_mode != 'calendar', search: display_mode != 'calendar',
formatNoMatches: function() { formatNoMatches: function() {
return '{% trans "No purchase orders found" %}'; return '{% jstrans "No purchase orders found" %}';
}, },
buttons: constructOrderTableButtons({ buttons: constructOrderTableButtons({
prefix: 'purchaseorder', prefix: 'purchaseorder',
@ -1664,7 +1664,7 @@ function loadPurchaseOrderTable(table, options) {
}, },
{ {
field: 'reference', field: 'reference',
title: '{% trans "Purchase Order" %}', title: '{% jstrans "Purchase Order" %}',
sortable: true, sortable: true,
switchable: false, switchable: false,
formatter: function(value, row) { formatter: function(value, row) {
@ -1672,7 +1672,7 @@ function loadPurchaseOrderTable(table, options) {
var html = renderLink(value, `/order/purchase-order/${row.pk}/`); var html = renderLink(value, `/order/purchase-order/${row.pk}/`);
if (row.overdue) { if (row.overdue) {
html += makeIconBadge('fa-calendar-times icon-red', '{% trans "Order is overdue" %}'); html += makeIconBadge('fa-calendar-times icon-red', '{% jstrans "Order is overdue" %}');
} }
return html; return html;
@ -1680,7 +1680,7 @@ function loadPurchaseOrderTable(table, options) {
}, },
{ {
field: 'supplier_detail', field: 'supplier_detail',
title: '{% trans "Supplier" %}', title: '{% jstrans "Supplier" %}',
sortable: true, sortable: true,
sortName: 'supplier__name', sortName: 'supplier__name',
formatter: function(value, row) { formatter: function(value, row) {
@ -1693,15 +1693,15 @@ function loadPurchaseOrderTable(table, options) {
}, },
{ {
field: 'supplier_reference', field: 'supplier_reference',
title: '{% trans "Supplier Reference" %}', title: '{% jstrans "Supplier Reference" %}',
}, },
{ {
field: 'description', field: 'description',
title: '{% trans "Description" %}', title: '{% jstrans "Description" %}',
}, },
{ {
field: 'project_code', field: 'project_code',
title: '{% trans "Project Code" %}', title: '{% jstrans "Project Code" %}',
switchable: global_settings.PROJECT_CODES_ENABLED, switchable: global_settings.PROJECT_CODES_ENABLED,
visible: global_settings.PROJECT_CODES_ENABLED, visible: global_settings.PROJECT_CODES_ENABLED,
sortable: true, sortable: true,
@ -1713,7 +1713,7 @@ function loadPurchaseOrderTable(table, options) {
}, },
{ {
field: 'status', field: 'status',
title: '{% trans "Status" %}', title: '{% jstrans "Status" %}',
switchable: true, switchable: true,
sortable: true, sortable: true,
formatter: function(value, row) { formatter: function(value, row) {
@ -1722,7 +1722,7 @@ function loadPurchaseOrderTable(table, options) {
}, },
{ {
field: 'creation_date', field: 'creation_date',
title: '{% trans "Date" %}', title: '{% jstrans "Date" %}',
sortable: true, sortable: true,
formatter: function(value) { formatter: function(value) {
return renderDate(value); return renderDate(value);
@ -1730,7 +1730,7 @@ function loadPurchaseOrderTable(table, options) {
}, },
{ {
field: 'target_date', field: 'target_date',
title: '{% trans "Target Date" %}', title: '{% jstrans "Target Date" %}',
sortable: true, sortable: true,
formatter: function(value) { formatter: function(value) {
return renderDate(value); return renderDate(value);
@ -1738,12 +1738,12 @@ function loadPurchaseOrderTable(table, options) {
}, },
{ {
field: 'line_items', field: 'line_items',
title: '{% trans "Items" %}', title: '{% jstrans "Items" %}',
sortable: true, sortable: true,
}, },
{ {
field: 'total_price', field: 'total_price',
title: '{% trans "Total Cost" %}', title: '{% jstrans "Total Cost" %}',
switchable: true, switchable: true,
sortable: true, sortable: true,
formatter: function(value, row) { formatter: function(value, row) {
@ -1754,7 +1754,7 @@ function loadPurchaseOrderTable(table, options) {
}, },
{ {
field: 'responsible', field: 'responsible',
title: '{% trans "Responsible" %}', title: '{% jstrans "Responsible" %}',
switchable: true, switchable: true,
sortable: true, sortable: true,
formatter: function(value, row) { formatter: function(value, row) {
@ -1834,16 +1834,16 @@ function deletePurchaseOrderLineItems(items, options={}) {
var html = ` var html = `
<div class='alert alert-block alert-danger'> <div class='alert alert-block alert-danger'>
{% trans "All selected Line items will be deleted" %} {% jstrans "All selected Line items will be deleted" %}
</div> </div>
<table class='table table-striped table-condensed'> <table class='table table-striped table-condensed'>
<tr> <tr>
<th>{% trans "Part" %}</th> <th>{% jstrans "Part" %}</th>
<th>{% trans "Description" %}</th> <th>{% jstrans "Description" %}</th>
<th>{% trans "SKU" %}</th> <th>{% jstrans "SKU" %}</th>
<th>{% trans "MPN" %}</th> <th>{% jstrans "MPN" %}</th>
<th>{% trans "Quantity" %}</th> <th>{% jstrans "Quantity" %}</th>
</tr> </tr>
${rows} ${rows}
</table> </table>
@ -1852,7 +1852,7 @@ function deletePurchaseOrderLineItems(items, options={}) {
constructForm('{% url "api-po-line-list" %}', { constructForm('{% url "api-po-line-list" %}', {
method: 'DELETE', method: 'DELETE',
multi_delete: true, multi_delete: true,
title: '{% trans "Delete selected Line items?" %}', title: '{% jstrans "Delete selected Line items?" %}',
form_data: { form_data: {
items: ids, items: ids,
}, },
@ -1907,7 +1907,7 @@ function loadPurchaseOrderLineItemTable(table, options={}) {
method: 'POST', method: 'POST',
fields: fields, fields: fields,
data: data, data: data,
title: '{% trans "Duplicate Line Item" %}', title: '{% jstrans "Duplicate Line Item" %}',
refreshTable: table, refreshTable: table,
}); });
} }
@ -1922,7 +1922,7 @@ function loadPurchaseOrderLineItemTable(table, options={}) {
constructForm(`{% url "api-po-line-list" %}${pk}/`, { constructForm(`{% url "api-po-line-list" %}${pk}/`, {
fields: fields, fields: fields,
title: '{% trans "Edit Line Item" %}', title: '{% jstrans "Edit Line Item" %}',
refreshTable: table, refreshTable: table,
}); });
}); });
@ -1933,7 +1933,7 @@ function loadPurchaseOrderLineItemTable(table, options={}) {
constructForm(`{% url "api-po-line-list" %}${pk}/`, { constructForm(`{% url "api-po-line-list" %}${pk}/`, {
method: 'DELETE', method: 'DELETE',
title: '{% trans "Delete Line Item" %}', title: '{% jstrans "Delete Line Item" %}',
refreshTable: table, refreshTable: table,
}); });
}); });
@ -1981,7 +1981,7 @@ function loadPurchaseOrderLineItemTable(table, options={}) {
name: 'purchaseorderlines', name: 'purchaseorderlines',
sidePagination: 'server', sidePagination: 'server',
formatNoMatches: function() { formatNoMatches: function() {
return '{% trans "No line items found" %}'; return '{% jstrans "No line items found" %}';
}, },
queryParams: filters, queryParams: filters,
original: options.params, original: options.params,
@ -1998,7 +1998,7 @@ function loadPurchaseOrderLineItemTable(table, options={}) {
field: 'part', field: 'part',
sortable: true, sortable: true,
sortName: 'part_name', sortName: 'part_name',
title: '{% trans "Part" %}', title: '{% jstrans "Part" %}',
switchable: false, switchable: false,
formatter: function(value, row, index, field) { formatter: function(value, row, index, field) {
if (row.part_detail) { if (row.part_detail) {
@ -2008,18 +2008,18 @@ function loadPurchaseOrderLineItemTable(table, options={}) {
} }
}, },
footerFormatter: function() { footerFormatter: function() {
return '{% trans "Total" %}'; return '{% jstrans "Total" %}';
} }
}, },
{ {
field: 'part_detail.description', field: 'part_detail.description',
title: '{% trans "Description" %}', title: '{% jstrans "Description" %}',
}, },
{ {
sortable: true, sortable: true,
sortName: 'SKU', sortName: 'SKU',
field: 'supplier_part_detail.SKU', field: 'supplier_part_detail.SKU',
title: '{% trans "SKU" %}', title: '{% jstrans "SKU" %}',
formatter: function(value, row, index, field) { formatter: function(value, row, index, field) {
if (value) { if (value) {
return renderClipboard(renderLink(value, `/supplier-part/${row.part}/`)); return renderClipboard(renderLink(value, `/supplier-part/${row.part}/`));
@ -2031,7 +2031,7 @@ function loadPurchaseOrderLineItemTable(table, options={}) {
{ {
sortable: false, sortable: false,
field: 'supplier_part_detail.link', field: 'supplier_part_detail.link',
title: '{% trans "Link" %}', title: '{% jstrans "Link" %}',
formatter: function(value, row, index, field) { formatter: function(value, row, index, field) {
if (value) { if (value) {
return renderLink(value, value, {external: true}); return renderLink(value, value, {external: true});
@ -2044,7 +2044,7 @@ function loadPurchaseOrderLineItemTable(table, options={}) {
sortable: true, sortable: true,
sortName: 'MPN', sortName: 'MPN',
field: 'supplier_part_detail.manufacturer_part_detail.MPN', field: 'supplier_part_detail.manufacturer_part_detail.MPN',
title: '{% trans "MPN" %}', title: '{% jstrans "MPN" %}',
formatter: function(value, row, index, field) { formatter: function(value, row, index, field) {
if (row.supplier_part_detail && row.supplier_part_detail.manufacturer_part) { if (row.supplier_part_detail && row.supplier_part_detail.manufacturer_part) {
return renderClipboard(renderLink(value, `/manufacturer-part/${row.supplier_part_detail.manufacturer_part}/`)); return renderClipboard(renderLink(value, `/manufacturer-part/${row.supplier_part_detail.manufacturer_part}/`));
@ -2056,13 +2056,13 @@ function loadPurchaseOrderLineItemTable(table, options={}) {
{ {
sortable: true, sortable: true,
field: 'reference', field: 'reference',
title: '{% trans "Reference" %}', title: '{% jstrans "Reference" %}',
}, },
{ {
sortable: true, sortable: true,
switchable: false, switchable: false,
field: 'quantity', field: 'quantity',
title: '{% trans "Quantity" %}', title: '{% jstrans "Quantity" %}',
formatter: function(value, row) { formatter: function(value, row) {
let units = ''; let units = '';
@ -2075,7 +2075,7 @@ function loadPurchaseOrderLineItemTable(table, options={}) {
if (row.supplier_part_detail && row.supplier_part_detail.pack_quantity_native != 1.0) { if (row.supplier_part_detail && row.supplier_part_detail.pack_quantity_native != 1.0) {
let pack_quantity = row.supplier_part_detail.pack_quantity; let pack_quantity = row.supplier_part_detail.pack_quantity;
let total = value * row.supplier_part_detail.pack_quantity_native; let total = value * row.supplier_part_detail.pack_quantity_native;
data += `<span class='fas fa-info-circle icon-blue float-right' title='{% trans "Pack Quantity" %}: ${pack_quantity} - {% trans "Total Quantity" %}: ${total}${units}'></span>`; data += `<span class='fas fa-info-circle icon-blue float-right' title='{% jstrans "Pack Quantity" %}: ${pack_quantity} - {% jstrans "Total Quantity" %}: ${total}${units}'></span>`;
} }
return data; return data;
@ -2092,7 +2092,7 @@ function loadPurchaseOrderLineItemTable(table, options={}) {
sortable: false, sortable: false,
switchable: true, switchable: true,
field: 'supplier_part_detail.pack_quantity', field: 'supplier_part_detail.pack_quantity',
title: '{% trans "Pack Quantity" %}', title: '{% jstrans "Pack Quantity" %}',
formatter: function(value, row) { formatter: function(value, row) {
var units = row.part_detail.units; var units = row.part_detail.units;
@ -2106,7 +2106,7 @@ function loadPurchaseOrderLineItemTable(table, options={}) {
{ {
sortable: true, sortable: true,
field: 'purchase_price', field: 'purchase_price',
title: '{% trans "Unit Price" %}', title: '{% jstrans "Unit Price" %}',
formatter: function(value, row) { formatter: function(value, row) {
return formatCurrency(row.purchase_price, { return formatCurrency(row.purchase_price, {
currency: row.purchase_price_currency, currency: row.purchase_price_currency,
@ -2116,7 +2116,7 @@ function loadPurchaseOrderLineItemTable(table, options={}) {
{ {
field: 'total_price', field: 'total_price',
sortable: true, sortable: true,
title: '{% trans "Total Price" %}', title: '{% jstrans "Total Price" %}',
formatter: function(value, row) { formatter: function(value, row) {
return formatCurrency(row.purchase_price * row.quantity, { return formatCurrency(row.purchase_price * row.quantity, {
currency: row.purchase_price_currency currency: row.purchase_price_currency
@ -2138,13 +2138,13 @@ function loadPurchaseOrderLineItemTable(table, options={}) {
sortable: true, sortable: true,
field: 'target_date', field: 'target_date',
switchable: true, switchable: true,
title: '{% trans "Target Date" %}', title: '{% jstrans "Target Date" %}',
formatter: function(value, row) { formatter: function(value, row) {
if (row.target_date) { if (row.target_date) {
var html = renderDate(row.target_date); var html = renderDate(row.target_date);
if (row.overdue) { if (row.overdue) {
html += makeIconBadge('fa-calendar-times icon-red', '{% trans "This line item is overdue" %}'); html += makeIconBadge('fa-calendar-times icon-red', '{% jstrans "This line item is overdue" %}');
} }
return html; return html;
@ -2160,7 +2160,7 @@ function loadPurchaseOrderLineItemTable(table, options={}) {
sortable: false, sortable: false,
field: 'received', field: 'received',
switchable: false, switchable: false,
title: '{% trans "Received" %}', title: '{% jstrans "Received" %}',
formatter: function(value, row, index, field) { formatter: function(value, row, index, field) {
return makeProgressBar(row.received, row.quantity, { return makeProgressBar(row.received, row.quantity, {
id: `order-line-progress-${row.pk}`, id: `order-line-progress-${row.pk}`,
@ -2180,7 +2180,7 @@ function loadPurchaseOrderLineItemTable(table, options={}) {
}, },
{ {
field: 'destination', field: 'destination',
title: '{% trans "Destination" %}', title: '{% jstrans "Destination" %}',
formatter: function(value, row) { formatter: function(value, row) {
if (value) { if (value) {
return renderLink(row.destination_detail.pathstring, `/stock/location/${value}/`); return renderLink(row.destination_detail.pathstring, `/stock/location/${value}/`);
@ -2191,11 +2191,11 @@ function loadPurchaseOrderLineItemTable(table, options={}) {
}, },
{ {
field: 'notes', field: 'notes',
title: '{% trans "Notes" %}', title: '{% jstrans "Notes" %}',
}, },
{ {
field: 'link', field: 'link',
title: '{% trans "Link" %}', title: '{% jstrans "Link" %}',
formatter: function(value) { formatter: function(value) {
if (value) { if (value) {
return renderLink(value, value); return renderLink(value, value);
@ -2211,13 +2211,13 @@ function loadPurchaseOrderLineItemTable(table, options={}) {
let pk = row.pk; let pk = row.pk;
if (options.allow_receive && row.received < row.quantity) { if (options.allow_receive && row.received < row.quantity) {
buttons += makeIconButton('fa-sign-in-alt icon-green', 'button-line-receive', pk, '{% trans "Receive line item" %}'); buttons += makeIconButton('fa-sign-in-alt icon-green', 'button-line-receive', pk, '{% jstrans "Receive line item" %}');
} }
if (options.allow_edit) { if (options.allow_edit) {
buttons += makeCopyButton('button-line-duplicate', pk, '{% trans "Duplicate line item" %}'); buttons += makeCopyButton('button-line-duplicate', pk, '{% jstrans "Duplicate line item" %}');
buttons += makeEditButton('button-line-edit', pk, '{% trans "Edit line item" %}'); buttons += makeEditButton('button-line-edit', pk, '{% jstrans "Edit line item" %}');
buttons += makeDeleteButton('button-line-delete', pk, '{% trans "Delete line item" %}'); buttons += makeDeleteButton('button-line-delete', pk, '{% jstrans "Delete line item" %}');
} }
return wrapButtons(buttons); return wrapButtons(buttons);

View File

@ -60,7 +60,7 @@ function selectReport(reports, items, options={}) {
html += ` html += `
<div class='alert alert-block alert-info'> <div class='alert alert-block alert-info'>
${items.length} {% trans "items selected" %} ${items.length} {% jstrans "items selected" %}
</div>`; </div>`;
} }
@ -68,7 +68,7 @@ function selectReport(reports, items, options={}) {
<form method='post' action='' class='js-modal-form' enctype='multipart/form-data'> <form method='post' action='' class='js-modal-form' enctype='multipart/form-data'>
<div class='form-group'> <div class='form-group'>
<label class='control-label requiredField' for='id_report'> <label class='control-label requiredField' for='id_report'>
{% trans "Select Report Template" %} {% jstrans "Select Report Template" %}
</label> </label>
<div class='controls'> <div class='controls'>
<select id='id_report' class='select form-control name='report'> <select id='id_report' class='select form-control name='report'>
@ -83,7 +83,7 @@ function selectReport(reports, items, options={}) {
}); });
modalEnable(modal, true); modalEnable(modal, true);
modalSetTitle(modal, '{% trans "Select Test Report Template" %}'); modalSetTitle(modal, '{% jstrans "Select Test Report Template" %}');
modalSetContent(modal, html); modalSetContent(modal, html);
attachSelect(modal); attachSelect(modal);
@ -120,8 +120,8 @@ function printReports(options) {
if (!options.items || options.items.length == 0) { if (!options.items || options.items.length == 0) {
showAlertDialog( showAlertDialog(
'{% trans "Select Items" %}', '{% jstrans "Select Items" %}',
'{% trans "No items selected for printing" }', '{% jstrans "No items selected for printing" }',
); );
return; return;
} }
@ -137,8 +137,8 @@ function printReports(options) {
success: function(response) { success: function(response) {
if (response.length == 0) { if (response.length == 0) {
showAlertDialog( showAlertDialog(
'{% trans "No Reports Found" %}', '{% jstrans "No Reports Found" %}',
'{% trans "No report templates found which match the selected items" %}', '{% jstrans "No report templates found which match the selected items" %}',
); );
return; return;
} }

View File

@ -57,7 +57,7 @@ function returnOrderFields(options={}) {
customer: { customer: {
icon: 'fa-user-tie', icon: 'fa-user-tie',
secondary: { secondary: {
title: '{% trans "Add Customer" %}', title: '{% jstrans "Add Customer" %}',
fields: function() { fields: function() {
var fields = companyFormFields(); var fields = companyFormFields();
fields.is_customer.value = true; fields.is_customer.value = true;
@ -131,7 +131,7 @@ function createReturnOrder(options={}) {
constructForm('{% url "api-return-order-list" %}', { constructForm('{% url "api-return-order-list" %}', {
method: 'POST', method: 'POST',
fields: fields, fields: fields,
title: '{% trans "Create Return Order" %}', title: '{% jstrans "Create Return Order" %}',
onSuccess: function(data) { onSuccess: function(data) {
location.href = `/order/return-order/${data.pk}/`; location.href = `/order/return-order/${data.pk}/`;
}, },
@ -146,7 +146,7 @@ function editReturnOrder(order_id, options={}) {
constructForm(`{% url "api-return-order-list" %}${order_id}/`, { constructForm(`{% url "api-return-order-list" %}${order_id}/`, {
fields: returnOrderFields(options), fields: returnOrderFields(options),
title: '{% trans "Edit Return Order" %}', title: '{% jstrans "Edit Return Order" %}',
onSuccess: function(response) { onSuccess: function(response) {
handleFormSuccess(response, options); handleFormSuccess(response, options);
} }
@ -161,12 +161,12 @@ function issueReturnOrder(order_id, options={}) {
let html = ` let html = `
<div class='alert alert-block alert-warning'> <div class='alert alert-block alert-warning'>
{% trans 'After placing this order, line items will no longer be editable.' %} {% jstrans 'After placing this order, line items will no longer be editable.' %}
</div>`; </div>`;
constructForm(`{% url "api-return-order-list" %}${order_id}/issue/`, { constructForm(`{% url "api-return-order-list" %}${order_id}/issue/`, {
method: 'POST', method: 'POST',
title: '{% trans "Issue Return Order" %}', title: '{% jstrans "Issue Return Order" %}',
confirm: true, confirm: true,
preFormContent: html, preFormContent: html,
onSuccess: function(response) { onSuccess: function(response) {
@ -183,14 +183,14 @@ function cancelReturnOrder(order_id, options={}) {
let html = ` let html = `
<div class='alert alert-danger alert-block'> <div class='alert alert-danger alert-block'>
{% trans "Are you sure you wish to cancel this Return Order?" %} {% jstrans "Are you sure you wish to cancel this Return Order?" %}
</div>`; </div>`;
constructForm( constructForm(
`{% url "api-return-order-list" %}${order_id}/cancel/`, `{% url "api-return-order-list" %}${order_id}/cancel/`,
{ {
method: 'POST', method: 'POST',
title: '{% trans "Cancel Return Order" %}', title: '{% jstrans "Cancel Return Order" %}',
confirm: true, confirm: true,
preFormContent: html, preFormContent: html,
onSuccess: function(response) { onSuccess: function(response) {
@ -207,7 +207,7 @@ function cancelReturnOrder(order_id, options={}) {
function completeReturnOrder(order_id, options={}) { function completeReturnOrder(order_id, options={}) {
let html = ` let html = `
<div class='alert alert-block alert-warning'> <div class='alert alert-block alert-warning'>
{% trans "Mark this order as complete?" %} {% jstrans "Mark this order as complete?" %}
</div> </div>
`; `;
@ -215,7 +215,7 @@ function completeReturnOrder(order_id, options={}) {
`{% url "api-return-order-list" %}${order_id}/complete/`, `{% url "api-return-order-list" %}${order_id}/complete/`,
{ {
method: 'POST', method: 'POST',
title: '{% trans "Complete Return Order" %}', title: '{% jstrans "Complete Return Order" %}',
confirm: true, confirm: true,
preFormContent: html, preFormContent: html,
onSuccess: function(response) { onSuccess: function(response) {
@ -263,7 +263,7 @@ function loadReturnOrderTable(table, options={}) {
showCustomView: is_calendar, showCustomView: is_calendar,
disablePagination: is_calendar, disablePagination: is_calendar,
formatNoMatches: function() { formatNoMatches: function() {
return '{% trans "No return orders found" %}'; return '{% jstrans "No return orders found" %}';
}, },
onLoadSuccess: function() { onLoadSuccess: function() {
// TODO // TODO
@ -278,12 +278,12 @@ function loadReturnOrderTable(table, options={}) {
{ {
sortable: true, sortable: true,
field: 'reference', field: 'reference',
title: '{% trans "Return Order" %}', title: '{% jstrans "Return Order" %}',
formatter: function(value, row) { formatter: function(value, row) {
let html = renderLink(value, `/order/return-order/${row.pk}/`); let html = renderLink(value, `/order/return-order/${row.pk}/`);
if (row.overdue) { if (row.overdue) {
html += makeIconBadge('fa-calendar-times icon-red', '{% trans "Order is overdue" %}'); html += makeIconBadge('fa-calendar-times icon-red', '{% jstrans "Order is overdue" %}');
} }
return html; return html;
@ -293,11 +293,11 @@ function loadReturnOrderTable(table, options={}) {
sortable: true, sortable: true,
sortName: 'customer__name', sortName: 'customer__name',
field: 'customer_detail', field: 'customer_detail',
title: '{% trans "Customer" %}', title: '{% jstrans "Customer" %}',
formatter: function(value, row) { formatter: function(value, row) {
if (!row.customer_detail) { if (!row.customer_detail) {
return '{% trans "Invalid Customer" %}'; return '{% jstrans "Invalid Customer" %}';
} }
return imageHoverIcon(row.customer_detail.image) + renderLink(row.customer_detail.name, `/company/${row.customer}/sales-orders/`); return imageHoverIcon(row.customer_detail.image) + renderLink(row.customer_detail.name, `/company/${row.customer}/sales-orders/`);
@ -306,16 +306,16 @@ function loadReturnOrderTable(table, options={}) {
{ {
sortable: true, sortable: true,
field: 'customer_reference', field: 'customer_reference',
title: '{% trans "Customer Reference" %}', title: '{% jstrans "Customer Reference" %}',
}, },
{ {
sortable: false, sortable: false,
field: 'description', field: 'description',
title: '{% trans "Description" %}', title: '{% jstrans "Description" %}',
}, },
{ {
field: 'project_code', field: 'project_code',
title: '{% trans "Project Code" %}', title: '{% jstrans "Project Code" %}',
switchable: global_settings.PROJECT_CODES_ENABLED, switchable: global_settings.PROJECT_CODES_ENABLED,
visible: global_settings.PROJECT_CODES_ENABLED, visible: global_settings.PROJECT_CODES_ENABLED,
sortable: true, sortable: true,
@ -328,7 +328,7 @@ function loadReturnOrderTable(table, options={}) {
{ {
sortable: true, sortable: true,
field: 'status', field: 'status',
title: '{% trans "Status" %}', title: '{% jstrans "Status" %}',
formatter: function(value, row) { formatter: function(value, row) {
return returnOrderStatusDisplay(row.status); return returnOrderStatusDisplay(row.status);
} }
@ -336,7 +336,7 @@ function loadReturnOrderTable(table, options={}) {
{ {
sortable: true, sortable: true,
field: 'creation_date', field: 'creation_date',
title: '{% trans "Creation Date" %}', title: '{% jstrans "Creation Date" %}',
formatter: function(value) { formatter: function(value) {
return renderDate(value); return renderDate(value);
} }
@ -344,19 +344,19 @@ function loadReturnOrderTable(table, options={}) {
{ {
sortable: true, sortable: true,
field: 'target_date', field: 'target_date',
title: '{% trans "Target Date" %}', title: '{% jstrans "Target Date" %}',
formatter: function(value) { formatter: function(value) {
return renderDate(value); return renderDate(value);
} }
}, },
{ {
field: 'line_items', field: 'line_items',
title: '{% trans "Items" %}', title: '{% jstrans "Items" %}',
sortable: true, sortable: true,
}, },
{ {
field: 'responsible', field: 'responsible',
title: '{% trans "Responsible" %}', title: '{% jstrans "Responsible" %}',
switchable: true, switchable: true,
sortable: true, sortable: true,
formatter: function(value, row) { formatter: function(value, row) {
@ -378,7 +378,7 @@ function loadReturnOrderTable(table, options={}) {
{ {
// TODO: Add in the 'total cost' field // TODO: Add in the 'total cost' field
field: 'total_price', field: 'total_price',
title: '{% trans "Total Cost" %}', title: '{% jstrans "Total Cost" %}',
switchable: true, switchable: true,
sortable: true, sortable: true,
visible: false, visible: false,
@ -456,7 +456,7 @@ function createReturnOrderLineItem(options={}) {
constructForm('{% url "api-return-order-line-list" %}', { constructForm('{% url "api-return-order-line-list" %}', {
fields: fields, fields: fields,
method: 'POST', method: 'POST',
title: '{% trans "Add Line Item" %}', title: '{% jstrans "Add Line Item" %}',
onSuccess: function(response) { onSuccess: function(response) {
handleFormSuccess(response, options); handleFormSuccess(response, options);
} }
@ -473,7 +473,7 @@ function editReturnOrderLineItem(pk, options={}) {
constructForm(`{% url "api-return-order-line-list" %}${pk}/`, { constructForm(`{% url "api-return-order-line-list" %}${pk}/`, {
fields: fields, fields: fields,
title: '{% trans "Edit Line Item" %}', title: '{% jstrans "Edit Line Item" %}',
onSuccess: function(response) { onSuccess: function(response) {
handleFormSuccess(response, options); handleFormSuccess(response, options);
} }
@ -488,8 +488,8 @@ function receiveReturnOrderItems(order_id, line_items, options={}) {
if (line_items.length == 0) { if (line_items.length == 0) {
showAlertDialog( showAlertDialog(
'{% trans "Select Line Items"% }', '{% jstrans "Select Line Items"% }',
'{% trans "At least one line item must be selected" %}' '{% jstrans "At least one line item must be selected" %}'
); );
return; return;
} }
@ -503,7 +503,7 @@ function receiveReturnOrderItems(order_id, line_items, options={}) {
let buttons = ''; let buttons = '';
if (line_items.length > 1) { if (line_items.length > 1) {
buttons += makeRemoveButton('button-row-remove', pk, '{% trans "Remove row" %}'); buttons += makeRemoveButton('button-row-remove', pk, '{% jstrans "Remove row" %}');
} }
buttons = wrapButtons(buttons); buttons = wrapButtons(buttons);
@ -536,8 +536,8 @@ function receiveReturnOrderItems(order_id, line_items, options={}) {
<table class='table table-striped table-condensed' id='order-receive-table'> <table class='table table-striped table-condensed' id='order-receive-table'>
<thead> <thead>
<tr> <tr>
<th>{% trans "Part" %}</th> <th>{% jstrans "Part" %}</th>
<th>{% trans "Serial Number" %}</th> <th>{% jstrans "Serial Number" %}</th>
</tr> </tr>
</thead> </thead>
<tbody>${table_entries}</tbody> <tbody>${table_entries}</tbody>
@ -558,8 +558,8 @@ function receiveReturnOrderItems(order_id, line_items, options={}) {
} }
}, },
confirm: true, confirm: true,
confirmMessage: '{% trans "Confirm receipt of items" %}', confirmMessage: '{% jstrans "Confirm receipt of items" %}',
title: '{% trans "Receive Return Order Items" %}', title: '{% jstrans "Receive Return Order Items" %}',
afterRender: function(fields, opts) { afterRender: function(fields, opts) {
// Add callback to remove rows // Add callback to remove rows
$(opts.modal).find('.button-row-remove').click(function() { $(opts.modal).find('.button-row-remove').click(function() {
@ -666,7 +666,7 @@ function loadReturnOrderLineItemTable(options={}) {
constructForm(`{% url "api-return-order-line-list" %}${pk}/`, { constructForm(`{% url "api-return-order-line-list" %}${pk}/`, {
fields: returnOrderLineItemFields(), fields: returnOrderLineItemFields(),
title: '{% trans "Edit Line Item" %}', title: '{% jstrans "Edit Line Item" %}',
refreshTable: table, refreshTable: table,
}); });
}); });
@ -679,7 +679,7 @@ function loadReturnOrderLineItemTable(options={}) {
constructForm(`{% url "api-return-order-line-list" %}${pk}/`, { constructForm(`{% url "api-return-order-line-list" %}${pk}/`, {
method: 'DELETE', method: 'DELETE',
title: '{% trans "Delete Line Item" %}', title: '{% jstrans "Delete Line Item" %}',
refreshTable: table, refreshTable: table,
}); });
}); });
@ -690,7 +690,7 @@ function loadReturnOrderLineItemTable(options={}) {
url: '{% url "api-return-order-line-list" %}', url: '{% url "api-return-order-line-list" %}',
name: 'returnorderlineitems', name: 'returnorderlineitems',
formatNoMatches: function() { formatNoMatches: function() {
return '{% trans "No matching line items" %}'; return '{% jstrans "No matching line items" %}';
}, },
onPostBody: setupCallbacks, onPostBody: setupCallbacks,
queryParams: filters, queryParams: filters,
@ -707,7 +707,7 @@ function loadReturnOrderLineItemTable(options={}) {
field: 'part', field: 'part',
sortable: true, sortable: true,
switchable: false, switchable: false,
title: '{% trans "Part" %}', title: '{% jstrans "Part" %}',
formatter: function(value, row) { formatter: function(value, row) {
let part = row.part_detail; let part = row.part_detail;
let html = thumbnailImage(part.thumbnail) + ' '; let html = thumbnailImage(part.thumbnail) + ' ';
@ -719,18 +719,18 @@ function loadReturnOrderLineItemTable(options={}) {
field: 'item', field: 'item',
sortable: true, sortable: true,
switchable: false, switchable: false,
title: '{% trans "Item" %}', title: '{% jstrans "Item" %}',
formatter: function(value, row) { formatter: function(value, row) {
return renderLink(`{% trans "Serial Number" %}: ${row.item_detail.serial}`, `/stock/item/${row.item}/`); return renderLink(`{% jstrans "Serial Number" %}: ${row.item_detail.serial}`, `/stock/item/${row.item}/`);
} }
}, },
{ {
field: 'reference', field: 'reference',
title: '{% trans "Reference" %}', title: '{% jstrans "Reference" %}',
}, },
{ {
field: 'outcome', field: 'outcome',
title: '{% trans "Outcome" %}', title: '{% jstrans "Outcome" %}',
sortable: true, sortable: true,
formatter: function(value, row) { formatter: function(value, row) {
return returnOrderLineItemStatusDisplay(value); return returnOrderLineItemStatusDisplay(value);
@ -738,7 +738,7 @@ function loadReturnOrderLineItemTable(options={}) {
}, },
{ {
field: 'price', field: 'price',
title: '{% trans "Price" %}', title: '{% jstrans "Price" %}',
formatter: function(value, row) { formatter: function(value, row) {
return formatCurrency(row.price, { return formatCurrency(row.price, {
currency: row.price_currency, currency: row.price_currency,
@ -748,12 +748,12 @@ function loadReturnOrderLineItemTable(options={}) {
{ {
sortable: true, sortable: true,
field: 'target_date', field: 'target_date',
title: '{% trans "Target Date" %}', title: '{% jstrans "Target Date" %}',
formatter: function(value, row) { formatter: function(value, row) {
let html = renderDate(value); let html = renderDate(value);
if (row.overdue) { if (row.overdue) {
html += makeIconBadge('fa-calendar-times icon-red', '{% trans "This line item is overdue" %}'); html += makeIconBadge('fa-calendar-times icon-red', '{% jstrans "This line item is overdue" %}');
} }
return html; return html;
@ -761,7 +761,7 @@ function loadReturnOrderLineItemTable(options={}) {
}, },
{ {
field: 'received_date', field: 'received_date',
title: '{% trans "Received" %}', title: '{% jstrans "Received" %}',
sortable: true, sortable: true,
formatter: function(value) { formatter: function(value) {
if (!value) { if (!value) {
@ -773,11 +773,11 @@ function loadReturnOrderLineItemTable(options={}) {
}, },
{ {
field: 'notes', field: 'notes',
title: '{% trans "Notes" %}', title: '{% jstrans "Notes" %}',
}, },
{ {
field: 'link', field: 'link',
title: '{% trans "Link" %}', title: '{% jstrans "Link" %}',
formatter: function(value, row) { formatter: function(value, row) {
if (value) { if (value) {
return renderLink(value, value); return renderLink(value, value);
@ -795,14 +795,14 @@ function loadReturnOrderLineItemTable(options={}) {
if (options.allow_edit) { if (options.allow_edit) {
if (options.allow_receive && !row.received_date) { if (options.allow_receive && !row.received_date) {
buttons += makeIconButton('fa-sign-in-alt icon-green', 'button-line-receive', pk, '{% trans "Mark item as received" %}'); buttons += makeIconButton('fa-sign-in-alt icon-green', 'button-line-receive', pk, '{% jstrans "Mark item as received" %}');
} }
buttons += makeEditButton('button-line-edit', pk, '{% trans "Edit line item" %}'); buttons += makeEditButton('button-line-edit', pk, '{% jstrans "Edit line item" %}');
} }
if (options.allow_delete) { if (options.allow_delete) {
buttons += makeDeleteButton('button-line-delete', pk, '{% trans "Delete line item" %}'); buttons += makeDeleteButton('button-line-delete', pk, '{% jstrans "Delete line item" %}');
} }
return wrapButtons(buttons); return wrapButtons(buttons);

View File

@ -83,7 +83,7 @@ function salesOrderFields(options={}) {
customer: { customer: {
icon: 'fa-user-tie', icon: 'fa-user-tie',
secondary: { secondary: {
title: '{% trans "Add Customer" %}', title: '{% jstrans "Add Customer" %}',
fields: function() { fields: function() {
var fields = companyFormFields(); var fields = companyFormFields();
fields.is_customer.value = true; fields.is_customer.value = true;
@ -158,7 +158,7 @@ function createSalesOrder(options={}) {
constructForm('{% url "api-so-list" %}', { constructForm('{% url "api-so-list" %}', {
method: 'POST', method: 'POST',
fields: fields, fields: fields,
title: '{% trans "Create Sales Order" %}', title: '{% jstrans "Create Sales Order" %}',
onSuccess: function(data) { onSuccess: function(data) {
location.href = `/order/sales-order/${data.pk}/`; location.href = `/order/sales-order/${data.pk}/`;
}, },
@ -173,7 +173,7 @@ function editSalesOrder(order_id, options={}) {
constructForm(`{% url "api-so-list" %}${order_id}/`, { constructForm(`{% url "api-so-list" %}${order_id}/`, {
fields: salesOrderFields(options), fields: salesOrderFields(options),
title: '{% trans "Edit Sales Order" %}', title: '{% jstrans "Edit Sales Order" %}',
onSuccess: function(response) { onSuccess: function(response) {
handleFormSuccess(response, options); handleFormSuccess(response, options);
} }
@ -234,7 +234,7 @@ function createSalesOrderLineItem(options={}) {
constructForm('{% url "api-so-line-list" %}', { constructForm('{% url "api-so-line-list" %}', {
fields: fields, fields: fields,
method: 'POST', method: 'POST',
title: '{% trans "Add Line Item" %}', title: '{% jstrans "Add Line Item" %}',
onSuccess: function(response) { onSuccess: function(response) {
handleFormSuccess(response, options); handleFormSuccess(response, options);
}, },
@ -288,17 +288,17 @@ function completeSalesOrderShipment(shipment_id, options={}) {
if (!allocations || allocations.length == 0) { if (!allocations || allocations.length == 0) {
html = ` html = `
<div class='alert alert-block alert-danger'> <div class='alert alert-block alert-danger'>
{% trans "No stock items have been allocated to this shipment" %} {% jstrans "No stock items have been allocated to this shipment" %}
</div> </div>
`; `;
} else { } else {
html = ` html = `
{% trans "The following stock items will be shipped" %} {% jstrans "The following stock items will be shipped" %}
<table class='table table-striped table-condensed'> <table class='table table-striped table-condensed'>
<thead> <thead>
<tr> <tr>
<th>{% trans "Part" %}</th> <th>{% jstrans "Part" %}</th>
<th>{% trans "Stock Item" %}</th> <th>{% jstrans "Stock Item" %}</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
@ -312,9 +312,9 @@ function completeSalesOrderShipment(shipment_id, options={}) {
var stock = ''; var stock = '';
if (allocation.serial) { if (allocation.serial) {
stock = `{% trans "Serial Number" %}: ${allocation.serial}`; stock = `{% jstrans "Serial Number" %}: ${allocation.serial}`;
} else { } else {
stock = `{% trans "Quantity" %}: ${allocation.quantity}`; stock = `{% jstrans "Quantity" %}: ${allocation.quantity}`;
} }
html += ` html += `
@ -333,7 +333,7 @@ function completeSalesOrderShipment(shipment_id, options={}) {
constructForm(`{% url "api-so-shipment-list" %}${shipment_id}/ship/`, { constructForm(`{% url "api-so-shipment-list" %}${shipment_id}/ship/`, {
method: 'POST', method: 'POST',
title: `{% trans "Complete Shipment" %} ${shipment.reference}`, title: `{% jstrans "Complete Shipment" %} ${shipment.reference}`,
fields: { fields: {
shipment_date: { shipment_date: {
value: moment().format('YYYY-MM-DD'), value: moment().format('YYYY-MM-DD'),
@ -357,7 +357,7 @@ function completeSalesOrderShipment(shipment_id, options={}) {
}, },
preFormContent: html, preFormContent: html,
confirm: true, confirm: true,
confirmMessage: '{% trans "Confirm Shipment" %}', confirmMessage: '{% jstrans "Confirm Shipment" %}',
buttons: options.buttons, buttons: options.buttons,
onSuccess: function(data) { onSuccess: function(data) {
// Reload tables // Reload tables
@ -413,11 +413,11 @@ function completePendingShipments(order_id, options={}) {
if (!pending_shipments.length) { if (!pending_shipments.length) {
html += ` html += `
{% trans "No pending shipments found" %} {% jstrans "No pending shipments found" %}
`; `;
} else { } else {
html += ` html += `
{% trans "No stock items have been allocated to pending shipments" %} {% jstrans "No stock items have been allocated to pending shipments" %}
`; `;
} }
@ -427,7 +427,7 @@ function completePendingShipments(order_id, options={}) {
constructForm(`{% url "api-so-shipment-list" %}0/ship/`, { constructForm(`{% url "api-so-shipment-list" %}0/ship/`, {
method: 'POST', method: 'POST',
title: '{% trans "Complete Shipments" %}', title: '{% jstrans "Complete Shipments" %}',
preFormContent: html, preFormContent: html,
onSubmit: function(fields, options) { onSubmit: function(fields, options) {
handleFormSuccess(fields, options); handleFormSuccess(fields, options);
@ -449,7 +449,7 @@ function completePendingShipmentsHelper(shipments, shipment_idx, options={}) {
buttons: [ buttons: [
{ {
name: 'skip', name: 'skip',
title: `{% trans "Skip" %}`, title: `{% jstrans "Skip" %}`,
onClick: function(form_options) { onClick: function(form_options) {
if (form_options.modal) { if (form_options.modal) {
$(form_options.modal).modal('hide'); $(form_options.modal).modal('hide');
@ -481,7 +481,7 @@ function completeSalesOrder(order_id, options={}) {
`/api/order/so/${order_id}/complete/`, `/api/order/so/${order_id}/complete/`,
{ {
method: 'POST', method: 'POST',
title: '{% trans "Complete Sales Order" %}', title: '{% jstrans "Complete Sales Order" %}',
confirm: true, confirm: true,
fieldsFunction: function(opts) { fieldsFunction: function(opts) {
var fields = { var fields = {
@ -497,21 +497,21 @@ function completeSalesOrder(order_id, options={}) {
preFormContent: function(opts) { preFormContent: function(opts) {
var html = ` var html = `
<div class='alert alert-block alert-info'> <div class='alert alert-block alert-info'>
{% trans "Mark this order as complete?" %} {% jstrans "Mark this order as complete?" %}
</div>`; </div>`;
if (opts.context.pending_shipments) { if (opts.context.pending_shipments) {
html += ` html += `
<div class='alert alert-block alert-danger'> <div class='alert alert-block alert-danger'>
{% trans "Order cannot be completed as there are incomplete shipments" %}<br> {% jstrans "Order cannot be completed as there are incomplete shipments" %}<br>
</div>`; </div>`;
} }
if (!opts.context.is_complete) { if (!opts.context.is_complete) {
html += ` html += `
<div class='alert alert-block alert-warning'> <div class='alert alert-block alert-warning'>
{% trans "This order has line items which have not been completed." %}<br> {% jstrans "This order has line items which have not been completed." %}<br>
{% trans "Completing this order means that the order and line items will no longer be editable." %} {% jstrans "Completing this order means that the order and line items will no longer be editable." %}
</div>`; </div>`;
} }
@ -532,12 +532,12 @@ function issueSalesOrder(order_id, options={}) {
let html = ` let html = `
<div class='alert alert-block alert-info'> <div class='alert alert-block alert-info'>
{% trans "Issue this Sales Order?" %} {% jstrans "Issue this Sales Order?" %}
</div>`; </div>`;
constructForm(`{% url "api-so-list" %}${order_id}/issue/`, { constructForm(`{% url "api-so-list" %}${order_id}/issue/`, {
method: 'POST', method: 'POST',
title: '{% trans "Issue Sales Order" %}', title: '{% jstrans "Issue Sales Order" %}',
confirm: true, confirm: true,
preFormContent: html, preFormContent: html,
onSuccess: function(response) { onSuccess: function(response) {
@ -556,12 +556,12 @@ function cancelSalesOrder(order_id, options={}) {
`/api/order/so/${order_id}/cancel/`, `/api/order/so/${order_id}/cancel/`,
{ {
method: 'POST', method: 'POST',
title: '{% trans "Cancel Sales Order" %}', title: '{% jstrans "Cancel Sales Order" %}',
confirm: true, confirm: true,
preFormContent: function(opts) { preFormContent: function(opts) {
var html = ` var html = `
<div class='alert alert-block alert-warning'> <div class='alert alert-block alert-warning'>
{% trans "Cancelling this order means that the order will no longer be editable." %} {% jstrans "Cancelling this order means that the order will no longer be editable." %}
</div>`; </div>`;
return html; return html;
@ -615,7 +615,7 @@ function createSalesOrderShipment(options={}) {
constructForm('{% url "api-so-shipment-list" %}', { constructForm('{% url "api-so-shipment-list" %}', {
method: 'POST', method: 'POST',
fields: fields, fields: fields,
title: '{% trans "Create New Shipment" %}', title: '{% jstrans "Create New Shipment" %}',
onSuccess: function(data) { onSuccess: function(data) {
if (options.onSuccess) { if (options.onSuccess) {
options.onSuccess(data); options.onSuccess(data);
@ -725,7 +725,7 @@ function loadSalesOrderTable(table, options) {
showCustomView: display_mode == 'calendar', showCustomView: display_mode == 'calendar',
disablePagination: display_mode == 'calendar', disablePagination: display_mode == 'calendar',
formatNoMatches: function() { formatNoMatches: function() {
return '{% trans "No sales orders found" %}'; return '{% jstrans "No sales orders found" %}';
}, },
buttons: constructOrderTableButtons({ buttons: constructOrderTableButtons({
prefix: 'salesorder', prefix: 'salesorder',
@ -766,12 +766,12 @@ function loadSalesOrderTable(table, options) {
{ {
sortable: true, sortable: true,
field: 'reference', field: 'reference',
title: '{% trans "Sales Order" %}', title: '{% jstrans "Sales Order" %}',
formatter: function(value, row) { formatter: function(value, row) {
var html = renderLink(value, `/order/sales-order/${row.pk}/`); var html = renderLink(value, `/order/sales-order/${row.pk}/`);
if (row.overdue) { if (row.overdue) {
html += makeIconBadge('fa-calendar-times icon-red', '{% trans "Order is overdue" %}'); html += makeIconBadge('fa-calendar-times icon-red', '{% jstrans "Order is overdue" %}');
} }
return html; return html;
@ -781,11 +781,11 @@ function loadSalesOrderTable(table, options) {
sortable: true, sortable: true,
sortName: 'customer__name', sortName: 'customer__name',
field: 'customer_detail', field: 'customer_detail',
title: '{% trans "Customer" %}', title: '{% jstrans "Customer" %}',
formatter: function(value, row) { formatter: function(value, row) {
if (!row.customer_detail) { if (!row.customer_detail) {
return '{% trans "Invalid Customer" %}'; return '{% jstrans "Invalid Customer" %}';
} }
return imageHoverIcon(row.customer_detail.image) + renderLink(row.customer_detail.name, `/company/${row.customer}/sales-orders/`); return imageHoverIcon(row.customer_detail.image) + renderLink(row.customer_detail.name, `/company/${row.customer}/sales-orders/`);
@ -794,16 +794,16 @@ function loadSalesOrderTable(table, options) {
{ {
sortable: true, sortable: true,
field: 'customer_reference', field: 'customer_reference',
title: '{% trans "Customer Reference" %}', title: '{% jstrans "Customer Reference" %}',
}, },
{ {
sortable: false, sortable: false,
field: 'description', field: 'description',
title: '{% trans "Description" %}', title: '{% jstrans "Description" %}',
}, },
{ {
field: 'project_code', field: 'project_code',
title: '{% trans "Project Code" %}', title: '{% jstrans "Project Code" %}',
switchable: global_settings.PROJECT_CODES_ENABLED, switchable: global_settings.PROJECT_CODES_ENABLED,
visible: global_settings.PROJECT_CODES_ENABLED, visible: global_settings.PROJECT_CODES_ENABLED,
sortable: true, sortable: true,
@ -816,7 +816,7 @@ function loadSalesOrderTable(table, options) {
{ {
sortable: true, sortable: true,
field: 'status', field: 'status',
title: '{% trans "Status" %}', title: '{% jstrans "Status" %}',
formatter: function(value, row) { formatter: function(value, row) {
return salesOrderStatusDisplay(row.status); return salesOrderStatusDisplay(row.status);
} }
@ -824,7 +824,7 @@ function loadSalesOrderTable(table, options) {
{ {
sortable: true, sortable: true,
field: 'creation_date', field: 'creation_date',
title: '{% trans "Creation Date" %}', title: '{% jstrans "Creation Date" %}',
formatter: function(value) { formatter: function(value) {
return renderDate(value); return renderDate(value);
} }
@ -832,7 +832,7 @@ function loadSalesOrderTable(table, options) {
{ {
sortable: true, sortable: true,
field: 'target_date', field: 'target_date',
title: '{% trans "Target Date" %}', title: '{% jstrans "Target Date" %}',
formatter: function(value) { formatter: function(value) {
return renderDate(value); return renderDate(value);
} }
@ -840,7 +840,7 @@ function loadSalesOrderTable(table, options) {
{ {
sortable: true, sortable: true,
field: 'shipment_date', field: 'shipment_date',
title: '{% trans "Shipment Date" %}', title: '{% jstrans "Shipment Date" %}',
formatter: function(value) { formatter: function(value) {
return renderDate(value); return renderDate(value);
} }
@ -848,11 +848,11 @@ function loadSalesOrderTable(table, options) {
{ {
sortable: true, sortable: true,
field: 'line_items', field: 'line_items',
title: '{% trans "Items" %}' title: '{% jstrans "Items" %}'
}, },
{ {
field: 'total_price', field: 'total_price',
title: '{% trans "Total Cost" %}', title: '{% jstrans "Total Cost" %}',
switchable: true, switchable: true,
sortable: true, sortable: true,
formatter: function(value, row) { formatter: function(value, row) {
@ -905,15 +905,15 @@ function loadSalesOrderShipmentTable(table, options={}) {
let html = ''; let html = '';
html += makeEditButton('button-shipment-edit', pk, '{% trans "Edit shipment" %}'); html += makeEditButton('button-shipment-edit', pk, '{% jstrans "Edit shipment" %}');
if (!options.shipped) { if (!options.shipped) {
html += makeIconButton('fa-truck icon-green', 'button-shipment-ship', pk, '{% trans "Complete shipment" %}'); html += makeIconButton('fa-truck icon-green', 'button-shipment-ship', pk, '{% jstrans "Complete shipment" %}');
} }
var enable_delete = row.allocations && row.allocations.length == 0; var enable_delete = row.allocations && row.allocations.length == 0;
html += makeDeleteButton('button-shipment-delete', pk, '{% trans "Delete shipment" %}', {disabled: !enable_delete}); html += makeDeleteButton('button-shipment-delete', pk, '{% jstrans "Delete shipment" %}', {disabled: !enable_delete});
return wrapButtons(html); return wrapButtons(html);
} }
@ -930,7 +930,7 @@ function loadSalesOrderShipmentTable(table, options={}) {
constructForm(`{% url "api-so-shipment-list" %}${pk}/`, { constructForm(`{% url "api-so-shipment-list" %}${pk}/`, {
fields: fields, fields: fields,
title: '{% trans "Edit Shipment" %}', title: '{% jstrans "Edit Shipment" %}',
refreshTable: table, refreshTable: table,
}); });
}); });
@ -945,7 +945,7 @@ function loadSalesOrderShipmentTable(table, options={}) {
var pk = $(this).attr('pk'); var pk = $(this).attr('pk');
constructForm(`{% url "api-so-shipment-list" %}${pk}/`, { constructForm(`{% url "api-so-shipment-list" %}${pk}/`, {
title: '{% trans "Delete Shipment" %}', title: '{% jstrans "Delete Shipment" %}',
method: 'DELETE', method: 'DELETE',
refreshTable: table, refreshTable: table,
}); });
@ -978,7 +978,7 @@ function loadSalesOrderShipmentTable(table, options={}) {
} }
}, },
formatNoMatches: function() { formatNoMatches: function() {
return '{% trans "No matching shipments found" %}'; return '{% jstrans "No matching shipments found" %}';
}, },
columns: [ columns: [
{ {
@ -989,13 +989,13 @@ function loadSalesOrderShipmentTable(table, options={}) {
{ {
visible: show_so_reference, visible: show_so_reference,
field: 'order_detail', field: 'order_detail',
title: '{% trans "Sales Order" %}', title: '{% jstrans "Sales Order" %}',
switchable: false, switchable: false,
formatter: function(value, row) { formatter: function(value, row) {
var html = renderLink(row.order_detail.reference, `/order/sales-order/${row.order}/`); var html = renderLink(row.order_detail.reference, `/order/sales-order/${row.order}/`);
if (row.overdue) { if (row.overdue) {
html += makeIconBadge('fa-calendar-times icon-red', '{% trans "Order is overdue" %}'); html += makeIconBadge('fa-calendar-times icon-red', '{% jstrans "Order is overdue" %}');
} }
return html; return html;
@ -1003,12 +1003,12 @@ function loadSalesOrderShipmentTable(table, options={}) {
}, },
{ {
field: 'reference', field: 'reference',
title: '{% trans "Shipment Reference" %}', title: '{% jstrans "Shipment Reference" %}',
switchable: false, switchable: false,
}, },
{ {
field: 'allocations', field: 'allocations',
title: '{% trans "Items" %}', title: '{% jstrans "Items" %}',
switchable: false, switchable: false,
sortable: true, sortable: true,
formatter: function(value, row) { formatter: function(value, row) {
@ -1021,39 +1021,39 @@ function loadSalesOrderShipmentTable(table, options={}) {
}, },
{ {
field: 'shipment_date', field: 'shipment_date',
title: '{% trans "Shipment Date" %}', title: '{% jstrans "Shipment Date" %}',
sortable: true, sortable: true,
formatter: function(value, row) { formatter: function(value, row) {
if (value) { if (value) {
return renderDate(value); return renderDate(value);
} else { } else {
return '<em>{% trans "Not shipped" %}</em>'; return '<em>{% jstrans "Not shipped" %}</em>';
} }
} }
}, },
{ {
field: 'delivery_date', field: 'delivery_date',
title: '{% trans "Delivery Date" %}', title: '{% jstrans "Delivery Date" %}',
sortable: true, sortable: true,
formatter: function(value, row) { formatter: function(value, row) {
if (value) { if (value) {
return renderDate(value); return renderDate(value);
} else { } else {
return '<em>{% trans "Unknown" %}</em>'; return '<em>{% jstrans "Unknown" %}</em>';
} }
} }
}, },
{ {
field: 'tracking_number', field: 'tracking_number',
title: '{% trans "Tracking" %}', title: '{% jstrans "Tracking" %}',
}, },
{ {
field: 'invoice_number', field: 'invoice_number',
title: '{% trans "Invoice" %}', title: '{% jstrans "Invoice" %}',
}, },
{ {
field: 'link', field: 'link',
title: '{% trans "Link" %}', title: '{% jstrans "Link" %}',
formatter: function(value) { formatter: function(value) {
if (value) { if (value) {
return renderLink(value, value); return renderLink(value, value);
@ -1064,7 +1064,7 @@ function loadSalesOrderShipmentTable(table, options={}) {
}, },
{ {
field: 'notes', field: 'notes',
title: '{% trans "Notes" %}', title: '{% jstrans "Notes" %}',
visible: false, visible: false,
switchable: false, switchable: false,
// TODO: Implement 'notes' field // TODO: Implement 'notes' field
@ -1106,7 +1106,7 @@ function allocateStockToSalesOrder(order_id, line_items, options={}) {
makeRemoveButton( makeRemoveButton(
'button-row-remove', 'button-row-remove',
pk, pk,
'{% trans "Remove row" %}', '{% jstrans "Remove row" %}',
) )
); );
@ -1118,7 +1118,7 @@ function allocateStockToSalesOrder(order_id, line_items, options={}) {
type: 'decimal', type: 'decimal',
min_value: 0, min_value: 0,
value: quantity || 0, value: quantity || 0,
title: '{% trans "Specify stock allocation quantity" %}', title: '{% jstrans "Specify stock allocation quantity" %}',
required: true, required: true,
}, },
{ {
@ -1168,8 +1168,8 @@ function allocateStockToSalesOrder(order_id, line_items, options={}) {
if (table_entries.length == 0) { if (table_entries.length == 0) {
showAlertDialog( showAlertDialog(
'{% trans "Select Parts" %}', '{% jstrans "Select Parts" %}',
'{% trans "You must select at least one part to allocate" %}', '{% jstrans "You must select at least one part to allocate" %}',
); );
return; return;
@ -1182,8 +1182,8 @@ function allocateStockToSalesOrder(order_id, line_items, options={}) {
'take_from', 'take_from',
{ {
type: 'related field', type: 'related field',
label: '{% trans "Source Location" %}', label: '{% jstrans "Source Location" %}',
help_text: '{% trans "Select source location (leave blank to take from all locations)" %}', help_text: '{% jstrans "Select source location (leave blank to take from all locations)" %}',
required: false, required: false,
}, },
{}, {},
@ -1194,9 +1194,9 @@ function allocateStockToSalesOrder(order_id, line_items, options={}) {
<table class='table table-striped table-condensed' id='stock-allocation-table'> <table class='table table-striped table-condensed' id='stock-allocation-table'>
<thead> <thead>
<tr> <tr>
<th>{% trans "Part" %}</th> <th>{% jstrans "Part" %}</th>
<th style='min-width: 250px;'>{% trans "Stock Item" %}</th> <th style='min-width: 250px;'>{% jstrans "Stock Item" %}</th>
<th>{% trans "Quantity" %}</th> <th>{% jstrans "Quantity" %}</th>
<th></th> <th></th>
</thead> </thead>
<tbody> <tbody>
@ -1216,7 +1216,7 @@ function allocateStockToSalesOrder(order_id, line_items, options={}) {
auto_fill: true, auto_fill: true,
secondary: { secondary: {
method: 'POST', method: 'POST',
title: '{% trans "Add Shipment" %}', title: '{% jstrans "Add Shipment" %}',
fields: function() { fields: function() {
var ref = null; var ref = null;
@ -1267,8 +1267,8 @@ function allocateStockToSalesOrder(order_id, line_items, options={}) {
}, },
preFormContent: html, preFormContent: html,
confirm: true, confirm: true,
confirmMessage: '{% trans "Confirm stock allocation" %}', confirmMessage: '{% jstrans "Confirm stock allocation" %}',
title: '{% trans "Allocate Stock Items to Sales Order" %}', title: '{% jstrans "Allocate Stock Items to Sales Order" %}',
afterRender: function(fields, opts) { afterRender: function(fields, opts) {
// Initialize source location field // Initialize source location field
@ -1280,7 +1280,7 @@ function allocateStockToSalesOrder(order_id, line_items, options={}) {
type: 'related field', type: 'related field',
value: options.source_location || null, value: options.source_location || null,
noResults: function(query) { noResults: function(query) {
return '{% trans "No matching stock locations" %}'; return '{% jstrans "No matching stock locations" %}';
}, },
}; };
@ -1359,7 +1359,7 @@ function allocateStockToSalesOrder(order_id, line_items, options={}) {
return filters; return filters;
}, },
noResults: function(query) { noResults: function(query) {
return '{% trans "No matching stock items" %}'; return '{% jstrans "No matching stock items" %}';
} }
}, },
null, null,
@ -1474,7 +1474,7 @@ function loadSalesOrderAllocationTable(table, options={}) {
paginationVAlign: 'bottom', paginationVAlign: 'bottom',
original: options.params, original: options.params,
formatNoMatches: function() { formatNoMatches: function() {
return '{% trans "No sales order allocations found" %}'; return '{% jstrans "No sales order allocations found" %}';
}, },
columns: [ columns: [
{ {
@ -1485,7 +1485,7 @@ function loadSalesOrderAllocationTable(table, options={}) {
{ {
field: 'order', field: 'order',
switchable: false, switchable: false,
title: '{% trans "Order" %}', title: '{% jstrans "Order" %}',
formatter: function(value, row) { formatter: function(value, row) {
var ref = `${row.order_detail.reference}`; var ref = `${row.order_detail.reference}`;
@ -1496,37 +1496,37 @@ function loadSalesOrderAllocationTable(table, options={}) {
{ {
field: 'item', field: 'item',
switchable: false, switchable: false,
title: '{% trans "Stock Item" %}', title: '{% jstrans "Stock Item" %}',
formatter: function(value, row) { formatter: function(value, row) {
// Render a link to the particular stock item // Render a link to the particular stock item
var link = `/stock/item/${row.item}/`; var link = `/stock/item/${row.item}/`;
var text = `{% trans "Stock Item" %} ${row.item}`; var text = `{% jstrans "Stock Item" %} ${row.item}`;
return renderLink(text, link); return renderLink(text, link);
} }
}, },
{ {
field: 'location', field: 'location',
title: '{% trans "Location" %}', title: '{% jstrans "Location" %}',
formatter: function(value, row) { formatter: function(value, row) {
return locationDetail(row.item_detail, true); return locationDetail(row.item_detail, true);
} }
}, },
{ {
field: 'quantity', field: 'quantity',
title: '{% trans "Quantity" %}', title: '{% jstrans "Quantity" %}',
sortable: true, sortable: true,
}, },
{ {
field: 'shipment_date', field: 'shipment_date',
title: '{% trans "Shipped" %}', title: '{% jstrans "Shipped" %}',
sortable: true, sortable: true,
formatter: function(value, row) { formatter: function(value, row) {
if (value) { if (value) {
return renderDate(value); return renderDate(value);
} else { } else {
return `<em>{% trans "Not shipped" %}</em>`; return `<em>{% jstrans "Not shipped" %}</em>`;
} }
} }
} }
@ -1566,7 +1566,7 @@ function showAllocationSubTable(index, row, element, options) {
fields: { fields: {
quantity: {}, quantity: {},
}, },
title: '{% trans "Edit Stock Allocation" %}', title: '{% jstrans "Edit Stock Allocation" %}',
refreshTable: options.table, refreshTable: options.table,
}, },
); );
@ -1580,8 +1580,8 @@ function showAllocationSubTable(index, row, element, options) {
`/api/order/so-allocation/${pk}/`, `/api/order/so-allocation/${pk}/`,
{ {
method: 'DELETE', method: 'DELETE',
confirmMessage: '{% trans "Confirm Delete Operation" %}', confirmMessage: '{% jstrans "Confirm Delete Operation" %}',
title: '{% trans "Delete Stock Allocation" %}', title: '{% jstrans "Delete Stock Allocation" %}',
refreshTable: options.table, refreshTable: options.table,
} }
); );
@ -1595,20 +1595,20 @@ function showAllocationSubTable(index, row, element, options) {
columns: [ columns: [
{ {
field: 'part_detail', field: 'part_detail',
title: '{% trans "Part" %}', title: '{% jstrans "Part" %}',
formatter: function(part, row) { formatter: function(part, row) {
return imageHoverIcon(part.thumbnail) + renderLink(part.full_name, `/part/${part.pk}/`); return imageHoverIcon(part.thumbnail) + renderLink(part.full_name, `/part/${part.pk}/`);
} }
}, },
{ {
field: 'allocated', field: 'allocated',
title: '{% trans "Stock Item" %}', title: '{% jstrans "Stock Item" %}',
formatter: function(value, row, index, field) { formatter: function(value, row, index, field) {
let item = row.item_detail; let item = row.item_detail;
let text = `{% trans "Quantity" %}: ${row.quantity}`; let text = `{% jstrans "Quantity" %}: ${row.quantity}`;
if (item && item.serial != null && row.quantity == 1) { if (item && item.serial != null && row.quantity == 1) {
text = `{% trans "Serial Number" %}: ${item.serial}`; text = `{% jstrans "Serial Number" %}: ${item.serial}`;
} }
return renderLink(text, `/stock/item/${row.item}/`); return renderLink(text, `/stock/item/${row.item}/`);
@ -1616,19 +1616,19 @@ function showAllocationSubTable(index, row, element, options) {
}, },
{ {
field: 'location', field: 'location',
title: '{% trans "Location" %}', title: '{% jstrans "Location" %}',
formatter: function(value, row, index, field) { formatter: function(value, row, index, field) {
if (row.shipment_date) { if (row.shipment_date) {
return `<em>{% trans "Shipped to customer" %} - ${row.shipment_date}</em>`; return `<em>{% jstrans "Shipped to customer" %} - ${row.shipment_date}</em>`;
} else if (row.location) { } else if (row.location) {
// Location specified // Location specified
return renderLink( return renderLink(
row.location_detail.pathstring || '{% trans "Location" %}', row.location_detail.pathstring || '{% jstrans "Location" %}',
`/stock/location/${row.location}/` `/stock/location/${row.location}/`
); );
} else { } else {
return `<em>{% trans "Stock location not specified" %}</em>`; return `<em>{% jstrans "Stock location not specified" %}</em>`;
} }
}, },
}, },
@ -1641,10 +1641,10 @@ function showAllocationSubTable(index, row, element, options) {
let pk = row.pk; let pk = row.pk;
if (row.shipment_date) { if (row.shipment_date) {
html += `<span class='badge bg-success badge-right'>{% trans "Shipped" %}</span>`; html += `<span class='badge bg-success badge-right'>{% jstrans "Shipped" %}</span>`;
} else { } else {
html += makeEditButton('button-allocation-edit', pk, '{% trans "Edit stock allocation" %}'); html += makeEditButton('button-allocation-edit', pk, '{% jstrans "Edit stock allocation" %}');
html += makeDeleteButton('button-allocation-delete', pk, '{% trans "Delete stock allocation" %}'); html += makeDeleteButton('button-allocation-delete', pk, '{% jstrans "Delete stock allocation" %}');
} }
return wrapButtons(html); return wrapButtons(html);
@ -1689,13 +1689,13 @@ function showFulfilledSubTable(index, row, element, options) {
}, },
{ {
field: 'stock', field: 'stock',
title: '{% trans "Stock Item" %}', title: '{% jstrans "Stock Item" %}',
formatter: function(value, row) { formatter: function(value, row) {
var text = ''; var text = '';
if (row.serial && row.quantity == 1) { if (row.serial && row.quantity == 1) {
text = `{% trans "Serial Number" %}: ${row.serial}`; text = `{% jstrans "Serial Number" %}: ${row.serial}`;
} else { } else {
text = `{% trans "Quantity" %}: ${row.quantity}`; text = `{% jstrans "Quantity" %}: ${row.quantity}`;
} }
return renderLink(text, `/stock/item/${row.pk}/`); return renderLink(text, `/stock/item/${row.pk}/`);
@ -1703,11 +1703,11 @@ function showFulfilledSubTable(index, row, element, options) {
}, },
{ {
field: 'location', field: 'location',
title: '{% trans "Location" %}', title: '{% jstrans "Location" %}',
formatter: function(value, row) { formatter: function(value, row) {
if (row.customer) { if (row.customer) {
return renderLink( return renderLink(
'{% trans "Shipped to customer" %}', '{% jstrans "Shipped to customer" %}',
`/company/${row.customer}/` `/company/${row.customer}/`
); );
} else if (row.location && row.location_detail) { } else if (row.location && row.location_detail) {
@ -1716,7 +1716,7 @@ function showFulfilledSubTable(index, row, element, options) {
`/stock/location/${row.location}`, `/stock/location/${row.location}`,
); );
} else { } else {
return `<em>{% trans "Stock location not specified" %}</em>`; return `<em>{% jstrans "Stock location not specified" %}</em>`;
} }
} }
} }
@ -1793,7 +1793,7 @@ function loadSalesOrderLineItemTable(table, options={}) {
sortable: true, sortable: true,
sortName: 'part_detail.name', sortName: 'part_detail.name',
field: 'part', field: 'part',
title: '{% trans "Part" %}', title: '{% jstrans "Part" %}',
switchable: false, switchable: false,
formatter: function(value, row, index, field) { formatter: function(value, row, index, field) {
if (row.part_detail) { if (row.part_detail) {
@ -1803,25 +1803,25 @@ function loadSalesOrderLineItemTable(table, options={}) {
} }
}, },
footerFormatter: function() { footerFormatter: function() {
return '{% trans "Total" %}'; return '{% jstrans "Total" %}';
}, },
}, },
{ {
sortable: false, sortable: false,
field: 'part_detail.description', field: 'part_detail.description',
title: '{% trans "Description" %}', title: '{% jstrans "Description" %}',
switchable: true, switchable: true,
}, },
{ {
sortable: true, sortable: true,
field: 'reference', field: 'reference',
title: '{% trans "Reference" %}', title: '{% jstrans "Reference" %}',
switchable: true, switchable: true,
}, },
{ {
sortable: true, sortable: true,
field: 'quantity', field: 'quantity',
title: '{% trans "Quantity" %}', title: '{% jstrans "Quantity" %}',
footerFormatter: function(data) { footerFormatter: function(data) {
return data.map(function(row) { return data.map(function(row) {
return +row['quantity']; return +row['quantity'];
@ -1834,7 +1834,7 @@ function loadSalesOrderLineItemTable(table, options={}) {
{ {
sortable: true, sortable: true,
field: 'sale_price', field: 'sale_price',
title: '{% trans "Unit Price" %}', title: '{% jstrans "Unit Price" %}',
formatter: function(value, row) { formatter: function(value, row) {
return formatCurrency(row.sale_price, { return formatCurrency(row.sale_price, {
currency: row.sale_price_currency currency: row.sale_price_currency
@ -1844,7 +1844,7 @@ function loadSalesOrderLineItemTable(table, options={}) {
{ {
field: 'total_price', field: 'total_price',
sortable: true, sortable: true,
title: '{% trans "Total Price" %}', title: '{% jstrans "Total Price" %}',
formatter: function(value, row) { formatter: function(value, row) {
return formatCurrency(row.sale_price * row.quantity, { return formatCurrency(row.sale_price * row.quantity, {
currency: row.sale_price_currency, currency: row.sale_price_currency,
@ -1864,7 +1864,7 @@ function loadSalesOrderLineItemTable(table, options={}) {
}, },
{ {
field: 'target_date', field: 'target_date',
title: '{% trans "Target Date" %}', title: '{% jstrans "Target Date" %}',
sortable: true, sortable: true,
switchable: true, switchable: true,
formatter: function(value, row) { formatter: function(value, row) {
@ -1872,7 +1872,7 @@ function loadSalesOrderLineItemTable(table, options={}) {
var html = renderDate(row.target_date); var html = renderDate(row.target_date);
if (row.overdue) { if (row.overdue) {
html += makeIconBadge('fa-calendar-times', '{% trans "This line item is overdue" %}'); html += makeIconBadge('fa-calendar-times', '{% jstrans "This line item is overdue" %}');
} }
return html; return html;
@ -1890,7 +1890,7 @@ function loadSalesOrderLineItemTable(table, options={}) {
columns.push( columns.push(
{ {
field: 'stock', field: 'stock',
title: '{% trans "Available Stock" %}', title: '{% jstrans "Available Stock" %}',
formatter: function(value, row) { formatter: function(value, row) {
let available = row.available_stock + row.available_variant_stock; let available = row.available_stock + row.available_variant_stock;
@ -1904,17 +1904,17 @@ function loadSalesOrderLineItemTable(table, options={}) {
html = renderLink(available, url); html = renderLink(available, url);
if (row.available_variant_stock && row.available_variant_stock > 0) { if (row.available_variant_stock && row.available_variant_stock > 0) {
html += makeIconBadge('fa-info-circle icon-blue', '{% trans "Includes variant stock" %}'); html += makeIconBadge('fa-info-circle icon-blue', '{% jstrans "Includes variant stock" %}');
} }
} else { } else {
html += `<span class='badge rounded-pill bg-danger'>{% trans "No Stock Available" %}</span>`; html += `<span class='badge rounded-pill bg-danger'>{% jstrans "No Stock Available" %}</span>`;
} }
if (required > 0) { if (required > 0) {
if (available >= required) { if (available >= required) {
html += makeIconBadge('fa-check-circle icon-green', '{% trans "Sufficient stock available" %}'); html += makeIconBadge('fa-check-circle icon-green', '{% jstrans "Sufficient stock available" %}');
} else { } else {
html += makeIconBadge('fa-times-circle icon-red', '{% trans "Insufficient stock available" %}'); html += makeIconBadge('fa-times-circle icon-red', '{% jstrans "Insufficient stock available" %}');
} }
} }
@ -1926,7 +1926,7 @@ function loadSalesOrderLineItemTable(table, options={}) {
columns.push( columns.push(
{ {
field: 'allocated', field: 'allocated',
title: '{% trans "Allocated" %}', title: '{% jstrans "Allocated" %}',
switchable: false, switchable: false,
sortable: true, sortable: true,
formatter: function(value, row, index, field) { formatter: function(value, row, index, field) {
@ -1954,7 +1954,7 @@ function loadSalesOrderLineItemTable(table, options={}) {
columns.push({ columns.push({
field: 'shipped', field: 'shipped',
title: '{% trans "Shipped" %}', title: '{% jstrans "Shipped" %}',
switchable: false, switchable: false,
sortable: true, sortable: true,
formatter: function(value, row) { formatter: function(value, row) {
@ -1979,12 +1979,12 @@ function loadSalesOrderLineItemTable(table, options={}) {
columns.push({ columns.push({
field: 'notes', field: 'notes',
title: '{% trans "Notes" %}', title: '{% jstrans "Notes" %}',
}); });
columns.push({ columns.push({
field: 'link', field: 'link',
title: '{% trans "Link" %}', title: '{% jstrans "Link" %}',
formatter: function(value) { formatter: function(value) {
if (value) { if (value) {
return renderLink(value, value); return renderLink(value, value);
@ -2005,37 +2005,37 @@ function loadSalesOrderLineItemTable(table, options={}) {
if (options.allow_edit && (row.shipped < row.quantity)) { if (options.allow_edit && (row.shipped < row.quantity)) {
if (part.trackable) { if (part.trackable) {
buttons += makeIconButton('fa-hashtag icon-green', 'button-add-by-sn', pk, '{% trans "Allocate serial numbers" %}'); buttons += makeIconButton('fa-hashtag icon-green', 'button-add-by-sn', pk, '{% jstrans "Allocate serial numbers" %}');
} }
buttons += makeIconButton('fa-sign-in-alt icon-green', 'button-add', pk, '{% trans "Allocate stock" %}'); buttons += makeIconButton('fa-sign-in-alt icon-green', 'button-add', pk, '{% jstrans "Allocate stock" %}');
if (part.purchaseable) { if (part.purchaseable) {
buttons += makeIconButton('fa-shopping-cart', 'button-buy', row.part, '{% trans "Purchase stock" %}'); buttons += makeIconButton('fa-shopping-cart', 'button-buy', row.part, '{% jstrans "Purchase stock" %}');
} }
if (part.assembly) { if (part.assembly) {
buttons += makeIconButton('fa-tools', 'button-build', row.part, '{% trans "Build stock" %}'); buttons += makeIconButton('fa-tools', 'button-build', row.part, '{% jstrans "Build stock" %}');
} }
} }
} }
buttons += makeIconButton('fa-dollar-sign icon-green', 'button-price', pk, '{% trans "Calculate price" %}'); buttons += makeIconButton('fa-dollar-sign icon-green', 'button-price', pk, '{% jstrans "Calculate price" %}');
if (options.allow_edit) { if (options.allow_edit) {
buttons += makeCopyButton('button-duplicate', pk, '{% trans "Duplicate line item" %}'); buttons += makeCopyButton('button-duplicate', pk, '{% jstrans "Duplicate line item" %}');
buttons += makeEditButton('button-edit', pk, '{% trans "Edit line item" %}'); buttons += makeEditButton('button-edit', pk, '{% jstrans "Edit line item" %}');
} }
if (options.allow_delete) { if (options.allow_delete) {
var delete_disabled = false; var delete_disabled = false;
var title = '{% trans "Delete line item" %}'; var title = '{% jstrans "Delete line item" %}';
if (row.shipped) { if (row.shipped) {
delete_disabled = true; delete_disabled = true;
title = '{% trans "Cannot be deleted as items have been shipped" %}'; title = '{% jstrans "Cannot be deleted as items have been shipped" %}';
} else if (row.allocated) { } else if (row.allocated) {
delete_disabled = true; delete_disabled = true;
title = '{% trans "Cannot be deleted as items have been allocated" %}'; title = '{% jstrans "Cannot be deleted as items have been allocated" %}';
} }
// Prevent deletion of the line item if items have been allocated or shipped! // Prevent deletion of the line item if items have been allocated or shipped!
@ -2067,7 +2067,7 @@ function loadSalesOrderLineItemTable(table, options={}) {
method: 'POST', method: 'POST',
fields: fields, fields: fields,
data: data, data: data,
title: '{% trans "Duplicate Line Item" %}', title: '{% jstrans "Duplicate Line Item" %}',
refreshTable: table, refreshTable: table,
}); });
} }
@ -2080,7 +2080,7 @@ function loadSalesOrderLineItemTable(table, options={}) {
constructForm(`{% url "api-so-line-list" %}${pk}/`, { constructForm(`{% url "api-so-line-list" %}${pk}/`, {
fields: soLineItemFields(), fields: soLineItemFields(),
title: '{% trans "Edit Line Item" %}', title: '{% jstrans "Edit Line Item" %}',
onSuccess: reloadTable, onSuccess: reloadTable,
}); });
}); });
@ -2091,7 +2091,7 @@ function loadSalesOrderLineItemTable(table, options={}) {
constructForm(`{% url "api-so-line-list" %}${pk}/`, { constructForm(`{% url "api-so-line-list" %}${pk}/`, {
method: 'DELETE', method: 'DELETE',
title: '{% trans "Delete Line Item" %}', title: '{% jstrans "Delete Line Item" %}',
onSuccess: reloadTable, onSuccess: reloadTable,
}); });
}); });
@ -2106,7 +2106,7 @@ function loadSalesOrderLineItemTable(table, options={}) {
constructForm(`{% url "api-so-list" %}${options.order}/allocate-serials/`, { constructForm(`{% url "api-so-list" %}${options.order}/allocate-serials/`, {
method: 'POST', method: 'POST',
title: '{% trans "Allocate Serial Numbers" %}', title: '{% jstrans "Allocate Serial Numbers" %}',
fields: { fields: {
line_item: { line_item: {
value: pk, value: pk,
@ -2205,7 +2205,7 @@ function loadSalesOrderLineItemTable(table, options={}) {
launchModalForm( launchModalForm(
'{% url "line-pricing" %}', '{% url "line-pricing" %}',
{ {
submit_text: '{% trans "Calculate price" %}', submit_text: '{% jstrans "Calculate price" %}',
data: { data: {
line_item: pk, line_item: pk,
quantity: row.quantity, quantity: row.quantity,
@ -2213,7 +2213,7 @@ function loadSalesOrderLineItemTable(table, options={}) {
buttons: [ buttons: [
{ {
name: 'update_price', name: 'update_price',
title: '{% trans "Update Unit Price" %}' title: '{% jstrans "Update Unit Price" %}'
}, },
], ],
success: reloadTable, success: reloadTable,
@ -2227,7 +2227,7 @@ function loadSalesOrderLineItemTable(table, options={}) {
name: 'salesorderlineitems', name: 'salesorderlineitems',
sidePagination: 'client', sidePagination: 'client',
formatNoMatches: function() { formatNoMatches: function() {
return '{% trans "No matching line items" %}'; return '{% jstrans "No matching line items" %}';
}, },
queryParams: filters, queryParams: filters,
original: options.params, original: options.params,

View File

@ -127,7 +127,7 @@ function updateSearch() {
filters.active = true; filters.active = true;
} }
addSearchQuery('part', '{% trans "Parts" %}', filters); addSearchQuery('part', '{% jstrans "Parts" %}', filters);
} }
if (checkPermission('part') && checkPermission('purchase_order')) { if (checkPermission('part') && checkPermission('purchase_order')) {
@ -144,18 +144,18 @@ function updateSearch() {
} }
if (user_settings.SEARCH_PREVIEW_SHOW_SUPPLIER_PARTS) { if (user_settings.SEARCH_PREVIEW_SHOW_SUPPLIER_PARTS) {
addSearchQuery('supplierpart', '{% trans "Supplier Parts" %}', filters); addSearchQuery('supplierpart', '{% jstrans "Supplier Parts" %}', filters);
} }
if (user_settings.SEARCH_PREVIEW_SHOW_MANUFACTURER_PARTS) { if (user_settings.SEARCH_PREVIEW_SHOW_MANUFACTURER_PARTS) {
addSearchQuery('manufacturerpart', '{% trans "Manufacturer Parts" %}', filters); addSearchQuery('manufacturerpart', '{% jstrans "Manufacturer Parts" %}', filters);
} }
} }
if (checkPermission('part_category') && user_settings.SEARCH_PREVIEW_SHOW_CATEGORIES) { if (checkPermission('part_category') && user_settings.SEARCH_PREVIEW_SHOW_CATEGORIES) {
let filters = {}; let filters = {};
addSearchQuery('partcategory', '{% trans "Part Categories" %}', filters); addSearchQuery('partcategory', '{% jstrans "Part Categories" %}', filters);
} }
if (checkPermission('stock') && user_settings.SEARCH_PREVIEW_SHOW_STOCK) { if (checkPermission('stock') && user_settings.SEARCH_PREVIEW_SHOW_STOCK) {
@ -169,13 +169,13 @@ function updateSearch() {
filters.in_stock = true; filters.in_stock = true;
} }
addSearchQuery('stockitem', '{% trans "Stock Items" %}', filters); addSearchQuery('stockitem', '{% jstrans "Stock Items" %}', filters);
} }
if (checkPermission('stock_location') && user_settings.SEARCH_PREVIEW_SHOW_LOCATIONS) { if (checkPermission('stock_location') && user_settings.SEARCH_PREVIEW_SHOW_LOCATIONS) {
let filters = {}; let filters = {};
addSearchQuery('stocklocation', '{% trans "Stock Locations" %}', filters); addSearchQuery('stocklocation', '{% jstrans "Stock Locations" %}', filters);
} }
if (checkPermission('build') && user_settings.SEARCH_PREVIEW_SHOW_BUILD_ORDERS) { if (checkPermission('build') && user_settings.SEARCH_PREVIEW_SHOW_BUILD_ORDERS) {
@ -183,13 +183,13 @@ function updateSearch() {
part_detail: true part_detail: true
}; };
addSearchQuery('build', '{% trans "Build Orders" %}', filters); addSearchQuery('build', '{% jstrans "Build Orders" %}', filters);
} }
if ((checkPermission('sales_order') || checkPermission('purchase_order')) && user_settings.SEARCH_PREVIEW_SHOW_COMPANIES) { if ((checkPermission('sales_order') || checkPermission('purchase_order')) && user_settings.SEARCH_PREVIEW_SHOW_COMPANIES) {
let filters = {}; let filters = {};
addSearchQuery('company', '{% trans "Companies" %}', filters); addSearchQuery('company', '{% jstrans "Companies" %}', filters);
} }
if (checkPermission('purchase_order') && user_settings.SEARCH_PREVIEW_SHOW_PURCHASE_ORDERS) { if (checkPermission('purchase_order') && user_settings.SEARCH_PREVIEW_SHOW_PURCHASE_ORDERS) {
@ -202,7 +202,7 @@ function updateSearch() {
filters.outstanding = true; filters.outstanding = true;
} }
addSearchQuery('purchaseorder', '{% trans "Purchase Orders" %}', filters); addSearchQuery('purchaseorder', '{% jstrans "Purchase Orders" %}', filters);
} }
if (checkPermission('sales_order') && user_settings.SEARCH_PREVIEW_SHOW_SALES_ORDERS) { if (checkPermission('sales_order') && user_settings.SEARCH_PREVIEW_SHOW_SALES_ORDERS) {
@ -216,7 +216,7 @@ function updateSearch() {
filters.outstanding = true; filters.outstanding = true;
} }
addSearchQuery('salesorder', '{% trans "Sales Orders" %}', filters); addSearchQuery('salesorder', '{% jstrans "Sales Orders" %}', filters);
} }
if (checkPermission('return_order') && user_settings.SEARCH_PREVIEW_SHOW_RETURN_ORDERS) { if (checkPermission('return_order') && user_settings.SEARCH_PREVIEW_SHOW_RETURN_ORDERS) {
@ -229,14 +229,14 @@ function updateSearch() {
filters.outstanding = true; filters.outstanding = true;
} }
addSearchQuery('returnorder', '{% trans "Return Orders" %}', filters); addSearchQuery('returnorder', '{% jstrans "Return Orders" %}', filters);
} }
let ctx = $('#offcanvas-search').find('#search-context'); let ctx = $('#offcanvas-search').find('#search-context');
ctx.html(` ctx.html(`
<div class='alert alert-block alert-secondary'> <div class='alert alert-block alert-secondary'>
<span class='fas fa-spinner fa-spin'></span> <em>{% trans "Searching" %}</em> <span class='fas fa-spinner fa-spin'></span> <em>{% jstrans "Searching" %}</em>
</div> </div>
`); `);
@ -267,7 +267,7 @@ function updateSearch() {
} else { } else {
ctx.html(` ctx.html(`
<div class='alert alert-block alert-warning'> <div class='alert alert-block alert-warning'>
<span class='fas fa-exclamation-circle'></span> <em>{% trans "No results" %}</em> <span class='fas fa-exclamation-circle'></span> <em>{% jstrans "No results" %}</em>
</div> </div>
`); `);
} }
@ -289,7 +289,7 @@ function clearSearchResults() {
panel.find('#search-context').html(` panel.find('#search-context').html(`
<div class='alert alert-block alert-info'> <div class='alert alert-block alert-info'>
<span class='fas fa-search'></span> <em>{% trans "Enter search query" %}</em> <span class='fas fa-search'></span> <em>{% jstrans "Enter search query" %}</em>
</div> </div>
`); `);
@ -339,7 +339,7 @@ function addSearchResults(results, resultType, resultCount) {
let renderer = resultType.renderer; let renderer = resultType.renderer;
let renderParams = resultType.renderParams; let renderParams = resultType.renderParams;
let resultText = resultCount == 1 ? '{% trans "result" %}' : '{% trans "results" %}'; let resultText = resultCount == 1 ? '{% jstrans "result" %}' : '{% jstrans "results" %}';
// Add the result group to the panel // Add the result group to the panel
panel.find('#search-results').append(` panel.find('#search-results').append(`
@ -349,10 +349,10 @@ function addSearchResults(results, resultType, resultCount) {
<h5>${title}</h5><span class='float-right'><em><small>&nbsp;-&nbsp;${resultCount} ${resultText}</small></em></span> <h5>${title}</h5><span class='float-right'><em><small>&nbsp;-&nbsp;${resultCount} ${resultText}</small></em></span>
<span class='flex' style='flex-grow: 1;'></span> <span class='flex' style='flex-grow: 1;'></span>
<div class='search-result-group-buttons btn-group float-right' role='group'> <div class='search-result-group-buttons btn-group float-right' role='group'>
<button class='btn btn-outline-secondary' id='hide-results-${key}' title='{% trans "Minimize results" %}'> <button class='btn btn-outline-secondary' id='hide-results-${key}' title='{% jstrans "Minimize results" %}'>
<span class='fas fa-chevron-up'></span> <span class='fas fa-chevron-up'></span>
</button> </button>
<button class='btn btn-outline-secondary' id='remove-results-${key}' title='{% trans "Remove results" %}'> <button class='btn btn-outline-secondary' id='remove-results-${key}' title='{% jstrans "Remove results" %}'>
<span class='fas fa-times icon-red'></span> <span class='fas fa-times icon-red'></span>
</button> </button>
</div> </div>

File diff suppressed because it is too large Load Diff

View File

@ -21,7 +21,7 @@
// Construct a dynamic API filter for the "issued by" field // Construct a dynamic API filter for the "issued by" field
function constructIssuedByFilter() { function constructIssuedByFilter() {
return { return {
title: '{% trans "Issued By" %}', title: '{% jstrans "Issued By" %}',
options: function() { options: function() {
let users = {}; let users = {};
@ -45,7 +45,7 @@ function constructIssuedByFilter() {
// Construct a dynamic API filter for the "project" field // Construct a dynamic API filter for the "project" field
function constructProjectCodeFilter() { function constructProjectCodeFilter() {
return { return {
title: '{% trans "Project Code" %}', title: '{% jstrans "Project Code" %}',
options: function() { options: function() {
let project_codes = {}; let project_codes = {};
@ -71,7 +71,7 @@ function constructProjectCodeFilter() {
function constructHasProjectCodeFilter() { function constructHasProjectCodeFilter() {
return { return {
type: 'bool', type: 'bool',
title: '{% trans "Has project code" %}', title: '{% jstrans "Has project code" %}',
}; };
} }
@ -86,20 +86,20 @@ function getAttachmentFilters() {
function getReturnOrderFilters() { function getReturnOrderFilters() {
var filters = { var filters = {
status: { status: {
title: '{% trans "Order status" %}', title: '{% jstrans "Order status" %}',
options: returnOrderCodes options: returnOrderCodes
}, },
outstanding: { outstanding: {
type: 'bool', type: 'bool',
title: '{% trans "Outstanding" %}', title: '{% jstrans "Outstanding" %}',
}, },
overdue: { overdue: {
type: 'bool', type: 'bool',
title: '{% trans "Overdue" %}', title: '{% jstrans "Overdue" %}',
}, },
assigned_to_me: { assigned_to_me: {
type: 'bool', type: 'bool',
title: '{% trans "Assigned to me" %}', title: '{% jstrans "Assigned to me" %}',
}, },
}; };
@ -117,10 +117,10 @@ function getReturnOrderLineItemFilters() {
return { return {
received: { received: {
type: 'bool', type: 'bool',
title: '{% trans "Received" %}', title: '{% jstrans "Received" %}',
}, },
outcome: { outcome: {
title: '{% trans "Outcome" %}', title: '{% jstrans "Outcome" %}',
options: returnOrderLineItemCodes, options: returnOrderLineItemCodes,
} }
}; };
@ -132,19 +132,19 @@ function getVariantsTableFilters() {
return { return {
active: { active: {
type: 'bool', type: 'bool',
title: '{% trans "Active" %}', title: '{% jstrans "Active" %}',
}, },
template: { template: {
type: 'bool', type: 'bool',
title: '{% trans "Template" %}', title: '{% jstrans "Template" %}',
}, },
virtual: { virtual: {
type: 'bool', type: 'bool',
title: '{% trans "Virtual" %}', title: '{% jstrans "Virtual" %}',
}, },
trackable: { trackable: {
type: 'bool', type: 'bool',
title: '{% trans "Trackable" %}', title: '{% jstrans "Trackable" %}',
}, },
}; };
} }
@ -155,43 +155,43 @@ function getBOMTableFilters() {
return { return {
sub_part_trackable: { sub_part_trackable: {
type: 'bool', type: 'bool',
title: '{% trans "Trackable Part" %}', title: '{% jstrans "Trackable Part" %}',
}, },
sub_part_assembly: { sub_part_assembly: {
type: 'bool', type: 'bool',
title: '{% trans "Assembled Part" %}', title: '{% jstrans "Assembled Part" %}',
}, },
available_stock: { available_stock: {
type: 'bool', type: 'bool',
title: '{% trans "Has Available Stock" %}', title: '{% jstrans "Has Available Stock" %}',
}, },
on_order: { on_order: {
type: 'bool', type: 'bool',
title: '{% trans "On Order" %}', title: '{% jstrans "On Order" %}',
}, },
validated: { validated: {
type: 'bool', type: 'bool',
title: '{% trans "Validated" %}', title: '{% jstrans "Validated" %}',
}, },
inherited: { inherited: {
type: 'bool', type: 'bool',
title: '{% trans "Gets inherited" %}', title: '{% jstrans "Gets inherited" %}',
}, },
allow_variants: { allow_variants: {
type: 'bool', type: 'bool',
title: '{% trans "Allow Variant Stock" %}', title: '{% jstrans "Allow Variant Stock" %}',
}, },
optional: { optional: {
type: 'bool', type: 'bool',
title: '{% trans "Optional" %}', title: '{% jstrans "Optional" %}',
}, },
consumable: { consumable: {
type: 'bool', type: 'bool',
title: '{% trans "Consumable" %}', title: '{% jstrans "Consumable" %}',
}, },
has_pricing: { has_pricing: {
type: 'bool', type: 'bool',
title: '{% trans "Has Pricing" %}', title: '{% jstrans "Has Pricing" %}',
}, },
}; };
} }
@ -208,19 +208,19 @@ function getUsedInTableFilters() {
return { return {
'inherited': { 'inherited': {
type: 'bool', type: 'bool',
title: '{% trans "Gets inherited" %}', title: '{% jstrans "Gets inherited" %}',
}, },
'optional': { 'optional': {
type: 'bool', type: 'bool',
title: '{% trans "Optional" %}', title: '{% jstrans "Optional" %}',
}, },
'part_active': { 'part_active': {
type: 'bool', type: 'bool',
title: '{% trans "Active" %}', title: '{% jstrans "Active" %}',
}, },
'part_trackable': { 'part_trackable': {
type: 'bool', type: 'bool',
title: '{% trans "Trackable" %}', title: '{% jstrans "Trackable" %}',
}, },
}; };
} }
@ -231,19 +231,19 @@ function getStockLocationFilters() {
return { return {
cascade: { cascade: {
type: 'bool', type: 'bool',
title: '{% trans "Include sublocations" %}', title: '{% jstrans "Include sublocations" %}',
description: '{% trans "Include locations" %}', description: '{% jstrans "Include locations" %}',
}, },
structural: { structural: {
type: 'bool', type: 'bool',
title: '{% trans "Structural" %}', title: '{% jstrans "Structural" %}',
}, },
external: { external: {
type: 'bool', type: 'bool',
title: '{% trans "External" %}', title: '{% jstrans "External" %}',
}, },
location_type: { location_type: {
title: '{% trans "Location type" %}', title: '{% jstrans "Location type" %}',
options: function() { options: function() {
const locationTypes = {}; const locationTypes = {};
@ -264,7 +264,7 @@ function getStockLocationFilters() {
}, },
has_location_type: { has_location_type: {
type: 'bool', type: 'bool',
title: '{% trans "Has location type" %}' title: '{% jstrans "Has location type" %}'
}, },
}; };
} }
@ -275,16 +275,16 @@ function getPartCategoryFilters() {
return { return {
cascade: { cascade: {
type: 'bool', type: 'bool',
title: '{% trans "Include subcategories" %}', title: '{% jstrans "Include subcategories" %}',
description: '{% trans "Include subcategories" %}', description: '{% jstrans "Include subcategories" %}',
}, },
structural: { structural: {
type: 'bool', type: 'bool',
title: '{% trans "Structural" %}', title: '{% jstrans "Structural" %}',
}, },
starred: { starred: {
type: 'bool', type: 'bool',
title: '{% trans "Subscribed" %}', title: '{% jstrans "Subscribed" %}',
}, },
}; };
} }
@ -295,23 +295,23 @@ function getCustomerStockFilters() {
return { return {
serialized: { serialized: {
type: 'bool', type: 'bool',
title: '{% trans "Is Serialized" %}', title: '{% jstrans "Is Serialized" %}',
}, },
serial_gte: { serial_gte: {
title: '{% trans "Serial number GTE" %}', title: '{% jstrans "Serial number GTE" %}',
description: '{% trans "Serial number greater than or equal to" %}', description: '{% jstrans "Serial number greater than or equal to" %}',
}, },
serial_lte: { serial_lte: {
title: '{% trans "Serial number LTE" %}', title: '{% jstrans "Serial number LTE" %}',
description: '{% trans "Serial number less than or equal to" %}', description: '{% jstrans "Serial number less than or equal to" %}',
}, },
serial: { serial: {
title: '{% trans "Serial number" %}', title: '{% jstrans "Serial number" %}',
description: '{% trans "Serial number" %}', description: '{% jstrans "Serial number" %}',
}, },
batch: { batch: {
title: '{% trans "Batch" %}', title: '{% jstrans "Batch" %}',
description: '{% trans "Batch code" %}', description: '{% jstrans "Batch code" %}',
}, },
}; };
} }
@ -322,109 +322,109 @@ function getStockTableFilters() {
var filters = { var filters = {
active: { active: {
type: 'bool', type: 'bool',
title: '{% trans "Active parts" %}', title: '{% jstrans "Active parts" %}',
description: '{% trans "Show stock for active parts" %}', description: '{% jstrans "Show stock for active parts" %}',
}, },
assembly: { assembly: {
type: 'bool', type: 'bool',
title: '{% trans "Assembly" %}', title: '{% jstrans "Assembly" %}',
description: '{% trans "Part is an assembly" %}', description: '{% jstrans "Part is an assembly" %}',
}, },
allocated: { allocated: {
type: 'bool', type: 'bool',
title: '{% trans "Is allocated" %}', title: '{% jstrans "Is allocated" %}',
description: '{% trans "Item has been allocated" %}', description: '{% jstrans "Item has been allocated" %}',
}, },
available: { available: {
type: 'bool', type: 'bool',
title: '{% trans "Available" %}', title: '{% jstrans "Available" %}',
description: '{% trans "Stock is available for use" %}', description: '{% jstrans "Stock is available for use" %}',
}, },
cascade: { cascade: {
type: 'bool', type: 'bool',
title: '{% trans "Include sublocations" %}', title: '{% jstrans "Include sublocations" %}',
description: '{% trans "Include stock in sublocations" %}', description: '{% jstrans "Include stock in sublocations" %}',
}, },
depleted: { depleted: {
type: 'bool', type: 'bool',
title: '{% trans "Depleted" %}', title: '{% jstrans "Depleted" %}',
description: '{% trans "Show stock items which are depleted" %}', description: '{% jstrans "Show stock items which are depleted" %}',
}, },
in_stock: { in_stock: {
type: 'bool', type: 'bool',
title: '{% trans "In Stock" %}', title: '{% jstrans "In Stock" %}',
description: '{% trans "Show items which are in stock" %}', description: '{% jstrans "Show items which are in stock" %}',
}, },
is_building: { is_building: {
type: 'bool', type: 'bool',
title: '{% trans "In Production" %}', title: '{% jstrans "In Production" %}',
description: '{% trans "Show items which are in production" %}', description: '{% jstrans "Show items which are in production" %}',
}, },
include_variants: { include_variants: {
type: 'bool', type: 'bool',
title: '{% trans "Include Variants" %}', title: '{% jstrans "Include Variants" %}',
description: '{% trans "Include stock items for variant parts" %}', description: '{% jstrans "Include stock items for variant parts" %}',
}, },
installed: { installed: {
type: 'bool', type: 'bool',
title: '{% trans "Installed" %}', title: '{% jstrans "Installed" %}',
description: '{% trans "Show stock items which are installed in another item" %}', description: '{% jstrans "Show stock items which are installed in another item" %}',
}, },
sent_to_customer: { sent_to_customer: {
type: 'bool', type: 'bool',
title: '{% trans "Sent to customer" %}', title: '{% jstrans "Sent to customer" %}',
description: '{% trans "Show items which have been assigned to a customer" %}', description: '{% jstrans "Show items which have been assigned to a customer" %}',
}, },
serialized: { serialized: {
type: 'bool', type: 'bool',
title: '{% trans "Is Serialized" %}', title: '{% jstrans "Is Serialized" %}',
}, },
serial: { serial: {
title: '{% trans "Serial number" %}', title: '{% jstrans "Serial number" %}',
description: '{% trans "Serial number" %}', description: '{% jstrans "Serial number" %}',
}, },
serial_gte: { serial_gte: {
title: '{% trans "Serial number GTE" %}', title: '{% jstrans "Serial number GTE" %}',
description: '{% trans "Serial number greater than or equal to" %}', description: '{% jstrans "Serial number greater than or equal to" %}',
}, },
serial_lte: { serial_lte: {
title: '{% trans "Serial number LTE" %}', title: '{% jstrans "Serial number LTE" %}',
description: '{% trans "Serial number less than or equal to" %}', description: '{% jstrans "Serial number less than or equal to" %}',
}, },
status: { status: {
options: stockCodes, options: stockCodes,
title: '{% trans "Stock status" %}', title: '{% jstrans "Stock status" %}',
description: '{% trans "Stock status" %}', description: '{% jstrans "Stock status" %}',
}, },
has_batch: { has_batch: {
title: '{% trans "Has batch code" %}', title: '{% jstrans "Has batch code" %}',
type: 'bool', type: 'bool',
}, },
batch: { batch: {
title: '{% trans "Batch" %}', title: '{% jstrans "Batch" %}',
description: '{% trans "Batch code" %}', description: '{% jstrans "Batch code" %}',
}, },
tracked: { tracked: {
title: '{% trans "Tracked" %}', title: '{% jstrans "Tracked" %}',
description: '{% trans "Stock item is tracked by either batch code or serial number" %}', description: '{% jstrans "Stock item is tracked by either batch code or serial number" %}',
type: 'bool', type: 'bool',
}, },
has_purchase_price: { has_purchase_price: {
type: 'bool', type: 'bool',
title: '{% trans "Has purchase price" %}', title: '{% jstrans "Has purchase price" %}',
description: '{% trans "Show stock items which have a purchase price set" %}', description: '{% jstrans "Show stock items which have a purchase price set" %}',
}, },
expiry_date_lte: { expiry_date_lte: {
type: 'date', type: 'date',
title: '{% trans "Expiry Date before" %}', title: '{% jstrans "Expiry Date before" %}',
}, },
expiry_date_gte: { expiry_date_gte: {
type: 'date', type: 'date',
title: '{% trans "Expiry Date after" %}', title: '{% jstrans "Expiry Date after" %}',
}, },
external: { external: {
type: 'bool', type: 'bool',
title: '{% trans "External Location" %}', title: '{% jstrans "External Location" %}',
} }
}; };
@ -432,14 +432,14 @@ function getStockTableFilters() {
if (global_settings.STOCK_ENABLE_EXPIRY) { if (global_settings.STOCK_ENABLE_EXPIRY) {
filters.expired = { filters.expired = {
type: 'bool', type: 'bool',
title: '{% trans "Expired" %}', title: '{% jstrans "Expired" %}',
description: '{% trans "Show stock items which have expired" %}', description: '{% jstrans "Show stock items which have expired" %}',
}; };
filters.stale = { filters.stale = {
type: 'bool', type: 'bool',
title: '{% trans "Stale" %}', title: '{% jstrans "Stale" %}',
description: '{% trans "Show stock which is close to expiring" %}', description: '{% jstrans "Show stock which is close to expiring" %}',
}; };
} }
@ -453,11 +453,11 @@ function getStockTestTableFilters() {
return { return {
result: { result: {
type: 'bool', type: 'bool',
title: '{% trans "Test Passed" %}', title: '{% jstrans "Test Passed" %}',
}, },
include_installed: { include_installed: {
type: 'bool', type: 'bool',
title: '{% trans "Include Installed Items" %}', title: '{% jstrans "Include Installed Items" %}',
} }
}; };
} }
@ -474,7 +474,7 @@ function getPartTestTemplateFilters() {
return { return {
required: { required: {
type: 'bool', type: 'bool',
title: '{% trans "Required" %}', title: '{% jstrans "Required" %}',
}, },
}; };
} }
@ -485,19 +485,19 @@ function getPluginTableFilters() {
return { return {
active: { active: {
type: 'bool', type: 'bool',
title: '{% trans "Active" %}', title: '{% jstrans "Active" %}',
}, },
builtin: { builtin: {
type: 'bool', type: 'bool',
title: '{% trans "Builtin" %}', title: '{% jstrans "Builtin" %}',
}, },
sample: { sample: {
type: 'bool', type: 'bool',
title: '{% trans "Sample" %}', title: '{% jstrans "Sample" %}',
}, },
installed: { installed: {
type: 'bool', type: 'bool',
title: '{% trans "Installed" %}' title: '{% jstrans "Installed" %}'
}, },
}; };
} }
@ -508,23 +508,23 @@ function getBuildTableFilters() {
let filters = { let filters = {
status: { status: {
title: '{% trans "Build status" %}', title: '{% jstrans "Build status" %}',
options: buildCodes, options: buildCodes,
}, },
active: { active: {
type: 'bool', type: 'bool',
title: '{% trans "Active" %}', title: '{% jstrans "Active" %}',
}, },
overdue: { overdue: {
type: 'bool', type: 'bool',
title: '{% trans "Overdue" %}', title: '{% jstrans "Overdue" %}',
}, },
assigned_to_me: { assigned_to_me: {
type: 'bool', type: 'bool',
title: '{% trans "Assigned to me" %}', title: '{% jstrans "Assigned to me" %}',
}, },
assigned_to: { assigned_to: {
title: '{% trans "Responsible" %}', title: '{% jstrans "Responsible" %}',
options: function() { options: function() {
var ownersList = {}; var ownersList = {};
inventreeGet('{% url "api-owner-list" %}', {}, { inventreeGet('{% url "api-owner-list" %}', {}, {
@ -564,23 +564,23 @@ function getBuildLineTableFilters() {
return { return {
allocated: { allocated: {
type: 'bool', type: 'bool',
title: '{% trans "Allocated" %}', title: '{% jstrans "Allocated" %}',
}, },
available: { available: {
type: 'bool', type: 'bool',
title: '{% trans "Available" %}', title: '{% jstrans "Available" %}',
}, },
tracked: { tracked: {
type: 'bool', type: 'bool',
title: '{% trans "Tracked" %}', title: '{% jstrans "Tracked" %}',
}, },
consumable: { consumable: {
type: 'bool', type: 'bool',
title: '{% trans "Consumable" %}', title: '{% jstrans "Consumable" %}',
}, },
optional: { optional: {
type: 'bool', type: 'bool',
title: '{% trans "Optional" %}', title: '{% jstrans "Optional" %}',
}, },
}; };
} }
@ -591,14 +591,14 @@ function getPurchaseOrderLineItemFilters() {
return { return {
pending: { pending: {
type: 'bool', type: 'bool',
title: '{% trans "Pending" %}', title: '{% jstrans "Pending" %}',
}, },
received: { received: {
type: 'bool', type: 'bool',
title: '{% trans "Received" %}', title: '{% jstrans "Received" %}',
}, },
order_status: { order_status: {
title: '{% trans "Order status" %}', title: '{% jstrans "Order status" %}',
options: purchaseOrderCodes, options: purchaseOrderCodes,
}, },
}; };
@ -610,20 +610,20 @@ function getPurchaseOrderFilters() {
var filters = { var filters = {
status: { status: {
title: '{% trans "Order status" %}', title: '{% jstrans "Order status" %}',
options: purchaseOrderCodes, options: purchaseOrderCodes,
}, },
outstanding: { outstanding: {
type: 'bool', type: 'bool',
title: '{% trans "Outstanding" %}', title: '{% jstrans "Outstanding" %}',
}, },
overdue: { overdue: {
type: 'bool', type: 'bool',
title: '{% trans "Overdue" %}', title: '{% jstrans "Overdue" %}',
}, },
assigned_to_me: { assigned_to_me: {
type: 'bool', type: 'bool',
title: '{% trans "Assigned to me" %}', title: '{% jstrans "Assigned to me" %}',
}, },
}; };
@ -641,7 +641,7 @@ function getSalesOrderAllocationFilters() {
return { return {
outstanding: { outstanding: {
type: 'bool', type: 'bool',
title: '{% trans "Outstanding" %}', title: '{% jstrans "Outstanding" %}',
} }
}; };
} }
@ -651,20 +651,20 @@ function getSalesOrderAllocationFilters() {
function getSalesOrderFilters() { function getSalesOrderFilters() {
var filters = { var filters = {
status: { status: {
title: '{% trans "Order status" %}', title: '{% jstrans "Order status" %}',
options: salesOrderCodes, options: salesOrderCodes,
}, },
outstanding: { outstanding: {
type: 'bool', type: 'bool',
title: '{% trans "Outstanding" %}', title: '{% jstrans "Outstanding" %}',
}, },
overdue: { overdue: {
type: 'bool', type: 'bool',
title: '{% trans "Overdue" %}', title: '{% jstrans "Overdue" %}',
}, },
assigned_to_me: { assigned_to_me: {
type: 'bool', type: 'bool',
title: '{% trans "Assigned to me" %}', title: '{% jstrans "Assigned to me" %}',
}, },
}; };
@ -682,7 +682,7 @@ function getSalesOrderLineItemFilters() {
return { return {
completed: { completed: {
type: 'bool', type: 'bool',
title: '{% trans "Completed" %}', title: '{% jstrans "Completed" %}',
}, },
}; };
} }
@ -693,7 +693,7 @@ function getSupplierPartFilters() {
return { return {
active: { active: {
type: 'bool', type: 'bool',
title: '{% trans "Active parts" %}', title: '{% jstrans "Active parts" %}',
}, },
}; };
} }
@ -704,75 +704,75 @@ function getPartTableFilters() {
return { return {
cascade: { cascade: {
type: 'bool', type: 'bool',
title: '{% trans "Include subcategories" %}', title: '{% jstrans "Include subcategories" %}',
description: '{% trans "Include parts in subcategories" %}', description: '{% jstrans "Include parts in subcategories" %}',
}, },
active: { active: {
type: 'bool', type: 'bool',
title: '{% trans "Active" %}', title: '{% jstrans "Active" %}',
description: '{% trans "Show active parts" %}', description: '{% jstrans "Show active parts" %}',
}, },
assembly: { assembly: {
type: 'bool', type: 'bool',
title: '{% trans "Assembly" %}', title: '{% jstrans "Assembly" %}',
}, },
unallocated_stock: { unallocated_stock: {
type: 'bool', type: 'bool',
title: '{% trans "Available stock" %}', title: '{% jstrans "Available stock" %}',
}, },
component: { component: {
type: 'bool', type: 'bool',
title: '{% trans "Component" %}', title: '{% jstrans "Component" %}',
}, },
has_units: { has_units: {
type: 'bool', type: 'bool',
title: '{% trans "Has Units" %}', title: '{% jstrans "Has Units" %}',
description: '{% trans "Part has defined units" %}', description: '{% jstrans "Part has defined units" %}',
}, },
has_ipn: { has_ipn: {
type: 'bool', type: 'bool',
title: '{% trans "Has IPN" %}', title: '{% jstrans "Has IPN" %}',
description: '{% trans "Part has internal part number" %}', description: '{% jstrans "Part has internal part number" %}',
}, },
has_stock: { has_stock: {
type: 'bool', type: 'bool',
title: '{% trans "In stock" %}', title: '{% jstrans "In stock" %}',
}, },
low_stock: { low_stock: {
type: 'bool', type: 'bool',
title: '{% trans "Low stock" %}', title: '{% jstrans "Low stock" %}',
}, },
purchaseable: { purchaseable: {
type: 'bool', type: 'bool',
title: '{% trans "Purchasable" %}', title: '{% jstrans "Purchasable" %}',
}, },
salable: { salable: {
type: 'bool', type: 'bool',
title: '{% trans "Salable" %}', title: '{% jstrans "Salable" %}',
}, },
starred: { starred: {
type: 'bool', type: 'bool',
title: '{% trans "Subscribed" %}', title: '{% jstrans "Subscribed" %}',
}, },
stocktake: { stocktake: {
type: 'bool', type: 'bool',
title: '{% trans "Has stocktake entries" %}', title: '{% jstrans "Has stocktake entries" %}',
}, },
is_template: { is_template: {
type: 'bool', type: 'bool',
title: '{% trans "Template" %}', title: '{% jstrans "Template" %}',
}, },
trackable: { trackable: {
type: 'bool', type: 'bool',
title: '{% trans "Trackable" %}', title: '{% jstrans "Trackable" %}',
}, },
virtual: { virtual: {
type: 'bool', type: 'bool',
title: '{% trans "Virtual" %}', title: '{% jstrans "Virtual" %}',
}, },
has_pricing: { has_pricing: {
type: 'bool', type: 'bool',
title: '{% trans "Has Pricing" %}', title: '{% jstrans "Has Pricing" %}',
}, },
}; };
} }
@ -789,15 +789,15 @@ function getCompanyFilters() {
return { return {
is_manufacturer: { is_manufacturer: {
type: 'bool', type: 'bool',
title: '{% trans "Manufacturer" %}', title: '{% jstrans "Manufacturer" %}',
}, },
is_supplier: { is_supplier: {
type: 'bool', type: 'bool',
title: '{% trans "Supplier" %}', title: '{% jstrans "Supplier" %}',
}, },
is_customer: { is_customer: {
type: 'bool', type: 'bool',
title: '{% trans "Customer" %}', title: '{% jstrans "Customer" %}',
}, },
}; };
} }
@ -814,15 +814,15 @@ function getPartParameterTemplateFilters() {
return { return {
checkbox: { checkbox: {
type: 'bool', type: 'bool',
title: '{% trans "Checkbox" %}', title: '{% jstrans "Checkbox" %}',
}, },
has_choices: { has_choices: {
type: 'bool', type: 'bool',
title: '{% trans "Has Choices" %}', title: '{% jstrans "Has Choices" %}',
}, },
has_units: { has_units: {
type: 'bool', type: 'bool',
title: '{% trans "Has Units" %}', title: '{% jstrans "Has Units" %}',
} }
}; };
} }

View File

@ -89,7 +89,7 @@ function constructOrderTableButtons(options={}) {
// Calendar view button // Calendar view button
if (!options.disableCalendarView) { if (!options.disableCalendarView) {
buttons.push({ buttons.push({
html: `<button type='button' name='${idx++}' class='btn ${class_calendar}' title='{% trans "Display calendar view" %}'><span class='fas fa-calendar-alt'></span></button>`, html: `<button type='button' name='${idx++}' class='btn ${class_calendar}' title='{% jstrans "Display calendar view" %}'><span class='fas fa-calendar-alt'></span></button>`,
event: function() { event: function() {
buttonCallback('calendar'); buttonCallback('calendar');
} }
@ -99,7 +99,7 @@ function constructOrderTableButtons(options={}) {
// List view button // List view button
if (!options.disableListView) { if (!options.disableListView) {
buttons.push({ buttons.push({
html: `<button type='button' name='${idx++}' class='btn ${class_list}' title='{% trans "Display list view" %}'><span class='fas fa-th-list'></span></button>`, html: `<button type='button' name='${idx++}' class='btn ${class_list}' title='{% jstrans "Display list view" %}'><span class='fas fa-th-list'></span></button>`,
event: function() { event: function() {
buttonCallback('list'); buttonCallback('list');
} }
@ -109,7 +109,7 @@ function constructOrderTableButtons(options={}) {
// Tree view button // Tree view button
if (!options.disableTreeView) { if (!options.disableTreeView) {
buttons.push({ buttons.push({
html: `<button type='button' name='${idx++}' class='btn ${class_tree}' title='{% trans "Display tree view" %}'><span class='fas fa-sitemap'></span></button>`, html: `<button type='button' name='${idx++}' class='btn ${class_tree}' title='{% jstrans "Display tree view" %}'><span class='fas fa-sitemap'></span></button>`,
event: function() { event: function() {
buttonCallback('tree'); buttonCallback('tree');
} }
@ -127,13 +127,13 @@ function constructExpandCollapseButtons(table, idx=0) {
return [ return [
{ {
html: `<button type='button' name='${idx++}' class='btn btn-outline-secondary' title='{% trans "Expand all rows" %}'><span class='fas fa-expand'></span></button>`, html: `<button type='button' name='${idx++}' class='btn btn-outline-secondary' title='{% jstrans "Expand all rows" %}'><span class='fas fa-expand'></span></button>`,
event: function() { event: function() {
$(table).bootstrapTable('expandAllRows'); $(table).bootstrapTable('expandAllRows');
} }
}, },
{ {
html: `<button type='button' name='${idx++}' class='btn btn-outline-secondary' title='{% trans "Collapse all rows" %}'><span class='fas fa-compress'></span></button>`, html: `<button type='button' name='${idx++}' class='btn btn-outline-secondary' title='{% jstrans "Collapse all rows" %}'><span class='fas fa-compress'></span></button>`,
event: function() { event: function() {
$(table).bootstrapTable('collapseAllRows'); $(table).bootstrapTable('collapseAllRows');
} }
@ -183,11 +183,11 @@ function downloadTableData(table, opts={}) {
url += '?'; url += '?';
constructFormBody({}, { constructFormBody({}, {
title: opts.title || '{% trans "Export Table Data" %}', title: opts.title || '{% jstrans "Export Table Data" %}',
fields: { fields: {
format: { format: {
label: '{% trans "Format" %}', label: '{% jstrans "Format" %}',
help_text: '{% trans "Select File Format" %}', help_text: '{% jstrans "Select File Format" %}',
required: true, required: true,
type: 'choice', type: 'choice',
value: 'csv', value: 'csv',
@ -526,39 +526,39 @@ function customGroupSorter(sortName, sortOrder, sortData) {
$.fn.bootstrapTable.locales['en-US-custom'] = { $.fn.bootstrapTable.locales['en-US-custom'] = {
formatLoadingMessage: function() { formatLoadingMessage: function() {
return '{% trans "Loading data" %}'; return '{% jstrans "Loading data" %}';
}, },
formatRecordsPerPage: function(pageNumber) { formatRecordsPerPage: function(pageNumber) {
return `${pageNumber} {% trans "rows per page" %}`; return `${pageNumber} {% jstrans "rows per page" %}`;
}, },
formatShowingRows: function(pageFrom, pageTo, totalRows) { formatShowingRows: function(pageFrom, pageTo, totalRows) {
if (totalRows === undefined || isNaN(totalRows)) { if (totalRows === undefined || isNaN(totalRows)) {
return '{% trans "Showing all rows" %}'; return '{% jstrans "Showing all rows" %}';
} else { } else {
return `{% trans "Showing" %} ${pageFrom} {% trans "to" %} ${pageTo} {% trans "of" %} ${totalRows} {% trans "rows" %}`; return `{% jstrans "Showing" %} ${pageFrom} {% jstrans "to" %} ${pageTo} {% jstrans "of" %} ${totalRows} {% jstrans "rows" %}`;
} }
}, },
formatSearch: function() { formatSearch: function() {
return '{% trans "Search" %}'; return '{% jstrans "Search" %}';
}, },
formatNoMatches: function() { formatNoMatches: function() {
return '{% trans "No matching results" %}'; return '{% jstrans "No matching results" %}';
}, },
formatPaginationSwitch: function() { formatPaginationSwitch: function() {
return '{% trans "Hide/Show pagination" %}'; return '{% jstrans "Hide/Show pagination" %}';
}, },
formatRefresh: function() { formatRefresh: function() {
return '{% trans "Refresh" %}'; return '{% jstrans "Refresh" %}';
}, },
formatToggle: function() { formatToggle: function() {
return '{% trans "Toggle" %}'; return '{% jstrans "Toggle" %}';
}, },
formatColumns: function() { formatColumns: function() {
return '{% trans "Columns" %}'; return '{% jstrans "Columns" %}';
}, },
formatAllRows: function() { formatAllRows: function() {
return '{% trans "All" %}'; return '{% jstrans "All" %}';
}, },
}; };

View File

@ -51,6 +51,7 @@ def check_prohibited_tags(data):
'for', 'for',
'endfor', 'endfor',
'trans', 'trans',
'jstrans',
'load', 'load',
'include', 'include',
'url', 'url',
@ -89,18 +90,18 @@ for filename in pathlib.Path(js_dynamic_dir).rglob('*.js'):
with open(filename, 'r') as js_file: with open(filename, 'r') as js_file:
data = js_file.readlines() data = js_file.readlines()
pattern = r'{% trans ' invalid_tags = ['trans', 'jstrans']
err_count = 0 err_count = 0
for idx, line in enumerate(data): for idx, line in enumerate(data):
for tag in invalid_tags:
tag = '{% ' + tag
if tag in line:
err_count += 1
results = re.findall(pattern, line) print(f" > Error on line {idx+1}: Prohibited tag '{tag}' found")
if len(results) > 0:
errors += 1
print(f" > prohibited {{% trans %}} tag found at line {idx + 1}")
if errors > 0: if errors > 0:
print(f"Found {errors} incorrect template tags") print(f"Found {errors} incorrect template tags")