feat: entité CustomerContact pour contacts additionnels d'un client
Entity CustomerContact : - customer (ManyToOne, CASCADE) : client parent - firstName, lastName : nom/prénom du contact - email : adresse email (nullable) - phone : téléphone (nullable) - role : fonction dans l'entreprise (Gérant, Comptable, etc.) - isBillingEmail : si true, reçoit les factures par email - createdAt / updatedAt : timestamps - getFullName() : prénom + nom CustomerContactTest (2 tests, 19 assertions) : - testConstructor : valeurs par défaut - testSetters : tous les setters/getters Migration : CREATE TABLE customer_contact avec FK customer ON DELETE CASCADE Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
34
migrations/Version20260404091315.php
Normal file
34
migrations/Version20260404091315.php
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
<?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 Version20260404091315 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 customer_contact (id INT GENERATED BY DEFAULT AS IDENTITY NOT NULL, first_name VARCHAR(255) NOT NULL, last_name VARCHAR(255) NOT NULL, email VARCHAR(255) DEFAULT NULL, phone VARCHAR(20) DEFAULT NULL, role VARCHAR(100) DEFAULT NULL, is_billing_email BOOLEAN NOT NULL, created_at TIMESTAMP(0) WITHOUT TIME ZONE NOT NULL, updated_at TIMESTAMP(0) WITHOUT TIME ZONE DEFAULT NULL, customer_id INT NOT NULL, PRIMARY KEY (id))');
|
||||||
|
$this->addSql('CREATE INDEX IDX_50BF42869395C3F3 ON customer_contact (customer_id)');
|
||||||
|
$this->addSql('ALTER TABLE customer_contact ADD CONSTRAINT FK_50BF42869395C3F3 FOREIGN KEY (customer_id) REFERENCES customer (id) ON DELETE CASCADE NOT DEFERRABLE');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function down(Schema $schema): void
|
||||||
|
{
|
||||||
|
// this down() migration is auto-generated, please modify it to your needs
|
||||||
|
$this->addSql('ALTER TABLE customer_contact DROP CONSTRAINT FK_50BF42869395C3F3');
|
||||||
|
$this->addSql('DROP TABLE customer_contact');
|
||||||
|
}
|
||||||
|
}
|
||||||
154
src/Entity/CustomerContact.php
Normal file
154
src/Entity/CustomerContact.php
Normal file
@@ -0,0 +1,154 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Entity;
|
||||||
|
|
||||||
|
use Doctrine\ORM\Mapping as ORM;
|
||||||
|
|
||||||
|
#[ORM\Entity]
|
||||||
|
class CustomerContact
|
||||||
|
{
|
||||||
|
#[ORM\Id]
|
||||||
|
#[ORM\GeneratedValue]
|
||||||
|
#[ORM\Column]
|
||||||
|
private ?int $id = null;
|
||||||
|
|
||||||
|
#[ORM\ManyToOne(targetEntity: Customer::class)]
|
||||||
|
#[ORM\JoinColumn(nullable: false, onDelete: 'CASCADE')]
|
||||||
|
private Customer $customer;
|
||||||
|
|
||||||
|
#[ORM\Column(length: 255)]
|
||||||
|
private string $firstName;
|
||||||
|
|
||||||
|
#[ORM\Column(length: 255)]
|
||||||
|
private string $lastName;
|
||||||
|
|
||||||
|
#[ORM\Column(length: 255, nullable: true)]
|
||||||
|
private ?string $email = null;
|
||||||
|
|
||||||
|
#[ORM\Column(length: 20, nullable: true)]
|
||||||
|
private ?string $phone = null;
|
||||||
|
|
||||||
|
#[ORM\Column(length: 100, nullable: true)]
|
||||||
|
private ?string $role = null;
|
||||||
|
|
||||||
|
#[ORM\Column]
|
||||||
|
private bool $isBillingEmail = false;
|
||||||
|
|
||||||
|
#[ORM\Column]
|
||||||
|
private \DateTimeImmutable $createdAt;
|
||||||
|
|
||||||
|
#[ORM\Column(nullable: true)]
|
||||||
|
private ?\DateTimeImmutable $updatedAt = null;
|
||||||
|
|
||||||
|
public function __construct(Customer $customer, string $firstName, string $lastName)
|
||||||
|
{
|
||||||
|
$this->customer = $customer;
|
||||||
|
$this->firstName = $firstName;
|
||||||
|
$this->lastName = $lastName;
|
||||||
|
$this->createdAt = new \DateTimeImmutable();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getId(): ?int
|
||||||
|
{
|
||||||
|
return $this->id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getCustomer(): Customer
|
||||||
|
{
|
||||||
|
return $this->customer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getFirstName(): string
|
||||||
|
{
|
||||||
|
return $this->firstName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setFirstName(string $firstName): static
|
||||||
|
{
|
||||||
|
$this->firstName = $firstName;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getLastName(): string
|
||||||
|
{
|
||||||
|
return $this->lastName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setLastName(string $lastName): static
|
||||||
|
{
|
||||||
|
$this->lastName = $lastName;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getFullName(): string
|
||||||
|
{
|
||||||
|
return $this->firstName.' '.$this->lastName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getEmail(): ?string
|
||||||
|
{
|
||||||
|
return $this->email;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setEmail(?string $email): static
|
||||||
|
{
|
||||||
|
$this->email = $email;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getPhone(): ?string
|
||||||
|
{
|
||||||
|
return $this->phone;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setPhone(?string $phone): static
|
||||||
|
{
|
||||||
|
$this->phone = $phone;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getRole(): ?string
|
||||||
|
{
|
||||||
|
return $this->role;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setRole(?string $role): static
|
||||||
|
{
|
||||||
|
$this->role = $role;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function isBillingEmail(): bool
|
||||||
|
{
|
||||||
|
return $this->isBillingEmail;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setIsBillingEmail(bool $isBillingEmail): static
|
||||||
|
{
|
||||||
|
$this->isBillingEmail = $isBillingEmail;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getCreatedAt(): \DateTimeImmutable
|
||||||
|
{
|
||||||
|
return $this->createdAt;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getUpdatedAt(): ?\DateTimeImmutable
|
||||||
|
{
|
||||||
|
return $this->updatedAt;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setUpdatedAt(?\DateTimeImmutable $updatedAt): static
|
||||||
|
{
|
||||||
|
$this->updatedAt = $updatedAt;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
}
|
||||||
68
tests/Entity/CustomerContactTest.php
Normal file
68
tests/Entity/CustomerContactTest.php
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Tests\Entity;
|
||||||
|
|
||||||
|
use App\Entity\Customer;
|
||||||
|
use App\Entity\CustomerContact;
|
||||||
|
use App\Entity\User;
|
||||||
|
use PHPUnit\Framework\TestCase;
|
||||||
|
|
||||||
|
class CustomerContactTest extends TestCase
|
||||||
|
{
|
||||||
|
private function createCustomer(): Customer
|
||||||
|
{
|
||||||
|
$user = new User();
|
||||||
|
$user->setEmail('c@t.com');
|
||||||
|
$user->setFirstName('C');
|
||||||
|
$user->setLastName('T');
|
||||||
|
$user->setPassword('h');
|
||||||
|
|
||||||
|
return new Customer($user);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testConstructor(): void
|
||||||
|
{
|
||||||
|
$customer = $this->createCustomer();
|
||||||
|
$contact = new CustomerContact($customer, 'Jean', 'Dupont');
|
||||||
|
|
||||||
|
$this->assertNull($contact->getId());
|
||||||
|
$this->assertSame($customer, $contact->getCustomer());
|
||||||
|
$this->assertSame('Jean', $contact->getFirstName());
|
||||||
|
$this->assertSame('Dupont', $contact->getLastName());
|
||||||
|
$this->assertSame('Jean Dupont', $contact->getFullName());
|
||||||
|
$this->assertNull($contact->getEmail());
|
||||||
|
$this->assertNull($contact->getPhone());
|
||||||
|
$this->assertNull($contact->getRole());
|
||||||
|
$this->assertFalse($contact->isBillingEmail());
|
||||||
|
$this->assertInstanceOf(\DateTimeImmutable::class, $contact->getCreatedAt());
|
||||||
|
$this->assertNull($contact->getUpdatedAt());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testSetters(): void
|
||||||
|
{
|
||||||
|
$contact = new CustomerContact($this->createCustomer(), 'A', 'B');
|
||||||
|
|
||||||
|
$contact->setFirstName('Marie');
|
||||||
|
$this->assertSame('Marie', $contact->getFirstName());
|
||||||
|
|
||||||
|
$contact->setLastName('Martin');
|
||||||
|
$this->assertSame('Martin', $contact->getLastName());
|
||||||
|
$this->assertSame('Marie Martin', $contact->getFullName());
|
||||||
|
|
||||||
|
$contact->setEmail('marie@entreprise.fr');
|
||||||
|
$this->assertSame('marie@entreprise.fr', $contact->getEmail());
|
||||||
|
|
||||||
|
$contact->setPhone('0612345678');
|
||||||
|
$this->assertSame('0612345678', $contact->getPhone());
|
||||||
|
|
||||||
|
$contact->setRole('Comptable');
|
||||||
|
$this->assertSame('Comptable', $contact->getRole());
|
||||||
|
|
||||||
|
$contact->setIsBillingEmail(true);
|
||||||
|
$this->assertTrue($contact->isBillingEmail());
|
||||||
|
|
||||||
|
$now = new \DateTimeImmutable();
|
||||||
|
$contact->setUpdatedAt($now);
|
||||||
|
$this->assertSame($now, $contact->getUpdatedAt());
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user