stockreports/spendings: Support grouping by store (closes #2308)

This commit is contained in:
Bernd Bestel 2023-08-14 18:12:40 +02:00
parent 106f25cc6b
commit 3a2929c016
No known key found for this signature in database
GPG Key ID: 71BD34C0D4891300
4 changed files with 60 additions and 33 deletions

View File

@ -10,6 +10,7 @@
### Stock ### Stock
- The stock report "Spendings" now also supports grouping by stores
- Fixed that the "Mark this stock entry as open"-button on the stock entries page opened always one unit instead of the whole stock entry - Fixed that the "Mark this stock entry as open"-button on the stock entries page opened always one unit instead of the whole stock entry
- Fixed that edited stock entries were not considered in some cases (affecting the product's average price and the stock reports) - Fixed that edited stock entries were not considered in some cases (affecting the product's average price and the stock reports)

View File

@ -21,29 +21,17 @@ class StockReportsController extends BaseController
$where = "pph.purchased_date >= DATE(DATE('now', 'localtime'), 'start of month')"; $where = "pph.purchased_date >= DATE(DATE('now', 'localtime'), 'start of month')";
} }
$groupBy = 'product';
if (isset($request->getQueryParams()['byGroup'])) if (isset($request->getQueryParams()['group-by']) && in_array($request->getQueryParams()['group-by'], ['product', 'productgroup', 'store']))
{ {
$sql = " $groupBy = $request->getQueryParams()['group-by'];
SELECT
pg.id AS id,
pg.name AS name,
SUM(pph.amount * pph.price) AS total
FROM products_price_history pph
JOIN products p
ON pph.product_id = p.id
JOIN product_groups pg
ON p.product_group_id = pg.id
WHERE $where
GROUP BY pg.id
ORDER BY pg.NAME COLLATE NOCASE
";
} }
else
if ($groupBy == 'product')
{ {
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 .= ' AND pg.id = ' . $request->getQueryParams()['product_group']; $where .= ' AND pg.id = ' . $request->getQueryParams()['product-group'];
} }
$sql = " $sql = "
@ -59,16 +47,50 @@ class StockReportsController extends BaseController
JOIN product_groups pg JOIN product_groups pg
ON p.product_group_id = pg.id ON p.product_group_id = pg.id
WHERE $where WHERE $where
GROUP BY p.id GROUP BY p.id, p.name, pg.id, pg.name
ORDER BY p.NAME COLLATE NOCASE ORDER BY p.name COLLATE NOCASE
";
}
elseif ($groupBy == 'productgroup')
{
$sql = "
SELECT
pg.id AS id,
pg.name AS name,
SUM(pph.amount * pph.price) AS total
FROM products_price_history pph
JOIN products p
ON pph.product_id = p.id
JOIN product_groups pg
ON p.product_group_id = pg.id
WHERE $where
GROUP BY pg.id, pg.name
ORDER BY pg.name COLLATE NOCASE
";
}
elseif ($groupBy == 'store')
{
$sql = "
SELECT
sl.id AS id,
sl.name AS name,
SUM(pph.amount * pph.price) AS total
FROM products_price_history pph
JOIN products p
ON pph.product_id = p.id
LEFT JOIN shopping_locations sl
ON pph.shopping_location_id = sl.id
WHERE $where
GROUP BY sl.id, sl.name
ORDER BY sl.NAME COLLATE NOCASE
"; ";
} }
return $this->renderPage($response, 'stockreportspendings', [ return $this->renderPage($response, 'stockreportspendings', [
'metrics' => $this->getDatabaseService()->ExecuteDbQuery($sql)->fetchAll(\PDO::FETCH_OBJ), 'metrics' => $this->getDatabaseService()->ExecuteDbQuery($sql)->fetchAll(\PDO::FETCH_OBJ),
'productGroups' => $this->getDatabase()->product_groups()->where('active = 1')->orderBy('name', 'COLLATE NOCASE'), 'productGroups' => $this->getDatabase()->product_groups()->where('active = 1')->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 'groupBy' => $groupBy
]); ]);
} }
} }

