<?php
namespace App\V4\Form\Type\Prospect;
use ApiPlatform\Core\DataProvider\CollectionDataProviderInterface;
use App\Form\Type\AbstractViewOrderAwareType;
use App\Form\Type\Compare\DateCompareType;
use App\Form\Type\Compare\NumberCompareType;
use App\Form\Type\SubresourceChoicesTrait;
use App\Listing\Transformer\ListingResponseTransformer;
use App\Model\IriNormalizableInterface;
use App\Model\Traits\TimeStampableFormType;
use App\Model\ViewOrder\ViewOrder;
use App\Security\SecurityConfig;
use App\Service\ApiWebServiceFilterBuilder\ListWithEmptyFilterBuilder;
use App\Service\Cache\CacheManager;
use App\Service\Form\Api\FormApiChoicesManager;
use App\V4\Form\Type\IdSearchTypeTrait;
use App\V4\Form\Type\ManagedByFilterTrait;
use App\V4\Form\Type\SectionNameFilterTrait;
use App\V4\Logger\SentryLogger;
use App\V4\Model\LegalForm\LegalForm;
use App\V4\Model\Origin\Origin;
use App\V4\Model\Potential\Potential;
use App\V4\Model\Prospect\Prospect;
use App\V4\Model\Prospect\ProspectSearch;
use App\V4\Model\ProspectType\ProspectType;
use App\V4\Model\QuoteState\QuoteState;
use App\V4\Model\StructureType\StructureType;
use App\V4\Model\TVA\TVA;
use App\V4\Model\Workforce\Workforce;
use Psr\Cache\CacheException;
use Psr\Cache\InvalidArgumentException;
use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Form\Extension\Core\Type\HiddenType;
use Symfony\Component\Form\Extension\Core\Type\TelType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Security\Core\Security;
use Symfony\Contracts\Translation\TranslatorInterface;
class ProspectSearchType extends AbstractViewOrderAwareType
{
use ManagedByFilterTrait;
use NafFilterTrait;
use SectionNameFilterTrait;
use TimeStampableFormType;
use SubresourceChoicesTrait {
getEntityChoices as private getEntityChoicesTrait;
}
use IdSearchTypeTrait;
/**
* @var CollectionDataProviderInterface
*/
private $collectionDataProvider;
/**
* @var CacheManager
*/
private $cacheManager;
/**
* @var Security
*/
private $security;
/**
* @var FormApiChoicesManager
*/
private $formApiChoicesManager;
/**
* @var TranslatorInterface
*/
private $translator;
/**
* @var SentryLogger
*/
private $sentryLogger;
/**
* @param CollectionDataProviderInterface $collectionDataProvider
* @param CacheManager $cacheManager
* @param Security $security
* @param FormApiChoicesManager $formApiChoicesManager
* @param TranslatorInterface $translator
* @param SentryLogger $sentryLogger
*/
public function __construct(
CollectionDataProviderInterface $collectionDataProvider,
CacheManager $cacheManager,
Security $security,
FormApiChoicesManager $formApiChoicesManager,
TranslatorInterface $translator,
SentryLogger $sentryLogger
) {
$this->collectionDataProvider = $collectionDataProvider;
$this->cacheManager = $cacheManager;
$this->security = $security;
$this->formApiChoicesManager = $formApiChoicesManager;
$this->translator = $translator;
$this->sentryLogger = $sentryLogger;
}
/**
* @param FormBuilderInterface $builder
* @param array $options
*
* @return void
*
* @throws CacheException
* @throws InvalidArgumentException
*/
public function buildForm(FormBuilderInterface $builder, array $options): void
{
parent::buildForm($builder, $options);
$this->addIdsField($builder);
$builder
->add('name', TextType::class, [
'label' => 'prospect_search_name',
'attr' => [
ListingResponseTransformer::FORM_FILTER_KEY => 'fullname',
],
])
->add('tasksLinked', CheckboxType::class, [
'false_values' => [null, '0', 0, false, '', 'false'],
])
->add('customerCode', TextType::class, [
'label' => 'prospect_search_customer_code',
])
->add('groupName', TextType::class)
->add('companyMail', TextType::class, [
'attr' => [
ListingResponseTransformer::FORM_FILTER_KEY => 'contact.email',
],
])
->add('tva', ChoiceType::class, [
'choices' => $this->getEntityChoices(TVA::class),
'choice_label' => 'value',
'choice_value' => 'id',
'multiple' => true,
])
->add('workforce', ChoiceType::class, [
'choices' => $this->getEntityChoices(Workforce::class),
'choice_label' => 'value',
'choice_value' => 'id',
'multiple' => true,
'attr' => [
ListingResponseTransformer::FORM_FILTER_KEY => 'company.workforce',
],
])
->add('type', ChoiceType::class, [
'label' => 'prospectType',
'choices' => $this->getEntityChoices(ProspectType::class),
'choice_label' => 'value',
'choice_value' => 'id',
'multiple' => true,
'attr' => [
ListingResponseTransformer::FORM_FILTER_KEY => 'prospectType',
],
])
->add('origin', ChoiceType::class, [
'choices' => $this->getEntityChoices(Origin::class),
'choice_label' => 'value',
'choice_value' => 'id',
'multiple' => true,
])
->add('naf', ChoiceType::class, [
'choices' => $this->getNafChoices(),
'choice_value' => 'id',
'multiple' => true,
'attr' => [
ListingResponseTransformer::FORM_FILTER_KEY => 'company.naf',
],
])
->add('potential', ChoiceType::class, [
'choices' => $this->getEntityChoices(Potential::class),
'choice_label' => 'value',
'choice_value' => 'id',
'multiple' => true,
])
->add('siret', TextType::class, [
'attr' => [
ListingResponseTransformer::FORM_FILTER_KEY => 'company.siret',
],
])
->add('fax', TelType::class, [
'attr' => [
ListingResponseTransformer::FORM_FILTER_KEY => 'contact.fax',
],
])
->add('webSite', TextType::class, [
'attr' => [
ListingResponseTransformer::FORM_FILTER_KEY => 'company.webSite',
],
])
->add('socialCapital', NumberCompareType::class, [
'attr' => [
ListingResponseTransformer::FORM_FILTER_KEY => 'company.socialCapital',
],
])
->add('structureType', ChoiceType::class, [
'choices' => $this->getEntityChoices(StructureType::class),
'choice_label' => 'value',
'choice_value' => 'id',
'multiple' => true,
'attr' => [
ListingResponseTransformer::FORM_FILTER_KEY => 'company.structureType',
],
])
->add('managedBy', ChoiceType::class, [
'choices' => $this->getManagedByChoices(),
'multiple' => true,
])
->add('myAccounts', CheckboxType::class, [
'false_values' => [null, '0', 0, false, '', 'false'],
'data' => $this->security->isGranted(SecurityConfig::MY_PROSPECT_BY_DEFAULT),
])
->add('phone', TelType::class, [
'attr' => [
ListingResponseTransformer::FORM_FILTER_KEY => 'contact.phone',
],
])
->add('address', TextType::class, [
'attr' => [
ListingResponseTransformer::FORM_FILTER_KEY => 'contact.addresses.address',
],
])
->add('addressComplement', TextType::class, [
'attr' => [
ListingResponseTransformer::FORM_FILTER_KEY => 'contact.addresses.addressMore',
],
])
->add('nameComplement', TextType::class, [
'attr' => [
ListingResponseTransformer::FORM_FILTER_KEY => 'company.nameComplement',
],
])
->add('cedex', TextType::class, [
'attr' => [
ListingResponseTransformer::FORM_FILTER_KEY => 'contact.addresses.postalCedex',
],
])
->add('departments', ChoiceType::class, [
'choices' => array_merge(array_map('strval', array_flip($this->formApiChoicesManager->getDepartements())), ['(Vide)' => 'empty']),
'multiple' => true,
'attr' => [
ListingResponseTransformer::FORM_FILTER_KEY => 'contact.addresses.departments',
],
])
->add('zip', TextType::class, [
'attr' => [
ListingResponseTransformer::FORM_FILTER_KEY => 'contact.addresses.postalCode',
],
])
->add('city', TextType::class, [
'attr' => [
ListingResponseTransformer::FORM_FILTER_KEY => 'contact.addresses.city',
],
])
->add('country', ChoiceType::class, [
'choices' => array_combine(
$this->formApiChoicesManager->getCountries(),
$this->formApiChoicesManager->getCountries()
),
'multiple' => true,
'attr' => [
ListingResponseTransformer::FORM_FILTER_KEY => 'contact.addresses.country',
],
])
->add('legalForm', ChoiceType::class, [
'choices' => $this->getEntityChoices(LegalForm::class),
'choice_label' => 'value',
'choice_value' => 'id',
'multiple' => true,
'attr' => [
ListingResponseTransformer::FORM_FILTER_KEY => 'company.legalForm',
],
])
->add('devisState', ChoiceType::class, [
'choices' => $this->getEntityChoices(QuoteState::class, [], 'name'),
'choice_label' => 'name',
'choice_value' => 'id',
'multiple' => true,
])
->add('creationYear', DateCompareType::class, [
'attr' => [
ListingResponseTransformer::FORM_FILTER_KEY => 'company.creationYear',
],
])
->add('turnOver', NumberCompareType::class, [
'attr' => [
ListingResponseTransformer::FORM_FILTER_KEY => 'company.turnover',
],
])
->add('justLabelAndId', CheckboxType::class, [
'false_values' => [null, '0', 0, false, '', 'false'],
'attr' => ['type' => 'hidden'],
])
->add('sectionName', ChoiceType::class, [
'choices' => $this->getSectionNameChoices(),
'multiple' => true,
])
->add('taskIds', ChoiceType::class, [
'label' => 'taskIds',
'required' => false,
'attr' => [
'type' => 'hidden',
ListingResponseTransformer::FORM_FILTER_KEY => 'tasks',
],
'multiple' => 'true',
])
->add('quoteIds', ChoiceType::class, [
'label' => 'quoteIds',
'required' => false,
'attr' => ['type' => 'hidden'],
'multiple' => 'true',
])
->add('prospectIds', ChoiceType::class, [
'label' => 'prospectIds',
'required' => false,
'attr' => [
'type' => 'hidden',
ListingResponseTransformer::FORM_FILTER_KEY => 'prospect',
],
'multiple' => 'true',
'mapped' => false,
])
->add('isReverse', CheckboxType::class, [
'label' => 'isReverse',
'required' => false,
'attr' => ['type' => 'hidden'],
])
->add('distance', HiddenType::class, [
'required' => false,
'attr' => [
'data-vo-forced-display' => true,
],
])
->add('lat', HiddenType::class, [
'attr' => [
'data-vo-forced-display' => true,
],
])
->add('lng', HiddenType::class, [
'attr' => [
'data-vo-forced-display' => true,
],
])
->add('fileLabel', TextType::class, [
'label' => 'prospect_search_file_label',
])
;
if ($this->security->isGranted(SecurityConfig::MODULE_PRODUCT)) {
$builder->add('hasSubscription', ChoiceType::class, [
'choices' => [
$this->translator->trans('no') => '0',
$this->translator->trans('yes') => '1',
],
]);
}
$builder->get('taskIds')->resetViewTransformers();
$builder->get('quoteIds')->resetViewTransformers();
$builder->get('prospectIds')->resetViewTransformers();
$this->addTimeStampableFields($builder, '_prospect');
}
/**
* @param OptionsResolver $resolver
*
* @return void
*/
public function configureOptions(OptionsResolver $resolver): void
{
parent::configureOptions($resolver);
$resolver->setDefaults([
'csrf_protection' => false,
'data_class' => ProspectSearch::class,
'required' => false,
'isGeolocationSearch' => false,
self::FORM_CONFIG_VIEW_ORDER_ENTITY => Prospect::class,
self::FORM_CONFIG_VIEW_ORDER_TYPE => ViewOrder::VIEWORDER_TYPE_SEARCH,
self::FORM_CONFIG_SPECIFIC_FIELD_ENTITY => Prospect::class,
]);
}
/**
* @param string $entityFQCN
* @param array $filters
* @param string $labelProperty
* @param string $valueProperty
*
* @return array<string, object>
*
* @throws CacheException
* @throws InvalidArgumentException
*/
private function getEntityChoices(string $entityFQCN, array $filters = [], string $labelProperty = 'value', string $valueProperty = 'id'): array
{
$choices = $this->getEntityChoicesTrait(
$this->collectionDataProvider,
$this->cacheManager,
$this->sentryLogger,
$entityFQCN,
$filters
);
$valueSetter = 'set'.ucfirst($valueProperty);
$labelSetter = 'set'.ucfirst($labelProperty);
$emptyValue = (new $entityFQCN())
->$valueSetter(ListWithEmptyFilterBuilder::EMPTY_VALUE)
->$labelSetter('(Vide)')
;
if ($emptyValue instanceof IriNormalizableInterface) {
$emptyValue->setNormalizeAsIRI(true);
}
$choices[] = $emptyValue;
return $choices;
}
}