Fixed/refined some things regarding purchase/consume/inventory of products with enabled tare weight handling

This commit is contained in:
Bernd Bestel 2019-09-19 21:10:36 +02:00
parent 412653d67d
commit 35a409f462
No known key found for this signature in database
GPG Key ID: 71BD34C0D4891300
4 changed files with 60 additions and 28 deletions

View File

@ -9,7 +9,7 @@
- Please note due to browser security restrictions, this only works when serving grocy via a secure connection (`https://`)
- There is also a `config.php` setting `DISABLE_BROWSER_BARCODE_CAMERA_SCANNING` to disable this, if you don't need it at all (defaults to `false`)
### Stock improvements
### Stock improvements/fixes
- Products can now have variations (nested products)
- Define the parent product for a product on the product edit page (only one level is possible, means a product which is used as a parent product in another product, cannot have a parent product itself)
- Parent and sub products can have stock (both are regular products, no difference from that side)
@ -27,6 +27,7 @@
- `FEATURE_FLAG_STOCK_LOCATION_TRACKING` to disable product location tracking
- `FEATURE_FLAG_STOCK_BEST_BEFORE_DATE_TRACKING` to disable product best before date tracking
- `FEATURE_FLAG_STOCK_PRODUCT_OPENED_TRACKING` to disable product opened tracking
- Fixed/refined some things regarding purchase/consume/inventory of products with enabled tare weight handling (nothing was broken, but the success popups may not displayed the correct amount that was posted)
### Recipe improvements
- Based on the new linked quantity units, recipe ingredients can now use any product related unit, the amount is calculated according to the cnoversion factor of the unit relation

View File

