From f9280db146dfd82403d6e24d4f9c1c3ffb1e250b Mon Sep 17 00:00:00 2001 From: Serreau Jovann Date: Wed, 21 Jan 2026 15:41:26 +0100 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20feat(Devis):=20Ajoute=20relation=20?= =?UTF-8?q?one-to-one=20avec=20Contrats=20et=20met=20=C3=A0=20jour=20l'ent?= =?UTF-8?q?it=C3=A9.=20=E2=9E=95=20feat(contrats):=20Ajoute=20le=20formula?= =?UTF-8?q?ire=20de=20cr=C3=A9ation=20de=20contrats.=20=F0=9F=93=9D=20feat?= =?UTF-8?q?(Contrats):=20Cr=C3=A9e=20le=20type=20de=20formulaire=20Contrat?= =?UTF-8?q?sType.=20=E2=9C=A8=20feat(Customer):=20Ajoute=20la=20relation?= =?UTF-8?q?=20one-to-many=20avec=20Contrats.=20=E2=9E=95=20feat(contrats):?= =?UTF-8?q?=20Ajoute=20la=20vue=20de=20cr=C3=A9ation=20de=20contrats.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- migrations/Version20260121135907.php | 39 ++ migrations/Version20260121140314.php | 40 ++ migrations/Version20260121140558.php | 44 +++ migrations/Version20260121141506.php | 39 ++ migrations/Version20260121143754.php | 38 ++ migrations/Version20260121143811.php | 34 ++ .../Dashboard/ContratsController.php | 23 +- src/Entity/Contrats.php | 364 ++++++++++++++++++ src/Entity/ContratsPayments.php | 80 ++++ src/Entity/Customer.php | 37 ++ src/Entity/Devis.php | 25 ++ src/Form/Type/ContratsType.php | 124 ++++++ src/Repository/ContratsPaymentsRepository.php | 43 +++ src/Repository/ContratsRepository.php | 43 +++ templates/dashboard/contrats/add.twig | 143 ++++++- 15 files changed, 1114 insertions(+), 2 deletions(-) create mode 100644 migrations/Version20260121135907.php create mode 100644 migrations/Version20260121140314.php create mode 100644 migrations/Version20260121140558.php create mode 100644 migrations/Version20260121141506.php create mode 100644 migrations/Version20260121143754.php create mode 100644 migrations/Version20260121143811.php create mode 100644 src/Entity/Contrats.php create mode 100644 src/Entity/ContratsPayments.php create mode 100644 src/Form/Type/ContratsType.php create mode 100644 src/Repository/ContratsPaymentsRepository.php create mode 100644 src/Repository/ContratsRepository.php diff --git a/migrations/Version20260121135907.php b/migrations/Version20260121135907.php new file mode 100644 index 0000000..b6a4e4f --- /dev/null +++ b/migrations/Version20260121135907.php @@ -0,0 +1,39 @@ +addSql('CREATE TABLE contrats (id SERIAL NOT NULL, customer_id INT DEFAULT NULL, devis_id INT DEFAULT NULL, num_reservation VARCHAR(255) NOT NULL, create_at TIMESTAMP(0) WITHOUT TIME ZONE NOT NULL, PRIMARY KEY(id))'); + $this->addSql('CREATE INDEX IDX_7268396C9395C3F3 ON contrats (customer_id)'); + $this->addSql('CREATE UNIQUE INDEX UNIQ_7268396C41DEFADA ON contrats (devis_id)'); + $this->addSql('COMMENT ON COLUMN contrats.create_at IS \'(DC2Type:datetime_immutable)\''); + $this->addSql('ALTER TABLE contrats ADD CONSTRAINT FK_7268396C9395C3F3 FOREIGN KEY (customer_id) REFERENCES customer (id) NOT DEFERRABLE INITIALLY IMMEDIATE'); + $this->addSql('ALTER TABLE contrats ADD CONSTRAINT FK_7268396C41DEFADA FOREIGN KEY (devis_id) REFERENCES devis (id) NOT DEFERRABLE INITIALLY IMMEDIATE'); + } + + public function down(Schema $schema): void + { + // this down() migration is auto-generated, please modify it to your needs + $this->addSql('CREATE SCHEMA public'); + $this->addSql('ALTER TABLE contrats DROP CONSTRAINT FK_7268396C9395C3F3'); + $this->addSql('ALTER TABLE contrats DROP CONSTRAINT FK_7268396C41DEFADA'); + $this->addSql('DROP TABLE contrats'); + } +} diff --git a/migrations/Version20260121140314.php b/migrations/Version20260121140314.php new file mode 100644 index 0000000..f11edc2 --- /dev/null +++ b/migrations/Version20260121140314.php @@ -0,0 +1,40 @@ +addSql('ALTER TABLE contrats ADD adress_event VARCHAR(255) NOT NULL'); + $this->addSql('ALTER TABLE contrats ADD adress2_event VARCHAR(255) NOT NULL'); + $this->addSql('ALTER TABLE contrats ADD adress3_event VARCHAR(255) DEFAULT NULL'); + $this->addSql('ALTER TABLE contrats ADD zip_code_event VARCHAR(255) NOT NULL'); + $this->addSql('ALTER TABLE contrats ADD town_event VARCHAR(255) NOT NULL'); + } + + public function down(Schema $schema): void + { + // this down() migration is auto-generated, please modify it to your needs + $this->addSql('CREATE SCHEMA public'); + $this->addSql('ALTER TABLE contrats DROP adress_event'); + $this->addSql('ALTER TABLE contrats DROP adress2_event'); + $this->addSql('ALTER TABLE contrats DROP adress3_event'); + $this->addSql('ALTER TABLE contrats DROP zip_code_event'); + $this->addSql('ALTER TABLE contrats DROP town_event'); + } +} diff --git a/migrations/Version20260121140558.php b/migrations/Version20260121140558.php new file mode 100644 index 0000000..2ec6332 --- /dev/null +++ b/migrations/Version20260121140558.php @@ -0,0 +1,44 @@ +addSql('ALTER TABLE contrats ADD type VARCHAR(255) NOT NULL'); + $this->addSql('ALTER TABLE contrats ADD details TEXT NOT NULL'); + $this->addSql('ALTER TABLE contrats ADD type_sol VARCHAR(255) NOT NULL'); + $this->addSql('ALTER TABLE contrats ADD pente VARCHAR(255) NOT NULL'); + $this->addSql('ALTER TABLE contrats ADD access TEXT NOT NULL'); + $this->addSql('ALTER TABLE contrats ADD distance_power DOUBLE PRECISION NOT NULL'); + $this->addSql('ALTER TABLE contrats ADD notes TEXT NOT NULL'); + } + + public function down(Schema $schema): void + { + // this down() migration is auto-generated, please modify it to your needs + $this->addSql('CREATE SCHEMA public'); + $this->addSql('ALTER TABLE contrats DROP type'); + $this->addSql('ALTER TABLE contrats DROP details'); + $this->addSql('ALTER TABLE contrats DROP type_sol'); + $this->addSql('ALTER TABLE contrats DROP pente'); + $this->addSql('ALTER TABLE contrats DROP access'); + $this->addSql('ALTER TABLE contrats DROP distance_power'); + $this->addSql('ALTER TABLE contrats DROP notes'); + } +} diff --git a/migrations/Version20260121141506.php b/migrations/Version20260121141506.php new file mode 100644 index 0000000..d01aa7d --- /dev/null +++ b/migrations/Version20260121141506.php @@ -0,0 +1,39 @@ +addSql('CREATE TABLE contrats_payments (id SERIAL NOT NULL, contrat_id INT DEFAULT NULL, type VARCHAR(255) NOT NULL, payment_id VARCHAR(255) NOT NULL, state VARCHAR(255) NOT NULL, PRIMARY KEY(id))'); + $this->addSql('CREATE INDEX IDX_95744AFC1823061F ON contrats_payments (contrat_id)'); + $this->addSql('ALTER TABLE contrats_payments ADD CONSTRAINT FK_95744AFC1823061F FOREIGN KEY (contrat_id) REFERENCES contrats (id) NOT DEFERRABLE INITIALLY IMMEDIATE'); + $this->addSql('ALTER TABLE contrats ADD is_signed BOOLEAN NOT NULL'); + $this->addSql('ALTER TABLE contrats ADD sign_id VARCHAR(255) DEFAULT NULL'); + } + + public function down(Schema $schema): void + { + // this down() migration is auto-generated, please modify it to your needs + $this->addSql('CREATE SCHEMA public'); + $this->addSql('ALTER TABLE contrats_payments DROP CONSTRAINT FK_95744AFC1823061F'); + $this->addSql('DROP TABLE contrats_payments'); + $this->addSql('ALTER TABLE contrats DROP is_signed'); + $this->addSql('ALTER TABLE contrats DROP sign_id'); + } +} diff --git a/migrations/Version20260121143754.php b/migrations/Version20260121143754.php new file mode 100644 index 0000000..5eb27cf --- /dev/null +++ b/migrations/Version20260121143754.php @@ -0,0 +1,38 @@ +addSql('CREATE TABLE env_at (id SERIAL NOT NULL, PRIMARY KEY(id))'); + $this->addSql('ALTER TABLE contrats ADD date_at TIMESTAMP(0) WITHOUT TIME ZONE NOT NULL'); + $this->addSql('ALTER TABLE contrats ADD end_at TIMESTAMP(0) WITHOUT TIME ZONE NOT NULL'); + $this->addSql('COMMENT ON COLUMN contrats.date_at IS \'(DC2Type:datetime_immutable)\''); + $this->addSql('COMMENT ON COLUMN contrats.end_at IS \'(DC2Type:datetime_immutable)\''); + } + + public function down(Schema $schema): void + { + // this down() migration is auto-generated, please modify it to your needs + $this->addSql('CREATE SCHEMA public'); + $this->addSql('DROP TABLE env_at'); + $this->addSql('ALTER TABLE contrats DROP date_at'); + $this->addSql('ALTER TABLE contrats DROP end_at'); + } +} diff --git a/migrations/Version20260121143811.php b/migrations/Version20260121143811.php new file mode 100644 index 0000000..6d75a15 --- /dev/null +++ b/migrations/Version20260121143811.php @@ -0,0 +1,34 @@ +addSql('DROP SEQUENCE env_at_id_seq CASCADE'); + $this->addSql('DROP TABLE env_at'); + } + + public function down(Schema $schema): void + { + // this down() migration is auto-generated, please modify it to your needs + $this->addSql('CREATE SCHEMA public'); + $this->addSql('CREATE SEQUENCE env_at_id_seq INCREMENT BY 1 MINVALUE 1 START 1'); + $this->addSql('CREATE TABLE env_at (id SERIAL NOT NULL, PRIMARY KEY(id))'); + } +} diff --git a/src/Controller/Dashboard/ContratsController.php b/src/Controller/Dashboard/ContratsController.php index 3ece1dd..caae209 100644 --- a/src/Controller/Dashboard/ContratsController.php +++ b/src/Controller/Dashboard/ContratsController.php @@ -2,6 +2,9 @@ namespace App\Controller\Dashboard; +use App\Entity\Contrats; +use App\Entity\Devis; +use App\Form\Type\ContratsType; use App\Logger\AppLogger; use App\Repository\AccountRepository; use App\Repository\DevisRepository; @@ -29,9 +32,27 @@ class ContratsController extends AbstractController #[Route(path: '/crm/contrats/add', name: 'app_crm_contrats_create', options: ['sitemap' => false], methods: ['GET'])] public function contratsAdd(Request $request,DevisRepository $devisRepository, AppLogger $appLogger): Response { + $devis = $devisRepository->find($request->get('idDevis',0)); + + $c = new Contrats(); + if($devis instanceof Devis){ + $c->setCustomer($devis->getCustomer()); + $c->setDevis($devis); + $c->setAddressEvent($devis->getAddressShip()->getAddress()); + $c->setAddress2Event($devis->getAddressShip()->getAddress2()); + $c->setAddress3Event($devis->getAddressShip()->getAddress3()); + $c->setZipCodeEvent($devis->getAddressShip()->getZipcode()); + $c->setTownEvent($devis->getAddressShip()->getCity()); + } + + $form = $this->createForm(ContratsType::class,$c); + + + $appLogger->record('VIEW', 'Consultation création d\'un contract'); return $this->render('dashboard/contrats/add.twig',[ - 'devis' => $devisRepository->find($request->get('idDevis',0)), + 'devis' => $devis, + 'form'=> $form->createView(), ]); } diff --git a/src/Entity/Contrats.php b/src/Entity/Contrats.php new file mode 100644 index 0000000..cd93a77 --- /dev/null +++ b/src/Entity/Contrats.php @@ -0,0 +1,364 @@ + + */ + #[ORM\OneToMany(targetEntity: ContratsPayments::class, mappedBy: 'contrat')] + private Collection $contratsPayments; + + #[ORM\Column] + private ?\DateTimeImmutable $dateAt = null; + + #[ORM\Column] + private ?\DateTimeImmutable $endAt = null; + + public function __construct() + { + $this->contratsPayments = new ArrayCollection(); + } + + public function getId(): ?int + { + return $this->id; + } + + public function getCustomer(): ?Customer + { + return $this->customer; + } + + public function setCustomer(?Customer $customer): static + { + $this->customer = $customer; + + return $this; + } + + public function getDevis(): ?Devis + { + return $this->devis; + } + + public function setDevis(?Devis $devis): static + { + $this->devis = $devis; + + return $this; + } + + public function getNumReservation(): ?string + { + return $this->numReservation; + } + + public function setNumReservation(string $numReservation): static + { + $this->numReservation = $numReservation; + + return $this; + } + + public function getCreateAt(): ?\DateTimeImmutable + { + return $this->createAt; + } + + public function setCreateAt(\DateTimeImmutable $createAt): static + { + $this->createAt = $createAt; + + return $this; + } + + public function getAddressEvent(): ?string + { + return $this->adressEvent; + } + + public function setAddressEvent(string $adressEvent): static + { + $this->adressEvent = $adressEvent; + + return $this; + } + + public function getAddress2Event(): ?string + { + return $this->adress2Event; + } + + public function setAddress2Event(string $adress2Event): static + { + $this->adress2Event = $adress2Event; + + return $this; + } + + public function getAddress3Event(): ?string + { + return $this->adress3Event; + } + + public function setAddress3Event(?string $adress3Event): static + { + $this->adress3Event = $adress3Event; + + return $this; + } + + public function getZipCodeEvent(): ?string + { + return $this->zipCodeEvent; + } + + public function setZipCodeEvent(string $zipCode): static + { + $this->zipCodeEvent = $zipCode; + + return $this; + } + + public function getTownEvent(): ?string + { + return $this->townEvent; + } + + public function setTownEvent(string $town): static + { + $this->townEvent = $town; + + return $this; + } + + public function getType(): ?string + { + return $this->type; + } + + public function setType(string $type): static + { + $this->type = $type; + + return $this; + } + + public function getDetails(): ?string + { + return $this->details; + } + + public function setDetails(string $details): static + { + $this->details = $details; + + return $this; + } + + public function getTypeSol(): ?string + { + return $this->typeSol; + } + + public function setTypeSol(string $typeSol): static + { + $this->typeSol = $typeSol; + + return $this; + } + + public function getPente(): ?string + { + return $this->pente; + } + + public function setPente(string $pente): static + { + $this->pente = $pente; + + return $this; + } + + public function getAccess(): ?string + { + return $this->access; + } + + public function setAccess(string $access): static + { + $this->access = $access; + + return $this; + } + + public function getDistancePower(): ?float + { + return $this->distancePower; + } + + public function setDistancePower(float $distancePower): static + { + $this->distancePower = $distancePower; + + return $this; + } + + public function getNotes(): ?string + { + return $this->notes; + } + + public function setNotes(string $notes): static + { + $this->notes = $notes; + + return $this; + } + + public function isSigned(): ?bool + { + return $this->isSigned; + } + + public function setIsSigned(bool $isSigned): static + { + $this->isSigned = $isSigned; + + return $this; + } + + public function getSignID(): ?string + { + return $this->signID; + } + + public function setSignID(?string $signID): static + { + $this->signID = $signID; + + return $this; + } + + /** + * @return Collection + */ + public function getContratsPayments(): Collection + { + return $this->contratsPayments; + } + + public function addContratsPayment(ContratsPayments $contratsPayment): static + { + if (!$this->contratsPayments->contains($contratsPayment)) { + $this->contratsPayments->add($contratsPayment); + $contratsPayment->setContrat($this); + } + + return $this; + } + + public function removeContratsPayment(ContratsPayments $contratsPayment): static + { + if ($this->contratsPayments->removeElement($contratsPayment)) { + // set the owning side to null (unless already changed) + if ($contratsPayment->getContrat() === $this) { + $contratsPayment->setContrat(null); + } + } + + return $this; + } + + public function getDateAt(): ?\DateTimeImmutable + { + return $this->dateAt; + } + + public function setDateAt(\DateTimeImmutable $dateAt): static + { + $this->dateAt = $dateAt; + + return $this; + } + + public function getEndAt(): ?\DateTimeImmutable + { + return $this->endAt; + } + + public function setEndAt(\DateTimeImmutable $endAt): static + { + $this->endAt = $endAt; + + return $this; + } +} diff --git a/src/Entity/ContratsPayments.php b/src/Entity/ContratsPayments.php new file mode 100644 index 0000000..1dd33a5 --- /dev/null +++ b/src/Entity/ContratsPayments.php @@ -0,0 +1,80 @@ +id; + } + + public function getContrat(): ?Contrats + { + return $this->contrat; + } + + public function setContrat(?Contrats $contrat): static + { + $this->contrat = $contrat; + + return $this; + } + + public function getType(): ?string + { + return $this->type; + } + + public function setType(string $type): static + { + $this->type = $type; + + return $this; + } + + public function getPaymentId(): ?string + { + return $this->paymentId; + } + + public function setPaymentId(string $paymentId): static + { + $this->paymentId = $paymentId; + + return $this; + } + + public function getState(): ?string + { + return $this->state; + } + + public function setState(string $state): static + { + $this->state = $state; + + return $this; + } +} diff --git a/src/Entity/Customer.php b/src/Entity/Customer.php index 3898665..fc556de 100644 --- a/src/Entity/Customer.php +++ b/src/Entity/Customer.php @@ -57,11 +57,18 @@ class Customer #[ORM\OneToMany(targetEntity: ProductReserve::class, mappedBy: 'customer')] private Collection $productReserves; + /** + * @var Collection + */ + #[ORM\OneToMany(targetEntity: Contrats::class, mappedBy: 'customer')] + private Collection $contrats; + public function __construct() { $this->customerAddresses = new ArrayCollection(); $this->devis = new ArrayCollection(); $this->productReserves = new ArrayCollection(); + $this->contrats = new ArrayCollection(); } public function getId(): ?int @@ -254,4 +261,34 @@ class Customer return $this; } + + /** + * @return Collection + */ + public function getContrats(): Collection + { + return $this->contrats; + } + + public function addContrat(Contrats $contrat): static + { + if (!$this->contrats->contains($contrat)) { + $this->contrats->add($contrat); + $contrat->setCustomer($this); + } + + return $this; + } + + public function removeContrat(Contrats $contrat): static + { + if ($this->contrats->removeElement($contrat)) { + // set the owning side to null (unless already changed) + if ($contrat->getCustomer() === $this) { + $contrat->setCustomer(null); + } + } + + return $this; + } } diff --git a/src/Entity/Devis.php b/src/Entity/Devis.php index b346fc9..1078fbf 100644 --- a/src/Entity/Devis.php +++ b/src/Entity/Devis.php @@ -80,6 +80,9 @@ class Devis #[ORM\OneToOne(mappedBy: 'devis', cascade: ['persist', 'remove'])] private ?ProductReserve $productReserve = null; + #[ORM\OneToOne(mappedBy: 'devis', cascade: ['persist', 'remove'])] + private ?Contrats $contrats = null; + public function __construct() { $this->devisLines = new ArrayCollection(); @@ -450,4 +453,26 @@ class Devis return $this; } + public function getContrats(): ?Contrats + { + return $this->contrats; + } + + public function setContrats(?Contrats $contrats): static + { + // unset the owning side of the relation if necessary + if ($contrats === null && $this->contrats !== null) { + $this->contrats->setDevis(null); + } + + // set the owning side of the relation if necessary + if ($contrats !== null && $contrats->getDevis() !== $this) { + $contrats->setDevis($this); + } + + $this->contrats = $contrats; + + return $this; + } + } diff --git a/src/Form/Type/ContratsType.php b/src/Form/Type/ContratsType.php new file mode 100644 index 0000000..2a0d6be --- /dev/null +++ b/src/Form/Type/ContratsType.php @@ -0,0 +1,124 @@ +add('addressEvent',TextType::class,[ + 'label' =>'Adresse', + 'required' => true, + ]) + ->add('address2Event',TextType::class,[ + 'label' =>'Adresse 2', + 'required' => true, + ]) + ->add('address3Event',TextType::class,[ + 'label' =>'Adresse 3', + 'required' => true, + ]) + ->add('dateAt',DateTimeType::class,[ + 'label' =>'Date', + 'widget' => 'single_text', + ]) + ->add('endAt',DateTimeType::class,[ + 'label' =>'Date de fin', + 'widget' => 'single_text', + ]) + ->add('zipCodeEvent',TextType::class,[ + 'label' =>'Code postal', + 'required' => true, + ]) + ->add('townEvent',TextType::class,[ + 'label' =>'Ville', + 'required' => true, + ]) + ->add('customer',EntityType::class,[ + 'label' => 'Client', + 'required' => true, + 'class' => Customer::class, + // Utilisation d'une fonction anonyme pour concaténer Nom et Prénom + 'choice_label' => function (Customer $customer) { + return sprintf('%s - %s', + strtoupper($customer->getSurname()), // Nom en majuscules + $customer->getName() // Prénom + ); + }, + 'placeholder' => 'Sélectionnez un client...', + + ]) + ->add('type',ChoiceType::class,[ + 'label' => 'Type', + 'required' => true, + 'choices' => [ + 'Anniversaire enfant' => 'Anniversaire enfant', + 'Kermesse scolaire' => 'Kermesse scolaire', + 'Fête communale' => 'Fête communale', + 'Événement d\'entreprise' => 'Événement d\'entreprise', + 'Mariage' => 'Mariage', + 'Autre' => 'Autre' + ] + ]) + ->add('details',TextareaType::class,[ + 'label' => 'Description', + 'required' => false, + + ]) + + ->add('typeSol',ChoiceType::class,[ + 'label' => 'Type de sol', + 'required' => true, + 'choices' => [ + 'Pelouse' => 'Pelouse', + 'Béton' => 'Béton', + 'Sable' => 'Sable', + 'Gourdon' => 'Gourdon', + 'Autre' => 'Autre' + ] + ]) + ->add('pente',ChoiceType::class,[ + 'label' => 'Pente', + 'required' => true, + 'choices' => [ + 'Plat' => 'Plat', + 'Léger' => 'Léger', + 'Important' => 'Important', + ] + ]) + ->add('access',TextareaType::class,[ + 'label' => 'Contraintes d\'accès', + 'required' => false, + ]) + ->add('distancePower',NumberType::class,[ + 'label' => 'Distance prise ↔ structure ', + 'required' => false, + ]) + + ->add('notes',TextareaType::class,[ + 'label' => 'Notes', + 'required' => false, + ]) + + ; + } + + public function configureOptions(OptionsResolver $resolver) + { + $resolver->setDefault('data_class',Contrats::class); + } +} diff --git a/src/Repository/ContratsPaymentsRepository.php b/src/Repository/ContratsPaymentsRepository.php new file mode 100644 index 0000000..3004128 --- /dev/null +++ b/src/Repository/ContratsPaymentsRepository.php @@ -0,0 +1,43 @@ + + */ +class ContratsPaymentsRepository extends ServiceEntityRepository +{ + public function __construct(ManagerRegistry $registry) + { + parent::__construct($registry, ContratsPayments::class); + } + + // /** + // * @return ContratsPayments[] Returns an array of ContratsPayments objects + // */ + // public function findByExampleField($value): array + // { + // return $this->createQueryBuilder('c') + // ->andWhere('c.exampleField = :val') + // ->setParameter('val', $value) + // ->orderBy('c.id', 'ASC') + // ->setMaxResults(10) + // ->getQuery() + // ->getResult() + // ; + // } + + // public function findOneBySomeField($value): ?ContratsPayments + // { + // return $this->createQueryBuilder('c') + // ->andWhere('c.exampleField = :val') + // ->setParameter('val', $value) + // ->getQuery() + // ->getOneOrNullResult() + // ; + // } +} diff --git a/src/Repository/ContratsRepository.php b/src/Repository/ContratsRepository.php new file mode 100644 index 0000000..2edf493 --- /dev/null +++ b/src/Repository/ContratsRepository.php @@ -0,0 +1,43 @@ + + */ +class ContratsRepository extends ServiceEntityRepository +{ + public function __construct(ManagerRegistry $registry) + { + parent::__construct($registry, Contrats::class); + } + + // /** + // * @return Contrats[] Returns an array of Contrats objects + // */ + // public function findByExampleField($value): array + // { + // return $this->createQueryBuilder('c') + // ->andWhere('c.exampleField = :val') + // ->setParameter('val', $value) + // ->orderBy('c.id', 'ASC') + // ->setMaxResults(10) + // ->getQuery() + // ->getResult() + // ; + // } + + // public function findOneBySomeField($value): ?Contrats + // { + // return $this->createQueryBuilder('c') + // ->andWhere('c.exampleField = :val') + // ->setParameter('val', $value) + // ->getQuery() + // ->getOneOrNullResult() + // ; + // } +} diff --git a/templates/dashboard/contrats/add.twig b/templates/dashboard/contrats/add.twig index 71e9768..0583700 100644 --- a/templates/dashboard/contrats/add.twig +++ b/templates/dashboard/contrats/add.twig @@ -1,8 +1,8 @@ {% extends 'dashboard/base.twig' %} - {% block title %}Création Contrat de location{% endblock %} {% block title_header %}Nouveau Contrat de location{% endblock %} + {% block actions %} @@ -13,4 +13,145 @@ {% endblock %} {% block body %} +
+ {{ form_start(form) }} + +
+ + {# --- BLOC 01 : CLIENT & VIGILANCE --- #} +
+
+

+ 01 + Client & Type +

+ +
+
+ {{ form_label(form.customer, 'Client', {'label_attr': {'class': 'text-[10px] font-black text-slate-500 uppercase tracking-[0.2em] ml-1 mb-2 block'}}) }} + {{ form_widget(form.customer, {'attr': {'class': 'w-full bg-slate-950/50 border-white/5 rounded-2xl text-white focus:ring-blue-500/20 focus:border-blue-500 transition-all py-3.5 px-5'}}) }} +
+ +
+ {{ form_label(form.type, 'Type de contrat', {'label_attr': {'class': 'text-[10px] font-black text-slate-500 uppercase tracking-[0.2em] ml-1 mb-2 block'}}) }} + {{ form_widget(form.type, {'attr': {'class': 'w-full bg-slate-950/50 border-white/5 rounded-2xl text-white focus:ring-blue-500/20 focus:border-blue-500 transition-all py-3.5 px-5'}}) }} +
+ +
+ {{ form_label(form.notes, 'Notes de vigilance', {'label_attr': {'class': 'text-[10px] font-black text-rose-500 uppercase tracking-[0.2em] ml-1 mb-2 block'}}) }} +
+ {{ form_widget(form.notes, { + 'attr': { + 'class': 'w-full bg-rose-500/5 border border-rose-500/10 rounded-2xl text-rose-100 placeholder:text-rose-500/30 focus:ring-rose-500/20 focus:border-rose-500/40 transition-all py-3.5 px-5 text-xs italic', + 'placeholder': 'Ex: Client exigeant, chien, accès compliqué...', + 'rows': '6' + } + }) }} +
+ + + +
+
+
+
+
+
+ + {# --- BLOC 02 & 03 : ADRESSE & TECHNIQUE --- #} +
+ + {# LIEU DE L'ÉVÉNEMENT #} +
+

+ 02 + Lieu de l'événement +

+ +
+
+ {{ form_label(form.addressEvent, 'Adresse principale', {'label_attr': {'class': 'text-[10px] font-black text-slate-500 uppercase tracking-[0.2em] ml-1 mb-2 block'}}) }} + {{ form_widget(form.addressEvent, {'attr': {'class': 'w-full bg-slate-950/50 border-white/5 rounded-2xl text-white focus:ring-blue-500/20 focus:border-blue-500 transition-all py-3.5 px-5'}}) }} +
+
+ {{ form_label(form.address2Event, 'Complément d\'adresse 1', {'label_attr': {'class': 'text-[10px] font-black text-slate-500 uppercase tracking-[0.2em] ml-1 mb-2 block'}}) }} + {{ form_widget(form.address2Event, {'attr': {'class': 'w-full bg-slate-950/50 border-white/5 rounded-2xl text-white focus:ring-blue-500/20 focus:border-blue-500 transition-all py-3.5 px-5'}}) }} +
+
+ {{ form_label(form.address3Event, 'Complément d\'adresse 2', {'label_attr': {'class': 'text-[10px] font-black text-slate-500 uppercase tracking-[0.2em] ml-1 mb-2 block'}}) }} + {{ form_widget(form.address3Event, {'attr': {'class': 'w-full bg-slate-950/50 border-white/5 rounded-2xl text-white focus:ring-blue-500/20 focus:border-blue-500 transition-all py-3.5 px-5'}}) }} +
+
+ {{ form_label(form.zipCodeEvent, 'Code Postal', {'label_attr': {'class': 'text-[10px] font-black text-slate-500 uppercase tracking-[0.2em] ml-1 mb-2 block'}}) }} + {{ form_widget(form.zipCodeEvent, {'attr': {'class': 'w-full bg-slate-950/50 border-white/5 rounded-2xl text-white font-mono focus:ring-blue-500/20 focus:border-blue-500 transition-all py-3.5 px-5'}}) }} +
+
+ {{ form_label(form.townEvent, 'Ville', {'label_attr': {'class': 'text-[10px] font-black text-slate-500 uppercase tracking-[0.2em] ml-1 mb-2 block'}}) }} + {{ form_widget(form.townEvent, {'attr': {'class': 'w-full bg-slate-950/50 border-white/5 rounded-2xl text-white focus:ring-blue-500/20 focus:border-blue-500 transition-all py-3.5 px-5'}}) }} +
+
+ {{ form_label(form.details, 'Précisions de livraison', {'label_attr': {'class': 'text-[10px] font-black text-slate-500 uppercase tracking-[0.2em] ml-1 mb-2 block'}}) }} + {{ form_widget(form.details, {'attr': {'class': 'w-full bg-slate-950/50 border-white/5 rounded-2xl text-white focus:ring-blue-500/20 focus:border-blue-500 transition-all py-3.5 px-5', 'rows': '2'}}) }} +
+
+
+ + {# CONTRAINTES TECHNIQUES #} +
+

+ 03 + Contraintes Techniques +

+
+
+ {{ form_label(form.typeSol, 'Nature du sol', {'label_attr': {'class': 'text-[10px] font-black text-slate-500 uppercase tracking-[0.2em] ml-1 mb-2 block'}}) }} + {{ form_widget(form.typeSol, {'attr': {'class': 'w-full bg-slate-950/50 border-white/5 rounded-2xl text-white focus:ring-amber-500/20 focus:border-amber-500 transition-all py-3.5 px-5'}}) }} +
+
+ {{ form_label(form.pente, 'Pente / Dénivelé', {'label_attr': {'class': 'text-[10px] font-black text-slate-500 uppercase tracking-[0.2em] ml-1 mb-2 block'}}) }} + {{ form_widget(form.pente, {'attr': {'class': 'w-full bg-slate-950/50 border-white/5 rounded-2xl text-white focus:ring-amber-500/20 focus:border-amber-500 transition-all py-3.5 px-5'}}) }} +
+
+ {{ form_label(form.access, 'Accès Camion', {'label_attr': {'class': 'text-[10px] font-black text-slate-500 uppercase tracking-[0.2em] ml-1 mb-2 block'}}) }} + {{ form_widget(form.access, {'attr': {'class': 'w-full bg-slate-950/50 border-white/5 rounded-2xl text-white focus:ring-amber-500/20 focus:border-amber-500 transition-all py-3.5 px-5'}}) }} +
+
+ {{ form_label(form.distancePower, 'Point électrique', {'label_attr': {'class': 'text-[10px] font-black text-slate-500 uppercase tracking-[0.2em] ml-1 mb-2 block'}}) }} + {{ form_widget(form.distancePower, {'attr': {'class': 'w-full bg-slate-950/50 border-white/5 rounded-2xl text-white focus:ring-amber-500/20 focus:border-amber-500 transition-all py-3.5 px-5'}}) }} +
+
+
+
+
+ + {# --- BLOC 04 : PÉRIODE DE LOCATION (Nouveau bloc Bento horizontal) --- #} +
+

+ 04 + Période de location +

+
+
+ {{ form_label(form.dateAt, 'Début de l\'événement', {'label_attr': {'class': 'text-[10px] font-black text-slate-500 uppercase tracking-[0.2em] ml-1 mb-2 block text-center'}}) }} + {{ form_widget(form.dateAt, {'attr': {'class': 'w-full bg-slate-950/50 border-white/5 rounded-2xl text-white text-center focus:ring-blue-500/40 focus:border-blue-500 transition-all py-5 px-5 text-lg font-black'}}) }} +
+
+ {{ form_label(form.endAt, 'Fin de l\'événement', {'label_attr': {'class': 'text-[10px] font-black text-slate-500 uppercase tracking-[0.2em] ml-1 mb-2 block text-center'}}) }} + {{ form_widget(form.endAt, {'attr': {'class': 'w-full bg-slate-950/50 border-white/5 rounded-2xl text-white text-center focus:ring-blue-500/40 focus:border-blue-500 transition-all py-5 px-5 text-lg font-black'}}) }} +
+
+
+ + {# --- BARRE D'ACTIONS --- #} +
+ +
+ + {{ form_end(form) }} +
{% endblock %}