diff --git a/src/DataTables/Adapters/TwoStepORMAdapter.php b/src/DataTables/Adapters/TwoStepORMAdapter.php index 53408f91..03ab0663 100644 --- a/src/DataTables/Adapters/TwoStepORMAdapter.php +++ b/src/DataTables/Adapters/TwoStepORMAdapter.php @@ -135,6 +135,10 @@ class TwoStepORMAdapter extends ORMAdapter protected function getCount(QueryBuilder $queryBuilder, $identifier): int { + if ($this->query_modifier !== null) { + $queryBuilder = $this->query_modifier->__invoke(clone $queryBuilder); + } + //Check if the queryBuilder is having a HAVING clause, which would make the count query invalid if (empty($queryBuilder->getDQLPart('having'))) { //If not, we can use the simple count query diff --git a/src/DataTables/PartsDataTable.php b/src/DataTables/PartsDataTable.php index b356d1c0..d8fcdb6c 100644 --- a/src/DataTables/PartsDataTable.php +++ b/src/DataTables/PartsDataTable.php @@ -231,20 +231,13 @@ final class PartsDataTable implements DataTableTypeInterface /* In the filter query we only select the IDs. The fetching of the full entities is done in the detail query. * We only need to join the entities here, so we can filter by them. * The filter conditions are added to this QB in the buildCriteria method. + * + * The amountSum field and the joins are dynmically added by the addJoins method, if the fields are used in the query. + * This improves the performance, as we do not need to join all tables, if we do not need them. */ $builder ->select('part.id') ->addSelect('part.minamount AS HIDDEN minamount') - //Calculate amount sum using a subquery, so we can filter and sort by it - ->addSelect( - '( - SELECT IFNULL(SUM(partLot.amount), 0.0) - FROM '.PartLot::class.' partLot - WHERE partLot.part = part.id - AND partLot.instock_unknown = false - AND (partLot.expiration_date IS NULL OR partLot.expiration_date > CURRENT_DATE()) - ) AS HIDDEN amountSum' - ) ->from(Part::class, 'part') //This must be the only group by, or the paginator will not work correctly @@ -323,6 +316,20 @@ final class PartsDataTable implements DataTableTypeInterface //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(); + //Add the amountSum field, if it is used in the query + if (str_contains($dql, 'amountSum')) { + //Calculate amount sum using a subquery, so we can filter and sort by it + $builder->addSelect( + '( + SELECT IFNULL(SUM(partLot.amount), 0.0) + FROM '.PartLot::class.' partLot + WHERE partLot.part = part.id + AND partLot.instock_unknown = false + AND (partLot.expiration_date IS NULL OR partLot.expiration_date > CURRENT_DATE()) + ) AS HIDDEN amountSum' + ); + } + if (str_contains($dql, '_category')) { $builder->leftJoin('part.category', '_category'); }