Squashed commit

Fixed number input min/max amount handling
Only (auto) save valid user inputs
More filters on the stock journal pages
Save the last price per used barcode and preselect that as a total price on purchase if not empty (closes #1131)
Don't apply conversions for only_check_single_unit_in_stock ingredients (fixes #1120)
Render shopping list userfields (closes #1052)
Fixed Focus when adding included recipes (closes #1019)
Order all base objects with NOCASE (closes #1086)
This commit is contained in:
Bernd Bestel
2020-11-17 19:11:02 +01:00
parent 1316c1f25f
commit 887526c727
40 changed files with 556 additions and 178 deletions

View File

@@ -133,7 +133,7 @@ $('.input-group-chore-period-type').on('change', function(e)
{
$("label[for='period_days']").text(__t("Period days"));
$("#period_days").attr("min", "0");
$("#period_days").attr("max", "999999");
$("#period_days").removeAttr("max");
$('#chore-period-type-info').attr("data-original-title", __t('This means the next execution of this chore is scheduled %s days after the last execution', periodDays.toString()));
}
else if (periodType === 'daily')

View File

@@ -32,30 +32,38 @@ $(".numberpicker").each(function()
{
mutations.forEach(function(mutation)
{
if (mutation.type == "attributes" && (mutation.attributeName == "min" || mutation.attributeName == "max" || mutation.attributeName == "data-not-equal"))
if (mutation.type == "attributes" && (mutation.attributeName == "min" || mutation.attributeName == "max" || mutation.attributeName == "data-not-equal" || mutation.attributeName == "data-initialised"))
{
var element = $(mutation.target);
var min = element.attr("min");
var max = element.attr("max");
var decimals = element.attr("data-decimals");
var max = "";
if (element.hasAttr("max"))
{
max = element.attr("max");
}
if (element.hasAttr("data-not-equal"))
{
var notEqual = element.attr("data-not-equal");
if (max.isEmpty() || max.startsWith("999999"))
if (notEqual != "NaN")
{
element.parent().find(".invalid-feedback").text(__t("This cannot be lower than %1$s or equal %2$s and needs to be a valid number with max. %3$s decimal places", parseFloat(min).toLocaleString(undefined, { minimumFractionDigits: 0, maximumFractionDigits: decimals }), parseFloat(notEqual).toLocaleString(undefined, { minimumFractionDigits: 0, maximumFractionDigits: decimals }), decimals));
}
else
{
element.parent().find(".invalid-feedback").text(__t("This must be between %1$s and %2$s, cannot equal %3$s and needs to be a valid number with max. %4$s decimal places", parseFloat(min).toLocaleString(undefined, { minimumFractionDigits: 0, maximumFractionDigits: decimals }), parseFloat(max).toLocaleString(undefined, { minimumFractionDigits: 0, maximumFractionDigits: decimals }), parseFloat(notEqual).toLocaleString(undefined, { minimumFractionDigits: decimals, maximumFractionDigits: decimals }), decimals));
}
if (max.isEmpty())
{
element.parent().find(".invalid-feedback").text(__t("This cannot be lower than %1$s or equal %2$s and needs to be a valid number with max. %3$s decimal places", parseFloat(min).toLocaleString(undefined, { minimumFractionDigits: 0, maximumFractionDigits: decimals }), parseFloat(notEqual).toLocaleString(undefined, { minimumFractionDigits: 0, maximumFractionDigits: decimals }), decimals));
}
else
{
element.parent().find(".invalid-feedback").text(__t("This must be between %1$s and %2$s, cannot equal %3$s and needs to be a valid number with max. %4$s decimal places", parseFloat(min).toLocaleString(undefined, { minimumFractionDigits: 0, maximumFractionDigits: decimals }), parseFloat(max).toLocaleString(undefined, { minimumFractionDigits: 0, maximumFractionDigits: decimals }), parseFloat(notEqual).toLocaleString(undefined, { minimumFractionDigits: decimals, maximumFractionDigits: decimals }), decimals));
}
return;
return;
}
}
if (max.isEmpty() || max.startsWith("999999"))
if (max.isEmpty())
{
element.parent().find(".invalid-feedback").text(__t("This cannot be lower than %1$s and needs to be a valid number with max. %2$s decimal places", parseFloat(min).toLocaleString(undefined, { minimumFractionDigits: 0, maximumFractionDigits: decimals }), decimals));
}
@@ -69,4 +77,4 @@ $(".numberpicker").each(function()
attributes: true
});
});
$(".numberpicker").attr("min", $(".numberpicker").attr("min")); // Dummy change to trigger MutationObserver above once
$(".numberpicker").attr("data-initialised", "true"); // Dummy change to trigger MutationObserver above once

View File

@@ -93,7 +93,7 @@
Grocy.Components.ProductAmountPicker.Reset();
$("#display_amount").attr("min", "0." + "0".repeat(parseInt(Grocy.UserSettings.stock_decimal_places_amounts) - 1) + "1");
$("#display_amount").attr("max", "999999");
$("#display_amount").removeAttr("max");
$('#display_amount').val(parseFloat(Grocy.UserSettings.stock_default_consume_amount));
RefreshLocaleNumberInput();
$(".input-group-productamountpicker").trigger("change");
@@ -272,6 +272,8 @@ Grocy.Components.ProductPicker.GetPicker().on('change', function(e)
Grocy.Api.Get('stock/products/' + productId,
function(productDetails)
{
current_productDetails = productDetails;
Grocy.Components.ProductAmountPicker.Reload(productDetails.product.id, productDetails.quantity_unit_stock.id);
Grocy.Components.ProductAmountPicker.SetQuantityUnit(productDetails.quantity_unit_stock.id);
$('#display_amount').val(parseFloat(Grocy.UserSettings.stock_default_consume_amount));
@@ -473,6 +475,11 @@ $("#use_specific_stock_entry").on("change", function()
Grocy.FrontendHelpers.ValidateForm("consume-form");
});
$("#qu_id").on("change", function()
{
RefreshForm();
});
function UndoStockBooking(bookingId)
{
Grocy.Api.Post('stock/bookings/' + bookingId.toString() + '/undo', {},
@@ -570,7 +577,7 @@ function RefreshForm()
$("#tare-weight-handling-info").addClass("d-none");
$("#display_amount").attr("min", "0." + "0".repeat(parseInt(Grocy.UserSettings.stock_decimal_places_amounts) - 1) + "1");
$('#display_amount').attr('max', sumValue);
$('#display_amount').attr('max', sumValue * $("#qu_id option:selected").attr("data-qu-factor"));
if (sumValue == 0)
{

View File

@@ -84,6 +84,7 @@
$("#tare-weight-handling-info").addClass("d-none");
$("#display_amount").attr("min", "0");
$('#display_amount').val('');
$('#display_amount').removeAttr("data-not-equal");
$(".input-group-productamountpicker").trigger("change");
$('#price').val('');
Grocy.Components.DateTimePicker.Clear();

View File

@@ -13,6 +13,11 @@
Grocy.Api.Post('objects/product_barcodes', jsonData,
function(result)
{
Grocy.EditObjectId = result.created_object_id;
Grocy.Components.UserfieldsForm.Save()
window.parent.postMessage(WindowMessageBag("ProductBarcodesChanged"), U("/product/" + GetUriParam("product")));
window.parent.postMessage(WindowMessageBag("CloseAllModals"), U("/product/" + GetUriParam("product")));
},
function(xhr)
{
@@ -23,9 +28,12 @@
}
else
{
Grocy.Components.UserfieldsForm.Save();
Grocy.Api.Put('objects/product_barcodes/' + Grocy.EditObjectId, jsonData,
function(result)
{
window.parent.postMessage(WindowMessageBag("ProductBarcodesChanged"), U("/product/" + GetUriParam("product")));
window.parent.postMessage(WindowMessageBag("CloseAllModals"), U("/product/" + GetUriParam("product")));
},
function(xhr)
{
@@ -34,9 +42,6 @@
}
);
}
window.parent.postMessage(WindowMessageBag("ProductBarcodesChanged"), U("/product/" + GetUriParam("product")));
window.parent.postMessage(WindowMessageBag("CloseAllModals"), U("/product/" + GetUriParam("product")));
});
$('#barcode').on('keyup', function(e)
@@ -82,3 +87,4 @@ if (Grocy.EditMode == "edit")
Grocy.FrontendHelpers.ValidateForm('barcode-form');
$('#barcode').focus();
RefreshLocaleNumberInput();
Grocy.Components.UserfieldsForm.Load()

View File

@@ -296,7 +296,7 @@ var quConversionsTable = $('#qu-conversions-table-products').DataTable({
dataSrc: 4
}
});
$('#qu-conversions-table tbody').removeClass("d-none");
$('#qu-conversions-table-products tbody').removeClass("d-none");
quConversionsTable.columns.adjust().draw();
var barcodeTable = $('#barcode-table').DataTable({

View File

@@ -55,6 +55,16 @@ $('#save-purchase-button').on('click', function(e)
Grocy.Api.Post('stock/products/' + jsonForm.product_id + '/add', jsonData,
function(result)
{
if ($("#purchase-form").hasAttr("data-used-barcode"))
{
Grocy.Api.Put('objects/product_barcodes/' + $("#purchase-form").attr("data-used-barcode"), { last_price: $("#price").val() / $("#display_amount").val() },
function(result)
{ },
function(xhr)
{ }
);
}
if (BoolVal(Grocy.UserSettings.scan_mode_purchase_enabled))
{
Grocy.UISound.Success();
@@ -108,6 +118,7 @@ $('#save-purchase-button').on('click', function(e)
}
Grocy.Components.ProductAmountPicker.Reset();
$("#purchase-form").removeAttr("data-used-barcode");
$("#display_amount").attr("min", "0." + "0".repeat(parseInt(Grocy.UserSettings.stock_decimal_places_amounts) - 1) + "1");
$('#display_amount').val(parseFloat(Grocy.UserSettings.stock_default_purchase_amount));
$(".input-group-productamountpicker").trigger("change");
@@ -202,7 +213,7 @@ if (Grocy.Components.ProductPicker !== undefined)
Grocy.Components.LocationPicker.SetId(productDetails.location.id);
}
if (productDetails.last_price == null)
if (productDetails.last_price == null || productDetails.last_price == 0)
{
$("#price").val("")
}
@@ -282,10 +293,11 @@ if (Grocy.Components.ProductPicker !== undefined)
if (barcodeResult != null)
{
var barcode = barcodeResult[0];
$("#purchase-form").attr("data-used-barcode", barcode.id);
if (barcode != null)
{
if (barcode.amount != null)
if (barcode.amount != null && !barcode.amount.isEmpty())
{
$("#display_amount").val(barcode.amount);
$("#display_amount").select();
@@ -301,6 +313,12 @@ if (Grocy.Components.ProductPicker !== undefined)
Grocy.Components.ShoppingLocationPicker.SetId(barcode.shopping_location_id);
}
if (barcode.last_price != null && !barcode.last_price.isEmpty())
{
$("#price").val(barcode.last_price);
$("#price-type-total-price").click();
}
$(".input-group-productamountpicker").trigger("change");
Grocy.FrontendHelpers.ValidateForm('purchase-form');
}
@@ -312,6 +330,10 @@ if (Grocy.Components.ProductPicker !== undefined)
}
);
}
else
{
$("#purchase-form").removeAttr("data-used-barcode");
}
$('#display_amount').trigger("keyup");
},
@@ -450,7 +472,7 @@ function refreshPriceHint()
price = parseFloat(price / $('#display_amount').val()).toFixed(Grocy.UserSettings.stock_decimal_places_prices);
}
$('#price-hint').text(__t('means %1$s per %2$s', price.toLocaleString(undefined, { style: "currency", currency: Grocy.Currency, minimumFractionDigits: 2, maximumFractionDigits: Grocy.UserSettings.stock_decimal_places_prices }), $("#qu_id").attr("data-destination-qu-name")));
$('#price-hint').text(__t('means %1$s per %2$s', price.toLocaleString(undefined, { style: "currency", currency: Grocy.Currency, minimumFractionDigits: Grocy.UserSettings.stock_decimal_places_prices, maximumFractionDigits: Grocy.UserSettings.stock_decimal_places_prices }), $("#qu_id").attr("data-destination-qu-name")));
}
else
{

View File

@@ -285,6 +285,7 @@ $("#recipe-include-add-button").on("click", function(e)
$("#recipe-include-editform-title").text(__t("Add included recipe"));
$("#recipe-include-form").data("edit-mode", "create");
Grocy.Components.RecipePicker.Clear();
Grocy.Components.RecipePicker.GetInputElement().focus();
$("#recipe-include-editform-modal").modal("show");
Grocy.FrontendHelpers.ValidateForm("recipe-include-form");
},

View File

@@ -10,9 +10,13 @@
Grocy.Api.Post('objects/shopping_lists', jsonData,
function(result)
{
window.parent.postMessage(WindowMessageBag("ShoppingListChanged", result.created_object_id), Grocy.BaseUrl);
window.parent.postMessage(WindowMessageBag("Ready"), Grocy.BaseUrl);
window.parent.postMessage(WindowMessageBag("CloseAllModals"), Grocy.BaseUrl);
Grocy.EditObjectId = result.created_object_id;
Grocy.Components.UserfieldsForm.Save(function()
{
window.parent.postMessage(WindowMessageBag("ShoppingListChanged", result.created_object_id), Grocy.BaseUrl);
window.parent.postMessage(WindowMessageBag("Ready"), Grocy.BaseUrl);
window.parent.postMessage(WindowMessageBag("CloseAllModals"), Grocy.BaseUrl);
});
},
function(xhr)
{
@@ -23,19 +27,22 @@
}
else
{
Grocy.Api.Put('objects/shopping_lists/' + Grocy.EditObjectId, jsonData,
function(result)
{
window.parent.postMessage(WindowMessageBag("ShoppingListChanged", Grocy.EditObjectId), Grocy.BaseUrl);
window.parent.postMessage(WindowMessageBag("Ready"), Grocy.BaseUrl);
window.parent.postMessage(WindowMessageBag("CloseAllModals"), Grocy.BaseUrl);
},
function(xhr)
{
Grocy.FrontendHelpers.EndUiBusy("shopping-list-form");
Grocy.FrontendHelpers.ShowGenericError('Error while saving, probably this item already exists', xhr.response);
}
);
Grocy.Components.UserfieldsForm.Save(function()
{
Grocy.Api.Put('objects/shopping_lists/' + Grocy.EditObjectId, jsonData,
function(result)
{
window.parent.postMessage(WindowMessageBag("ShoppingListChanged", Grocy.EditObjectId), Grocy.BaseUrl);
window.parent.postMessage(WindowMessageBag("Ready"), Grocy.BaseUrl);
window.parent.postMessage(WindowMessageBag("CloseAllModals"), Grocy.BaseUrl);
},
function(xhr)
{
Grocy.FrontendHelpers.EndUiBusy("shopping-list-form");
Grocy.FrontendHelpers.ShowGenericError('Error while saving, probably this item already exists', xhr.response);
}
);
});
}
});
@@ -61,5 +68,6 @@ $('#shopping-list-form input').keydown(function(event)
}
});
Grocy.Components.UserfieldsForm.Load();
$('#name').focus();
Grocy.FrontendHelpers.ValidateForm('shopping-list-form');

View File

@@ -21,6 +21,9 @@ $('#save-shoppinglist-button').on('click', function(e)
Grocy.Api.Post('stock/shoppinglist/add-product', jsonData,
function(result)
{
Grocy.EditObjectId = result.created_object_id;
Grocy.Components.UserfieldsForm.Save();
if (GetUriParam("embedded") !== undefined)
{
Grocy.Api.Get('stock/products/' + jsonData.product_id,
@@ -54,6 +57,9 @@ $('#save-shoppinglist-button').on('click', function(e)
Grocy.Api.Post('objects/shopping_list', jsonData,
function(result)
{
Grocy.EditObjectId = result.created_object_id;
Grocy.Components.UserfieldsForm.Save();
if (GetUriParam("embedded") !== undefined)
{
if (jsonData.product_id)
@@ -94,6 +100,8 @@ $('#save-shoppinglist-button').on('click', function(e)
Grocy.Api.Put('objects/shopping_list/' + Grocy.EditObjectId, jsonData,
function(result)
{
Grocy.Components.UserfieldsForm.Save();
if (GetUriParam("embedded") !== undefined)
{
if (jsonData.product_id)
@@ -216,3 +224,5 @@ if (GetUriParam("amount") !== undefined)
$(".input-group-productamountpicker").trigger("change");
Grocy.FrontendHelpers.ValidateForm('shoppinglist-form');
}
Grocy.Components.UserfieldsForm.Load();

View File

@@ -23,6 +23,42 @@ $("#product-filter").on("change", function()
stockJournalTable.column(1).search(text).draw();
});
$("#transaction-type-filter").on("change", function()
{
var value = $(this).val();
var text = $("#transaction-type-filter option:selected").text();
if (value === "all")
{
text = "";
}
stockJournalTable.column(4).search(text).draw();
});
$("#location-filter").on("change", function()
{
var value = $(this).val();
var text = $("#location-filter option:selected").text();
if (value === "all")
{
text = "";
}
stockJournalTable.column(5).search(text).draw();
});
$("#user-filter").on("change", function()
{
var value = $(this).val();
var text = $("#user-filter option:selected").text();
if (value === "all")
{
text = "";
}
stockJournalTable.column(6).search(text).draw();
});
$("#search").on("keyup", Delay(function()
{
var value = $(this).val();
@@ -37,6 +73,12 @@ $("#search").on("keyup", Delay(function()
$("#clear-filter-button").on("click", function()
{
$("#search").val("");
$("#transaction-type-filter").val("all");
$("#location-filter").val("all");
$("#user-filter").val("all");
stockJournalTable.column(4).search("").draw();
stockJournalTable.column(5).search("").draw();
stockJournalTable.column(6).search("").draw();
stockJournalTable.search("").draw();
});

View File

@@ -1,8 +1,71 @@
var journalSummaryTable = $('#journal-summary-table').DataTable({
var journalSummaryTable = $('#stock-journal-summary-table').DataTable({
'paginate': true,
'order': [[0, 'desc']]
'order': [[1, 'asc']],
'columnDefs': [
{ 'orderable': false, 'targets': 0 },
{ 'searchable': false, "targets": 0 }
]
});
$('#journal-summary-table tbody').removeClass("d-none");
$('#stock-journal-summary-table tbody').removeClass("d-none");
journalSummaryTable.columns.adjust().draw();
$('.dataTables_scrollBody').addClass("dragscroll");
dragscroll.reset();
$("#product-filter").on("change", function()
{
var value = $(this).val();
var text = $("#product-filter option:selected").text();
if (value === "all")
{
text = "";
}
journalSummaryTable.column(1).search(text).draw();
});
$("#transaction-type-filter").on("change", function()
{
var value = $(this).val();
var text = $("#transaction-type-filter option:selected").text();
if (value === "all")
{
text = "";
}
journalSummaryTable.column(2).search(text).draw();
});
$("#user-filter").on("change", function()
{
var value = $(this).val();
var text = $("#user-filter option:selected").text();
if (value === "all")
{
text = "";
}
journalSummaryTable.column(3).search(text).draw();
});
$("#search").on("keyup", Delay(function()
{
var value = $(this).val();
if (value === "all")
{
value = "";
}
journalSummaryTable.search(value).draw();
}, 200));
$("#clear-filter-button").on("click", function()
{
$("#search").val("");
$("#transaction-type-filter").val("all");
$("#location-filter").val("all");
$("#user-filter").val("all");
journalSummaryTable.column(1).search("").draw();
journalSummaryTable.column(2).search("").draw();
journalSummaryTable.column(3).search("").draw();
journalSummaryTable.search("").draw();
});

View File

@@ -90,7 +90,7 @@
Grocy.Components.ProductAmountPicker.Reset();
$("#location_id_from").find("option").remove().end().append("<option></option>");
$("#display_amount").attr("min", "0." + "0".repeat(parseInt(Grocy.UserSettings.stock_decimal_places_amounts) - 1) + "1");
$("#display_amount").attr("max", "999999");
$("#display_amount").removeAttr("max");
$('#display_amount').val(parseFloat(Grocy.UserSettings.stock_default_transfer_amount));
RefreshLocaleNumberInput();
$(".input-group-productamountpicker").trigger("change");
@@ -198,6 +198,8 @@ Grocy.Components.ProductPicker.GetPicker().on('change', function(e)
$("#tare-weight-handling-info").addClass("d-none");
}
$('#display_amount').attr("data-stock-amount", productDetails.stock_amount);
if ((parseFloat(productDetails.stock_amount) || 0) === 0)
{
Grocy.Components.ProductPicker.Clear();
@@ -274,7 +276,7 @@ $("#location_id_from").on('change', function(e)
sumValue = sumValue + parseFloat(stockEntry.amount);
}
});
$("#display_amount").attr("max", sumValue);
$("#display_amount").attr("max", sumValue * $("#qu_id option:selected").attr("data-qu-factor"));
if (sumValue == 0)
{
$("#display_amount").parent().find(".invalid-feedback").text(__t('There are no units available at this location'));
@@ -299,6 +301,11 @@ $("#location_id_to").on('change', function(e)
}
});
$("#qu_id").on('change', function(e)
{
$("#display_amount").attr("max", parseFloat($('#display_amount').attr("data-stock-amount")) * $("#qu_id option:selected").attr("data-qu-factor"));
});
$('#display_amount').on('focus', function(e)
{
$(this).select();
@@ -346,7 +353,7 @@ $("#specific_stock_entry").on("change", function(e)
sumValue = sumValue + parseFloat(stockEntry.amount);
}
});
$("#display_amount").attr("max", sumValue);
$("#display_amount").attr("max", sumValue * $("#qu_id option:selected").attr("data-qu-factor"));
if (sumValue == 0)
{
$("#display_amount").parent().find(".invalid-feedback").text(__t('There are no units available at this location'));