Distinguish expiry/best before dates (closes #851)

This commit is contained in:
Bernd Bestel
2020-11-15 19:53:44 +01:00
parent 1d50d5dd22
commit b393998601
39 changed files with 348 additions and 192 deletions

View File

@@ -460,7 +460,8 @@ canvas.drawingBuffer {
.warning-message,
.error-message,
.normal-message {
.normal-message,
.secondary-message {
padding: 12px;
font-weight: bold;
width: fit-content;
@@ -485,6 +486,12 @@ canvas.drawingBuffer {
border-top-color: #4c63b6;
}
.secondary-message {
background-color: #e1e4e8;
color: #4e575f;
border-top-color: #68696b;
}
.status-filter-message,
.user-filter-message {
display: inline-block;

View File

@@ -219,7 +219,7 @@ $("#location_id").on('change', function(e)
$("#specific_stock_entry").append($("<option>", {
value: stockEntry.stock_id,
amount: stockEntry.amount,
text: __t("Amount: %1$s; Expires on %2$s; Bought on %3$s", stockEntry.amount, moment(stockEntry.best_before_date).format("YYYY-MM-DD"), moment(stockEntry.purchased_date).format("YYYY-MM-DD")) + "; " + openTxt
text: __t("Amount: %1$s; Due on %2$s; Bought on %3$s", stockEntry.amount, moment(stockEntry.best_before_date).format("YYYY-MM-DD"), moment(stockEntry.purchased_date).format("YYYY-MM-DD")) + "; " + openTxt
}));
sumValue = sumValue + parseFloat(stockEntry.amount);

View File

@@ -99,11 +99,11 @@ $('#save-purchase-button').on('click', function(e)
toastr.success(successMessage);
Grocy.Components.ProductPicker.FinishFlow();
if (Grocy.FeatureFlags.GROCY_FEATURE_FLAG_STOCK_BEST_BEFORE_DATE_TRACKING && BoolVal(Grocy.UserSettings.show_warning_on_purchase_when_best_before_date_is_earlier_than_next))
if (Grocy.FeatureFlags.GROCY_FEATURE_FLAG_STOCK_BEST_BEFORE_DATE_TRACKING && BoolVal(Grocy.UserSettings.show_warning_on_purchase_when_due_date_is_earlier_than_next))
{
if (moment(jsonData.best_before_date).isBefore(CurrentProductDetails.next_best_before_date))
if (moment(jsonData.best_before_date).isBefore(CurrentProductDetails.next_due_date))
{
toastr.warning(__t("There are items in stock which expire earlier"));
toastr.warning(__t("There are items in stock which are due earlier"));
}
}

View File

@@ -174,9 +174,9 @@ $(document).on('click', '#add-products-below-min-stock-amount', function(e)
);
});
$(document).on('click', '#add-expired-products', function(e)
$(document).on('click', '#add-overdue-products', function(e)
{
Grocy.Api.Post('stock/shoppinglist/add-expired-products', { "list_id": $("#selected-shopping-list").val() },
Grocy.Api.Post('stock/shoppinglist/add-overdue-products', { "list_id": $("#selected-shopping-list").val() },
function(result)
{
window.location.href = U('/shoppinglist?list=' + $("#selected-shopping-list").val());

View File

@@ -148,7 +148,7 @@ function RefreshStockEntryRow(stockRowId)
}
else
{
var expiringThreshold = moment().add(Grocy.UserSettings.stock_expiring_soon_days, "days");
var dueThreshold = moment().add(Grocy.UserSettings.stock_due_soon_days, "days");
var now = moment();
var bestBeforeDate = moment(result.best_before_date);
@@ -159,9 +159,16 @@ function RefreshStockEntryRow(stockRowId)
stockRow.removeAttr("style");
if (now.isAfter(bestBeforeDate))
{
stockRow.addClass("table-danger");
if (stockRow.attr("data-due-type") == 1)
{
stockRow.addClass("table-secondary");
}
else
{
stockRow.addClass("table-danger");
}
}
else if (bestBeforeDate.isBefore(expiringThreshold))
else if (bestBeforeDate.isBefore(dueThreshold))
{
stockRow.addClass("table-warning");
}
@@ -169,8 +176,8 @@ function RefreshStockEntryRow(stockRowId)
animateCSS("#stock-" + stockRowId + "-row td:not(:first)", "shake");
$('#stock-' + stockRowId + '-amount').text(result.amount);
$('#stock-' + stockRowId + '-best-before-date').text(result.best_before_date);
$('#stock-' + stockRowId + '-best-before-date-timeago').attr('datetime', result.best_before_date + ' 23:59:59');
$('#stock-' + stockRowId + '-due-date').text(result.best_before_date);
$('#stock-' + stockRowId + '-due-date-timeago').attr('datetime', result.best_before_date + ' 23:59:59');
$(".stock-consume-button").attr('data-location-id', result.location_id);

View File

@@ -233,12 +233,13 @@ function RefreshStatistics()
}
);
var nextXDays = $("#info-expiring-products").data("next-x-days");
Grocy.Api.Get('stock/volatile?expiring_days=' + nextXDays,
var nextXDays = $("#info-duesoon-products").data("next-x-days");
Grocy.Api.Get('stock/volatile?due_soon_days=' + nextXDays,
function(result)
{
$("#info-expiring-products").html('<span class="d-block d-md-none">' + result.expiring_products.length + ' <i class="fas fa-clock"></i></span><span class="d-none d-md-block">' + __n(result.expiring_products.length, '%s product expires', '%s products expiring') + ' ' + __n(nextXDays, 'within the next day', 'within the next %s days') + '</span>');
$("#info-expired-products").html('<span class="d-block d-md-none">' + result.expired_products.length + ' <i class="fas fa-times-circle"></i></span><span class="d-none d-md-block">' + __n(result.expired_products.length, '%s product is already expired', '%s products are already expired') + '</span>');
$("#info-duesoon-products").html('<span class="d-block d-md-none">' + result.due_products.length + ' <i class="fas fa-clock"></i></span><span class="d-none d-md-block">' + __n(result.due_products.length, '%s product is due', '%s products are due') + ' ' + __n(nextXDays, 'within the next day', 'within the next %s days') + '</span>');
$("#info-overdue-products").html('<span class="d-block d-md-none">' + result.overdue_products.length + ' <i class="fas fa-times-circle"></i></span><span class="d-none d-md-block">' + __n(result.overdue_products.length, '%s product is overdue', '%s products are overdue') + '</span>');
$("#info-expired-products").html('<span class="d-block d-md-none">' + result.expired_products.length + ' <i class="fas fa-times-circle"></i></span><span class="d-none d-md-block">' + __n(result.expired_products.length, '%s product is expired', '%s products are expired') + '</span>');
$("#info-missing-products").html('<span class="d-block d-md-none">' + result.missing_products.length + ' <i class="fas fa-exclamation-circle"></i></span><span class="d-none d-md-block">' + __n(result.missing_products.length, '%s product is below defined min. stock amount', '%s products are below defined min. stock amount') + '</span>');
},
function(xhr)
@@ -263,20 +264,28 @@ function RefreshProductRow(productId)
}
var productRow = $('#product-' + productId + '-row');
var expiringThreshold = moment().add($("#info-expiring-products").data("next-x-days"), "days");
var dueSoonThreshold = moment().add($("#info-duesoon-products").data("next-x-days"), "days");
var now = moment();
var nextBestBeforeDate = moment(result.next_best_before_date);
var nextDueDate = moment(result.next_due_date);
productRow.removeClass("table-warning");
productRow.removeClass("table-danger");
productRow.removeClass("table-secondary");
productRow.removeClass("table-info");
productRow.removeClass("d-none");
productRow.removeAttr("style");
if (now.isAfter(nextBestBeforeDate))
if (now.isAfter(nextDueDate))
{
productRow.addClass("table-danger");
if (result.product.due_type == 1)
{
productRow.addClass("table-secondary");
}
else
{
productRow.addClass("table-danger");
}
}
else if (nextBestBeforeDate.isBefore(expiringThreshold))
else if (nextDueDate.isBefore(dueSoonThreshold))
{
productRow.addClass("table-warning");
}
@@ -297,8 +306,8 @@ function RefreshProductRow(productId)
$('#product-' + productId + '-amount').text(result.stock_amount);
$('#product-' + productId + '-consume-all-button').attr('data-consume-amount', result.stock_amount);
$('#product-' + productId + '-value').text(result.stock_value);
$('#product-' + productId + '-next-best-before-date').text(result.next_best_before_date);
$('#product-' + productId + '-next-best-before-date-timeago').attr('datetime', result.next_best_before_date);
$('#product-' + productId + '-next-due-date').text(result.next_due_date);
$('#product-' + productId + '-next-due-date-timeago').attr('datetime', result.next_due_date);
var openedAmount = result.stock_amount_opened || 0;
if (openedAmount > 0)
@@ -316,8 +325,8 @@ function RefreshProductRow(productId)
}
}
$('#product-' + productId + '-next-best-before-date').text(result.next_best_before_date);
$('#product-' + productId + '-next-best-before-date-timeago').attr('datetime', result.next_best_before_date + ' 23:59:59');
$('#product-' + productId + '-next-due-date').text(result.next_due_date);
$('#product-' + productId + '-next-due-date-timeago').attr('datetime', result.next_due_date + ' 23:59:59');
if (result.stock_amount_opened > 0)
{

View File

@@ -1,7 +1,7 @@
$("#product_presets_location_id").val(Grocy.UserSettings.product_presets_location_id);
$("#product_presets_product_group_id").val(Grocy.UserSettings.product_presets_product_group_id);
$("#product_presets_qu_id").val(Grocy.UserSettings.product_presets_qu_id);
$("#stock_expiring_soon_days").val(Grocy.UserSettings.stock_expiring_soon_days);
$("#stock_due_soon_days").val(Grocy.UserSettings.stock_due_soon_days);
$("#stock_default_purchase_amount").val(Grocy.UserSettings.stock_default_purchase_amount);
$("#stock_default_consume_amount").val(Grocy.UserSettings.stock_default_consume_amount);
$("#stock_decimal_places_amounts").val(Grocy.UserSettings.stock_decimal_places_amounts);
@@ -16,9 +16,9 @@ if (BoolVal(Grocy.UserSettings.show_purchased_date_on_purchase))
$("#show_purchased_date_on_purchase").prop("checked", true);
}
if (BoolVal(Grocy.UserSettings.show_warning_on_purchase_when_best_before_date_is_earlier_than_next))
if (BoolVal(Grocy.UserSettings.show_warning_on_purchase_when_due_date_is_earlier_than_next))
{
$("#show_warning_on_purchase_when_best_before_date_is_earlier_than_next").prop("checked", true);
$("#show_warning_on_purchase_when_due_date_is_earlier_than_next").prop("checked", true);
}
RefreshLocaleNumberInput();

View File

@@ -278,7 +278,7 @@ $("#location_id_from").on('change', function(e)
$("#specific_stock_entry").append($("<option>", {
value: stockEntry.stock_id,
amount: stockEntry.amount,
text: __t("Amount: %1$s; Expires on %2$s; Bought on %3$s", stockEntry.amount, moment(stockEntry.best_before_date).format("YYYY-MM-DD"), moment(stockEntry.purchased_date).format("YYYY-MM-DD")) + "; " + openTxt
text: __t("Amount: %1$s; Due on %2$s; Bought on %3$s", stockEntry.amount, moment(stockEntry.best_before_date).format("YYYY-MM-DD"), moment(stockEntry.purchased_date).format("YYYY-MM-DD")) + "; " + openTxt
}));
if (stockEntry.stock_id == stockId)
{