refactor: renommer Order en Facture + meme OrderNumber partage entre Devis/Advert/Facture

Changement de modele:
- Le meme OrderNumber est partage entre Devis, Advert et Facture
  (ex: 04/2026-00001 pour les 3)
- Les relations OrderNumber passent de OneToOne a ManyToOne pour
  permettre le partage du meme numero

src/Entity/Order.php supprime, remplace par:
src/Entity/Facture.php (nouveau):
- orderNumber: ManyToOne vers OrderNumber (meme numero que l'Advert parent)
- advert: ManyToOne vers Advert (nullable)
- splitIndex: smallint, suffixe pour factures multiples sur un meme advert
  (0 = pas de suffixe, 1 = -1, 2 = -2, etc.)
- getInvoiceNumber(): retourne le numero complet avec suffixe si splitIndex > 0
  (ex: 04/2026-00001 ou 04/2026-00001-2)

src/Entity/Devis.php:
- orderNumber: OneToOne remplace par ManyToOne vers OrderNumber
- adverts: OneToMany vers Advert (inchange)

src/Entity/Advert.php:
- orderNumber: OneToOne remplace par ManyToOne vers OrderNumber
- orders: renomme en factures, OneToMany vers Facture

src/Repository/OrderRepository.php supprime, remplace par:
src/Repository/FactureRepository.php (nouveau)

migrations/Version20260402202809.php:
- Suppression table `order`, creation table facture
- Modification des contraintes unique sur devis et advert
  (unique index supprime car ManyToOne)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Serreau Jovann
2026-04-02 22:28:30 +02:00
parent a6e529e643
commit da7f46f7e9
5 changed files with 71 additions and 19 deletions

View File

@@ -0,0 +1,53 @@
<?php
declare(strict_types=1);
namespace DoctrineMigrations;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;
/**
* Auto-generated Migration: Please modify to your needs!
*/
final class Version20260402202809 extends AbstractMigration
{
public function getDescription(): string
{
return '';
}
public function up(Schema $schema): void
{
// this up() migration is auto-generated, please modify it to your needs
$this->addSql('CREATE TABLE facture (id INT GENERATED BY DEFAULT AS IDENTITY NOT NULL, split_index SMALLINT DEFAULT 0 NOT NULL, created_at TIMESTAMP(0) WITHOUT TIME ZONE NOT NULL, order_number_id INT NOT NULL, advert_id INT DEFAULT NULL, PRIMARY KEY (id))');
$this->addSql('CREATE INDEX IDX_FE8664108C26A5E8 ON facture (order_number_id)');
$this->addSql('CREATE INDEX IDX_FE866410D07ECCB6 ON facture (advert_id)');
$this->addSql('ALTER TABLE facture ADD CONSTRAINT FK_FE8664108C26A5E8 FOREIGN KEY (order_number_id) REFERENCES order_number (id) NOT DEFERRABLE');
$this->addSql('ALTER TABLE facture ADD CONSTRAINT FK_FE866410D07ECCB6 FOREIGN KEY (advert_id) REFERENCES advert (id) NOT DEFERRABLE');
$this->addSql('ALTER TABLE "order" DROP CONSTRAINT fk_f5299398d07eccb6');
$this->addSql('ALTER TABLE "order" DROP CONSTRAINT fk_f52993988c26a5e8');
$this->addSql('DROP TABLE "order"');
$this->addSql('DROP INDEX uniq_54f1f40b8c26a5e8');
$this->addSql('CREATE INDEX IDX_54F1F40B8C26A5E8 ON advert (order_number_id)');
$this->addSql('DROP INDEX uniq_8b27c52b8c26a5e8');
$this->addSql('CREATE INDEX IDX_8B27C52B8C26A5E8 ON devis (order_number_id)');
}
public function down(Schema $schema): void
{
// this down() migration is auto-generated, please modify it to your needs
$this->addSql('CREATE TABLE "order" (id INT GENERATED BY DEFAULT AS IDENTITY NOT NULL, split_index SMALLINT DEFAULT 0 NOT NULL, created_at TIMESTAMP(0) WITHOUT TIME ZONE NOT NULL, order_number_id INT NOT NULL, advert_id INT DEFAULT NULL, PRIMARY KEY (id))');
$this->addSql('CREATE INDEX idx_f5299398d07eccb6 ON "order" (advert_id)');
$this->addSql('CREATE UNIQUE INDEX uniq_f52993988c26a5e8 ON "order" (order_number_id)');
$this->addSql('ALTER TABLE "order" ADD CONSTRAINT fk_f5299398d07eccb6 FOREIGN KEY (advert_id) REFERENCES advert (id) NOT DEFERRABLE INITIALLY IMMEDIATE');
$this->addSql('ALTER TABLE "order" ADD CONSTRAINT fk_f52993988c26a5e8 FOREIGN KEY (order_number_id) REFERENCES order_number (id) NOT DEFERRABLE INITIALLY IMMEDIATE');
$this->addSql('ALTER TABLE facture DROP CONSTRAINT FK_FE8664108C26A5E8');
$this->addSql('ALTER TABLE facture DROP CONSTRAINT FK_FE866410D07ECCB6');
$this->addSql('DROP TABLE facture');
$this->addSql('DROP INDEX IDX_54F1F40B8C26A5E8');
$this->addSql('CREATE UNIQUE INDEX uniq_54f1f40b8c26a5e8 ON advert (order_number_id)');
$this->addSql('DROP INDEX IDX_8B27C52B8C26A5E8');
$this->addSql('CREATE UNIQUE INDEX uniq_8b27c52b8c26a5e8 ON devis (order_number_id)');
}
}

View File

@@ -15,7 +15,7 @@ class Advert
#[ORM\Column] #[ORM\Column]
private ?int $id = null; private ?int $id = null;
#[ORM\OneToOne(targetEntity: OrderNumber::class)] #[ORM\ManyToOne(targetEntity: OrderNumber::class)]
#[ORM\JoinColumn(nullable: false)] #[ORM\JoinColumn(nullable: false)]
private OrderNumber $orderNumber; private OrderNumber $orderNumber;
@@ -26,15 +26,15 @@ class Advert
#[ORM\Column] #[ORM\Column]
private \DateTimeImmutable $createdAt; private \DateTimeImmutable $createdAt;
/** @var Collection<int, Order> */ /** @var Collection<int, Facture> */
#[ORM\OneToMany(targetEntity: Order::class, mappedBy: 'advert')] #[ORM\OneToMany(targetEntity: Facture::class, mappedBy: 'advert')]
private Collection $orders; private Collection $factures;
public function __construct(OrderNumber $orderNumber) public function __construct(OrderNumber $orderNumber)
{ {
$this->orderNumber = $orderNumber; $this->orderNumber = $orderNumber;
$this->createdAt = new \DateTimeImmutable(); $this->createdAt = new \DateTimeImmutable();
$this->orders = new ArrayCollection(); $this->factures = new ArrayCollection();
} }
public function getId(): ?int public function getId(): ?int
@@ -62,9 +62,9 @@ class Advert
return $this->createdAt; return $this->createdAt;
} }
/** @return Collection<int, Order> */ /** @return Collection<int, Facture> */
public function getOrders(): Collection public function getFactures(): Collection
{ {
return $this->orders; return $this->factures;
} }
} }

