mirror of
https://github.com/grocy/grocy.git
synced 2026-04-04 03:46:16 +02:00
Applied code style
This commit is contained in:
parent
d3e2003dee
commit
d723c44e63
|
|
@ -517,11 +517,11 @@ class StockController extends BaseController
|
|||
|
||||
public function StockMetricsPurchases(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
||||
{
|
||||
if (isset($request->getQueryParams()['start_date']) AND isset($request->getQueryParams()['end_date']))
|
||||
if (isset($request->getQueryParams()['start_date']) and isset($request->getQueryParams()['end_date']))
|
||||
{
|
||||
$start_date = $request->getQueryParams()['start_date'];
|
||||
$end_date = $request->getQueryParams()['end_date'];
|
||||
$where = "purchased_date >= '$start_date' AND purchased_date <= '$end_date'";
|
||||
$startDate = $request->getQueryParams()['start_date'];
|
||||
$endDate = $request->getQueryParams()['end_date'];
|
||||
$where = "purchased_date >= '$startDate' AND purchased_date <= '$endDate'";
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -535,14 +535,14 @@ class StockController extends BaseController
|
|||
$sql = "
|
||||
SELECT product_group_id as id, product_group as name, sum(quantity * price) as total
|
||||
FROM product_purchase_history
|
||||
where $where
|
||||
WHERE $where
|
||||
GROUP BY product_group
|
||||
ORDER BY product_group
|
||||
";
|
||||
}
|
||||
else
|
||||
{
|
||||
if (isset($request->getQueryParams()['product_group']) AND $request->getQueryParams()['product_group'] != 'all')
|
||||
if (isset($request->getQueryParams()['product_group']) and $request->getQueryParams()['product_group'] != 'all')
|
||||
{
|
||||
$where = $where . ' AND product_group_id = ' . $request->getQueryParams()['product_group'];
|
||||
}
|
||||
|
|
@ -559,7 +559,7 @@ class StockController extends BaseController
|
|||
return $this->renderPage($response, 'stockmetricspurchases', [
|
||||
'metrics' => $this->getDatabaseService()->ExecuteDbQuery($sql)->fetchAll(\PDO::FETCH_OBJ),
|
||||
'productGroups' => $this->getDatabase()->product_groups()->orderBy('name', 'COLLATE NOCASE'),
|
||||
'selectedGroup' => isset($request->getQueryParams()['product_group']) ? $request->getQueryParams()['product_group'] : null,
|
||||
'selectedGroup' => isset($request->getQueryParams()['product_group']) ? $request->getQueryParams()['product_group'] : null,
|
||||
'byGroup' => isset($request->getQueryParams()['byGroup']) ? $request->getQueryParams()['byGroup'] : null
|
||||
]);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,23 +2,19 @@ CREATE VIEW product_purchase_history
|
|||
AS
|
||||
SELECT
|
||||
1 AS id, -- Dummy, LessQL needs an id column
|
||||
p.id as product_id,
|
||||
p.name as product_name,
|
||||
g.id as product_group_id,
|
||||
g.name as product_group,
|
||||
s.amount as quantity,
|
||||
s.price as price,
|
||||
s.purchased_date as purchased_date
|
||||
FROM
|
||||
product_groups as g
|
||||
INNER JOIN products as p
|
||||
p.id AS product_id,
|
||||
p.name AS product_name,
|
||||
g.id AS product_group_id,
|
||||
g.name AS product_group,
|
||||
s.amount AS quantity,
|
||||
s.price AS price,
|
||||
s.purchased_date AS purchased_date
|
||||
FROM product_groups g
|
||||
JOIN products p
|
||||
ON p.product_group_id = g.id
|
||||
INNER JOIN stock_log as s
|
||||
JOIN stock_log s
|
||||
ON s.product_id = p.id
|
||||
WHERE
|
||||
s.transaction_type = 'purchase'
|
||||
AND
|
||||
s.undone = 0
|
||||
AND
|
||||
s.price is not null
|
||||
ORDER BY p.name ASC
|
||||
WHERE s.transaction_type = 'purchase'
|
||||
AND s.undone = 0
|
||||
AND s.price IS NOT NULL
|
||||
ORDER BY p.name ASC;
|
||||
|
|
|
|||
|
|
@ -1,39 +1,40 @@
|
|||
/*
|
||||
* Metrics Javascript
|
||||
*/
|
||||
|
||||
/* Charting */
|
||||
var labels = [];
|
||||
var data = [];
|
||||
var totalAmount = 0;
|
||||
$("#metrics-table tbody tr").each(function () {
|
||||
$("#metrics-table tbody tr").each(function()
|
||||
{
|
||||
var self = $(this);
|
||||
labels.push(self.find("td:eq(0)").attr('data-chart-label'));
|
||||
var itemTotalRaw = parseFloat(self.find("td:eq(1)").attr('data-chart-value'));
|
||||
var itemTotal = parseFloat((Math.round(itemTotalRaw * 100) / 100).toFixed(2));
|
||||
labels.push(self.find("td:eq(0)").attr("data-chart-label"));
|
||||
var itemTotalRaw = Number.parseFloat(self.find("td:eq(1)").attr("data-chart-value"));
|
||||
var itemTotal = Number.parseFloat((Math.round(itemTotalRaw * 100) / 100).toFixed(2));
|
||||
data.push(itemTotal);
|
||||
totalAmount = (parseFloat(totalAmount) + parseFloat(itemTotal));
|
||||
totalAmount = (Number.parseFloat(totalAmount) + Number.parseFloat(itemTotal));
|
||||
});
|
||||
totalAmount = totalAmount.toLocaleString(undefined, { style: "currency", currency: Grocy.Currency });
|
||||
|
||||
var backgroundColorChoices=['#6C747C',
|
||||
'#BFB8A4',
|
||||
'#BFADA4',
|
||||
'#4F575E',
|
||||
'#918B78',
|
||||
'#343A40',
|
||||
'#635E4F',
|
||||
'#63554F',
|
||||
'#1A1F24',
|
||||
'#383426',
|
||||
'#382C26',
|
||||
'#121B25',
|
||||
'#383119',
|
||||
'#382319']
|
||||
var backgroundColors=[];
|
||||
var backgroundColorChoices = [
|
||||
"#6C747C",
|
||||
"#BFB8A4",
|
||||
"#BFADA4",
|
||||
"#4F575E",
|
||||
"#918B78",
|
||||
"#343A40",
|
||||
"#635E4F",
|
||||
"#63554F",
|
||||
"#1A1F24",
|
||||
"#383426",
|
||||
"#382C26",
|
||||
"#121B25",
|
||||
"#383119",
|
||||
"#382319"
|
||||
]
|
||||
var backgroundColors = [];
|
||||
var colorChoiceIndex = 0;
|
||||
for(let i=0;i<data.length;i++){
|
||||
if ((i + 1) == (backgroundColorChoices.length)){
|
||||
for (i = 0; i < data.length; i++)
|
||||
{
|
||||
if ((i + 1) == (backgroundColorChoices.length))
|
||||
{
|
||||
// restart background color choices
|
||||
colorChoiceIndex = 1;
|
||||
}
|
||||
|
|
@ -41,105 +42,110 @@ for(let i=0;i<data.length;i++){
|
|||
colorChoiceIndex++;
|
||||
}
|
||||
|
||||
var metricsChart = new Chart('metrics-chart', {
|
||||
type: 'outlabeledDoughnut',
|
||||
options: {
|
||||
legend: {
|
||||
display: false
|
||||
var metricsChart = new Chart("metrics-chart", {
|
||||
"type": "outlabeledDoughnut",
|
||||
"options": {
|
||||
"legend": {
|
||||
"display": false
|
||||
},
|
||||
tooltips: {
|
||||
enabled: false
|
||||
"tooltips": {
|
||||
"enabled": false
|
||||
},
|
||||
tooltips: {enabled: false},
|
||||
plugins: {
|
||||
outlabels: {
|
||||
text: '%l %p',
|
||||
backgroundColor: "#343a40",
|
||||
color: 'white',
|
||||
stretch: 45,
|
||||
font: {
|
||||
resizable: true,
|
||||
minSize: 12,
|
||||
maxSize: 18
|
||||
"tooltips": { enabled: false },
|
||||
"plugins": {
|
||||
"outlabels": {
|
||||
"text": "%l %p",
|
||||
"backgroundColor": "#343a40",
|
||||
"color": "white",
|
||||
"stretch": 45,
|
||||
"font": {
|
||||
"resizable": true,
|
||||
"minSize": 12,
|
||||
"maxSize": 18
|
||||
}
|
||||
},
|
||||
doughnutlabel: {
|
||||
labels: [
|
||||
"doughnutlabel": {
|
||||
"labels": [
|
||||
{
|
||||
text: totalAmount,
|
||||
font: {
|
||||
size: 24,
|
||||
weight: 'bold',
|
||||
"text": totalAmount,
|
||||
"font": {
|
||||
"size": 24,
|
||||
"weight": "bold"
|
||||
},
|
||||
},
|
||||
{
|
||||
text: __t("Total"),
|
||||
"text": __t("Total")
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
data: {
|
||||
labels: labels,
|
||||
datasets: [{
|
||||
data: data,
|
||||
backgroundColor: backgroundColors
|
||||
"data": {
|
||||
"labels": labels,
|
||||
"datasets": [{
|
||||
"data": data,
|
||||
"backgroundColor": backgroundColors
|
||||
}]
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
/* DataTables */
|
||||
var metricsTable = $('#metrics-table').DataTable({
|
||||
var metricsTable = $("#metrics-table").DataTable({
|
||||
"columnDefs": [
|
||||
{ "type": "num", "targets": 1 }
|
||||
]
|
||||
].concat($.fn.dataTable.defaults.columnDefs)
|
||||
});
|
||||
$('#metrics-table tbody').removeClass("d-none");
|
||||
$("#metrics-table tbody").removeClass("d-none");
|
||||
metricsTable.columns.adjust().draw();
|
||||
|
||||
/* DateRangePicker */
|
||||
const urlParams = new URLSearchParams(window.location.search);
|
||||
var startDate = moment().startOf("month").format("YYYY-MM-DD");
|
||||
var endDate = moment().endOf("month").format("YYYY-MM-DD");
|
||||
|
||||
var start_date = moment().startOf("month").format('YYYY-MM-DD');
|
||||
var end_date = moment().endOf("month").format('YYYY-MM-DD');
|
||||
if (GetUriParam("start_date"))
|
||||
{
|
||||
startDate = moment(GetUriParam("start_date"));
|
||||
}
|
||||
if (GetUriParam("end_date"))
|
||||
{
|
||||
endDate = moment(GetUriParam("end_date"));
|
||||
}
|
||||
|
||||
if (urlParams.get('start_date')) start_date = moment(urlParams.get('start_date')) ;
|
||||
if (urlParams.get('end_date')) end_date = moment(urlParams.get('end_date'));
|
||||
var ranges = {};
|
||||
ranges[__t("Today")] = [moment(), moment()];
|
||||
ranges[__t("Yesterday")] = [moment().subtract(1, "days"), moment().subtract(1, "days")];
|
||||
ranges[__t("Last 7 Days")] = [moment().subtract(6, "days"), moment()];
|
||||
ranges[__t("Last 14 Days")] = [moment().subtract(13, "days"), moment()];
|
||||
ranges[__t("Last 30 Days")] = [moment().subtract(29, "days"), moment()];
|
||||
ranges[__t("This Month")] = [moment().startOf("month"), moment().endOf("month")];
|
||||
ranges[__t("Last Month")] = [moment().subtract(1, "month").startOf("month"), moment().subtract(1, "month").endOf("month")];
|
||||
ranges[__t("This Year")] = [moment().startOf("year"), moment().endOf("year")];
|
||||
ranges[__t("Last Year")] = [moment().subtract(1, "year").startOf("year"), moment().subtract(1, "year").endOf("year")];
|
||||
|
||||
var _ranges = {}
|
||||
_ranges[__t("Today")] = [moment(), moment()]
|
||||
_ranges[__t("Yesterday")] = [moment().subtract(1, 'days'), moment().subtract(1, 'days')]
|
||||
_ranges[__t("Last 7 Days")] = [moment().subtract(6, 'days'), moment()],
|
||||
_ranges[__t("Last 14 Days")] = [moment().subtract(13, 'days'), moment()],
|
||||
_ranges[__t("Last 30 Days")] = [moment().subtract(29, 'days'), moment()],
|
||||
_ranges[__t("This Month")] = [moment().startOf('month'), moment().endOf('month')],
|
||||
_ranges[__t("Last Month")] = [moment().subtract(1, 'month').startOf('month'), moment().subtract(1, 'month').endOf('month')],
|
||||
_ranges[__t("This Year")] = [moment().startOf('year'), moment().endOf('year')],
|
||||
_ranges[__t("Last Year")] = [moment().subtract(1, 'year').startOf('year'), moment().subtract(1, 'year').endOf('year')]
|
||||
|
||||
$('#daterange-filter').daterangepicker({
|
||||
showDropdowns: true,
|
||||
startDate: start_date,
|
||||
endDate: end_date,
|
||||
showWeekNumbers: Grocy.CalendarShowWeekNumbers,
|
||||
locale: {
|
||||
"format": 'YYYY-MM-DD',
|
||||
$("#daterange-filter").daterangepicker({
|
||||
"showDropdowns": true,
|
||||
"startDate": startDate,
|
||||
"endDate": endDate,
|
||||
"showWeekNumbers": Grocy.CalendarShowWeekNumbers,
|
||||
"locale": {
|
||||
"format": "YYYY-MM-DD",
|
||||
"firstDay": Grocy.CalendarFirstDayOfWeek
|
||||
},
|
||||
applyLabel: __t("Apply"),
|
||||
cancelLabel: __t("Cancel"),
|
||||
customRangeLabel: __t("Custom Range"),
|
||||
ranges: _ranges
|
||||
}, function(start, end, label) {
|
||||
UpdateUriParam("start_date", start.format('YYYY-MM-DD'));
|
||||
UpdateUriParam("end_date", end.format('YYYY-MM-DD'))
|
||||
"applyLabel": __t("Apply"),
|
||||
"cancelLabel": __t("Cancel"),
|
||||
"customRangeLabel": __t("Custom Range"),
|
||||
"ranges": ranges
|
||||
}, function(start, end, label)
|
||||
{
|
||||
UpdateUriParam("start_date", start.format("YYYY-MM-DD"));
|
||||
UpdateUriParam("end_date", end.format("YYYY-MM-DD"))
|
||||
window.location.reload();
|
||||
});
|
||||
|
||||
$('#daterange-filter').on('cancel.daterangepicker', function(ev, picker)
|
||||
$("#daterange-filter").on("cancel.daterangepicker", function(ev, picker)
|
||||
{
|
||||
$(this).val(start_date + ' - ' + end_date);
|
||||
$(this).val(start_date + " - " + end_date);
|
||||
});
|
||||
|
||||
$("#clear-filter-button").on("click", function()
|
||||
|
|
|
|||
|
|
@ -72,7 +72,7 @@
|
|||
<link href="{{ $U('/node_modules/bootstrap-select/dist/css/bootstrap-select.min.css?v=', true) }}{{ $version }}"
|
||||
rel="stylesheet">
|
||||
<link href="{{ $U('/node_modules/daterangepicker/daterangepicker.css?v=', true) }}{{ $version }}"
|
||||
rel="stylesheet">
|
||||
rel="stylesheet">
|
||||
<link href="{{ $U('/node_modules/@fontsource/noto-sans/latin.css?v=', true) }}{{ $version }}"
|
||||
rel="stylesheet">
|
||||
<link href="{{ $U('/css/grocy.css?v=', true) }}{{ $version }}"
|
||||
|
|
|
|||
|
|
@ -4,12 +4,12 @@
|
|||
@section('activeNav', 'stockmetricspurchases')
|
||||
|
||||
@once
|
||||
@push('componentScripts')
|
||||
<script src="{{ $U('/node_modules/chart.js/dist/Chart.min.js?v=', true) }}{{ $version }}"></script>
|
||||
<script src="{{ $U('/node_modules/chartjs-plugin-doughnutlabel/dist/chartjs-plugin-doughnutlabel.js?v=', true) }}{{ $version }}"></script>
|
||||
<script src="{{ $U('/node_modules/chartjs-plugin-piechart-outlabels/dist/chartjs-plugin-piechart-outlabels.js?v=', true) }}{{ $version}}"></script>
|
||||
<script src="{{ $U('/viewjs/metrics.js', true) }}?v={{ $version }}"></script>
|
||||
@endpush
|
||||
@push('componentScripts')
|
||||
<script src="{{ $U('/node_modules/chart.js/dist/Chart.min.js?v=', true) }}{{ $version }}"></script>
|
||||
<script src="{{ $U('/node_modules/chartjs-plugin-doughnutlabel/dist/chartjs-plugin-doughnutlabel.js?v=', true) }}{{ $version }}"></script>
|
||||
<script src="{{ $U('/node_modules/chartjs-plugin-piechart-outlabels/dist/chartjs-plugin-piechart-outlabels.js?v=', true) }}{{ $version}}"></script>
|
||||
<script src="{{ $U('/viewjs/metrics.js', true) }}?v={{ $version }}"></script>
|
||||
@endpush
|
||||
@endonce
|
||||
|
||||
@section('content')
|
||||
|
|
@ -20,26 +20,26 @@
|
|||
@yield('title')
|
||||
</h2>
|
||||
<h2 class="mb-0 mr-auto order-3 order-md-1 width-xs-sm-100">
|
||||
<span id="info-current-stock"
|
||||
class="text-muted small"></span>
|
||||
<span id="info-current-stock"
|
||||
class="text-muted small"></span>
|
||||
</h2>
|
||||
<button class="btn btn-outline-dark d-md-none mt-2 float-right order-1 order-md-3"
|
||||
type="button"
|
||||
data-toggle="collapse"
|
||||
data-target="#related-links">
|
||||
type="button"
|
||||
data-toggle="collapse"
|
||||
data-target="#related-links">
|
||||
<i class="fa-solid fa-ellipsis-v"></i>
|
||||
</button>
|
||||
<div class="related-links collapse d-md-flex order-2 width-xs-sm-100"
|
||||
id="related-links">
|
||||
id="related-links">
|
||||
<a class="btn btn-outline-dark responsive-button @if(!$byGroup) active @endif m-1 mt-md-0 mb-md-0 float-right"
|
||||
href="{{ $U('/stockmetricspurchases') }}">
|
||||
href="{{ $U('/stockmetricspurchases') }}">
|
||||
{{ $__t('by Product') }}
|
||||
</a>
|
||||
</div>
|
||||
<div class="related-links collapse d-md-flex order-2 width-xs-sm-100"
|
||||
id="related-links">
|
||||
id="related-links">
|
||||
<a class="btn btn-outline-dark responsive-button @if($byGroup) active @endif m-1 mt-md-0 mb-md-0 float-right"
|
||||
href="{{ $U('/stockmetricspurchases?byGroup=true') }}">
|
||||
href="{{ $U('/stockmetricspurchases?byGroup=true') }}">
|
||||
{{ $__t('by Group') }}
|
||||
</a>
|
||||
</div>
|
||||
|
|
@ -50,40 +50,44 @@
|
|||
<hr class="my-2">
|
||||
|
||||
<div class="row collapse d-md-flex"
|
||||
id="table-filter-row">
|
||||
id="table-filter-row">
|
||||
<div class="col-sm-12 col-md-6 col-xl-4">
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fa-solid fa-clock"></i> {{ $__t('Date range') }}</span>
|
||||
<input type="text" name="date-filter" id="daterange-filter" class="custom-control custom-select" value="" />
|
||||
<input type="text"
|
||||
name="date-filter"
|
||||
id="daterange-filter"
|
||||
class="custom-control custom-select"
|
||||
value="" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@if(!$byGroup)
|
||||
<div class="col-sm-12 col-md-6 col-xl-4">
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fa-solid fa-filter"></i> {{ $__t('Product group') }}</span>
|
||||
</div>
|
||||
<select class="custom-control custom-select"
|
||||
id="product-group-filter">
|
||||
<option value="all">{{ $__t('All') }}</option>
|
||||
@foreach($productGroups as $productGroup)
|
||||
<option @if($selectedGroup == $productGroup->id)
|
||||
selected="selected"
|
||||
@endif
|
||||
value="{{ $productGroup->id }}">{{ $productGroup->name }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
<div class="col-sm-12 col-md-6 col-xl-4">
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fa-solid fa-filter"></i> {{ $__t('Product group') }}</span>
|
||||
</div>
|
||||
<select class="custom-control custom-select"
|
||||
id="product-group-filter">
|
||||
<option value="all">{{ $__t('All') }}</option>
|
||||
@foreach($productGroups as $productGroup)
|
||||
<option @if($selectedGroup==$productGroup->id)
|
||||
selected="selected"
|
||||
@endif
|
||||
value="{{ $productGroup->id }}">{{ $productGroup->name }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
<div class="col">
|
||||
<div class="float-right mt-1">
|
||||
<button id="clear-filter-button"
|
||||
class="btn btn-sm btn-outline-info"
|
||||
data-toggle="tooltip"
|
||||
title="{{ $__t('Clear filter') }}">
|
||||
class="btn btn-sm btn-outline-info"
|
||||
data-toggle="tooltip"
|
||||
title="{{ $__t('Clear filter') }}">
|
||||
<i class="fa-solid fa-filter-circle-xmark"></i>
|
||||
</button>
|
||||
</div>
|
||||
|
|
@ -91,37 +95,39 @@
|
|||
</div>
|
||||
|
||||
<div class="row mt-2">
|
||||
<div id="chart-wrapper" class="col-sm-12 col-md-12 col-xl-12">
|
||||
<div id="chart-wrapper"
|
||||
class="col-sm-12 col-md-12 col-xl-12">
|
||||
<canvas id="metrics-chart"></canvas>
|
||||
</div>
|
||||
<div class="col-sm-12 col-md-12 col-xl-12">
|
||||
<table id="metrics-table"
|
||||
class="table table-sm table-striped nowrap w-100">
|
||||
class="table table-sm table-striped nowrap w-100">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>{{ $__t('Name') }}</th>
|
||||
<th>{{ $__t('Total') }}</th>
|
||||
@if(!$byGroup)
|
||||
<tr>
|
||||
<th>{{ $__t('Name') }}</th>
|
||||
<th>{{ $__t('Total') }}</th>
|
||||
@if(!$byGroup)
|
||||
<th>{{ $__t('Product group') }}</th>
|
||||
@endif
|
||||
</tr>
|
||||
@endif
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="d-none">
|
||||
@foreach($metrics as $metric)
|
||||
@foreach($metrics as $metric)
|
||||
<tr>
|
||||
<td data-chart-label="{{ $metric->name }}">
|
||||
{{ $metric->name }}
|
||||
</td>
|
||||
<td data-chart-value="{{ $metric->total }}" data-order="{{ $metric->total }}">
|
||||
<td data-chart-value="{{ $metric->total }}"
|
||||
data-order="{{ $metric->total }}">
|
||||
<span class="locale-number locale-number-currency">{{ $metric->total }}</span>
|
||||
</td>
|
||||
@if(!$byGroup)
|
||||
<td>
|
||||
{{ $metric->group_name }}
|
||||
</td>
|
||||
<td>
|
||||
{{ $metric->group_name }}
|
||||
</td>
|
||||
@endif
|
||||
</tr>
|
||||
@endforeach
|
||||
@endforeach
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@
|
|||
{{ $__t('Stock entries') }}
|
||||
</a>
|
||||
<a class="btn btn-outline-dark responsive-button m-1 mt-md-0 mb-md-0 float-right"
|
||||
href="{{ $U('/stockmetricspurchases') }}">
|
||||
href="{{ $U('/stockmetricspurchases') }}">
|
||||
{{ $__t('Metrics') }}
|
||||
</a>
|
||||
@if(GROCY_FEATURE_FLAG_STOCK_LOCATION_TRACKING)
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user