Various small changes (code style, missing OpenAPI endpoint, remove location_id null checking)

This commit is contained in:
Bernd Bestel 2019-11-04 20:03:33 +01:00 committed by Kurt Riddlesperger
parent 048312dd9b
commit 77d172d3e8
6 changed files with 199 additions and 126 deletions

View File

@ -1130,7 +1130,7 @@
}, },
"/stock/products/{productId}/locations": { "/stock/products/{productId}/locations": {
"get": { "get": {
"summary": "Returns all locations with current stock", "summary": "Returns all locations where the given product currently has stock",
"tags": [ "tags": [
"Stock" "Stock"
], ],
@ -1427,7 +1427,7 @@
}, },
"/stock/products/{productId}/transfer": { "/stock/products/{productId}/transfer": {
"post": { "post": {
"summary": "Transfer the given amount of the given product from stock from one location to another", "summary": "Transfers the given amount of the given product from one location to another (this is currently not supported for tare weight handling enabled products)",
"tags": [ "tags": [
"Stock" "Stock"
], ],
@ -1451,31 +1451,27 @@
"properties": { "properties": {
"amount": { "amount": {
"type": "number", "type": "number",
"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" "description": "The amount to transfer - 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": { "location_id_from": {
"$ref": "#/components/internalSchemas/StockTransactionType"
},
"location_from_id": {
"type": "number", "type": "number",
"format": "integer", "format": "integer",
"description": "Location the stock is transfering from" "description": "A valid location id, the location from where the product should be transfered"
}, },
"location_to_id": { "location_id_to": {
"type": "number", "type": "number",
"format": "integer", "format": "integer",
"description": "Location the stock is transfering to" "description": "A valid location id, the location to where the product should be transfered"
}, },
"stock_entry_id": { "stock_entry_id": {
"type": "string", "type": "string",
"description": "A specific stock entry id to consume, if used, the amount has to be 1" "description": "A specific stock entry id to transfer, if used, the amount has to be 1"
} }
}, },
"example": { "example": {
"amount": 1, "amount": 1,
"transaction_type": "transfer", "location_id_from": 1,
"location_from_id": 1, "location_id_to": 2
"location_to_id": 2
} }
} }
} }
@ -1493,7 +1489,7 @@
} }
}, },
"400": { "400": {
"description": "The operation was not successful (possible errors are: Not existing product, invalid transaction type, given amount > current stock amount)", "description": "The operation was not successful (possible errors are: Not existing product, no existing from or to location, given amount > current stock amount at the source location)",
"content": { "content": {
"application/json": { "application/json": {
"schema": { "schema": {
@ -1847,6 +1843,82 @@
} }
} }
}, },
"/stock/products/by-barcode/{barcode}/transfer": {
"post": {
"summary": "Transfers the given amount of the by its barcode given product from one location to another (this is currently not supported for tare weight handling enabled products)",
"tags": [
"Stock"
],
"parameters": [
{
"in": "path",
"name": "barcode",
"required": true,
"description": "Barcode",
"schema": {
"type": "string"
}
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"amount": {
"type": "number",
"description": "The amount to transfer - 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"
},
"location_id_from": {
"type": "number",
"format": "integer",
"description": "A valid location id, the location from where the product should be transfered"
},
"location_id_to": {
"type": "number",
"format": "integer",
"description": "A valid location id, the location to where the product should be transfered"
},
"stock_entry_id": {
"type": "string",
"description": "A specific stock entry id to transfer, if used, the amount has to be 1"
}
},
"example": {
"amount": 1,
"location_id_from": 1,
"location_id_to": 2
}
}
}
}
},
"responses": {
"200": {
"description": "The operation was successful",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/StockLogEntry"
}
}
}
},
"400": {
"description": "The operation was not successful (possible errors are: Not existing product, no existing from or to location, given amount > current stock amount at the source location)",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/GenericErrorResponse"
}
}
}
}
}
}
},
"/stock/products/by-barcode/{barcode}/inventory": { "/stock/products/by-barcode/{barcode}/inventory": {
"post": { "post": {
"summary": "Inventories the by its barcode given product (adds/removes based on the given new amount)", "summary": "Inventories the by its barcode given product (adds/removes based on the given new amount)",

View File

@ -15,13 +15,14 @@ BEGIN
END; END;
DROP VIEW stock_current_locations; DROP VIEW stock_current_locations;
CREATE VIEW stock_current_locations AS CREATE VIEW stock_current_locations
SELECT AS
s.id, SELECT
1 AS id, -- Dummy, LessQL needs an id column
s.product_id, s.product_id,
IFNULL(s.location_id, p.location_id) AS location_id, s.location_id AS location_id,
l.name AS name l.name AS location_name
FROM stock s FROM stock s
JOIN products p ON s.product_id = p.id JOIN locations l
JOIN locations l on IFNULL(s.location_id, p.location_id) = l.id ON s.location_id = l.id
GROUP BY s.product_id, IFNULL(s.location_id, p.location_id); GROUP BY s.product_id, s.location_id, l.name;

View File

@ -90,7 +90,6 @@
} }
else else
{ {
Grocy.FrontendHelpers.EndUiBusy("consume-form"); Grocy.FrontendHelpers.EndUiBusy("consume-form");
toastr.success(successMessage); toastr.success(successMessage);
@ -187,56 +186,48 @@ $("#location_id").on('change', function(e)
var sumValue = 0; var sumValue = 0;
$("#specific_stock_entry").find("option").remove().end().append("<option></option>"); $("#specific_stock_entry").find("option").remove().end().append("<option></option>");
if ($("#use_specific_stock_entry").is(":checked")) if ($("#use_specific_stock_entry").is(":checked"))
{ {
$("#use_specific_stock_entry").click(); $("#use_specific_stock_entry").click();
} }
if (locationId) if (locationId)
{ {
Grocy.Api.Get("stock/products/" + Grocy.Components.ProductPicker.GetValue() + '/entries', Grocy.Api.Get("stock/products/" + Grocy.Components.ProductPicker.GetValue() + '/entries',
function(stockEntries) function(stockEntries)
{ {
stockEntries.forEach(stockEntry => stockEntries.forEach(stockEntry =>
{ {
var openTxt = __t("Not opened"); var openTxt = __t("Not opened");
if (stockEntry.open == 1) if (stockEntry.open == 1)
{ {
openTxt = __t("Opened"); openTxt = __t("Opened");
} }
if (stockEntry.location_id == locationId)
{
$("#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
}));
sumValue = sumValue + parseFloat(stockEntry.amount);
}
if (stockEntry.location_id === null) if (stockEntry.location_id == locationId)
{ {
$("#specific_stock_entry").append($("<option>", { $("#specific_stock_entry").append($("<option>", {
value: stockEntry.stock_id, value: stockEntry.stock_id,
amount: stockEntry.amount, 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; 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
})); }));
sumValue = sumValue + parseFloat(stockEntry.amount); sumValue = sumValue + parseFloat(stockEntry.amount);
} }
}); });
$("#amount").attr("max", sumValue); $("#amount").attr("max", sumValue);
if (sumValue == 0) if (sumValue == 0)
{ {
$("#amount").parent().find(".invalid-feedback").text(__t('There are no units available at this location')); $("#amount").parent().find(".invalid-feedback").text(__t('There are no units available at this location'));
} else { }
$("#amount").parent().find(".invalid-feedback").text(__t('The amount must be between %1$s and %2$s', "1", sumValue)); else
} {
}, $("#amount").parent().find(".invalid-feedback").text(__t('The amount must be between %1$s and %2$s', "1", sumValue));
function(xhr) }
{ },
console.error(xhr); function(xhr)
} {
); console.error(xhr);
}
);
} }
}); });
@ -261,37 +252,41 @@ Grocy.Components.ProductPicker.GetPicker().on('change', function(e)
$('#amount_qu_unit').text(productDetails.quantity_unit_stock.name); $('#amount_qu_unit').text(productDetails.quantity_unit_stock.name);
$("#location_id").find("option").remove().end().append("<option></option>"); $("#location_id").find("option").remove().end().append("<option></option>");
Grocy.Api.Get("stock/products/" + productId + '/locations', Grocy.Api.Get("stock/products/" + productId + '/locations',
function(stockLocations) function(stockLocations)
{ {
var setDefault = 0; var setDefault = 0;
stockLocations.forEach(stockLocation => stockLocations.forEach(stockLocation =>
{ {
if (productDetails.location.id == stockLocation.location_id) { if (productDetails.location.id == stockLocation.location_id) {
$("#location_id").append($("<option>", {
value: stockLocation.location_id,
text: __t("%1$s (default location)", stockLocation.name)
}));
$("#location_id").val(productDetails.location.id);
$("#location_id").trigger('change');
setDefault = 1;
} else {
$("#location_id").append($("<option>", { $("#location_id").append($("<option>", {
value: stockLocation.location_id, value: stockLocation.location_id,
text: __t("%1$s", stockLocation.name) text: __t("%1$s (default location)", stockLocation.location_name)
})); }));
} $("#location_id").val(productDetails.location.id);
if (setDefault == 0) { $("#location_id").trigger('change');
setDefault = 1;
}
else
{
$("#location_id").append($("<option>", {
value: stockLocation.location_id,
text: __t("%1$s", stockLocation.location_name)
}));
}
if (setDefault == 0)
{
$("#location_id").val(stockLocation.location_id); $("#location_id").val(stockLocation.location_id);
$("#location_id").trigger('change'); $("#location_id").trigger('change');
} }
}); });
}, },
function(xhr) function(xhr)
{ {
console.error(xhr); console.error(xhr);
} }
); );
if (productDetails.product.allow_partial_units_in_stock == 1) if (productDetails.product.allow_partial_units_in_stock == 1)
{ {
@ -405,7 +400,9 @@ $("#specific_stock_entry").on("change", function(e)
if (sumValue == 0) if (sumValue == 0)
{ {
$("#amount").parent().find(".invalid-feedback").text(__t('There are no units available at this location')); $("#amount").parent().find(".invalid-feedback").text(__t('There are no units available at this location'));
} else { }
else
{
$("#amount").parent().find(".invalid-feedback").text(__t('The amount must be between %1$s and %2$s', "1", sumValue)); $("#amount").parent().find(".invalid-feedback").text(__t('The amount must be between %1$s and %2$s', "1", sumValue));
} }
}, },
@ -414,7 +411,9 @@ $("#specific_stock_entry").on("change", function(e)
console.error(xhr); console.error(xhr);
} }
); );
} else { }
else
{
$("#amount").parent().find(".invalid-feedback").text(__t('The amount must be between %1$s and %2$s', "1", $('option:selected', this).attr('amount'))); $("#amount").parent().find(".invalid-feedback").text(__t('The amount must be between %1$s and %2$s', "1", $('option:selected', this).attr('amount')));
$("#amount").attr("max", $('option:selected', this).attr('amount')); $("#amount").attr("max", $('option:selected', this).attr('amount'));
} }
@ -431,7 +430,7 @@ $("#use_specific_stock_entry").on("change", function()
} }
else else
{ {
$("#specific_stock_entry").find("option").remove().end().append("<option></option>"); $("#specific_stock_entry").find("option").remove().end().append("<option></option>");
$("#specific_stock_entry").attr("disabled", ""); $("#specific_stock_entry").attr("disabled", "");
$("#specific_stock_entry").removeAttr("required"); $("#specific_stock_entry").removeAttr("required");
} }

