mirror of
https://github.com/grocy/grocy.git
synced 2026-04-05 20:36:15 +02:00
Various small changes (code style, missing OpenAPI endpoint, remove location_id null checking)
This commit is contained in:
parent
048312dd9b
commit
77d172d3e8
|
|
@ -1130,7 +1130,7 @@
|
|||
},
|
||||
"/stock/products/{productId}/locations": {
|
||||
"get": {
|
||||
"summary": "Returns all locations with current stock",
|
||||
"summary": "Returns all locations where the given product currently has stock",
|
||||
"tags": [
|
||||
"Stock"
|
||||
],
|
||||
|
|
@ -1427,7 +1427,7 @@
|
|||
},
|
||||
"/stock/products/{productId}/transfer": {
|
||||
"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": [
|
||||
"Stock"
|
||||
],
|
||||
|
|
@ -1451,31 +1451,27 @@
|
|||
"properties": {
|
||||
"amount": {
|
||||
"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": {
|
||||
"$ref": "#/components/internalSchemas/StockTransactionType"
|
||||
},
|
||||
"location_from_id": {
|
||||
"location_id_from": {
|
||||
"type": "number",
|
||||
"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",
|
||||
"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": {
|
||||
"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": {
|
||||
"amount": 1,
|
||||
"transaction_type": "transfer",
|
||||
"location_from_id": 1,
|
||||
"location_to_id": 2
|
||||
"location_id_from": 1,
|
||||
"location_id_to": 2
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1493,7 +1489,7 @@
|
|||
}
|
||||
},
|
||||
"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": {
|
||||
"application/json": {
|
||||
"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": {
|
||||
"post": {
|
||||
"summary": "Inventories the by its barcode given product (adds/removes based on the given new amount)",
|
||||
|
|
|
|||
|
|
@ -15,13 +15,14 @@ BEGIN
|
|||
END;
|
||||
|
||||
DROP VIEW stock_current_locations;
|
||||
CREATE VIEW stock_current_locations AS
|
||||
SELECT
|
||||
s.id,
|
||||
CREATE VIEW stock_current_locations
|
||||
AS
|
||||
SELECT
|
||||
1 AS id, -- Dummy, LessQL needs an id column
|
||||
s.product_id,
|
||||
IFNULL(s.location_id, p.location_id) AS location_id,
|
||||
l.name AS name
|
||||
FROM stock s
|
||||
JOIN products p ON s.product_id = p.id
|
||||
JOIN locations l on IFNULL(s.location_id, p.location_id) = l.id
|
||||
GROUP BY s.product_id, IFNULL(s.location_id, p.location_id);
|
||||
s.location_id AS location_id,
|
||||
l.name AS location_name
|
||||
FROM stock s
|
||||
JOIN locations l
|
||||
ON s.location_id = l.id
|
||||
GROUP BY s.product_id, s.location_id, l.name;
|
||||
|
|
|
|||
|
|
@ -90,7 +90,6 @@
|
|||
}
|
||||
else
|
||||
{
|
||||
|
||||
Grocy.FrontendHelpers.EndUiBusy("consume-form");
|
||||
toastr.success(successMessage);
|
||||
|
||||
|
|
@ -187,56 +186,48 @@ $("#location_id").on('change', function(e)
|
|||
var sumValue = 0;
|
||||
$("#specific_stock_entry").find("option").remove().end().append("<option></option>");
|
||||
if ($("#use_specific_stock_entry").is(":checked"))
|
||||
{
|
||||
$("#use_specific_stock_entry").click();
|
||||
}
|
||||
{
|
||||
$("#use_specific_stock_entry").click();
|
||||
}
|
||||
|
||||
if (locationId)
|
||||
{
|
||||
Grocy.Api.Get("stock/products/" + Grocy.Components.ProductPicker.GetValue() + '/entries',
|
||||
function(stockEntries)
|
||||
{
|
||||
stockEntries.forEach(stockEntry =>
|
||||
{
|
||||
var openTxt = __t("Not opened");
|
||||
if (stockEntry.open == 1)
|
||||
{
|
||||
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);
|
||||
}
|
||||
Grocy.Api.Get("stock/products/" + Grocy.Components.ProductPicker.GetValue() + '/entries',
|
||||
function(stockEntries)
|
||||
{
|
||||
stockEntries.forEach(stockEntry =>
|
||||
{
|
||||
var openTxt = __t("Not opened");
|
||||
if (stockEntry.open == 1)
|
||||
{
|
||||
openTxt = __t("Opened");
|
||||
}
|
||||
|
||||
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);
|
||||
if (sumValue == 0)
|
||||
{
|
||||
$("#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));
|
||||
}
|
||||
},
|
||||
function(xhr)
|
||||
{
|
||||
console.error(xhr);
|
||||
}
|
||||
);
|
||||
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);
|
||||
}
|
||||
});
|
||||
$("#amount").attr("max", sumValue);
|
||||
if (sumValue == 0)
|
||||
{
|
||||
$("#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));
|
||||
}
|
||||
},
|
||||
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);
|
||||
|
||||
$("#location_id").find("option").remove().end().append("<option></option>");
|
||||
Grocy.Api.Get("stock/products/" + productId + '/locations',
|
||||
function(stockLocations)
|
||||
{
|
||||
var setDefault = 0;
|
||||
stockLocations.forEach(stockLocation =>
|
||||
{
|
||||
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 {
|
||||
Grocy.Api.Get("stock/products/" + productId + '/locations',
|
||||
function(stockLocations)
|
||||
{
|
||||
var setDefault = 0;
|
||||
stockLocations.forEach(stockLocation =>
|
||||
{
|
||||
if (productDetails.location.id == stockLocation.location_id) {
|
||||
$("#location_id").append($("<option>", {
|
||||
value: stockLocation.location_id,
|
||||
text: __t("%1$s", stockLocation.name)
|
||||
}));
|
||||
}
|
||||
if (setDefault == 0) {
|
||||
value: stockLocation.location_id,
|
||||
text: __t("%1$s (default location)", stockLocation.location_name)
|
||||
}));
|
||||
$("#location_id").val(productDetails.location.id);
|
||||
$("#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").trigger('change');
|
||||
}
|
||||
});
|
||||
},
|
||||
function(xhr)
|
||||
{
|
||||
console.error(xhr);
|
||||
}
|
||||
);
|
||||
$("#location_id").trigger('change');
|
||||
}
|
||||
});
|
||||
},
|
||||
function(xhr)
|
||||
{
|
||||
console.error(xhr);
|
||||
}
|
||||
);
|
||||
|
||||
if (productDetails.product.allow_partial_units_in_stock == 1)
|
||||
{
|
||||
|
|
@ -405,7 +400,9 @@ $("#specific_stock_entry").on("change", function(e)
|
|||
if (sumValue == 0)
|
||||
{
|
||||
$("#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));
|
||||
}
|
||||
},
|
||||
|
|
@ -414,7 +411,9 @@ $("#specific_stock_entry").on("change", function(e)
|
|||
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").attr("max", $('option:selected', this).attr('amount'));
|
||||
}
|
||||
|
|
@ -431,7 +430,7 @@ $("#use_specific_stock_entry").on("change", function()
|
|||
}
|
||||
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").removeAttr("required");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
||||
|
|
|
|||
|
|
@ -139,24 +139,29 @@ Grocy.Components.ProductPicker.GetPicker().on('change', function(e)
|
|||
Grocy.Api.Get("stock/products/" + productId + '/locations',
|
||||
function(stockLocations)
|
||||
{
|
||||
var setDefault = 0;
|
||||
var setDefault = 0;
|
||||
stockLocations.forEach(stockLocation =>
|
||||
{
|
||||
if (productDetails.location.id == stockLocation.location_id) {
|
||||
if (productDetails.location.id == stockLocation.location_id)
|
||||
{
|
||||
$("#location_id_from").append($("<option>", {
|
||||
value: stockLocation.location_id,
|
||||
text: __t("%1$s (default location)", stockLocation.name)
|
||||
}));
|
||||
value: stockLocation.location_id,
|
||||
text: __t("%1$s (default location)", stockLocation.location_name)
|
||||
}));
|
||||
$("#location_id_from").val(productDetails.location.id);
|
||||
$("#location_id_from").trigger('change');
|
||||
setDefault = 1;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
$("#location_id_from").append($("<option>", {
|
||||
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").trigger('change');
|
||||
}
|
||||
|
|
@ -256,22 +261,14 @@ $("#location_id_from").on('change', function(e)
|
|||
}));
|
||||
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);
|
||||
if (sumValue == 0)
|
||||
{
|
||||
$("#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));
|
||||
}
|
||||
},
|
||||
|
|
@ -345,7 +342,9 @@ $("#specific_stock_entry").on("change", function(e)
|
|||
if (sumValue == 0)
|
||||
{
|
||||
$("#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));
|
||||
}
|
||||
},
|
||||
|
|
@ -354,7 +353,9 @@ $("#specific_stock_entry").on("change", function(e)
|
|||
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").attr("max", $('option:selected', this).attr('amount'));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -141,7 +141,7 @@
|
|||
<i class="fas fa-utensils"></i> {{ $__t('Consume') }}
|
||||
</a>
|
||||
@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 }}">
|
||||
<i class="fas fa-exchange-alt"></i> {{ $__t('Transfer') }}
|
||||
</a>
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user