Fixed problem that tables could not be sorted by manufacturers, categories, etc.

This commit is contained in:
Jan Böhmer 2024-02-29 23:13:17 +01:00
parent 77a5cadf51
commit c635637c00
2 changed files with 41 additions and 26 deletions

View file

@ -55,6 +55,8 @@ class TwoStepORMAdapter extends ORMAdapter
private bool $use_simple_total = false; private bool $use_simple_total = false;
private \Closure|null $query_modifier;
public function __construct(ManagerRegistry $registry = null) public function __construct(ManagerRegistry $registry = null)
{ {
parent::__construct($registry); parent::__construct($registry);
@ -81,6 +83,10 @@ class TwoStepORMAdapter extends ORMAdapter
*/ */
$resolver->setDefault('simple_total_query', false); $resolver->setDefault('simple_total_query', false);
//Add the possibility of a closure to modify the query builder before the query is executed
$resolver->setDefault('query_modifier', null);
$resolver->setAllowedTypes('query_modifier', ['null', \Closure::class]);
} }
protected function afterConfiguration(array $options): void protected function afterConfiguration(array $options): void
@ -88,6 +94,7 @@ class TwoStepORMAdapter extends ORMAdapter
parent::afterConfiguration($options); parent::afterConfiguration($options);
$this->detailQueryCallable = $options['detail_query']; $this->detailQueryCallable = $options['detail_query'];
$this->use_simple_total = $options['simple_total_query']; $this->use_simple_total = $options['simple_total_query'];
$this->query_modifier = $options['query_modifier'];
} }
protected function prepareQuery(AdapterQuery $query): void protected function prepareQuery(AdapterQuery $query): void
@ -159,6 +166,11 @@ class TwoStepORMAdapter extends ORMAdapter
; ;
} }
//Apply the query modifier, if set
if ($this->query_modifier !== null) {
$builder = $this->query_modifier->__invoke($builder);
}
$id_query = $builder->getQuery(); $id_query = $builder->getQuery();
$event = new ORMAdapterQueryEvent($id_query); $event = new ORMAdapterQueryEvent($id_query);
$state->getDataTable()->getEventDispatcher()->dispatch($event, ORMAdapterEvents::PRE_QUERY); $state->getDataTable()->getEventDispatcher()->dispatch($event, ORMAdapterEvents::PRE_QUERY);

View file

