Remove {% jstrans %} tag (#6298)

* Revert {% jstrans %} for .js files

- file extension is enough

* Remove custom jstrans templatetag

* Replace jstrans calls for .html files

- Add "escape=True"

* Allow for custom "escape" argument

* Update custom trans tag

- Cannot pass kwargs in the same way
- Add the "escape" attribute

* Update js translations in html files
This commit is contained in:
Oliver 2024-01-21 22:47:47 +11:00 committed by GitHub
parent c5d0902379
commit 4b5fcd4e69
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
49 changed files with 1654 additions and 1664 deletions

View File

@ -62,7 +62,7 @@ class CustomTranslateNode(TranslateNode):
@register.tag('translate') @register.tag('translate')
@register.tag('trans') @register.tag('trans')
def do_translate(parser, token, escape=False): def do_translate(parser, token):
"""Custom translation function. """Custom translation function.
- Lifted from https://github.com/django/django/blob/main/django/templatetags/i18n.py. - Lifted from https://github.com/django/django/blob/main/django/templatetags/i18n.py.
@ -74,6 +74,7 @@ def do_translate(parser, token, escape=False):
message_string = parser.compile_filter(bits[1]) message_string = parser.compile_filter(bits[1])
remaining = bits[2:] remaining = bits[2:]
escape = False
noop = False noop = False
asvar = None asvar = None
message_context = None message_context = None
@ -110,6 +111,8 @@ def do_translate(parser, token, escape=False):
"No argument provided to the '%s' tag for the as option." % bits[0] "No argument provided to the '%s' tag for the as option." % bits[0]
) )
asvar = value asvar = value
elif option == 'escape':
escape = True
else: else:
raise TemplateSyntaxError( raise TemplateSyntaxError(
"Unknown argument for '%s' tag: '%s'. The only options " "Unknown argument for '%s' tag: '%s'. The only options "
@ -123,18 +126,6 @@ def do_translate(parser, token, escape=False):
) )
@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
register.tag('blocktrans', django.templatetags.i18n.do_block_translate) register.tag('blocktrans', django.templatetags.i18n.do_block_translate)
register.tag('blocktranslate', django.templatetags.i18n.do_block_translate) register.tag('blocktranslate', django.templatetags.i18n.do_block_translate)

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: '{% jstrans "Delete Build Order" %}', title: '{% trans "Delete Build Order" escape %}',
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(
'{% jstrans "Build Order QR Code" %}', '{% trans "Build Order QR Code" escape %}',
'{"build": {{ build.pk }} }' '{"build": {{ build.pk }} }'
); );
}); });
@ -292,7 +292,7 @@ src="{% static 'img/blank_image.png' %}"
build: {{ build.pk }}, build: {{ build.pk }},
}, },
{ {
title: '{% jstrans "Link Barcode to Build Order" %}', title: '{% trans "Link Barcode to Build Order" escape %}',
} }
); );
}); });

View File

@ -419,8 +419,8 @@ function allocateSelectedLines() {
if (unallocated_lines.length == 0) { if (unallocated_lines.length == 0) {
showAlertDialog( showAlertDialog(
'{% jstrans "Allocation Complete" %}', '{% trans "Allocation Complete" escape %}',
'{% jstrans "All lines have been fully allocated" %}', '{% trans "All lines have been fully allocated" escape %}',
); );
} 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: '{% jstrans "Delete Company" %}', title: '{% trans "Delete Company" escape %}',
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(
'{% jstrans "Remove Image" %}', '{% trans "Remove Image" escape %}',
'{% jstrans "Remove associated image from this company" %}', '{% trans "Remove associated image from this company" escape %}',
{ {
accept_text: '{% jstrans "Remove" %}', accept_text: '{% trans "Remove" escape %}',
submitClass: 'danger', submitClass: 'danger',
accept: function() { accept: function() {
inventreePut( inventreePut(
@ -234,7 +234,7 @@
fields: { fields: {
image: {}, image: {},
}, },
title: '{% jstrans "Upload Image" %}', title: '{% trans "Upload Image" escape %}',
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: '{% jstrans "Download Image" %}', title: '{% trans "Download Image" escape %}',
fields: { fields: {
remote_image: {}, remote_image: {},
}, },

View File

@ -203,7 +203,7 @@ $('#parameter-create').click(function() {
hidden: true, hidden: true,
} }
}, },
title: '{% jstrans "Add Parameter" %}', title: '{% trans "Add Parameter" escape %}',
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(
'{% jstrans "Supplier Part QR Code" %}', '{% trans "Supplier Part QR Code" escape %}',
'{"supplierpart": {{ part.pk }} }' '{"supplierpart": {{ part.pk }} }'
); );
}); });
@ -284,7 +284,7 @@ $("#barcode-link").click(function() {
supplierpart: {{ part.pk }}, supplierpart: {{ part.pk }},
}, },
{ {
title: '{% jstrans "Link Barcode to Supplier Part" %}', title: '{% trans "Link Barcode to Supplier Part" escape %}',
} }
); );
}); });
@ -356,7 +356,7 @@ $('#update-part-availability').click(function() {
fields: { fields: {
available: {}, available: {},
}, },
title: '{% jstrans "Update Part Availability" %}', title: '{% trans "Update Part Availability" escape %}',
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(
'{% jstrans "Purchase Order QR Code" %}', '{% trans "Purchase Order QR Code" escape %}',
'{"purchaseorder": {{ order.pk }} }' '{"purchaseorder": {{ order.pk }} }'
); );
}); });
@ -327,7 +327,7 @@ $("#barcode-link").click(function() {
purchaseorder: {{ order.pk }}, purchaseorder: {{ order.pk }},
}, },
{ {
title: '{% jstrans "Link Barcode to Purchase Order" %}', title: '{% trans "Link Barcode to Purchase Order" escape %}',
} }
); );
}); });

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(
'{% jstrans "Return Order QR Code" %}', '{% trans "Return Order QR Code" escape %}',
'{"returnorder": {{ order.pk }} }' '{"returnorder": {{ order.pk }} }'
); );
}); });
@ -272,7 +272,7 @@ $("#barcode-link").click(function() {
returnorder: {{ order.pk }}, returnorder: {{ order.pk }},
}, },
{ {
title: '{% jstrans "Link Barcode to Return Order" %}', title: '{% trans "Link Barcode to Return Order" escape %}',
} }
); );
}); });

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(
'{% jstrans "Sales Order QR Code" %}', '{% trans "Sales Order QR Code" escape %}',
'{"salesorder": {{ order.pk }} }' '{"salesorder": {{ order.pk }} }'
); );
}); });
@ -321,7 +321,7 @@ $("#barcode-link").click(function() {
salesorder: {{ order.pk }}, salesorder: {{ order.pk }},
}, },
{ {
title: '{% jstrans "Link Barcode to Sales Order" %}', title: '{% trans "Link Barcode to Sales Order" escape %}',
} }
); );
}); });

View File

@ -656,7 +656,7 @@
value: {{ part.pk }}, value: {{ part.pk }},
}, },
part_2: { part_2: {
label: '{% jstrans "Related Part" %}', label: '{% trans "Related Part" escape %}',
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: '{% jstrans "Add Related Part" %}', title: '{% trans "Add Related Part" escape %}',
refreshTable: '#related-parts-table', refreshTable: '#related-parts-table',
}); });
}); });
@ -749,7 +749,7 @@
fields: partTestTemplateFields({ fields: partTestTemplateFields({
part: {{ part.pk }} part: {{ part.pk }}
}), }),
title: '{% jstrans "Add Test Result Template" %}', title: '{% trans "Add Test Result Template" escape %}',
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(
'{% jstrans "Part QR Code" %}', '{% trans "Part QR Code" escape %}',
'{"part": {{ part.pk }} }', '{"part": {{ part.pk }} }',
); );
}); });
@ -458,7 +458,7 @@
part: {{ part.pk }}, part: {{ part.pk }},
}, },
{ {
title: '{% jstrans "Link Barcode to Part" %}', title: '{% trans "Link Barcode to Part" escape %}',
} }
); );
}); });
@ -509,7 +509,7 @@
launchModalForm( launchModalForm(
"{% url 'part-pricing' part.id %}", "{% url 'part-pricing' part.id %}",
{ {
submit_text: '{% jstrans "Calculate" %}', submit_text: '{% trans "Calculate" escape %}',
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(
'{% jstrans "Remove Image" %}', '{% trans "Remove Image" escape %}',
'{% jstrans "Remove associated image from this part" %}', '{% trans "Remove associated image from this part" escape %}',
{ {
accept_text: '{% jstrans "Remove" %}', accept_text: '{% trans "Remove" escape %}',
submitClass: 'danger', submitClass: 'danger',
accept: function() { accept: function() {
inventreePut( inventreePut(
@ -557,7 +557,7 @@
fields: { fields: {
image: {}, image: {},
}, },
title: '{% jstrans "Upload Image" %}', title: '{% trans "Upload Image" escape %}',
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 '{% jstrans "No matching images found" %}'; return '{% trans "No matching images found" escape %}';
}, },
columns: [ columns: [
{ {
@ -611,7 +611,7 @@
'{% url "api-part-detail" part.pk %}', '{% url "api-part-detail" part.pk %}',
{ {
method: 'PATCH', method: 'PATCH',
title: '{% jstrans "Download Image" %}', title: '{% trans "Download Image" escape %}',
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('{% jstrans "Hide Part Details" %}'); $('#toggle-details-button').html('{% trans "Hide Part Details" escape %}');
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('{% jstrans "Show Part Details" %}'); $('#toggle-details-button').html('{% trans "Show Part Details" escape %}');
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: '{% jstrans "Update Pricing" %}', title: '{% trans "Update Pricing" escape %}',
fields: { fields: {
override_min: {}, override_min: {},
override_min_currency: {}, override_min_currency: {},

View File

@ -276,7 +276,7 @@
}, },
multi_delete: true, multi_delete: true,
method: 'DELETE', method: 'DELETE',
title: '{% jstrans "Delete Test Data" %}', title: '{% trans "Delete Test Data" escape %}',
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: '{% jstrans "Add Test Result" %}', title: '{% trans "Add Test Result" escape %}',
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: '{% jstrans "stock item" %}', singular_name: '{% trans "stock item" escape %}',
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: '{% jstrans "Edit Stock Status" %}', title: '{% trans "Edit Stock Status" escape %}',
}); });
}); });
@ -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(
'{% jstrans "Stock Item QR Code" %}', '{% trans "Stock Item QR Code" escape %}',
'{"stockitem": {{ item.pk }} }', '{"stockitem": {{ item.pk }} }',
); );
}); });
@ -549,7 +549,7 @@ $("#barcode-link").click(function() {
stockitem: {{ item.pk }}, stockitem: {{ item.pk }},
}, },
{ {
title: '{% jstrans "Link Barcode to Stock Item" %}', title: '{% trans "Link Barcode to Stock Item" escape %}',
} }
); );
}); });
@ -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: '{% jstrans "Convert Stock Item" %}', title: '{% trans "Convert Stock Item" escape %}',
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: '{% jstrans "Return to Stock" %}', title: '{% trans "Return to Stock" escape %}',
reload: true, reload: true,
}); });

View File

