src/V4/Form/Type/Quote/QuoteSearchType.php line 40

Open in your IDE?
  1. <?php
  2. namespace App\V4\Form\Type\Quote;
  3. use ApiPlatform\Core\DataProvider\CollectionDataProviderInterface;
  4. use App\Form\Type\AbstractViewOrderAwareType;
  5. use App\Form\Type\Compare\DateCompareType;
  6. use App\Form\Type\Compare\NumberCompareType;
  7. use App\Form\Type\SubresourceChoicesTrait;
  8. use App\Listing\Transformer\ListingResponseTransformer;
  9. use App\Model\IriNormalizableInterface;
  10. use App\Model\Traits\TimeStampableFormType;
  11. use App\Model\ViewOrder\ViewOrder;
  12. use App\Security\SecurityConfig;
  13. use App\Service\ApiWebServiceFilterBuilder\ListWithEmptyFilterBuilder;
  14. use App\Service\Cache\CacheManager;
  15. use App\V4\Form\AsyncSubresourceChoicesLoader;
  16. use App\V4\Form\Type\IdSearchTypeTrait;
  17. use App\V4\Form\Type\ManagedByFilterTrait;
  18. use App\V4\Form\Type\SectionNameFilterTrait;
  19. use App\V4\Logger\SentryLogger;
  20. use App\V4\Model\Prospect\Prospect;
  21. use App\V4\Model\Quote\Quote;
  22. use App\V4\Model\Quote\QuoteSearch;
  23. use App\V4\Model\QuoteReason\QuoteReason;
  24. use App\V4\Model\QuoteState\QuoteState;
  25. use Psr\Cache\CacheException;
  26. use Psr\Cache\InvalidArgumentException;
  27. use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
  28. use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
  29. use Symfony\Component\Form\Extension\Core\Type\IntegerType;
  30. use Symfony\Component\Form\Extension\Core\Type\TextareaType;
  31. use Symfony\Component\Form\Extension\Core\Type\TextType;
  32. use Symfony\Component\Form\FormBuilderInterface;
  33. use Symfony\Component\Form\FormEvent;
  34. use Symfony\Component\Form\FormEvents;
  35. use Symfony\Component\OptionsResolver\OptionsResolver;
  36. use Symfony\Component\Security\Core\Security;
  37. class QuoteSearchType extends AbstractViewOrderAwareType
  38. {
  39.     use ManagedByFilterTrait;
  40.     use SectionNameFilterTrait;
  41.     use TimeStampableFormType;
  42.     use SubresourceChoicesTrait {
  43.         getEntityChoices as private getEntityChoicesTrait;
  44.     }
  45.     use IdSearchTypeTrait;
  46.     /**
  47.      * @var CollectionDataProviderInterface
  48.      */
  49.     private $collectionDataProvider;
  50.     /**
  51.      * @var CacheManager
  52.      */
  53.     private $cacheManager;
  54.     /**
  55.      * @var Security
  56.      */
  57.     private $security;
  58.     /**
  59.      * @var SentryLogger
  60.      */
  61.     private $sentryLogger;
  62.     /**
  63.      * @param CollectionDataProviderInterface $collectionDataProvider
  64.      * @param CacheManager                    $cacheManager
  65.      * @param Security                        $security
  66.      * @param SentryLogger                    $sentryLogger
  67.      */
  68.     public function __construct(
  69.         CollectionDataProviderInterface $collectionDataProvider,
  70.         CacheManager $cacheManager,
  71.         Security $security,
  72.         SentryLogger $sentryLogger
  73.     ) {
  74.         $this->collectionDataProvider $collectionDataProvider;
  75.         $this->cacheManager $cacheManager;
  76.         $this->security $security;
  77.         $this->sentryLogger $sentryLogger;
  78.     }
  79.     /**
  80.      * @param FormBuilderInterface $builder
  81.      * @param array                $options
  82.      *
  83.      * @return void
  84.      *
  85.      * @throws CacheException
  86.      * @throws InvalidArgumentException
  87.      */
  88.     public function buildForm(FormBuilderInterface $builder, array $options): void
  89.     {
  90.         parent::buildForm($builder$options);
  91.         $this->addIdsField($builder);
  92.         $builder
  93.             ->add('name'TextType::class, [
  94.                 'label' => 'quote_title',
  95.             ])
  96.             ->add('quoteNumber'TextType::class)
  97.             ->add('contractNumber'TextType::class)
  98.             ->add('isMaintenance'CheckboxType::class, [
  99.                 'false_values' => [null'0'0false'''false'],
  100.             ])
  101.             ->add('myQuotes'CheckboxType::class, [
  102.                 'false_values' => [null'0'0false'''false'],
  103.                 'data' => $this->security->isGranted(SecurityConfig::MY_QUOTE_BY_DEFAULT),
  104.             ])
  105.             ->add('status'ChoiceType::class, [
  106.                 'choices' => $this->getEntityChoices(QuoteState::class, [], 'name'),
  107.                 'choice_label' => 'name',
  108.                 'choice_value' => 'id',
  109.                 'multiple' => true,
  110.             ])
  111.             ->add('salesForecast'ChoiceType::class, [
  112.                 'choices' => [
  113.                     'yes' => 'yes',
  114.                     'no' => 'no',
  115.                     'all' => 'all',
  116.                 ],
  117.                 'expanded' => true,
  118.             ])
  119.             ->add('issuedAt'DateCompareType::class, [
  120.                 'attr' => [
  121.                     'type' => 'date_compare',
  122.                 ],
  123.             ])
  124.             ->add('expectedSignedAt'DateCompareType::class, [
  125.                 'attr' => [
  126.                     'type' => 'date_compare',
  127.                 ],
  128.             ])
  129.             ->add('warrantlyAt'DateCompareType::class, [
  130.                 'attr' => [
  131.                     'type' => 'date_compare',
  132.                 ],
  133.             ])
  134.             ->add('expiredAt'DateCompareType::class, [
  135.                 'attr' => [
  136.                     'type' => 'date_compare',
  137.                 ],
  138.             ])
  139.             ->add('prospects'ChoiceType::class, [
  140.                 'label' => 'prospects_clients',
  141.                 'multiple' => true,
  142.                 'choice_label' => 'fullname',
  143.                 'choice_value' => 'id',
  144.                 'choice_loader' => new AsyncSubresourceChoicesLoader(
  145.                     $this->collectionDataProvider,
  146.                     $this->cacheManager,
  147.                     $this->sentryLogger,
  148.                     Prospect::class,
  149.                     'id'
  150.                 ),
  151.                 'attr' => [
  152.                     'type' => 'autocomplete',
  153.                     'autocomplete_entity' => 'prospect',
  154.                     ListingResponseTransformer::FORM_FILTER_KEY => 'prospectId',
  155.                 ],
  156.             ])
  157.             ->add('managedBy'ChoiceType::class, [
  158.                 'choices' => $this->getManagedByChoices(),
  159.                 'multiple' => true,
  160.             ])
  161.             ->add('totalExcludingVat'NumberCompareType::class)
  162.             ->add('potential'IntegerType::class, [
  163.                 'label' => 'quote_potential',
  164.                 'attr' => ['min' => 0'max' => 100'step' => 25'type' => 'slider'],
  165.             ])
  166.             ->add('sectionName'ChoiceType::class, [
  167.                 'choices' => $this->getSectionNameChoices(),
  168.             ])
  169.             ->add('prospectIds'ChoiceType::class, [
  170.                 'label' => 'prospectIds',
  171.                 'required' => false,
  172.                 'attr' => [
  173.                     'type' => 'hidden',
  174.                     ListingResponseTransformer::FORM_FILTER_KEY => 'prospectId',
  175.                 ],
  176.                 'multiple' => 'true',
  177.             ])
  178.             ->add('productIds'ChoiceType::class, [
  179.                 'label' => 'productIds',
  180.                 'required' => false,
  181.                 'attr' => ['type' => 'hidden'],
  182.                 'multiple' => 'true',
  183.             ])
  184.             ->add('contactIds'ChoiceType::class, [
  185.                 'label' => 'contactIds',
  186.                 'required' => false,
  187.                 'attr' => [
  188.                     'type' => 'hidden',
  189.                     ListingResponseTransformer::FORM_FILTER_KEY => 'contactId',
  190.                 ],
  191.                 'multiple' => 'true',
  192.             ])
  193.             ->add('reason'ChoiceType::class, [
  194.                 'choices' => $this->getEntityChoices(QuoteReason::class, [], 'name'),
  195.                 'choice_label' => 'name',
  196.                 'choice_value' => 'id',
  197.                 'multiple' => true,
  198.             ])
  199.             ->add('reasonComment'TextareaType::class, [
  200.                 'required' => false,
  201.             ])
  202.             ->add('fileLabel'TextType::class, [
  203.                 'label' => 'quote_search_file_label',
  204.             ])
  205.         ;
  206.         $builder->get('prospectIds')->resetViewTransformers();
  207.         $builder->get('productIds')->resetViewTransformers();
  208.         $builder->get('contactIds')->resetViewTransformers();
  209.         //La recherche enchainĂ©e des prospects est prioritaire sur le champ de recherche prospect classique
  210.         $builder->addEventListener(FormEvents::PRE_SUBMIT, function (FormEvent $event) {
  211.             $data $event->getData();
  212.             if (!empty($data['prospectIds'])) {
  213.                 $data['prospects'] = $data['prospectIds'];
  214.                 $data['prospectIds'] = [];
  215.                 $event->setData($data);
  216.             }
  217.         });
  218.         $this->addTimeStampableFields($builder'_quote');
  219.     }
  220.     /**
  221.      * @param OptionsResolver $resolver
  222.      *
  223.      * @return void
  224.      */
  225.     public function configureOptions(OptionsResolver $resolver): void
  226.     {
  227.         parent::configureOptions($resolver);
  228.         $resolver->setDefaults([
  229.             'csrf_protection' => false,
  230.             'data_class' => QuoteSearch::class,
  231.             'required' => false,
  232.             self::FORM_CONFIG_VIEW_ORDER_ENTITY => Quote::class,
  233.             self::FORM_CONFIG_VIEW_ORDER_TYPE => ViewOrder::VIEWORDER_TYPE_SEARCH,
  234.             self::FORM_CONFIG_SPECIFIC_FIELD_ENTITY => Quote::class,
  235.             self::FORM_CONFIG_VIEW_ORDER_ENTITY_TYPE => null,
  236.         ]);
  237.     }
  238.     /**
  239.      * @param string $entityFQCN
  240.      * @param array  $filters
  241.      * @param string $labelProperty
  242.      * @param string $valueProperty
  243.      *
  244.      * @return array<string, object>
  245.      *
  246.      * @throws CacheException
  247.      * @throws InvalidArgumentException
  248.      */
  249.     private function getEntityChoices(string $entityFQCN, array $filters = [], string $labelProperty 'value'string $valueProperty 'id'): array
  250.     {
  251.         $choices $this->getEntityChoicesTrait(
  252.             $this->collectionDataProvider,
  253.             $this->cacheManager,
  254.             $this->sentryLogger,
  255.             $entityFQCN,
  256.             $filters
  257.         );
  258.         $valueSetter 'set'.ucfirst($valueProperty);
  259.         $labelSetter 'set'.ucfirst($labelProperty);
  260.         $emptyValue = (new $entityFQCN())
  261.             ->$valueSetter(ListWithEmptyFilterBuilder::EMPTY_VALUE)
  262.             ->$labelSetter('(Vide)')
  263.         ;
  264.         if ($emptyValue instanceof IriNormalizableInterface) {
  265.             $emptyValue->setNormalizeAsIRI(true);
  266.         }
  267.         $choices[] = $emptyValue;
  268.         return $choices;
  269.     }
  270. }