mirror of
https://github.com/inventree/InvenTree.git
synced 2025-06-18 13:05:42 +00:00
Merge branch 'inventree:master' into matmair/issue2694
This commit is contained in:
@ -1,8 +1,9 @@
|
||||
{% extends "base.html" %}
|
||||
{% load i18n %}
|
||||
{% load inventree_extras %}
|
||||
|
||||
{% block page_title %}
|
||||
InvenTree | {% trans "Permission Denied" %}
|
||||
{% inventree_title %} | {% trans "Permission Denied" %}
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
|
@ -1,8 +1,9 @@
|
||||
{% extends "base.html" %}
|
||||
{% load i18n %}
|
||||
{% load inventree_extras %}
|
||||
|
||||
{% block page_title %}
|
||||
InvenTree | {% trans "Page Not Found" %}
|
||||
{% inventree_title %} | {% trans "Page Not Found" %}
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
|
@ -1,8 +1,9 @@
|
||||
{% extends "base.html" %}
|
||||
{% load i18n %}
|
||||
{% load inventree_extras %}
|
||||
|
||||
{% block page_title %}
|
||||
InvenTree | {% trans "Internal Server Error" %}
|
||||
{% inventree_title %} | {% trans "Internal Server Error" %}
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
@ -11,7 +12,7 @@ InvenTree | {% trans "Internal Server Error" %}
|
||||
<h3>{% trans "Internal Server Error" %}</h3>
|
||||
|
||||
<div class='alert alert-danger alert-block'>
|
||||
{% trans "The InvenTree server raised an internal error" %}<br>
|
||||
{% blocktrans %}The {{ inventree_title }} server raised an internal error{% endblocktrans %}<br>
|
||||
{% trans "Refer to the error log in the admin interface for further details" %}
|
||||
</div>
|
||||
</div>
|
||||
|
@ -30,7 +30,7 @@
|
||||
<div class='container-fluid'>
|
||||
|
||||
<div class='clearfix content-heading login-header d-flex flex-wrap'>
|
||||
<img class="pull-left" src="{% static 'img/inventree.png' %}" width="60" height="60"/>
|
||||
<img class="pull-left" src="{% inventree_logo %}" width="60" height="60"/>
|
||||
{% include "spacer.html" %}
|
||||
<span class='float-right'><h3>{% block body_title %}{% trans 'Site is in Maintenance' %}{% endblock %}</h3></span>
|
||||
</div>
|
||||
|
@ -15,6 +15,7 @@
|
||||
<tbody>
|
||||
{% include "InvenTree/settings/setting.html" with key="INVENTREE_INSTANCE" icon="fa-info-circle" %}
|
||||
{% include "InvenTree/settings/setting.html" with key="INVENTREE_INSTANCE_TITLE" icon="fa-info-circle" %}
|
||||
{% include "InvenTree/settings/setting.html" with key="INVENTREE_RESTRICT_ABOUT" icon="fa-info-circle" %}
|
||||
{% include "InvenTree/settings/setting.html" with key="INVENTREE_BASE_URL" icon="fa-globe" %}
|
||||
{% include "InvenTree/settings/setting.html" with key="INVENTREE_COMPANY_NAME" icon="fa-building" %}
|
||||
{% include "InvenTree/settings/setting.html" with key="INVENTREE_DOWNLOAD_FROM_URL" icon="fa-cloud-download-alt" %}
|
||||
|
@ -13,7 +13,7 @@
|
||||
{% block content %}
|
||||
|
||||
<div class='alert alert-block alert-danger'>
|
||||
{% trans "Changing the settings below require you to immediatly restart InvenTree. Do not change this while under active usage." %}
|
||||
{% trans "Changing the settings below require you to immediatly restart the server. Do not change this while under active usage." %}
|
||||
</div>
|
||||
|
||||
<div class='table-responsive'>
|
||||
|
@ -85,7 +85,7 @@
|
||||
{% if plugin.is_package %}
|
||||
{% trans "This plugin was installed as a package" %}
|
||||
{% else %}
|
||||
{% trans "This plugin was found in a local InvenTree path" %}
|
||||
{% trans "This plugin was found in a local server path" %}
|
||||
{% endif %}
|
||||
</td>
|
||||
</tr>
|
||||
|
@ -11,6 +11,7 @@
|
||||
|
||||
<table class='table table-striped table-condensed'>
|
||||
<tbody>
|
||||
{% include "InvenTree/settings/setting.html" with key="STOCK_BATCH_CODE_TEMPLATE" icon="fa-layer-group" %}
|
||||
{% include "InvenTree/settings/setting.html" with key="STOCK_ENABLE_EXPIRY" icon="fa-stopwatch" %}
|
||||
{% include "InvenTree/settings/setting.html" with key="STOCK_STALE_DAYS" icon="fa-calendar" %}
|
||||
{% include "InvenTree/settings/setting.html" with key="STOCK_ALLOW_EXPIRED_SALE" icon="fa-truck" %}
|
||||
|
@ -101,7 +101,7 @@
|
||||
</div>
|
||||
<div class="col-sm-6">
|
||||
<h4>{% trans "Help the translation efforts!" %}</h4>
|
||||
<p>{% blocktrans with link="https://crowdin.com/project/inventree" %}Native language translation of the InvenTree web application is <a href="{{link}}">community contributed via crowdin</a>. Contributions are welcomed and encouraged.{% endblocktrans %}</p>
|
||||
<p>{% blocktrans with link="https://crowdin.com/project/inventree" %}Native language translation of the web application is <a href="{{link}}">community contributed via crowdin</a>. Contributions are welcomed and encouraged.{% endblocktrans %}</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
@ -67,7 +67,7 @@
|
||||
<div class='container-fluid'>
|
||||
|
||||
<div class='clearfix content-heading login-header d-flex flex-wrap'>
|
||||
<img class="pull-left" src="{% static 'img/inventree.png' %}" width="60" height="60"/>
|
||||
<img class="pull-left" src="{% inventree_logo %}" width="60" height="60"/>
|
||||
{% include "spacer.html" %}
|
||||
<span class='float-right'><h3>{% inventree_title %}</h3></span>
|
||||
</div>
|
||||
@ -89,7 +89,7 @@
|
||||
<script type='text/javascript' src="{% static 'script/jquery-ui/jquery-ui.min.js' %}"></script>
|
||||
<script type="text/javascript" src="{% static 'bootstrap/js/bootstrap.bundle.min.js' %}"></script>
|
||||
|
||||
<!-- general InvenTree -->
|
||||
<!-- general JS -->
|
||||
<script type='text/javascript' src="{% static 'script/inventree/inventree.js' %}"></script>
|
||||
<script type='text/javascript' src="{% i18n_static 'notification.js' %}"></script>
|
||||
|
||||
|
@ -10,6 +10,7 @@
|
||||
{% settings_value 'LOGIN_ENABLE_REG' as enable_reg %}
|
||||
{% settings_value 'LOGIN_ENABLE_PWD_FORGOT' as enable_pwd_forgot %}
|
||||
{% settings_value 'LOGIN_ENABLE_SSO' as enable_sso %}
|
||||
{% inventree_customize 'login_message' as login_message %}
|
||||
{% mail_configured as mail_conf %}
|
||||
{% inventree_demo_mode as demo %}
|
||||
|
||||
@ -35,19 +36,15 @@ for a account and sign in below:{% endblocktrans %}</p>
|
||||
{% endif %}
|
||||
|
||||
<hr>
|
||||
{% if login_message %}
|
||||
<div>{{ login_message }}<hr></div>
|
||||
{% endif %}
|
||||
<div class="btn-group float-right" role="group">
|
||||
<button class="btn btn-success" type="submit">{% trans "Sign In" %}</button>
|
||||
</div>
|
||||
{% if mail_conf and enable_pwd_forgot and not demo %}
|
||||
<a class="" href="{% url 'account_reset_password' %}"><small>{% trans "Forgot Password?" %}</small></a>
|
||||
{% endif %}
|
||||
{% if demo %}
|
||||
<p>
|
||||
<h6>
|
||||
{% trans "InvenTree demo instance" %} - <a href='https://inventree.readthedocs.io/en/latest/demo/'>{% trans "Click here for login details" %}</a>
|
||||
</h6>
|
||||
</p>
|
||||
{% endif %}
|
||||
</form>
|
||||
|
||||
{% if enable_sso %}
|
||||
|
@ -7,6 +7,7 @@
|
||||
{% settings_value "REPORT_ENABLE" as report_enabled %}
|
||||
{% settings_value "SERVER_RESTART_REQUIRED" as server_restart_required %}
|
||||
{% settings_value "LABEL_ENABLE" with user=user as labels_enabled %}
|
||||
{% inventree_show_about user as show_about %}
|
||||
{% inventree_demo_mode as demo_mode %}
|
||||
|
||||
<!DOCTYPE html>
|
||||
@ -130,7 +131,7 @@
|
||||
</div>
|
||||
|
||||
{% include 'modals.html' %}
|
||||
{% include 'about.html' %}
|
||||
{% if show_about %}{% include 'about.html' %}{% endif %}
|
||||
{% include "notifications.html" %}
|
||||
{% include "search.html" %}
|
||||
</div>
|
||||
@ -166,7 +167,7 @@
|
||||
<script type='text/javascript' src="{% static 'script/clipboard.min.js' %}"></script>
|
||||
<script type='text/javascript' src="{% static 'script/randomColor.min.js' %}"></script>
|
||||
|
||||
<!-- general InvenTree -->
|
||||
<!-- general JS -->
|
||||
<script type='text/javascript' src="{% static 'script/inventree/inventree.js' %}"></script>
|
||||
|
||||
<!-- dynamic javascript templates -->
|
||||
|
@ -32,7 +32,7 @@
|
||||
{% block footer_prefix %}
|
||||
<!-- Custom footer information goes here -->
|
||||
{% endblock %}
|
||||
<p><em><small>{% trans "InvenTree version" %}: {% inventree_version %} - <a href='https://inventree.readthedocs.io'>inventree.readthedocs.io</a></small></em></p>
|
||||
<p><em><small>{% inventree_version shortstring=True %} - <a href='https://inventree.readthedocs.io'>readthedocs.io</a></small></em></p>
|
||||
{% block footer_suffix %}
|
||||
<!-- Custom footer information goes here -->
|
||||
{% endblock %}
|
||||
|
@ -691,8 +691,24 @@ function loadBomTable(table, options={}) {
|
||||
|
||||
setupFilterList('bom', $(table));
|
||||
|
||||
// Construct the table columns
|
||||
function availableQuantity(row) {
|
||||
|
||||
// Base stock
|
||||
var available = row.available_stock;
|
||||
|
||||
// Substitute stock
|
||||
available += (row.available_substitute_stock || 0);
|
||||
|
||||
// Variant stock
|
||||
if (row.allow_variants) {
|
||||
available += (row.available_variant_stock || 0);
|
||||
}
|
||||
|
||||
return available;
|
||||
|
||||
}
|
||||
|
||||
// Construct the table columns
|
||||
var cols = [];
|
||||
|
||||
if (options.editable) {
|
||||
@ -807,15 +823,27 @@ function loadBomTable(table, options={}) {
|
||||
var url = `/part/${row.sub_part_detail.pk}/?display=part-stock`;
|
||||
|
||||
// Calculate total "available" (unallocated) quantity
|
||||
var total = row.available_stock + row.available_substitute_stock;
|
||||
var substitute_stock = row.available_substitute_stock || 0;
|
||||
var variant_stock = row.allow_variants ? (row.available_variant_stock || 0) : 0;
|
||||
|
||||
var text = `${total}`;
|
||||
var available_stock = availableQuantity(row);
|
||||
|
||||
var text = `${available_stock}`;
|
||||
|
||||
if (total <= 0) {
|
||||
if (available_stock <= 0) {
|
||||
text = `<span class='badge rounded-pill bg-danger'>{% trans "No Stock Available" %}</span>`;
|
||||
} else {
|
||||
if (row.available_substitute_stock > 0) {
|
||||
text += `<span title='{% trans "Includes substitute stock" %}' class='fas fa-info-circle float-right icon-blue'></span>`;
|
||||
var extra = '';
|
||||
if ((substitute_stock > 0) && (variant_stock > 0)) {
|
||||
extra = '{% trans "Includes variant and substitute stock" %}';
|
||||
} else if (variant_stock > 0) {
|
||||
extra = '{% trans "Includes variant stock" %}';
|
||||
} else if (substitute_stock > 0) {
|
||||
extra = '{% trans "Includes substitute stock" %}';
|
||||
}
|
||||
|
||||
if (extra) {
|
||||
text += `<span title='${extra}' class='fas fa-info-circle float-right icon-blue'></span>`;
|
||||
}
|
||||
}
|
||||
|
||||
@ -910,7 +938,7 @@ function loadBomTable(table, options={}) {
|
||||
formatter: function(value, row) {
|
||||
var can_build = 0;
|
||||
|
||||
var available = row.available_stock + row.available_substitute_stock;
|
||||
var available = availableQuantity(row);
|
||||
|
||||
if (row.quantity > 0) {
|
||||
can_build = available / row.quantity;
|
||||
@ -924,11 +952,11 @@ function loadBomTable(table, options={}) {
|
||||
var cb_b = 0;
|
||||
|
||||
if (rowA.quantity > 0) {
|
||||
cb_a = (rowA.available_stock + rowA.available_substitute_stock) / rowA.quantity;
|
||||
cb_a = availableQuantity(rowA) / rowA.quantity;
|
||||
}
|
||||
|
||||
if (rowB.quantity > 0) {
|
||||
cb_b = (rowB.available_stock + rowB.available_substitute_stock) / rowB.quantity;
|
||||
cb_b = availableQuantity(rowB) / rowB.quantity;
|
||||
}
|
||||
|
||||
return (cb_a > cb_b) ? 1 : -1;
|
||||
|
@ -1031,6 +1031,23 @@ function loadBuildOutputAllocationTable(buildInfo, output, options={}) {
|
||||
return row.required;
|
||||
}
|
||||
|
||||
function availableQuantity(row) {
|
||||
|
||||
// Base stock
|
||||
var available = row.available_stock;
|
||||
|
||||
// Substitute stock
|
||||
available += (row.available_substitute_stock || 0);
|
||||
|
||||
// Variant stock
|
||||
if (row.allow_variants) {
|
||||
available += (row.available_variant_stock || 0);
|
||||
}
|
||||
|
||||
return available;
|
||||
|
||||
}
|
||||
|
||||
function sumAllocations(row) {
|
||||
// Calculat total allocations for a given row
|
||||
if (!row.allocations) {
|
||||
@ -1425,20 +1442,52 @@ function loadBuildOutputAllocationTable(buildInfo, output, options={}) {
|
||||
title: '{% trans "Available" %}',
|
||||
sortable: true,
|
||||
formatter: function(value, row) {
|
||||
var total = row.available_stock + row.available_substitute_stock;
|
||||
|
||||
var text = `${total}`;
|
||||
var url = `/part/${row.sub_part_detail.pk}/?display=part-stock`;
|
||||
|
||||
if (total <= 0) {
|
||||
text = `<span class='badge rounded-pill bg-danger'>{% trans "No Stock Available" %}</span>`;
|
||||
// Calculate total "available" (unallocated) quantity
|
||||
var substitute_stock = row.available_substitute_stock || 0;
|
||||
var variant_stock = row.allow_variants ? (row.available_variant_stock || 0) : 0;
|
||||
|
||||
var available_stock = availableQuantity(row);
|
||||
|
||||
var required = requiredQuantity(row);
|
||||
|
||||
var text = '';
|
||||
|
||||
if (available_stock > 0) {
|
||||
text += `${available_stock}`;
|
||||
}
|
||||
|
||||
if (available_stock < required) {
|
||||
text += `<span class='fas fa-times-circle icon-red float-right' title='{% trans "Insufficient stock available" %}'></span>`;
|
||||
} else {
|
||||
if (row.available_substitute_stock > 0) {
|
||||
text += `<span title='{% trans "Includes substitute stock" %}' class='fas fa-info-circle float-right icon-blue'></span>`;
|
||||
}
|
||||
text += `<span class='fas fa-check-circle icon-green float-right' title='{% trans "Sufficient stock available" %}'></span>`;
|
||||
}
|
||||
|
||||
return text;
|
||||
}
|
||||
if (available_stock <= 0) {
|
||||
text += `<span class='badge rounded-pill bg-danger'>{% trans "No Stock Available" %}</span>`;
|
||||
} else {
|
||||
var extra = '';
|
||||
if ((substitute_stock > 0) && (variant_stock > 0)) {
|
||||
extra = '{% trans "Includes variant and substitute stock" %}';
|
||||
} else if (variant_stock > 0) {
|
||||
extra = '{% trans "Includes variant stock" %}';
|
||||
} else if (substitute_stock > 0) {
|
||||
extra = '{% trans "Includes substitute stock" %}';
|
||||
}
|
||||
|
||||
if (extra) {
|
||||
text += `<span title='${extra}' class='fas fa-info-circle float-right icon-blue'></span>`;
|
||||
}
|
||||
}
|
||||
|
||||
return renderLink(text, url);
|
||||
},
|
||||
sorter: function(valA, valB, rowA, rowB) {
|
||||
|
||||
return availableQuantity(rowA) > availableQuantity(rowB) ? 1 : -1;
|
||||
},
|
||||
},
|
||||
{
|
||||
field: 'allocated',
|
||||
|
@ -672,7 +672,20 @@ function loadPartVariantTable(table, partId, options={}) {
|
||||
field: 'in_stock',
|
||||
title: '{% trans "Stock" %}',
|
||||
formatter: function(value, row) {
|
||||
return renderLink(value, `/part/${row.pk}/?display=part-stock`);
|
||||
|
||||
var base_stock = row.in_stock;
|
||||
var variant_stock = row.variant_stock || 0;
|
||||
|
||||
var total = base_stock + variant_stock;
|
||||
|
||||
var text = `${total}`;
|
||||
|
||||
if (variant_stock > 0) {
|
||||
text = `<em>${text}</em>`;
|
||||
text += `<span title='{% trans "Includes variant stock" %}' class='fas fa-info-circle float-right icon-blue'></span>`;
|
||||
}
|
||||
|
||||
return renderLink(text, `/part/${row.pk}/?display=part-stock`);
|
||||
}
|
||||
}
|
||||
];
|
||||
@ -1917,7 +1930,9 @@ function loadPriceBreakTable(table, options) {
|
||||
formatNoMatches: function() {
|
||||
return `{% trans "No ${human_name} information found" %}`;
|
||||
},
|
||||
queryParams: {part: options.part},
|
||||
queryParams: {
|
||||
part: options.part
|
||||
},
|
||||
url: options.url,
|
||||
onLoadSuccess: function(tableData) {
|
||||
if (linkedGraph) {
|
||||
@ -2023,36 +2038,45 @@ function initPriceBreakSet(table, options) {
|
||||
}
|
||||
|
||||
pb_new_btn.click(function() {
|
||||
launchModalForm(pb_new_url,
|
||||
{
|
||||
success: reloadPriceBreakTable,
|
||||
data: {
|
||||
part: part_id,
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
constructForm(pb_new_url, {
|
||||
fields: {
|
||||
part: {
|
||||
hidden: true,
|
||||
value: part_id,
|
||||
},
|
||||
quantity: {},
|
||||
price: {},
|
||||
price_currency: {},
|
||||
},
|
||||
method: 'POST',
|
||||
title: '{% trans "Add Price Break" %}',
|
||||
onSuccess: reloadPriceBreakTable,
|
||||
});
|
||||
});
|
||||
|
||||
table.on('click', `.button-${pb_url_slug}-delete`, function() {
|
||||
var pk = $(this).attr('pk');
|
||||
|
||||
launchModalForm(
|
||||
`/part/${pb_url_slug}/${pk}/delete/`,
|
||||
{
|
||||
success: reloadPriceBreakTable
|
||||
}
|
||||
);
|
||||
constructForm(`${pb_url}${pk}/`, {
|
||||
method: 'DELETE',
|
||||
title: '{% trans "Delete Price Break" %}',
|
||||
onSuccess: reloadPriceBreakTable,
|
||||
});
|
||||
});
|
||||
|
||||
table.on('click', `.button-${pb_url_slug}-edit`, function() {
|
||||
var pk = $(this).attr('pk');
|
||||
|
||||
launchModalForm(
|
||||
`/part/${pb_url_slug}/${pk}/edit/`,
|
||||
{
|
||||
success: reloadPriceBreakTable
|
||||
}
|
||||
);
|
||||
constructForm(`${pb_url}${pk}/`, {
|
||||
fields: {
|
||||
quantity: {},
|
||||
price: {},
|
||||
price_currency: {},
|
||||
},
|
||||
title: '{% trans "Edit Price Break" %}',
|
||||
onSuccess: reloadPriceBreakTable,
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -7,11 +7,13 @@
|
||||
{% settings_value 'STICKY_HEADER' user=request.user as sticky %}
|
||||
{% navigation_enabled as plugin_nav %}
|
||||
{% inventree_demo_mode as demo %}
|
||||
{% inventree_show_about user as show_about %}
|
||||
{% inventree_customize 'navbar_message' as navbar_message %}
|
||||
|
||||
<nav class="navbar {% if sticky %}fixed-top{% endif %} navbar-expand-lg navbar-light">
|
||||
<div class="container-fluid">
|
||||
<div class="navbar-header clearfix content-heading">
|
||||
<a class="navbar-brand" id='logo' href="{% url 'index' %}" style="padding-top: 7px; padding-bottom: 5px;"><img src="{% static 'img/inventree.png' %}" width="32" height="32" style="display:block; margin: auto;"/></a>
|
||||
<a class="navbar-brand" id='logo' href="{% url 'index' %}" style="padding-top: 7px; padding-bottom: 5px;"><img src="{% inventree_logo %}" width="32" height="32" style="display:block; margin: auto;"/></a>
|
||||
</div>
|
||||
<div class="navbar-collapse collapse" id="navbar-objects">
|
||||
<ul class="navbar-nav">
|
||||
@ -84,8 +86,13 @@
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
{% if demo %}
|
||||
{% include "navbar_demo.html" %}
|
||||
{% if navbar_message %}
|
||||
{% include "spacer.html" %}
|
||||
<div class='flex justify-content-center'>
|
||||
{{ navbar_message }}
|
||||
</div>
|
||||
{% include "spacer.html" %}
|
||||
{% include "spacer.html" %}
|
||||
{% endif %}
|
||||
|
||||
<ul class='navbar-nav flex-row'>
|
||||
@ -144,6 +151,7 @@
|
||||
{% trans "System Information" %}
|
||||
</a>
|
||||
</li>
|
||||
{% if show_about %}
|
||||
<li id='launch-about'>
|
||||
<a class='dropdown-item' href='#'>
|
||||
{% if up_to_date %}
|
||||
@ -154,6 +162,7 @@
|
||||
{% trans "About InvenTree" %}
|
||||
</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
|
@ -1,12 +0,0 @@
|
||||
{% load i18n %}
|
||||
{% include "spacer.html" %}
|
||||
<div class='flex'>
|
||||
<h6>
|
||||
{% trans "InvenTree demo mode" %}
|
||||
<a href='https://inventree.readthedocs.io/en/latest/demo/'>
|
||||
<span class='fas fa-info-circle'></span>
|
||||
</a>
|
||||
</h6>
|
||||
</div>
|
||||
{% include "spacer.html" %}
|
||||
{% include "spacer.html" %}
|
@ -75,7 +75,7 @@
|
||||
<script type='text/javascript' src="{% static 'script/clipboard.min.js' %}"></script>
|
||||
<script type='text/javascript' src="{% static 'script/randomColor.min.js' %}"></script>
|
||||
|
||||
<!-- general InvenTree -->
|
||||
<!-- general JS -->
|
||||
<script type='text/javascript' src="{% static 'script/inventree/inventree.js' %}"></script>
|
||||
<script type='text/javascript' src="{% i18n_static 'notification.js' %}"></script>
|
||||
{% block body_scripts_inventree %}
|
||||
|
Reference in New Issue
Block a user