mirror of
https://github.com/grocy/grocy.git
synced 2025-08-15 02:04:38 +00:00
Implemented tare weight handling (closes #132)
This commit is contained in:
@@ -27,7 +27,7 @@ class BatteriesApiController extends BaseApiController
|
|||||||
}
|
}
|
||||||
|
|
||||||
$chargeCycleId = $this->BatteriesService->TrackChargeCycle($args['batteryId'], $trackedTime);
|
$chargeCycleId = $this->BatteriesService->TrackChargeCycle($args['batteryId'], $trackedTime);
|
||||||
return $this->ApiResponse(array('charge_cycle_id' => $chargeCycleId));
|
return $this->ApiResponse($this->Database->battery_charge_cycles($chargeCycleId));
|
||||||
}
|
}
|
||||||
catch (\Exception $ex)
|
catch (\Exception $ex)
|
||||||
{
|
{
|
||||||
|
@@ -33,7 +33,7 @@ class ChoresApiController extends BaseApiController
|
|||||||
}
|
}
|
||||||
|
|
||||||
$choreExecutionId = $this->ChoresService->TrackChore($args['choreId'], $trackedTime, $doneBy);
|
$choreExecutionId = $this->ChoresService->TrackChore($args['choreId'], $trackedTime, $doneBy);
|
||||||
return $this->ApiResponse(array('chore_execution_id' => $choreExecutionId));
|
return $this->ApiResponse($this->Database->chores_log($choreExecutionId));
|
||||||
}
|
}
|
||||||
catch (\Exception $ex)
|
catch (\Exception $ex)
|
||||||
{
|
{
|
||||||
|
@@ -79,7 +79,7 @@ class StockApiController extends BaseApiController
|
|||||||
}
|
}
|
||||||
|
|
||||||
$bookingId = $this->StockService->AddProduct($args['productId'], $requestBody['amount'], $bestBeforeDate, $transactionType, date('Y-m-d'), $price, $locationId);
|
$bookingId = $this->StockService->AddProduct($args['productId'], $requestBody['amount'], $bestBeforeDate, $transactionType, date('Y-m-d'), $price, $locationId);
|
||||||
return $this->ApiResponse(array('booking_id' => $bookingId));
|
return $this->ApiResponse($this->Database->stock_log($bookingId));
|
||||||
}
|
}
|
||||||
catch (\Exception $ex)
|
catch (\Exception $ex)
|
||||||
{
|
{
|
||||||
@@ -128,7 +128,7 @@ class StockApiController extends BaseApiController
|
|||||||
}
|
}
|
||||||
|
|
||||||
$bookingId = $this->StockService->ConsumeProduct($args['productId'], $requestBody['amount'], $spoiled, $transactionType, $specificStockEntryId, $recipeId);
|
$bookingId = $this->StockService->ConsumeProduct($args['productId'], $requestBody['amount'], $spoiled, $transactionType, $specificStockEntryId, $recipeId);
|
||||||
return $this->ApiResponse(array('booking_id' => $bookingId));
|
return $this->ApiResponse($this->Database->stock_log($bookingId));
|
||||||
}
|
}
|
||||||
catch (\Exception $ex)
|
catch (\Exception $ex)
|
||||||
{
|
{
|
||||||
@@ -159,7 +159,7 @@ class StockApiController extends BaseApiController
|
|||||||
}
|
}
|
||||||
|
|
||||||
$bookingId = $this->StockService->InventoryProduct($args['productId'], $requestBody['new_amount'], $bestBeforeDate);
|
$bookingId = $this->StockService->InventoryProduct($args['productId'], $requestBody['new_amount'], $bestBeforeDate);
|
||||||
return $this->ApiResponse(array('booking_id' => $bookingId));
|
return $this->ApiResponse($this->Database->stock_log($bookingId));
|
||||||
}
|
}
|
||||||
catch (\Exception $ex)
|
catch (\Exception $ex)
|
||||||
{
|
{
|
||||||
@@ -190,7 +190,7 @@ class StockApiController extends BaseApiController
|
|||||||
}
|
}
|
||||||
|
|
||||||
$bookingId = $this->StockService->OpenProduct($args['productId'], $requestBody['amount'], $specificStockEntryId);
|
$bookingId = $this->StockService->OpenProduct($args['productId'], $requestBody['amount'], $specificStockEntryId);
|
||||||
return $this->ApiResponse(array('booking_id' => $bookingId));
|
return $this->ApiResponse($this->Database->stock_log($bookingId));
|
||||||
}
|
}
|
||||||
catch (\Exception $ex)
|
catch (\Exception $ex)
|
||||||
{
|
{
|
||||||
|
@@ -1022,7 +1022,8 @@
|
|||||||
"properties": {
|
"properties": {
|
||||||
"amount": {
|
"amount": {
|
||||||
"type": "number",
|
"type": "number",
|
||||||
"format": "double"
|
"format": "double",
|
||||||
|
"description": "The amount to add - please note that when tare weight handling for the product is enabled, this needs to be the amount including the container weight (gross), the amount to be posted will be automatically calculated based on what is in stock and the defined tare weight"
|
||||||
},
|
},
|
||||||
"best_before_date": {
|
"best_before_date": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
@@ -1059,7 +1060,7 @@
|
|||||||
"content": {
|
"content": {
|
||||||
"application/json": {
|
"application/json": {
|
||||||
"schema": {
|
"schema": {
|
||||||
"$ref": "#/components/schemas/StockBookingResponse"
|
"$ref": "#/components/schemas/StockLogEntry"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1103,7 +1104,7 @@
|
|||||||
"properties": {
|
"properties": {
|
||||||
"amount": {
|
"amount": {
|
||||||
"type": "double",
|
"type": "double",
|
||||||
"description": "The amount to remove"
|
"description": "The amount to remove - please note that when tare weight handling for the product is enabled, this needs to be the amount including the container weight (gross), the amount to be posted will be automatically calculated based on what is in stock and the defined tare weight"
|
||||||
},
|
},
|
||||||
"transaction_type": {
|
"transaction_type": {
|
||||||
"$ref": "#/components/internalSchemas/StockTransactionType"
|
"$ref": "#/components/internalSchemas/StockTransactionType"
|
||||||
@@ -1137,7 +1138,7 @@
|
|||||||
"content": {
|
"content": {
|
||||||
"application/json": {
|
"application/json": {
|
||||||
"schema": {
|
"schema": {
|
||||||
"$ref": "#/components/schemas/StockBookingResponse"
|
"$ref": "#/components/schemas/StockLogEntry"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1181,7 +1182,7 @@
|
|||||||
"properties": {
|
"properties": {
|
||||||
"new_amount": {
|
"new_amount": {
|
||||||
"type": "integer",
|
"type": "integer",
|
||||||
"description": "The new current amount for the given product"
|
"description": "The new current amount for the given product - please note that when tare weight handling for the product is enabled, this needs to be the amount including the container weight (gross), the amount to be posted will be automatically calculated based on what is in stock and the defined tare weight"
|
||||||
},
|
},
|
||||||
"best_before_date": {
|
"best_before_date": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
@@ -1199,7 +1200,7 @@
|
|||||||
"content": {
|
"content": {
|
||||||
"application/json": {
|
"application/json": {
|
||||||
"schema": {
|
"schema": {
|
||||||
"$ref": "#/components/schemas/StockBookingResponse"
|
"$ref": "#/components/schemas/StockLogEntry"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1263,7 +1264,7 @@
|
|||||||
"content": {
|
"content": {
|
||||||
"application/json": {
|
"application/json": {
|
||||||
"schema": {
|
"schema": {
|
||||||
"$ref": "#/components/schemas/StockBookingResponse"
|
"$ref": "#/components/schemas/StockLogEntry"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1568,12 +1569,7 @@
|
|||||||
"content": {
|
"content": {
|
||||||
"application/json": {
|
"application/json": {
|
||||||
"schema": {
|
"schema": {
|
||||||
"type": "object",
|
"$ref": "#/components/schemas/ChoreLogEntry"
|
||||||
"properties": {
|
|
||||||
"chore_execution_id": {
|
|
||||||
"type": "integer"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1729,12 +1725,7 @@
|
|||||||
"content": {
|
"content": {
|
||||||
"application/json": {
|
"application/json": {
|
||||||
"schema": {
|
"schema": {
|
||||||
"type": "object",
|
"$ref": "#/components/schemas/BatteryChargeCycleEntry"
|
||||||
"properties": {
|
|
||||||
"charge_cycle_id": {
|
|
||||||
"type": "integer"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2345,7 +2336,7 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"BatteryChargeCycle": {
|
"BatteryChargeCycleEntry": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
"id": {
|
"id": {
|
||||||
@@ -2462,14 +2453,6 @@
|
|||||||
"error_message": "The error message..."
|
"error_message": "The error message..."
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"StockBookingResponse": {
|
|
||||||
"type": "object",
|
|
||||||
"properties": {
|
|
||||||
"booking_id": {
|
|
||||||
"type": "integer"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"CurrentStockResponse": {
|
"CurrentStockResponse": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
|
@@ -335,5 +335,11 @@ return array(
|
|||||||
'This is for statistical purposes only' => 'This is for statistical purposes only',
|
'This is for statistical purposes only' => 'This is for statistical purposes only',
|
||||||
'You have to select a recipe' => 'You have to select a recipe',
|
'You have to select a recipe' => 'You have to select a recipe',
|
||||||
'Key type' => 'Key type',
|
'Key type' => 'Key type',
|
||||||
'Export as iCal' => 'Export as iCal'
|
'Export as iCal' => 'Export as iCal',
|
||||||
|
'Allow partial units in stock' => 'Allow partial units in stock',
|
||||||
|
'Enable tare weight handling' => 'Enable tare weight handling',
|
||||||
|
'This is useful e.g. for flour in jars - on purchase/consume/inventory you always weigh the whole jar, the amount to be posted is then automatically calculated based on what is in stock and the tare weight defined below' => 'This is useful e.g. for flour in jars - on purchase/consume/inventory you always weigh the whole jar, the amount to be posted is then automatically calculated based on what is in stock and the tare weight defined below',
|
||||||
|
'Tare weight' => 'Tare weight',
|
||||||
|
'Tare weight handling enabled - please weigh the whole container, the amount to be posted will be automatically calculcated' => 'Tare weight handling enabled - please weigh the whole container, the amount to be posted will be automatically calculcated',
|
||||||
|
'You have to select a location' => 'You have to select a location'
|
||||||
);
|
);
|
||||||
|
5
migrations/0057.sql
Normal file
5
migrations/0057.sql
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
ALTER TABLE products
|
||||||
|
ADD enable_tare_weight_handling TINYINT NOT NULL DEFAULT 0;
|
||||||
|
|
||||||
|
ALTER TABLE products
|
||||||
|
ADD tare_weight REAL NOT NULL DEFAULT 0;
|
@@ -502,7 +502,7 @@ $("#about-dialog-link").on("click", function()
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
$(".local-number-format[data-format='currency']").each(function ()
|
$(".locale-number-format[data-format='currency']").each(function ()
|
||||||
{
|
{
|
||||||
$(this).text(parseFloat($(this).text()).toLocaleString(undefined, { minimumFractionDigits: 2 }));
|
$(this).text(parseFloat($(this).text()).toLocaleString(undefined, { style: "currency", currency: Grocy.Currency }));
|
||||||
});
|
});
|
||||||
|
@@ -12,7 +12,7 @@
|
|||||||
function(result)
|
function(result)
|
||||||
{
|
{
|
||||||
Grocy.FrontendHelpers.EndUiBusy("batterytracking-form");
|
Grocy.FrontendHelpers.EndUiBusy("batterytracking-form");
|
||||||
toastr.success(L('Tracked charge cycle of battery #1 on #2', batteryDetails.battery.name, $('#tracked_time').find('input').val()) + '<br><a class="btn btn-secondary btn-sm mt-2" href="#" onclick="UndoChargeCycle(' + result.charge_cycle_id + ')"><i class="fas fa-undo"></i> ' + L("Undo") + '</a>');
|
toastr.success(L('Tracked charge cycle of battery #1 on #2', batteryDetails.battery.name, $('#tracked_time').find('input').val()) + '<br><a class="btn btn-secondary btn-sm mt-2" href="#" onclick="UndoChargeCycle(' + result.id + ')"><i class="fas fa-undo"></i> ' + L("Undo") + '</a>');
|
||||||
|
|
||||||
$('#battery_id').val('');
|
$('#battery_id').val('');
|
||||||
$('#battery_id_text_input').focus();
|
$('#battery_id_text_input').focus();
|
||||||
|
@@ -12,7 +12,7 @@
|
|||||||
function(result)
|
function(result)
|
||||||
{
|
{
|
||||||
Grocy.FrontendHelpers.EndUiBusy("choretracking-form");
|
Grocy.FrontendHelpers.EndUiBusy("choretracking-form");
|
||||||
toastr.success(L('Tracked execution of chore #1 on #2', choreDetails.chore.name, Grocy.Components.DateTimePicker.GetValue()) + '<br><a class="btn btn-secondary btn-sm mt-2" href="#" onclick="UndoChoreExecution(' + result.chore_execution_id + ')"><i class="fas fa-undo"></i> ' + L("Undo") + '</a>');
|
toastr.success(L('Tracked execution of chore #1 on #2', choreDetails.chore.name, Grocy.Components.DateTimePicker.GetValue()) + '<br><a class="btn btn-secondary btn-sm mt-2" href="#" onclick="UndoChoreExecution(' + result.id + ')"><i class="fas fa-undo"></i> ' + L("Undo") + '</a>');
|
||||||
|
|
||||||
$('#chore_id').val('');
|
$('#chore_id').val('');
|
||||||
$('#chore_id_text_input').focus();
|
$('#chore_id_text_input').focus();
|
||||||
|
@@ -39,9 +39,14 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
Grocy.FrontendHelpers.EndUiBusy("consume-form");
|
Grocy.FrontendHelpers.EndUiBusy("consume-form");
|
||||||
toastr.success(L('Removed #1 #2 of #3 from stock', jsonForm.amount, Pluralize(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.booking_id + ')"><i class="fas fa-undo"></i> ' + L("Undo") + '</a>');
|
toastr.success(L('Removed #1 #2 of #3 from stock', Math.abs(result.amount), Pluralize(Math.abs(result.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> ' + L("Undo") + '</a>');
|
||||||
|
|
||||||
|
$("#amount").attr("min", "1");
|
||||||
|
$("#amount").attr("max", "999999");
|
||||||
|
$("#amount").attr("step", "1");
|
||||||
|
$("#amount").parent().find(".invalid-feedback").text(L('The amount cannot be lower than #1', '1'));
|
||||||
$('#amount').val(1);
|
$('#amount').val(1);
|
||||||
|
$("#tare-weight-handling-info").addClass("d-none");
|
||||||
Grocy.Components.ProductPicker.Clear();
|
Grocy.Components.ProductPicker.Clear();
|
||||||
if (Grocy.FeatureFlags.GROCY_FEATURE_FLAG_RECIPES)
|
if (Grocy.FeatureFlags.GROCY_FEATURE_FLAG_RECIPES)
|
||||||
{
|
{
|
||||||
@@ -100,7 +105,7 @@ $('#save-mark-as-open-button').on('click', function(e)
|
|||||||
}
|
}
|
||||||
|
|
||||||
Grocy.FrontendHelpers.EndUiBusy("consume-form");
|
Grocy.FrontendHelpers.EndUiBusy("consume-form");
|
||||||
toastr.success(L('Marked #1 #2 of #3 as opened', jsonForm.amount, Pluralize(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.booking_id + ')"><i class="fas fa-undo"></i> ' + L("Undo") + '</a>');
|
toastr.success(L('Marked #1 #2 of #3 as opened', jsonForm.amount, Pluralize(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> ' + L("Undo") + '</a>');
|
||||||
|
|
||||||
$('#amount').val(1);
|
$('#amount').val(1);
|
||||||
Grocy.Components.ProductPicker.Clear();
|
Grocy.Components.ProductPicker.Clear();
|
||||||
@@ -146,13 +151,25 @@ Grocy.Components.ProductPicker.GetPicker().on('change', function(e)
|
|||||||
{
|
{
|
||||||
$("#amount").attr("min", "0.01");
|
$("#amount").attr("min", "0.01");
|
||||||
$("#amount").attr("step", "0.01");
|
$("#amount").attr("step", "0.01");
|
||||||
$("#amount").parent().find(".invalid-feedback").text(L('The amount cannot be lower than #1', 0.01.toLocaleString()));
|
$("#amount").parent().find(".invalid-feedback").text(L('The amount must be between #1 and #2', 0.01.toLocaleString(), parseFloat(productDetails.stock_amount).toLocaleString()));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
$("#amount").attr("min", "1");
|
$("#amount").attr("min", "1");
|
||||||
$("#amount").attr("step", "1");
|
$("#amount").attr("step", "1");
|
||||||
$("#amount").parent().find(".invalid-feedback").text(L('The amount cannot be lower than #1', '1'));
|
$("#amount").parent().find(".invalid-feedback").text(L('The amount must be between #1 and #2', "1", parseFloat(productDetails.stock_amount).toLocaleString()));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (productDetails.product.enable_tare_weight_handling == 1)
|
||||||
|
{
|
||||||
|
$("#amount").attr("min", productDetails.product.tare_weight);
|
||||||
|
$('#amount').attr('max', parseFloat(productDetails.stock_amount) + parseFloat(productDetails.product.tare_weight));
|
||||||
|
$("#amount").parent().find(".invalid-feedback").text(L('The amount must be between #1 and #2', parseFloat(productDetails.product.tare_weight).toLocaleString(), (parseFloat(productDetails.stock_amount) + parseFloat(productDetails.product.tare_weight)).toLocaleString()));
|
||||||
|
$("#tare-weight-handling-info").removeClass("d-none");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$("#tare-weight-handling-info").addClass("d-none");
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((productDetails.stock_amount || 0) === 0)
|
if ((productDetails.stock_amount || 0) === 0)
|
||||||
|
@@ -6,7 +6,7 @@
|
|||||||
Grocy.FrontendHelpers.BeginUiBusy("inventory-form");
|
Grocy.FrontendHelpers.BeginUiBusy("inventory-form");
|
||||||
|
|
||||||
Grocy.Api.Get('stock/products/' + jsonForm.product_id,
|
Grocy.Api.Get('stock/products/' + jsonForm.product_id,
|
||||||
function (productDetails)
|
function(productDetails)
|
||||||
{
|
{
|
||||||
var jsonData = { };
|
var jsonData = { };
|
||||||
jsonData.new_amount = jsonForm.new_amount;
|
jsonData.new_amount = jsonForm.new_amount;
|
||||||
@@ -38,7 +38,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
Grocy.FrontendHelpers.EndUiBusy("inventory-form");
|
Grocy.FrontendHelpers.EndUiBusy("inventory-form");
|
||||||
toastr.success(L('Stock amount of #1 is now #2 #3', productDetails.product.name, jsonForm.new_amount, Pluralize(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.booking_id + ')"><i class="fas fa-undo"></i> ' + L("Undo") + '</a>');
|
toastr.success(L('Stock amount of #1 is now #2 #3', productDetails.product.name, productDetails.stock_amount, Pluralize(productDetails.stock_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> ' + L("Undo") + '</a>');
|
||||||
|
|
||||||
if (addBarcode !== undefined)
|
if (addBarcode !== undefined)
|
||||||
{
|
{
|
||||||
@@ -47,6 +47,10 @@
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
$('#inventory-change-info').addClass('d-none');
|
$('#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(L('The amount cannot be lower than #1', '0'));
|
||||||
$('#new_amount').val('');
|
$('#new_amount').val('');
|
||||||
Grocy.Components.DateTimePicker.Clear();
|
Grocy.Components.DateTimePicker.Clear();
|
||||||
Grocy.Components.ProductPicker.SetValue('');
|
Grocy.Components.ProductPicker.SetValue('');
|
||||||
@@ -91,9 +95,20 @@ Grocy.Components.ProductPicker.GetPicker().on('change', function(e)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
$("#new_amount").attr("min", "1");
|
$("#new_amount").attr("min", "0");
|
||||||
$("#new_amount").attr("step", "1");
|
$("#new_amount").attr("step", "1");
|
||||||
$("#new_amount").parent().find(".invalid-feedback").text(L('The amount cannot be lower than #1', '1'));
|
$("#new_amount").parent().find(".invalid-feedback").text(L('The amount cannot be lower than #1', '0'));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (productDetails.product.enable_tare_weight_handling == 1)
|
||||||
|
{
|
||||||
|
$("#new_amount").attr("min", productDetails.product.tare_weight);
|
||||||
|
$("#new_amount").parent().find(".invalid-feedback").text(L('The amount cannot be lower than #1', parseFloat(productDetails.product.tare_weight).toLocaleString({ minimumFractionDigits: 0, maximumFractionDigits: 2 })));
|
||||||
|
$("#tare-weight-handling-info").removeClass("d-none");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$("#tare-weight-handling-info").addClass("d-none");
|
||||||
}
|
}
|
||||||
|
|
||||||
$('#new_amount').focus();
|
$('#new_amount').focus();
|
||||||
@@ -177,26 +192,31 @@ $('#new_amount').on('keyup', function(e)
|
|||||||
Grocy.Api.Get('stock/products/' + productId,
|
Grocy.Api.Get('stock/products/' + productId,
|
||||||
function(productDetails)
|
function(productDetails)
|
||||||
{
|
{
|
||||||
var productStockAmount = parseInt(productDetails.stock_amount || '0');
|
var productStockAmount = parseFloat(productDetails.stock_amount || parseFloat('0'));
|
||||||
|
|
||||||
if (newAmount > productStockAmount)
|
var containerWeight = parseFloat("0");
|
||||||
|
if (productDetails.product.enable_tare_weight_handling == 1)
|
||||||
{
|
{
|
||||||
var amountToAdd = newAmount - productDetails.stock_amount;
|
containerWeight = parseFloat(productDetails.product.tare_weight);
|
||||||
$('#inventory-change-info').text(L('This means #1 will be added to stock', amountToAdd.toString() + ' ' + productDetails.quantity_unit_stock.name));
|
|
||||||
$('#inventory-change-info').removeClass('d-none');
|
|
||||||
Grocy.Components.DateTimePicker.GetInputElement().attr('required', '');
|
|
||||||
}
|
}
|
||||||
else if (newAmount < productStockAmount)
|
|
||||||
{
|
var estimatedBookingAmount = Math.abs(newAmount - productStockAmount - containerWeight);
|
||||||
var amountToRemove = productStockAmount - newAmount;
|
|
||||||
$('#inventory-change-info').text(L('This means #1 will be removed from stock', amountToRemove.toString() + ' ' + productDetails.quantity_unit_stock.name));
|
|
||||||
$('#inventory-change-info').removeClass('d-none');
|
$('#inventory-change-info').removeClass('d-none');
|
||||||
Grocy.Components.DateTimePicker.GetInputElement().removeAttr('required');
|
|
||||||
}
|
if (productDetails.product.enable_tare_weight_handling == 1 && newAmount < containerWeight)
|
||||||
else
|
|
||||||
{
|
{
|
||||||
$('#inventory-change-info').addClass('d-none');
|
$('#inventory-change-info').addClass('d-none');
|
||||||
}
|
}
|
||||||
|
else if (newAmount > productStockAmount + containerWeight)
|
||||||
|
{
|
||||||
|
$('#inventory-change-info').text(L('This means #1 will be added to stock', estimatedBookingAmount.toLocaleString() + ' ' + Pluralize(estimatedBookingAmount, productDetails.quantity_unit_stock.name, productDetails.quantity_unit_stock.name_plural)));
|
||||||
|
Grocy.Components.DateTimePicker.GetInputElement().attr('required', '');
|
||||||
|
}
|
||||||
|
else if (newAmount < productStockAmount + containerWeight)
|
||||||
|
{
|
||||||
|
$('#inventory-change-info').text(L('This means #1 will be removed from stock', estimatedBookingAmount.toLocaleString() + ' ' + Pluralize(estimatedBookingAmount, productDetails.quantity_unit_stock.name, productDetails.quantity_unit_stock.name_plural)));
|
||||||
|
Grocy.Components.DateTimePicker.GetInputElement().removeAttr('required');
|
||||||
|
}
|
||||||
|
|
||||||
Grocy.FrontendHelpers.ValidateForm('inventory-form');
|
Grocy.FrontendHelpers.ValidateForm('inventory-form');
|
||||||
},
|
},
|
||||||
|
@@ -169,6 +169,8 @@ $('.input-group-qu').on('change', function(e)
|
|||||||
$('#qu-conversion-info').addClass('d-none');
|
$('#qu-conversion-info').addClass('d-none');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$("#tare_weight_qu_info").text($("#qu_id_stock option:selected").text());
|
||||||
|
|
||||||
Grocy.FrontendHelpers.ValidateForm('product-form');
|
Grocy.FrontendHelpers.ValidateForm('product-form');
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -199,6 +201,20 @@ $('#product-form input').keydown(function(event)
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
$("#enable_tare_weight_handling").on("click", function()
|
||||||
|
{
|
||||||
|
if (this.checked)
|
||||||
|
{
|
||||||
|
$("#tare_weight").removeAttr("disabled");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$("#tare_weight").attr("disabled", "");
|
||||||
|
}
|
||||||
|
|
||||||
|
Grocy.FrontendHelpers.ValidateForm("product-form");
|
||||||
|
});
|
||||||
|
|
||||||
Grocy.DeleteProductPictureOnSave = false;
|
Grocy.DeleteProductPictureOnSave = false;
|
||||||
$('#delete-current-product-picture-button').on('click', function (e)
|
$('#delete-current-product-picture-button').on('click', function (e)
|
||||||
{
|
{
|
||||||
|
@@ -48,7 +48,7 @@
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
var successMessage = L('Added #1 #2 of #3 to stock', amount, Pluralize(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.booking_id + ')"><i class="fas fa-undo"></i> ' + L("Undo") + '</a>';
|
var successMessage = L('Added #1 #2 of #3 to stock', result.amount, Pluralize(result.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> ' + L("Undo") + '</a>';
|
||||||
|
|
||||||
if (addBarcode !== undefined)
|
if (addBarcode !== undefined)
|
||||||
{
|
{
|
||||||
@@ -64,8 +64,13 @@
|
|||||||
{
|
{
|
||||||
Grocy.FrontendHelpers.EndUiBusy("purchase-form");
|
Grocy.FrontendHelpers.EndUiBusy("purchase-form");
|
||||||
toastr.success(successMessage);
|
toastr.success(successMessage);
|
||||||
|
|
||||||
|
$("#amount").attr("min", "1");
|
||||||
|
$("#amount").attr("step", "1");
|
||||||
|
$("#amount").parent().find(".invalid-feedback").text(L('The amount cannot be lower than #1', '1'));
|
||||||
$('#amount').val(0);
|
$('#amount').val(0);
|
||||||
$('#price').val('');
|
$('#price').val('');
|
||||||
|
$("#tare-weight-handling-info").addClass("d-none");
|
||||||
Grocy.Components.LocationPicker.Clear();
|
Grocy.Components.LocationPicker.Clear();
|
||||||
Grocy.Components.DateTimePicker.Clear();
|
Grocy.Components.DateTimePicker.Clear();
|
||||||
Grocy.Components.ProductPicker.SetValue('');
|
Grocy.Components.ProductPicker.SetValue('');
|
||||||
@@ -97,7 +102,7 @@ Grocy.Components.ProductPicker.GetPicker().on('change', function(e)
|
|||||||
Grocy.Components.ProductCard.Refresh(productId);
|
Grocy.Components.ProductCard.Refresh(productId);
|
||||||
|
|
||||||
Grocy.Api.Get('stock/products/' + productId,
|
Grocy.Api.Get('stock/products/' + productId,
|
||||||
function(productDetails)
|
function (productDetails)
|
||||||
{
|
{
|
||||||
$('#amount_qu_unit').text(productDetails.quantity_unit_purchase.name);
|
$('#amount_qu_unit').text(productDetails.quantity_unit_purchase.name);
|
||||||
$('#price').val(productDetails.last_price);
|
$('#price').val(productDetails.last_price);
|
||||||
@@ -116,6 +121,18 @@ Grocy.Components.ProductPicker.GetPicker().on('change', function(e)
|
|||||||
$("#amount").parent().find(".invalid-feedback").text(L('The amount cannot be lower than #1', '1'));
|
$("#amount").parent().find(".invalid-feedback").text(L('The amount cannot be lower than #1', '1'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (productDetails.product.enable_tare_weight_handling == 1)
|
||||||
|
{
|
||||||
|
var minAmount = parseFloat(productDetails.product.tare_weight) + parseFloat(productDetails.stock_amount) + 1;
|
||||||
|
$("#amount").attr("min", minAmount);
|
||||||
|
$("#amount").parent().find(".invalid-feedback").text(L('The amount cannot be lower than #1', minAmount.toLocaleString()));
|
||||||
|
$("#tare-weight-handling-info").removeClass("d-none");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$("#tare-weight-handling-info").addClass("d-none");
|
||||||
|
}
|
||||||
|
|
||||||
if (productDetails.product.default_best_before_days.toString() !== '0')
|
if (productDetails.product.default_best_before_days.toString() !== '0')
|
||||||
{
|
{
|
||||||
if (productDetails.product.default_best_before_days == -1)
|
if (productDetails.product.default_best_before_days == -1)
|
||||||
|
@@ -63,7 +63,7 @@ class DemoDataGeneratorService extends BaseService
|
|||||||
INSERT INTO products (name, location_id, qu_id_purchase, qu_id_stock, qu_factor_purchase_to_stock, product_group_id) VALUES ('{$localizationService->LocalizeForSqlString('Salami')}', 2, 3, 3, 1, 6); --18
|
INSERT INTO products (name, location_id, qu_id_purchase, qu_id_stock, qu_factor_purchase_to_stock, product_group_id) VALUES ('{$localizationService->LocalizeForSqlString('Salami')}', 2, 3, 3, 1, 6); --18
|
||||||
INSERT INTO products (name, location_id, qu_id_purchase, qu_id_stock, qu_factor_purchase_to_stock, product_group_id) VALUES ('{$localizationService->LocalizeForSqlString('Toast')}', 4, 5, 5, 1, 2); --19
|
INSERT INTO products (name, location_id, qu_id_purchase, qu_id_stock, qu_factor_purchase_to_stock, product_group_id) VALUES ('{$localizationService->LocalizeForSqlString('Toast')}', 4, 5, 5, 1, 2); --19
|
||||||
INSERT INTO products (name, location_id, qu_id_purchase, qu_id_stock, qu_factor_purchase_to_stock, product_group_id) VALUES ('{$localizationService->LocalizeForSqlString('Minced meat')}', 2, 3, 3, 1, 4); --20
|
INSERT INTO products (name, location_id, qu_id_purchase, qu_id_stock, qu_factor_purchase_to_stock, product_group_id) VALUES ('{$localizationService->LocalizeForSqlString('Minced meat')}', 2, 3, 3, 1, 4); --20
|
||||||
INSERT INTO products (name, location_id, qu_id_purchase, qu_id_stock, qu_factor_purchase_to_stock, product_group_id) VALUES ('{$localizationService->LocalizeForSqlString('Flour')}', 2, 3, 3, 1, 3); --21
|
INSERT INTO products (name, location_id, qu_id_purchase, qu_id_stock, qu_factor_purchase_to_stock, product_group_id, enable_tare_weight_handling, tare_weight) VALUES ('{$localizationService->LocalizeForSqlString('Flour')}', 3, 8, 8, 1, 3, 1, 500); --21
|
||||||
INSERT INTO products (name, location_id, qu_id_purchase, qu_id_stock, qu_factor_purchase_to_stock, product_group_id) VALUES ('{$localizationService->LocalizeForSqlString('Sugar')}', 3, 3, 3, 1, 3); --22
|
INSERT INTO products (name, location_id, qu_id_purchase, qu_id_stock, qu_factor_purchase_to_stock, product_group_id) VALUES ('{$localizationService->LocalizeForSqlString('Sugar')}', 3, 3, 3, 1, 3); --22
|
||||||
INSERT INTO products (name, location_id, qu_id_purchase, qu_id_stock, qu_factor_purchase_to_stock) VALUES ('{$localizationService->LocalizeForSqlString('Milk')}', 2, 10, 10, 1); --23
|
INSERT INTO products (name, location_id, qu_id_purchase, qu_id_stock, qu_factor_purchase_to_stock) VALUES ('{$localizationService->LocalizeForSqlString('Milk')}', 2, 10, 10, 1); --23
|
||||||
|
|
||||||
@@ -191,15 +191,15 @@ class DemoDataGeneratorService extends BaseService
|
|||||||
$stockService->AddProduct(15, 1, date('Y-m-d', strtotime('-2 days')), StockService::TRANSACTION_TYPE_PURCHASE, date('Y-m-d', strtotime('-30 days')), $this->RandomPrice());
|
$stockService->AddProduct(15, 1, date('Y-m-d', strtotime('-2 days')), StockService::TRANSACTION_TYPE_PURCHASE, date('Y-m-d', strtotime('-30 days')), $this->RandomPrice());
|
||||||
$stockService->AddProduct(15, 1, date('Y-m-d', strtotime('-2 days')), StockService::TRANSACTION_TYPE_PURCHASE, date('Y-m-d', strtotime('-40 days')), $this->RandomPrice());
|
$stockService->AddProduct(15, 1, date('Y-m-d', strtotime('-2 days')), StockService::TRANSACTION_TYPE_PURCHASE, date('Y-m-d', strtotime('-40 days')), $this->RandomPrice());
|
||||||
$stockService->AddProduct(15, 1, date('Y-m-d', strtotime('-2 days')), StockService::TRANSACTION_TYPE_PURCHASE, date('Y-m-d', strtotime('-50 days')), $this->RandomPrice());
|
$stockService->AddProduct(15, 1, date('Y-m-d', strtotime('-2 days')), StockService::TRANSACTION_TYPE_PURCHASE, date('Y-m-d', strtotime('-50 days')), $this->RandomPrice());
|
||||||
$stockService->AddProduct(21, 1, date('Y-m-d', strtotime('+200 days')), StockService::TRANSACTION_TYPE_PURCHASE, date('Y-m-d', strtotime('-10 days')), $this->RandomPrice());
|
$stockService->AddProduct(21, 1500, date('Y-m-d', strtotime('+200 days')), StockService::TRANSACTION_TYPE_PURCHASE, date('Y-m-d', strtotime('-10 days')), $this->RandomPrice());
|
||||||
$stockService->AddProduct(21, 1, date('Y-m-d', strtotime('+200 days')), StockService::TRANSACTION_TYPE_PURCHASE, date('Y-m-d', strtotime('-20 days')), $this->RandomPrice());
|
$stockService->AddProduct(21, 2500, date('Y-m-d', strtotime('+200 days')), StockService::TRANSACTION_TYPE_PURCHASE, date('Y-m-d', strtotime('-20 days')), $this->RandomPrice());
|
||||||
$stockService->AddProduct(22, 1, date('Y-m-d', strtotime('+200 days')), StockService::TRANSACTION_TYPE_PURCHASE, date('Y-m-d', strtotime('-10 days')), $this->RandomPrice());
|
$stockService->AddProduct(22, 1, date('Y-m-d', strtotime('+200 days')), StockService::TRANSACTION_TYPE_PURCHASE, date('Y-m-d', strtotime('-10 days')), $this->RandomPrice());
|
||||||
$stockService->AddProduct(22, 1, date('Y-m-d', strtotime('+200 days')), StockService::TRANSACTION_TYPE_PURCHASE, date('Y-m-d', strtotime('-20 days')), $this->RandomPrice());
|
$stockService->AddProduct(22, 1, date('Y-m-d', strtotime('+200 days')), StockService::TRANSACTION_TYPE_PURCHASE, date('Y-m-d', strtotime('-20 days')), $this->RandomPrice());
|
||||||
$stockService->AddProduct(23, 1, date('Y-m-d', strtotime('+2 days')), StockService::TRANSACTION_TYPE_PURCHASE, date('Y-m-d', strtotime('-40 days')), $this->RandomPrice());
|
$stockService->AddProduct(23, 1, date('Y-m-d', strtotime('+2 days')), StockService::TRANSACTION_TYPE_PURCHASE, date('Y-m-d', strtotime('-40 days')), $this->RandomPrice());
|
||||||
$stockService->AddProduct(23, 1, date('Y-m-d', strtotime('+2 days')), StockService::TRANSACTION_TYPE_PURCHASE, date('Y-m-d', strtotime('-50 days')), $this->RandomPrice());
|
$stockService->AddProduct(23, 1, date('Y-m-d', strtotime('+2 days')), StockService::TRANSACTION_TYPE_PURCHASE, date('Y-m-d', strtotime('-50 days')), $this->RandomPrice());
|
||||||
$stockService->AddMissingProductsToShoppingList();
|
$stockService->AddMissingProductsToShoppingList();
|
||||||
|
$stockService->OpenProduct(3, 1);
|
||||||
$stockService->OpenProduct(6, 1);
|
$stockService->OpenProduct(6, 1);
|
||||||
$stockService->OpenProduct(21, 1);
|
|
||||||
$stockService->OpenProduct(22, 1);
|
$stockService->OpenProduct(22, 1);
|
||||||
|
|
||||||
$choresService = new ChoresService();
|
$choresService = new ChoresService();
|
||||||
|
@@ -130,6 +130,20 @@ class StockService extends BaseService
|
|||||||
throw new \Exception('Product does not exist');
|
throw new \Exception('Product does not exist');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Tare weight handling
|
||||||
|
// The given amount is the new total amount including the container weight (gross)
|
||||||
|
// The amount to be posted needs to be the given amount - stock amount - tare weight
|
||||||
|
$productDetails = (object)$this->GetProductDetails($productId);
|
||||||
|
if ($productDetails->product->enable_tare_weight_handling == 1)
|
||||||
|
{
|
||||||
|
if ($amount <= $productDetails->product->tare_weight + $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;
|
||||||
|
}
|
||||||
|
|
||||||
if ($transactionType === self::TRANSACTION_TYPE_PURCHASE || $transactionType === self::TRANSACTION_TYPE_INVENTORY_CORRECTION)
|
if ($transactionType === self::TRANSACTION_TYPE_PURCHASE || $transactionType === self::TRANSACTION_TYPE_INVENTORY_CORRECTION)
|
||||||
{
|
{
|
||||||
$stockId = uniqid();
|
$stockId = uniqid();
|
||||||
@@ -174,6 +188,20 @@ class StockService extends BaseService
|
|||||||
throw new \Exception('Product does not exist');
|
throw new \Exception('Product does not exist');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Tare weight handling
|
||||||
|
// The given amount is the new total amount including the container weight (gross)
|
||||||
|
// The amount to be posted needs to be the absolute value of the given amount - stock amount - tare weight
|
||||||
|
$productDetails = (object)$this->GetProductDetails($productId);
|
||||||
|
if ($productDetails->product->enable_tare_weight_handling == 1)
|
||||||
|
{
|
||||||
|
if ($amount < $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);
|
||||||
|
}
|
||||||
|
|
||||||
if ($transactionType === self::TRANSACTION_TYPE_CONSUME || $transactionType === self::TRANSACTION_TYPE_INVENTORY_CORRECTION)
|
if ($transactionType === self::TRANSACTION_TYPE_CONSUME || $transactionType === self::TRANSACTION_TYPE_INVENTORY_CORRECTION)
|
||||||
{
|
{
|
||||||
$productStockAmount = $this->Database->stock()->where('product_id', $productId)->sum('amount');
|
$productStockAmount = $this->Database->stock()->where('product_id', $productId)->sum('amount');
|
||||||
@@ -259,18 +287,36 @@ class StockService extends BaseService
|
|||||||
throw new \Exception('Product does not exist');
|
throw new \Exception('Product does not exist');
|
||||||
}
|
}
|
||||||
|
|
||||||
$productStockAmount = $this->Database->stock()->where('product_id', $productId)->sum('amount');
|
$productDetails = (object)$this->GetProductDetails($productId);
|
||||||
|
|
||||||
if ($newAmount > $productStockAmount)
|
// Tare weight handling
|
||||||
|
// The given amount is the new total amount including the container weight (gross)
|
||||||
|
// So assume that the amount in stock is the amount also including the container weight
|
||||||
|
$containerWeight = 0;
|
||||||
|
if ($productDetails->product->enable_tare_weight_handling == 1)
|
||||||
{
|
{
|
||||||
$productDetails = $this->GetProductDetails($productId);
|
$containerWeight = $productDetails->product->tare_weight;
|
||||||
$amountToAdd = $newAmount - $productStockAmount;
|
|
||||||
$this->AddProduct($productId, $amountToAdd, $bestBeforeDate, self::TRANSACTION_TYPE_INVENTORY_CORRECTION, date('Y-m-d'), $productDetails['last_price']);
|
|
||||||
}
|
}
|
||||||
else if ($newAmount < $productStockAmount)
|
|
||||||
|
if ($newAmount > $productDetails->stock_amount + $containerWeight)
|
||||||
{
|
{
|
||||||
$amountToRemove = $productStockAmount - $newAmount;
|
$bookingAmount = $newAmount - $productDetails->stock_amount;
|
||||||
$this->ConsumeProduct($productId, $amountToRemove, false, self::TRANSACTION_TYPE_INVENTORY_CORRECTION);
|
if ($productDetails->product->enable_tare_weight_handling == 1)
|
||||||
|
{
|
||||||
|
$bookingAmount = $newAmount;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->AddProduct($productId, $bookingAmount, $bestBeforeDate, self::TRANSACTION_TYPE_INVENTORY_CORRECTION, date('Y-m-d'), $productDetails->last_price);
|
||||||
|
}
|
||||||
|
else if ($newAmount < $productDetails->stock_amount + $containerWeight)
|
||||||
|
{
|
||||||
|
$bookingAmount = $productDetails->stock_amount - $newAmount;
|
||||||
|
if ($productDetails->product->enable_tare_weight_handling == 1)
|
||||||
|
{
|
||||||
|
$bookingAmount = $newAmount;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->ConsumeProduct($productId, $bookingAmount, false, self::TRANSACTION_TYPE_INVENTORY_CORRECTION);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->Database->lastInsertId();
|
return $this->Database->lastInsertId();
|
||||||
|
@@ -12,10 +12,11 @@
|
|||||||
@php if(empty($additionalGroupCssClasses)) { $additionalGroupCssClasses = ''; } @endphp
|
@php if(empty($additionalGroupCssClasses)) { $additionalGroupCssClasses = ''; } @endphp
|
||||||
@php if(empty($additionalAttributes)) { $additionalAttributes = ''; } @endphp
|
@php if(empty($additionalAttributes)) { $additionalAttributes = ''; } @endphp
|
||||||
@php if(empty($additionalHtmlElements)) { $additionalHtmlElements = ''; } @endphp
|
@php if(empty($additionalHtmlElements)) { $additionalHtmlElements = ''; } @endphp
|
||||||
|
@php if(empty($additionalHtmlContextHelp)) { $additionalHtmlContextHelp = ''; } @endphp
|
||||||
@php if(!isset($isRequired)) { $isRequired = true; } @endphp
|
@php if(!isset($isRequired)) { $isRequired = true; } @endphp
|
||||||
|
|
||||||
<div class="form-group {{ $additionalGroupCssClasses }}">
|
<div class="form-group {{ $additionalGroupCssClasses }}">
|
||||||
<label for="{{ $id }}">{{ $L($label) }} <span id="{{ $hintId }}" class="small text-muted">{{ $hint }}</span></label>
|
<label for="{{ $id }}">{{ $L($label) }} <span id="{{ $hintId }}" class="small text-muted">{{ $hint }}</span>{!! $additionalHtmlContextHelp !!}</label>
|
||||||
<div class="input-group">
|
<div class="input-group">
|
||||||
<input {!! $additionalAttributes !!} type="number" class="form-control numberpicker {{ $additionalCssClasses }}" id="{{ $id }}" name="{{ $id }}" value="{{ $value }}" min="{{ $min }}" max="{{ $max }}" step="{{ $step }}" @if($isRequired) required @endif>
|
<input {!! $additionalAttributes !!} type="number" class="form-control numberpicker {{ $additionalCssClasses }}" id="{{ $id }}" name="{{ $id }}" value="{{ $value }}" min="{{ $min }}" max="{{ $max }}" step="{{ $step }}" @if($isRequired) required @endif>
|
||||||
<div class="input-group-append">
|
<div class="input-group-append">
|
||||||
|
@@ -23,7 +23,8 @@
|
|||||||
'hintId' => 'amount_qu_unit',
|
'hintId' => 'amount_qu_unit',
|
||||||
'min' => 1,
|
'min' => 1,
|
||||||
'value' => 1,
|
'value' => 1,
|
||||||
'invalidFeedback' => $L('The amount cannot be lower than #1', '1')
|
'invalidFeedback' => $L('The amount cannot be lower than #1', '1'),
|
||||||
|
'additionalHtmlContextHelp' => '<div id="tare-weight-handling-info" class="text-info font-italic d-none">' . $L('Tare weight handling enabled - please weigh the whole container, the amount to be posted will be automatically calculcated') . '</div>'
|
||||||
))
|
))
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
|
@@ -22,9 +22,10 @@
|
|||||||
'hintId' => 'new_amount_qu_unit',
|
'hintId' => 'new_amount_qu_unit',
|
||||||
'min' => 0,
|
'min' => 0,
|
||||||
'value' => 1,
|
'value' => 1,
|
||||||
'invalidFeedback' => $L('The amount cannot be lower than #1', '1'),
|
'invalidFeedback' => $L('The amount cannot be lower than #1', '0'),
|
||||||
'additionalAttributes' => 'data-notequal="notequal" not-equal="-1"',
|
'additionalAttributes' => 'data-notequal="notequal" not-equal="-1"',
|
||||||
'additionalHtmlElements' => '<div id="inventory-change-info" class="form-text text-muted small d-none"></div>'
|
'additionalHtmlElements' => '<div id="inventory-change-info" class="form-text text-muted small d-none"></div>',
|
||||||
|
'additionalHtmlContextHelp' => '<div id="tare-weight-handling-info" class="text-small text-info font-italic d-none">' . $L('Tare weight handling enabled - please weigh the whole container, the amount to be posted will be automatically calculcated') . '</div>'
|
||||||
))
|
))
|
||||||
|
|
||||||
@include('components.datetimepicker', array(
|
@include('components.datetimepicker', array(
|
||||||
|
@@ -134,6 +134,29 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<div class="form-check">
|
||||||
|
<input type="hidden" name="enable_tare_weight_handling" value="0">
|
||||||
|
<input @if($mode == 'edit' && $product->enable_tare_weight_handling == 1) checked @endif class="form-check-input" type="checkbox" id="enable_tare_weight_handling" name="enable_tare_weight_handling" value="1">
|
||||||
|
<label class="form-check-label" for="enable_tare_weight_handling">{{ $L('Enable tare weight handling') }}
|
||||||
|
<span class="text-muted small">{{ $L('This is useful e.g. for flour in jars - on purchase/consume/inventory you always weigh the whole jar, the amount to be posted is then automatically calculated based on what is in stock and the tare weight defined below') }}</span>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
@php if($mode == 'edit') { $value = $product->tare_weight; } else { $value = 0; } @endphp
|
||||||
|
@php if(($mode == 'edit' && $product->enable_tare_weight_handling == 0) || $mode == 'create') { $additionalAttributes = 'disabled'; } else { $additionalAttributes = ''; } @endphp
|
||||||
|
@include('components.numberpicker', array(
|
||||||
|
'id' => 'tare_weight',
|
||||||
|
'label' => 'Tare weight',
|
||||||
|
'min' => 0,
|
||||||
|
'step' => 0.01,
|
||||||
|
'value' => $value,
|
||||||
|
'invalidFeedback' => $L('This cannot be lower than #1', '0'),
|
||||||
|
'additionalAttributes' => $additionalAttributes,
|
||||||
|
'hintId' => 'tare_weight_qu_info'
|
||||||
|
))
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="product-picture">{{ $L('Product picture') }}
|
<label for="product-picture">{{ $L('Product picture') }}
|
||||||
<span class="text-muted small">{{ $L('If you don\'t select a file, the current picture will not be altered') }}</span>
|
<span class="text-muted small">{{ $L('If you don\'t select a file, the current picture will not be altered') }}</span>
|
||||||
|
@@ -35,7 +35,8 @@
|
|||||||
'label' => 'Amount',
|
'label' => 'Amount',
|
||||||
'hintId' => 'amount_qu_unit',
|
'hintId' => 'amount_qu_unit',
|
||||||
'min' => 1,
|
'min' => 1,
|
||||||
'invalidFeedback' => $L('The amount cannot be lower than #1', '1')
|
'invalidFeedback' => $L('The amount cannot be lower than #1', '1'),
|
||||||
|
'additionalHtmlContextHelp' => '<div id="tare-weight-handling-info" class="text-info font-italic d-none">' . $L('Tare weight handling enabled - please weigh the whole container, the amount to be posted will be automatically calculcated') . '</div>'
|
||||||
))
|
))
|
||||||
|
|
||||||
@include('components.numberpicker', array(
|
@include('components.numberpicker', array(
|
||||||
|
@@ -88,7 +88,7 @@
|
|||||||
<span class="small text-muted">{{ $L('Based on the prices of the last purchase per product') }}</span>
|
<span class="small text-muted">{{ $L('Based on the prices of the last purchase per product') }}</span>
|
||||||
</label>
|
</label>
|
||||||
<p class="font-weight-bold font-italic">
|
<p class="font-weight-bold font-italic">
|
||||||
<span class="local-number-format" data-format="currency">{{ $totalRecipeCosts }}</span> {{ GROCY_CURRENCY }}
|
<span class="locale-number-format" data-format="currency">{{ $totalRecipeCosts }}</span> {{ GROCY_CURRENCY }}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
Reference in New Issue
Block a user