<?php
namespace App\Form;
use App\Entity\Charge;
use App\Entity\User;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Form\Extension\Core\Type\DateType;
use Symfony\Component\Form\Extension\Core\Type\NumberType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Doctrine\ORM\EntityRepository;
use Symfony\Component\Validator\Constraints\NotBlank;
use Symfony\Component\Validator\Constraints\Type;
use Symfony\Component\Validator\Constraints\Range;
use Symfony\Component\Form\FormEvent;
use Symfony\Component\Form\FormEvents;
class ChargeType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options): void
{
$builder
->add('date', DateType::class, [
'widget' => 'single_text',
'label' => 'Date',
'required' => true,
'attr' => [
'class' => 'form-control'
]
])
->add('agent', EntityType::class, [
'class' => User::class,
'choice_label' => 'username',
'label' => 'Agent',
'required' => true,
'query_builder' => function (EntityRepository $er) {
return $er->createQueryBuilder('u')
->where('u.roles LIKE :role')
->setParameter('role', '%ROLE_TEAM%')
->orderBy('u.username', 'ASC');
},
'attr' => [
'class' => 'form-select'
],
'preferred_choices' => function (User $user) {
return $user->getUsername() === 'Contact';
}
])
->add('isEntrepriseCharge', CheckboxType::class, [
'label' => 'Charge de l\'entreprise',
'required' => false,
'attr' => [
'class' => 'form-check-input'
],
'label_attr' => [
'class' => 'form-check-label'
]
])
->add('designation', TextType::class, [
'label' => 'Désignation',
'required' => true,
'attr' => [
'class' => 'form-control',
'placeholder' => 'Description de la charge'
]
])
->add('categorieDesignation', ChoiceType::class, [
'label' => 'Catégorie',
'choices' => [
'Employés' => 'employes',
'Administratif' => 'administratif',
'Locaux' => 'locaux',
'Fonctionnement' => 'fonctionnement',
'Déplacement' => 'deplacement',
'Restauration' => 'restauration',
'Fourniture' => 'fourniture',
'Autres' => 'autres',
],
'required' => true,
'attr' => [
'class' => 'form-select'
]
])
->add('categoriePersonnalisee', TextType::class, [
'label' => 'Catégorie personnalisée',
'required' => false,
'help' => 'Optionnel - Utilisez ce champ pour ajouter une catégorie spécifique',
'attr' => [
'class' => 'form-control',
'placeholder' => 'Ex: Marketing, Formation...'
]
])
->add('montantHT', NumberType::class, [
'label' => 'Montant HT',
'required' => true,
'scale' => 2,
'html5' => true,
'attr' => [
'class' => 'form-control',
'step' => '0.01',
'min' => '0',
'placeholder' => '0.00'
],
'constraints' => [
new NotBlank(['message' => 'Le montant HT est requis']),
new Type(['type' => 'numeric', 'message' => 'Le montant doit être un nombre']),
new Range(['min' => 0, 'minMessage' => 'Le montant ne peut pas être négatif'])
]
])
->add('tauxTVA', TextType::class, [
'label' => 'Taux TVA',
'required' => true,
'attr' => [
'class' => 'form-control',
'placeholder' => '20.00'
],
'constraints' => [
new NotBlank(['message' => 'Le taux de TVA est requis'])
]
])
->add('montantTVA', NumberType::class, [
'label' => 'Montant TVA',
'required' => true,
'scale' => 2,
'html5' => true,
'attr' => [
'class' => 'form-control',
'step' => '0.01',
'min' => '0',
'placeholder' => '0.00'
],
'constraints' => [
new NotBlank(['message' => 'Le montant TVA est requis']),
new Type(['type' => 'numeric', 'message' => 'Le montant doit être un nombre']),
new Range(['min' => 0, 'minMessage' => 'Le montant ne peut pas être négatif'])
]
])
->add('montantTTC', NumberType::class, [
'label' => 'Montant TTC',
'required' => true,
'scale' => 2,
'html5' => true,
'attr' => [
'class' => 'form-control',
'step' => '0.01',
'min' => '0',
'placeholder' => '0.00'
],
'constraints' => [
new NotBlank(['message' => 'Le montant TTC est requis']),
new Type(['type' => 'numeric', 'message' => 'Le montant doit être un nombre']),
new Range(['min' => 0, 'minMessage' => 'Le montant ne peut pas être négatif'])
]
])
->add('isMensuel', CheckboxType::class, [
'label' => 'Charge mensuelle récurrente',
'required' => false,
'help' => 'Cochez cette case pour les factures qui se répètent chaque mois',
'attr' => [
'class' => 'form-check-input'
],
'label_attr' => [
'class' => 'form-check-label'
]
])
->add('datePaiement', DateType::class, [
'widget' => 'single_text',
'label' => 'Date Paiement',
'required' => false,
'attr' => [
'class' => 'form-control'
]
])
;
// Ajouter un listener pour normaliser les montants avant la soumission
$builder->addEventListener(FormEvents::PRE_SUBMIT, function (FormEvent $event) {
$data = $event->getData();
// Convertir les montants en format décimal
if (isset($data['montantHT'])) {
$data['montantHT'] = str_replace([' ', ','], ['', '.'], $data['montantHT']);
}
if (isset($data['montantTVA'])) {
$data['montantTVA'] = str_replace([' ', ','], ['', '.'], $data['montantTVA']);
}
if (isset($data['montantTTC'])) {
$data['montantTTC'] = str_replace([' ', ','], ['', '.'], $data['montantTTC']);
}
$event->setData($data);
});
}
public function configureOptions(OptionsResolver $resolver): void
{
$resolver->setDefaults([
'data_class' => Charge::class,
]);
}
}