@ -26,12 +26,16 @@
jsonData.recipe_id = Grocy.Components.RecipePicker.GetValue();
}
var bookingResponse = null;
Grocy.Api.Get('stock/products/' + jsonForm.product_id,
function(productDetails)
{
Grocy.Api.Post(apiUrl, jsonData,
function(result)
{
bookingResponse = result;
var addBarcode = GetUriParam('addbarcodetoselection');
if (addBarcode !== undefined)
{
@ -66,7 +70,14 @@
}
Grocy.FrontendHelpers.EndUiBusy("consume-form");
toastr.success(__t('Removed %1$s of %2$s from stock', jsonForm.amount + " " + __n(jsonForm.amount, productDetails.quantity_unit_stock.name, productDetails.quantity_unit_stock.name_plural), productDetails.product.name) + '<br><a class="btn btn-secondary btn-sm mt-2" href="#" onclick="UndoStockBooking(' + result.id + ')"><i class="fas fa-undo"></i> ' + __t("Undo") + '</a>');
if (productDetails.product.enable_tare_weight_handling == 1)
{
toastr.success(__t('Removed %1$s of %2$s from stock', Math.abs(jsonForm.amount - parseFloat(productDetails.product.tare_weight)) + " " + __n(jsonForm.amount, productDetails.quantity_unit_stock.name, productDetails.quantity_unit_stock.name_plural), productDetails.product.name) + '<br><a class="btn btn-secondary btn-sm mt-2" href="#" onclick="UndoStockBooking(' + bookingResponse.id + ')"><i class="fas fa-undo"></i> ' + __t("Undo") + '</a>');
}
else
{
toastr.success(__t('Removed %1$s of %2$s from stock', Math.abs(jsonForm.amount) + " " + __n(jsonForm.amount, productDetails.quantity_unit_stock.name, productDetails.quantity_unit_stock.name_plural), productDetails.product.name) + '<br><a class="btn btn-secondary btn-sm mt-2" href="#" onclick="UndoStockBooking(' + bookingResponse.id + ')"><i class="fas fa-undo"></i> ' + __t("Undo") + '</a>');
}
$("#amount").attr("min", "1");
$("#amount").attr("max", "999999");
@ -242,6 +253,12 @@ Grocy.Components.ProductPicker.GetPicker().on('change', function(e)
for (i = 0; i < stockEntry.amount; i++)
{
// Do this only for the first 50 entries to prevent a very long loop (is more anytime needed)?
if (i > 50)
{
break;
}
$("#specific_stock_entry").append($("<option>", {
value: stockEntry.stock_id,
text: __t("Expires on %1$s; Bought on %2$s", moment(stockEntry.best_before_date).format("YYYY-MM-DD"), moment(stockEntry.purchased_date).format("YYYY-MM-DD")) + "; " + openTxt

View File

@ -27,9 +27,13 @@
}
jsonData.price = price;
var bookingResponse = null;
Grocy.Api.Post('stock/products/' + jsonForm.product_id + '/inventory', jsonData,
function(result)
{
bookingResponse = result;
var addBarcode = GetUriParam('addbarcodetoselection');
if (addBarcode !== undefined)
{
@ -57,21 +61,31 @@
);
}
Grocy.FrontendHelpers.EndUiBusy("inventory-form");
toastr.success(__t('Stock amount of %1$s is now %2$s', productDetails.product.name, jsonForm.new_amount + " " + __n(jsonForm.new_amount, productDetails.quantity_unit_stock.name, productDetails.quantity_unit_stock.name_plural)) + '<br><a class="btn btn-secondary btn-sm mt-2" href="#" onclick="UndoStockBooking(' + result.id + ')"><i class="fas fa-undo"></i> ' + __t("Undo") + '</a>');
Grocy.Api.Get('stock/products/' + jsonForm.product_id,
function(result)
{
Grocy.FrontendHelpers.EndUiBusy("inventory-form");
toastr.success(__t('Stock amount of %1$s is now %2$s', result.product.name, result.stock_amount + " " + __n(result.stock_amount, result.quantity_unit_stock.name, result.quantity_unit_stock.name_plural)) + '<br><a class="btn btn-secondary btn-sm mt-2" href="#" onclick="UndoStockBooking(' + bookingResponse.id + ')"><i class="fas fa-undo"></i> ' + __t("Undo") + '</a>');
$('#inventory-change-info').addClass('d-none');
$("#tare-weight-handling-info").addClass("d-none");
$("#new_amount").attr("min", "0");
$("#new_amount").attr("step", "1");
$("#new_amount").parent().find(".invalid-feedback").text(__t('The amount cannot be lower than %s', '0'));
$('#new_amount').val('');
$('#new_amount_qu_unit').text("");
$('#price').val('');
Grocy.Components.DateTimePicker.Clear();
Grocy.Components.ProductPicker.SetValue('');
Grocy.Components.ProductPicker.GetInputElement().focus();
Grocy.FrontendHelpers.ValidateForm('inventory-form');
$('#inventory-change-info').addClass('d-none');
$("#tare-weight-handling-info").addClass("d-none");
$("#new_amount").attr("min", "0");
$("#new_amount").attr("step", "1");
$("#new_amount").parent().find(".invalid-feedback").text(__t('The amount cannot be lower than %s', '0'));
$('#new_amount').val('');
$('#new_amount_qu_unit').text("");
$('#price').val('');
Grocy.Components.DateTimePicker.Clear();
Grocy.Components.ProductPicker.SetValue('');
Grocy.Components.ProductPicker.GetInputElement().focus();
Grocy.FrontendHelpers.ValidateForm('inventory-form');
},
function(xhr)
{
Grocy.FrontendHelpers.EndUiBusy();
console.error(xhr);
}
);
},
function(xhr)
{
@ -118,7 +132,7 @@ Grocy.Components.ProductPicker.GetPicker().on('change', function(e)
if (productDetails.product.enable_tare_weight_handling == 1)
{
$("#new_amount").attr("min", productDetails.product.tare_weight);
$("#new_amount").parent().find(".invalid-feedback").text(__t('The amount cannot be lower than %1$s or equal %2$s', parseFloat(productDetails.product.tare_weight).toLocaleString({ minimumFractionDigits: 0, maximumFractionDigits: 2 }), productDetails.stock_amount.toLocaleString()));
$("#new_amount").parent().find(".invalid-feedback").text(__t('The amount cannot be lower than %1$s or equal %2$s', parseFloat(productDetails.product.tare_weight).toLocaleString({ minimumFractionDigits: 0, maximumFractionDigits: 2 }), (parseFloat(productDetails.stock_amount) + parseFloat(productDetails.product.tare_weight)).toLocaleString()));
$("#tare-weight-handling-info").removeClass("d-none");
}
else

View File

@ -189,12 +189,12 @@ class StockService extends BaseService
$productDetails = (object)$this->GetProductDetails($productId);
if ($productDetails->product->enable_tare_weight_handling == 1)
{
if ($amount <= $productDetails->product->tare_weight + $productDetails->stock_amount)
if ($amount <= floatval($productDetails->product->tare_weight) + floatval($productDetails->stock_amount))
{
throw new \Exception('The amount cannot be lower or equal than the defined tare weight + current stock amount');
}
$amount = $amount - $productDetails->stock_amount - $productDetails->product->tare_weight;
$amount = $amount - floatval($productDetails->stock_amount) - floatval($productDetails->product->tare_weight);
}
//Sets the default best before date, if none is supplied
@ -264,12 +264,12 @@ class StockService extends BaseService
$productDetails = (object)$this->GetProductDetails($productId);
if ($productDetails->product->enable_tare_weight_handling == 1)
{
if ($amount < $productDetails->product->tare_weight)
if ($amount < floatval($productDetails->product->tare_weight))
{
throw new \Exception('The amount cannot be lower than the defined tare weight');
}
$amount = abs($amount - $productDetails->stock_amount - $productDetails->product->tare_weight);
$amount = abs($amount - floatval($productDetails->stock_amount) - floatval($productDetails->product->tare_weight));
}
if ($transactionType === self::TRANSACTION_TYPE_CONSUME || $transactionType === self::TRANSACTION_TYPE_INVENTORY_CORRECTION)
@ -370,22 +370,22 @@ class StockService extends BaseService
$containerWeight = 0;
if ($productDetails->product->enable_tare_weight_handling == 1)
{
$containerWeight = $productDetails->product->tare_weight;
$containerWeight = floatval($productDetails->product->tare_weight);
}
if ($newAmount == $productDetails->stock_amount + $containerWeight)
if ($newAmount == floatval($productDetails->stock_amount) + $containerWeight)
{
throw new \Exception('The new amount cannot equal the current stock amount');
}
else if ($newAmount > $productDetails->stock_amount + $containerWeight)
else if ($newAmount > floatval($productDetails->stock_amount) + $containerWeight)
{
$bookingAmount = $newAmount - $productDetails->stock_amount;
$bookingAmount = $newAmount - floatval($productDetails->stock_amount);
if ($productDetails->product->enable_tare_weight_handling == 1)
{
$bookingAmount = $newAmount;
}
$this->AddProduct($productId, $bookingAmount, $bestBeforeDate, self::TRANSACTION_TYPE_INVENTORY_CORRECTION, date('Y-m-d'), $price, $locationId);
return $this->AddProduct($productId, $bookingAmount, $bestBeforeDate, self::TRANSACTION_TYPE_INVENTORY_CORRECTION, date('Y-m-d'), $price, $locationId);
}
else if ($newAmount < $productDetails->stock_amount + $containerWeight)
{
@ -395,10 +395,10 @@ class StockService extends BaseService
$bookingAmount = $newAmount;
}
$this->ConsumeProduct($productId, $bookingAmount, false, self::TRANSACTION_TYPE_INVENTORY_CORRECTION);
return $this->ConsumeProduct($productId, $bookingAmount, false, self::TRANSACTION_TYPE_INVENTORY_CORRECTION);
}
return $this->Database->lastInsertId();
return null;
}
public function OpenProduct(int $productId, float $amount, $specificStockEntryId = 'default')