View File

@@ -15,7 +15,7 @@ class Devis
#[ORM\Column] #[ORM\Column]
private ?int $id = null; private ?int $id = null;
#[ORM\OneToOne(targetEntity: OrderNumber::class)] #[ORM\ManyToOne(targetEntity: OrderNumber::class)]
#[ORM\JoinColumn(nullable: false)] #[ORM\JoinColumn(nullable: false)]
private OrderNumber $orderNumber; private OrderNumber $orderNumber;

View File

@@ -2,23 +2,22 @@
namespace App\Entity; namespace App\Entity;
use App\Repository\OrderRepository; use App\Repository\FactureRepository;
use Doctrine\ORM\Mapping as ORM; use Doctrine\ORM\Mapping as ORM;
#[ORM\Entity(repositoryClass: OrderRepository::class)] #[ORM\Entity(repositoryClass: FactureRepository::class)]
#[ORM\Table(name: '`order`')] class Facture
class Order
{ {
#[ORM\Id] #[ORM\Id]
#[ORM\GeneratedValue] #[ORM\GeneratedValue]
#[ORM\Column] #[ORM\Column]
private ?int $id = null; private ?int $id = null;
#[ORM\OneToOne(targetEntity: OrderNumber::class)] #[ORM\ManyToOne(targetEntity: OrderNumber::class)]
#[ORM\JoinColumn(nullable: false)] #[ORM\JoinColumn(nullable: false)]
private OrderNumber $orderNumber; private OrderNumber $orderNumber;
#[ORM\ManyToOne(targetEntity: Advert::class, inversedBy: 'orders')] #[ORM\ManyToOne(targetEntity: Advert::class, inversedBy: 'factures')]
#[ORM\JoinColumn(nullable: true)] #[ORM\JoinColumn(nullable: true)]
private ?Advert $advert = null; private ?Advert $advert = null;

View File

@@ -2,17 +2,17 @@
namespace App\Repository; namespace App\Repository;
use App\Entity\Order; use App\Entity\Facture;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository; use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Doctrine\Persistence\ManagerRegistry; use Doctrine\Persistence\ManagerRegistry;
/** /**
* @extends ServiceEntityRepository<Order> * @extends ServiceEntityRepository<Facture>
*/ */
class OrderRepository extends ServiceEntityRepository class FactureRepository extends ServiceEntityRepository
{ {
public function __construct(ManagerRegistry $registry) public function __construct(ManagerRegistry $registry)
{ {
parent::__construct($registry, Order::class); parent::__construct($registry, Facture::class);
} }
} }