diff --git a/src/DataTables/Filters/Constraints/FilterTrait.php b/src/DataTables/Filters/Constraints/FilterTrait.php index 01130c1b..dbf57691 100644 --- a/src/DataTables/Filters/Constraints/FilterTrait.php +++ b/src/DataTables/Filters/Constraints/FilterTrait.php @@ -47,10 +47,16 @@ trait FilterTrait */ protected function addSimpleAndConstraint(QueryBuilder $queryBuilder, string $property, string $parameterIdentifier, string $comparison_operator, $value): void { - if($this->useHaving || $this->isAggregateFunctionString($property)) { //If the property is an aggregate function, we have to use the "having" instead of the "where" - $queryBuilder->andHaving(sprintf("%s %s (:%s)", $property, $comparison_operator, $parameterIdentifier)); + if ($comparison_operator === 'IN') { + $expression = sprintf("%s %s (:%s)", $property, $comparison_operator, $parameterIdentifier); } else { - $queryBuilder->andWhere(sprintf("%s %s (:%s)", $property, $comparison_operator, $parameterIdentifier)); + $expression = sprintf("%s %s :%s", $property, $comparison_operator, $parameterIdentifier); + } + + if($this->useHaving || $this->isAggregateFunctionString($property)) { //If the property is an aggregate function, we have to use the "having" instead of the "where" + $queryBuilder->andHaving($expression); + } else { + $queryBuilder->andWhere($expression); } $queryBuilder->setParameter($parameterIdentifier, $value); diff --git a/src/DataTables/Filters/PartFilter.php b/src/DataTables/Filters/PartFilter.php index 8935d6ba..f6e9c277 100644 --- a/src/DataTables/Filters/PartFilter.php +++ b/src/DataTables/Filters/PartFilter.php @@ -68,10 +68,13 @@ class PartFilter implements FilterInterface /** @var EntityConstraint */ protected $supplier; + /** @var IntConstraint */ + protected $orderdetailsCount; + /** @var EntityConstraint */ protected $storelocation; - /** @var NumberConstraint */ + /** @var IntConstraint */ protected $lotCount; /** @var EntityConstraint */ @@ -83,6 +86,9 @@ class PartFilter implements FilterInterface /** @var TextConstraint */ protected $manufacturer_product_number; + /** @var IntConstraint */ + protected $attachmentsCount; + public function __construct(NodesListBuilder $nodesListBuilder) { $this->name = new TextConstraint('part.name'); @@ -108,7 +114,10 @@ class PartFilter implements FilterInterface $this->manufacturer_product_url = new TextConstraint('part.manufacturer_product_url'); $this->storelocation = new EntityConstraint($nodesListBuilder, Storelocation::class, 'partLots.storage_location'); + $this->lotCount = new IntConstraint('COUNT(partLots)'); + $this->attachmentsCount = new IntConstraint('COUNT(attachments)'); + $this->orderdetailsCount = new IntConstraint('COUNT(orderdetails)'); } public function apply(QueryBuilder $queryBuilder): void @@ -261,4 +270,22 @@ class PartFilter implements FilterInterface { return $this->tags; } + + /** + * @return IntConstraint + */ + public function getOrderdetailsCount(): IntConstraint + { + return $this->orderdetailsCount; + } + + /** + * @return IntConstraint + */ + public function getAttachmentsCount(): IntConstraint + { + return $this->attachmentsCount; + } + + } diff --git a/src/DataTables/PartsDataTable.php b/src/DataTables/PartsDataTable.php index de06a09f..3cca6ba2 100644 --- a/src/DataTables/PartsDataTable.php +++ b/src/DataTables/PartsDataTable.php @@ -348,7 +348,10 @@ final class PartsDataTable implements DataTableTypeInterface ->leftJoin('part.orderdetails', 'orderdetails') ->leftJoin('orderdetails.supplier', 'suppliers') ->leftJoin('part.attachments', 'attachments') - ->leftJoin('part.partUnit', 'partUnit'); + ->leftJoin('part.partUnit', 'partUnit') + + ->groupBy('part') + ; } private function buildCriteria(QueryBuilder $builder, array $options): void diff --git a/src/Form/Filters/PartFilterType.php b/src/Form/Filters/PartFilterType.php index 55891457..bf0e2cde 100644 --- a/src/Form/Filters/PartFilterType.php +++ b/src/Form/Filters/PartFilterType.php @@ -17,6 +17,7 @@ use App\Form\Filters\Constraints\TextConstraintType; use Svg\Tag\Text; use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\Extension\Core\Type\DateTimeType; +use Symfony\Component\Form\Extension\Core\Type\ResetType; use Symfony\Component\Form\Extension\Core\Type\SubmitType; use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\Form\SubmitButton; @@ -72,6 +73,7 @@ class PartFilterType extends AbstractType $builder->add('dbId', NumberConstraintType::class, [ 'label' => 'part.filter.dbId', 'min' => 1, + 'step' => 1, ]); $builder->add('favorite', BooleanConstraintType::class, [ @@ -128,6 +130,12 @@ class PartFilterType extends AbstractType 'entity_class' => Manufacturer::class ]); + $builder->add('orderdetailsCount', NumberConstraintType::class, [ + 'label' => 'part.filter.orderdetails_count', + 'step' => 1, + 'min' => 0, + ]); + /* * Stocks tabs @@ -144,12 +152,26 @@ class PartFilterType extends AbstractType $builder->add('lotCount', NumberConstraintType::class, [ 'label' => 'part.filter.lot_count', - 'min' => 0 + 'min' => 0, + 'step' => 1, ]); + /** + * Attachments count + */ + $builder->add('attachmentsCount', NumberConstraintType::class, [ + 'label' => 'part.filter.attachments_count', + 'step' => 1, + 'min' => 0, + ]); $builder->add('submit', SubmitType::class, [ 'label' => 'Update', ]); + + $builder->add('reset', ResetType::class, [ + 'label' => 'Reset', + ]); + } } \ No newline at end of file diff --git a/templates/Parts/lists/_filter.html.twig b/templates/Parts/lists/_filter.html.twig index 6a999fd9..c236d5f2 100644 --- a/templates/Parts/lists/_filter.html.twig +++ b/templates/Parts/lists/_filter.html.twig @@ -14,6 +14,9 @@ + @@ -50,10 +53,16 @@
{{ form_row(filterForm.storelocation) }} {{ form_row(filterForm.minAmount) }} + {{ form_row(filterForm.lotCount) }} +
+ +
+ {{ form_row(filterForm.attachmentsCount) }}
{{ form_row(filterForm.supplier) }} + {{ form_row(filterForm.orderdetailsCount) }}
diff --git a/translations/messages.en.xlf b/translations/messages.en.xlf index db335770..06471c86 100644 --- a/translations/messages.en.xlf +++ b/translations/messages.en.xlf @@ -9459,5 +9459,23 @@ Element 3 None of the tags + + + part.filter.lot_count + Number of lots + + + + + part.filter.attachments_count + Number of attachments + + + + + part.filter.orderdetails_count + Number of orderdetails + +