Use TwoStepORMAdapter to enable sorting based on other columns like storage location, manufacturing status

This commit is contained in:
root 2026-04-04 18:33:13 +02:00
parent 1bb943d5ce
commit a8b5a138b1

View file

@ -22,21 +22,22 @@ declare(strict_types=1);
namespace App\DataTables; namespace App\DataTables;
use App\DataTables\Adapters\TwoStepORMAdapter;
use App\DataTables\Column\EntityColumn; use App\DataTables\Column\EntityColumn;
use App\DataTables\Column\EnumColumn; use App\DataTables\Column\EnumColumn;
use App\DataTables\Column\LocaleDateTimeColumn; use App\DataTables\Column\LocaleDateTimeColumn;
use App\DataTables\Column\MarkdownColumn; use App\DataTables\Column\MarkdownColumn;
use App\DataTables\Helpers\PartDataTableHelper; use App\DataTables\Helpers\PartDataTableHelper;
use App\Entity\Attachments\Attachment; use App\Doctrine\Helpers\FieldHelper;
use App\Entity\Parts\Part; use App\Entity\Parts\Part;
use App\Entity\Parts\ManufacturingStatus; use App\Entity\Parts\ManufacturingStatus;
use App\Entity\ProjectSystem\ProjectBOMEntry; use App\Entity\ProjectSystem\ProjectBOMEntry;
use App\Services\ElementTypeNameGenerator; use App\Services\ElementTypeNameGenerator;
use App\Services\EntityURLGenerator; use App\Services\EntityURLGenerator;
use App\Services\Formatters\AmountFormatter; use App\Services\Formatters\AmountFormatter;
use Doctrine\ORM\AbstractQuery;
use Doctrine\ORM\QueryBuilder; use Doctrine\ORM\QueryBuilder;
use Omines\DataTablesBundle\Adapter\Doctrine\ORM\SearchCriteriaProvider; use Omines\DataTablesBundle\Adapter\Doctrine\ORM\SearchCriteriaProvider;
use Omines\DataTablesBundle\Adapter\Doctrine\ORMAdapter;
use Omines\DataTablesBundle\Column\TextColumn; use Omines\DataTablesBundle\Column\TextColumn;
use Omines\DataTablesBundle\DataTable; use Omines\DataTablesBundle\DataTable;
use Omines\DataTablesBundle\DataTableTypeInterface; use Omines\DataTablesBundle\DataTableTypeInterface;
@ -152,6 +153,8 @@ class ProjectBomEntriesDataTable implements DataTableTypeInterface
->add('manufacturing_status', EnumColumn::class, [ ->add('manufacturing_status', EnumColumn::class, [
'label' => $this->translator->trans('part.table.manufacturingStatus'), 'label' => $this->translator->trans('part.table.manufacturingStatus'),
'data' => static fn(ProjectBOMEntry $context): ?ManufacturingStatus => $context->getPart()?->getManufacturingStatus(),
'orderField' => 'part.manufacturing_status',
'class' => ManufacturingStatus::class, 'class' => ManufacturingStatus::class,
'render' => function (?ManufacturingStatus $status, ProjectBOMEntry $context): string { 'render' => function (?ManufacturingStatus $status, ProjectBOMEntry $context): string {
if ($status === null) { if ($status === null) {
@ -211,11 +214,13 @@ class ProjectBomEntriesDataTable implements DataTableTypeInterface
$dataTable->addOrderBy('name', DataTable::SORT_ASCENDING); $dataTable->addOrderBy('name', DataTable::SORT_ASCENDING);
$dataTable->createAdapter(ORMAdapter::class, [ $dataTable->createAdapter(TwoStepORMAdapter::class, [
'entity' => Attachment::class, 'entity' => ProjectBOMEntry::class,
'query' => function (QueryBuilder $builder) use ($options): void { 'hydrate' => AbstractQuery::HYDRATE_OBJECT,
$this->getQuery($builder, $options); 'filter_query' => function (QueryBuilder $builder) use ($options): void {
$this->getFilterQuery($builder, $options);
}, },
'detail_query' => $this->getDetailQuery(...),
'criteria' => [ 'criteria' => [
function (QueryBuilder $builder) use ($options): void { function (QueryBuilder $builder) use ($options): void {
$this->buildCriteria($builder, $options); $this->buildCriteria($builder, $options);
@ -225,11 +230,45 @@ class ProjectBomEntriesDataTable implements DataTableTypeInterface
]); ]);
} }
private function getQuery(QueryBuilder $builder, array $options): void private function getFilterQuery(QueryBuilder $builder, array $options): void
{ {
$builder $builder
->select('bom_entry') ->select('bom_entry.id')
->from(ProjectBOMEntry::class, 'bom_entry')
->leftJoin('bom_entry.part', 'part')
->leftJoin('part.category', 'category')
->leftJoin('part.partLots', '_partLots')
->leftJoin('_partLots.storage_location', '_storelocations')
->leftJoin('part.footprint', 'footprint')
->leftJoin('part.manufacturer', 'manufacturer')
->leftJoin('part.partCustomState', 'partCustomState')
->where('bom_entry.project = :project')
->setParameter('project', $options['project'])
->addGroupBy('bom_entry')
->addGroupBy('part')
->addGroupBy('category')
->addGroupBy('footprint')
->addGroupBy('manufacturer')
->addGroupBy('partCustomState')
;
}
private function getDetailQuery(QueryBuilder $builder, array $filter_results): void
{
$ids = array_map(static fn (array $row) => $row['id'], $filter_results);
if ($ids === []) {
$ids = [-1];
}
$builder
->select('bom_entry')
->addSelect('part') ->addSelect('part')
->addSelect('category')
->addSelect('partLots')
->addSelect('storelocations')
->addSelect('footprint')
->addSelect('manufacturer')
->addSelect('partCustomState')
->from(ProjectBOMEntry::class, 'bom_entry') ->from(ProjectBOMEntry::class, 'bom_entry')
->leftJoin('bom_entry.part', 'part') ->leftJoin('bom_entry.part', 'part')
->leftJoin('part.category', 'category') ->leftJoin('part.category', 'category')
@ -238,9 +277,9 @@ class ProjectBomEntriesDataTable implements DataTableTypeInterface
->leftJoin('part.footprint', 'footprint') ->leftJoin('part.footprint', 'footprint')
->leftJoin('part.manufacturer', 'manufacturer') ->leftJoin('part.manufacturer', 'manufacturer')
->leftJoin('part.partCustomState', 'partCustomState') ->leftJoin('part.partCustomState', 'partCustomState')
->where('bom_entry.project = :project') ->where('bom_entry.id IN (:ids)')
->setParameter('project', $options['project']) ->setParameter('ids', $ids)
->addGroupBy('bom_entry')
->addGroupBy('part') ->addGroupBy('part')
->addGroupBy('partLots') ->addGroupBy('partLots')
->addGroupBy('category') ->addGroupBy('category')
@ -249,6 +288,8 @@ class ProjectBomEntriesDataTable implements DataTableTypeInterface
->addGroupBy('manufacturer') ->addGroupBy('manufacturer')
->addGroupBy('partCustomState') ->addGroupBy('partCustomState')
; ;
FieldHelper::addOrderByFieldParam($builder, 'bom_entry.id', 'ids');
} }
private function buildCriteria(QueryBuilder $builder, array $options): void private function buildCriteria(QueryBuilder $builder, array $options): void