@ -127,18 +127,21 @@ final class PartsDataTable implements DataTableTypeInterface
->add('category', EntityColumn::class, [ ->add('category', EntityColumn::class, [
'label' => $this->translator->trans('part.table.category'), 'label' => $this->translator->trans('part.table.category'),
'property' => 'category', 'property' => 'category',
'orderField' => '_category.name'
]) ])
->add('footprint', EntityColumn::class, [ ->add('footprint', EntityColumn::class, [
'property' => 'footprint', 'property' => 'footprint',
'label' => $this->translator->trans('part.table.footprint'), 'label' => $this->translator->trans('part.table.footprint'),
'orderField' => '_footprint.name'
]) ])
->add('manufacturer', EntityColumn::class, [ ->add('manufacturer', EntityColumn::class, [
'property' => 'manufacturer', 'property' => 'manufacturer',
'label' => $this->translator->trans('part.table.manufacturer'), 'label' => $this->translator->trans('part.table.manufacturer'),
'orderField' => '_manufacturer.name'
]) ])
->add('storelocation', TextColumn::class, [ ->add('storelocation', TextColumn::class, [
'label' => $this->translator->trans('part.table.storeLocations'), 'label' => $this->translator->trans('part.table.storeLocations'),
'orderField' => 'storelocations.name', 'orderField' => '_storelocations.name',
'render' => fn ($value, Part $context) => $this->partDataTableHelper->renderStorageLocations($context), 'render' => fn ($value, Part $context) => $this->partDataTableHelper->renderStorageLocations($context),
], alias: 'storage_location') ], alias: 'storage_location')
->add('amount', TextColumn::class, [ ->add('amount', TextColumn::class, [
@ -154,6 +157,7 @@ final class PartsDataTable implements DataTableTypeInterface
->add('partUnit', TextColumn::class, [ ->add('partUnit', TextColumn::class, [
'field' => 'partUnit.name', 'field' => 'partUnit.name',
'label' => $this->translator->trans('part.table.partUnit'), 'label' => $this->translator->trans('part.table.partUnit'),
'orderField' => '_partUnit.name'
]) ])
->add('addedDate', LocaleDateTimeColumn::class, [ ->add('addedDate', LocaleDateTimeColumn::class, [
'label' => $this->translator->trans('part.table.addedDate'), 'label' => $this->translator->trans('part.table.addedDate'),
@ -217,6 +221,7 @@ final class PartsDataTable implements DataTableTypeInterface
}, },
new SearchCriteriaProvider(), new SearchCriteriaProvider(),
], ],
'query_modifier' => $this->addJoins(...),
]); ]);
} }
@ -241,18 +246,6 @@ final class PartsDataTable implements DataTableTypeInterface
) AS HIDDEN amountSum' ) AS HIDDEN amountSum'
) )
->from(Part::class, 'part') ->from(Part::class, 'part')
/*->leftJoin('part.category', 'category')
->leftJoin('part.master_picture_attachment', 'master_picture_attachment')
->leftJoin('part.partLots', 'partLots')
->leftJoin('partLots.storage_location', 'storelocations')
->leftJoin('part.footprint', 'footprint')
->leftJoin('footprint.master_picture_attachment', 'footprint_attachment')
->leftJoin('part.manufacturer', 'manufacturer')
->leftJoin('part.orderdetails', 'orderdetails')
->leftJoin('orderdetails.supplier', 'suppliers')
->leftJoin('part.attachments', 'attachments')
->leftJoin('part.partUnit', 'partUnit')
->leftJoin('part.parameters', 'parameters')*/
//This must be the only group by, or the paginator will not work correctly //This must be the only group by, or the paginator will not work correctly
->addGroupBy('part.id'); ->addGroupBy('part.id');
@ -318,20 +311,14 @@ final class PartsDataTable implements DataTableTypeInterface
FieldHelper::addOrderByFieldParam($builder, 'part.id', 'ids'); FieldHelper::addOrderByFieldParam($builder, 'part.id', 'ids');
} }
private function buildCriteria(QueryBuilder $builder, array $options): void /**
* This function is called right before the filter query is executed.
* We use it to dynamically add joins to the query, if the fields are used in the query.
* @param QueryBuilder $builder
* @return QueryBuilder
*/
private function addJoins(QueryBuilder $builder): QueryBuilder
{ {
//Apply the search criterias first
if ($options['search'] instanceof PartSearchFilter) {
$search = $options['search'];
$search->apply($builder);
}
//We do the most stuff here in the filter class
if ($options['filter'] instanceof PartFilter) {
$filter = $options['filter'];
$filter->apply($builder);
}
//Check if the query contains certain conditions, for which we need to add additional joins //Check if the query contains certain conditions, for which we need to add additional joins
//The join fields get prefixed with an underscore, so we can check if they are used in the query easy without confusing them for a part subfield //The join fields get prefixed with an underscore, so we can check if they are used in the query easy without confusing them for a part subfield
$dql = $builder->getDQL(); $dql = $builder->getDQL();
@ -366,5 +353,21 @@ final class PartsDataTable implements DataTableTypeInterface
$builder->leftJoin('part.parameters', '_parameters'); $builder->leftJoin('part.parameters', '_parameters');
} }
return $builder;
}
private function buildCriteria(QueryBuilder $builder, array $options): void
{
//Apply the search criterias first
if ($options['search'] instanceof PartSearchFilter) {
$search = $options['search'];
$search->apply($builder);
}
//We do the most stuff here in the filter class
if ($options['filter'] instanceof PartFilter) {
$filter = $options['filter'];
$filter->apply($builder);
}
} }
} }