View File

@ -134,12 +134,12 @@ $("#clear-filter-button").on("click", function()
{ {
RemoveUriParam("start_date"); RemoveUriParam("start_date");
RemoveUriParam("end_date"); RemoveUriParam("end_date");
RemoveUriParam("product_group"); RemoveUriParam("product-group");
window.location.reload(); window.location.reload();
}); });
$("#product-group-filter").on("change", function() $("#product-group-filter").on("change", function()
{ {
UpdateUriParam("product_group", $(this).val()); UpdateUriParam("product-group", $(this).val());
window.location.reload(); window.location.reload();
}); });

View File

@ -27,18 +27,22 @@
</div> </div>
<div class="related-links collapse d-md-flex order-2 width-xs-sm-100" <div class="related-links collapse d-md-flex order-2 width-xs-sm-100"
id="related-links"> id="related-links">
<a class="btn btn-link responsive-button m-1 mt-md-0 mb-md-0 @if(!$byGroup) active @endif discrete-link disabled" <a class="btn btn-link responsive-button m-1 mt-md-0 mb-md-0 discrete-link disabled"
href="#"> href="#">
{{ $__t('Group by') }}: {{ $__t('Group by') }}:
</a> </a>
<a class="btn btn-outline-dark responsive-button m-1 mt-md-0 mb-md-0 float-right @if(!$byGroup) active @endif" <a class="btn btn-outline-dark responsive-button m-1 mt-md-0 mb-md-0 float-right @if($groupBy == 'product') active @endif"
href="{{ $U('/stockreports/spendings') }}"> href="{{ $U('/stockreports/spendings?group-by=product') }}">
{{ $__t('Product') }} {{ $__t('Product') }}
</a> </a>
<a class="btn btn-outline-dark responsive-button m-1 mt-md-0 mb-md-0 float-right @if($byGroup) active @endif" <a class="btn btn-outline-dark responsive-button m-1 mt-md-0 mb-md-0 float-right @if($groupBy == 'productgroup') active @endif"
href="{{ $U('/stockreports/spendings?byGroup=true') }}"> href="{{ $U('/stockreports/spendings?group-by=productgroup') }}">
{{ $__t('Product group') }} {{ $__t('Product group') }}
</a> </a>
<a class="btn btn-outline-dark responsive-button m-1 mt-md-0 mb-md-0 float-right @if($groupBy == 'store') active @endif"
href="{{ $U('/stockreports/spendings?group-by=store') }}">
{{ $__t('Store') }}
</a>
</div> </div>
</div> </div>
</div> </div>
@ -60,7 +64,7 @@
value="" /> value="" />
</div> </div>
</div> </div>
@if(!$byGroup) @if($groupBy == 'product')
<div class="col-sm-12 col-md-6 col-xl-4"> <div class="col-sm-12 col-md-6 col-xl-4">
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend"> <div class="input-group-prepend">
@ -100,7 +104,7 @@
<tr> <tr>
<th>{{ $__t('Name') }}</th> <th>{{ $__t('Name') }}</th>
<th>{{ $__t('Total') }}</th> <th>{{ $__t('Total') }}</th>
@if(!$byGroup) @if($groupBy == 'product')
<th>{{ $__t('Product group') }}</th> <th>{{ $__t('Product group') }}</th>
@endif @endif
</tr> </tr>
@ -115,7 +119,7 @@
data-order="{{ $metric->total }}"> data-order="{{ $metric->total }}">
<span class="locale-number locale-number-currency">{{ $metric->total }}</span> <span class="locale-number locale-number-currency">{{ $metric->total }}</span>
</td> </td>
@if(!$byGroup) @if($groupBy == 'product')
<td> <td>
{{ $metric->group_name }} {{ $metric->group_name }}
</td> </td>