2
0
mirror of https://github.com/inventree/InvenTree.git synced 2025-06-18 13:05:42 +00:00

Merge branch 'inventree:master' into matmair/issue2279

This commit is contained in:
Matthias Mair
2022-03-14 23:14:29 +01:00
committed by GitHub
51 changed files with 19267 additions and 31473 deletions

View File

@ -18,6 +18,7 @@
{% include "InvenTree/settings/setting.html" with key="DATE_DISPLAY_FORMAT" icon="fa-calendar-alt" user_setting=True %}
{% include "InvenTree/settings/setting.html" with key="FORMS_CLOSE_USING_ESCAPE" icon="fa-window-close" user_setting=True %}
{% include "InvenTree/settings/setting.html" with key="PART_SHOW_QUANTITY_IN_FORMS" icon="fa-hashtag" user_setting=True %}
{% include "InvenTree/settings/setting.html" with key="DISPLAY_SCHEDULE_TAB" icon="fa-calendar-alt" user_setting=True %}
</tbody>
</table>
</div>

View File

@ -154,8 +154,10 @@
<script type="text/javascript" src="{% static 'fullcalendar/main.js' %}"></script>
<script type="text/javascript" src="{% static 'fullcalendar/locales-all.js' %}"></script>
<script type="text/javascript" src="{% static 'select2/js/select2.full.js' %}"></script>
<script type='text/javascript' src="{% static 'script/chart.js' %}"></script>
<script type='text/javascript' src="{% static 'script/moment.js' %}"></script>
<script type='text/javascript' src="{% static 'script/chart.min.js' %}"></script>
<script type='text/javascript' src="{% static 'script/chartjs-adapter-moment.js' %}"></script>
<script type='text/javascript' src="{% static 'script/clipboard.min.js' %}"></script>
<script type='text/javascript' src="{% static 'script/randomColor.min.js' %}"></script>

View File

@ -1219,6 +1219,18 @@ function loadBuildOutputAllocationTable(buildInfo, output, options={}) {
$(table).bootstrapTable('updateByUniqueId', key, tableRow, true);
}
// Update any rows which we did not receive allocation information for
var td = $(table).bootstrapTable('getData');
td.forEach(function(tableRow) {
if (tableRow.allocations == null) {
tableRow.allocations = [];
$(table).bootstrapTable('updateByUniqueId', tableRow.pk, tableRow, true);
}
});
// Update the progress bar for this build output
var build_progress = $(`#output-progress-${outputId}`);
@ -1419,15 +1431,17 @@ function loadBuildOutputAllocationTable(buildInfo, output, options={}) {
formatter: function(value, row) {
var allocated = 0;
if (row.allocations) {
if (row.allocations != null) {
row.allocations.forEach(function(item) {
allocated += item.quantity;
});
var required = requiredQuantity(row);
return makeProgressBar(allocated, required);
} else {
return `<em>{% trans "loading" %}...</em><span class='fas fa-spinner fa-spin float-right'></span>`;
}
var required = requiredQuantity(row);
return makeProgressBar(allocated, required);
},
sorter: function(valA, valB, rowA, rowB) {
// Custom sorting function for progress bars
@ -1876,6 +1890,7 @@ function autoAllocateStockToBuild(build_id, bom_items=[], options={}) {
location: {
value: options.location,
},
exclude_location: {},
interchangeable: {
value: true,
},

View File

@ -33,6 +33,7 @@
loadPartPurchaseOrderTable,
loadPartTable,
loadPartTestTemplateTable,
loadPartSchedulingChart,
loadPartVariantTable,
loadRelatedPartsTable,
loadSellPricingChart,
@ -1981,6 +1982,123 @@ function initPriceBreakSet(table, options) {
}
function loadPartSchedulingChart(canvas_id, part_id) {
var part_info = null;
// First, grab updated data for the particular part
inventreeGet(`/api/part/${part_id}/`, {}, {
async: false,
success: function(response) {
part_info = response;
}
});
var today = moment();
// Create an initial entry, using the available quantity
var stock_schedule = [
{
date: today,
delta: 0,
label: '{% trans "Current Stock" %}',
}
];
/* Request scheduling information for the part.
* Note that this information has already been 'curated' by the server,
* and arranged in increasing chronological order
*/
inventreeGet(
`/api/part/${part_id}/scheduling/`,
{},
{
async: false,
success: function(response) {
response.forEach(function(entry) {
stock_schedule.push({
date: moment(entry.date),
delta: entry.quantity,
title: entry.title,
label: entry.label,
url: entry.url,
});
});
}
}
);
// Iterate through future "events" to calculate expected quantity
var quantity = part_info.in_stock;
for (var idx = 0; idx < stock_schedule.length; idx++) {
quantity += stock_schedule[idx].delta;
stock_schedule[idx].x = stock_schedule[idx].date.format('YYYY-MM-DD');
stock_schedule[idx].y = quantity;
}
var context = document.getElementById(canvas_id);
const data = {
datasets: [{
label: '{% trans "Scheduled Stock Quantities" %}',
data: stock_schedule,
backgroundColor: 'rgb(220, 160, 80)',
borderWidth: 2,
borderColor: 'rgb(90, 130, 150)'
}],
};
return new Chart(context, {
type: 'scatter',
data: data,
options: {
showLine: true,
stepped: true,
scales: {
x: {
type: 'time',
min: today.format(),
position: 'bottom',
time: {
unit: 'day',
},
},
y: {
beginAtZero: true,
}
},
plugins: {
tooltip: {
callbacks: {
label: function(item) {
return item.raw.label;
},
beforeLabel: function(item) {
return item.raw.title;
},
afterLabel: function(item) {
var delta = item.raw.delta;
if (delta == 0) {
delta = '';
} else {
delta = ` (${item.raw.delta > 0 ? '+' : ''}${item.raw.delta})`;
}
return `{% trans "Quantity" %}: ${item.raw.y}${delta}`;
}
}
}
},
}
});
}
function loadStockPricingChart(context, data) {
return new Chart(context, {
type: 'bar',

View File

@ -294,7 +294,17 @@ function stockItemGroups(options={}) {
*/
function duplicateStockItem(pk, options) {
// First, we need the StockItem informatino
// If no "success" function provided, add a default
if (!options.onSuccess) {
options.onSuccess = function(response) {
showAlertOrCache('{% trans "Stock item duplicated" %}', true, {style: 'success'});
window.location.href = `/stock/item/${response.pk}/`;
};
}
// First, we need the StockItem information
inventreeGet(`/api/stock/${pk}/`, {}, {
success: function(data) {