@ -286,7 +286,7 @@
printLabels({ printLabels({
items: locs, items: locs,
singular_name: '{% jstrans "stock location" %}', singular_name: '{% trans "stock location" escape %}',
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(
'{% jstrans "Scanned stock container into this location" %}', '{% trans "Scanned stock container into this location" escape %}',
{ {
style: 'success', style: 'success',
} }
@ -387,7 +387,7 @@
{% if barcodes %} {% if barcodes %}
$('#show-qr-code').click(function() { $('#show-qr-code').click(function() {
showQRDialog( showQRDialog(
'{% jstrans "Stock Location QR Code" %}', '{% trans "Stock Location QR Code" escape %}',
'{"stocklocation": {{ location.pk }} }' '{"stocklocation": {{ location.pk }} }'
); );
}); });
@ -398,7 +398,7 @@
stocklocation: {{ location.pk }}, stocklocation: {{ location.pk }},
}, },
{ {
title: '{% jstrans "Link Barcode to Stock Location" %}', title: '{% trans "Link Barcode to Stock Location" escape %}',
} }
); );
}); });

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('{% jstrans "Parts" %}'); addHeaderTitle('{% trans "Parts" escape %}');
{% if setting_part_starred %} {% if setting_part_starred %}
addHeaderAction('starred-parts', '{% jstrans "Subscribed Parts" %}', 'fa-bell'); addHeaderAction('starred-parts', '{% trans "Subscribed Parts" escape %}', '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', '{% jstrans "Subscribed Categories" %}', 'fa-bell'); addHeaderAction('starred-categories', '{% trans "Subscribed Categories" escape %}', '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', '{% jstrans "Latest Parts" %}', 'fa-newspaper'); addHeaderAction('latest-parts', '{% trans "Latest Parts" escape %}', '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', '{% jstrans "BOM Waiting Validation" %}', 'fa-times-circle'); addHeaderAction('bom-validation', '{% trans "BOM Waiting Validation" escape %}', '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', '{% jstrans "Recently Updated" %}', 'fa-clock'); addHeaderAction('recently-updated-stock', '{% trans "Recently Updated" escape %}', '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', '{% jstrans "Low Stock" %}', 'fa-flag'); addHeaderAction('low-stock', '{% trans "Low Stock" escape %}', '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', '{% jstrans "Depleted Stock" %}', 'fa-times'); addHeaderAction('depleted-stock', '{% trans "Depleted Stock" escape %}', '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', '{% jstrans "Required for Build Orders" %}', 'fa-bullhorn'); addHeaderAction('stock-to-build', '{% trans "Required for Build Orders" escape %}', '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', '{% jstrans "Expired Stock" %}', 'fa-calendar-times'); addHeaderAction('expired-stock', '{% trans "Expired Stock" escape %}', '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', '{% jstrans "Stale Stock" %}', 'fa-stopwatch'); addHeaderAction('stale-stock', '{% trans "Stale Stock" escape %}', '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('{% jstrans "Build Orders" %}'); addHeaderTitle('{% trans "Build Orders" escape %}');
{% if setting_build_pending %} {% if setting_build_pending %}
addHeaderAction('build-pending', '{% jstrans "Build Orders In Progress" %}', 'fa-cogs'); addHeaderAction('build-pending', '{% trans "Build Orders In Progress" escape %}', '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', '{% jstrans "Overdue Build Orders" %}', 'fa-calendar-times'); addHeaderAction('build-overdue', '{% trans "Overdue Build Orders" escape %}', '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('{% jstrans "Purchase Orders" %}'); addHeaderTitle('{% trans "Purchase Orders" escape %}');
{% if setting_po_outstanding %} {% if setting_po_outstanding %}
addHeaderAction('po-outstanding', '{% jstrans "Outstanding Purchase Orders" %}', 'fa-sign-in-alt'); addHeaderAction('po-outstanding', '{% trans "Outstanding Purchase Orders" escape %}', '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', '{% jstrans "Overdue Purchase Orders" %}', 'fa-calendar-times'); addHeaderAction('po-overdue', '{% trans "Overdue Purchase Orders" escape %}', '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('{% jstrans "Sales Orders" %}'); addHeaderTitle('{% trans "Sales Orders" escape %}');
{% if setting_so_outstanding %} {% if setting_so_outstanding %}
addHeaderAction('so-outstanding', '{% jstrans "Outstanding Sales Orders" %}', 'fa-sign-out-alt'); addHeaderAction('so-outstanding', '{% trans "Outstanding Sales Orders" escape %}', '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', '{% jstrans "Overdue Sales Orders" %}', 'fa-calendar-times'); addHeaderAction('so-overdue', '{% trans "Overdue Sales Orders" escape %}', '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', '{% jstrans "Pending Shipments" %}', 'fa-truck-loading'); addHeaderAction('so-shipments', '{% trans "Pending Shipments" escape %}', '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('{% jstrans "InvenTree News" %}'); addHeaderTitle('{% trans "InvenTree News" escape %}');
addHeaderAction('news', '{% jstrans "Current News" %}', 'fa-newspaper'); addHeaderAction('news', '{% trans "Current News" escape %}', '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 '{% jstrans "No unread notifications found" %}'; }, no_matches: function() { return '{% trans "No unread notifications found" escape %}'; },
}); });
$("#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 '{% jstrans "No notification history found" %}'; }, no_matches: function() { return '{% trans "No notification history found" escape %}'; },
}, 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: '{% jstrans "Delete Notifications" %}', title: '{% trans "Delete Notifications" escape %}',
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: '{% jstrans "Delete Notification" %}', title: '{% trans "Delete Notification" escape %}',
onSuccess: function(data) { onSuccess: function(data) {
updateNotificationTables(); updateNotificationTables();
} }

View File

@ -79,9 +79,9 @@
} }
{% if roles.part.view %} {% if roles.part.view %}
addItemTitle('{% jstrans "Part" %}'); addItemTitle('{% trans "Part" escape %}');
addItem('part', '{% jstrans "Parts" %}', 'fa-shapes'); addItem('part', '{% trans "Parts" escape %}', 'fa-shapes');
loadPartTable("#table-part", loadPartTable("#table-part",
"{% url 'api-part-list' %}", "{% url 'api-part-list' %}",
@ -94,7 +94,7 @@
} }
); );
addItem('category', '{% jstrans "Part Categories" %}', 'fa-sitemap'); addItem('category', '{% trans "Part Categories" escape %}', 'fa-sitemap');
loadPartCategoryTable($("#table-category"), { loadPartCategoryTable($("#table-category"), {
params: { params: {
@ -102,7 +102,7 @@
} }
}); });
addItem('manufacturer-part', '{% jstrans "Manufacturer Parts" %}', 'fa-toolbox'); addItem('manufacturer-part', '{% trans "Manufacturer Parts" escape %}', 'fa-toolbox');
loadManufacturerPartTable( loadManufacturerPartTable(
"#table-manufacturer-part", "#table-manufacturer-part",
@ -117,7 +117,7 @@
} }
); );
addItem('supplier-part', '{% jstrans "Supplier Parts" %}', 'fa-pallet'); addItem('supplier-part', '{% trans "Supplier Parts" escape %}', 'fa-pallet');
loadSupplierPartTable( loadSupplierPartTable(
"#table-supplier-part", "#table-supplier-part",
@ -136,9 +136,9 @@
{% if roles.build.view %} {% if roles.build.view %}
addItemTitle('{% jstrans "Build" %}'); addItemTitle('{% trans "Build" escape %}');
addItem('build-order', '{% jstrans "Build Orders" %}', 'fa-tools'); addItem('build-order', '{% trans "Build Orders" escape %}', '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('{% jstrans "Stock" %}'); addItemTitle('{% trans "Stock" escape %}');
addItem('stock', '{% jstrans "Stock Items" %}', 'fa-boxes'); addItem('stock', '{% trans "Stock Items" escape %}', 'fa-boxes');
loadStockTable($('#table-stock'), { loadStockTable($('#table-stock'), {
filterKey: 'stocksearch', filterKey: 'stocksearch',
@ -163,7 +163,7 @@
} }
}); });
addItem('location', '{% jstrans "Stock Locations" %}', 'fa-map-marker-alt'); addItem('location', '{% trans "Stock Locations" escape %}', '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('{% jstrans "Company" %}'); addItemTitle('{% trans "Company" escape %}');
addItem('manufacturer', '{% jstrans "Manufacturers" %}', 'fa-industry'); addItem('manufacturer', '{% trans "Manufacturers" escape %}', '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', '{% jstrans "Suppliers" %}', 'fa-building'); addItem('supplier', '{% trans "Suppliers" escape %}', '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', '{% jstrans "Purchase Orders" %}', 'fa-shopping-cart'); addItem('purchase-order', '{% trans "Purchase Orders" escape %}', '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', '{% jstrans "Customers" %}', 'fa-user-tie'); addItem('customer', '{% trans "Customers" escape %}', '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', '{% jstrans "Sales Orders" %}', 'fa-truck'); addItem('sales-orders', '{% trans "Sales Orders" escape %}', '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 = '{% jstrans "Edit Plugin Setting" %}'; title = '{% trans "Edit Plugin Setting" escape %}';
} else if (notification) { } else if (notification) {
title = '{% jstrans "Edit Notification Setting" %}'; title = '{% trans "Edit Notification Setting" escape %}';
setting = $(this).attr('pk'); setting = $(this).attr('pk');
} else if (is_global) { } else if (is_global) {
title = '{% jstrans "Edit Global Setting" %}'; title = '{% trans "Edit Global Setting" escape %}';
} else { } else {
title = '{% jstrans "Edit User Setting" %}'; title = '{% trans "Edit User Setting" escape %}';
} }
editSetting(setting, { editSetting(setting, {

View File

@ -41,12 +41,12 @@ onPanelLoad('pricing', function() {
{ {
field: 'currency', field: 'currency',
sortable: true, sortable: true,
title: '{% jstrans "Currency" %}', title: '{% trans "Currency" escape %}',
}, },
{ {
field: 'rate', field: 'rate',
sortable: true, sortable: true,
title: '{% jstrans "Rate" %}', title: '{% trans "Rate" escape %}',
} }
] ]
}); });
@ -64,21 +64,21 @@ onPanelLoad('units', function() {
columns: [ columns: [
{ {
field: 'name', field: 'name',
title: '{% jstrans "Name" %}', title: '{% trans "Name" escape %}',
}, },
{ {
field: 'definition', field: 'definition',
title: '{% jstrans "Definition" %}', title: '{% trans "Definition" escape %}',
}, },
{ {
field: 'symbol', field: 'symbol',
title: '{% jstrans "Symbol" %}', title: '{% trans "Symbol" escape %}',
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, '{% jstrans "Edit" %}'); buttons += makeEditButton('button-units-edit', row.pk, '{% trans "Edit" escape %}');
buttons += makeDeleteButton('button-units-delete', row.pk, '{% jstrans "Delete" %}'); buttons += makeDeleteButton('button-units-delete', row.pk, '{% trans "Delete" escape %}');
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: '{% jstrans "Edit Custom Unit" %}', title: '{% trans "Edit Custom Unit" escape %}',
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: '{% jstrans "Delete Custom Unit" %}', title: '{% trans "Delete Custom Unit" escape %}',
method: 'DELETE', method: 'DELETE',
refreshTable: '#physical-units-table', refreshTable: '#physical-units-table',
}); });
@ -121,7 +121,7 @@ onPanelLoad('units', function() {
definition: {}, definition: {},
symbol: {}, symbol: {},
}, },
title: '{% jstrans "New Custom Unit" %}', title: '{% trans "New Custom Unit" escape %}',
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 '{% jstrans "No project codes found" %}'; return '{% trans "No project codes found" escape %}';
}, },
columns: [ columns: [
{ {
field: 'code', field: 'code',
sortable: true, sortable: true,
title: '{% jstrans "Project Code" %}', title: '{% trans "Project Code" escape %}',
}, },
{ {
field: 'responsible', field: 'responsible',
title: '{% jstrans "Responsible" %}', title: '{% trans "Responsible" escape %}',
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 == '{% jstrans "group" %}') { if (row.responsible_detail.label == '{% trans "group" escape %}') {
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: '{% jstrans "Description" %}', title: '{% trans "Description" escape %}',
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, '{% jstrans "Edit Project Code" %}'); buttons += makeEditButton('button-project-code-edit', row.pk, '{% trans "Edit Project Code" escape %}');
buttons += makeDeleteButton('button-project-code-delete', row.pk, '{% jstrans "Delete Project Code" %}'); buttons += makeDeleteButton('button-project-code-delete', row.pk, '{% trans "Delete Project Code" escape %}');
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: '{% jstrans "Edit Project Code" %}', title: '{% trans "Edit Project Code" escape %}',
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: '{% jstrans "Delete Project Code" %}', title: '{% trans "Delete Project Code" escape %}',
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: '{% jstrans "New Project Code" %}', title: '{% trans "New Project Code" escape %}',
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 '{% jstrans "No category parameter templates found" %}'; }, formatNoMatches: function() { return '{% trans "No category parameter templates found" escape %}'; },
columns: [ columns: [
{ {
field: 'pk', field: 'pk',
@ -292,21 +292,21 @@ onPanelLoad('category', function() {
}, },
{ {
field: 'parameter_template_detail.name', field: 'parameter_template_detail.name',
title: '{% jstrans "Parameter Template" %}', title: '{% trans "Parameter Template" escape %}',
sortable: 'true', sortable: 'true',
}, },
{ {
field: 'category_detail.pathstring', field: 'category_detail.pathstring',
title: '{% jstrans "Category" %}', title: '{% trans "Category" escape %}',
}, },
{ {
field: 'default_value', field: 'default_value',
title: '{% jstrans "Default Value" %}', title: '{% trans "Default Value" escape %}',
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, '{% jstrans "Edit Template" %}'); buttons += makeEditButton('template-edit', row.pk, '{% trans "Edit Template" escape %}');
buttons += makeDeleteButton('template-delete', row.pk, '{% jstrans "Delete Template" %}'); buttons += makeDeleteButton('template-delete', row.pk, '{% trans "Delete Template" escape %}');
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: '{% jstrans "Edit Category Parameter Template" %}', title: '{% trans "Edit Category Parameter Template" escape %}',
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: '{% jstrans "Delete Category Parameter Template" %}', title: '{% trans "Delete Category Parameter Template" escape %}',
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: '{% jstrans "Create Category Parameter Template" %}', title: '{% trans "Create Category Parameter Template" escape %}',
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: '{% jstrans "Create Part Parameter Template" %}', title: '{% trans "Create Part Parameter Template" escape %}',
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 '{% jstrans "No stock location types found" %}'; return '{% trans "No stock location types found" escape %}';
}, },
columns: [ columns: [
{ {
field: 'name', field: 'name',
sortable: true, sortable: true,
title: '{% jstrans "Name" %}', title: '{% trans "Name" escape %}',
}, },
{ {
field: 'description', field: 'description',
sortable: false, sortable: false,
title: '{% jstrans "Description" %}', title: '{% trans "Description" escape %}',
}, },
{ {
field: 'icon', field: 'icon',
sortable: true, sortable: true,
title: '{% jstrans "Icon" %}', title: '{% trans "Icon" escape %}',
}, },
{ {
field: 'location_count', field: 'location_count',
sortable: true, sortable: true,
title: '{% jstrans "Location count" %}', title: '{% trans "Location count" escape %}',
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, '{% jstrans "Edit Location Type" %}'); buttons += makeEditButton('button-location-type-edit', row.pk, '{% trans "Edit Location Type" escape %}');
buttons += makeDeleteButton('button-location-type-delete', row.pk, '{% jstrans "Delete Location type" %}'); buttons += makeDeleteButton('button-location-type-delete', row.pk, '{% trans "Delete Location type" escape %}');
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: '{% jstrans "Edit Location Type" %}', title: '{% trans "Edit Location Type" escape %}',
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: '{% jstrans "Delete Location Type" %}', title: '{% trans "Delete Location Type" escape %}',
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: '{% jstrans "New Location Type" %}', title: '{% trans "New Location Type" escape %}',
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: '{% jstrans "Report" %}', title: '{% trans "Report" escape %}',
formatter: function(value, row) { formatter: function(value, row) {
return attachmentLink(value); return attachmentLink(value);
} }
}, },
{ {
field: 'part_count', field: 'part_count',
title: '{% jstrans "Part Count" %}', title: '{% trans "Part Count" escape %}',
}, },
{ {
field: 'date', field: 'date',
title: '{% jstrans "Date" %}', title: '{% trans "Date" escape %}',
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 = "{% jstrans 'Do you really want to remove the selected email address?' %}"; var message = '{% trans "Do you really want to remove the selected email address?" escape %}';
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 = '{% jstrans "No Response" %}'; title = '{% trans "No Response" %}';
message = '{% jstrans "No response from the InvenTree server" %}'; message = '{% trans "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 = '{% jstrans "Error 400: Bad request" %}'; title = '{% trans "Error 400: Bad request" %}';
message = '{% jstrans "API request returned error code 400" %}'; message = '{% trans "API request returned error code 400" %}';
break; break;
// Not authenticated // Not authenticated
case 401: case 401:
title = '{% jstrans "Error 401: Not Authenticated" %}'; title = '{% trans "Error 401: Not Authenticated" %}';
message = '{% jstrans "Authentication credentials not supplied" %}'; message = '{% trans "Authentication credentials not supplied" %}';
break; break;
// Permission denied // Permission denied
case 403: case 403:
title = '{% jstrans "Error 403: Permission Denied" %}'; title = '{% trans "Error 403: Permission Denied" %}';
message = '{% jstrans "You do not have the required permissions to access this function" %}'; message = '{% trans "You do not have the required permissions to access this function" %}';
break; break;
// Resource not found // Resource not found
case 404: case 404:
title = '{% jstrans "Error 404: Resource Not Found" %}'; title = '{% trans "Error 404: Resource Not Found" %}';
message = '{% jstrans "The requested resource could not be located on the server" %}'; message = '{% trans "The requested resource could not be located on the server" %}';
break; break;
// Method not allowed // Method not allowed
case 405: case 405:
title = '{% jstrans "Error 405: Method Not Allowed" %}'; title = '{% trans "Error 405: Method Not Allowed" %}';
message = '{% jstrans "HTTP method not allowed at URL" %}'; message = '{% trans "HTTP method not allowed at URL" %}';
break; break;
// Timeout // Timeout
case 408: case 408:
title = '{% jstrans "Error 408: Timeout" %}'; title = '{% trans "Error 408: Timeout" %}';
message = '{% jstrans "Connection timeout while requesting data from server" %}'; message = '{% trans "Connection timeout while requesting data from server" %}';
break; break;
case 503: case 503:
title = '{% jstrans "Error 503: Service Unavailable" %}'; title = '{% trans "Error 503: Service Unavailable" %}';
message = '{% jstrans "The server is currently unavailable" %}'; message = '{% trans "The server is currently unavailable" %}';
break; break;
default: default:
title = '{% jstrans "Unhandled Error Code" %}'; title = '{% trans "Unhandled Error Code" %}';
message = `{% jstrans "Error code" %}: ${xhr.status}`; message = `{% trans "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: '{% jstrans "Add Attachment" %}', title: '{% trans "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: '{% jstrans "Add Link" %}', title: '{% trans "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'>
{% jstrans "All selected attachments will be deleted" %} {% trans "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>{% jstrans "Attachment" %}</th> <th>{% trans "Attachment" %}</th>
<th>{% jstrans "Comment" %}</th> <th>{% trans "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: '{% jstrans "Delete Attachments" %}', title: '{% trans "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: '{% jstrans "Delete attachments" %}', title: '{% trans "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: '{% jstrans "Attachment actions" %}', title: '{% trans "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 '{% jstrans "No attachments found" %}'; return '{% trans "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: '{% jstrans "Edit Attachment" %}', title: '{% trans "Edit Attachment" %}',
}); });
}); });
} }
@ -323,7 +323,7 @@ function loadAttachmentTable(url, options) {
}, },
{ {
field: 'attachment', field: 'attachment',
title: '{% jstrans "Attachment" %}', title: '{% trans "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: '{% jstrans "Comment" %}', title: '{% trans "Comment" %}',
}, },
{ {
field: 'upload_date', field: 'upload_date',
sortable: true, sortable: true,
title: '{% jstrans "Upload Date" %}', title: '{% trans "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,
'{% jstrans "Edit attachment" %}', '{% trans "Edit attachment" %}',
); );
} }
@ -371,7 +371,7 @@ function loadAttachmentTable(url, options) {
buttons += makeDeleteButton( buttons += makeDeleteButton(
'button-attachment-delete', 'button-attachment-delete',
row.pk, row.pk,
'{% jstrans "Delete attachment" %}', '{% trans "Delete attachment" %}',
); );
} }

View File

@ -40,23 +40,23 @@ var barcodeInputTimer = null;
*/ */
function makeBarcodeInput(placeholderText='', hintText='') { function makeBarcodeInput(placeholderText='', hintText='') {
placeholderText = placeholderText || '{% jstrans "Scan barcode data here using barcode scanner" %}'; placeholderText = placeholderText || '{% trans "Scan barcode data here using barcode scanner" %}';
hintText = hintText || '{% jstrans "Enter barcode data" %}'; hintText = hintText || '{% trans "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'>{% jstrans "Barcode" %}</label> <label class='control-label' for='barcode'>{% trans "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='{% jstrans "Scan barcode using connected webcam" %}' id='barcode_scan_btn' type='button' class='btn btn-secondary' onclick='onBarcodeScanClicked()' style='display: none;'> <button title='{% trans "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 || '{% jstrans "Enter optional notes for stock transfer" %}'; var tooltip = options.tooltip || '{% trans "Enter optional notes for stock transfer" %}';
var placeholder = options.placeholder || '{% jstrans "Enter notes" %}'; var placeholder = options.placeholder || '{% trans "Enter notes" %}';
return ` return `
<div class='form-group'> <div class='form-group'>
<label class='control-label' for='notes'>{% jstrans "Notes" %}</label> <label class='control-label' for='notes'>{% trans "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 || '{% jstrans "Server error" %}'); showBarcodeMessage(modal, data.error || '{% trans "Server error" %}');
} }
break; break;
default: default:
@ -214,7 +214,7 @@ function postBarcodeData(barcode_data, options={}) {
} else { } else {
showBarcodeMessage( showBarcodeMessage(
modal, modal,
'{% jstrans "Unknown response from server" %}', '{% trans "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,
`{% jstrans "Invalid server response" %}<br>{% jstrans "Status" %}: '${status}'` `{% trans "Invalid server response" %}<br>{% trans "Status" %}: '${status}'`
); );
} }
@ -369,7 +369,7 @@ function barcodeDialog(title, options={}) {
modalShowSubmitButton(modal, false); modalShowSubmitButton(modal, false);
} }
var details = options.details || '{% jstrans "Scan barcode data" %}'; var details = options.details || '{% trans "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 || '{% jstrans "Scan Barcode" %}'; let title = options.title || '{% trans "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,
'{% jstrans "No URL in response" %}', '{% trans "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>{% jstrans "Unlink Barcode" %}</b><br>`; var html = `<b>{% trans "Unlink Barcode" %}</b><br>`;
html += '{% jstrans "This will remove the link to the associated barcode" %}'; html += '{% trans "This will remove the link to the associated barcode" %}';
showQuestionDialog( showQuestionDialog(
'{% jstrans "Unlink Barcode" %}', '{% trans "Unlink Barcode" %}',
html, html,
{ {
accept_text: '{% jstrans "Unlink" %}', accept_text: '{% trans "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>{% jstrans "Part" %}</th> <th>{% trans "Part" %}</th>
<th>{% jstrans "Location" %}</th> <th>{% trans "Location" %}</th>
<th>{% jstrans "Quantity" %}</th> <th>{% trans "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, '{% jstrans "Remove stock item" %}')}</td> <td>${makeRemoveButton('button-item-remove', item.pk, '{% trans "Remove stock item" %}')}</td>
</tr>`; </tr>`;
}); });
@ -607,12 +607,12 @@ function barcodeCheckInStockItems(location_id, options={}) {
var extra = makeNotesField(); var extra = makeNotesField();
barcodeDialog( barcodeDialog(
'{% jstrans "Scan Stock Items Into Location" %}', '{% trans "Scan Stock Items Into Location" %}',
{ {
details: '{% jstrans "Scan stock item barcode to check in to this location" %}', details: '{% trans "Scan stock item barcode to check in to this location" %}',
headerContent: table, headerContent: table,
preShow: function() { preShow: function() {
modalSetSubmitText(modal, '{% jstrans "Check In" %}'); modalSetSubmitText(modal, '{% trans "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, '{% jstrans "No barcode provided" %}', 'warning'); showBarcodeMessage(modal, '{% trans "No barcode provided" %}', 'warning');
return; return;
} }
@ -684,18 +684,18 @@ function barcodeCheckInStockItems(location_id, options={}) {
}); });
if (duplicate) { if (duplicate) {
showBarcodeMessage(modal, '{% jstrans "Stock Item already scanned" %}', 'warning'); showBarcodeMessage(modal, '{% trans "Stock Item already scanned" %}', 'warning');
} else { } else {
if (stockitem.location == location_id) { if (stockitem.location == location_id) {
showBarcodeMessage(modal, '{% jstrans "Stock Item already in this location" %}'); showBarcodeMessage(modal, '{% trans "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, '{% jstrans "Added stock item" %}', 'success'); showBarcodeMessage(modal, '{% trans "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, '{% jstrans "Barcode does not match valid stock item" %}', 'warning'); showBarcodeMessage(modal, '{% trans "Barcode does not match valid stock item" %}', 'warning');
} }
}, },
} }
@ -723,9 +723,9 @@ function barcodeCheckInStockLocations(location_id, options={}) {
var header = ''; var header = '';
barcodeDialog( barcodeDialog(
'{% jstrans "Scan Stock Container Into Location" %}', '{% trans "Scan Stock Container Into Location" %}',
{ {
details: '{% jstrans "Scan stock container barcode to check in to this location" %}', details: '{% trans "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, '{% jstrans "Barcode does not match valid stock location" %}', 'warning'); showBarcodeMessage(modal, '{% trans "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>{% jstrans "Location" %}</b></br> <b>{% trans "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(
'{% jstrans "Check Into Location" %}', '{% trans "Check Into Location" %}',
{ {
headerContent: header, headerContent: header,
extraFields: extra, extraFields: extra,
modal: modal, modal: modal,
preShow: function() { preShow: function() {
modalSetSubmitText(modal, '{% jstrans "Check In" %}'); modalSetSubmitText(modal, '{% trans "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,
'{% jstrans "Barcode does not match a valid location" %}', '{% trans "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,
'{% jstrans "Barcode does not match a valid location" %}', '{% trans "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: '{% jstrans "Create BOM Item" %}', title: '{% trans "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, '{% jstrans "Display row data" %}'); buttons += makeInfoButton('button-row-data', idx, '{% trans "Display row data" %}');
buttons += makeRemoveButton('button-row-remove', idx, '{% jstrans "Remove row" %}'); buttons += makeRemoveButton('button-row-remove', idx, '{% trans "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: '{% jstrans "Row Data" %}', title: '{% trans "Row Data" %}',
closeText: '{% jstrans "Close" %}', closeText: '{% trans "Close" %}',
hideSubmitButton: true hideSubmitButton: true
}); });
@ -303,11 +303,11 @@ function downloadBomTemplate(options={}) {
} }
constructFormBody({}, { constructFormBody({}, {
title: '{% jstrans "Download BOM Template" %}', title: '{% trans "Download BOM Template" %}',
fields: { fields: {
format: { format: {
label: '{% jstrans "Format" %}', label: '{% trans "Format" %}',
help_text: '{% jstrans "Select file format" %}', help_text: '{% trans "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: '{% jstrans "Export BOM" %}', title: '{% trans "Export BOM" %}',
fields: { fields: {
format: { format: {
label: '{% jstrans "Format" %}', label: '{% trans "Format" %}',
help_text: '{% jstrans "Select file format" %}', help_text: '{% trans "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: '{% jstrans "Multi Level BOM" %}', label: '{% trans "Multi Level BOM" %}',
help_text: '{% jstrans "Include BOM data for subassemblies" %}', help_text: '{% trans "Include BOM data for subassemblies" %}',
type: 'boolean', type: 'boolean',
value: inventreeLoad('bom-export-cascading', true), value: inventreeLoad('bom-export-cascading', true),
}, },
levels: { levels: {
label: '{% jstrans "Levels" %}', label: '{% trans "Levels" %}',
help_text: '{% jstrans "Select maximum number of BOM levels to export (0 = all levels)" %}', help_text: '{% trans "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: '{% jstrans "Include Alternative Parts" %}', label: '{% trans "Include Alternative Parts" %}',
help_text: '{% jstrans "Include alternative parts in exported BOM" %}', help_text: '{% trans "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: '{% jstrans "Include Parameter Data" %}', label: '{% trans "Include Parameter Data" %}',
help_text: '{% jstrans "Include part parameter data in exported BOM" %}', help_text: '{% trans "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: '{% jstrans "Include Stock Data" %}', label: '{% trans "Include Stock Data" %}',
help_text: '{% jstrans "Include part stock data in exported BOM" %}', help_text: '{% trans "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: '{% jstrans "Include Manufacturer Data" %}', label: '{% trans "Include Manufacturer Data" %}',
help_text: '{% jstrans "Include part manufacturer data in exported BOM" %}', help_text: '{% trans "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: '{% jstrans "Include Supplier Data" %}', label: '{% trans "Include Supplier Data" %}',
help_text: '{% jstrans "Include part supplier data in exported BOM" %}', help_text: '{% trans "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: '{% jstrans "Include Pricing Data" %}', label: '{% trans "Include Pricing Data" %}',
help_text: '{% jstrans "Include part pricing data in exported BOM" %}', help_text: '{% trans "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: '{% jstrans "New Part" %}', title: '{% trans "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, '{% jstrans "Remove substitute part" %}'); buttons += makeRemoveButton('button-row-remove', pk, '{% trans "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>{% jstrans "Base Part" %}</strong><hr> <strong>{% trans "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>{% jstrans "Part" %}</th> <th>{% trans "Part" %}</th>
<th>{% jstrans "Description" %}</th> <th>{% trans "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'>
{% jstrans "Select and add a new substitute part using the input below" %} {% trans "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'>
{% jstrans "Are you sure you wish to remove this substitute part link?" %} {% trans "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: '{% jstrans "Remove Substitute Part" %}', title: '{% trans "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: '{% jstrans "Close" %}', closeText: '{% trans "Close" %}',
submitText: '{% jstrans "Add Substitute" %}', submitText: '{% trans "Add Substitute" %}',
title: '{% jstrans "Edit BOM Item Substitutes" %}', title: '{% trans "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'>
{% jstrans "All selected BOM items will be deleted" %} {% trans "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>{% jstrans "Part" %}</th> <th>{% trans "Part" %}</th>
<th>{% jstrans "Reference" %}</th> <th>{% trans "Reference" %}</th>
<th>{% jstrans "Quantity" %}</th> <th>{% trans "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: '{% jstrans "Delete selected BOM items?" %}', title: '{% trans "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: '{% jstrans "Delete items" %}', title: '{% trans "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: '{% jstrans "Part" %}', title: '{% trans "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='{% jstrans "Load BOM for subassembly" %}'></span> <span class='fas fa-sync-alt' title='{% trans "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', '{% jstrans "Substitutes Available" %}'); html += makeIconBadge('fa-exchange-alt', '{% trans "Substitutes Available" %}');
} }
if (row.allow_variants) { if (row.allow_variants) {
html += makeIconBadge('fa-sitemap', '{% jstrans "Variant stock allowed" %}'); html += makeIconBadge('fa-sitemap', '{% trans "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: '{% jstrans "Description" %}', title: '{% trans "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: '{% jstrans "Reference" %}', title: '{% trans "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: '{% jstrans "Quantity" %}', title: '{% trans "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>({% jstrans "Consumable" %})</small>`; text += ` <small>({% trans "Consumable" %})</small>`;
} }
if (row.optional) { if (row.optional) {
text += ' <small>({% jstrans "Optional" %})</small>'; text += ' <small>({% trans "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: '{% jstrans "Substitutes" %}', title: '{% trans "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: '{% jstrans "Optional" %}', title: '{% trans "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: '{% jstrans "Consumable" %}', title: '{% trans "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: '{% jstrans "Allow Variants" %}', title: '{% trans "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: '{% jstrans "Gets inherited" %}', title: '{% trans "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: '{% jstrans "Price Range" %}', title: '{% trans "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',
'{% jstrans "BOM pricing is complete" %}', '{% trans "BOM pricing is complete" %}',
); );
} else { } else {
html += makeIconBadge( html += makeIconBadge(
'fa-exclamation-circle icon-yellow', 'fa-exclamation-circle icon-yellow',
'{% jstrans "BOM pricing is incomplete" %}', '{% trans "BOM pricing is incomplete" %}',
); );
} }
return html; return html;
} else { } else {
let html = '<em>{% jstrans "No pricing available" %}</em>'; let html = '<em>{% trans "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: '{% jstrans "Available" %}', title: '{% trans "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', '{% jstrans "No Stock Available" %}'); text += makeIconBadge('fa-times-circle icon-red', '{% trans "No Stock Available" %}');
} else { } else {
var extra = ''; var extra = '';
if ((substitute_stock > 0) && (variant_stock > 0)) { if ((substitute_stock > 0) && (variant_stock > 0)) {
extra = '{% jstrans "Includes variant and substitute stock" %}'; extra = '{% trans "Includes variant and substitute stock" %}';
} else if (variant_stock > 0) { } else if (variant_stock > 0) {
extra = '{% jstrans "Includes variant stock" %}'; extra = '{% trans "Includes variant stock" %}';
} else if (substitute_stock > 0) { } else if (substitute_stock > 0) {
extra = '{% jstrans "Includes substitute stock" %}'; extra = '{% trans "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',
`{% jstrans "On Order" %}: ${row.on_order}`, `{% trans "On Order" %}: ${row.on_order}`,
); );
} }
@ -1210,13 +1210,13 @@ function loadBomTable(table, options={}) {
cols.push( cols.push(
{ {
field: 'can_build', field: 'can_build',
title: '{% jstrans "Can Build" %}', title: '{% trans "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>{% jstrans "Consumable item" %}</em>`; return `<em>{% trans "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: '{% jstrans "Notes" %}', title: '{% trans "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: '{% jstrans "Actions" %}', title: '{% trans "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, '{% jstrans "Validate BOM Item" %}'); var bValidate = makeIconButton('fa-check-circle icon-green', 'bom-validate-button', row.pk, '{% trans "Validate BOM Item" %}');
var bValid = makeIconButton('fa-check-double icon-green', 'bom-valid-button', row.pk, '{% jstrans "This line has been validated" %}', {disabled: true}); var bValid = makeIconButton('fa-check-double icon-green', 'bom-valid-button', row.pk, '{% trans "This line has been validated" %}', {disabled: true});
var bSubs = makeIconButton('fa-exchange-alt icon-blue', 'bom-substitutes-button', row.pk, '{% jstrans "Edit substitute parts" %}'); var bSubs = makeIconButton('fa-exchange-alt icon-blue', 'bom-substitutes-button', row.pk, '{% trans "Edit substitute parts" %}');
var bEdit = makeEditButton('bom-edit-button', row.pk, '{% jstrans "Edit BOM Item" %}'); var bEdit = makeEditButton('bom-edit-button', row.pk, '{% trans "Edit BOM Item" %}');
var bDelt = makeDeleteButton('bom-delete-button', row.pk, '{% jstrans "Delete BOM Item" %}'); var bDelt = makeDeleteButton('bom-delete-button', row.pk, '{% trans "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(
'{% jstrans "View BOM" %}', '{% trans "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='{% jstrans "Add BOM Item" %}' id='bom-item-new-footer'> <button class='btn btn-success float-right' type='button' title='{% trans "Add BOM Item" %}' id='bom-item-new-footer'>
${makeIcon('fa-plus-circle')} {% jstrans "Add BOM Item" %} ${makeIcon('fa-plus-circle')} {% trans "Add BOM Item" %}
</button> </button>
`; `;
} }
@ -1388,7 +1388,7 @@ function loadBomTable(table, options={}) {
}, },
formatNoMatches: function() { formatNoMatches: function() {
return '{% jstrans "No BOM items found" %}'; return '{% trans "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: '{% jstrans "Edit BOM Item" %}', title: '{% trans "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: '{% jstrans "Assembly" %}', title: '{% trans "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: '{% jstrans "Required Part" %}', title: '{% trans "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: '{% jstrans "Required Quantity" %}', title: '{% trans "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>({% jstrans "Inherited from parent BOM" %})</em>`; html += ` <em>({% trans "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: '{% jstrans "Edit Build Order" %}', title: '{% trans "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: '{% jstrans "Create Build Order" %}', title: '{% trans "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: '{% jstrans "Cancel Build Order" %}', title: '{% trans "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'>
{% jstrans "Are you sure you wish to cancel this build?" %} {% trans "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'>
{% jstrans "Stock items have been allocated to this build order" %} {% trans "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'>
{% jstrans "There are incomplete outputs remaining for this build order" %} {% trans "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'>
{% jstrans "Build order is ready to be completed" %}' {% trans "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>{% jstrans "Build order has incomplete outputs" %}</strong><br> <strong>{% trans "Build order has incomplete outputs" %}</strong><br>
{% jstrans "This build order cannot be completed as there are incomplete outputs" %} {% trans "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>{% jstrans "Build Order is incomplete" %}</strong> <strong>{% trans "Build Order is incomplete" %}</strong>
</div> </div>
`; `;
} }
if (!ctx.allocated) { if (!ctx.allocated) {
html += `<div class='alert alert-block alert-warning'>{% jstrans "Required stock has not been fully allocated" %}</div>`; html += `<div class='alert alert-block alert-warning'>{% trans "Required stock has not been fully allocated" %}</div>`;
} }
if (ctx.remaining > 0) { if (ctx.remaining > 0) {
html += `<div class='alert alert-block alert-warning'>{% jstrans "Required build quantity has not been completed" %}</div>`; html += `<div class='alert alert-block alert-warning'>{% trans "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: '{% jstrans "Complete Build Order" %}', title: '{% trans "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 = `{% jstrans "Next available serial number" %}: ${data.next}`; fields.serial_numbers.placeholder = `{% trans "Next available serial number" %}: ${data.next}`;
} else if (data.latest) { } else if (data.latest) {
fields.serial_numbers.placeholder = `{% jstrans "Latest serial number" %}: ${data.latest}`; fields.serial_numbers.placeholder = `{% trans "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'>
{% jstrans "The Bill of Materials contains trackable parts" %}.<br> {% trans "The Bill of Materials contains trackable parts" %}.<br>
{% jstrans "Build outputs must be generated individually" %}. {% trans "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'>
{% jstrans "Trackable parts can have serial numbers specified" %}<br> {% trans "Trackable parts can have serial numbers specified" %}<br>
{% jstrans "Enter serial numbers to generate multiple single build outputs" %} {% trans "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: '{% jstrans "Create Build Output" %}', title: '{% trans "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,
'{% jstrans "Allocate stock items to this build output" %}', '{% trans "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,
'{% jstrans "Deallocate stock from build output" %}', '{% trans "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,
'{% jstrans "Complete build output" %}', '{% trans "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,
'{% jstrans "Scrap build output" %}', '{% trans "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,
'{% jstrans "Delete build output" %}', '{% trans "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'>
{% jstrans "Are you sure you wish to deallocate the selected stock items from this build?" %} {% trans "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: '{% jstrans "Deallocate Stock Items" %}', title: '{% trans "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 += `{% jstrans "Serial Number" %}: ${output.serial}`; output_html += `{% trans "Serial Number" %}: ${output.serial}`;
} else { } else {
output_html += `{% jstrans "Quantity" %}: ${output.quantity}`; output_html += `{% trans "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, '{% jstrans "Remove row" %}'); buttons += makeRemoveButton('button-row-remove', pk, '{% trans "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(
'{% jstrans "Select Build Outputs" %}', '{% trans "Select Build Outputs" %}',
'{% jstrans "At least one build output must be selected" %}', '{% trans "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'>
{% jstrans "Selected build outputs will be marked as complete" %} {% trans "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'>{% jstrans "Output" %}</th> <th colspan='2'>{% trans "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: '{% jstrans "Complete Build Outputs" %}', title: '{% trans "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(
'{% jstrans "Select Build Outputs" %}', '{% trans "Select Build Outputs" %}',
'{% jstrans "At least one build output must be selected" %}', '{% trans "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'>
{% jstrans "Selected build outputs will be marked as scrapped" %} {% trans "Selected build outputs will be marked as scrapped" %}
<ul> <ul>
<li>{% jstrans "Scrapped output are marked as rejected" %}</li> <li>{% trans "Scrapped output are marked as rejected" %}</li>
<li>{% jstrans "Allocated stock items will no longer be available" %}</li> <li>{% trans "Allocated stock items will no longer be available" %}</li>
<li>{% jstrans "The completion status of the build order will not be adjusted" %}</li> <li>{% trans "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'>{% jstrans "Output" %}</th> <th colspan='2'>{% trans "Output" %}</th>
<th>{% jstrans "Quantity" %}</th> <th>{% trans "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: '{% jstrans "Scrap Build Outputs" %}', title: '{% trans "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(
'{% jstrans "Select Build Outputs" %}', '{% trans "Select Build Outputs" %}',
'{% jstrans "At least one build output must be selected" %}', '{% trans "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'>
{% jstrans "Selected build outputs will be deleted" %} {% trans "Selected build outputs will be deleted" %}
<ul> <ul>
<li>{% jstrans "Build output data will be permanently deleted" %}</li> <li>{% trans "Build output data will be permanently deleted" %}</li>
<li>{% jstrans "Allocated stock items will be returned to stock" %}</li> <li>{% trans "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'>{% jstrans "Output" %}</th> <th colspan='2'>{% trans "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: '{% jstrans "Delete Build Outputs" %}', title: '{% trans "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 '{% jstrans "No build order allocations found" %}'; return '{% trans "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: '{% jstrans "Build Order" %}', title: '{% trans "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: '{% jstrans "Allocated Quantity" %}', title: '{% trans "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: '{% jstrans "Location" %}', title: '{% trans "Location" %}',
formatter: function(value, row) { formatter: function(value, row) {
if (!value) { if (!value) {
return '{% jstrans "Location not specified" %}'; return '{% trans "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: '{% jstrans "Complete outputs" %}', title: '{% trans "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: '{% jstrans "Scrap outputs" %}', title: '{% trans "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: '{% jstrans "Delete outputs" %}', title: '{% trans "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: '{% jstrans "build output" %}', singular_name: '{% trans "build output" %}',
plural_name: '{% jstrans "build outputs" %}', plural_name: '{% trans "build outputs" %}',
custom_actions: [{ custom_actions: [{
label: 'buildoutput', label: 'buildoutput',
icon: 'fa-tools', icon: 'fa-tools',
title: '{% jstrans "Build output actions" %}', title: '{% trans "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 '{% jstrans "No active build outputs found" %}'; return '{% trans "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: '{% jstrans "Part" %}', title: '{% trans "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: '{% jstrans "Build Output" %}', title: '{% trans "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 = `{% jstrans "Serial Number" %}: ${row.serial}`; text = `{% trans "Serial Number" %}: ${row.serial}`;
} else { } else {
text = `{% jstrans "Quantity" %}: ${row.quantity}`; text = `{% trans "Quantity" %}: ${row.quantity}`;
} }
@ -1364,7 +1364,7 @@ function loadBuildOutputTable(build_info, options={}) {
} }
if (row.batch) { if (row.batch) {
text += ` <small>({% jstrans "Batch" %}: ${row.batch})</small>`; text += ` <small>({% trans "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: '{% jstrans "Allocated Lines" %}', title: '{% trans "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: '{% jstrans "Required Tests" %}', title: '{% trans "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(
'{% jstrans "Select Parts" %}', '{% trans "Select Parts" %}',
'{% jstrans "You must select at least one part to allocate" %}', '{% trans "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,
'{% jstrans "Remove row" %}', '{% trans "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: '{% jstrans "Specify stock allocation quantity" %}', title: '{% trans "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(
'{% jstrans "All Parts Allocated" %}', '{% trans "All Parts Allocated" %}',
'{% jstrans "All selected parts have been fully allocated" %}', '{% trans "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: '{% jstrans "Source Location" %}', label: '{% trans "Source Location" %}',
help_text: '{% jstrans "Select source location (leave blank to take from all locations)" %}', help_text: '{% trans "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>{% jstrans "Part" %}</th> <th>{% trans "Part" %}</th>
<th>{% jstrans "Allocated" %}</th> <th>{% trans "Allocated" %}</th>
<th style='min-width: 250px;'>{% jstrans "Stock Item" %}</th> <th style='min-width: 250px;'>{% trans "Stock Item" %}</th>
<th>{% jstrans "Quantity" %}</th> <th>{% trans "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: '{% jstrans "Allocate Stock Items to Build Order" %}', title: '{% trans "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 '{% jstrans "No matching stock locations" %}'; return '{% trans "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 '{% jstrans "No matching stock items" %}'; return '{% trans "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>{% jstrans "Automatic Stock Allocation" %}</strong><br> <strong>{% trans "Automatic Stock Allocation" %}</strong><br>
{% jstrans "Stock items will be automatically allocated to this build order, according to the provided guidelines" %}: {% trans "Stock items will be automatically allocated to this build order, according to the provided guidelines" %}:
<ul> <ul>
<li>{% jstrans "If a location is specified, stock will only be allocated from that location" %}</li> <li>{% trans "If a location is specified, stock will only be allocated from that location" %}</li>
<li>{% jstrans "If stock is considered interchangeable, it will be allocated from the first location it is found" %}</li> <li>{% trans "If stock is considered interchangeable, it will be allocated from the first location it is found" %}</li>
<li>{% jstrans "If substitute stock is allowed, it will be used where stock of the primary part cannot be found" %}</li> <li>{% trans "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: '{% jstrans "Allocate Stock Items" %}', title: '{% trans "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 '{% jstrans "No builds matching query" %}'; return '{% trans "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: '{% jstrans "Select" %}', title: '{% trans "Select" %}',
searchable: false, searchable: false,
switchable: false, switchable: false,
}, },
{ {
field: 'reference', field: 'reference',
title: '{% jstrans "Build" %}', title: '{% trans "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', '{% jstrans "Build order is overdue" %}'); html += makeIconBadge('fa-calendar-times icon-red', '{% trans "Build order is overdue" %}');
} }
return html; return html;
@ -2124,12 +2124,12 @@ function loadBuildTable(table, options) {
}, },
{ {
field: 'title', field: 'title',
title: '{% jstrans "Description" %}', title: '{% trans "Description" %}',
switchable: true, switchable: true,
}, },
{ {
field: 'project_code', field: 'project_code',
title: '{% jstrans "Project Code" %}', title: '{% trans "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: '{% jstrans "Priority" %}', title: '{% trans "Priority" %}',
switchable: true, switchable: true,
sortable: true, sortable: true,
}, },
{ {
field: 'part', field: 'part',
title: '{% jstrans "Part" %}', title: '{% trans "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: '{% jstrans "Progress" %}', title: '{% trans "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: '{% jstrans "Status" %}', title: '{% trans "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: '{% jstrans "Created" %}', title: '{% trans "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: '{% jstrans "Issued by" %}', title: '{% trans "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>{% jstrans "No user information" %}</i>`; return `<i>{% trans "No user information" %}</i>`;
} }
} }
}, },
{ {
field: 'responsible', field: 'responsible',
title: '{% jstrans "Responsible" %}', title: '{% trans "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 == '{% jstrans "group" %}') { if (row.responsible_detail.label == '{% trans "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: '{% jstrans "Target Date" %}', title: '{% trans "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: '{% jstrans "Completion Date" %}', title: '{% trans "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: '{% jstrans "Part" %}', title: '{% trans "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: '{% jstrans "Allocated Quantity" %}', title: '{% trans "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 = `{% jstrans "Serial Number" %}: ${serial}`; text = `{% trans "Serial Number" %}: ${serial}`;
} else { } else {
text = `{% jstrans "Quantity" %}: ${row.quantity}`; text = `{% trans "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: '{% jstrans "Location" %}', title: '{% trans "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>{% jstrans "No location set" %}</i>'; return '<i>{% trans "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, '{% jstrans "Edit stock allocation" %}'); buttons += makeEditButton('button-allocation-edit', row.pk, '{% trans "Edit stock allocation" %}');
buttons += makeDeleteButton('button-allocation-delete', row.pk, '{% jstrans "Delete stock allocation" %}'); buttons += makeDeleteButton('button-allocation-delete', row.pk, '{% trans "Delete stock allocation" %}');
return wrapButtons(buttons); return wrapButtons(buttons);
} }
} }
@ -2390,7 +2390,7 @@ function renderBuildLineAllocationTable(element, build_line, options={}) {
fields: { fields: {
quantity: {}, quantity: {},
}, },
title: '{% jstrans "Edit Allocation" %}', title: '{% trans "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: '{% jstrans "Remove Allocation" %}', title: '{% trans "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: '{% jstrans "build line" %}', singular_name: '{% trans "build line" %}',
plural_name: '{% jstrans "build lines" %}', plural_name: '{% trans "build lines" %}',
}); });
} }
@ -2462,18 +2462,18 @@ function loadBuildLineTable(table, build_id, options={}) {
}); });
}, },
formatNoMatches: function() { formatNoMatches: function() {
return '{% jstrans "No build lines found" %}'; return '{% trans "No build lines found" %}';
}, },
columns: [ columns: [
{ {
checkbox: true, checkbox: true,
title: '{% jstrans "Select" %}', title: '{% trans "Select" %}',
searchable: false, searchable: false,
switchable: false, switchable: false,
}, },
{ {
field: 'bom_item', field: 'bom_item',
title: '{% jstrans "Required Part" %}', title: '{% trans "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', '{% jstrans "Variant stock allowed" %}'); html += makeIconBadge('fa-sitemap', '{% trans "Variant stock allowed" %}');
} }
if (row.part_detail.trackable) { if (row.part_detail.trackable) {
html += makeIconBadge('fa-directions', '{% jstrans "Trackable part" %}'); html += makeIconBadge('fa-directions', '{% trans "Trackable part" %}');
} }
return html; return html;
@ -2500,7 +2500,7 @@ function loadBuildLineTable(table, build_id, options={}) {
}, },
{ {
field: 'reference', field: 'reference',
title: '{% jstrans "Reference" %}', title: '{% trans "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: '{% jstrans "Consumable" %}', title: '{% trans "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: '{% jstrans "Optional" %}', title: '{% trans "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: '{% jstrans "Unit Quantity" %}', title: '{% trans "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: '{% jstrans "Required Quantity" %}', title: '{% trans "Required Quantity" %}',
sortable: true, sortable: true,
}, },
{ {
field: 'available_stock', field: 'available_stock',
title: '{% jstrans "Available" %}', title: '{% trans "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='{% jstrans "Consumable item" %}'></span>`; icons += `<span class='fas fa-info-circle icon-blue float-right' title='{% trans "Consumable item" %}'></span>`;
} else { } else {
if (available < (row.quantity - row.allocated)) { if (available < (row.quantity - row.allocated)) {
icons += makeIconBadge('fa-times-circle icon-red', '{% jstrans "Insufficient stock available" %}'); icons += makeIconBadge('fa-times-circle icon-red', '{% trans "Insufficient stock available" %}');
} else { } else {
icons += makeIconBadge('fa-check-circle icon-green', '{% jstrans "Sufficient stock available" %}'); icons += makeIconBadge('fa-check-circle icon-green', '{% trans "Sufficient stock available" %}');
} }
if (available <= 0) { if (available <= 0) {
icons += `<span class='badge rounded-pill bg-danger'>{% jstrans "No Stock Available" %}</span>`; icons += `<span class='badge rounded-pill bg-danger'>{% trans "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 = '{% jstrans "Includes variant and substitute stock" %}'; extra = '{% trans "Includes variant and substitute stock" %}';
} else if (row.available_variant_stock > 0) { } else if (row.available_variant_stock > 0) {
extra = '{% jstrans "Includes variant stock" %}'; extra = '{% trans "Includes variant stock" %}';
} else if (row.available_substitute_stock > 0) { } else if (row.available_substitute_stock > 0) {
extra = '{% jstrans "Includes substitute stock" %}'; extra = '{% trans "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', `{% jstrans "On Order" %}: ${formatDecimal(row.on_order)}`); icons += makeIconBadge('fa-shopping-cart', `{% trans "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: '{% jstrans "Allocated" %}', title: '{% trans "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>{% jstrans "Consumable Item" %}</em>`; return `<em>{% trans "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>{% jstrans "Tracked item" %}</em>`; return `<em>{% trans "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, '{% jstrans "Build stock" %}'); buttons += makeIconButton('fa-tools icon-blue', 'button-build', pk, '{% trans "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, '{% jstrans "Order stock" %}'); buttons += makeIconButton('fa-shopping-cart icon-blue', 'button-buy', pk, '{% trans "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, '{% jstrans "Allocate stock" %}'); buttons += makeIconButton('fa-sign-in-alt icon-green', 'button-allocate', pk, '{% trans "Allocate stock" %}');
} }
if (row.allocated > 0) { if (row.allocated > 0) {
buttons += makeRemoveButton('button-unallocate', pk, '{% jstrans "Remove stock allocation" %}'); buttons += makeRemoveButton('button-unallocate', pk, '{% trans "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: '{% jstrans "Add Manufacturer" %}', title: '{% trans "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: '{% jstrans "Add Manufacturer Part" %}', title: '{% trans "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: '{% jstrans "Edit Manufacturer Part" %}', title: '{% trans "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: '{% jstrans "Add Supplier" %}', title: '{% trans "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: '{% jstrans "Add Manufacturer Part" %}', title: '{% trans "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: '{% jstrans "Add Supplier Part" %}', title: '{% trans "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: '{% jstrans "Duplicate Supplier Part" %}', title: '{% trans "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 || '{% jstrans "Edit Supplier Part" %}', title: options.title || '{% trans "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'>
{% jstrans "All selected supplier parts will be deleted" %} {% trans "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>{% jstrans "Part" %}</th> <th>{% trans "Part" %}</th>
<th>{% jstrans "SKU" %}</th> <th>{% trans "SKU" %}</th>
<th>{% jstrans "Supplier" %}</th> <th>{% trans "Supplier" %}</th>
<th>{% jstrans "MPN" %}</th> <th>{% trans "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: '{% jstrans "Delete Supplier Parts" %}', title: '{% trans "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: '{% jstrans "Add Price Break" %}', title: '{% trans "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: '{% jstrans "Edit Company" %}', title: '{% trans "Edit Company" %}',
} }
); );
} }
@ -462,7 +462,7 @@ function createCompany(options={}) {
method: 'POST', method: 'POST',
fields: fields, fields: fields,
follow: true, follow: true,
title: '{% jstrans "Add new Company" %}', title: '{% trans "Add new Company" %}',
} }
); );
} }
@ -492,22 +492,22 @@ function loadCompanyTable(table, url, options={}) {
}, },
{ {
field: 'name', field: 'name',
title: '{% jstrans "Company" %}', title: '{% trans "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='{% jstrans "Customer" %}' class='fas fa-user-tie float-right'></span>`; html += `<span title='{% trans "Customer" %}' class='fas fa-user-tie float-right'></span>`;
} }
if (row.is_manufacturer) { if (row.is_manufacturer) {
html += `<span title='{% jstrans "Manufacturer" %}' class='fas fa-industry float-right'></span>`; html += `<span title='{% trans "Manufacturer" %}' class='fas fa-industry float-right'></span>`;
} }
if (row.is_supplier) { if (row.is_supplier) {
html += `<span title='{% jstrans "Supplier" %}' class='fas fa-building float-right'></span>`; html += `<span title='{% trans "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: '{% jstrans "Description" %}', title: '{% trans "Description" %}',
}, },
{ {
field: 'website', field: 'website',
title: '{% jstrans "Website" %}', title: '{% trans "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: '{% jstrans "Parts Supplied" %}', title: '{% trans "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: '{% jstrans "Parts Manufactured" %}', title: '{% trans "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 '{% jstrans "No company information found" %}'; return '{% trans "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: '{% jstrans "Create New Contact" %}', title: '{% trans "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: '{% jstrans "Edit Contact" %}', title: '{% trans "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'>
{% jstrans "All selected contacts will be deleted" %} {% trans "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>{% jstrans "Name" %}</th> <th>{% trans "Name" %}</th>
<th>{% jstrans "Email" %}</th> <th>{% trans "Email" %}</th>
<th>{% jstrans "Role" %}</th> <th>{% trans "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: '{% jstrans "Delete Contacts" %}', title: '{% trans "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 '{% jstrans "No contacts found" %}'; return '{% trans "No contacts found" %}';
}, },
showColumns: true, showColumns: true,
name: 'contacts', name: 'contacts',
columns: [ columns: [
{ {
field: 'name', field: 'name',
title: '{% jstrans "Name" %}', title: '{% trans "Name" %}',
sortable: true, sortable: true,
switchable: false, switchable: false,
}, },
{ {
field: 'phone', field: 'phone',
title: '{% jstrans "Phone Number" %}', title: '{% trans "Phone Number" %}',
sortable: false, sortable: false,
switchable: true, switchable: true,
}, },
{ {
field: 'email', field: 'email',
title: '{% jstrans "Email Address" %}', title: '{% trans "Email Address" %}',
sortable: false, sortable: false,
switchable: true, switchable: true,
}, },
{ {
field: 'role', field: 'role',
title: '{% jstrans "Role" %}', title: '{% trans "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, '{% jstrans "Edit Contact" %}'); html += makeEditButton('btn-contact-edit', pk, '{% trans "Edit Contact" %}');
} }
if (options.allow_delete) { if (options.allow_delete) {
html += makeDeleteButton('btn-contact-delete', pk, '{% jstrans "Delete Contact" %}'); html += makeDeleteButton('btn-contact-delete', pk, '{% trans "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: '{% jstrans "Create New Address" %}', title: '{% trans "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: '{% jstrans "Edit Address" %}', title: '{% trans "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'>
{% jstrans "All selected addresses will be deleted" %} {% trans "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>{% jstrans "Name" %}</th> <th>{% trans "Name" %}</th>
<th>{% jstrans "Line 1" %}</th> <th>{% trans "Line 1" %}</th>
<th>{% jstrans "Line 2" %}</th> <th>{% trans "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: '{% jstrans "Delete Addresses" %}', title: '{% trans "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 '{% jstrans "No addresses found" %}'; return '{% trans "No addresses found" %}';
}, },
showColumns: true, showColumns: true,
name: 'addresses', name: 'addresses',
columns: [ columns: [
{ {
field: 'primary', field: 'primary',
title: '{% jstrans "Primary" %}', title: '{% trans "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: '{% jstrans "Title" %}', title: '{% trans "Title" %}',
sortable: true, sortable: true,
switchable: false, switchable: false,
}, },
{ {
field: 'line1', field: 'line1',
title: '{% jstrans "Line 1" %}', title: '{% trans "Line 1" %}',
sortable: false, sortable: false,
switchable: false, switchable: false,
}, },
{ {
field: 'line2', field: 'line2',
title: '{% jstrans "Line 2" %}', title: '{% trans "Line 2" %}',
sortable: false, sortable: false,
switchable: false, switchable: false,
}, },
{ {
field: 'postal_code', field: 'postal_code',
title: '{% jstrans "Postal code" %}', title: '{% trans "Postal code" %}',
sortable: false, sortable: false,
switchable: false, switchable: false,
}, },
{ {
field: 'postal_city', field: 'postal_city',
title: '{% jstrans "Postal city" %}', title: '{% trans "Postal city" %}',
sortable: false, sortable: false,
switchable: false, switchable: false,
}, },
{ {
field: 'province', field: 'province',
title: '{% jstrans "State/province" %}', title: '{% trans "State/province" %}',
sortable: false, sortable: false,
switchable: false, switchable: false,
}, },
{ {
field: 'country', field: 'country',
title: '{% jstrans "Country" %}', title: '{% trans "Country" %}',
sortable: false, sortable: false,
switchable: false, switchable: false,
}, },
{ {
field: 'shipping_notes', field: 'shipping_notes',
title: '{% jstrans "Courier notes" %}', title: '{% trans "Courier notes" %}',
sortable: false, sortable: false,
switchable: true, switchable: true,
}, },
{ {
field: 'internal_shipping_notes', field: 'internal_shipping_notes',
title: '{% jstrans "Internal notes" %}', title: '{% trans "Internal notes" %}',
sortable: false, sortable: false,
switchable: true, switchable: true,
}, },
{ {
field: 'link', field: 'link',
title: '{% jstrans "External Link" %}', title: '{% trans "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, '{% jstrans "Edit Address" %}'); html += makeEditButton('btn-address-edit', pk, '{% trans "Edit Address" %}');
} }
if (options.allow_delete) { if (options.allow_delete) {
html += makeDeleteButton('btn-address-delete', pk, '{% jstrans "Delete Address" %}'); html += makeDeleteButton('btn-address-delete', pk, '{% trans "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'>
{% jstrans "All selected manufacturer parts will be deleted" %} {% trans "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>{% jstrans "Part" %}</th> <th>{% trans "Part" %}</th>
<th>{% jstrans "MPN" %}</th> <th>{% trans "MPN" %}</th>
<th>{% jstrans "Manufacturer" %}</th> <th>{% trans "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: '{% jstrans "Delete Manufacturer Parts" %}', title: '{% trans "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'>
{% jstrans "All selected parameters will be deleted" %} {% trans "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>{% jstrans "Name" %}</th> <th>{% trans "Name" %}</th>
<th>{% jstrans "Value" %}</th> <th>{% trans "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: '{% jstrans "Delete Parameters" %}', title: '{% trans "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: '{% jstrans "Order parts" %}', title: '{% trans "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: '{% jstrans "Delete manufacturer parts" %}', title: '{% trans "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: '{% jstrans "Manufacturer part actions" %}', title: '{% trans "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 '{% jstrans "No manufacturer parts found" %}'; return '{% trans "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: '{% jstrans "Part" %}', title: '{% trans "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', '{% jstrans "Template part" %}'); html += makeIconBadge('fa-clone', '{% trans "Template part" %}');
} }
if (row.part_detail.assembly) { if (row.part_detail.assembly) {
html += makeIconBadge('fa-tools', '{% jstrans "Assembled part" %}'); html += makeIconBadge('fa-tools', '{% trans "Assembled part" %}');
} }
if (!row.part_detail.active) { if (!row.part_detail.active) {
html += `<span class='badge badge-right rounded-pill bg-warning'>{% jstrans "Inactive" %}</span>`; html += `<span class='badge badge-right rounded-pill bg-warning'>{% trans "Inactive" %}</span>`;
} }
return html; return html;
@ -1283,7 +1283,7 @@ function loadManufacturerPartTable(table, url, options) {
{ {
sortable: true, sortable: true,
field: 'manufacturer', field: 'manufacturer',
title: '{% jstrans "Manufacturer" %}', title: '{% trans "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: '{% jstrans "MPN" %}', title: '{% trans "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: '{% jstrans "Link" %}', title: '{% trans "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: '{% jstrans "Description" %}', title: '{% trans "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, '{% jstrans "Edit manufacturer part" %}'); html += makeEditButton('button-manufacturer-part-edit', pk, '{% trans "Edit manufacturer part" %}');
html += makeDeleteButton('button-manufacturer-part-delete', pk, '{% jstrans "Delete manufacturer part" %}'); html += makeDeleteButton('button-manufacturer-part-delete', pk, '{% trans "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 '{% jstrans "No parameters found" %}'; return '{% trans "No parameters found" %}';
}, },
columns: [ columns: [
{ {
@ -1400,19 +1400,19 @@ function loadManufacturerPartParameterTable(table, url, options) {
}, },
{ {
field: 'name', field: 'name',
title: '{% jstrans "Name" %}', title: '{% trans "Name" %}',
switchable: false, switchable: false,
sortable: true, sortable: true,
}, },
{ {
field: 'value', field: 'value',
title: '{% jstrans "Value" %}', title: '{% trans "Value" %}',
switchable: false, switchable: false,
sortable: true, sortable: true,
}, },
{ {
field: 'units', field: 'units',
title: '{% jstrans "Units" %}', title: '{% trans "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, '{% jstrans "Edit parameter" %}'); html += makeEditButton('button-parameter-edit', pk, '{% trans "Edit parameter" %}');
html += makeDeleteButton('button-parameter-delete', pk, '{% jstrans "Delete parameter" %}'); html += makeDeleteButton('button-parameter-delete', pk, '{% trans "Delete parameter" %}');
return wrapButtons(html); return wrapButtons(html);
} }
@ -1443,7 +1443,7 @@ function loadManufacturerPartParameterTable(table, url, options) {
value: {}, value: {},
units: {}, units: {},
}, },
title: '{% jstrans "Edit Parameter" %}', title: '{% trans "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: '{% jstrans "Delete Parameter" %}', title: '{% trans "Delete Parameter" %}',
refreshTable: table, refreshTable: table,
}); });
}); });
@ -1466,7 +1466,7 @@ function makeSupplierPartActions(options={}) {
return [ return [
{ {
label: 'order', label: 'order',
title: '{% jstrans "Order parts" %}', title: '{% trans "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: '{% jstrans "Delete supplier parts" %}', title: '{% trans "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: '{% jstrans "Supplier part actions" %}', title: '{% trans "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 '{% jstrans "No supplier parts found" %}'; return '{% trans "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: '{% jstrans "Part" %}', title: '{% trans "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', '{% jstrans "Template part" %}'); html += makeIconBadge('fa-clone', '{% trans "Template part" %}');
} }
if (row.part_detail.assembly) { if (row.part_detail.assembly) {
html += makeIconBadge('fa-tools', '{% jstrans "Assembled part" %}'); html += makeIconBadge('fa-tools', '{% trans "Assembled part" %}');
} }
if (!row.part_detail.active) { if (!row.part_detail.active) {
html += `<span class='badge badge-right rounded-pill bg-warning'>{% jstrans "Inactive" %}</span>`; html += `<span class='badge badge-right rounded-pill bg-warning'>{% trans "Inactive" %}</span>`;
} }
return html; return html;
@ -1571,7 +1571,7 @@ function loadSupplierPartTable(table, url, options) {
{ {
sortable: true, sortable: true,
field: 'supplier', field: 'supplier',
title: '{% jstrans "Supplier" %}', title: '{% trans "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: '{% jstrans "Supplier Part" %}', title: '{% trans "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: '{% jstrans "Manufacturer" %}', title: '{% trans "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: '{% jstrans "MPN" %}', title: '{% trans "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: '{% jstrans "Description" %}', title: '{% trans "Description" %}',
sortable: false, sortable: false,
}, },
{ {
field: 'packaging', field: 'packaging',
title: '{% jstrans "Packaging" %}', title: '{% trans "Packaging" %}',
sortable: true, sortable: true,
}, },
{ {
field: 'pack_quantity', field: 'pack_quantity',
title: '{% jstrans "Pack Quantity" %}', title: '{% trans "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='{% jstrans "Base Units" %}: ${row.part_detail.units}'></span>`; html += `<span class='fas fa-info-circle float-right' title='{% trans "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: '{% jstrans "Link" %}', title: '{% trans "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: '{% jstrans "Notes" %}', title: '{% trans "Notes" %}',
sortable: false, sortable: false,
}, },
{ {
field: 'in_stock', field: 'in_stock',
title: '{% jstrans "In Stock" %}', title: '{% trans "In Stock" %}',
sortable: true, sortable: true,
}, },
{ {
field: 'available', field: 'available',
title: '{% jstrans "Availability" %}', title: '{% trans "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',
`{% jstrans "Last Updated" %}: ${date}` `{% trans "Last Updated" %}: ${date}`
); );
return html; return html;
} else { } else {
@ -1700,7 +1700,7 @@ function loadSupplierPartTable(table, url, options) {
}, },
{ {
field: 'updated', field: 'updated',
title: '{% jstrans "Last Updated" %}', title: '{% trans "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, '{% jstrans "Edit supplier part" %}'); html += makeEditButton('button-supplier-part-edit', pk, '{% trans "Edit supplier part" %}');
html += makeDeleteButton('button-supplier-part-delete', pk, '{% jstrans "Delete supplier part" %}'); html += makeDeleteButton('button-supplier-part-delete', pk, '{% trans "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: '{% jstrans "Delete Price Break" %}', title: '{% trans "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: '{% jstrans "Edit Price Break" %}', title: '{% trans "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 '{% jstrans "No price break information found" %}'; return '{% trans "No price break information found" %}';
}, },
onPostBody: function() { onPostBody: function() {
setupCallbacks(); setupCallbacks();
@ -1805,12 +1805,12 @@ function loadSupplierPriceBreakTable(options={}) {
}, },
{ {
field: 'quantity', field: 'quantity',
title: '{% jstrans "Quantity" %}', title: '{% trans "Quantity" %}',
sortable: true, sortable: true,
}, },
{ {
field: 'price', field: 'price',
title: '{% jstrans "Price" %}', title: '{% trans "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: '{% jstrans "Last updated" %}', title: '{% trans "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, '{% jstrans "Edit price break" %}'); buttons += makeEditButton('button-price-break-edit', row.pk, '{% trans "Edit price break" %}');
buttons += makeDeleteButton('button-price-break-delete', row.pk, '{% jstrans "Delete price break" %}'); buttons += makeDeleteButton('button-price-break-delete', row.pk, '{% trans "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: '{% jstrans "true" %}', value: '{% trans "true" %}',
}, },
'0': { '0': {
key: '0', key: '0',
value: '{% jstrans "false" %}', value: '{% trans "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=''>{% jstrans 'Select filter' %}</option>`; html += `<option value=''>{% trans '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 || '{% jstrans "Actions" %}'; let title = action_group.title || '{% trans "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='{% jstrans "Barcode actions" %}' class='btn btn-outline-secondary dropdown-toggle' type='button' data-bs-toggle='dropdown'> <button id='barcode-actions' title='{% trans "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='{% jstrans "Printing actions" %}' class='btn btn-outline-secondary dropdown-toggle' type='button' data-bs-toggle='dropdown'> <button id='printing-options' title='{% trans "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> {% jstrans "Print Labels" %}</a></li>`; print_buttons += `<li><a class='dropdown-item' href='#' id='print-labels-${tableKey}'><span class='fas fa-tag'></span> {% trans "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> {% jstrans "Print Reports" %}</a></li>`; 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 += `</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: '{% jstrans "Download table data" %}', title: '{% trans "Download table data" %}',
icon: 'fa-download', icon: 'fa-download',
}); });
} }
buttons += makeFilterButton({ buttons += makeFilterButton({
id: `reload-${tableKey}`, id: `reload-${tableKey}`,
title: '{% jstrans "Reload table data" %}', title: '{% trans "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: '{% jstrans "Add new filter" %}', title: '{% trans "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: '{% jstrans "Clear all filters" %}', title: '{% trans "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='{% jstrans "Create filter" %}' class='btn btn-outline-secondary filter-button' id='${make}'><span class='fas fa-plus'></span></button>`; html += `<button title='{% trans "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 '{% jstrans "true" %}'; if (value == '1') return '{% trans "true" %}';
if (value == '0') return '{% jstrans "false" %}'; if (value == '0') return '{% trans "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('{% jstrans "Action Prohibited" %}', { showMessage('{% trans "Action Prohibited" %}', {
style: 'danger', style: 'danger',
details: '{% jstrans "Create operation not allowed" %}', details: '{% trans "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('{% jstrans "Action Prohibited" %}', { showMessage('{% trans "Action Prohibited" %}', {
style: 'danger', style: 'danger',
details: '{% jstrans "Update operation not allowed" %}', details: '{% trans "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('{% jstrans "Action Prohibited" %}', { showMessage('{% trans "Action Prohibited" %}', {
style: 'danger', style: 'danger',
details: '{% jstrans "Delete operation not allowed" %}', details: '{% trans "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('{% jstrans "Action Prohibited" %}', { showMessage('{% trans "Action Prohibited" %}', {
style: 'danger', style: 'danger',
details: '{% jstrans "View operation not allowed" %}', details: '{% trans "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 = '{% jstrans "Delete" %}'; options.submitText = '{% trans "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 || '{% jstrans "Confirm" %}'; var message = options.confirmMessage || '{% trans "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 || '{% jstrans "Keep this form open" %}'; var message = options.persistMessage || '{% trans "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] = ['{% jstrans "Enter a valid number" %}']; data_errors[name] = ['{% trans "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>{% jstrans "Form errors exist" %}</b> <b>{% trans "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 '{% jstrans "No results found" %}'; return '{% trans "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 = '{% jstrans "Select" %}' + " " + options.actions[name].label; const title = '{% trans "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="{% jstrans "Search" %} ${options.actions[name].label}..." /> <input class="form-control" type="text" id="${name}_tree_search" placeholder="{% trans "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: '{% jstrans "Select" %}', accept_text: '{% trans "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>{% jstrans "Searching" %}...</span>`; return `<span>{% trans "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='{% jstrans "Clear input" %}'> <button class='input-group-text form-clear' id='clear_${field_name}' title='{% trans "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>{% jstrans "File Column" %}</th><th>{% jstrans "Field Name" %}</th></tr>`; var headers = `<tr><th>{% trans "File Column" %}</th><th>{% trans "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: '{% jstrans "Select Columns" %}', title: '{% trans "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 || '{% jstrans "YES" %}'; text = options.pass || '{% trans "YES" %}';
color = 'bg-success'; color = 'bg-success';
} else { } else {
text = options.fail || '{% jstrans "NO" %}'; text = options.fail || '{% trans "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 = '{% jstrans "True" %}'; options.pass = '{% trans "True" %}';
options.fail = '{% jstrans "False" %}'; options.fail = '{% trans "False" %}';
return yesNoLabel(value, options); return yesNoLabel(value, options);
} }
function editButton(url, text='{% jstrans "Edit" %}') { function editButton(url, text='{% trans "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='{% jstrans "Delete" %}') { function deleteButton(url, text='{% trans "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='{% jstrans "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='{% trans "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 '{% jstrans "No parts required for builds" %}'; return '{% trans "No parts required for builds" %}';
}, },
columns: [ columns: [
{ {
field: 'name', field: 'name',
title: '{% jstrans "Part" %}', title: '{% trans "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: '{% jstrans "Description" %}', title: '{% trans "Description" %}',
}, },
{ {
field: 'total_in_stock', field: 'total_in_stock',
title: '{% jstrans "Available" %}', title: '{% trans "Available" %}',
formatter: function(value, row) { formatter: function(value, row) {
return value; return value;
} }
}, },
{ {
field: 'allocated_to_build_orders', field: 'allocated_to_build_orders',
title: '{% jstrans "Allocated Stock" %}', title: '{% trans "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(
'{% jstrans "Select Items" %}', '{% trans "Select Items" %}',
'{% jstrans "No items selected for printing" %}', '{% trans "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(
'{% jstrans "No Labels Found" %}', '{% trans "No Labels Found" %}',
'{% jstrans "No label templates found which match the selected items" %}', '{% trans "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} {% jstrans "selected" %} ${options.items.length} ${options.plural_name} {% trans "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>{% jstrans "Printing Options" %}</h5>` }, divider: { type: "candy", html: `<hr/><h5>{% trans "Printing Options" %}</h5>` },
...printingOptions, ...printingOptions,
}; };
} }
@ -145,14 +145,14 @@ function printLabels(options) {
} }
const printingFormOptions = { const printingFormOptions = {
title: options.items.length === 1 ? `{% jstrans "Print label" %}` : `{% jstrans "Print labels" %}`, title: options.items.length === 1 ? `{% trans "Print label" %}` : `{% trans "Print labels" %}`,
submitText: `{% jstrans "Print" %}`, submitText: `{% trans "Print" %}`,
method: "POST", method: "POST",
disableSuccessMessage: true, disableSuccessMessage: true,
header_html, header_html,
fields: { fields: {
_label_template: { _label_template: {
label: `{% jstrans "Select label template" %}`, label: `{% trans "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: `{% jstrans "Select plugin" %}`, label: `{% trans "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('{% jstrans "Labels sent to printer" %}', { showMessage('{% trans "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'>{% jstrans "Cancel" %}</button>`; buttons += `<button type='button' class='btn btn-secondary' id='modal-form-close' data-bs-dismiss='modal'>{% trans "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'>{% jstrans "Submit" %}</button>`; buttons += `<button type='button' class='btn btn-${submitClass}' id='modal-form-submit'>{% trans "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='{% jstrans "Close" %}'></button> <button type='button' class='btn-close' data-bs-dismiss='modal' aria-label='{% trans "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 || '{% jstrans "Form Title" %}'); modalSetTitle(modal_name, options.title || '{% trans "Form Title" %}');
modalSetSubmitText(modal_name, options.submitText || '{% jstrans "Submit" %}'); modalSetSubmitText(modal_name, options.submitText || '{% trans "Submit" %}');
modalSetCloseText(modal_name, options.closeText || '{% jstrans "Cancel" %}'); modalSetCloseText(modal_name, options.closeText || '{% trans "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> {% jstrans 'Waiting for server...' %}`; return `<span class='glyphicon glyphicon-refresh glyphicon-refresh-animate'></span> {% trans '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">{% jstrans "Show Error Information" %}</a> <a data-bs-toggle='collapse' href="#collapse-error-info">{% trans "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: '{% jstrans "Close" %}', closeText: '{% trans "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 || '{% jstrans "Accept" %}'; options.submitText = options.accept_text || '{% trans "Accept" %}';
options.closeText = options.cancel_text || '{% jstrans "Cancel" %}'; options.closeText = options.cancel_text || '{% trans "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, '{% jstrans "Loading Data" %}...'); modalSetTitle(modal, '{% trans "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 || '{% jstrans "Submit" %}'; var submit_text = options.submit_text || '{% trans "Submit" %}';
var close_text = options.close_text || '{% jstrans "Close" %}'; var close_text = options.close_text || '{% trans "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('{% jstrans "Invalid response from server" %}', '{% jstrans "Form data missing from server response" %}'); showAlertDialog('{% trans "Invalid response from server" %}', '{% trans "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('{% jstrans "Error posting form data" %}', renderErrorMessage(xhr)); showAlertDialog('{% trans "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 || '{% jstrans "Submit" %}'; var submit_text = options.submit_text || '{% trans "Submit" %}';
var close_text = options.close_text || '{% jstrans "Close" %}'; var close_text = options.close_text || '{% trans "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('{% jstrans "Invalid server response" %}', '{% jstrans "JSON response missing form data" %}'); showAlertDialog('{% trans "Invalid server response" %}', '{% trans "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(
'{% jstrans "No Response" %}', '{% trans "No Response" %}',
'{% jstrans "No response from the InvenTree server" %}', '{% trans "No response from the InvenTree server" %}',
); );
} else if (xhr.status == 400) { } else if (xhr.status == 400) {
showAlertDialog( showAlertDialog(
'{% jstrans "Error 400: Bad Request" %}', '{% trans "Error 400: Bad Request" %}',
'{% jstrans "Server returned error code 400" %}', '{% trans "Server returned error code 400" %}',
); );
} else if (xhr.status == 401) { } else if (xhr.status == 401) {
showAlertDialog( showAlertDialog(
'{% jstrans "Error 401: Not Authenticated" %}', '{% trans "Error 401: Not Authenticated" %}',
'{% jstrans "Authentication credentials not supplied" %}', '{% trans "Authentication credentials not supplied" %}',
); );
} else if (xhr.status == 403) { } else if (xhr.status == 403) {
showAlertDialog( showAlertDialog(
'{% jstrans "Error 403: Permission Denied" %}', '{% trans "Error 403: Permission Denied" %}',
'{% jstrans "You do not have the required permissions to access this function" %}', '{% trans "You do not have the required permissions to access this function" %}',
); );
} else if (xhr.status == 404) { } else if (xhr.status == 404) {
showAlertDialog( showAlertDialog(
'{% jstrans "Error 404: Resource Not Found" %}', '{% trans "Error 404: Resource Not Found" %}',
'{% jstrans "The requested resource could not be located on the server" %}', '{% trans "The requested resource could not be located on the server" %}',
); );
} else if (xhr.status == 408) { } else if (xhr.status == 408) {
showAlertDialog( showAlertDialog(
'{% jstrans "Error 408: Timeout" %}', '{% trans "Error 408: Timeout" %}',
'{% jstrans "Connection timeout while requesting data from server" %}', '{% trans "Connection timeout while requesting data from server" %}',
); );
} else { } else {
showAlertDialog('{% jstrans "Error requesting form data" %}', renderErrorMessage(xhr)); showAlertDialog('{% trans "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'>{% jstrans "No Stock"% }</span>`; stock_detail = `<span class='badge rounded-pill bg-danger'>{% trans "No Stock"% }</span>`;
} else { } else {
if (data.serial && data.quantity == 1) { if (data.serial && data.quantity == 1) {
stock_detail = `{% jstrans "Serial Number" %}: ${data.serial}`; stock_detail = `{% trans "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 = `{% jstrans "Available" %}: ${available}`; stock_detail = `{% trans "Available" %}: ${available}`;
} else { } else {
stock_detail = `{% jstrans "Quantity" %}: ${data.quantity}`; stock_detail = `{% trans "Quantity" %}: ${data.quantity}`;
} }
} }
if (data.batch) { if (data.batch) {
stock_detail += ` - <small>{% jstrans "Batch" %}: ${data.batch}</small>`; stock_detail += ` - <small>{% trans "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'>{% jstrans "Inactive" %}</span>`; labels += `<span class='badge badge-right rounded-pill bg-danger'>{% trans "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: `{% jstrans "Shipment" %} ${data.reference}`, textSecondary: `{% trans "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 '{% jstrans "No news found" %}'; return '{% trans "No news found" %}';
}, },
columns: [ columns: [
{ {
field: 'pk', field: 'pk',
title: '{% jstrans "ID" %}', title: '{% trans "ID" %}',
visible: false, visible: false,
switchable: false, switchable: false,
}, },
{ {
field: 'title', field: 'title',
title: '{% jstrans "Title" %}', title: '{% trans "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: '{% jstrans "Summary" %}', title: '{% trans "Summary" %}',
}, },
{ {
field: 'author', field: 'author',
title: '{% jstrans "Author" %}', title: '{% trans "Author" %}',
}, },
{ {
field: 'published', field: 'published',
title: '{% jstrans "Published" %}', title: '{% trans "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: '{% jstrans "ID" %}', title: '{% trans "ID" %}',
visible: false, visible: false,
switchable: false, switchable: false,
}, },
{ {
field: 'age', field: 'age',
title: '{% jstrans "Age" %}', title: '{% trans "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: '{% jstrans "Category" %}', title: '{% trans "Category" %}',
sortable: 'true', sortable: 'true',
}, },
{ {
field: 'name', field: 'name',
title: '{% jstrans "Notification" %}', title: '{% trans "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: '{% jstrans "Message" %}', title: '{% trans "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='{% 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>`; 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>`;
} }
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 = '{% jstrans "Mark as unread" %}'; bReadText = '{% trans "Mark as unread" %}';
bReadIcon = 'fas fa-bookmark icon-red'; bReadIcon = 'fas fa-bookmark icon-red';
bReadTarget = 'unread'; bReadTarget = 'unread';
} else { } else {
bReadText = '{% jstrans "Mark as read" %}'; bReadText = '{% trans "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>{% jstrans "No unread notifications" %}</em><span class='fas fa-check-circle icon-green float-right'></span></p>`; html = `<p class='text-muted'><em>{% trans "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'>{% jstrans "Notifications will load here" %}</p>`); $('#notification-center').html(`<p class='text-muted'>{% trans "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: '{% jstrans "Add Extra Line Item" %}', title: '{% trans "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: '{% jstrans "Export Order" %}', title: '{% trans "Export Order" %}',
fields: { fields: {
format: { format: {
label: '{% jstrans "Format" %}', label: '{% trans "Format" %}',
help_text: '{% jstrans "Select file format" %}', help_text: '{% trans "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: '{% jstrans "Duplicate Line" %}', title: '{% trans "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: '{% jstrans "Edit Line" %}', title: '{% trans "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: '{% jstrans "Delete Line" %}', title: '{% trans "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 '{% jstrans "No line items found" %}'; return '{% trans "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: '{% jstrans "Reference" %}', title: '{% trans "Reference" %}',
switchable: false, switchable: false,
}, },
{ {
sortable: false, sortable: false,
switchable: true, switchable: true,
field: 'description', field: 'description',
title: '{% jstrans "Description" %}', title: '{% trans "Description" %}',
}, },
{ {
sortable: true, sortable: true,
switchable: false, switchable: false,
field: 'quantity', field: 'quantity',
title: '{% jstrans "Quantity" %}', title: '{% trans "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: '{% jstrans "Unit Price" %}', title: '{% trans "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: '{% jstrans "Total Price" %}', title: '{% trans "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: '{% jstrans "Notes" %}', title: '{% trans "Notes" %}',
}, },
{ {
field: 'link', field: 'link',
title: '{% jstrans "Link" %}', title: '{% trans "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, '{% jstrans "Duplicate line" %}'); html += makeCopyButton('button-duplicate', pk, '{% trans "Duplicate line" %}');
html += makeEditButton('button-edit', pk, '{% jstrans "Edit line" %}'); html += makeEditButton('button-edit', pk, '{% trans "Edit line" %}');
} }
if (options.allow_delete) { if (options.allow_delete) {
html += makeDeleteButton('button-delete', pk, '{% jstrans "Delete line" %}', ); html += makeDeleteButton('button-delete', pk, '{% trans "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 '{% jstrans "No plugins found" %}'; return '{% trans "No plugins found" %}';
}, },
columns: [ columns: [
{ {
field: 'name', field: 'name',
title: '{% jstrans "Plugin" %}', title: '{% trans "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='{% jstrans "This plugin is no longer installed" %}'></span>`; html += `<span class='fa fa-question-circle' title='{% trans "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='{% jstrans "This plugin is active" %}'></span>`; html += `<span class='fa fa-check-circle icon-green' title='{% trans "This plugin is active" %}'></span>`;
} else { } else {
html += `<span class='fa fa-times-circle icon-red' title ='{% jstrans "This plugin is installed but not active" %}'></span>`; html += `<span class='fa fa-times-circle icon-red' title ='{% trans "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'>{% jstrans "Builtin" %}</span>`; html += `<span class='badge bg-success rounded-pill badge-right'>{% trans "Builtin" %}</span>`;
} }
if (row.is_sample) { if (row.is_sample) {
html += `<span class='badge bg-info rounded-pill badge-right'>{% jstrans "Sample" %}</span>`; html += `<span class='badge bg-info rounded-pill badge-right'>{% trans "Sample" %}</span>`;
} }
return html; return html;
@ -77,13 +77,13 @@ function loadPluginTable(table, options={}) {
}, },
{ {
field: 'meta.description', field: 'meta.description',
title: '{% jstrans "Description" %}', title: '{% trans "Description" %}',
sortable: false, sortable: false,
switchable: true, switchable: true,
}, },
{ {
field: 'meta.version', field: 'meta.version',
title: '{% jstrans "Version" %}', title: '{% trans "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: '{% jstrans "Author" %}', title: '{% trans "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, '{% jstrans "Disable Plugin" %}'); buttons += makeIconButton('fa-stop-circle icon-red', 'btn-plugin-disable', row.pk, '{% trans "Disable Plugin" %}');
} else { } else {
buttons += makeIconButton('fa-play-circle icon-green', 'btn-plugin-enable', row.pk, '{% jstrans "Enable Plugin" %}'); buttons += makeIconButton('fa-play-circle icon-green', 'btn-plugin-enable', row.pk, '{% trans "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: '{% jstrans "Install Plugin" %}', title: '{% trans "Install Plugin" %}',
fields: { fields: {
packagename: {}, packagename: {},
url: {}, url: {},
confirm: {}, confirm: {},
}, },
onSuccess: function(data) { onSuccess: function(data) {
let msg = '{% jstrans "The Plugin was installed" %}'; let msg = '{% trans "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'>
{% jstrans "Are you sure you want to enable this plugin?" %} {% trans "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'>
{% jstrans "Are you sure you want to disable this plugin?" %} {% trans "Are you sure you want to disable this plugin?" %}
</span> </span>
`; `;
constructForm(null, { constructForm(null, {
title: active ? '{% jstrans "Enable Plugin" %}' : '{% jstrans "Disable Plugin" %}', title: active ? '{% trans "Enable Plugin" %}' : '{% trans "Disable Plugin" %}',
preFormContent: html, preFormContent: html,
confirm: true, confirm: true,
submitText: active ? '{% jstrans "Enable" %}' : '{% jstrans "Disable" %}', submitText: active ? '{% trans "Enable" %}' : '{% trans "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('{% jstrans "Plugin updated" %}', {style: 'success'}); addCachedAlert('{% trans "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: '{% jstrans "Reload Plugins" %}', title: '{% trans "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='{% jstrans "Error fetching currency data" %}'></span>`; return `<span class='icon-red fas fa-exclamation-circle' title='{% trans "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 '{% jstrans "No BOM data available" %}'; return '{% trans "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: '{% jstrans "Maximum Price" %}', label: '{% trans "Maximum Price" %}',
data: maxValues, data: maxValues,
backgroundColor: colors, backgroundColor: colors,
}, },
{ {
label: '{% jstrans "Minimum Price" %}', label: '{% trans "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: '{% jstrans "Part" %}', title: '{% trans "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: '{% jstrans "Quantity" %}', title: '{% trans "Quantity" %}',
sortable: true, sortable: true,
}, },
{ {
field: 'reference', field: 'reference',
title: '{% jstrans "Reference" %}', title: '{% trans "Reference" %}',
sortable: true, sortable: true,
}, },
{ {
field: 'pricing', field: 'pricing',
title: '{% jstrans "Price Range" %}', title: '{% trans "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 '{% jstrans "No supplier pricing data available" %}'; return '{% trans "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} - {% jstrans "Quantity" %} ${x.quantity}`)); var graphLabels = Array.from(data, (x) => (`${x.part_detail.SKU} - {% trans "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: '{% jstrans "Supplier Pricing" %}', label: '{% trans "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: '{% jstrans "Supplier" %}', title: '{% trans "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: '{% jstrans "SKU" %}', title: '{% trans "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: '{% jstrans "Quantity" %}', title: '{% trans "Quantity" %}',
}, },
{ {
sortable: true, sortable: true,
field: 'price', field: 'price',
title: '{% jstrans "Unit Price" %}', title: '{% trans "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 `{% jstrans "No price break data available" %}`; return `{% trans "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: '{% jstrans "Unit Price" %}', label: '{% trans "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: '{% jstrans "Quantity" %}', title: '{% trans "Quantity" %}',
sortable: true, sortable: true,
}, },
{ {
field: 'price', field: 'price',
title: '{% jstrans "Price" %}', title: '{% trans "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, `{% jstrans "Edit" %} ${human_name}`); buttons += makeEditButton(`button-${name}-edit`, row.pk, `{% trans "Edit" %} ${human_name}`);
buttons += makeDeleteButton(`button-${name}-delete`, row.pk, `{% jstrans "Delete" %} ${human_name}"`); buttons += makeDeleteButton(`button-${name}-delete`, row.pk, `{% trans "Delete" %} ${human_name}"`);
html += wrapButtons(buttons); html += wrapButtons(buttons);
@ -681,7 +681,7 @@ function initPriceBreakSet(table, options) {
}, },
}, },
method: 'POST', method: 'POST',
title: '{% jstrans "Add Price Break" %}', title: '{% trans "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: '{% jstrans "Delete Price Break" %}', title: '{% trans "Delete Price Break" %}',
onSuccess: reloadPriceBreakTable, onSuccess: reloadPriceBreakTable,
}); });
}); });
@ -709,7 +709,7 @@ function initPriceBreakSet(table, options) {
icon: 'fa-coins', icon: 'fa-coins',
}, },
}, },
title: '{% jstrans "Edit Price Break" %}', title: '{% trans "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 '{% jstrans "No purchase history data available" %}'; return '{% trans "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: '{% jstrans "Purchase Price History" %}', label: '{% trans "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: '{% jstrans "Purchase Order" %}', title: '{% trans "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: '{% jstrans "Date" %}', title: '{% trans "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: '{% jstrans "Unit Price" %}', title: '{% trans "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 '{% jstrans "No sales history data available" %}'; return '{% trans "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: '{% jstrans "Sale Price History" %}', label: '{% trans "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: '{% jstrans "Sales Order" %}', title: '{% trans "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: '{% jstrans "Date" %}', title: '{% trans "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: '{% jstrans "Sale Price" %}', title: '{% trans "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 '{% jstrans "No variant data available" %}'; return '{% trans "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: '{% jstrans "Minimum Price" %}', label: '{% trans "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: '{% jstrans "Maximum Price" %}', label: '{% trans "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: '{% jstrans "Variant Part" %}', title: '{% trans "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: '{% jstrans "Price Range" %}', title: '{% trans "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: '{% jstrans "Add Supplier" %}', title: '{% trans "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: '{% jstrans "Purchase Order" %}', label: '{% trans "Purchase Order" %}',
help_text: '{% jstrans "Select purchase order to duplicate" %}', help_text: '{% trans "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: '{% jstrans "Duplicate Line Items" %}', label: '{% trans "Duplicate Line Items" %}',
help_text: '{% jstrans "Duplicate all line items from the selected order" %}', help_text: '{% trans "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: '{% jstrans "Duplicate Extra Lines" %}', label: '{% trans "Duplicate Extra Lines" %}',
help_text: '{% jstrans "Duplicate extra line items from the selected order" %}', help_text: '{% trans "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: '{% jstrans "Edit Purchase Order" %}', title: '{% trans "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: '{% jstrans "Duplication Options" %}', title: '{% trans "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 || '{% jstrans "Create Purchase Order" %}', title: options.title || '{% trans "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> {% jstrans "Pack Quantity" %}: ${formatDecimal(pack_quantity)} ${units}`; var txt = `<span class='fas fa-info-circle icon-blue'></span> {% trans "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: '{% jstrans "Add Supplier Part" %}', title: '{% trans "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: '{% jstrans "Add Line Item" %}', title: '{% trans "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: '{% jstrans "Complete Purchase Order" %}', title: '{% trans "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'>
{% jstrans "Mark this order as complete?" %} {% trans "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'>
{% jstrans "All line items have been received" %} {% trans "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'>
{% jstrans 'This order has line items which have not been marked as received.' %}</br> {% trans 'This order has line items which have not been marked as received.' %}</br>
{% jstrans 'Completing this order means that the order and line items will no longer be editable.' %} {% trans '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: '{% jstrans "Cancel Purchase Order" %}', title: '{% trans "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'>
{% jstrans "Are you sure you wish to cancel this purchase order?" %} {% trans "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'>
{% jstrans "This purchase order can not be cancelled" %} {% trans "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'>
{% jstrans 'After placing this order, line items will no longer be editable.' %} {% trans '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: '{% jstrans "Issue Purchase Order" %}', title: '{% trans "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(
'{% jstrans "Select Parts" %}', '{% trans "Select Parts" %}',
'{% jstrans "At least one purchaseable part must be selected" %}', '{% trans "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: '{% jstrans "Quantity to order" %}', title: '{% trans "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='{% jstrans "New supplier part" %}'> <button type='button' class='input-group-text button-row-new-sp' pk='${pk}' title='{% trans "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='{% jstrans "New purchase order" %}'> <button type='button' class='input-group-text button-row-new-po' pk='${pk}' title='{% trans "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,
'{% jstrans "Remove row" %}', '{% trans "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,
'{% jstrans "Add to purchase order" %}', '{% trans "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>{% jstrans "Part" %}</th> <th>{% trans "Part" %}</th>
<th style='min-width: 300px;'>{% jstrans "Supplier Part" %}</th> <th style='min-width: 300px;'>{% trans "Supplier Part" %}</th>
<th style='min-width: 300px;'>{% jstrans "Purchase Order" %}</th> <th style='min-width: 300px;'>{% trans "Purchase Order" %}</th>
<th style='min-width: 50px;'>{% jstrans "Quantity" %}</th> <th style='min-width: 50px;'>{% trans "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: '{% jstrans "Order Parts" %}', title: '{% trans "Order Parts" %}',
hideSubmitButton: true, hideSubmitButton: true,
closeText: '{% jstrans "Close" %}', closeText: '{% trans "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> {% jstrans "Pack Quantity" %}: ${pack_quantity} ${units}`; var txt = `<span class='fas fa-info-circle icon-blue'></span> {% trans "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 '{% jstrans "No matching supplier parts" %}'; return '{% trans "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 '{% jstrans "No matching purchase orders" %}'; return '{% trans "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(
'{% jstrans "Select Line Items" %}', '{% trans "Select Line Items" %}',
'{% jstrans "At least one line item must be selected" %}', '{% trans "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'>
{% jstrans "Pack Quantity" %}: ${pack_quantity}<br> {% trans "Pack Quantity" %}: ${pack_quantity}<br>
{% jstrans "Received Quantity" %}: <span class='pack_received_quantity' id='items_received_quantity_${pk}'>${received}</span> ${units} {% trans "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: '{% jstrans "Quantity to receive" %}', title: '{% trans "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: '{% jstrans "Batch Code" %}', label: '{% trans "Batch Code" %}',
help_text: '{% jstrans "Enter batch code for incoming stock items" %}', help_text: '{% trans "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: '{% jstrans "Serial Numbers" %}', label: '{% trans "Serial Numbers" %}',
help_text: '{% jstrans "Enter serial numbers for incoming stock items" %}', help_text: '{% trans "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: '{% jstrans "Location" %}', label: '{% trans "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: '{% jstrans "Stock Status" %}', label: '{% trans "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, '{% jstrans "Add barcode" %}'); buttons += makeIconButton('fa-qrcode', 'button-row-add-barcode', pk, '{% trans "Add barcode" %}');
buttons += makeIconButton('fa-unlink icon-red', 'button-row-remove-barcode', pk, '{% jstrans "Remove barcode" %}', {hidden: true}); buttons += makeIconButton('fa-unlink icon-red', 'button-row-remove-barcode', pk, '{% trans "Remove barcode" %}', {hidden: true});
} }
buttons += makeIconButton('fa-sitemap', 'button-row-add-location', pk, '{% jstrans "Specify location" %}', { buttons += makeIconButton('fa-sitemap', 'button-row-add-location', pk, '{% trans "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,
'{% jstrans "Add batch code" %}', '{% trans "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,
'{% jstrans "Add serial numbers" %}', '{% trans "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, '{% jstrans "Remove row" %}'); buttons += makeRemoveButton('button-row-remove', pk, '{% trans "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>{% jstrans "Location" %}</th> <th>{% trans "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>{% jstrans "Batch" %}</th> <th>{% trans "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>{% jstrans "Serials" %}</th> <th>{% trans "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>{% jstrans "Part" %}</th> <th>{% trans "Part" %}</th>
<th>{% jstrans "Order Code" %}</th> <th>{% trans "Order Code" %}</th>
<th>{% jstrans "Received" %}</th> <th>{% trans "Received" %}</th>
<th style='min-width: 50px;'>{% jstrans "Quantity to Receive" %}</th> <th style='min-width: 50px;'>{% trans "Quantity to Receive" %}</th>
<th style='min-width: 150px;'>{% jstrans "Status" %}</th> <th style='min-width: 150px;'>{% trans "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: '{% jstrans "Confirm receipt of items" %}', confirmMessage: '{% trans "Confirm receipt of items" %}',
title: '{% jstrans "Receive Purchase Order Items" %}', title: '{% trans "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('{% jstrans "Scan Item Barcode" %}', { barcodeDialog('{% trans "Scan Item Barcode" %}', {
details: '{% jstrans "Scan barcode on incoming item (must not match any existing stock items)" %}', details: '{% trans "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, '{% jstrans "Barcode matches existing item" %}'); showBarcodeMessage(barcode_options.modal, '{% trans "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, '{% jstrans "Invalid barcode data" %}'); showBarcodeMessage(barcode_options.modal, '{% trans "Invalid barcode data" %}');
} }
} }
}); });
@ -1648,7 +1648,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 '{% jstrans "No purchase orders found" %}'; return '{% trans "No purchase orders found" %}';
}, },
buttons: constructOrderTableButtons({ buttons: constructOrderTableButtons({
prefix: 'purchaseorder', prefix: 'purchaseorder',
@ -1667,7 +1667,7 @@ function loadPurchaseOrderTable(table, options) {
}, },
{ {
field: 'reference', field: 'reference',
title: '{% jstrans "Purchase Order" %}', title: '{% trans "Purchase Order" %}',
sortable: true, sortable: true,
switchable: false, switchable: false,
formatter: function(value, row) { formatter: function(value, row) {
@ -1675,7 +1675,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', '{% jstrans "Order is overdue" %}'); html += makeIconBadge('fa-calendar-times icon-red', '{% trans "Order is overdue" %}');
} }
return html; return html;
@ -1683,7 +1683,7 @@ function loadPurchaseOrderTable(table, options) {
}, },
{ {
field: 'supplier_detail', field: 'supplier_detail',
title: '{% jstrans "Supplier" %}', title: '{% trans "Supplier" %}',
sortable: true, sortable: true,
sortName: 'supplier__name', sortName: 'supplier__name',
formatter: function(value, row) { formatter: function(value, row) {
@ -1696,15 +1696,15 @@ function loadPurchaseOrderTable(table, options) {
}, },
{ {
field: 'supplier_reference', field: 'supplier_reference',
title: '{% jstrans "Supplier Reference" %}', title: '{% trans "Supplier Reference" %}',
}, },
{ {
field: 'description', field: 'description',
title: '{% jstrans "Description" %}', title: '{% trans "Description" %}',
}, },
{ {
field: 'project_code', field: 'project_code',
title: '{% jstrans "Project Code" %}', title: '{% trans "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,
@ -1716,7 +1716,7 @@ function loadPurchaseOrderTable(table, options) {
}, },
{ {
field: 'status', field: 'status',
title: '{% jstrans "Status" %}', title: '{% trans "Status" %}',
switchable: true, switchable: true,
sortable: true, sortable: true,
formatter: function(value, row) { formatter: function(value, row) {
@ -1725,7 +1725,7 @@ function loadPurchaseOrderTable(table, options) {
}, },
{ {
field: 'creation_date', field: 'creation_date',
title: '{% jstrans "Date" %}', title: '{% trans "Date" %}',
sortable: true, sortable: true,
formatter: function(value) { formatter: function(value) {
return renderDate(value); return renderDate(value);
@ -1733,7 +1733,7 @@ function loadPurchaseOrderTable(table, options) {
}, },
{ {
field: 'target_date', field: 'target_date',
title: '{% jstrans "Target Date" %}', title: '{% trans "Target Date" %}',
sortable: true, sortable: true,
formatter: function(value) { formatter: function(value) {
return renderDate(value); return renderDate(value);
@ -1741,12 +1741,12 @@ function loadPurchaseOrderTable(table, options) {
}, },
{ {
field: 'line_items', field: 'line_items',
title: '{% jstrans "Items" %}', title: '{% trans "Items" %}',
sortable: true, sortable: true,
}, },
{ {
field: 'total_price', field: 'total_price',
title: '{% jstrans "Total Cost" %}', title: '{% trans "Total Cost" %}',
switchable: true, switchable: true,
sortable: true, sortable: true,
formatter: function(value, row) { formatter: function(value, row) {
@ -1757,7 +1757,7 @@ function loadPurchaseOrderTable(table, options) {
}, },
{ {
field: 'responsible', field: 'responsible',
title: '{% jstrans "Responsible" %}', title: '{% trans "Responsible" %}',
switchable: true, switchable: true,
sortable: true, sortable: true,
formatter: function(value, row) { formatter: function(value, row) {
@ -1837,16 +1837,16 @@ function deletePurchaseOrderLineItems(items, options={}) {
var html = ` var html = `
<div class='alert alert-block alert-danger'> <div class='alert alert-block alert-danger'>
{% jstrans "All selected Line items will be deleted" %} {% trans "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>{% jstrans "Part" %}</th> <th>{% trans "Part" %}</th>
<th>{% jstrans "Description" %}</th> <th>{% trans "Description" %}</th>
<th>{% jstrans "SKU" %}</th> <th>{% trans "SKU" %}</th>
<th>{% jstrans "MPN" %}</th> <th>{% trans "MPN" %}</th>
<th>{% jstrans "Quantity" %}</th> <th>{% trans "Quantity" %}</th>
</tr> </tr>
${rows} ${rows}
</table> </table>
@ -1855,7 +1855,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: '{% jstrans "Delete selected Line items?" %}', title: '{% trans "Delete selected Line items?" %}',
form_data: { form_data: {
items: ids, items: ids,
}, },
@ -1910,7 +1910,7 @@ function loadPurchaseOrderLineItemTable(table, options={}) {
method: 'POST', method: 'POST',
fields: fields, fields: fields,
data: data, data: data,
title: '{% jstrans "Duplicate Line Item" %}', title: '{% trans "Duplicate Line Item" %}',
refreshTable: table, refreshTable: table,
}); });
} }
@ -1925,7 +1925,7 @@ function loadPurchaseOrderLineItemTable(table, options={}) {
constructForm(`{% url "api-po-line-list" %}${pk}/`, { constructForm(`{% url "api-po-line-list" %}${pk}/`, {
fields: fields, fields: fields,
title: '{% jstrans "Edit Line Item" %}', title: '{% trans "Edit Line Item" %}',
refreshTable: table, refreshTable: table,
}); });
}); });
@ -1936,7 +1936,7 @@ function loadPurchaseOrderLineItemTable(table, options={}) {
constructForm(`{% url "api-po-line-list" %}${pk}/`, { constructForm(`{% url "api-po-line-list" %}${pk}/`, {
method: 'DELETE', method: 'DELETE',
title: '{% jstrans "Delete Line Item" %}', title: '{% trans "Delete Line Item" %}',
refreshTable: table, refreshTable: table,
}); });
}); });
@ -1984,7 +1984,7 @@ function loadPurchaseOrderLineItemTable(table, options={}) {
name: 'purchaseorderlines', name: 'purchaseorderlines',
sidePagination: 'server', sidePagination: 'server',
formatNoMatches: function() { formatNoMatches: function() {
return '{% jstrans "No line items found" %}'; return '{% trans "No line items found" %}';
}, },
queryParams: filters, queryParams: filters,
original: options.params, original: options.params,
@ -2001,7 +2001,7 @@ function loadPurchaseOrderLineItemTable(table, options={}) {
field: 'part', field: 'part',
sortable: true, sortable: true,
sortName: 'part_name', sortName: 'part_name',
title: '{% jstrans "Part" %}', title: '{% trans "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) {
@ -2011,18 +2011,18 @@ function loadPurchaseOrderLineItemTable(table, options={}) {
} }
}, },
footerFormatter: function() { footerFormatter: function() {
return '{% jstrans "Total" %}'; return '{% trans "Total" %}';
} }
}, },
{ {
field: 'part_detail.description', field: 'part_detail.description',
title: '{% jstrans "Description" %}', title: '{% trans "Description" %}',
}, },
{ {
sortable: true, sortable: true,
sortName: 'SKU', sortName: 'SKU',
field: 'supplier_part_detail.SKU', field: 'supplier_part_detail.SKU',
title: '{% jstrans "SKU" %}', title: '{% trans "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}/`));
@ -2034,7 +2034,7 @@ function loadPurchaseOrderLineItemTable(table, options={}) {
{ {
sortable: false, sortable: false,
field: 'supplier_part_detail.link', field: 'supplier_part_detail.link',
title: '{% jstrans "Link" %}', title: '{% trans "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});
@ -2047,7 +2047,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: '{% jstrans "MPN" %}', title: '{% trans "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}/`));
@ -2059,13 +2059,13 @@ function loadPurchaseOrderLineItemTable(table, options={}) {
{ {
sortable: true, sortable: true,
field: 'reference', field: 'reference',
title: '{% jstrans "Reference" %}', title: '{% trans "Reference" %}',
}, },
{ {
sortable: true, sortable: true,
switchable: false, switchable: false,
field: 'quantity', field: 'quantity',
title: '{% jstrans "Quantity" %}', title: '{% trans "Quantity" %}',
formatter: function(value, row) { formatter: function(value, row) {
let units = ''; let units = '';
@ -2078,7 +2078,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='{% jstrans "Pack Quantity" %}: ${pack_quantity} - {% jstrans "Total Quantity" %}: ${total}${units}'></span>`; data += `<span class='fas fa-info-circle icon-blue float-right' title='{% trans "Pack Quantity" %}: ${pack_quantity} - {% trans "Total Quantity" %}: ${total}${units}'></span>`;
} }
return data; return data;
@ -2095,7 +2095,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: '{% jstrans "Pack Quantity" %}', title: '{% trans "Pack Quantity" %}',
formatter: function(value, row) { formatter: function(value, row) {
var units = row.part_detail.units; var units = row.part_detail.units;
@ -2109,7 +2109,7 @@ function loadPurchaseOrderLineItemTable(table, options={}) {
{ {
sortable: true, sortable: true,
field: 'purchase_price', field: 'purchase_price',
title: '{% jstrans "Unit Price" %}', title: '{% trans "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,
@ -2119,7 +2119,7 @@ function loadPurchaseOrderLineItemTable(table, options={}) {
{ {
field: 'total_price', field: 'total_price',
sortable: true, sortable: true,
title: '{% jstrans "Total Price" %}', title: '{% trans "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
@ -2141,13 +2141,13 @@ function loadPurchaseOrderLineItemTable(table, options={}) {
sortable: true, sortable: true,
field: 'target_date', field: 'target_date',
switchable: true, switchable: true,
title: '{% jstrans "Target Date" %}', title: '{% trans "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', '{% jstrans "This line item is overdue" %}'); html += makeIconBadge('fa-calendar-times icon-red', '{% trans "This line item is overdue" %}');
} }
return html; return html;
@ -2163,7 +2163,7 @@ function loadPurchaseOrderLineItemTable(table, options={}) {
sortable: false, sortable: false,
field: 'received', field: 'received',
switchable: false, switchable: false,
title: '{% jstrans "Received" %}', title: '{% trans "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}`,
@ -2183,7 +2183,7 @@ function loadPurchaseOrderLineItemTable(table, options={}) {
}, },
{ {
field: 'destination', field: 'destination',
title: '{% jstrans "Destination" %}', title: '{% trans "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}/`);
@ -2194,11 +2194,11 @@ function loadPurchaseOrderLineItemTable(table, options={}) {
}, },
{ {
field: 'notes', field: 'notes',
title: '{% jstrans "Notes" %}', title: '{% trans "Notes" %}',
}, },
{ {
field: 'link', field: 'link',
title: '{% jstrans "Link" %}', title: '{% trans "Link" %}',
formatter: function(value) { formatter: function(value) {
if (value) { if (value) {
return renderLink(value, value); return renderLink(value, value);
@ -2214,13 +2214,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, '{% jstrans "Receive line item" %}'); buttons += makeIconButton('fa-sign-in-alt icon-green', 'button-line-receive', pk, '{% trans "Receive line item" %}');
} }
if (options.allow_edit) { if (options.allow_edit) {
buttons += makeCopyButton('button-line-duplicate', pk, '{% jstrans "Duplicate line item" %}'); buttons += makeCopyButton('button-line-duplicate', pk, '{% trans "Duplicate line item" %}');
buttons += makeEditButton('button-line-edit', pk, '{% jstrans "Edit line item" %}'); buttons += makeEditButton('button-line-edit', pk, '{% trans "Edit line item" %}');
buttons += makeDeleteButton('button-line-delete', pk, '{% jstrans "Delete line item" %}'); buttons += makeDeleteButton('button-line-delete', pk, '{% trans "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} {% jstrans "items selected" %} ${items.length} {% trans "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'>
{% jstrans "Select Report Template" %} {% trans "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, '{% jstrans "Select Test Report Template" %}'); modalSetTitle(modal, '{% trans "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(
'{% jstrans "Select Items" %}', '{% trans "Select Items" %}',
'{% jstrans "No items selected for printing" }', '{% trans "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(
'{% jstrans "No Reports Found" %}', '{% trans "No Reports Found" %}',
'{% jstrans "No report templates found which match the selected items" %}', '{% trans "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: '{% jstrans "Add Customer" %}', title: '{% trans "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: '{% jstrans "Create Return Order" %}', title: '{% trans "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: '{% jstrans "Edit Return Order" %}', title: '{% trans "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'>
{% jstrans 'After placing this order, line items will no longer be editable.' %} {% trans '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: '{% jstrans "Issue Return Order" %}', title: '{% trans "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'>
{% jstrans "Are you sure you wish to cancel this Return Order?" %} {% trans "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: '{% jstrans "Cancel Return Order" %}', title: '{% trans "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'>
{% jstrans "Mark this order as complete?" %} {% trans "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: '{% jstrans "Complete Return Order" %}', title: '{% trans "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 '{% jstrans "No return orders found" %}'; return '{% trans "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: '{% jstrans "Return Order" %}', title: '{% trans "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', '{% jstrans "Order is overdue" %}'); html += makeIconBadge('fa-calendar-times icon-red', '{% trans "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: '{% jstrans "Customer" %}', title: '{% trans "Customer" %}',
formatter: function(value, row) { formatter: function(value, row) {
if (!row.customer_detail) { if (!row.customer_detail) {
return '{% jstrans "Invalid Customer" %}'; return '{% trans "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: '{% jstrans "Customer Reference" %}', title: '{% trans "Customer Reference" %}',
}, },
{ {
sortable: false, sortable: false,
field: 'description', field: 'description',
title: '{% jstrans "Description" %}', title: '{% trans "Description" %}',
}, },
{ {
field: 'project_code', field: 'project_code',
title: '{% jstrans "Project Code" %}', title: '{% trans "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: '{% jstrans "Status" %}', title: '{% trans "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: '{% jstrans "Creation Date" %}', title: '{% trans "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: '{% jstrans "Target Date" %}', title: '{% trans "Target Date" %}',
formatter: function(value) { formatter: function(value) {
return renderDate(value); return renderDate(value);
} }
}, },
{ {
field: 'line_items', field: 'line_items',
title: '{% jstrans "Items" %}', title: '{% trans "Items" %}',
sortable: true, sortable: true,
}, },
{ {
field: 'responsible', field: 'responsible',
title: '{% jstrans "Responsible" %}', title: '{% trans "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: '{% jstrans "Total Cost" %}', title: '{% trans "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: '{% jstrans "Add Line Item" %}', title: '{% trans "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: '{% jstrans "Edit Line Item" %}', title: '{% trans "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(
'{% jstrans "Select Line Items"% }', '{% trans "Select Line Items"% }',
'{% jstrans "At least one line item must be selected" %}' '{% trans "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, '{% jstrans "Remove row" %}'); buttons += makeRemoveButton('button-row-remove', pk, '{% trans "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>{% jstrans "Part" %}</th> <th>{% trans "Part" %}</th>
<th>{% jstrans "Serial Number" %}</th> <th>{% trans "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: '{% jstrans "Confirm receipt of items" %}', confirmMessage: '{% trans "Confirm receipt of items" %}',
title: '{% jstrans "Receive Return Order Items" %}', title: '{% trans "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: '{% jstrans "Edit Line Item" %}', title: '{% trans "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: '{% jstrans "Delete Line Item" %}', title: '{% trans "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 '{% jstrans "No matching line items" %}'; return '{% trans "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: '{% jstrans "Part" %}', title: '{% trans "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: '{% jstrans "Item" %}', title: '{% trans "Item" %}',
formatter: function(value, row) { formatter: function(value, row) {
return renderLink(`{% jstrans "Serial Number" %}: ${row.item_detail.serial}`, `/stock/item/${row.item}/`); return renderLink(`{% trans "Serial Number" %}: ${row.item_detail.serial}`, `/stock/item/${row.item}/`);
} }
}, },
{ {
field: 'reference', field: 'reference',
title: '{% jstrans "Reference" %}', title: '{% trans "Reference" %}',
}, },
{ {
field: 'outcome', field: 'outcome',
title: '{% jstrans "Outcome" %}', title: '{% trans "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: '{% jstrans "Price" %}', title: '{% trans "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: '{% jstrans "Target Date" %}', title: '{% trans "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', '{% jstrans "This line item is overdue" %}'); html += makeIconBadge('fa-calendar-times icon-red', '{% trans "This line item is overdue" %}');
} }
return html; return html;
@ -761,7 +761,7 @@ function loadReturnOrderLineItemTable(options={}) {
}, },
{ {
field: 'received_date', field: 'received_date',
title: '{% jstrans "Received" %}', title: '{% trans "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: '{% jstrans "Notes" %}', title: '{% trans "Notes" %}',
}, },
{ {
field: 'link', field: 'link',
title: '{% jstrans "Link" %}', title: '{% trans "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, '{% jstrans "Mark item as received" %}'); buttons += makeIconButton('fa-sign-in-alt icon-green', 'button-line-receive', pk, '{% trans "Mark item as received" %}');
} }
buttons += makeEditButton('button-line-edit', pk, '{% jstrans "Edit line item" %}'); buttons += makeEditButton('button-line-edit', pk, '{% trans "Edit line item" %}');
} }
if (options.allow_delete) { if (options.allow_delete) {
buttons += makeDeleteButton('button-line-delete', pk, '{% jstrans "Delete line item" %}'); buttons += makeDeleteButton('button-line-delete', pk, '{% trans "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: '{% jstrans "Add Customer" %}', title: '{% trans "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: '{% jstrans "Create Sales Order" %}', title: '{% trans "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: '{% jstrans "Edit Sales Order" %}', title: '{% trans "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: '{% jstrans "Add Line Item" %}', title: '{% trans "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'>
{% jstrans "No stock items have been allocated to this shipment" %} {% trans "No stock items have been allocated to this shipment" %}
</div> </div>
`; `;
} else { } else {
html = ` html = `
{% jstrans "The following stock items will be shipped" %} {% trans "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>{% jstrans "Part" %}</th> <th>{% trans "Part" %}</th>
<th>{% jstrans "Stock Item" %}</th> <th>{% trans "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 = `{% jstrans "Serial Number" %}: ${allocation.serial}`; stock = `{% trans "Serial Number" %}: ${allocation.serial}`;
} else { } else {
stock = `{% jstrans "Quantity" %}: ${allocation.quantity}`; stock = `{% trans "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: `{% jstrans "Complete Shipment" %} ${shipment.reference}`, title: `{% trans "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: '{% jstrans "Confirm Shipment" %}', confirmMessage: '{% trans "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 += `
{% jstrans "No pending shipments found" %} {% trans "No pending shipments found" %}
`; `;
} else { } else {
html += ` html += `
{% jstrans "No stock items have been allocated to pending shipments" %} {% trans "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: '{% jstrans "Complete Shipments" %}', title: '{% trans "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: `{% jstrans "Skip" %}`, title: `{% trans "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: '{% jstrans "Complete Sales Order" %}', title: '{% trans "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'>
{% jstrans "Mark this order as complete?" %} {% trans "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'>
{% jstrans "Order cannot be completed as there are incomplete shipments" %}<br> {% trans "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'>
{% jstrans "This order has line items which have not been completed." %}<br> {% trans "This order has line items which have not been completed." %}<br>
{% jstrans "Completing this order means that the order and line items will no longer be editable." %} {% trans "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'>
{% jstrans "Issue this Sales Order?" %} {% trans "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: '{% jstrans "Issue Sales Order" %}', title: '{% trans "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: '{% jstrans "Cancel Sales Order" %}', title: '{% trans "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'>
{% jstrans "Cancelling this order means that the order will no longer be editable." %} {% trans "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: '{% jstrans "Create New Shipment" %}', title: '{% trans "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 '{% jstrans "No sales orders found" %}'; return '{% trans "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: '{% jstrans "Sales Order" %}', title: '{% trans "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', '{% jstrans "Order is overdue" %}'); html += makeIconBadge('fa-calendar-times icon-red', '{% trans "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: '{% jstrans "Customer" %}', title: '{% trans "Customer" %}',
formatter: function(value, row) { formatter: function(value, row) {
if (!row.customer_detail) { if (!row.customer_detail) {
return '{% jstrans "Invalid Customer" %}'; return '{% trans "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: '{% jstrans "Customer Reference" %}', title: '{% trans "Customer Reference" %}',
}, },
{ {
sortable: false, sortable: false,
field: 'description', field: 'description',
title: '{% jstrans "Description" %}', title: '{% trans "Description" %}',
}, },
{ {
field: 'project_code', field: 'project_code',
title: '{% jstrans "Project Code" %}', title: '{% trans "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: '{% jstrans "Status" %}', title: '{% trans "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: '{% jstrans "Creation Date" %}', title: '{% trans "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: '{% jstrans "Target Date" %}', title: '{% trans "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: '{% jstrans "Shipment Date" %}', title: '{% trans "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: '{% jstrans "Items" %}' title: '{% trans "Items" %}'
}, },
{ {
field: 'total_price', field: 'total_price',
title: '{% jstrans "Total Cost" %}', title: '{% trans "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, '{% jstrans "Edit shipment" %}'); html += makeEditButton('button-shipment-edit', pk, '{% trans "Edit shipment" %}');
if (!options.shipped) { if (!options.shipped) {
html += makeIconButton('fa-truck icon-green', 'button-shipment-ship', pk, '{% jstrans "Complete shipment" %}'); html += makeIconButton('fa-truck icon-green', 'button-shipment-ship', pk, '{% trans "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, '{% jstrans "Delete shipment" %}', {disabled: !enable_delete}); html += makeDeleteButton('button-shipment-delete', pk, '{% trans "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: '{% jstrans "Edit Shipment" %}', title: '{% trans "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: '{% jstrans "Delete Shipment" %}', title: '{% trans "Delete Shipment" %}',
method: 'DELETE', method: 'DELETE',
refreshTable: table, refreshTable: table,
}); });
@ -978,7 +978,7 @@ function loadSalesOrderShipmentTable(table, options={}) {
} }
}, },
formatNoMatches: function() { formatNoMatches: function() {
return '{% jstrans "No matching shipments found" %}'; return '{% trans "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: '{% jstrans "Sales Order" %}', title: '{% trans "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', '{% jstrans "Order is overdue" %}'); html += makeIconBadge('fa-calendar-times icon-red', '{% trans "Order is overdue" %}');
} }
return html; return html;
@ -1003,12 +1003,12 @@ function loadSalesOrderShipmentTable(table, options={}) {
}, },
{ {
field: 'reference', field: 'reference',
title: '{% jstrans "Shipment Reference" %}', title: '{% trans "Shipment Reference" %}',
switchable: false, switchable: false,
}, },
{ {
field: 'allocations', field: 'allocations',
title: '{% jstrans "Items" %}', title: '{% trans "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: '{% jstrans "Shipment Date" %}', title: '{% trans "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>{% jstrans "Not shipped" %}</em>'; return '<em>{% trans "Not shipped" %}</em>';
} }
} }
}, },
{ {
field: 'delivery_date', field: 'delivery_date',
title: '{% jstrans "Delivery Date" %}', title: '{% trans "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>{% jstrans "Unknown" %}</em>'; return '<em>{% trans "Unknown" %}</em>';
} }
} }
}, },
{ {
field: 'tracking_number', field: 'tracking_number',
title: '{% jstrans "Tracking" %}', title: '{% trans "Tracking" %}',
}, },
{ {
field: 'invoice_number', field: 'invoice_number',
title: '{% jstrans "Invoice" %}', title: '{% trans "Invoice" %}',
}, },
{ {
field: 'link', field: 'link',
title: '{% jstrans "Link" %}', title: '{% trans "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: '{% jstrans "Notes" %}', title: '{% trans "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,
'{% jstrans "Remove row" %}', '{% trans "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: '{% jstrans "Specify stock allocation quantity" %}', title: '{% trans "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(
'{% jstrans "Select Parts" %}', '{% trans "Select Parts" %}',
'{% jstrans "You must select at least one part to allocate" %}', '{% trans "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: '{% jstrans "Source Location" %}', label: '{% trans "Source Location" %}',
help_text: '{% jstrans "Select source location (leave blank to take from all locations)" %}', help_text: '{% trans "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>{% jstrans "Part" %}</th> <th>{% trans "Part" %}</th>
<th style='min-width: 250px;'>{% jstrans "Stock Item" %}</th> <th style='min-width: 250px;'>{% trans "Stock Item" %}</th>
<th>{% jstrans "Quantity" %}</th> <th>{% trans "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: '{% jstrans "Add Shipment" %}', title: '{% trans "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: '{% jstrans "Confirm stock allocation" %}', confirmMessage: '{% trans "Confirm stock allocation" %}',
title: '{% jstrans "Allocate Stock Items to Sales Order" %}', title: '{% trans "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 '{% jstrans "No matching stock locations" %}'; return '{% trans "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 '{% jstrans "No matching stock items" %}'; return '{% trans "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 '{% jstrans "No sales order allocations found" %}'; return '{% trans "No sales order allocations found" %}';
}, },
columns: [ columns: [
{ {
@ -1485,7 +1485,7 @@ function loadSalesOrderAllocationTable(table, options={}) {
{ {
field: 'order', field: 'order',
switchable: false, switchable: false,
title: '{% jstrans "Order" %}', title: '{% trans "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: '{% jstrans "Stock Item" %}', title: '{% trans "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 = `{% jstrans "Stock Item" %} ${row.item}`; var text = `{% trans "Stock Item" %} ${row.item}`;
return renderLink(text, link); return renderLink(text, link);
} }
}, },
{ {
field: 'location', field: 'location',
title: '{% jstrans "Location" %}', title: '{% trans "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: '{% jstrans "Quantity" %}', title: '{% trans "Quantity" %}',
sortable: true, sortable: true,
}, },
{ {
field: 'shipment_date', field: 'shipment_date',
title: '{% jstrans "Shipped" %}', title: '{% trans "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>{% jstrans "Not shipped" %}</em>`; return `<em>{% trans "Not shipped" %}</em>`;
} }
} }
} }
@ -1566,7 +1566,7 @@ function showAllocationSubTable(index, row, element, options) {
fields: { fields: {
quantity: {}, quantity: {},
}, },
title: '{% jstrans "Edit Stock Allocation" %}', title: '{% trans "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: '{% jstrans "Confirm Delete Operation" %}', confirmMessage: '{% trans "Confirm Delete Operation" %}',
title: '{% jstrans "Delete Stock Allocation" %}', title: '{% trans "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: '{% jstrans "Part" %}', title: '{% trans "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: '{% jstrans "Stock Item" %}', title: '{% trans "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 = `{% jstrans "Quantity" %}: ${row.quantity}`; let text = `{% trans "Quantity" %}: ${row.quantity}`;
if (item && item.serial != null && row.quantity == 1) { if (item && item.serial != null && row.quantity == 1) {
text = `{% jstrans "Serial Number" %}: ${item.serial}`; text = `{% trans "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: '{% jstrans "Location" %}', title: '{% trans "Location" %}',
formatter: function(value, row, index, field) { formatter: function(value, row, index, field) {
if (row.shipment_date) { if (row.shipment_date) {
return `<em>{% jstrans "Shipped to customer" %} - ${row.shipment_date}</em>`; return `<em>{% trans "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 || '{% jstrans "Location" %}', row.location_detail.pathstring || '{% trans "Location" %}',
`/stock/location/${row.location}/` `/stock/location/${row.location}/`
); );
} else { } else {
return `<em>{% jstrans "Stock location not specified" %}</em>`; return `<em>{% trans "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'>{% jstrans "Shipped" %}</span>`; html += `<span class='badge bg-success badge-right'>{% trans "Shipped" %}</span>`;
} else { } else {
html += makeEditButton('button-allocation-edit', pk, '{% jstrans "Edit stock allocation" %}'); html += makeEditButton('button-allocation-edit', pk, '{% trans "Edit stock allocation" %}');
html += makeDeleteButton('button-allocation-delete', pk, '{% jstrans "Delete stock allocation" %}'); html += makeDeleteButton('button-allocation-delete', pk, '{% trans "Delete stock allocation" %}');
} }
return wrapButtons(html); return wrapButtons(html);
@ -1689,13 +1689,13 @@ function showFulfilledSubTable(index, row, element, options) {
}, },
{ {
field: 'stock', field: 'stock',
title: '{% jstrans "Stock Item" %}', title: '{% trans "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 = `{% jstrans "Serial Number" %}: ${row.serial}`; text = `{% trans "Serial Number" %}: ${row.serial}`;
} else { } else {
text = `{% jstrans "Quantity" %}: ${row.quantity}`; text = `{% trans "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: '{% jstrans "Location" %}', title: '{% trans "Location" %}',
formatter: function(value, row) { formatter: function(value, row) {
if (row.customer) { if (row.customer) {
return renderLink( return renderLink(
'{% jstrans "Shipped to customer" %}', '{% trans "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>{% jstrans "Stock location not specified" %}</em>`; return `<em>{% trans "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: '{% jstrans "Part" %}', title: '{% trans "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 '{% jstrans "Total" %}'; return '{% trans "Total" %}';
}, },
}, },
{ {
sortable: false, sortable: false,
field: 'part_detail.description', field: 'part_detail.description',
title: '{% jstrans "Description" %}', title: '{% trans "Description" %}',
switchable: true, switchable: true,
}, },
{ {
sortable: true, sortable: true,
field: 'reference', field: 'reference',
title: '{% jstrans "Reference" %}', title: '{% trans "Reference" %}',
switchable: true, switchable: true,
}, },
{ {
sortable: true, sortable: true,
field: 'quantity', field: 'quantity',
title: '{% jstrans "Quantity" %}', title: '{% trans "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: '{% jstrans "Unit Price" %}', title: '{% trans "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: '{% jstrans "Total Price" %}', title: '{% trans "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: '{% jstrans "Target Date" %}', title: '{% trans "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', '{% jstrans "This line item is overdue" %}'); html += makeIconBadge('fa-calendar-times', '{% trans "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: '{% jstrans "Available Stock" %}', title: '{% trans "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', '{% jstrans "Includes variant stock" %}'); html += makeIconBadge('fa-info-circle icon-blue', '{% trans "Includes variant stock" %}');
} }
} else { } else {
html += `<span class='badge rounded-pill bg-danger'>{% jstrans "No Stock Available" %}</span>`; html += `<span class='badge rounded-pill bg-danger'>{% trans "No Stock Available" %}</span>`;
} }
if (required > 0) { if (required > 0) {
if (available >= required) { if (available >= required) {
html += makeIconBadge('fa-check-circle icon-green', '{% jstrans "Sufficient stock available" %}'); html += makeIconBadge('fa-check-circle icon-green', '{% trans "Sufficient stock available" %}');
} else { } else {
html += makeIconBadge('fa-times-circle icon-red', '{% jstrans "Insufficient stock available" %}'); html += makeIconBadge('fa-times-circle icon-red', '{% trans "Insufficient stock available" %}');
} }
} }
@ -1926,7 +1926,7 @@ function loadSalesOrderLineItemTable(table, options={}) {
columns.push( columns.push(
{ {
field: 'allocated', field: 'allocated',
title: '{% jstrans "Allocated" %}', title: '{% trans "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: '{% jstrans "Shipped" %}', title: '{% trans "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: '{% jstrans "Notes" %}', title: '{% trans "Notes" %}',
}); });
columns.push({ columns.push({
field: 'link', field: 'link',
title: '{% jstrans "Link" %}', title: '{% trans "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, '{% jstrans "Allocate serial numbers" %}'); buttons += makeIconButton('fa-hashtag icon-green', 'button-add-by-sn', pk, '{% trans "Allocate serial numbers" %}');
} }
buttons += makeIconButton('fa-sign-in-alt icon-green', 'button-add', pk, '{% jstrans "Allocate stock" %}'); buttons += makeIconButton('fa-sign-in-alt icon-green', 'button-add', pk, '{% trans "Allocate stock" %}');
if (part.purchaseable) { if (part.purchaseable) {
buttons += makeIconButton('fa-shopping-cart', 'button-buy', row.part, '{% jstrans "Purchase stock" %}'); buttons += makeIconButton('fa-shopping-cart', 'button-buy', row.part, '{% trans "Purchase stock" %}');
} }
if (part.assembly) { if (part.assembly) {
buttons += makeIconButton('fa-tools', 'button-build', row.part, '{% jstrans "Build stock" %}'); buttons += makeIconButton('fa-tools', 'button-build', row.part, '{% trans "Build stock" %}');
} }
} }
} }
buttons += makeIconButton('fa-dollar-sign icon-green', 'button-price', pk, '{% jstrans "Calculate price" %}'); buttons += makeIconButton('fa-dollar-sign icon-green', 'button-price', pk, '{% trans "Calculate price" %}');
if (options.allow_edit) { if (options.allow_edit) {
buttons += makeCopyButton('button-duplicate', pk, '{% jstrans "Duplicate line item" %}'); buttons += makeCopyButton('button-duplicate', pk, '{% trans "Duplicate line item" %}');
buttons += makeEditButton('button-edit', pk, '{% jstrans "Edit line item" %}'); buttons += makeEditButton('button-edit', pk, '{% trans "Edit line item" %}');
} }
if (options.allow_delete) { if (options.allow_delete) {
var delete_disabled = false; var delete_disabled = false;
var title = '{% jstrans "Delete line item" %}'; var title = '{% trans "Delete line item" %}';
if (row.shipped) { if (row.shipped) {
delete_disabled = true; delete_disabled = true;
title = '{% jstrans "Cannot be deleted as items have been shipped" %}'; title = '{% trans "Cannot be deleted as items have been shipped" %}';
} else if (row.allocated) { } else if (row.allocated) {
delete_disabled = true; delete_disabled = true;
title = '{% jstrans "Cannot be deleted as items have been allocated" %}'; title = '{% trans "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: '{% jstrans "Duplicate Line Item" %}', title: '{% trans "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: '{% jstrans "Edit Line Item" %}', title: '{% trans "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: '{% jstrans "Delete Line Item" %}', title: '{% trans "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: '{% jstrans "Allocate Serial Numbers" %}', title: '{% trans "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: '{% jstrans "Calculate price" %}', submit_text: '{% trans "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: '{% jstrans "Update Unit Price" %}' title: '{% trans "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 '{% jstrans "No matching line items" %}'; return '{% trans "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', '{% jstrans "Parts" %}', filters); addSearchQuery('part', '{% trans "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', '{% jstrans "Supplier Parts" %}', filters); addSearchQuery('supplierpart', '{% trans "Supplier Parts" %}', filters);
} }
if (user_settings.SEARCH_PREVIEW_SHOW_MANUFACTURER_PARTS) { if (user_settings.SEARCH_PREVIEW_SHOW_MANUFACTURER_PARTS) {
addSearchQuery('manufacturerpart', '{% jstrans "Manufacturer Parts" %}', filters); addSearchQuery('manufacturerpart', '{% trans "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', '{% jstrans "Part Categories" %}', filters); addSearchQuery('partcategory', '{% trans "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', '{% jstrans "Stock Items" %}', filters); addSearchQuery('stockitem', '{% trans "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', '{% jstrans "Stock Locations" %}', filters); addSearchQuery('stocklocation', '{% trans "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', '{% jstrans "Build Orders" %}', filters); addSearchQuery('build', '{% trans "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', '{% jstrans "Companies" %}', filters); addSearchQuery('company', '{% trans "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', '{% jstrans "Purchase Orders" %}', filters); addSearchQuery('purchaseorder', '{% trans "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', '{% jstrans "Sales Orders" %}', filters); addSearchQuery('salesorder', '{% trans "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', '{% jstrans "Return Orders" %}', filters); addSearchQuery('returnorder', '{% trans "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>{% jstrans "Searching" %}</em> <span class='fas fa-spinner fa-spin'></span> <em>{% trans "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>{% jstrans "No results" %}</em> <span class='fas fa-exclamation-circle'></span> <em>{% trans "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>{% jstrans "Enter search query" %}</em> <span class='fas fa-search'></span> <em>{% trans "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 ? '{% jstrans "result" %}' : '{% jstrans "results" %}'; let resultText = resultCount == 1 ? '{% trans "result" %}' : '{% trans "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='{% jstrans "Minimize results" %}'> <button class='btn btn-outline-secondary' id='hide-results-${key}' title='{% trans "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='{% jstrans "Remove results" %}'> <button class='btn btn-outline-secondary' id='remove-results-${key}' title='{% trans "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: '{% jstrans "Issued By" %}', title: '{% trans "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: '{% jstrans "Project Code" %}', title: '{% trans "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: '{% jstrans "Has project code" %}', title: '{% trans "Has project code" %}',
}; };
} }
@ -86,20 +86,20 @@ function getAttachmentFilters() {
function getReturnOrderFilters() { function getReturnOrderFilters() {
var filters = { var filters = {
status: { status: {
title: '{% jstrans "Order status" %}', title: '{% trans "Order status" %}',
options: returnOrderCodes options: returnOrderCodes
}, },
outstanding: { outstanding: {
type: 'bool', type: 'bool',
title: '{% jstrans "Outstanding" %}', title: '{% trans "Outstanding" %}',
}, },
overdue: { overdue: {
type: 'bool', type: 'bool',
title: '{% jstrans "Overdue" %}', title: '{% trans "Overdue" %}',
}, },
assigned_to_me: { assigned_to_me: {
type: 'bool', type: 'bool',
title: '{% jstrans "Assigned to me" %}', title: '{% trans "Assigned to me" %}',
}, },
}; };
@ -117,10 +117,10 @@ function getReturnOrderLineItemFilters() {
return { return {
received: { received: {
type: 'bool', type: 'bool',
title: '{% jstrans "Received" %}', title: '{% trans "Received" %}',
}, },
outcome: { outcome: {
title: '{% jstrans "Outcome" %}', title: '{% trans "Outcome" %}',
options: returnOrderLineItemCodes, options: returnOrderLineItemCodes,
} }
}; };
@ -132,19 +132,19 @@ function getVariantsTableFilters() {
return { return {
active: { active: {
type: 'bool', type: 'bool',
title: '{% jstrans "Active" %}', title: '{% trans "Active" %}',
}, },
template: { template: {
type: 'bool', type: 'bool',
title: '{% jstrans "Template" %}', title: '{% trans "Template" %}',
}, },
virtual: { virtual: {
type: 'bool', type: 'bool',
title: '{% jstrans "Virtual" %}', title: '{% trans "Virtual" %}',
}, },
trackable: { trackable: {
type: 'bool', type: 'bool',
title: '{% jstrans "Trackable" %}', title: '{% trans "Trackable" %}',
}, },
}; };
} }
@ -155,43 +155,43 @@ function getBOMTableFilters() {
return { return {
sub_part_trackable: { sub_part_trackable: {
type: 'bool', type: 'bool',
title: '{% jstrans "Trackable Part" %}', title: '{% trans "Trackable Part" %}',
}, },
sub_part_assembly: { sub_part_assembly: {
type: 'bool', type: 'bool',
title: '{% jstrans "Assembled Part" %}', title: '{% trans "Assembled Part" %}',
}, },
available_stock: { available_stock: {
type: 'bool', type: 'bool',
title: '{% jstrans "Has Available Stock" %}', title: '{% trans "Has Available Stock" %}',
}, },
on_order: { on_order: {
type: 'bool', type: 'bool',
title: '{% jstrans "On Order" %}', title: '{% trans "On Order" %}',
}, },
validated: { validated: {
type: 'bool', type: 'bool',
title: '{% jstrans "Validated" %}', title: '{% trans "Validated" %}',
}, },
inherited: { inherited: {
type: 'bool', type: 'bool',
title: '{% jstrans "Gets inherited" %}', title: '{% trans "Gets inherited" %}',
}, },
allow_variants: { allow_variants: {
type: 'bool', type: 'bool',
title: '{% jstrans "Allow Variant Stock" %}', title: '{% trans "Allow Variant Stock" %}',
}, },
optional: { optional: {
type: 'bool', type: 'bool',
title: '{% jstrans "Optional" %}', title: '{% trans "Optional" %}',
}, },
consumable: { consumable: {
type: 'bool', type: 'bool',
title: '{% jstrans "Consumable" %}', title: '{% trans "Consumable" %}',
}, },
has_pricing: { has_pricing: {
type: 'bool', type: 'bool',
title: '{% jstrans "Has Pricing" %}', title: '{% trans "Has Pricing" %}',
}, },
}; };
} }
@ -208,19 +208,19 @@ function getUsedInTableFilters() {
return { return {
'inherited': { 'inherited': {
type: 'bool', type: 'bool',
title: '{% jstrans "Gets inherited" %}', title: '{% trans "Gets inherited" %}',
}, },
'optional': { 'optional': {
type: 'bool', type: 'bool',
title: '{% jstrans "Optional" %}', title: '{% trans "Optional" %}',
}, },
'part_active': { 'part_active': {
type: 'bool', type: 'bool',
title: '{% jstrans "Active" %}', title: '{% trans "Active" %}',
}, },
'part_trackable': { 'part_trackable': {
type: 'bool', type: 'bool',
title: '{% jstrans "Trackable" %}', title: '{% trans "Trackable" %}',
}, },
}; };
} }
@ -231,19 +231,19 @@ function getStockLocationFilters() {
return { return {
cascade: { cascade: {
type: 'bool', type: 'bool',
title: '{% jstrans "Include sublocations" %}', title: '{% trans "Include sublocations" %}',
description: '{% jstrans "Include locations" %}', description: '{% trans "Include locations" %}',
}, },
structural: { structural: {
type: 'bool', type: 'bool',
title: '{% jstrans "Structural" %}', title: '{% trans "Structural" %}',
}, },
external: { external: {
type: 'bool', type: 'bool',
title: '{% jstrans "External" %}', title: '{% trans "External" %}',
}, },
location_type: { location_type: {
title: '{% jstrans "Location type" %}', title: '{% trans "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: '{% jstrans "Has location type" %}' title: '{% trans "Has location type" %}'
}, },
}; };
} }
@ -275,16 +275,16 @@ function getPartCategoryFilters() {
return { return {
cascade: { cascade: {
type: 'bool', type: 'bool',
title: '{% jstrans "Include subcategories" %}', title: '{% trans "Include subcategories" %}',
description: '{% jstrans "Include subcategories" %}', description: '{% trans "Include subcategories" %}',
}, },
structural: { structural: {
type: 'bool', type: 'bool',
title: '{% jstrans "Structural" %}', title: '{% trans "Structural" %}',
}, },
starred: { starred: {
type: 'bool', type: 'bool',
title: '{% jstrans "Subscribed" %}', title: '{% trans "Subscribed" %}',
}, },
}; };
} }
@ -295,23 +295,23 @@ function getCustomerStockFilters() {
return { return {
serialized: { serialized: {
type: 'bool', type: 'bool',
title: '{% jstrans "Is Serialized" %}', title: '{% trans "Is Serialized" %}',
}, },
serial_gte: { serial_gte: {
title: '{% jstrans "Serial number GTE" %}', title: '{% trans "Serial number GTE" %}',
description: '{% jstrans "Serial number greater than or equal to" %}', description: '{% trans "Serial number greater than or equal to" %}',
}, },
serial_lte: { serial_lte: {
title: '{% jstrans "Serial number LTE" %}', title: '{% trans "Serial number LTE" %}',
description: '{% jstrans "Serial number less than or equal to" %}', description: '{% trans "Serial number less than or equal to" %}',
}, },
serial: { serial: {
title: '{% jstrans "Serial number" %}', title: '{% trans "Serial number" %}',
description: '{% jstrans "Serial number" %}', description: '{% trans "Serial number" %}',
}, },
batch: { batch: {
title: '{% jstrans "Batch" %}', title: '{% trans "Batch" %}',
description: '{% jstrans "Batch code" %}', description: '{% trans "Batch code" %}',
}, },
}; };
} }
@ -322,109 +322,109 @@ function getStockTableFilters() {
var filters = { var filters = {
active: { active: {
type: 'bool', type: 'bool',
title: '{% jstrans "Active parts" %}', title: '{% trans "Active parts" %}',
description: '{% jstrans "Show stock for active parts" %}', description: '{% trans "Show stock for active parts" %}',
}, },
assembly: { assembly: {
type: 'bool', type: 'bool',
title: '{% jstrans "Assembly" %}', title: '{% trans "Assembly" %}',
description: '{% jstrans "Part is an assembly" %}', description: '{% trans "Part is an assembly" %}',
}, },
allocated: { allocated: {
type: 'bool', type: 'bool',
title: '{% jstrans "Is allocated" %}', title: '{% trans "Is allocated" %}',
description: '{% jstrans "Item has been allocated" %}', description: '{% trans "Item has been allocated" %}',
}, },
available: { available: {
type: 'bool', type: 'bool',
title: '{% jstrans "Available" %}', title: '{% trans "Available" %}',
description: '{% jstrans "Stock is available for use" %}', description: '{% trans "Stock is available for use" %}',
}, },
cascade: { cascade: {
type: 'bool', type: 'bool',
title: '{% jstrans "Include sublocations" %}', title: '{% trans "Include sublocations" %}',
description: '{% jstrans "Include stock in sublocations" %}', description: '{% trans "Include stock in sublocations" %}',
}, },
depleted: { depleted: {
type: 'bool', type: 'bool',
title: '{% jstrans "Depleted" %}', title: '{% trans "Depleted" %}',
description: '{% jstrans "Show stock items which are depleted" %}', description: '{% trans "Show stock items which are depleted" %}',
}, },
in_stock: { in_stock: {
type: 'bool', type: 'bool',
title: '{% jstrans "In Stock" %}', title: '{% trans "In Stock" %}',
description: '{% jstrans "Show items which are in stock" %}', description: '{% trans "Show items which are in stock" %}',
}, },
is_building: { is_building: {
type: 'bool', type: 'bool',
title: '{% jstrans "In Production" %}', title: '{% trans "In Production" %}',
description: '{% jstrans "Show items which are in production" %}', description: '{% trans "Show items which are in production" %}',
}, },
include_variants: { include_variants: {
type: 'bool', type: 'bool',
title: '{% jstrans "Include Variants" %}', title: '{% trans "Include Variants" %}',
description: '{% jstrans "Include stock items for variant parts" %}', description: '{% trans "Include stock items for variant parts" %}',
}, },
installed: { installed: {
type: 'bool', type: 'bool',
title: '{% jstrans "Installed" %}', title: '{% trans "Installed" %}',
description: '{% jstrans "Show stock items which are installed in another item" %}', description: '{% trans "Show stock items which are installed in another item" %}',
}, },
sent_to_customer: { sent_to_customer: {
type: 'bool', type: 'bool',
title: '{% jstrans "Sent to customer" %}', title: '{% trans "Sent to customer" %}',
description: '{% jstrans "Show items which have been assigned to a customer" %}', description: '{% trans "Show items which have been assigned to a customer" %}',
}, },
serialized: { serialized: {
type: 'bool', type: 'bool',
title: '{% jstrans "Is Serialized" %}', title: '{% trans "Is Serialized" %}',
}, },
serial: { serial: {
title: '{% jstrans "Serial number" %}', title: '{% trans "Serial number" %}',
description: '{% jstrans "Serial number" %}', description: '{% trans "Serial number" %}',
}, },
serial_gte: { serial_gte: {
title: '{% jstrans "Serial number GTE" %}', title: '{% trans "Serial number GTE" %}',
description: '{% jstrans "Serial number greater than or equal to" %}', description: '{% trans "Serial number greater than or equal to" %}',
}, },
serial_lte: { serial_lte: {
title: '{% jstrans "Serial number LTE" %}', title: '{% trans "Serial number LTE" %}',
description: '{% jstrans "Serial number less than or equal to" %}', description: '{% trans "Serial number less than or equal to" %}',
}, },
status: { status: {
options: stockCodes, options: stockCodes,
title: '{% jstrans "Stock status" %}', title: '{% trans "Stock status" %}',
description: '{% jstrans "Stock status" %}', description: '{% trans "Stock status" %}',
}, },
has_batch: { has_batch: {
title: '{% jstrans "Has batch code" %}', title: '{% trans "Has batch code" %}',
type: 'bool', type: 'bool',
}, },
batch: { batch: {
title: '{% jstrans "Batch" %}', title: '{% trans "Batch" %}',
description: '{% jstrans "Batch code" %}', description: '{% trans "Batch code" %}',
}, },
tracked: { tracked: {
title: '{% jstrans "Tracked" %}', title: '{% trans "Tracked" %}',
description: '{% jstrans "Stock item is tracked by either batch code or serial number" %}', description: '{% trans "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: '{% jstrans "Has purchase price" %}', title: '{% trans "Has purchase price" %}',
description: '{% jstrans "Show stock items which have a purchase price set" %}', description: '{% trans "Show stock items which have a purchase price set" %}',
}, },
expiry_date_lte: { expiry_date_lte: {
type: 'date', type: 'date',
title: '{% jstrans "Expiry Date before" %}', title: '{% trans "Expiry Date before" %}',
}, },
expiry_date_gte: { expiry_date_gte: {
type: 'date', type: 'date',
title: '{% jstrans "Expiry Date after" %}', title: '{% trans "Expiry Date after" %}',
}, },
external: { external: {
type: 'bool', type: 'bool',
title: '{% jstrans "External Location" %}', title: '{% trans "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: '{% jstrans "Expired" %}', title: '{% trans "Expired" %}',
description: '{% jstrans "Show stock items which have expired" %}', description: '{% trans "Show stock items which have expired" %}',
}; };
filters.stale = { filters.stale = {
type: 'bool', type: 'bool',
title: '{% jstrans "Stale" %}', title: '{% trans "Stale" %}',
description: '{% jstrans "Show stock which is close to expiring" %}', description: '{% trans "Show stock which is close to expiring" %}',
}; };
} }
@ -453,11 +453,11 @@ function getStockTestTableFilters() {
return { return {
result: { result: {
type: 'bool', type: 'bool',
title: '{% jstrans "Test Passed" %}', title: '{% trans "Test Passed" %}',
}, },
include_installed: { include_installed: {
type: 'bool', type: 'bool',
title: '{% jstrans "Include Installed Items" %}', title: '{% trans "Include Installed Items" %}',
} }
}; };
} }
@ -474,7 +474,7 @@ function getPartTestTemplateFilters() {
return { return {
required: { required: {
type: 'bool', type: 'bool',
title: '{% jstrans "Required" %}', title: '{% trans "Required" %}',
}, },
}; };
} }
@ -485,19 +485,19 @@ function getPluginTableFilters() {
return { return {
active: { active: {
type: 'bool', type: 'bool',
title: '{% jstrans "Active" %}', title: '{% trans "Active" %}',
}, },
builtin: { builtin: {
type: 'bool', type: 'bool',
title: '{% jstrans "Builtin" %}', title: '{% trans "Builtin" %}',
}, },
sample: { sample: {
type: 'bool', type: 'bool',
title: '{% jstrans "Sample" %}', title: '{% trans "Sample" %}',
}, },
installed: { installed: {
type: 'bool', type: 'bool',
title: '{% jstrans "Installed" %}' title: '{% trans "Installed" %}'
}, },
}; };
} }
@ -508,23 +508,23 @@ function getBuildTableFilters() {
let filters = { let filters = {
status: { status: {
title: '{% jstrans "Build status" %}', title: '{% trans "Build status" %}',
options: buildCodes, options: buildCodes,
}, },
active: { active: {
type: 'bool', type: 'bool',
title: '{% jstrans "Active" %}', title: '{% trans "Active" %}',
}, },
overdue: { overdue: {
type: 'bool', type: 'bool',
title: '{% jstrans "Overdue" %}', title: '{% trans "Overdue" %}',
}, },
assigned_to_me: { assigned_to_me: {
type: 'bool', type: 'bool',
title: '{% jstrans "Assigned to me" %}', title: '{% trans "Assigned to me" %}',
}, },
assigned_to: { assigned_to: {
title: '{% jstrans "Responsible" %}', title: '{% trans "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: '{% jstrans "Allocated" %}', title: '{% trans "Allocated" %}',
}, },
available: { available: {
type: 'bool', type: 'bool',
title: '{% jstrans "Available" %}', title: '{% trans "Available" %}',
}, },
tracked: { tracked: {
type: 'bool', type: 'bool',
title: '{% jstrans "Tracked" %}', title: '{% trans "Tracked" %}',
}, },
consumable: { consumable: {
type: 'bool', type: 'bool',
title: '{% jstrans "Consumable" %}', title: '{% trans "Consumable" %}',
}, },
optional: { optional: {
type: 'bool', type: 'bool',
title: '{% jstrans "Optional" %}', title: '{% trans "Optional" %}',
}, },
}; };
} }
@ -591,14 +591,14 @@ function getPurchaseOrderLineItemFilters() {
return { return {
pending: { pending: {
type: 'bool', type: 'bool',
title: '{% jstrans "Pending" %}', title: '{% trans "Pending" %}',
}, },
received: { received: {
type: 'bool', type: 'bool',
title: '{% jstrans "Received" %}', title: '{% trans "Received" %}',
}, },
order_status: { order_status: {
title: '{% jstrans "Order status" %}', title: '{% trans "Order status" %}',
options: purchaseOrderCodes, options: purchaseOrderCodes,
}, },
}; };
@ -610,20 +610,20 @@ function getPurchaseOrderFilters() {
var filters = { var filters = {
status: { status: {
title: '{% jstrans "Order status" %}', title: '{% trans "Order status" %}',
options: purchaseOrderCodes, options: purchaseOrderCodes,
}, },
outstanding: { outstanding: {
type: 'bool', type: 'bool',
title: '{% jstrans "Outstanding" %}', title: '{% trans "Outstanding" %}',
}, },
overdue: { overdue: {
type: 'bool', type: 'bool',
title: '{% jstrans "Overdue" %}', title: '{% trans "Overdue" %}',
}, },
assigned_to_me: { assigned_to_me: {
type: 'bool', type: 'bool',
title: '{% jstrans "Assigned to me" %}', title: '{% trans "Assigned to me" %}',
}, },
}; };
@ -641,7 +641,7 @@ function getSalesOrderAllocationFilters() {
return { return {
outstanding: { outstanding: {
type: 'bool', type: 'bool',
title: '{% jstrans "Outstanding" %}', title: '{% trans "Outstanding" %}',
} }
}; };
} }
@ -651,20 +651,20 @@ function getSalesOrderAllocationFilters() {
function getSalesOrderFilters() { function getSalesOrderFilters() {
var filters = { var filters = {
status: { status: {
title: '{% jstrans "Order status" %}', title: '{% trans "Order status" %}',
options: salesOrderCodes, options: salesOrderCodes,
}, },
outstanding: { outstanding: {
type: 'bool', type: 'bool',
title: '{% jstrans "Outstanding" %}', title: '{% trans "Outstanding" %}',
}, },
overdue: { overdue: {
type: 'bool', type: 'bool',
title: '{% jstrans "Overdue" %}', title: '{% trans "Overdue" %}',
}, },
assigned_to_me: { assigned_to_me: {
type: 'bool', type: 'bool',
title: '{% jstrans "Assigned to me" %}', title: '{% trans "Assigned to me" %}',
}, },
}; };
@ -682,7 +682,7 @@ function getSalesOrderLineItemFilters() {
return { return {
completed: { completed: {
type: 'bool', type: 'bool',
title: '{% jstrans "Completed" %}', title: '{% trans "Completed" %}',
}, },
}; };
} }
@ -693,7 +693,7 @@ function getSupplierPartFilters() {
return { return {
active: { active: {
type: 'bool', type: 'bool',
title: '{% jstrans "Active parts" %}', title: '{% trans "Active parts" %}',
}, },
}; };
} }
@ -704,75 +704,75 @@ function getPartTableFilters() {
return { return {
cascade: { cascade: {
type: 'bool', type: 'bool',
title: '{% jstrans "Include subcategories" %}', title: '{% trans "Include subcategories" %}',
description: '{% jstrans "Include parts in subcategories" %}', description: '{% trans "Include parts in subcategories" %}',
}, },
active: { active: {
type: 'bool', type: 'bool',
title: '{% jstrans "Active" %}', title: '{% trans "Active" %}',
description: '{% jstrans "Show active parts" %}', description: '{% trans "Show active parts" %}',
}, },
assembly: { assembly: {
type: 'bool', type: 'bool',
title: '{% jstrans "Assembly" %}', title: '{% trans "Assembly" %}',
}, },
unallocated_stock: { unallocated_stock: {
type: 'bool', type: 'bool',
title: '{% jstrans "Available stock" %}', title: '{% trans "Available stock" %}',
}, },
component: { component: {
type: 'bool', type: 'bool',
title: '{% jstrans "Component" %}', title: '{% trans "Component" %}',
}, },
has_units: { has_units: {
type: 'bool', type: 'bool',
title: '{% jstrans "Has Units" %}', title: '{% trans "Has Units" %}',
description: '{% jstrans "Part has defined units" %}', description: '{% trans "Part has defined units" %}',
}, },
has_ipn: { has_ipn: {
type: 'bool', type: 'bool',
title: '{% jstrans "Has IPN" %}', title: '{% trans "Has IPN" %}',
description: '{% jstrans "Part has internal part number" %}', description: '{% trans "Part has internal part number" %}',
}, },
has_stock: { has_stock: {
type: 'bool', type: 'bool',
title: '{% jstrans "In stock" %}', title: '{% trans "In stock" %}',
}, },
low_stock: { low_stock: {
type: 'bool', type: 'bool',
title: '{% jstrans "Low stock" %}', title: '{% trans "Low stock" %}',
}, },
purchaseable: { purchaseable: {
type: 'bool', type: 'bool',
title: '{% jstrans "Purchasable" %}', title: '{% trans "Purchasable" %}',
}, },
salable: { salable: {
type: 'bool', type: 'bool',
title: '{% jstrans "Salable" %}', title: '{% trans "Salable" %}',
}, },
starred: { starred: {
type: 'bool', type: 'bool',
title: '{% jstrans "Subscribed" %}', title: '{% trans "Subscribed" %}',
}, },
stocktake: { stocktake: {
type: 'bool', type: 'bool',
title: '{% jstrans "Has stocktake entries" %}', title: '{% trans "Has stocktake entries" %}',
}, },
is_template: { is_template: {
type: 'bool', type: 'bool',
title: '{% jstrans "Template" %}', title: '{% trans "Template" %}',
}, },
trackable: { trackable: {
type: 'bool', type: 'bool',
title: '{% jstrans "Trackable" %}', title: '{% trans "Trackable" %}',
}, },
virtual: { virtual: {
type: 'bool', type: 'bool',
title: '{% jstrans "Virtual" %}', title: '{% trans "Virtual" %}',
}, },
has_pricing: { has_pricing: {
type: 'bool', type: 'bool',
title: '{% jstrans "Has Pricing" %}', title: '{% trans "Has Pricing" %}',
}, },
}; };
} }
@ -789,15 +789,15 @@ function getCompanyFilters() {
return { return {
is_manufacturer: { is_manufacturer: {
type: 'bool', type: 'bool',
title: '{% jstrans "Manufacturer" %}', title: '{% trans "Manufacturer" %}',
}, },
is_supplier: { is_supplier: {
type: 'bool', type: 'bool',
title: '{% jstrans "Supplier" %}', title: '{% trans "Supplier" %}',
}, },
is_customer: { is_customer: {
type: 'bool', type: 'bool',
title: '{% jstrans "Customer" %}', title: '{% trans "Customer" %}',
}, },
}; };
} }
@ -814,15 +814,15 @@ function getPartParameterTemplateFilters() {
return { return {
checkbox: { checkbox: {
type: 'bool', type: 'bool',
title: '{% jstrans "Checkbox" %}', title: '{% trans "Checkbox" %}',
}, },
has_choices: { has_choices: {
type: 'bool', type: 'bool',
title: '{% jstrans "Has Choices" %}', title: '{% trans "Has Choices" %}',
}, },
has_units: { has_units: {
type: 'bool', type: 'bool',
title: '{% jstrans "Has Units" %}', title: '{% trans "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='{% jstrans "Display calendar view" %}'><span class='fas fa-calendar-alt'></span></button>`, html: `<button type='button' name='${idx++}' class='btn ${class_calendar}' title='{% trans "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='{% jstrans "Display list view" %}'><span class='fas fa-th-list'></span></button>`, html: `<button type='button' name='${idx++}' class='btn ${class_list}' title='{% trans "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='{% jstrans "Display tree view" %}'><span class='fas fa-sitemap'></span></button>`, html: `<button type='button' name='${idx++}' class='btn ${class_tree}' title='{% trans "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='{% jstrans "Expand all rows" %}'><span class='fas fa-expand'></span></button>`, html: `<button type='button' name='${idx++}' class='btn btn-outline-secondary' title='{% trans "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='{% jstrans "Collapse all rows" %}'><span class='fas fa-compress'></span></button>`, html: `<button type='button' name='${idx++}' class='btn btn-outline-secondary' title='{% trans "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 || '{% jstrans "Export Table Data" %}', title: opts.title || '{% trans "Export Table Data" %}',
fields: { fields: {
format: { format: {
label: '{% jstrans "Format" %}', label: '{% trans "Format" %}',
help_text: '{% jstrans "Select File Format" %}', help_text: '{% trans "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 '{% jstrans "Loading data" %}'; return '{% trans "Loading data" %}';
}, },
formatRecordsPerPage: function(pageNumber) { formatRecordsPerPage: function(pageNumber) {
return `${pageNumber} {% jstrans "rows per page" %}`; return `${pageNumber} {% trans "rows per page" %}`;
}, },
formatShowingRows: function(pageFrom, pageTo, totalRows) { formatShowingRows: function(pageFrom, pageTo, totalRows) {
if (totalRows === undefined || isNaN(totalRows)) { if (totalRows === undefined || isNaN(totalRows)) {
return '{% jstrans "Showing all rows" %}'; return '{% trans "Showing all rows" %}';
} else { } else {
return `{% jstrans "Showing" %} ${pageFrom} {% jstrans "to" %} ${pageTo} {% jstrans "of" %} ${totalRows} {% jstrans "rows" %}`; return `{% trans "Showing" %} ${pageFrom} {% trans "to" %} ${pageTo} {% trans "of" %} ${totalRows} {% trans "rows" %}`;
} }
}, },
formatSearch: function() { formatSearch: function() {
return '{% jstrans "Search" %}'; return '{% trans "Search" %}';
}, },
formatNoMatches: function() { formatNoMatches: function() {
return '{% jstrans "No matching results" %}'; return '{% trans "No matching results" %}';
}, },
formatPaginationSwitch: function() { formatPaginationSwitch: function() {
return '{% jstrans "Hide/Show pagination" %}'; return '{% trans "Hide/Show pagination" %}';
}, },
formatRefresh: function() { formatRefresh: function() {
return '{% jstrans "Refresh" %}'; return '{% trans "Refresh" %}';
}, },
formatToggle: function() { formatToggle: function() {
return '{% jstrans "Toggle" %}'; return '{% trans "Toggle" %}';
}, },
formatColumns: function() { formatColumns: function() {
return '{% jstrans "Columns" %}'; return '{% trans "Columns" %}';
}, },
formatAllRows: function() { formatAllRows: function() {
return '{% jstrans "All" %}'; return '{% trans "All" %}';
}, },
}; };

View File

@ -50,7 +50,6 @@ def check_prohibited_tags(data):
'for', 'for',
'endfor', 'endfor',
'trans', 'trans',
'jstrans',
'load', 'load',
'include', 'include',
'url', 'url',
@ -85,7 +84,7 @@ 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()
invalid_tags = ['trans', 'jstrans'] invalid_tags = ['blocktrans', 'blocktranslate', 'trans', 'translate']
err_count = 0 err_count = 0