View File

@ -219,7 +219,7 @@ $(document).on("click", ".product-purchase-button", function(e)
}); });
}); });
$(document).on("click", ".product-transfer-custom-amount-button", function(e) $(document).on("click", ".product-transfer-button", function(e)
{ {
e.preventDefault(); e.preventDefault();

View File

@ -139,24 +139,29 @@ Grocy.Components.ProductPicker.GetPicker().on('change', function(e)
Grocy.Api.Get("stock/products/" + productId + '/locations', Grocy.Api.Get("stock/products/" + productId + '/locations',
function(stockLocations) function(stockLocations)
{ {
var setDefault = 0; var setDefault = 0;
stockLocations.forEach(stockLocation => stockLocations.forEach(stockLocation =>
{ {
if (productDetails.location.id == stockLocation.location_id) { if (productDetails.location.id == stockLocation.location_id)
{
$("#location_id_from").append($("<option>", { $("#location_id_from").append($("<option>", {
value: stockLocation.location_id, value: stockLocation.location_id,
text: __t("%1$s (default location)", stockLocation.name) text: __t("%1$s (default location)", stockLocation.location_name)
})); }));
$("#location_id_from").val(productDetails.location.id); $("#location_id_from").val(productDetails.location.id);
$("#location_id_from").trigger('change'); $("#location_id_from").trigger('change');
setDefault = 1; setDefault = 1;
} else { }
else
{
$("#location_id_from").append($("<option>", { $("#location_id_from").append($("<option>", {
value: stockLocation.location_id, value: stockLocation.location_id,
text: __t("%1$s", stockLocation.name) text: __t("%1$s", stockLocation.location_name)
})); }));
} }
if (setDefault == 0) {
if (setDefault == 0)
{
$("#location_id_from").val(stockLocation.location_id); $("#location_id_from").val(stockLocation.location_id);
$("#location_id_from").trigger('change'); $("#location_id_from").trigger('change');
} }
@ -256,22 +261,14 @@ $("#location_id_from").on('change', function(e)
})); }));
sumValue = sumValue + parseFloat(stockEntry.amount); sumValue = sumValue + parseFloat(stockEntry.amount);
} }
if (stockEntry.location_id === null)
{
$("#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
}));
sumValue = sumValue + parseFloat(stockEntry.amount);
}
}); });
$("#amount").attr("max", sumValue); $("#amount").attr("max", sumValue);
if (sumValue == 0) if (sumValue == 0)
{ {
$("#amount").parent().find(".invalid-feedback").text(__t('There are no units available at this location')); $("#amount").parent().find(".invalid-feedback").text(__t('There are no units available at this location'));
} else { }
else
{
$("#amount").parent().find(".invalid-feedback").text(__t('The amount must be between %1$s and %2$s', "1", sumValue)); $("#amount").parent().find(".invalid-feedback").text(__t('The amount must be between %1$s and %2$s', "1", sumValue));
} }
}, },
@ -345,7 +342,9 @@ $("#specific_stock_entry").on("change", function(e)
if (sumValue == 0) if (sumValue == 0)
{ {
$("#amount").parent().find(".invalid-feedback").text(__t('There are no units available at this location')); $("#amount").parent().find(".invalid-feedback").text(__t('There are no units available at this location'));
} else { }
else
{
$("#amount").parent().find(".invalid-feedback").text(__t('The amount must be between %1$s and %2$s', "1", sumValue)); $("#amount").parent().find(".invalid-feedback").text(__t('The amount must be between %1$s and %2$s', "1", sumValue));
} }
}, },
@ -354,7 +353,9 @@ $("#specific_stock_entry").on("change", function(e)
console.error(xhr); console.error(xhr);
} }
); );
} else { }
else
{
$("#amount").parent().find(".invalid-feedback").text(__t('The amount must be between %1$s and %2$s', "1", $('option:selected', this).attr('amount'))); $("#amount").parent().find(".invalid-feedback").text(__t('The amount must be between %1$s and %2$s', "1", $('option:selected', this).attr('amount')));
$("#amount").attr("max", $('option:selected', this).attr('amount')); $("#amount").attr("max", $('option:selected', this).attr('amount'));
} }

View File

@ -141,7 +141,7 @@
<i class="fas fa-utensils"></i> {{ $__t('Consume') }} <i class="fas fa-utensils"></i> {{ $__t('Consume') }}
</a> </a>
@if(GROCY_FEATURE_FLAG_STOCK_LOCATION_TRACKING) @if(GROCY_FEATURE_FLAG_STOCK_LOCATION_TRACKING)
<a class="dropdown-item product-transfer-custom-amount-button @if($currentStockEntry->amount < 1) disabled @endif" type="button" href="#" <a class="dropdown-item product-transfer-button @if($currentStockEntry->amount < 1) disabled @endif" type="button" href="#"
data-product-id="{{ $currentStockEntry->product_id }}"> data-product-id="{{ $currentStockEntry->product_id }}">
<i class="fas fa-exchange-alt"></i> {{ $__t('Transfer') }} <i class="fas fa-exchange-alt"></i> {{ $__t('Transfer') }}
</a> </a>