mirror of
https://github.com/grocy/grocy.git
synced 2025-04-29 01:32:38 +00:00
Squashed commit
Improved locale number display on stockoverview page Fixed choresoverview chore execution color highlighting Highlight recipe ingredients based on the new due score (references #1813) Reworked current price handling views (mostly needed for recipes)
This commit is contained in:
parent
fbb84277bf
commit
cd60c239af
@ -5,7 +5,7 @@
|
|||||||
### New feature: Notes and Userfields for stock entries
|
### New feature: Notes and Userfields for stock entries
|
||||||
|
|
||||||
- Stock entries can now have notes
|
- Stock entries can now have notes
|
||||||
- For example to distinguish between same, yet different products (e.g. having only a generic product "Chocolate" and note in that field what special one it is exactly this time)
|
- For example to distinguish between same, yet different products (e.g. having only a generic product "Chocolate" and note in that field what special one it is exactly this time - an alternative to have sub products)
|
||||||
- => New field on the purchase and inventory page
|
- => New field on the purchase and inventory page
|
||||||
- => New column on the stock entries and stock journal page
|
- => New column on the stock entries and stock journal page
|
||||||
- => Visible also in the "Use a specific stock item" dropdown on the consume and transfer page
|
- => Visible also in the "Use a specific stock item" dropdown on the consume and transfer page
|
||||||
@ -22,6 +22,7 @@
|
|||||||
- 10 points per overdue ingredient
|
- 10 points per overdue ingredient
|
||||||
- 20 points per expired ingredient
|
- 20 points per expired ingredient
|
||||||
- (or else 0)
|
- (or else 0)
|
||||||
|
- The corresponding ingredient is also highlighted in red/yellow/grey (same colors as on the stock overview page)
|
||||||
|
|
||||||
### Stock
|
### Stock
|
||||||
|
|
||||||
@ -89,3 +90,4 @@
|
|||||||
|
|
||||||
- Added a new endpoint `GET /stock/locations/{locationId}/entries` to get all stock entries of a given location (similar to the already existing endpoint `GET /stock/products/{productId}/entries`)
|
- Added a new endpoint `GET /stock/locations/{locationId}/entries` to get all stock entries of a given location (similar to the already existing endpoint `GET /stock/products/{productId}/entries`)
|
||||||
- Endpoint `/recipes/{recipeId}/consume`: Fixed that consuming partially fulfilled recipes was possible, although an error was already returned in that case (and potentially some of the in-stock ingredients were consumed in fact)
|
- Endpoint `/recipes/{recipeId}/consume`: Fixed that consuming partially fulfilled recipes was possible, although an error was already returned in that case (and potentially some of the in-stock ingredients were consumed in fact)
|
||||||
|
- Endpoint `/stock/products/{productId}`: The property/field `oldest_price` has been removed (as this had no real sense)
|
||||||
|
@ -4756,9 +4756,6 @@
|
|||||||
"avg_price": {
|
"avg_price": {
|
||||||
"type": "number"
|
"type": "number"
|
||||||
},
|
},
|
||||||
"oldest_price": {
|
|
||||||
"type": "number"
|
|
||||||
},
|
|
||||||
"last_shopping_location_id": {
|
"last_shopping_location_id": {
|
||||||
"type": "integer"
|
"type": "integer"
|
||||||
},
|
},
|
||||||
@ -4829,7 +4826,6 @@
|
|||||||
},
|
},
|
||||||
"last_price": null,
|
"last_price": null,
|
||||||
"avg_price": null,
|
"avg_price": null,
|
||||||
"oldest_price": null,
|
|
||||||
"last_shopping_location_id": null,
|
"last_shopping_location_id": null,
|
||||||
"next_due_date": "2019-07-07",
|
"next_due_date": "2019-07-07",
|
||||||
"location": {
|
"location": {
|
||||||
|
170
migrations/0179.sql
Normal file
170
migrations/0179.sql
Normal file
@ -0,0 +1,170 @@
|
|||||||
|
CREATE VIEW stock_next_use
|
||||||
|
AS
|
||||||
|
|
||||||
|
/*
|
||||||
|
The default consume rule is:
|
||||||
|
Opened first, then first due first, then first in first out
|
||||||
|
|
||||||
|
This orders the stock entries by that
|
||||||
|
=> Lowest "priority" per product = the stock entry to use next
|
||||||
|
*/
|
||||||
|
|
||||||
|
SELECT
|
||||||
|
-1, -- Dummy
|
||||||
|
ROW_NUMBER() OVER(PARTITION BY product_id ORDER BY open DESC, best_before_date ASC, purchased_date ASC) AS priority,
|
||||||
|
product_id,
|
||||||
|
stock_id,
|
||||||
|
price
|
||||||
|
FROM stock;
|
||||||
|
|
||||||
|
CREATE VIEW products_current_price
|
||||||
|
AS
|
||||||
|
|
||||||
|
/*
|
||||||
|
Current price per product,
|
||||||
|
based on the stock entry to use next,
|
||||||
|
or on the last price if the product is currently not in stock
|
||||||
|
*/
|
||||||
|
|
||||||
|
SELECT
|
||||||
|
-1, -- Dummy,
|
||||||
|
p.id AS product_id,
|
||||||
|
IFNULL(snu.price, plp.price) AS price
|
||||||
|
FROM products p
|
||||||
|
LEFT JOIN (
|
||||||
|
SELECT
|
||||||
|
product_id,
|
||||||
|
MIN(priority),
|
||||||
|
price -- Bare column, ref https://www.sqlite.org/lang_select.html#bare_columns_in_an_aggregate_query
|
||||||
|
FROM stock_next_use
|
||||||
|
GROUP BY product_id
|
||||||
|
) snu
|
||||||
|
ON p.id = snu.product_id
|
||||||
|
LEFT JOIN products_last_purchased plp
|
||||||
|
ON p.id = plp.product_id;
|
||||||
|
|
||||||
|
DROP VIEW products_oldest_stock_unit_price;
|
||||||
|
|
||||||
|
DROP VIEW recipes_pos_resolved;
|
||||||
|
CREATE VIEW recipes_pos_resolved
|
||||||
|
AS
|
||||||
|
|
||||||
|
-- Multiplication by 1.0 to force conversion to float (REAL)
|
||||||
|
|
||||||
|
SELECT
|
||||||
|
r.id AS recipe_id,
|
||||||
|
rp.id AS recipe_pos_id,
|
||||||
|
rp.product_id AS product_id,
|
||||||
|
CASE WHEN rnr.recipe_id = rnr.includes_recipe_id THEN rp.amount * ((r.desired_servings*1.0) / (r.base_servings*1.0)) ELSE rp.amount * ((r.desired_servings*1.0) / (r.base_servings*1.0)) * ((rnr.includes_servings*1.0) / (rnrr.base_servings*1.0)) END AS recipe_amount,
|
||||||
|
IFNULL(sc.amount_aggregated, 0) AS stock_amount,
|
||||||
|
CASE WHEN IFNULL(sc.amount_aggregated, 0) >= CASE WHEN rp.only_check_single_unit_in_stock = 1 THEN 0.00000001 ELSE CASE WHEN rnr.recipe_id = rnr.includes_recipe_id THEN rp.amount * ((r.desired_servings*1.0) / (r.base_servings*1.0)) ELSE rp.amount * ((r.desired_servings*1.0) / (r.base_servings*1.0)) * ((rnr.includes_servings*1.0) / (rnrr.base_servings*1.0)) END END THEN 1 ELSE 0 END AS need_fulfilled,
|
||||||
|
CASE WHEN IFNULL(sc.amount_aggregated, 0) - CASE WHEN rp.only_check_single_unit_in_stock = 1 THEN 0.00000001 ELSE CASE WHEN rnr.recipe_id = rnr.includes_recipe_id THEN rp.amount * ((r.desired_servings*1.0) / (r.base_servings*1.0)) ELSE rp.amount * ((r.desired_servings*1.0) / (r.base_servings*1.0)) * ((rnr.includes_servings*1.0) / (rnrr.base_servings*1.0)) END END < 0 THEN ABS(IFNULL(sc.amount_aggregated, 0) - (CASE WHEN rnr.recipe_id = rnr.includes_recipe_id THEN rp.amount * ((r.desired_servings*1.0) / (r.base_servings*1.0)) ELSE rp.amount * ((r.desired_servings*1.0) / (r.base_servings*1.0)) * ((rnr.includes_servings*1.0) / (rnrr.base_servings*1.0)) END)) ELSE 0 END AS missing_amount,
|
||||||
|
IFNULL(sl.amount, 0) * p.qu_factor_purchase_to_stock AS amount_on_shopping_list,
|
||||||
|
CASE WHEN ROUND(IFNULL(sc.amount_aggregated, 0) + (CASE WHEN r.not_check_shoppinglist = 1 THEN 0 ELSE IFNULL(sl.amount, 0) END * p.qu_factor_purchase_to_stock), 2) >= ROUND(CASE WHEN rp.only_check_single_unit_in_stock = 1 THEN 0.00000001 ELSE CASE WHEN rnr.recipe_id = rnr.includes_recipe_id THEN rp.amount * ((r.desired_servings*1.0) / (r.base_servings*1.0)) ELSE rp.amount * ((r.desired_servings*1.0) / (r.base_servings*1.0)) * ((rnr.includes_servings*1.0) / (rnrr.base_servings*1.0)) END END, 2) THEN 1 ELSE 0 END AS need_fulfilled_with_shopping_list,
|
||||||
|
rp.qu_id,
|
||||||
|
(r.desired_servings*1.0 / r.base_servings*1.0) * (rnr.includes_servings*1.0 / CASE WHEN rnr.recipe_id != rnr.includes_recipe_id THEN rnrr.base_servings*1.0 ELSE 1 END) * rp.amount * IFNULL(pcp.price, 0) * rp.price_factor * CASE WHEN rp.only_check_single_unit_in_stock = 1 THEN IFNULL(qucr.factor, 1) ELSE 1 END AS costs,
|
||||||
|
CASE WHEN rnr.recipe_id = rnr.includes_recipe_id THEN 0 ELSE 1 END AS is_nested_recipe_pos,
|
||||||
|
rp.ingredient_group,
|
||||||
|
pg.name as product_group,
|
||||||
|
rp.id, -- Just a dummy id column
|
||||||
|
r.type as recipe_type,
|
||||||
|
rnr.includes_recipe_id as child_recipe_id,
|
||||||
|
rp.note,
|
||||||
|
rp.variable_amount AS recipe_variable_amount,
|
||||||
|
rp.only_check_single_unit_in_stock,
|
||||||
|
rp.amount / r.base_servings*1.0 * (rnr.includes_servings*1.0 / CASE WHEN rnr.recipe_id != rnr.includes_recipe_id THEN rnrr.base_servings*1.0 ELSE 1 END) * IFNULL(p.calories, 0) * CASE WHEN rp.only_check_single_unit_in_stock = 1 THEN IFNULL(qucr.factor, 1) ELSE 1 END AS calories,
|
||||||
|
p.active AS product_active,
|
||||||
|
CASE pvs.current_due_status
|
||||||
|
WHEN 'ok' THEN 0
|
||||||
|
WHEN 'due_soon' THEN 1
|
||||||
|
WHEN 'overdue' THEN 10
|
||||||
|
WHEN 'expired' THEN 20
|
||||||
|
END AS due_score
|
||||||
|
FROM recipes r
|
||||||
|
JOIN recipes_nestings_resolved rnr
|
||||||
|
ON r.id = rnr.recipe_id
|
||||||
|
JOIN recipes rnrr
|
||||||
|
ON rnr.includes_recipe_id = rnrr.id
|
||||||
|
JOIN recipes_pos rp
|
||||||
|
ON rnr.includes_recipe_id = rp.recipe_id
|
||||||
|
JOIN products p
|
||||||
|
ON rp.product_id = p.id
|
||||||
|
JOIN products_volatile_status pvs
|
||||||
|
ON rp.product_id = pvs.product_id
|
||||||
|
LEFT JOIN product_groups pg
|
||||||
|
ON p.product_group_id = pg.id
|
||||||
|
LEFT JOIN (
|
||||||
|
SELECT product_id, SUM(amount) AS amount
|
||||||
|
FROM shopping_list
|
||||||
|
GROUP BY product_id) sl
|
||||||
|
ON rp.product_id = sl.product_id
|
||||||
|
LEFT JOIN stock_current sc
|
||||||
|
ON rp.product_id = sc.product_id
|
||||||
|
LEFT JOIN products_current_price pcp
|
||||||
|
ON rp.product_id = pcp.product_id
|
||||||
|
LEFT JOIN quantity_unit_conversions_resolved qucr
|
||||||
|
ON rp.product_id = qucr.product_id
|
||||||
|
AND rp.qu_id = qucr.from_qu_id
|
||||||
|
AND p.qu_id_stock = qucr.to_qu_id
|
||||||
|
WHERE rp.not_check_stock_fulfillment = 0
|
||||||
|
|
||||||
|
UNION
|
||||||
|
|
||||||
|
-- Just add all recipe positions which should not be checked against stock with fulfilled need
|
||||||
|
|
||||||
|
SELECT
|
||||||
|
r.id AS recipe_id,
|
||||||
|
rp.id AS recipe_pos_id,
|
||||||
|
rp.product_id AS product_id,
|
||||||
|
CASE WHEN rnr.recipe_id = rnr.includes_recipe_id THEN rp.amount * ((r.desired_servings*1.0) / (r.base_servings*1.0)) ELSE rp.amount * ((r.desired_servings*1.0) / (r.base_servings*1.0)) * ((rnr.includes_servings*1.0) / (rnrr.base_servings*1.0)) END AS recipe_amount,
|
||||||
|
IFNULL(sc.amount_aggregated, 0) AS stock_amount,
|
||||||
|
1 AS need_fulfilled,
|
||||||
|
0 AS missing_amount,
|
||||||
|
IFNULL(sl.amount, 0) * p.qu_factor_purchase_to_stock AS amount_on_shopping_list,
|
||||||
|
1 AS need_fulfilled_with_shopping_list,
|
||||||
|
rp.qu_id,
|
||||||
|
(r.desired_servings*1.0 / r.base_servings*1.0) * (rnr.includes_servings*1.0 / CASE WHEN rnr.recipe_id != rnr.includes_recipe_id THEN rnrr.base_servings*1.0 ELSE 1 END) * rp.amount * IFNULL(pcp.price, 0) * rp.price_factor * CASE WHEN rp.only_check_single_unit_in_stock = 1 THEN IFNULL(qucr.factor, 1) ELSE 1 END AS costs,
|
||||||
|
CASE WHEN rnr.recipe_id = rnr.includes_recipe_id THEN 0 ELSE 1 END AS is_nested_recipe_pos,
|
||||||
|
rp.ingredient_group,
|
||||||
|
pg.name as product_group,
|
||||||
|
rp.id, -- Just a dummy id column
|
||||||
|
r.type as recipe_type,
|
||||||
|
rnr.includes_recipe_id as child_recipe_id,
|
||||||
|
rp.note,
|
||||||
|
rp.variable_amount AS recipe_variable_amount,
|
||||||
|
rp.only_check_single_unit_in_stock,
|
||||||
|
rp.amount / r.base_servings*1.0 * (rnr.includes_servings*1.0 / CASE WHEN rnr.recipe_id != rnr.includes_recipe_id THEN rnrr.base_servings*1.0 ELSE 1 END) * IFNULL(p.calories, 0) * CASE WHEN rp.only_check_single_unit_in_stock = 1 THEN IFNULL(qucr.factor, 1) ELSE 1 END AS calories,
|
||||||
|
p.active AS product_active,
|
||||||
|
CASE pvs.current_due_status
|
||||||
|
WHEN 'ok' THEN 0
|
||||||
|
WHEN 'due_soon' THEN 1
|
||||||
|
WHEN 'overdue' THEN 10
|
||||||
|
WHEN 'expired' THEN 20
|
||||||
|
END AS due_score
|
||||||
|
FROM recipes r
|
||||||
|
JOIN recipes_nestings_resolved rnr
|
||||||
|
ON r.id = rnr.recipe_id
|
||||||
|
JOIN recipes rnrr
|
||||||
|
ON rnr.includes_recipe_id = rnrr.id
|
||||||
|
JOIN recipes_pos rp
|
||||||
|
ON rnr.includes_recipe_id = rp.recipe_id
|
||||||
|
JOIN products p
|
||||||
|
ON rp.product_id = p.id
|
||||||
|
JOIN products_volatile_status pvs
|
||||||
|
ON rp.product_id = pvs.product_id
|
||||||
|
LEFT JOIN product_groups pg
|
||||||
|
ON p.product_group_id = pg.id
|
||||||
|
LEFT JOIN (
|
||||||
|
SELECT product_id, SUM(amount) AS amount
|
||||||
|
FROM shopping_list
|
||||||
|
GROUP BY product_id) sl
|
||||||
|
ON rp.product_id = sl.product_id
|
||||||
|
LEFT JOIN stock_current sc
|
||||||
|
ON rp.product_id = sc.product_id
|
||||||
|
LEFT JOIN products_current_price pcp
|
||||||
|
ON rp.product_id = pcp.product_id
|
||||||
|
LEFT JOIN quantity_unit_conversions_resolved qucr
|
||||||
|
ON rp.product_id = qucr.product_id
|
||||||
|
AND rp.qu_id = qucr.from_qu_id
|
||||||
|
AND p.qu_id_stock = qucr.to_qu_id
|
||||||
|
WHERE rp.not_check_stock_fulfillment = 1;
|
@ -123,17 +123,24 @@ $(document).on('click', '.track-chore-button', function(e)
|
|||||||
{
|
{
|
||||||
var choreRow = $('#chore-' + choreId + '-row');
|
var choreRow = $('#chore-' + choreId + '-row');
|
||||||
var nextXDaysThreshold = moment().add($("#info-due-soon-chores").data("next-x-days"), "days");
|
var nextXDaysThreshold = moment().add($("#info-due-soon-chores").data("next-x-days"), "days");
|
||||||
|
var todayThreshold = moment().endOf("day");
|
||||||
var now = moment();
|
var now = moment();
|
||||||
var nextExecutionTime = moment(result.next_estimated_execution_time);
|
var nextExecutionTime = moment(result.next_estimated_execution_time);
|
||||||
|
|
||||||
choreRow.removeClass("table-warning");
|
choreRow.removeClass("table-warning");
|
||||||
choreRow.removeClass("table-danger");
|
choreRow.removeClass("table-danger");
|
||||||
|
choreRow.removeClass("table-info");
|
||||||
$('#chore-' + choreId + '-due-filter-column').html("");
|
$('#chore-' + choreId + '-due-filter-column').html("");
|
||||||
if (nextExecutionTime.isBefore(now))
|
if (nextExecutionTime.isBefore(now))
|
||||||
{
|
{
|
||||||
choreRow.addClass("table-danger");
|
choreRow.addClass("table-danger");
|
||||||
$('#chore-' + choreId + '-due-filter-column').html("overdue");
|
$('#chore-' + choreId + '-due-filter-column').html("overdue");
|
||||||
}
|
}
|
||||||
|
else if (nextExecutionTime.isSameOrBefore(todayThreshold))
|
||||||
|
{
|
||||||
|
choreRow.addClass("table-info");
|
||||||
|
$('#chore-' + choreId + '-due-filter-column').html("duetoday");
|
||||||
|
}
|
||||||
else if (nextExecutionTime.isBefore(nextXDaysThreshold))
|
else if (nextExecutionTime.isBefore(nextXDaysThreshold))
|
||||||
{
|
{
|
||||||
choreRow.addClass("table-warning");
|
choreRow.addClass("table-warning");
|
||||||
@ -332,7 +339,6 @@ $("#reschedule-chore-clear-button").on("click", function(e)
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
if (GetUriParam("user") !== undefined)
|
if (GetUriParam("user") !== undefined)
|
||||||
{
|
{
|
||||||
$("#user-filter").val("xx" + GetUriParam("user") + "xx");
|
$("#user-filter").val("xx" + GetUriParam("user") + "xx");
|
||||||
|
@ -696,7 +696,6 @@ class StockService extends BaseService
|
|||||||
$lastPrice = null;
|
$lastPrice = null;
|
||||||
$lastShoppingLocation = null;
|
$lastShoppingLocation = null;
|
||||||
$avgPrice = null;
|
$avgPrice = null;
|
||||||
$oldestPrice = null;
|
|
||||||
if ($productLastPurchased)
|
if ($productLastPurchased)
|
||||||
{
|
{
|
||||||
$lastPurchasedDate = $productLastPurchased->purchased_date;
|
$lastPurchasedDate = $productLastPurchased->purchased_date;
|
||||||
@ -707,11 +706,6 @@ class StockService extends BaseService
|
|||||||
{
|
{
|
||||||
$avgPrice = $avgPriceRow->price;
|
$avgPrice = $avgPriceRow->price;
|
||||||
}
|
}
|
||||||
$oldestPriceRow = $this->getDatabase()->products_oldest_stock_unit_price()->where('product_id', $productId)->fetch();
|
|
||||||
if ($oldestPriceRow)
|
|
||||||
{
|
|
||||||
$oldestPrice = $avgPriceRow->price;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$product = $this->getDatabase()->products($productId);
|
$product = $this->getDatabase()->products($productId);
|
||||||
@ -746,7 +740,6 @@ class StockService extends BaseService
|
|||||||
'quantity_unit_stock' => $quStock,
|
'quantity_unit_stock' => $quStock,
|
||||||
'last_price' => $lastPrice,
|
'last_price' => $lastPrice,
|
||||||
'avg_price' => $avgPrice,
|
'avg_price' => $avgPrice,
|
||||||
'oldest_price' => $oldestPrice,
|
|
||||||
'last_shopping_location_id' => $lastShoppingLocation,
|
'last_shopping_location_id' => $lastShoppingLocation,
|
||||||
'default_shopping_location_id' => $product->shopping_location_id,
|
'default_shopping_location_id' => $product->shopping_location_id,
|
||||||
'next_due_date' => $nextDueDate,
|
'next_due_date' => $nextDueDate,
|
||||||
|
@ -478,12 +478,14 @@
|
|||||||
$selectedRecipePosition->recipe_amount = $selectedRecipePosition->recipe_amount * $productQuConversion->factor;
|
$selectedRecipePosition->recipe_amount = $selectedRecipePosition->recipe_amount * $productQuConversion->factor;
|
||||||
}
|
}
|
||||||
@endphp
|
@endphp
|
||||||
@if(!empty($selectedRecipePosition->recipe_variable_amount))
|
<span class="@if($selectedRecipePosition->due_score == 20) text-danger @elseif($selectedRecipePosition->due_score == 10) text-secondary @elseif($selectedRecipePosition->due_score == 1) text-warning @endif">
|
||||||
{{ $selectedRecipePosition->recipe_variable_amount }}
|
@if(!empty($selectedRecipePosition->recipe_variable_amount))
|
||||||
@else
|
{{ $selectedRecipePosition->recipe_variable_amount }}
|
||||||
<span class="locale-number locale-number-quantity-amount">@if($selectedRecipePosition->recipe_amount == round($selectedRecipePosition->recipe_amount, 2)){{ round($selectedRecipePosition->recipe_amount, 2) }}@else{{ $selectedRecipePosition->recipe_amount }}@endif</span>
|
@else
|
||||||
@endif
|
<span class="locale-number locale-number-quantity-amount">@if($selectedRecipePosition->recipe_amount == round($selectedRecipePosition->recipe_amount, 2)){{ round($selectedRecipePosition->recipe_amount, 2) }}@else{{ $selectedRecipePosition->recipe_amount }}@endif</span>
|
||||||
{{ $__n($selectedRecipePosition->recipe_amount, FindObjectInArrayByPropertyValue($quantityUnits, 'id', $selectedRecipePosition->qu_id)->name, FindObjectInArrayByPropertyValue($quantityUnits, 'id', $selectedRecipePosition->qu_id)->name_plural) }} {{ FindObjectInArrayByPropertyValue($products, 'id', $selectedRecipePosition->product_id)->name }}
|
@endif
|
||||||
|
{{ $__n($selectedRecipePosition->recipe_amount, FindObjectInArrayByPropertyValue($quantityUnits, 'id', $selectedRecipePosition->qu_id)->name, FindObjectInArrayByPropertyValue($quantityUnits, 'id', $selectedRecipePosition->qu_id)->name_plural) }} {{ FindObjectInArrayByPropertyValue($products, 'id', $selectedRecipePosition->product_id)->name }}
|
||||||
|
</span>
|
||||||
@if(GROCY_FEATURE_FLAG_STOCK)
|
@if(GROCY_FEATURE_FLAG_STOCK)
|
||||||
<span class="d-print-none">
|
<span class="d-print-none">
|
||||||
@if($selectedRecipePosition->need_fulfilled == 1)<i class="fas fa-check text-success"></i>@elseif($selectedRecipePosition->need_fulfilled_with_shopping_list == 1)<i class="fas fa-exclamation text-warning"></i>@else<i class="fas fa-times text-danger"></i>@endif
|
@if($selectedRecipePosition->need_fulfilled == 1)<i class="fas fa-check text-success"></i>@elseif($selectedRecipePosition->need_fulfilled_with_shopping_list == 1)<i class="fas fa-exclamation text-warning"></i>@else<i class="fas fa-times text-danger"></i>@endif
|
||||||
|
@ -330,8 +330,12 @@
|
|||||||
<span class="pl-1 text-secondary">
|
<span class="pl-1 text-secondary">
|
||||||
<i class="fas fa-custom-sigma-sign"></i> <span id="product-{{ $currentStockEntry->product_id }}-amount-aggregated"
|
<i class="fas fa-custom-sigma-sign"></i> <span id="product-{{ $currentStockEntry->product_id }}-amount-aggregated"
|
||||||
class="locale-number locale-number-quantity-amount">{{ $currentStockEntry->amount_aggregated }}</span> {{ $__n($currentStockEntry->amount_aggregated, $currentStockEntry->qu_unit_name, $currentStockEntry->qu_unit_name_plural, true) }}
|
class="locale-number locale-number-quantity-amount">{{ $currentStockEntry->amount_aggregated }}</span> {{ $__n($currentStockEntry->amount_aggregated, $currentStockEntry->qu_unit_name, $currentStockEntry->qu_unit_name_plural, true) }}
|
||||||
@if($currentStockEntry->amount_opened_aggregated > 0)<span id="product-{{ $currentStockEntry->product_id }}-opened-amount-aggregated"
|
@if($currentStockEntry->amount_opened_aggregated > 0)
|
||||||
class="small font-italic">{{ $__t('%s opened', $currentStockEntry->amount_opened_aggregated) }}</span>@endif
|
<span id="product-{{ $currentStockEntry->product_id }}-opened-amount-aggregated"
|
||||||
|
class="small font-italic">
|
||||||
|
{!! $__t('%s opened', '<span class="locale-number locale-number-quantity-amount">' . $currentStockEntry->amount_opened_aggregated . '</span>') !!}
|
||||||
|
</span>
|
||||||
|
@endif
|
||||||
</span>
|
</span>
|
||||||
@endif
|
@endif
|
||||||
@if(boolval($userSettings['show_icon_on_stock_overview_page_when_product_is_on_shopping_list']))
|
@if(boolval($userSettings['show_icon_on_stock_overview_page_when_product_is_on_shopping_list']))
|
||||||
|
Loading…
x
Reference in New Issue
Block a user