Added low-stock part listing.

This commit is contained in:
Hannes Matuschek 2020-08-30 15:51:27 +02:00
parent 226fe2f4ba
commit 0dd95da8de
4 changed files with 47 additions and 1 deletions

View file

@ -276,4 +276,21 @@ class PartListsController extends AbstractController
return $this->render('Parts/lists/all_list.html.twig', ['datatable' => $table]);
}
/**
* @Route("/lowstock", name="parts_show_low_stock")
*
* @return JsonResponse|Response
*/
public function showLowStock(Request $request, DataTableFactory $dataTable)
{
$table = $dataTable->createFromType(PartsDataTable::class, ['lowstock'=>true])
->handleRequest($request);
if ($table->isCallback()) {
return $table->getResponse();
}
return $this->render('Parts/lists/lowstock_list.html.twig', ['datatable' => $table]);
}
}

View file

@ -53,6 +53,7 @@ use App\Entity\Parts\Category;
use App\Entity\Parts\Footprint;
use App\Entity\Parts\Manufacturer;
use App\Entity\Parts\Part;
use App\Entity\Parts\PartLot;
use App\Entity\Parts\Storelocation;
use App\Entity\Parts\Supplier;
use App\Services\AmountFormatter;
@ -107,6 +108,7 @@ final class PartsDataTable implements DataTableTypeInterface
'storelocation' => null,
'supplier' => null,
'tag' => null,
'lowstock' => null,
'search' => null,
]);
@ -115,6 +117,7 @@ final class PartsDataTable implements DataTableTypeInterface
$optionsResolver->setAllowedTypes('manufacturer', ['null', Manufacturer::class]);
$optionsResolver->setAllowedTypes('supplier', ['null', Supplier::class]);
$optionsResolver->setAllowedTypes('tag', ['null', 'string']);
$optionsResolver->setAllowedTypes('lowstock', ['null', 'bool']);
$optionsResolver->setAllowedTypes('search', ['null', 'string']);
//Configure search options
@ -233,7 +236,7 @@ final class PartsDataTable implements DataTableTypeInterface
])
->add('minamount', TextColumn::class, [
'label' => $this->translator->trans('part.table.minamount'),
'visible' => false,
'visible' => isset($options["lowstock"]),
'render' => function ($value, Part $context) {
return $this->amountFormatter->format($value, $context->getPartUnit());
},
@ -395,6 +398,16 @@ final class PartsDataTable implements DataTableTypeInterface
$builder->andWhere('part.tags LIKE :tag')->setParameter('tag', '%'.$options['tag'].'%');
}
if (isset($options['lowstock'])) {
$in = $builder->getEntityManager()->createQueryBuilder();
$in->select("parts.id")
->from(Part::class, 'parts')
->innerJoin("parts.partLots", "lots")
->groupBy('parts.id')
->having('SUM(lots.amount)<parts.minamount');
$builder->andWhere($builder->expr()->in('part', $in->getDQL()));
}
if (!empty($options['search'])) {
if (!$options['search_options']['regex']) {
//Dont show results, if no things are selected

View file

@ -245,6 +245,11 @@ class ToolsTreeBuilder
$this->urlGenerator->generate('parts_show_all')
);
$show_nodes[] = new TreeViewNode(
$this->translator->trans('tree.tools.show.low_stock_parts'),
$this->urlGenerator->generate('parts_show_low_stock')
);
if ($this->security->isGranted('read', new PartAttachment())) {
$show_nodes[] = new TreeViewNode(
$this->translator->trans('tree.tools.show.all_attachments'),

View file

@ -0,0 +1,11 @@
{% extends "base.html.twig" %}
{% block title %}
{% trans %}parts_list.lowstock.title{% endtrans %}
{% endblock %}
{% block content %}
{% include "Parts/lists/_parts_list.html.twig" %}
{% endblock %}