src/Form/ChargeType.php line 50

Open in your IDE?
  1. <?php
  2. namespace App\Form;
  3. use App\Entity\Charge;
  4. use App\Entity\User;
  5. use Symfony\Bridge\Doctrine\Form\Type\EntityType;
  6. use Symfony\Component\Form\AbstractType;
  7. use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
  8. use Symfony\Component\Form\Extension\Core\Type\DateType;
  9. use Symfony\Component\Form\Extension\Core\Type\NumberType;
  10. use Symfony\Component\Form\Extension\Core\Type\TextType;
  11. use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
  12. use Symfony\Component\Form\FormBuilderInterface;
  13. use Symfony\Component\OptionsResolver\OptionsResolver;
  14. use Doctrine\ORM\EntityRepository;
  15. use Symfony\Component\Validator\Constraints\NotBlank;
  16. use Symfony\Component\Validator\Constraints\Type;
  17. use Symfony\Component\Validator\Constraints\Range;
  18. use Symfony\Component\Form\FormEvent;
  19. use Symfony\Component\Form\FormEvents;
  20. class ChargeType extends AbstractType
  21. {
  22.     public function buildForm(FormBuilderInterface $builder, array $options): void
  23.     {
  24.         $builder
  25.             ->add('date'DateType::class, [
  26.                 'widget' => 'single_text',
  27.                 'label' => 'Date',
  28.                 'required' => true,
  29.                 'attr' => [
  30.                     'class' => 'form-control'
  31.                 ]
  32.             ])
  33.             ->add('agent'EntityType::class, [
  34.                 'class' => User::class,
  35.                 'choice_label' => 'username',
  36.                 'label' => 'Agent',
  37.                 'required' => true,
  38.                 'query_builder' => function (EntityRepository $er) {
  39.                     return $er->createQueryBuilder('u')
  40.                         ->where('u.roles LIKE :role')
  41.                         ->setParameter('role''%ROLE_TEAM%')
  42.                         ->orderBy('u.username''ASC');
  43.                 },
  44.                 'attr' => [
  45.                     'class' => 'form-select'
  46.                 ],
  47.                 'preferred_choices' => function (User $user) {
  48.                     return $user->getUsername() === 'Contact';
  49.                 }
  50.             ])
  51.             ->add('isEntrepriseCharge'CheckboxType::class, [
  52.                 'label' => 'Charge de l\'entreprise',
  53.                 'required' => false,
  54.                 'attr' => [
  55.                     'class' => 'form-check-input'
  56.                 ],
  57.                 'label_attr' => [
  58.                     'class' => 'form-check-label'
  59.                 ]
  60.             ])
  61.             ->add('designation'TextType::class, [
  62.                 'label' => 'Désignation',
  63.                 'required' => true,
  64.                 'attr' => [
  65.                     'class' => 'form-control',
  66.                     'placeholder' => 'Description de la charge'
  67.                 ]
  68.             ])
  69.             ->add('categorieDesignation'ChoiceType::class, [
  70.                 'label' => 'Catégorie',
  71.                 'choices' => [
  72.                     'Employés' => 'employes',
  73.                     'Administratif' => 'administratif',
  74.                     'Locaux' => 'locaux',
  75.                     'Fonctionnement' => 'fonctionnement',
  76.                     'Déplacement' => 'deplacement',
  77.                     'Restauration' => 'restauration',
  78.                     'Fourniture' => 'fourniture',
  79.                     'Autres' => 'autres',
  80.                 ],
  81.                 'required' => true,
  82.                 'attr' => [
  83.                     'class' => 'form-select'
  84.                 ]
  85.             ])
  86.             ->add('categoriePersonnalisee'TextType::class, [
  87.                 'label' => 'Catégorie personnalisée',
  88.                 'required' => false,
  89.                 'help' => 'Optionnel - Utilisez ce champ pour ajouter une catégorie spécifique',
  90.                 'attr' => [
  91.                     'class' => 'form-control',
  92.                     'placeholder' => 'Ex: Marketing, Formation...'
  93.                 ]
  94.             ])
  95.             ->add('montantHT'NumberType::class, [
  96.                 'label' => 'Montant HT',
  97.                 'required' => true,
  98.                 'scale' => 2,
  99.                 'html5' => true,
  100.                 'attr' => [
  101.                     'class' => 'form-control',
  102.                     'step' => '0.01',
  103.                     'min' => '0',
  104.                     'placeholder' => '0.00'
  105.                 ],
  106.                 'constraints' => [
  107.                     new NotBlank(['message' => 'Le montant HT est requis']),
  108.                     new Type(['type' => 'numeric''message' => 'Le montant doit être un nombre']),
  109.                     new Range(['min' => 0'minMessage' => 'Le montant ne peut pas être négatif'])
  110.                 ]
  111.             ])
  112.             ->add('tauxTVA'TextType::class, [
  113.                 'label' => 'Taux TVA',
  114.                 'required' => true,
  115.                 'attr' => [
  116.                     'class' => 'form-control',
  117.                     'placeholder' => '20.00'
  118.                 ],
  119.                 'constraints' => [
  120.                     new NotBlank(['message' => 'Le taux de TVA est requis'])
  121.                 ]
  122.             ])
  123.             ->add('montantTVA'NumberType::class, [
  124.                 'label' => 'Montant TVA',
  125.                 'required' => true,
  126.                 'scale' => 2,
  127.                 'html5' => true,
  128.                 'attr' => [
  129.                     'class' => 'form-control',
  130.                     'step' => '0.01',
  131.                     'min' => '0',
  132.                     'placeholder' => '0.00'
  133.                 ],
  134.                 'constraints' => [
  135.                     new NotBlank(['message' => 'Le montant TVA est requis']),
  136.                     new Type(['type' => 'numeric''message' => 'Le montant doit être un nombre']),
  137.                     new Range(['min' => 0'minMessage' => 'Le montant ne peut pas être négatif'])
  138.                 ]
  139.             ])
  140.             ->add('montantTTC'NumberType::class, [
  141.                 'label' => 'Montant TTC',
  142.                 'required' => true,
  143.                 'scale' => 2,
  144.                 'html5' => true,
  145.                 'attr' => [
  146.                     'class' => 'form-control',
  147.                     'step' => '0.01',
  148.                     'min' => '0',
  149.                     'placeholder' => '0.00'
  150.                 ],
  151.                 'constraints' => [
  152.                     new NotBlank(['message' => 'Le montant TTC est requis']),
  153.                     new Type(['type' => 'numeric''message' => 'Le montant doit être un nombre']),
  154.                     new Range(['min' => 0'minMessage' => 'Le montant ne peut pas être négatif'])
  155.                 ]
  156.             ])
  157.             ->add('isMensuel'CheckboxType::class, [
  158.                 'label' => 'Charge mensuelle récurrente',
  159.                 'required' => false,
  160.                 'help' => 'Cochez cette case pour les factures qui se répètent chaque mois',
  161.                 'attr' => [
  162.                     'class' => 'form-check-input'
  163.                 ],
  164.                 'label_attr' => [
  165.                     'class' => 'form-check-label'
  166.                 ]
  167.             ])
  168.             ->add('datePaiement'DateType::class, [
  169.                 'widget' => 'single_text',
  170.                 'label' => 'Date Paiement',
  171.                 'required' => false,
  172.                 'attr' => [
  173.                     'class' => 'form-control'
  174.                 ]
  175.             ])
  176.         ;
  177.         // Ajouter un listener pour normaliser les montants avant la soumission
  178.         $builder->addEventListener(FormEvents::PRE_SUBMIT, function (FormEvent $event) {
  179.             $data $event->getData();
  180.             
  181.             // Convertir les montants en format décimal
  182.             if (isset($data['montantHT'])) {
  183.                 $data['montantHT'] = str_replace([' '','], ['''.'], $data['montantHT']);
  184.             }
  185.             if (isset($data['montantTVA'])) {
  186.                 $data['montantTVA'] = str_replace([' '','], ['''.'], $data['montantTVA']);
  187.             }
  188.             if (isset($data['montantTTC'])) {
  189.                 $data['montantTTC'] = str_replace([' '','], ['''.'], $data['montantTTC']);
  190.             }
  191.             $event->setData($data);
  192.         });
  193.     }
  194.     public function configureOptions(OptionsResolver $resolver): void
  195.     {
  196.         $resolver->setDefaults([
  197.             'data_class' => Charge::class,
  198.         ]);
  199.     }
  200. }