mirror of
https://github.com/inventree/InvenTree.git
synced 2025-06-19 21:45:39 +00:00
Merge branch 'master' of https://github.com/inventree/InvenTree into plugin-2037
This commit is contained in:
@ -13,8 +13,6 @@
|
||||
<table class='table table-striped table-condensed'>
|
||||
{% include "InvenTree/settings/header.html" %}
|
||||
<tbody>
|
||||
{% include "InvenTree/settings/setting.html" with key="BUILD_FUNCTION_ENABLE" icon="fa-check" %}
|
||||
<tr><td colspan='5'></td></tr>
|
||||
{% include "InvenTree/settings/setting.html" with key="BUILDORDER_REFERENCE_PREFIX" %}
|
||||
{% include "InvenTree/settings/setting.html" with key="BUILDORDER_REFERENCE_REGEX" %}
|
||||
</tbody>
|
||||
|
@ -14,7 +14,6 @@
|
||||
<table class='table table-striped table-condensed'>
|
||||
{% include "InvenTree/settings/header.html" %}
|
||||
<tbody>
|
||||
{% include "InvenTree/settings/setting.html" with key="LOGIN_ENABLE_REG" icon="fa-info-circle" %}
|
||||
{% include "InvenTree/settings/setting.html" with key="LOGIN_ENABLE_SSO" icon="fa-info-circle" %}
|
||||
{% include "InvenTree/settings/setting.html" with key="LOGIN_ENABLE_PWD_FORGOT" icon="fa-info-circle" %}
|
||||
{% include "InvenTree/settings/setting.html" with key="LOGIN_MAIL_REQUIRED" icon="fa-info-circle" %}
|
||||
@ -22,9 +21,11 @@
|
||||
<td>{% trans 'Signup' %}</td>
|
||||
<td colspan='4'></td>
|
||||
</tr>
|
||||
{% include "InvenTree/settings/setting.html" with key="LOGIN_ENABLE_REG" icon="fa-info-circle" %}
|
||||
{% include "InvenTree/settings/setting.html" with key="LOGIN_SIGNUP_MAIL_TWICE" icon="fa-info-circle" %}
|
||||
{% include "InvenTree/settings/setting.html" with key="LOGIN_SIGNUP_PWD_TWICE" icon="fa-info-circle" %}
|
||||
{% include "InvenTree/settings/setting.html" with key="LOGIN_SIGNUP_SSO_AUTO" icon="fa-info-circle" %}
|
||||
{% include "InvenTree/settings/setting.html" with key="SIGNUP_GROUP" %}
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
|
@ -17,6 +17,7 @@
|
||||
{% include "InvenTree/settings/setting.html" with key="PART_IPN_REGEX" %}
|
||||
{% include "InvenTree/settings/setting.html" with key="PART_ALLOW_DUPLICATE_IPN" %}
|
||||
{% include "InvenTree/settings/setting.html" with key="PART_ALLOW_EDIT_IPN" %}
|
||||
{% include "InvenTree/settings/setting.html" with key="PART_NAME_FORMAT" %}
|
||||
{% include "InvenTree/settings/setting.html" with key="PART_SHOW_PRICE_IN_FORMS" icon="fa-dollar-sign" %}
|
||||
{% include "InvenTree/settings/setting.html" with key="PART_SHOW_PRICE_IN_BOM" icon="fa-dollar-sign" %}
|
||||
{% include "InvenTree/settings/setting.html" with key="PART_SHOW_RELATED" icon="fa-random" %}
|
||||
|
@ -11,9 +11,6 @@
|
||||
<table class='table table-striped table-condensed'>
|
||||
{% include "InvenTree/settings/header.html" %}
|
||||
<tbody>
|
||||
{% include "InvenTree/settings/setting.html" with key="PO_FUNCTION_ENABLE" icon="fa-check" %}
|
||||
{% include "InvenTree/settings/setting.html" with key="BUY_FUNCTION_ENABLE" icon="fa-check" %}
|
||||
<tr><td colspan='5'></td></tr>
|
||||
{% include "InvenTree/settings/setting.html" with key="PURCHASEORDER_REFERENCE_PREFIX" %}
|
||||
</tbody>
|
||||
</table>
|
||||
|
@ -12,9 +12,6 @@
|
||||
<table class='table table-striped table-condensed'>
|
||||
{% include "InvenTree/settings/header.html" %}
|
||||
<tbody>
|
||||
{% include "InvenTree/settings/setting.html" with key="SO_FUNCTION_ENABLE" icon="fa-check" %}
|
||||
{% include "InvenTree/settings/setting.html" with key="SELL_FUNCTION_ENABLE" icon="fa-check" %}
|
||||
<tr><td colspan='5'></td></tr>
|
||||
{% include "InvenTree/settings/setting.html" with key="SALESORDER_REFERENCE_PREFIX" %}
|
||||
</tbody>
|
||||
</table>
|
||||
|
@ -12,8 +12,6 @@
|
||||
<table class='table table-striped table-condensed'>
|
||||
{% include "InvenTree/settings/header.html" %}
|
||||
<tbody>
|
||||
{% include "InvenTree/settings/setting.html" with key="STOCK_FUNCTION_ENABLE" icon="fa-check" %}
|
||||
<tr><td colspan='5'></td></tr>
|
||||
{% include "InvenTree/settings/setting.html" with key="STOCK_GROUP_BY_PART" icon="fa-layer-group" %}
|
||||
{% include "InvenTree/settings/setting.html" with key="STOCK_ENABLE_EXPIRY" icon="fa-stopwatch" %}
|
||||
{% include "InvenTree/settings/setting.html" with key="STOCK_STALE_DAYS" icon="fa-calendar" %}
|
||||
|
@ -39,12 +39,12 @@
|
||||
</table>
|
||||
|
||||
<div class='panel-heading'>
|
||||
<h4>{% trans "E-Mail" %}</h4>
|
||||
<h4>{% trans "Email" %}</h4>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
{% if user.emailaddress_set.all %}
|
||||
<p>{% trans 'The following e-mail addresses are associated with your account:' %}</p>
|
||||
<p>{% trans 'The following email addresses are associated with your account:' %}</p>
|
||||
|
||||
<form action="{% url 'account_email' %}" class="email_list" method="post">
|
||||
{% csrf_token %}
|
||||
@ -78,19 +78,19 @@
|
||||
|
||||
{% else %}
|
||||
<p><strong>{% trans 'Warning:'%}</strong>
|
||||
{% trans "You currently do not have any e-mail address set up. You should really add an e-mail address so you can receive notifications, reset your password, etc." %}
|
||||
{% trans "You currently do not have any email address set up. You should really add an email address so you can receive notifications, reset your password, etc." %}
|
||||
</p>
|
||||
|
||||
{% endif %}
|
||||
|
||||
{% if can_add_email %}
|
||||
<br>
|
||||
<h4>{% trans "Add E-mail Address" %}</h4>
|
||||
<h4>{% trans "Add Email Address" %}</h4>
|
||||
|
||||
<form method="post" action="{% url 'account_email' %}" class="add_email">
|
||||
{% csrf_token %}
|
||||
{{ add_email_form|crispy }}
|
||||
<button class="btn btn-primary" name="action_add" type="submit">{% trans "Add E-mail" %}</button>
|
||||
<button class="btn btn-primary" name="action_add" type="submit">{% trans "Add Email" %}</button>
|
||||
</form>
|
||||
{% endif %}
|
||||
<br>
|
||||
@ -220,7 +220,7 @@
|
||||
|
||||
{% block js_ready %}
|
||||
(function() {
|
||||
var message = "{% trans 'Do you really want to remove the selected e-mail address?' %}";
|
||||
var message = "{% trans 'Do you really want to remove the selected email address?' %}";
|
||||
var actions = document.getElementsByName('action_remove');
|
||||
if (actions.length) {
|
||||
actions[0].addEventListener("click", function(e) {
|
||||
|
@ -3,17 +3,17 @@
|
||||
{% load i18n %}
|
||||
{% load account %}
|
||||
|
||||
{% block head_title %}{% trans "Confirm E-mail Address" %}{% endblock %}
|
||||
{% block head_title %}{% trans "Confirm Email Address" %}{% endblock %}
|
||||
|
||||
|
||||
{% block content %}
|
||||
<h1>{% trans "Confirm E-mail Address" %}</h1>
|
||||
<h1>{% trans "Confirm Email Address" %}</h1>
|
||||
|
||||
{% if confirmation %}
|
||||
|
||||
{% user_display confirmation.email_address.user as user_display %}
|
||||
|
||||
<p>{% blocktrans with confirmation.email_address.email as email %}Please confirm that <a href="mailto:{{ email }}">{{ email }}</a> is an e-mail address for user {{ user_display }}.{% endblocktrans %}</p>
|
||||
<p>{% blocktrans with confirmation.email_address.email as email %}Please confirm that <a href="mailto:{{ email }}">{{ email }}</a> is an email address for user {{ user_display }}.{% endblocktrans %}</p>
|
||||
|
||||
<form method="post" action="{% url 'account_confirm_email' confirmation.key %}">
|
||||
{% csrf_token %}
|
||||
@ -24,7 +24,7 @@
|
||||
|
||||
{% url 'account_email' as email_url %}
|
||||
|
||||
<p>{% blocktrans %}This e-mail confirmation link expired or is invalid. Please <a href="{{ email_url }}">issue a new e-mail confirmation request</a>.{% endblocktrans %}</p>
|
||||
<p>{% blocktrans %}This email confirmation link expired or is invalid. Please <a href="{{ email_url }}">issue a new email confirmation request</a>.{% endblocktrans %}</p>
|
||||
|
||||
{% endif %}
|
||||
|
||||
|
@ -15,7 +15,7 @@
|
||||
{% endif %}
|
||||
|
||||
{% if mail_conf and enable_pwd_forgot %}
|
||||
<p>{% trans "Forgotten your password? Enter your e-mail address below, and we'll send you an e-mail allowing you to reset it." %}</p>
|
||||
<p>{% trans "Forgotten your password? Enter your email address below, and we'll send you an email allowing you to reset it." %}</p>
|
||||
|
||||
<form method="POST" action="{% url 'account_reset_password' %}" class="password_reset">
|
||||
{% csrf_token %}
|
||||
|
@ -143,6 +143,174 @@ function newPartFromBomWizard(e) {
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Launch a modal dialog displaying the "substitute parts" for a particular BomItem
|
||||
*
|
||||
* If editable, allows substitutes to be added and deleted
|
||||
*/
|
||||
function bomSubstitutesDialog(bom_item_id, substitutes, options={}) {
|
||||
|
||||
// Reload data for the parent table
|
||||
function reloadParentTable() {
|
||||
if (options.table) {
|
||||
options.table.bootstrapTable('refresh');
|
||||
}
|
||||
}
|
||||
|
||||
// Extract a list of all existing "substitute" id values
|
||||
function getSubstituteIdValues(modal) {
|
||||
|
||||
var id_values = [];
|
||||
|
||||
$(modal).find('.substitute-row').each(function(el) {
|
||||
var part = $(this).attr('part');
|
||||
id_values.push(part);
|
||||
});
|
||||
|
||||
return id_values;
|
||||
}
|
||||
|
||||
function renderSubstituteRow(substitute) {
|
||||
|
||||
var pk = substitute.pk;
|
||||
|
||||
var part = substitute.part_detail;
|
||||
|
||||
var thumb = thumbnailImage(part.thumbnail || part.image);
|
||||
|
||||
var buttons = '';
|
||||
|
||||
buttons += makeIconButton('fa-times icon-red', 'button-row-remove', pk, '{% trans "Remove substitute part" %}');
|
||||
|
||||
// Render a single row
|
||||
var html = `
|
||||
<tr id='substitute-row-${pk}' class='substitute-row' part='${substitute.part}'>
|
||||
<td id='part-${pk}'>
|
||||
<a href='/part/${part.pk}/'>
|
||||
${thumb} ${part.full_name}
|
||||
</a>
|
||||
</td>
|
||||
<td id='description-${pk}'><em>${part.description}</em></td>
|
||||
<td>${buttons}</td>
|
||||
</tr>
|
||||
`;
|
||||
|
||||
return html;
|
||||
}
|
||||
|
||||
// Construct a table to render the rows
|
||||
var rows = '';
|
||||
|
||||
substitutes.forEach(function(sub) {
|
||||
rows += renderSubstituteRow(sub);
|
||||
});
|
||||
|
||||
var html = `
|
||||
<table class='table table-striped table-condensed' id='substitute-table'>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>{% trans "Part" %}</th>
|
||||
<th>{% trans "Description" %}</th>
|
||||
<th><!-- Actions --></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
${rows}
|
||||
</tbody>
|
||||
</table>
|
||||
`;
|
||||
|
||||
html += `
|
||||
<div class='alert alert-success alert-block'>
|
||||
{% trans "Select and add a new variant item using the input below" %}
|
||||
</div>
|
||||
`;
|
||||
|
||||
// Add a callback to remove a row from the table
|
||||
function addRemoveCallback(modal, element) {
|
||||
$(modal).find(element).click(function() {
|
||||
var pk = $(this).attr('pk');
|
||||
|
||||
var pre = `
|
||||
<div class='alert alert-block alert-warning'>
|
||||
{% trans "Are you sure you wish to remove this substitute part link?" %}
|
||||
</div>
|
||||
`;
|
||||
|
||||
constructForm(`/api/bom/substitute/${pk}/`, {
|
||||
method: 'DELETE',
|
||||
title: '{% trans "Remove Substitute Part" %}',
|
||||
preFormContent: pre,
|
||||
confirm: true,
|
||||
onSuccess: function() {
|
||||
$(modal).find(`#substitute-row-${pk}`).remove();
|
||||
reloadParentTable();
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
constructForm('{% url "api-bom-substitute-list" %}', {
|
||||
method: 'POST',
|
||||
fields: {
|
||||
bom_item: {
|
||||
hidden: true,
|
||||
value: bom_item_id,
|
||||
},
|
||||
part: {
|
||||
required: false,
|
||||
adjustFilters: function(query, opts) {
|
||||
|
||||
var subs = getSubstituteIdValues(opts.modal);
|
||||
|
||||
// Also exclude the "master" part (if provided)
|
||||
if (options.sub_part) {
|
||||
subs.push(options.sub_part);
|
||||
}
|
||||
|
||||
if (subs.length > 0) {
|
||||
query.exclude_id = subs;
|
||||
}
|
||||
|
||||
return query;
|
||||
}
|
||||
},
|
||||
},
|
||||
preFormContent: html,
|
||||
cancelText: '{% trans "Close" %}',
|
||||
submitText: '{% trans "Add Substitute" %}',
|
||||
title: '{% trans "Edit BOM Item Substitutes" %}',
|
||||
afterRender: function(fields, opts) {
|
||||
addRemoveCallback(opts.modal, '.button-row-remove');
|
||||
},
|
||||
preventClose: true,
|
||||
onSuccess: function(response, opts) {
|
||||
|
||||
// Clear the form
|
||||
var field = {
|
||||
type: 'related field',
|
||||
};
|
||||
|
||||
updateFieldValue('part', null, field, opts);
|
||||
|
||||
// Add the new substitute to the table
|
||||
var row = renderSubstituteRow(response);
|
||||
$(opts.modal).find('#substitute-table > tbody:last-child').append(row);
|
||||
|
||||
// Add a callback to the new button
|
||||
addRemoveCallback(opts.modal, `#button-row-remove-${response.pk}`);
|
||||
|
||||
// Re-enable the "submit" button
|
||||
$(opts.modal).find('#modal-form-submit').prop('disabled', false);
|
||||
|
||||
// Reload the parent BOM table
|
||||
reloadParentTable();
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
|
||||
function loadBomTable(table, options) {
|
||||
/* Load a BOM table with some configurable options.
|
||||
*
|
||||
@ -229,6 +397,14 @@ function loadBomTable(table, options) {
|
||||
|
||||
html += makePartIcons(row.sub_part_detail);
|
||||
|
||||
if (row.substitutes && row.substitutes.length > 0) {
|
||||
html += makeIconBadge('fa-exchange-alt', '{% trans "Substitutes Available" %}');
|
||||
}
|
||||
|
||||
if (row.allow_variants) {
|
||||
html += makeIconBadge('fa-sitemap', '{% trans "Variant stock allowed" %}');
|
||||
}
|
||||
|
||||
// Display an extra icon if this part is an assembly
|
||||
if (sub_part.assembly) {
|
||||
var text = `<span title='{% trans "Open subassembly" %}' class='fas fa-stream label-right'></span>`;
|
||||
@ -300,6 +476,20 @@ function loadBomTable(table, options) {
|
||||
return renderLink(text, url);
|
||||
}
|
||||
});
|
||||
|
||||
cols.push({
|
||||
field: 'substitutes',
|
||||
title: '{% trans "Substitutes" %}',
|
||||
searchable: false,
|
||||
sortable: true,
|
||||
formatter: function(value, row) {
|
||||
if (row.substitutes && row.substitutes.length > 0) {
|
||||
return row.substitutes.length;
|
||||
} else {
|
||||
return `-`;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if (show_pricing) {
|
||||
cols.push({
|
||||
@ -420,18 +610,17 @@ function loadBomTable(table, options) {
|
||||
|
||||
if (row.part == options.parent_id) {
|
||||
|
||||
var bValidate = `<button title='{% trans "Validate BOM Item" %}' class='bom-validate-button btn btn-default btn-glyph' type='button' pk='${row.pk}'><span class='fas fa-check-circle icon-blue'/></button>`;
|
||||
var bValidate = makeIconButton('fa-check-circle icon-green', 'bom-validate-button', row.pk, '{% trans "Validate BOM Item" %}');
|
||||
|
||||
var bValid = `<span title='{% trans "This line has been validated" %}' class='fas fa-check-double icon-green'/>`;
|
||||
|
||||
var bEdit = `<button title='{% trans "Edit BOM Item" %}' class='bom-edit-button btn btn-default btn-glyph' type='button' pk='${row.pk}'><span class='fas fa-edit'></span></button>`;
|
||||
var bSubs = makeIconButton('fa-exchange-alt icon-blue', 'bom-substitutes-button', row.pk, '{% trans "Edit substitute parts" %}');
|
||||
|
||||
var bDelt = `<button title='{% trans "Delete BOM Item" %}' class='bom-delete-button btn btn-default btn-glyph' type='button' pk='${row.pk}'><span class='fas fa-trash-alt icon-red'></span></button>`;
|
||||
var bEdit = makeIconButton('fa-edit icon-blue', 'bom-edit-button', row.pk, '{% trans "Edit BOM Item" %}');
|
||||
|
||||
var html = `<div class='btn-group' role='group'>`;
|
||||
var bDelt = makeIconButton('fa-trash-alt icon-red', 'bom-delete-button', row.pk, '{% trans "Delete BOM Item" %}');
|
||||
|
||||
html += bEdit;
|
||||
html += bDelt;
|
||||
var html = `<div class='btn-group float-right' role='group' style='min-width: 100px;'>`;
|
||||
|
||||
if (!row.validated) {
|
||||
html += bValidate;
|
||||
@ -439,6 +628,10 @@ function loadBomTable(table, options) {
|
||||
html += bValid;
|
||||
}
|
||||
|
||||
html += bEdit;
|
||||
html += bSubs;
|
||||
html += bDelt;
|
||||
|
||||
html += `</div>`;
|
||||
|
||||
return html;
|
||||
@ -490,6 +683,7 @@ function loadBomTable(table, options) {
|
||||
treeEnable: !options.editable,
|
||||
rootParentId: parent_id,
|
||||
idField: 'pk',
|
||||
uniqueId: 'pk',
|
||||
parentIdField: 'parentId',
|
||||
treeShowField: 'sub_part',
|
||||
showColumns: true,
|
||||
@ -566,19 +760,27 @@ function loadBomTable(table, options) {
|
||||
// In editing mode, attached editables to the appropriate table elements
|
||||
if (options.editable) {
|
||||
|
||||
// Callback for "delete" button
|
||||
table.on('click', '.bom-delete-button', function() {
|
||||
|
||||
var pk = $(this).attr('pk');
|
||||
|
||||
var html = `
|
||||
<div class='alert alert-block alert-danger'>
|
||||
{% trans "Are you sure you want to delete this BOM item?" %}
|
||||
</div>`;
|
||||
|
||||
constructForm(`/api/bom/${pk}/`, {
|
||||
method: 'DELETE',
|
||||
title: '{% trans "Delete BOM Item" %}',
|
||||
preFormContent: html,
|
||||
onSuccess: function() {
|
||||
reloadBomTable(table);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// Callback for "edit" button
|
||||
table.on('click', '.bom-edit-button', function() {
|
||||
|
||||
var pk = $(this).attr('pk');
|
||||
@ -595,6 +797,7 @@ function loadBomTable(table, options) {
|
||||
});
|
||||
});
|
||||
|
||||
// Callback for "validate" button
|
||||
table.on('click', '.bom-validate-button', function() {
|
||||
|
||||
var pk = $(this).attr('pk');
|
||||
@ -613,5 +816,22 @@ function loadBomTable(table, options) {
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
// Callback for "substitutes" button
|
||||
table.on('click', '.bom-substitutes-button', function() {
|
||||
var pk = $(this).attr('pk');
|
||||
|
||||
var row = table.bootstrapTable('getRowByUniqueId', pk);
|
||||
var subs = row.substitutes || [];
|
||||
|
||||
bomSubstitutesDialog(
|
||||
pk,
|
||||
subs,
|
||||
{
|
||||
table: table,
|
||||
sub_part: row.sub_part,
|
||||
}
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -208,15 +208,10 @@ function makeBuildOutputActionButtons(output, buildInfo, lines) {
|
||||
|
||||
var pk = $(this).attr('pk');
|
||||
|
||||
launchModalForm(
|
||||
`/build/${buildId}/unallocate/`,
|
||||
{
|
||||
success: reloadTable,
|
||||
data: {
|
||||
output: pk,
|
||||
}
|
||||
}
|
||||
);
|
||||
unallocateStock(buildId, {
|
||||
output: pk,
|
||||
table: table,
|
||||
});
|
||||
});
|
||||
|
||||
$(panel).find(`#button-output-delete-${outputId}`).click(function() {
|
||||
@ -236,6 +231,49 @@ function makeBuildOutputActionButtons(output, buildInfo, lines) {
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Unallocate stock against a particular build order
|
||||
*
|
||||
* Options:
|
||||
* - output: pk value for a stock item "build output"
|
||||
* - bom_item: pk value for a particular BOMItem (build item)
|
||||
*/
|
||||
function unallocateStock(build_id, options={}) {
|
||||
|
||||
var url = `/api/build/${build_id}/unallocate/`;
|
||||
|
||||
var html = `
|
||||
<div class='alert alert-block alert-warning'>
|
||||
{% trans "Are you sure you wish to unallocate stock items from this build?" %}
|
||||
</dvi>
|
||||
`;
|
||||
|
||||
constructForm(url, {
|
||||
method: 'POST',
|
||||
confirm: true,
|
||||
preFormContent: html,
|
||||
fields: {
|
||||
output: {
|
||||
hidden: true,
|
||||
value: options.output,
|
||||
},
|
||||
bom_item: {
|
||||
hidden: true,
|
||||
value: options.bom_item,
|
||||
},
|
||||
},
|
||||
title: '{% trans "Unallocate Stock Items" %}',
|
||||
onSuccess: function(response, opts) {
|
||||
if (options.table) {
|
||||
// Reload the parent table
|
||||
$(options.table).bootstrapTable('refresh');
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
|
||||
function loadBuildOrderAllocationTable(table, options={}) {
|
||||
/**
|
||||
* Load a table showing all the BuildOrder allocations for a given part
|
||||
@ -348,6 +386,17 @@ function loadBuildOutputAllocationTable(buildInfo, output, options={}) {
|
||||
table = `#allocation-table-${outputId}`;
|
||||
}
|
||||
|
||||
// Filters
|
||||
var filters = loadTableFilters('builditems');
|
||||
|
||||
var params = options.params || {};
|
||||
|
||||
for (var key in params) {
|
||||
filters[key] = params[key];
|
||||
}
|
||||
|
||||
setupFilterList('builditems', $(table), options.filterTarget || null);
|
||||
|
||||
// If an "output" is specified, then only "trackable" parts are allocated
|
||||
// Otherwise, only "untrackable" parts are allowed
|
||||
var trackable = ! !output;
|
||||
@ -458,17 +507,16 @@ function loadBuildOutputAllocationTable(buildInfo, output, options={}) {
|
||||
|
||||
// Callback for 'unallocate' button
|
||||
$(table).find('.button-unallocate').click(function() {
|
||||
var pk = $(this).attr('pk');
|
||||
|
||||
launchModalForm(`/build/${buildId}/unallocate/`,
|
||||
{
|
||||
success: reloadTable,
|
||||
data: {
|
||||
output: outputId,
|
||||
part: pk,
|
||||
}
|
||||
}
|
||||
);
|
||||
// Extract row data from the table
|
||||
var idx = $(this).closest('tr').attr('data-index');
|
||||
var row = $(table).bootstrapTable('getData')[idx];
|
||||
|
||||
unallocateStock(buildId, {
|
||||
bom_item: row.pk,
|
||||
output: outputId == 'untracked' ? null : outputId,
|
||||
table: table,
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@ -726,6 +774,14 @@ function loadBuildOutputAllocationTable(buildInfo, output, options={}) {
|
||||
|
||||
html += makePartIcons(row.sub_part_detail);
|
||||
|
||||
if (row.substitutes && row.substitutes.length > 0) {
|
||||
html += makeIconBadge('fa-exchange-alt', '{% trans "Substitute parts available" %}');
|
||||
}
|
||||
|
||||
if (row.allow_variants) {
|
||||
html += makeIconBadge('fa-sitemap', '{% trans "Variant stock allowed" %}');
|
||||
}
|
||||
|
||||
return html;
|
||||
}
|
||||
},
|
||||
@ -1021,12 +1077,12 @@ function allocateStockToBuild(build_id, part_id, bom_items, options={}) {
|
||||
filters: {
|
||||
bom_item: bom_item.pk,
|
||||
in_stock: true,
|
||||
part_detail: false,
|
||||
part_detail: true,
|
||||
location_detail: true,
|
||||
},
|
||||
model: 'stockitem',
|
||||
required: true,
|
||||
render_part_detail: false,
|
||||
render_part_detail: true,
|
||||
render_location_detail: true,
|
||||
auto_fill: true,
|
||||
adjustFilters: function(filters) {
|
||||
|
@ -283,10 +283,16 @@ function setupFilterList(tableKey, table, target) {
|
||||
|
||||
element.append(`<button id='reload-${tableKey}' title='{% trans "Reload data" %}' class='btn btn-default filter-tag'><span class='fas fa-redo-alt'></span></button>`);
|
||||
|
||||
// If there are no filters defined for this table, exit now
|
||||
if (jQuery.isEmptyObject(getAvailableTableFilters(tableKey))) {
|
||||
return;
|
||||
}
|
||||
|
||||
// If there are filters currently "in use", add them in!
|
||||
element.append(`<button id='${add}' title='{% trans "Add new filter" %}' class='btn btn-default filter-tag'><span class='fas fa-filter'></span></button>`);
|
||||
|
||||
if (Object.keys(filters).length > 0) {
|
||||
element.append(`<button id='${clear}' title='{% trans "Clear all filters" %}' class='btn btn-default filter-tag'><span class='fas fa-trash-alt'></span></button>`);
|
||||
element.append(`<button id='${clear}' title='{% trans "Clear all filters" %}' class='btn btn-default filter-tag'><span class='fas fa-backspace icon-red'></span></button>`);
|
||||
}
|
||||
|
||||
for (var key in filters) {
|
||||
|
@ -1349,7 +1349,7 @@ function initializeRelatedField(field, fields, options) {
|
||||
|
||||
// Allow custom run-time filter augmentation
|
||||
if ('adjustFilters' in field) {
|
||||
query = field.adjustFilters(query);
|
||||
query = field.adjustFilters(query, options);
|
||||
}
|
||||
|
||||
return query;
|
||||
|
@ -52,8 +52,6 @@ function renderStockItem(name, data, parameters, options) {
|
||||
if (data.part_detail) {
|
||||
image = data.part_detail.thumbnail || data.part_detail.image || blankImage();
|
||||
}
|
||||
|
||||
var html = '';
|
||||
|
||||
var render_part_detail = true;
|
||||
|
||||
@ -61,23 +59,10 @@ function renderStockItem(name, data, parameters, options) {
|
||||
render_part_detail = parameters['render_part_detail'];
|
||||
}
|
||||
|
||||
var part_detail = '';
|
||||
|
||||
if (render_part_detail) {
|
||||
html += `<img src='${image}' class='select2-thumbnail'>`;
|
||||
html += ` <span>${data.part_detail.full_name || data.part_detail.name}</span>`;
|
||||
}
|
||||
|
||||
html += '<span>';
|
||||
|
||||
if (data.serial && data.quantity == 1) {
|
||||
html += `{% trans "Serial Number" %}: ${data.serial}`;
|
||||
} else {
|
||||
html += `{% trans "Quantity" %}: ${data.quantity}`;
|
||||
}
|
||||
|
||||
html += '</span>';
|
||||
|
||||
if (render_part_detail && data.part_detail.description) {
|
||||
html += `<p><small>${data.part_detail.description}</small></p>`;
|
||||
part_detail = `<img src='${image}' class='select2-thumbnail'><span>${data.part_detail.full_name}</span> - `;
|
||||
}
|
||||
|
||||
var render_stock_id = true;
|
||||
@ -86,8 +71,10 @@ function renderStockItem(name, data, parameters, options) {
|
||||
render_stock_id = parameters['render_stock_id'];
|
||||
}
|
||||
|
||||
var stock_id = '';
|
||||
|
||||
if (render_stock_id) {
|
||||
html += `<span class='float-right'><small>{% trans "Stock ID" %}: ${data.pk}</small></span>`;
|
||||
stock_id = `<span class='float-right'><small>{% trans "Stock ID" %}: ${data.pk}</small></span>`;
|
||||
}
|
||||
|
||||
var render_location_detail = false;
|
||||
@ -96,10 +83,28 @@ function renderStockItem(name, data, parameters, options) {
|
||||
render_location_detail = parameters['render_location_detail'];
|
||||
}
|
||||
|
||||
var location_detail = '';
|
||||
|
||||
if (render_location_detail && data.location_detail) {
|
||||
html += `<span> - ${data.location_detail.name}</span>`;
|
||||
location_detail = ` - (<em>${data.location_detail.name}</em>)`;
|
||||
}
|
||||
|
||||
var stock_detail = '';
|
||||
|
||||
if (data.serial && data.quantity == 1) {
|
||||
stock_detail = `{% trans "Serial Number" %}: ${data.serial}`;
|
||||
} else if (data.quantity == 0) {
|
||||
stock_detail = `<span class='label-form label-red'>{% trans "No Stock"% }</span>`;
|
||||
} else {
|
||||
stock_detail = `{% trans "Quantity" %}: ${data.quantity}`;
|
||||
}
|
||||
|
||||
var html = `
|
||||
<span>
|
||||
${part_detail}${stock_detail}${location_detail}${stock_id}
|
||||
</span>
|
||||
`;
|
||||
|
||||
return html;
|
||||
}
|
||||
|
||||
@ -159,21 +164,25 @@ function renderPart(name, data, parameters, options) {
|
||||
html += ` - <i>${data.description}</i>`;
|
||||
}
|
||||
|
||||
var stock = '';
|
||||
var extra = '';
|
||||
|
||||
// Display available part quantity
|
||||
if (user_settings.PART_SHOW_QUANTITY_IN_FORMS) {
|
||||
if (data.in_stock == 0) {
|
||||
stock = `<span class='label-form label-red'>{% trans "No Stock" %}</span>`;
|
||||
extra += `<span class='label-form label-red'>{% trans "No Stock" %}</span>`;
|
||||
} else {
|
||||
stock = `<span class='label-form label-green'>{% trans "In Stock" %}: ${data.in_stock}</span>`;
|
||||
extra += `<span class='label-form label-green'>{% trans "Stock" %}: ${data.in_stock}</span>`;
|
||||
}
|
||||
}
|
||||
|
||||
if (!data.active) {
|
||||
extra += `<span class='label-form label-red'>{% trans "Inactive" %}</span>`;
|
||||
}
|
||||
|
||||
html += `
|
||||
<span class='float-right'>
|
||||
<small>
|
||||
${stock}
|
||||
${extra}
|
||||
{% trans "Part ID" %}: ${data.pk}
|
||||
</small>
|
||||
</span>`;
|
||||
|
@ -592,7 +592,7 @@ function loadPartParameterTable(table, url, options) {
|
||||
filters[key] = params[key];
|
||||
}
|
||||
|
||||
// setupFilterLsit("#part-parameters", $(table));
|
||||
// setupFilterList("#part-parameters", $(table));
|
||||
|
||||
$(table).inventreeTable({
|
||||
url: url,
|
||||
@ -876,23 +876,7 @@ function loadPartTable(table, url, options={}) {
|
||||
switchable: false,
|
||||
formatter: function(value, row) {
|
||||
|
||||
var name = '';
|
||||
|
||||
if (row.IPN) {
|
||||
name += row.IPN;
|
||||
name += ' | ';
|
||||
}
|
||||
|
||||
name += value;
|
||||
|
||||
if (row.revision) {
|
||||
name += ' | ';
|
||||
name += row.revision;
|
||||
}
|
||||
|
||||
if (row.is_template) {
|
||||
name = '<i>' + name + '</i>';
|
||||
}
|
||||
var name = row.full_name;
|
||||
|
||||
var display = imageHoverIcon(row.thumbnail) + renderLink(name, '/part/' + row.pk + '/');
|
||||
|
||||
|
@ -4,12 +4,6 @@
|
||||
{% load i18n %}
|
||||
|
||||
{% settings_value 'BARCODE_ENABLE' as barcodes %}
|
||||
{% settings_value 'BUILD_FUNCTION_ENABLE' as enable_build %}
|
||||
{% settings_value 'BUY_FUNCTION_ENABLE' as enable_buy %}
|
||||
{% settings_value 'SELL_FUNCTION_ENABLE' as enable_sell %}
|
||||
{% settings_value 'STOCK_FUNCTION_ENABLE' as enable_stock %}
|
||||
{% settings_value 'SO_FUNCTION_ENABLE' as enable_so %}
|
||||
{% settings_value 'PO_FUNCTION_ENABLE' as enable_po %}
|
||||
|
||||
<nav class="navbar navbar-xs navbar-default navbar-fixed-top ">
|
||||
<div class="container-fluid">
|
||||
@ -29,32 +23,28 @@
|
||||
{% if roles.part.view %}
|
||||
<li><a href="{% url 'part-index' %}"><span class='fas fa-shapes icon-header'></span>{% trans "Parts" %}</a></li>
|
||||
{% endif %}
|
||||
{% if roles.stock.view and enable_stock %}
|
||||
{% if roles.stock.view %}
|
||||
<li><a href="{% url 'stock-index' %}"><span class='fas fa-boxes icon-header'></span>{% trans "Stock" %}</a></li>
|
||||
{% endif %}
|
||||
{% if roles.build.view and enable_build %}
|
||||
{% if roles.build.view %}
|
||||
<li><a href="{% url 'build-index' %}"><span class='fas fa-tools icon-header'></span>{% trans "Build" %}</a></li>
|
||||
{% endif %}
|
||||
{% if roles.purchase_order.view and enable_buy %}
|
||||
{% if roles.purchase_order.view %}
|
||||
<li class='nav navbar-nav'>
|
||||
<a class='dropdown-toggle' data-toggle='dropdown' href='#'><span class='fas fa-shopping-cart icon-header'></span>{% trans "Buy" %}</a>
|
||||
<ul class='dropdown-menu'>
|
||||
<li><a href="{% url 'supplier-index' %}"><span class='fas fa-building icon-header'></span>{% trans "Suppliers" %}</a></li>
|
||||
<li><a href="{% url 'manufacturer-index' %}"><span class='fas fa-industry icon-header'></span>{% trans "Manufacturers" %}</a></li>
|
||||
{% if enable_po %}
|
||||
<li><a href="{% url 'po-index' %}"><span class='fas fa-list icon-header'></span>{% trans "Purchase Orders" %}</a></li>
|
||||
{% endif %}
|
||||
</ul>
|
||||
</li>
|
||||
{% endif %}
|
||||
{% if roles.sales_order.view and enable_sell %}
|
||||
{% if roles.sales_order.view %}
|
||||
<li class='nav navbar-nav'>
|
||||
<a class='dropdown-toggle' data-toggle='dropdown' href='#'><span class='fas fa-truck icon-header'></span>{% trans "Sell" %}</a>
|
||||
<ul class='dropdown-menu'>
|
||||
<li><a href="{% url 'customer-index' %}"><span class='fas fa-user-tie icon-header'></span>{% trans "Customers" %}</a>
|
||||
{% if enable_so %}
|
||||
<li><a href="{% url 'so-index' %}"><span class='fas fa-list icon-header'></span>{% trans "Sales Orders" %}</a></li>
|
||||
{% endif %}
|
||||
</ul>
|
||||
</li>
|
||||
{% endif %}
|
||||
|
Reference in New Issue
Block a user