2
0
mirror of https://github.com/inventree/InvenTree.git synced 2025-08-07 20:32:12 +00:00
Files
InvenTree/InvenTree/stock/templates/stock/location.html
Oliver 397419f365 Build consume stock (#4817)
* Adds "consumed_by" field to the StockItem model.

- Points to a BuildOrder instance which "consumed" this stock
- Marks item as unavailable
- Allows filtering against build order

* Allow API filtering

* Adds table of "consumed stock items" to build order page

* Update stock table to show "consumed by" stock status

* Add "consumed_by" link to stock item detail

* Optionally add 'buildorder' details to installStockItem method

* Update methodology for completing a build item

- Instead of deleting stock, mark as "consumed by"

* Fix history entry for splitting stock

* Bug fix

* track "consumed_by" field for tracked items also

* Update build docs

* Update allocation documentation

* Update terminology.md

* Unit test updates

* Fix conflicting migrations

* revert change
2023-05-16 21:25:02 +10:00

448 lines
14 KiB
HTML

{% extends "stock/stock_app_base.html" %}
{% load static %}
{% load inventree_extras %}
{% load plugin_extras %}
{% load i18n %}
{% block sidebar %}
{% include "stock/location_sidebar.html" %}
{% endblock sidebar %}
{% block breadcrumb_tree %}
<div id="breadcrumb-tree"></div>
{% endblock breadcrumb_tree %}
{% block heading %}
{% if location %}
{% trans "Stock Location" %}:
{% settings_value "STOCK_LOCATION_DEFAULT_ICON" as default_icon %}
{% if location.icon or default_icon %}
<span class="{{ location.icon|default:default_icon }}"></span>
{% endif %}
{{ location.name }}
{% else %}
{% trans "Stock" %}
{% endif %}
{% endblock heading %}
{% block actions %}
<!-- Admin view -->
{% if location and user.is_staff and roles.stock_location.change %}
{% url 'admin:stock_stocklocation_change' location.pk as url %}
{% include "admin_button.html" with url=url %}
{% endif %}
{% settings_value "STOCKTAKE_ENABLE" as stocktake_enable %}
{% if stocktake_enable and roles.stocktake.add %}
<button type='button' class='btn btn-outline-secondary' id='location-stocktake' title='{% trans "Perform stocktake for this stock location" %}'>
<span class='fas fa-clipboard-check'></span>
</button>
{% endif %}
{% mixin_available "locate" as locate_available %}
{% if location and plugins_enabled and locate_available %}
<button id='locate-location-button' title='{% trans "Locate stock location" %}' class='btn btn-outline-secondary' typy='button'>
<span class='fas fa-search-location'></span>
</button>
{% endif %}
{% if barcodes %}
<!-- Barcode actions menu -->
{% if location %}
<div class='btn-group' role='group'>
<button id='barcode-options' 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='caret'></span></button>
<ul class='dropdown-menu'>
<li><a class='dropdown-item' href='#' id='show-qr-code'><span class='fas fa-qrcode'></span> {% trans "Show QR Code" %}</a></li>
{% if location.barcode_hash %}
<li><a class='dropdown-item' href='#' id='barcode-unlink'><span class='fas fa-unlink'></span> {% trans "Unlink Barcode" %}</a></li>
{% else %}
<li><a class='dropdown-item' href='#' id='barcode-link'><span class='fas fa-link'></span> {% trans "Link Barcode" %}</a></li>
{% endif %}
<li><a class='dropdown-item' href='#' id='barcode-scan-in-items' title='{% trans "Scan stock items into this location" %}'><span class='fas fa-boxes'></span> {% trans "Scan In Stock Items" %}</a></li>
<li><a class='dropdown-item' href='#' id='barcode-scan-in-containers' title='{% trans "Scan stock container into this location" %}'><span class='fas fa-sitemap'></span> {% trans "Scan In Container" %}</a></li>
</ul>
</div>
<!-- Printing action -->
{% if labels_enabled %}
<div class='btn-group' role='group'>
<button id='printing-options' title='{% trans "Printing actions" %}' class='btn btn-outline-secondary dropdown-toggle' type='button' data-bs-toggle='dropdown'>
<span class='fas fa-print'></span> <span class='caret'></span>
</button>
<ul class='dropdown-menu'>
<li><a class='dropdown-item' href='#' id='print-label'><span class='fas fa-tag'></span> {% trans "Print Label" %}</a>
</ul>
</div>
{% endif %}
<!-- Check permissions and owner -->
{% if user_owns_location %}
{% if roles.stock.change %}
<div class='btn-group' role='group'>
<button id='stock-actions' title='{% trans "Stock actions" %}' class='btn btn-outline-secondary dropdown-toggle' type='button' data-bs-toggle='dropdown'>
<span class='fas fa-boxes'></span> <span class='caret'></span>
</button>
<ul class='dropdown-menu' role='menu'>
<li>
<a class='dropdown-item' href='#' id='location-count'>
<span class='fas fa-clipboard-list'></span>
{% trans "Count stock" %}
</a>
</li>
<li>
<a class='dropdown-item' href='#' id='location-move'>
<span class='fas fa-exchange-alt'></span>
{% trans "Transfer stock" %}
</a>
</li>
</ul>
</div>
{% endif %}
{% if roles.stock_location.change %}
<div class='btn-group' role='group'>
<button id='location-actions' title='{% trans "Location actions" %}' class='btn btn-outline-secondary dropdown-toggle' type='button' data-bs-toggle="dropdown"><span class='fas fa-sitemap'></span> <span class='caret'></span></button>
<ul class='dropdown-menu' role='menu'>
<li><a class='dropdown-item' href='#' id='location-edit'><span class='fas fa-edit icon-green'></span> {% trans "Edit location" %}</a></li>
{% if roles.stock.delete %}
<li><a class='dropdown-item' href='#' id='location-delete'><span class='fas fa-trash-alt icon-red'></span> {% trans "Delete location" %}</a></li>
{% endif %}
</ul>
</div>
{% endif %}
{% endif %}
{% endif %}
{% endif %}
{% endblock actions %}
{% block details_left %}
<table class='table table-striped table-condensed'>
<col width='25'>
{% if location %}
{% if location.description %}
<tr>
<td><span class='fas fa-info-circle'></span></td>
<td>{% trans "Description" %}</td>
<td>{{ location.description }}</td>
</tr>
{% endif %}
<tr>
<td><span class='fas fa-sitemap'></span></td>
<td>{% trans "Location Path" %}</td>
<td>{{ location.pathstring }}</td>
</tr>
{% else %}
<tr>
<td><span class='fas fa-sitemap'></span></td>
<td>{% trans "Location Path" %}</td>
<td><em>{% trans "Top level stock location" %}</em></td>
</tr>
{% endif %}
{% if ownership_enabled and location_owner %}
<tr>
<td><span class='fas fa-users'></span></td>
<td>{% trans "Location Owner" %}</td>
<td>
{{ location_owner }}
{% if not user_owns_location %}
<span class='badge rounded-pill bg-warning badge-right' title='{% trans "You are not in the list of owners of this location. This stock location cannot be edited." %}'>
{% trans "Read only" %}
</span>
{% endif %}
</td>
</tr>
{% endif %}
{% include "barcode_data.html" with instance=location %}
</table>
{% endblock details_left %}
{% block details_right %}
{% if location %}
<table class='table table-striped table-condensed'>
<col width='25'>
<tr>
<td><span class='fas fa-map-marker-alt'></span></td>
<td>{% trans "Sublocations" %}</td>
<td>{{ location.children.count }}</td>
</tr>
<tr>
<td><span class='fas fa-boxes'></span></td>
<td>{% trans "Stock Items" %}</td>
<td>{{ location.item_count }}</td>
</tr>
</table>
{% else %}
<table class='table table-striped table-condensed'>
<col width='25'>
<tr>
<td><span class='fas fa-map-marker-alt'></span></td>
<td>{% trans "Stock Locations" %}</td>
<td>{{ loc_count }}</td>
</tr>
<tr>
<td><span class='fas fa-boxes'></span></td>
<td>{% trans "Stock Items" %}</td>
<td>{{ stock_count }}</td>
</tr>
</table>
{% endif %}
{% endblock details_right %}
{% block page_content %}
<div class='panel panel-hidden' id='panel-stock'>
<div class='panel-heading'>
<div class='d-flex flex-wrap'>
<h4>{% trans "Stock Items" %}</h4>
{% include "spacer.html" %}
<div class='btn-group' role='group'>
<button type='button' class='btn btn-success' id='item-create' title='{% trans "Create new stock item" %}'>
<span class='fas fa-plus-circle'></span> {% trans "New Stock Item" %}
</button>
</div>
</div>
</div>
<div class='panel-content'>
{% include "stock_table.html" %}
</div>
</div>
<div class='panel panel-hidden' id='panel-sublocations'>
<div class='panel-heading'>
<div class='d-flex flex-wrap'>
<h4>{% trans "Sublocations" %}</h4>
{% include "spacer.html" %}
<div class='btn-group' role='group'>
{% if user_owns_location and roles.stock_location.add %}
<button class='btn btn-success' id='location-create' type='button' title='{% trans "Create new stock location" %}'>
<span class='fas fa-plus-circle'></span> {% trans "New Location" %}
</button>
{% endif %}
</div>
</div>
</div>
<div class='panel-content'>
<div id='sublocation-button-toolbar'>
<div class='btn-group' role='group'>
{% include "filter_list.html" with id="location" %}
</div>
</div>
<table class='table table-striped table-condensed' data-toolbar='#sublocation-button-toolbar' id='sublocation-table'></table>
</div>
</div>
{% endblock page_content %}
{% block js_ready %}
{{ block.super }}
{% settings_value "STOCKTAKE_ENABLE" as stocktake_enable %}
{% if stocktake_enable and roles.stocktake.add %}
$('#location-stocktake').click(function() {
generateStocktakeReport({
category: {},
location: {
{% if location %}value: {{ location.pk }},{% endif %}
},
generate_report: {},
update_parts: {},
});
});
{% endif %}
{% if plugins_enabled and location %}
$('#locate-location-button').click(function() {
locateItemOrLocation({
location: {{ location.pk }},
});
});
{% endif %}
onPanelLoad('sublocations', function() {
loadStockLocationTable($('#sublocation-table'), {
params: {
{% if location %}
parent: {{ location.pk }},
{% else %}
parent: 'null',
{% endif %}
},
allowTreeView: true,
});
});
linkButtonsToSelection(
$('#sublocation-table'),
[
'#location-print-options',
]
);
{% if labels_enabled %}
$('#print-label').click(function() {
var locs = [{{ location.pk }}];
printLabels({
items: locs,
singular_name: '{% trans "stock location" %}',
key: 'location',
url: '{% url "api-stocklocation-label-list" %}',
});
});
{% endif %}
{% if location %}
$("#barcode-scan-in-items").click(function() {
barcodeCheckInStockItems({{ location.id }});
});
$('#barcode-scan-in-containers').click(function() {
barcodeCheckInStockLocations({{ location.id }},
{
onSuccess: function() {
showMessage(
'{% trans "Scanned stock container into this location" %}',
{
style: 'success',
}
);
$('#sublocation-table').bootstrapTable('refresh');
}
}
);
});
{% endif %}
$('#location-create').click(function () {
createStockLocation({
{% if location %}
parent: {{ location.pk }},
{% endif %}
follow: true,
});
});
{% if location %}
$('#location-edit').click(function() {
editStockLocation({{ location.id }}, {
reload: true,
});
});
$('#location-delete').click(function() {
deleteStockLocation({{ location.pk }}, {
{% if location.parent %}
redirect: '{% url "stock-location-detail" location.parent.pk %}',
{% else %}
redirect: '{% url "stock-index" %}',
{% endif %}
});
});
function adjustLocationStock(action) {
inventreeGet(
'{% url "api-stock-list" %}',
{
location: {{ location.id }},
in_stock: true,
part_detail: true,
location_detail: true,
},
{
success: function(items) {
adjustStock(action, items, {
success: function() {
location.reload();
}
});
}
}
);
}
$("#location-count").click(function() {
adjustLocationStock('count');
});
$("#location-move").click(function() {
adjustLocationStock('move');
});
{% if barcodes %}
$('#show-qr-code').click(function() {
showQRDialog(
'{% trans "Stock Location QR Code" %}',
'{"stocklocation": {{ location.pk }} }'
);
});
$("#barcode-link").click(function() {
linkBarcodeDialog(
{
stocklocation: {{ location.pk }},
},
{
title: '{% trans "Link Barcode to Stock Location" %}',
}
);
});
$("#barcode-unlink").click(function() {
unlinkBarcode({
stocklocation: {{ location.pk }},
});
});
{% endif %}
{% endif %}
$('#item-create').click(function () {
createNewStockItem({
data: {
{% if location %}
location: {{ location.id }}
{% endif %}
},
});
});
onPanelLoad('stock', function() {
loadStockTable($("#stock-table"), {
buttons: [
'#stock-options',
],
params: {
{% if location %}
location: {{ location.pk }},
{% endif %}
part_detail: true,
location_detail: true,
supplier_part_detail: true,
},
});
});
enableSidebar('stocklocation');
// Enable breadcrumb tree view
enableBreadcrumbTree({
label: 'location',
url: '{% url "api-location-tree" %}',
{% if location %}
selected: {{ location.pk }},
{% endif %}
processNode: function(node) {
node.text = node.name;
node.href = `/stock/location/${node.pk}/`;
return node;
},
defaultIcon: global_settings.STOCK_LOCATION_DEFAULT_ICON,
});
{% endblock js_ready %}