mirror of
https://github.com/grocy/grocy.git
synced 2025-04-29 01:32:38 +00:00
Optimizations regarding displaying prices (closes #1743)
This commit is contained in:
parent
7ad979cba9
commit
6a50f74a14
@ -28,6 +28,9 @@
|
||||
|
||||
- It's now possible to change a products stock QU, even after it was once added to stock
|
||||
- When the product was once added to stock, there needs to exist a corresponding unit conversion for the new QU
|
||||
- Product card, stock overiew and stock entries page optimizations regarding displaying prices:
|
||||
- Prices are now shown per default purchase quantity unit, instead of per stock QU and when clicking/hovering, a tooltip shows the price per stock QU
|
||||
- The price history chart is now based on the value per purchase QU, instead of per stock QU
|
||||
- New product option "Disable own stock" (defaults to disabled)
|
||||
- When enabled, the corresponding product can't have own stock, means it will not be selectable on purchase (useful for parent products which are just used as a summary/total view of the child products)
|
||||
- The location content sheet can now optionally list also out of stock products (at the products default location, new checkbox "Show only in-stock products " at the top of the page, defaults to enabled)
|
||||
|
64
migrations/0182.sql
Normal file
64
migrations/0182.sql
Normal file
@ -0,0 +1,64 @@
|
||||
DROP VIEW uihelper_stock_current_overview;
|
||||
CREATE VIEW uihelper_stock_current_overview
|
||||
AS
|
||||
SELECT
|
||||
p.id,
|
||||
sc.amount_opened AS amount_opened,
|
||||
p.tare_weight AS tare_weight,
|
||||
p.enable_tare_weight_handling AS enable_tare_weight_handling,
|
||||
sc.amount AS amount,
|
||||
sc.value as value,
|
||||
sc.product_id AS product_id,
|
||||
sc.best_before_date AS best_before_date,
|
||||
EXISTS(SELECT id FROM stock_missing_products WHERE id = sc.product_id) AS product_missing,
|
||||
(SELECT name FROM quantity_units WHERE quantity_units.id = p.qu_id_stock) AS qu_unit_name,
|
||||
(SELECT name_plural FROM quantity_units WHERE quantity_units.id = p.qu_id_stock) AS qu_unit_name_plural,
|
||||
p.name AS product_name,
|
||||
(SELECT name FROM product_groups WHERE product_groups.id = p.product_group_id) AS product_group_name,
|
||||
EXISTS(SELECT * FROM shopping_list WHERE shopping_list.product_id = sc.product_id) AS on_shopping_list,
|
||||
(SELECT name FROM quantity_units WHERE quantity_units.id = p.qu_id_purchase) AS qu_purchase_unit_name,
|
||||
(SELECT name_plural FROM quantity_units WHERE quantity_units.id = p.qu_id_purchase) AS qu_purchase_unit_name_plural,
|
||||
sc.is_aggregated_amount,
|
||||
sc.amount_opened_aggregated,
|
||||
sc.amount_aggregated,
|
||||
p.calories AS product_calories,
|
||||
sc.amount * p.calories AS calories,
|
||||
sc.amount_aggregated * p.calories AS calories_aggregated,
|
||||
p.quick_consume_amount,
|
||||
p.due_type,
|
||||
plp.purchased_date AS last_purchased,
|
||||
plp.price AS last_price,
|
||||
pap.price as average_price,
|
||||
p.min_stock_amount,
|
||||
pbcs.barcodes AS product_barcodes,
|
||||
p.description AS product_description,
|
||||
l.name AS product_default_location_name,
|
||||
p_parent.id AS parent_product_id,
|
||||
p_parent.name AS parent_product_name,
|
||||
p.picture_file_name AS product_picture_file_name,
|
||||
p.no_own_stock AS product_no_own_stock,
|
||||
p.qu_factor_purchase_to_stock AS product_qu_factor_purchase_to_stock
|
||||
FROM (
|
||||
SELECT *
|
||||
FROM stock_current
|
||||
WHERE best_before_date IS NOT NULL
|
||||
UNION
|
||||
SELECT m.id, 0, 0, 0, null, 0, 0, 0, p.due_type
|
||||
FROM stock_missing_products m
|
||||
JOIN products p
|
||||
ON m.id = p.id
|
||||
WHERE m.id NOT IN (SELECT product_id FROM stock_current)
|
||||
) sc
|
||||
LEFT JOIN products_last_purchased plp
|
||||
ON sc.product_id = plp.product_id
|
||||
LEFT JOIN products_average_price pap
|
||||
ON sc.product_id = pap.product_id
|
||||
LEFT JOIN products p
|
||||
ON sc.product_id = p.id
|
||||
LEFT JOIN product_barcodes_comma_separated pbcs
|
||||
ON sc.product_id = pbcs.product_id
|
||||
LEFT JOIN products p_parent
|
||||
ON p.parent_product_id = p_parent.id
|
||||
LEFT JOIN locations l
|
||||
ON p.location_id = l.id
|
||||
WHERE p.hide_on_stock_overview = 0;
|
@ -1181,3 +1181,8 @@ if (Grocy.FeatureFlags.GROCY_FEATURE_FLAG_RECIPES)
|
||||
$("#meal-plan-nav-link").attr("href", $("#meal-plan-nav-link").attr("href") + "?start=" + moment().startOf("week").format("YYYY-MM-DD"));
|
||||
}
|
||||
}
|
||||
|
||||
$('[data-toggle="tooltip"][data-html="true"]').on("shown.bs.tooltip", function()
|
||||
{
|
||||
RefreshLocaleNumberDisplay(".tooltip");
|
||||
})
|
||||
|
@ -12,7 +12,7 @@ Grocy.Components.ProductCard.Refresh = function(productId)
|
||||
$('#productcard-product-description').html(productDetails.product.description);
|
||||
$('#productcard-product-stock-amount').text(stockAmount);
|
||||
$('#productcard-product-stock-qu-name').text(__n(stockAmount, productDetails.quantity_unit_stock.name, productDetails.quantity_unit_stock.name_plural, true));
|
||||
$('#productcard-product-stock-value').text(stockValue + ' ' + Grocy.Currency);
|
||||
$('#productcard-product-stock-value').text(stockValue);
|
||||
$('#productcard-product-last-purchased').text((productDetails.last_purchased || '2999-12-31').substring(0, 10));
|
||||
$('#productcard-product-last-purchased-timeago').attr("datetime", productDetails.last_purchased || '2999-12-31');
|
||||
$('#productcard-product-last-used').text((productDetails.last_used || '2999-12-31').substring(0, 10));
|
||||
@ -84,20 +84,24 @@ Grocy.Components.ProductCard.Refresh = function(productId)
|
||||
|
||||
if (productDetails.last_price !== null)
|
||||
{
|
||||
$('#productcard-product-last-price').text(__t("%1$s per %2$s", Number.parseFloat(productDetails.last_price).toLocaleString(undefined, { style: "currency", currency: Grocy.Currency, minimumFractionDigits: Grocy.UserSettings.stock_decimal_places_prices, maximumFractionDigits: Grocy.UserSettings.stock_decimal_places_prices }), productDetails.quantity_unit_stock.name));
|
||||
$('#productcard-product-last-price').text(__t("%1$s per %2$s", (Number.parseFloat(productDetails.last_price) * Number.parseFloat(productDetails.product.qu_factor_purchase_to_stock)).toLocaleString(undefined, { style: "currency", currency: Grocy.Currency, minimumFractionDigits: Grocy.UserSettings.stock_decimal_places_prices, maximumFractionDigits: Grocy.UserSettings.stock_decimal_places_prices }), productDetails.default_quantity_unit_purchase.name));
|
||||
$('#productcard-product-last-price').attr("data-original-title", __t("%1$s per %2$s", Number.parseFloat(productDetails.last_price).toLocaleString(undefined, { style: "currency", currency: Grocy.Currency, minimumFractionDigits: Grocy.UserSettings.stock_decimal_places_prices, maximumFractionDigits: Grocy.UserSettings.stock_decimal_places_prices }), productDetails.quantity_unit_stock.name));
|
||||
}
|
||||
else
|
||||
{
|
||||
$('#productcard-product-last-price').text(__t('Unknown'));
|
||||
$('#productcard-product-last-price').removeAttr("data-original-title");
|
||||
}
|
||||
|
||||
if (productDetails.avg_price !== null)
|
||||
{
|
||||
$('#productcard-product-average-price').text(__t("%1$s per %2$s", Number.parseFloat(productDetails.avg_price).toLocaleString(undefined, { style: "currency", currency: Grocy.Currency, minimumFractionDigits: Grocy.UserSettings.stock_decimal_places_prices, maximumFractionDigits: Grocy.UserSettings.stock_decimal_places_prices }), productDetails.quantity_unit_stock.name));
|
||||
$('#productcard-product-average-price').text(__t("%1$s per %2$s", (Number.parseFloat(productDetails.avg_price) * Number.parseFloat(productDetails.product.qu_factor_purchase_to_stock)).toLocaleString(undefined, { style: "currency", currency: Grocy.Currency, minimumFractionDigits: Grocy.UserSettings.stock_decimal_places_prices, maximumFractionDigits: Grocy.UserSettings.stock_decimal_places_prices }), productDetails.default_quantity_unit_purchase.name));
|
||||
$('#productcard-product-average-price').attr("data-original-title", __t("%1$s per %2$s", Number.parseFloat(productDetails.avg_price).toLocaleString(undefined, { style: "currency", currency: Grocy.Currency, minimumFractionDigits: Grocy.UserSettings.stock_decimal_places_prices, maximumFractionDigits: Grocy.UserSettings.stock_decimal_places_prices }), productDetails.quantity_unit_stock.name));
|
||||
}
|
||||
else
|
||||
{
|
||||
$('#productcard-product-average-price').text(__t('Unknown'));
|
||||
$().removeAttr("data-original-title");
|
||||
}
|
||||
|
||||
if (productDetails.product.picture_file_name !== null && !productDetails.product.picture_file_name.isEmpty())
|
||||
@ -120,65 +124,65 @@ Grocy.Components.ProductCard.Refresh = function(productId)
|
||||
|
||||
RefreshContextualTimeago(".productcard");
|
||||
RefreshLocaleNumberDisplay(".productcard");
|
||||
|
||||
if (Grocy.FeatureFlags.GROCY_FEATURE_FLAG_STOCK_PRICE_TRACKING)
|
||||
{
|
||||
Grocy.Api.Get('stock/products/' + productId + '/price-history',
|
||||
function(priceHistoryDataPoints)
|
||||
{
|
||||
if (priceHistoryDataPoints.length > 0)
|
||||
{
|
||||
$("#productcard-product-price-history-chart").removeClass("d-none");
|
||||
$("#productcard-no-price-data-hint").addClass("d-none");
|
||||
|
||||
Grocy.Components.ProductCard.ReInitPriceHistoryChart();
|
||||
var datasets = {};
|
||||
var chart = Grocy.Components.ProductCard.PriceHistoryChart.data;
|
||||
priceHistoryDataPoints.forEach((dataPoint) =>
|
||||
{
|
||||
var key = __t("Unknown store");
|
||||
if (dataPoint.shopping_location)
|
||||
{
|
||||
key = dataPoint.shopping_location.name
|
||||
}
|
||||
|
||||
if (!datasets[key])
|
||||
{
|
||||
datasets[key] = []
|
||||
}
|
||||
chart.labels.push(moment(dataPoint.date).toDate());
|
||||
datasets[key].push(Number.parseFloat(dataPoint.price) * Number.parseFloat(productDetails.product.qu_factor_purchase_to_stock));
|
||||
|
||||
});
|
||||
Object.keys(datasets).forEach((key) =>
|
||||
{
|
||||
chart.datasets.push({
|
||||
data: datasets[key],
|
||||
fill: false,
|
||||
borderColor: "HSL(" + (129 * chart.datasets.length) + ",100%,50%)",
|
||||
label: key,
|
||||
});
|
||||
});
|
||||
Grocy.Components.ProductCard.PriceHistoryChart.update();
|
||||
}
|
||||
else
|
||||
{
|
||||
$("#productcard-product-price-history-chart").addClass("d-none");
|
||||
$("#productcard-no-price-data-hint").removeClass("d-none");
|
||||
}
|
||||
},
|
||||
function(xhr)
|
||||
{
|
||||
console.error(xhr);
|
||||
}
|
||||
);
|
||||
}
|
||||
},
|
||||
function(xhr)
|
||||
{
|
||||
console.error(xhr);
|
||||
}
|
||||
);
|
||||
|
||||
if (Grocy.FeatureFlags.GROCY_FEATURE_FLAG_STOCK_PRICE_TRACKING)
|
||||
{
|
||||
Grocy.Api.Get('stock/products/' + productId + '/price-history',
|
||||
function(priceHistoryDataPoints)
|
||||
{
|
||||
if (priceHistoryDataPoints.length > 0)
|
||||
{
|
||||
$("#productcard-product-price-history-chart").removeClass("d-none");
|
||||
$("#productcard-no-price-data-hint").addClass("d-none");
|
||||
|
||||
Grocy.Components.ProductCard.ReInitPriceHistoryChart();
|
||||
var datasets = {};
|
||||
var chart = Grocy.Components.ProductCard.PriceHistoryChart.data;
|
||||
priceHistoryDataPoints.forEach((dataPoint) =>
|
||||
{
|
||||
var key = __t("Unknown store");
|
||||
if (dataPoint.shopping_location)
|
||||
{
|
||||
key = dataPoint.shopping_location.name
|
||||
}
|
||||
|
||||
if (!datasets[key])
|
||||
{
|
||||
datasets[key] = []
|
||||
}
|
||||
chart.labels.push(moment(dataPoint.date).toDate());
|
||||
datasets[key].push(dataPoint.price);
|
||||
|
||||
});
|
||||
Object.keys(datasets).forEach((key) =>
|
||||
{
|
||||
chart.datasets.push({
|
||||
data: datasets[key],
|
||||
fill: false,
|
||||
borderColor: "HSL(" + (129 * chart.datasets.length) + ",100%,50%)",
|
||||
label: key,
|
||||
});
|
||||
});
|
||||
Grocy.Components.ProductCard.PriceHistoryChart.update();
|
||||
}
|
||||
else
|
||||
{
|
||||
$("#productcard-product-price-history-chart").addClass("d-none");
|
||||
$("#productcard-no-price-data-hint").removeClass("d-none");
|
||||
}
|
||||
},
|
||||
function(xhr)
|
||||
{
|
||||
console.error(xhr);
|
||||
}
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
Grocy.Components.ProductCard.ReInitPriceHistoryChart = function()
|
||||
@ -220,12 +224,32 @@ Grocy.Components.ProductCard.ReInitPriceHistoryChart = function()
|
||||
}],
|
||||
yAxes: [{
|
||||
ticks: {
|
||||
beginAtZero: true
|
||||
beginAtZero: true,
|
||||
callback: function(value, index, ticks)
|
||||
{
|
||||
return Number.parseFloat(value).toLocaleString(undefined, { style: "currency", currency: Grocy.Currency, minimumFractionDigits: Grocy.UserSettings.stock_decimal_places_prices, maximumFractionDigits: Grocy.UserSettings.stock_decimal_places_prices });
|
||||
}
|
||||
}
|
||||
}]
|
||||
},
|
||||
legend: {
|
||||
display: true
|
||||
},
|
||||
tooltips: {
|
||||
callbacks: {
|
||||
label: function(tooltipItem, data)
|
||||
{
|
||||
var label = data.datasets[tooltipItem.datasetIndex].label || '';
|
||||
|
||||
if (label)
|
||||
{
|
||||
label += ': ';
|
||||
}
|
||||
|
||||
label += tooltipItem.yLabel.toLocaleString(undefined, { style: "currency", currency: Grocy.Currency, minimumFractionDigits: Grocy.UserSettings.stock_decimal_places_prices, maximumFractionDigits: Grocy.UserSettings.stock_decimal_places_prices })
|
||||
return label;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -216,7 +216,18 @@ function RefreshStockEntryRow(stockRowId)
|
||||
}
|
||||
);
|
||||
|
||||
$('#stock-' + stockRowId + '-price').text(result.price);
|
||||
Grocy.Api.Get("stock/products/" + result.product_id,
|
||||
function(productDetails)
|
||||
{
|
||||
$('#stock-' + stockRowId + '-price').text(__t("%1$s per %2$s", (Number.parseFloat(result.price) * Number.parseFloat(productDetails.product.qu_factor_purchase_to_stock)).toLocaleString(undefined, { style: "currency", currency: Grocy.Currency, minimumFractionDigits: Grocy.UserSettings.stock_decimal_places_prices, maximumFractionDigits: Grocy.UserSettings.stock_decimal_places_prices }), productDetails.default_quantity_unit_purchase.name));
|
||||
$('#stock-' + stockRowId + '-price').attr("data-original-title", __t("%1$s per %2$s", Number.parseFloat(result.price).toLocaleString(undefined, { style: "currency", currency: Grocy.Currency, minimumFractionDigits: Grocy.UserSettings.stock_decimal_places_prices, maximumFractionDigits: Grocy.UserSettings.stock_decimal_places_prices }), productDetails.quantity_unit_stock.name));
|
||||
},
|
||||
function(xhr)
|
||||
{
|
||||
console.error(xhr);
|
||||
}
|
||||
);
|
||||
|
||||
$('#stock-' + stockRowId + '-note').text(result.note);
|
||||
$('#stock-' + stockRowId + '-purchased-date').text(result.purchased_date);
|
||||
$('#stock-' + stockRowId + '-purchased-date-timeago').attr('datetime', result.purchased_date + ' 23:59:59');
|
||||
|
@ -49,15 +49,32 @@
|
||||
class="pl-2 text-secondary d-none"><i class="fas fa-custom-sigma-sign"></i> <span id="productcard-product-stock-amount-aggregated"
|
||||
class="locale-number locale-number-quantity-amount"></span> <span id="productcard-product-stock-qu-name-aggregated"></span> <span id="productcard-product-stock-opened-amount-aggregated locale-number locale-number-quantity-amount"
|
||||
class="small font-italic"></span></span><br>
|
||||
@if(GROCY_FEATURE_FLAG_STOCK_PRICE_TRACKING)<strong>{{ $__t('Stock value') }}:</strong> <span id="productcard-product-stock-value"
|
||||
class="locale-number locale-number-currency"></span><br>@endif
|
||||
|
||||
@if(GROCY_FEATURE_FLAG_STOCK_PRICE_TRACKING)
|
||||
<strong>{{ $__t('Stock value') }}:</strong> <span id="productcard-product-stock-value"
|
||||
class="locale-number locale-number-currency"></span><br>
|
||||
@endif
|
||||
|
||||
@if(GROCY_FEATURE_FLAG_STOCK_LOCATION_TRACKING)<strong>{{ $__t('Default location') }}:</strong> <span id="productcard-product-location"></span><br>@endif
|
||||
<strong>{{ $__t('Last purchased') }}:</strong> <span id="productcard-product-last-purchased"></span> <time id="productcard-product-last-purchased-timeago"
|
||||
class="timeago timeago-contextual"></time><br>
|
||||
<strong>{{ $__t('Last used') }}:</strong> <span id="productcard-product-last-used"></span> <time id="productcard-product-last-used-timeago"
|
||||
class="timeago timeago-contextual"></time><br>
|
||||
@if(GROCY_FEATURE_FLAG_STOCK_PRICE_TRACKING)<strong>{{ $__t('Last price') }}:</strong> <span id="productcard-product-last-price"></span><br>@endif
|
||||
@if(GROCY_FEATURE_FLAG_STOCK_PRICE_TRACKING)<strong>{{ $__t('Average price') }}:</strong> <span id="productcard-product-average-price"></span><br>@endif
|
||||
|
||||
@if(GROCY_FEATURE_FLAG_STOCK_PRICE_TRACKING)<strong>
|
||||
{{ $__t('Last price') }}:</strong> <span id="productcard-product-last-price"
|
||||
data-toggle="tooltip"
|
||||
data-trigger="hover click"></span>
|
||||
<br>
|
||||
@endif
|
||||
|
||||
@if(GROCY_FEATURE_FLAG_STOCK_PRICE_TRACKING)
|
||||
<strong>{{ $__t('Average price') }}:</strong> <span id="productcard-product-average-price"
|
||||
data-toggle="tooltip"
|
||||
data-trigger="hover click"></span>
|
||||
<br>
|
||||
@endif
|
||||
|
||||
@if(GROCY_FEATURE_FLAG_STOCK_BEST_BEFORE_DATE_TRACKING)<strong>{{ $__t('Average shelf life') }}:</strong> <span id="productcard-product-average-shelf-life"></span><br>@endif
|
||||
<strong>{{ $__t('Spoil rate') }}:</strong> <span id="productcard-product-spoil-rate"></span>
|
||||
|
||||
|
@ -261,11 +261,15 @@
|
||||
{{ FindObjectInArrayByPropertyValue($shoppinglocations, 'id', $stockEntry->shopping_location_id)->name }}
|
||||
@endif
|
||||
</td>
|
||||
<td id="stock-{{ $stockEntry->id }}-price"
|
||||
class="@if(!GROCY_FEATURE_FLAG_STOCK_PRICE_TRACKING) d-none @endif"
|
||||
class="locale-number locale-number-currency"
|
||||
data-price-id="{{ $stockEntry->price }}">
|
||||
{{ $stockEntry->price }}
|
||||
<td data-order="{{$stockEntry->price}}"
|
||||
class="@if(!GROCY_FEATURE_FLAG_STOCK_PRICE_TRACKING) d-none @endif">
|
||||
<span id="stock-{{ $stockEntry->id }}-price"
|
||||
data-toggle="tooltip"
|
||||
data-trigger="hover click"
|
||||
data-html="true"
|
||||
title="{!! $__t('%1$s per %2$s', '<span class=\'locale-number locale-number-currency\'>' . $stockEntry->price . '</span>', FindObjectInArrayByPropertyValue($quantityunits, 'id', FindObjectInArrayByPropertyValue($products, 'id', $stockEntry->product_id)->qu_id_stock)->name) !!}">
|
||||
{!! $__t('%1$s per %2$s', '<span class="locale-number locale-number-currency">' . floatval($stockEntry->price) * floatval(FindObjectInArrayByPropertyValue($products, 'id', $stockEntry->product_id)->qu_factor_purchase_to_stock) . '</span>', FindObjectInArrayByPropertyValue($quantityunits, 'id', FindObjectInArrayByPropertyValue($products, 'id', $stockEntry->product_id)->qu_id_purchase)->name) !!}
|
||||
</span>
|
||||
</td>
|
||||
<td>
|
||||
<span id="stock-{{ $stockEntry->id }}-purchased-date">{{ $stockEntry->purchased_date }}</span>
|
||||
|
@ -399,8 +399,16 @@
|
||||
<time class="timeago timeago-contextual"
|
||||
datetime="{{ $currentStockEntry->last_purchased }}"></time>
|
||||
</td>
|
||||
<td class="@if(!GROCY_FEATURE_FLAG_STOCK_PRICE_TRACKING) d-none @endif">
|
||||
<span class="locale-number locale-number-currency">{{ $currentStockEntry->last_price }}</span>
|
||||
<td data-order="{{$currentStockEntry->last_price}}"
|
||||
class="@if(!GROCY_FEATURE_FLAG_STOCK_PRICE_TRACKING) d-none @endif">
|
||||
@if(!empty($currentStockEntry->last_price))
|
||||
<span data-toggle="tooltip"
|
||||
data-trigger="hover click"
|
||||
data-html="true"
|
||||
title="{!! $__t('%1$s per %2$s', '<span class=\'locale-number locale-number-currency\'>' . $currentStockEntry->last_price . '</span>', $currentStockEntry->qu_unit_name) !!}">
|
||||
{!! $__t('%1$s per %2$s', '<span class="locale-number locale-number-currency">' . floatval($currentStockEntry->last_price) * floatval($currentStockEntry->product_qu_factor_purchase_to_stock) . '</span>', $currentStockEntry->qu_purchase_unit_name) !!}
|
||||
</span>
|
||||
@endif
|
||||
</td>
|
||||
<td>
|
||||
<span class="locale-number locale-number-quantity-amount">{{ $currentStockEntry->min_stock_amount }}</span>
|
||||
@ -421,8 +429,16 @@
|
||||
class="lazy">
|
||||
@endif
|
||||
</td>
|
||||
<td class="@if(!GROCY_FEATURE_FLAG_STOCK_PRICE_TRACKING) d-none @endif">
|
||||
<span class="locale-number locale-number-currency">{{ $currentStockEntry->average_price }}</span>
|
||||
<td data-order="{{$currentStockEntry->average_price}}"
|
||||
class="@if(!GROCY_FEATURE_FLAG_STOCK_PRICE_TRACKING) d-none @endif">
|
||||
@if(!empty($currentStockEntry->average_price))
|
||||
<span data-toggle="tooltip"
|
||||
data-trigger="hover click"
|
||||
data-html="true"
|
||||
title="{!! $__t('%1$s per %2$s', '<span class=\'locale-number locale-number-currency\'>' . $currentStockEntry->average_price . '</span>', $currentStockEntry->qu_unit_name) !!}">
|
||||
{!! $__t('%1$s per %2$s', '<span class="locale-number locale-number-currency">' . floatval($currentStockEntry->average_price) * floatval($currentStockEntry->product_qu_factor_purchase_to_stock) . '</span>', $currentStockEntry->qu_purchase_unit_name) !!}
|
||||
</span>
|
||||
@endif
|
||||
</td>
|
||||
|
||||
@include('components.userfields_tbody', array(
|
||||
|
Loading…
x
Reference in New Issue
Block a user