mirror of
https://github.com/inventree/InvenTree.git
synced 2025-04-29 20:16:44 +00:00
Merge remote-tracking branch 'inventree/master' into order-parts-wizard
This commit is contained in:
commit
090445f2c3
@ -211,44 +211,18 @@
|
|||||||
{% if part.component %}
|
{% if part.component %}
|
||||||
{% if required_build_order_quantity > 0 %}
|
{% if required_build_order_quantity > 0 %}
|
||||||
<tr>
|
<tr>
|
||||||
<td><span class='fas fa-clipboard-list'></span></td>
|
<td><span class='fas fa-tools'></span></td>
|
||||||
<td>{% trans "Required for Build Orders" %}</td>
|
|
||||||
<td>{% decimal required_build_order_quantity %}</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td><span class='fas fa-dolly'></span></td>
|
|
||||||
<td>{% trans "Allocated to Build Orders" %}</td>
|
<td>{% trans "Allocated to Build Orders" %}</td>
|
||||||
<td>
|
<td>{% progress_bar allocated_build_order_quantity required_build_order_quantity id='build-order-allocated' max_width='150px' %}</td>
|
||||||
{% decimal allocated_build_order_quantity %}
|
|
||||||
{% if allocated_build_order_quantity < required_build_order_quantity %}
|
|
||||||
<span class='fas fa-times-circle icon-red float-right' title='{% trans "Required quantity has not been allocated" %}'></span>
|
|
||||||
{% else %}
|
|
||||||
<span class='fas fa-check-circle icon-green float-right' title='{% trans "Required quantity has been allocated" %}'></span>
|
|
||||||
{% endif %}
|
|
||||||
</td>
|
|
||||||
</tr>
|
</tr>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if part.salable %}
|
{% if part.salable %}
|
||||||
{% if required_sales_order_quantity > 0 %}
|
{% if required_sales_order_quantity > 0 %}
|
||||||
<tr>
|
<tr>
|
||||||
<td><span class='fas fa-clipboard-list'></span></td>
|
<td><span class='fas fa-truck'></span></td>
|
||||||
<td>{% trans "Required for Sales Orders" %}</td>
|
|
||||||
<td>
|
|
||||||
{% decimal required_sales_order_quantity %}
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td><span class='fas fa-dolly'></span></td>
|
|
||||||
<td>{% trans "Allocated to Sales Orders" %}</td>
|
<td>{% trans "Allocated to Sales Orders" %}</td>
|
||||||
<td>
|
<td>{% progress_bar allocated_sales_order_quantity required_sales_order_quantity id='sales-order-allocated' max_width='150px' %}</td>
|
||||||
{% decimal allocated_sales_order_quantity %}
|
|
||||||
{% if allocated_sales_order_quantity < required_sales_order_quantity %}
|
|
||||||
<span class='fas fa-times-circle icon-red float-right' title='{% trans "Required quantity has not been allocated" %}'></span>
|
|
||||||
{% else %}
|
|
||||||
<span class='fas fa-check-circle icon-green float-right' title='{% trans "Required quantity has been allocated" %}'></span>
|
|
||||||
{% endif %}
|
|
||||||
</td>
|
|
||||||
</tr>
|
</tr>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
@ -352,21 +352,24 @@ def visible_global_settings(*args, **kwargs):
|
|||||||
|
|
||||||
|
|
||||||
@register.simple_tag()
|
@register.simple_tag()
|
||||||
def progress_bar(val, max, *args, **kwargs):
|
def progress_bar(val, max_val, *args, **kwargs):
|
||||||
"""
|
"""
|
||||||
Render a progress bar element
|
Render a progress bar element
|
||||||
"""
|
"""
|
||||||
|
|
||||||
item_id = kwargs.get('id', 'progress-bar')
|
item_id = kwargs.get('id', 'progress-bar')
|
||||||
|
|
||||||
if val > max:
|
val = InvenTree.helpers.normalize(val)
|
||||||
|
max_val = InvenTree.helpers.normalize(max_val)
|
||||||
|
|
||||||
|
if val > max_val:
|
||||||
style = 'progress-bar-over'
|
style = 'progress-bar-over'
|
||||||
elif val < max:
|
elif val < max_val:
|
||||||
style = 'progress-bar-under'
|
style = 'progress-bar-under'
|
||||||
else:
|
else:
|
||||||
style = ''
|
style = ''
|
||||||
|
|
||||||
percent = float(val / max) * 100
|
percent = float(val / max_val) * 100
|
||||||
|
|
||||||
if percent > 100:
|
if percent > 100:
|
||||||
percent = 100
|
percent = 100
|
||||||
@ -383,7 +386,7 @@ def progress_bar(val, max, *args, **kwargs):
|
|||||||
html = f"""
|
html = f"""
|
||||||
<div id='{item_id}' class='progress' style='{" ".join(style_tags)}'>
|
<div id='{item_id}' class='progress' style='{" ".join(style_tags)}'>
|
||||||
<div class='progress-bar {style}' role='progressbar' aria-valuemin='0' aria-valuemax='100' style='width:{percent}%'></div>
|
<div class='progress-bar {style}' role='progressbar' aria-valuemin='0' aria-valuemax='100' style='width:{percent}%'></div>
|
||||||
<div class='progress-value'>{val} / {max}</div>
|
<div class='progress-value'>{val} / {max_val}</div>
|
||||||
</div>
|
</div>
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
@ -504,10 +504,10 @@ class APICallMixin:
|
|||||||
|
|
||||||
@property
|
@property
|
||||||
def api_headers(self):
|
def api_headers(self):
|
||||||
return {
|
headers = {'Content-Type': 'application/json'}
|
||||||
self.API_TOKEN: self.get_setting(self.API_TOKEN_SETTING),
|
if getattr(self, 'API_TOKEN_SETTING'):
|
||||||
'Content-Type': 'application/json'
|
headers[self.API_TOKEN] = self.get_setting(self.API_TOKEN_SETTING)
|
||||||
}
|
return headers
|
||||||
|
|
||||||
def api_build_url_args(self, arguments):
|
def api_build_url_args(self, arguments):
|
||||||
groups = []
|
groups = []
|
||||||
@ -515,16 +515,21 @@ class APICallMixin:
|
|||||||
groups.append(f'{key}={",".join([str(a) for a in val])}')
|
groups.append(f'{key}={",".join([str(a) for a in val])}')
|
||||||
return f'?{"&".join(groups)}'
|
return f'?{"&".join(groups)}'
|
||||||
|
|
||||||
def api_call(self, endpoint, method: str = 'GET', url_args=None, data=None, headers=None, simple_response: bool = True):
|
def api_call(self, endpoint, method: str = 'GET', url_args=None, data=None, headers=None, simple_response: bool = True, endpoint_is_url: bool = False):
|
||||||
if url_args:
|
if url_args:
|
||||||
endpoint += self.api_build_url_args(url_args)
|
endpoint += self.api_build_url_args(url_args)
|
||||||
|
|
||||||
if headers is None:
|
if headers is None:
|
||||||
headers = self.api_headers
|
headers = self.api_headers
|
||||||
|
|
||||||
|
if endpoint_is_url:
|
||||||
|
url = endpoint
|
||||||
|
else:
|
||||||
|
url = f'{self.api_url}/{endpoint}'
|
||||||
|
|
||||||
# build kwargs for call
|
# build kwargs for call
|
||||||
kwargs = {
|
kwargs = {
|
||||||
'url': f'{self.api_url}/{endpoint}',
|
'url': url,
|
||||||
'headers': headers,
|
'headers': headers,
|
||||||
}
|
}
|
||||||
if data:
|
if data:
|
||||||
|
@ -691,8 +691,24 @@ function loadBomTable(table, options={}) {
|
|||||||
|
|
||||||
setupFilterList('bom', $(table));
|
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 = [];
|
var cols = [];
|
||||||
|
|
||||||
if (options.editable) {
|
if (options.editable) {
|
||||||
@ -807,11 +823,10 @@ function loadBomTable(table, options={}) {
|
|||||||
var url = `/part/${row.sub_part_detail.pk}/?display=part-stock`;
|
var url = `/part/${row.sub_part_detail.pk}/?display=part-stock`;
|
||||||
|
|
||||||
// Calculate total "available" (unallocated) quantity
|
// Calculate total "available" (unallocated) quantity
|
||||||
var base_stock = row.available_stock;
|
|
||||||
var substitute_stock = row.available_substitute_stock || 0;
|
var substitute_stock = row.available_substitute_stock || 0;
|
||||||
var variant_stock = row.allow_variants ? (row.available_variant_stock || 0) : 0;
|
var variant_stock = row.allow_variants ? (row.available_variant_stock || 0) : 0;
|
||||||
|
|
||||||
var available_stock = base_stock + substitute_stock + variant_stock;
|
var available_stock = availableQuantity(row);
|
||||||
|
|
||||||
var text = `${available_stock}`;
|
var text = `${available_stock}`;
|
||||||
|
|
||||||
@ -923,7 +938,7 @@ function loadBomTable(table, options={}) {
|
|||||||
formatter: function(value, row) {
|
formatter: function(value, row) {
|
||||||
var can_build = 0;
|
var can_build = 0;
|
||||||
|
|
||||||
var available = row.available_stock + (row.available_substitute_stock || 0) + (row.available_variant_stock || 0);
|
var available = availableQuantity(row);
|
||||||
|
|
||||||
if (row.quantity > 0) {
|
if (row.quantity > 0) {
|
||||||
can_build = available / row.quantity;
|
can_build = available / row.quantity;
|
||||||
@ -937,11 +952,11 @@ function loadBomTable(table, options={}) {
|
|||||||
var cb_b = 0;
|
var cb_b = 0;
|
||||||
|
|
||||||
if (rowA.quantity > 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) {
|
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;
|
return (cb_a > cb_b) ? 1 : -1;
|
||||||
|
@ -1031,6 +1031,23 @@ function loadBuildOutputAllocationTable(buildInfo, output, options={}) {
|
|||||||
return row.required;
|
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) {
|
function sumAllocations(row) {
|
||||||
// Calculat total allocations for a given row
|
// Calculat total allocations for a given row
|
||||||
if (!row.allocations) {
|
if (!row.allocations) {
|
||||||
@ -1429,16 +1446,27 @@ function loadBuildOutputAllocationTable(buildInfo, output, options={}) {
|
|||||||
var url = `/part/${row.sub_part_detail.pk}/?display=part-stock`;
|
var url = `/part/${row.sub_part_detail.pk}/?display=part-stock`;
|
||||||
|
|
||||||
// Calculate total "available" (unallocated) quantity
|
// Calculate total "available" (unallocated) quantity
|
||||||
var base_stock = row.available_stock;
|
|
||||||
var substitute_stock = row.available_substitute_stock || 0;
|
var substitute_stock = row.available_substitute_stock || 0;
|
||||||
var variant_stock = row.allow_variants ? (row.available_variant_stock || 0) : 0;
|
var variant_stock = row.allow_variants ? (row.available_variant_stock || 0) : 0;
|
||||||
|
|
||||||
var available_stock = base_stock + substitute_stock + variant_stock;
|
var available_stock = availableQuantity(row);
|
||||||
|
|
||||||
var text = `${available_stock}`;
|
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 {
|
||||||
|
text += `<span class='fas fa-check-circle icon-green float-right' title='{% trans "Sufficient stock available" %}'></span>`;
|
||||||
|
}
|
||||||
|
|
||||||
if (available_stock <= 0) {
|
if (available_stock <= 0) {
|
||||||
text = `<span class='badge rounded-pill bg-danger'>{% trans "No Stock Available" %}</span>`;
|
text += `<span class='badge rounded-pill bg-danger'>{% trans "No Stock Available" %}</span>`;
|
||||||
} else {
|
} else {
|
||||||
var extra = '';
|
var extra = '';
|
||||||
if ((substitute_stock > 0) && (variant_stock > 0)) {
|
if ((substitute_stock > 0) && (variant_stock > 0)) {
|
||||||
@ -1455,7 +1483,11 @@ function loadBuildOutputAllocationTable(buildInfo, output, options={}) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return renderLink(text, url);
|
return renderLink(text, url);
|
||||||
}
|
},
|
||||||
|
sorter: function(valA, valB, rowA, rowB) {
|
||||||
|
|
||||||
|
return availableQuantity(rowA) > availableQuantity(rowB) ? 1 : -1;
|
||||||
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
field: 'allocated',
|
field: 'allocated',
|
||||||
|
@ -65,8 +65,8 @@ RUN apk add --no-cache git make bash \
|
|||||||
libjpeg-turbo libjpeg-turbo-dev jpeg jpeg-dev \
|
libjpeg-turbo libjpeg-turbo-dev jpeg jpeg-dev \
|
||||||
libffi libffi-dev \
|
libffi libffi-dev \
|
||||||
zlib zlib-dev \
|
zlib zlib-dev \
|
||||||
# Cairo deps for WeasyPrint (these will be deprecated once WeasyPrint drops cairo requirement)
|
# Special deps for WeasyPrint (these will be deprecated once WeasyPrint drops cairo requirement)
|
||||||
cairo cairo-dev pango pango-dev \
|
cairo cairo-dev pango pango-dev gdk-pixbuf \
|
||||||
# Fonts
|
# Fonts
|
||||||
fontconfig ttf-droid ttf-liberation ttf-dejavu ttf-opensans ttf-ubuntu-font-family font-croscore font-noto \
|
fontconfig ttf-droid ttf-liberation ttf-dejavu ttf-opensans ttf-ubuntu-font-family font-croscore font-noto \
|
||||||
# Core python
|
# Core python
|
||||||
|
Loading…
x
Reference in New Issue
Block a user