Added filter constraint for manufacturing status.

This commit is contained in:
Jan Böhmer 2022-09-04 00:45:10 +02:00
parent 7b3538a2c7
commit ec5e956e31
11 changed files with 342 additions and 1 deletions

View file

@ -0,0 +1,84 @@
<?php
namespace App\DataTables\Filters\Constraints;
use Doctrine\ORM\QueryBuilder;
class ChoiceConstraint extends AbstractConstraint
{
public const ALLOWED_OPERATOR_VALUES = ['ANY', 'NONE'];
/**
* @var string[] The values to compare to
*/
protected $value;
/**
* @var string The operator to use
*/
protected $operator;
/**
* @return string[]
*/
public function getValue(): array
{
return $this->value;
}
/**
* @param string[] $value
* @return ChoiceConstraint
*/
public function setValue(array $value): ChoiceConstraint
{
$this->value = $value;
return $this;
}
/**
* @return string
*/
public function getOperator(): string
{
return $this->operator;
}
/**
* @param string $operator
* @return ChoiceConstraint
*/
public function setOperator(string $operator): ChoiceConstraint
{
$this->operator = $operator;
return $this;
}
public function isEnabled(): bool
{
return !empty($this->operator);
}
public function apply(QueryBuilder $queryBuilder): void
{
//If no value is provided then we do not apply a filter
if (!$this->isEnabled()) {
return;
}
//Ensure we have an valid operator
if(!in_array($this->operator, self::ALLOWED_OPERATOR_VALUES, true)) {
throw new \RuntimeException('Invalid operator '. $this->operator . ' provided. Valid operators are '. implode(', ', self::ALLOWED_OPERATOR_VALUES));
}
if ($this->operator === 'ANY') {
$this->addSimpleAndConstraint($queryBuilder, $this->property, $this->identifier, 'IN', $this->value);
} elseif ($this->operator === 'NONE') {
$this->addSimpleAndConstraint($queryBuilder, $this->property, $this->identifier, 'NOT IN', $this->value);
} else {
throw new \RuntimeException('Unknown operator '. $this->operator . ' provided. Valid operators are '. implode(', ', self::ALLOWED_OPERATOR_VALUES));
}
}
}

View file

@ -47,7 +47,7 @@ trait FilterTrait
*/
protected function addSimpleAndConstraint(QueryBuilder $queryBuilder, string $property, string $parameterIdentifier, string $comparison_operator, $value): void
{
if ($comparison_operator === 'IN') {
if ($comparison_operator === 'IN' || $comparison_operator === 'NOT IN') {
$expression = sprintf("%s %s (:%s)", $property, $comparison_operator, $parameterIdentifier);
} else {
$expression = sprintf("%s %s :%s", $property, $comparison_operator, $parameterIdentifier);

View file

@ -3,6 +3,7 @@
namespace App\DataTables\Filters;
use App\DataTables\Filters\Constraints\BooleanConstraint;
use App\DataTables\Filters\Constraints\ChoiceConstraint;
use App\DataTables\Filters\Constraints\DateTimeConstraint;
use App\DataTables\Filters\Constraints\EntityConstraint;
use App\DataTables\Filters\Constraints\IntConstraint;
@ -67,6 +68,9 @@ class PartFilter implements FilterInterface
/** @var EntityConstraint */
protected $manufacturer;
/** @var ChoiceConstraint */
protected $manufacturing_status;
/** @var EntityConstraint */
protected $supplier;
@ -133,6 +137,7 @@ class PartFilter implements FilterInterface
$this->manufacturer = new EntityConstraint($nodesListBuilder, Manufacturer::class, 'part.manufacturer');
$this->manufacturer_product_number = new TextConstraint('part.manufacturer_product_number');
$this->manufacturer_product_url = new TextConstraint('part.manufacturer_product_url');
$this->manufacturing_status = new ChoiceConstraint('part.manufacturing_status');
$this->storelocation = new EntityConstraint($nodesListBuilder, Storelocation::class, 'partLots.storage_location');
@ -350,6 +355,11 @@ class PartFilter implements FilterInterface
return $this->attachmentName;
}
public function getManufacturingStatus(): ChoiceConstraint
{
return $this->manufacturing_status;
}
}

View file

@ -0,0 +1,48 @@
<?php
namespace App\Form\Filters\Constraints;
use App\DataTables\Filters\Constraints\ChoiceConstraint;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
class ChoiceConstraintType extends AbstractType
{
public function configureOptions(OptionsResolver $resolver): void
{
$resolver->setRequired('choices');
$resolver->setAllowedTypes('choices', 'array');
$resolver->setDefaults([
'compound' => true,
'data_class' => ChoiceConstraint::class,
]);
}
public function buildForm(FormBuilderInterface $builder, array $options): void
{
$choices = [
'' => '',
'filter.choice_constraint.operator.ANY' => 'ANY',
'filter.choice_constraint.operator.NONE' => 'NONE',
];
$builder->add('operator', ChoiceType::class, [
'choices' => $choices,
'required' => false,
]);
$builder->add('value', ChoiceType::class, [
'choices' => $options['choices'],
'required' => false,
'multiple' => true,
'attr' => [
'data-controller' => 'elements--select-multiple',
]
]);
}
}

View file

@ -10,6 +10,7 @@ use App\Entity\Parts\Manufacturer;
use App\Entity\Parts\MeasurementUnit;
use App\Entity\Parts\Storelocation;
use App\Form\Filters\Constraints\BooleanConstraintType;
use App\Form\Filters\Constraints\ChoiceConstraintType;
use App\Form\Filters\Constraints\DateTimeConstraintType;
use App\Form\Filters\Constraints\NumberConstraintType;
use App\Form\Filters\Constraints\StructuralEntityConstraintType;
@ -123,6 +124,20 @@ class PartFilterType extends AbstractType
'label' => 'part.edit.mpn'
]);
$status_choices = [
'm_status.unknown' => '',
'm_status.announced' => 'announced',
'm_status.active' => 'active',
'm_status.nrfnd' => 'nrfnd',
'm_status.eol' => 'eol',
'm_status.discontinued' => 'discontinued',
];
$builder->add('manufacturing_status', ChoiceConstraintType::class, [
'label' => 'part.edit.manufacturing_status',
'choices' => $status_choices,
]);
/*
* Purchasee informations
*/