diff --git a/migrations/Version20260622100916.php b/migrations/Version20260622100916.php new file mode 100644 index 0000000..337586b --- /dev/null +++ b/migrations/Version20260622100916.php @@ -0,0 +1,222 @@ +addSql('CREATE TABLE commercial_report (id INT GENERATED BY DEFAULT AS IDENTITY NOT NULL, subject VARCHAR(255) NOT NULL, body TEXT DEFAULT NULL, occurred_at DATE NOT NULL, type VARCHAR(32) NOT NULL, created_at TIMESTAMP(0) WITHOUT TIME ZONE DEFAULT NULL, updated_at TIMESTAMP(0) WITHOUT TIME ZONE DEFAULT NULL, client_id INT DEFAULT NULL, prospect_id INT DEFAULT NULL, author_id INT DEFAULT NULL, created_by INT DEFAULT NULL, updated_by INT DEFAULT NULL, PRIMARY KEY (id))'); + $this->addSql('CREATE INDEX IDX_886919D819EB6921 ON commercial_report (client_id)'); + $this->addSql('CREATE INDEX IDX_886919D8D182060A ON commercial_report (prospect_id)'); + $this->addSql('CREATE INDEX IDX_886919D8F675F31B ON commercial_report (author_id)'); + $this->addSql('CREATE INDEX IDX_886919D8DE12AB56 ON commercial_report (created_by)'); + $this->addSql('CREATE INDEX IDX_886919D816FE72E1 ON commercial_report (updated_by)'); + $this->addSql('CREATE TABLE directory_address (id INT GENERATED BY DEFAULT AS IDENTITY NOT NULL, label VARCHAR(255) DEFAULT NULL, street VARCHAR(255) DEFAULT NULL, street_complement VARCHAR(255) DEFAULT NULL, postal_code VARCHAR(20) DEFAULT NULL, city VARCHAR(255) DEFAULT NULL, country VARCHAR(2) NOT NULL, created_at TIMESTAMP(0) WITHOUT TIME ZONE DEFAULT NULL, updated_at TIMESTAMP(0) WITHOUT TIME ZONE DEFAULT NULL, client_id INT DEFAULT NULL, prospect_id INT DEFAULT NULL, created_by INT DEFAULT NULL, updated_by INT DEFAULT NULL, PRIMARY KEY (id))'); + $this->addSql('CREATE INDEX IDX_6E5D970719EB6921 ON directory_address (client_id)'); + $this->addSql('CREATE INDEX IDX_6E5D9707D182060A ON directory_address (prospect_id)'); + $this->addSql('CREATE INDEX IDX_6E5D9707DE12AB56 ON directory_address (created_by)'); + $this->addSql('CREATE INDEX IDX_6E5D970716FE72E1 ON directory_address (updated_by)'); + $this->addSql('CREATE TABLE directory_contact (id INT GENERATED BY DEFAULT AS IDENTITY NOT NULL, first_name VARCHAR(255) DEFAULT NULL, last_name VARCHAR(255) DEFAULT NULL, job_title VARCHAR(255) DEFAULT NULL, email VARCHAR(255) DEFAULT NULL, phone_primary VARCHAR(50) DEFAULT NULL, phone_secondary VARCHAR(50) DEFAULT NULL, created_at TIMESTAMP(0) WITHOUT TIME ZONE DEFAULT NULL, updated_at TIMESTAMP(0) WITHOUT TIME ZONE DEFAULT NULL, client_id INT DEFAULT NULL, prospect_id INT DEFAULT NULL, created_by INT DEFAULT NULL, updated_by INT DEFAULT NULL, PRIMARY KEY (id))'); + $this->addSql('CREATE INDEX IDX_2F711EBE19EB6921 ON directory_contact (client_id)'); + $this->addSql('CREATE INDEX IDX_2F711EBED182060A ON directory_contact (prospect_id)'); + $this->addSql('CREATE INDEX IDX_2F711EBEDE12AB56 ON directory_contact (created_by)'); + $this->addSql('CREATE INDEX IDX_2F711EBE16FE72E1 ON directory_contact (updated_by)'); + $this->addSql('CREATE TABLE report_document (id INT GENERATED BY DEFAULT AS IDENTITY NOT NULL, original_name VARCHAR(255) NOT NULL, file_name VARCHAR(255) DEFAULT NULL, mime_type VARCHAR(100) NOT NULL, size INT NOT NULL, created_at TIMESTAMP(0) WITHOUT TIME ZONE NOT NULL, commercial_report_id INT NOT NULL, uploaded_by_id INT DEFAULT NULL, PRIMARY KEY (id))'); + $this->addSql('CREATE INDEX IDX_D809130B4AB5D1D4 ON report_document (commercial_report_id)'); + $this->addSql('CREATE INDEX IDX_D809130BA2B28FE8 ON report_document (uploaded_by_id)'); + $this->addSql('ALTER TABLE commercial_report ADD CONSTRAINT FK_886919D819EB6921 FOREIGN KEY (client_id) REFERENCES client (id) ON DELETE CASCADE NOT DEFERRABLE'); + $this->addSql('ALTER TABLE commercial_report ADD CONSTRAINT FK_886919D8D182060A FOREIGN KEY (prospect_id) REFERENCES prospect (id) ON DELETE CASCADE NOT DEFERRABLE'); + $this->addSql('ALTER TABLE commercial_report ADD CONSTRAINT FK_886919D8F675F31B FOREIGN KEY (author_id) REFERENCES "user" (id) ON DELETE SET NULL NOT DEFERRABLE'); + $this->addSql('ALTER TABLE commercial_report ADD CONSTRAINT FK_886919D8DE12AB56 FOREIGN KEY (created_by) REFERENCES "user" (id) ON DELETE SET NULL NOT DEFERRABLE'); + $this->addSql('ALTER TABLE commercial_report ADD CONSTRAINT FK_886919D816FE72E1 FOREIGN KEY (updated_by) REFERENCES "user" (id) ON DELETE SET NULL NOT DEFERRABLE'); + $this->addSql('ALTER TABLE directory_address ADD CONSTRAINT FK_6E5D970719EB6921 FOREIGN KEY (client_id) REFERENCES client (id) ON DELETE CASCADE NOT DEFERRABLE'); + $this->addSql('ALTER TABLE directory_address ADD CONSTRAINT FK_6E5D9707D182060A FOREIGN KEY (prospect_id) REFERENCES prospect (id) ON DELETE CASCADE NOT DEFERRABLE'); + $this->addSql('ALTER TABLE directory_address ADD CONSTRAINT FK_6E5D9707DE12AB56 FOREIGN KEY (created_by) REFERENCES "user" (id) ON DELETE SET NULL NOT DEFERRABLE'); + $this->addSql('ALTER TABLE directory_address ADD CONSTRAINT FK_6E5D970716FE72E1 FOREIGN KEY (updated_by) REFERENCES "user" (id) ON DELETE SET NULL NOT DEFERRABLE'); + $this->addSql('ALTER TABLE directory_contact ADD CONSTRAINT FK_2F711EBE19EB6921 FOREIGN KEY (client_id) REFERENCES client (id) ON DELETE CASCADE NOT DEFERRABLE'); + $this->addSql('ALTER TABLE directory_contact ADD CONSTRAINT FK_2F711EBED182060A FOREIGN KEY (prospect_id) REFERENCES prospect (id) ON DELETE CASCADE NOT DEFERRABLE'); + $this->addSql('ALTER TABLE directory_contact ADD CONSTRAINT FK_2F711EBEDE12AB56 FOREIGN KEY (created_by) REFERENCES "user" (id) ON DELETE SET NULL NOT DEFERRABLE'); + $this->addSql('ALTER TABLE directory_contact ADD CONSTRAINT FK_2F711EBE16FE72E1 FOREIGN KEY (updated_by) REFERENCES "user" (id) ON DELETE SET NULL NOT DEFERRABLE'); + $this->addSql('ALTER TABLE report_document ADD CONSTRAINT FK_D809130B4AB5D1D4 FOREIGN KEY (commercial_report_id) REFERENCES commercial_report (id) ON DELETE CASCADE NOT DEFERRABLE'); + $this->addSql('ALTER TABLE report_document ADD CONSTRAINT FK_D809130BA2B28FE8 FOREIGN KEY (uploaded_by_id) REFERENCES "user" (id) ON DELETE SET NULL NOT DEFERRABLE'); + + // Ownership CHECK constraints: each row must belong to a client or a prospect. + $this->addSql('ALTER TABLE directory_contact ADD CONSTRAINT chk_contact_owner CHECK (client_id IS NOT NULL OR prospect_id IS NOT NULL)'); + $this->addSql('ALTER TABLE directory_address ADD CONSTRAINT chk_address_owner CHECK (client_id IS NOT NULL OR prospect_id IS NOT NULL)'); + $this->addSql('ALTER TABLE commercial_report ADD CONSTRAINT chk_report_owner CHECK (client_id IS NOT NULL OR prospect_id IS NOT NULL)'); + + // Data migration: copy existing inline addresses into directory_address before dropping the columns. + $this->addSql("INSERT INTO directory_address (label, street, postal_code, city, country, client_id, created_at, updated_at) + SELECT 'Principale', street, postal_code, city, 'FR', id, NOW(), NOW() + FROM client + WHERE COALESCE(street, '') <> '' OR COALESCE(city, '') <> '' OR COALESCE(postal_code, '') <> ''"); + $this->addSql("INSERT INTO directory_address (label, street, postal_code, city, country, prospect_id, created_at, updated_at) + SELECT 'Principale', street, postal_code, city, 'FR', id, NOW(), NOW() + FROM prospect + WHERE COALESCE(street, '') <> '' OR COALESCE(city, '') <> '' OR COALESCE(postal_code, '') <> ''"); + + $this->addSql('COMMENT ON COLUMN absence_balance.created_at IS \'\''); + $this->addSql('COMMENT ON COLUMN absence_balance.updated_at IS \'\''); + $this->addSql('COMMENT ON COLUMN absence_balance.created_by IS \'\''); + $this->addSql('COMMENT ON COLUMN absence_balance.updated_by IS \'\''); + $this->addSql('COMMENT ON COLUMN absence_policy.created_at IS \'\''); + $this->addSql('COMMENT ON COLUMN absence_policy.updated_at IS \'\''); + $this->addSql('COMMENT ON COLUMN absence_policy.created_by IS \'\''); + $this->addSql('COMMENT ON COLUMN absence_policy.updated_by IS \'\''); + $this->addSql('COMMENT ON COLUMN book_stack_configuration.created_at IS \'\''); + $this->addSql('COMMENT ON COLUMN book_stack_configuration.updated_at IS \'\''); + $this->addSql('COMMENT ON COLUMN book_stack_configuration.created_by IS \'\''); + $this->addSql('COMMENT ON COLUMN book_stack_configuration.updated_by IS \'\''); + $this->addSql('ALTER TABLE client DROP street'); + $this->addSql('ALTER TABLE client DROP city'); + $this->addSql('ALTER TABLE client DROP postal_code'); + $this->addSql('COMMENT ON COLUMN client.created_at IS \'\''); + $this->addSql('COMMENT ON COLUMN client.updated_at IS \'\''); + $this->addSql('COMMENT ON COLUMN client.created_by IS \'\''); + $this->addSql('COMMENT ON COLUMN client.updated_by IS \'\''); + $this->addSql('COMMENT ON COLUMN gitea_configuration.created_at IS \'\''); + $this->addSql('COMMENT ON COLUMN gitea_configuration.updated_at IS \'\''); + $this->addSql('COMMENT ON COLUMN gitea_configuration.created_by IS \'\''); + $this->addSql('COMMENT ON COLUMN gitea_configuration.updated_by IS \'\''); + $this->addSql('COMMENT ON COLUMN mail_configuration.created_at IS \'\''); + $this->addSql('COMMENT ON COLUMN mail_configuration.updated_at IS \'\''); + $this->addSql('COMMENT ON COLUMN mail_configuration.created_by IS \'\''); + $this->addSql('COMMENT ON COLUMN mail_configuration.updated_by IS \'\''); + $this->addSql('COMMENT ON COLUMN project.created_at IS \'\''); + $this->addSql('COMMENT ON COLUMN project.updated_at IS \'\''); + $this->addSql('COMMENT ON COLUMN project.created_by IS \'\''); + $this->addSql('COMMENT ON COLUMN project.updated_by IS \'\''); + $this->addSql('ALTER TABLE prospect DROP street'); + $this->addSql('ALTER TABLE prospect DROP city'); + $this->addSql('ALTER TABLE prospect DROP postal_code'); + $this->addSql('COMMENT ON COLUMN prospect.status IS \'\''); + $this->addSql('COMMENT ON COLUMN prospect.created_at IS \'\''); + $this->addSql('COMMENT ON COLUMN prospect.updated_at IS \'\''); + $this->addSql('COMMENT ON COLUMN prospect.converted_client_id IS \'\''); + $this->addSql('COMMENT ON COLUMN prospect.created_by IS \'\''); + $this->addSql('COMMENT ON COLUMN prospect.updated_by IS \'\''); + $this->addSql('COMMENT ON COLUMN share_configuration.created_at IS \'\''); + $this->addSql('COMMENT ON COLUMN share_configuration.updated_at IS \'\''); + $this->addSql('COMMENT ON COLUMN share_configuration.created_by IS \'\''); + $this->addSql('COMMENT ON COLUMN share_configuration.updated_by IS \'\''); + $this->addSql('COMMENT ON COLUMN task.created_at IS \'\''); + $this->addSql('COMMENT ON COLUMN task.updated_at IS \'\''); + $this->addSql('COMMENT ON COLUMN task.created_by IS \'\''); + $this->addSql('COMMENT ON COLUMN task.updated_by IS \'\''); + $this->addSql('COMMENT ON COLUMN time_entry.created_at IS \'\''); + $this->addSql('COMMENT ON COLUMN time_entry.updated_at IS \'\''); + $this->addSql('COMMENT ON COLUMN time_entry.created_by IS \'\''); + $this->addSql('COMMENT ON COLUMN time_entry.updated_by IS \'\''); + $this->addSql('COMMENT ON COLUMN zimbra_configuration.created_at IS \'\''); + $this->addSql('COMMENT ON COLUMN zimbra_configuration.updated_at IS \'\''); + $this->addSql('COMMENT ON COLUMN zimbra_configuration.created_by IS \'\''); + $this->addSql('COMMENT ON COLUMN zimbra_configuration.updated_by IS \'\''); + $this->addSql('DROP INDEX idx_75ea56e016ba31db'); + $this->addSql('DROP INDEX idx_75ea56e0fb7336f0'); + $this->addSql('DROP INDEX idx_75ea56e0e3bd61ce'); + $this->addSql('ALTER TABLE messenger_messages ALTER id DROP DEFAULT'); + $this->addSql('ALTER TABLE messenger_messages ALTER id ADD GENERATED BY DEFAULT AS IDENTITY'); + $this->addSql('CREATE INDEX IDX_75EA56E0FB7336F0E3BD61CE16BA31DBBF396750 ON messenger_messages (queue_name, available_at, delivered_at, id)'); + } + + public function down(Schema $schema): void + { + // this down() migration is auto-generated, please modify it to your needs + $this->addSql('ALTER TABLE commercial_report DROP CONSTRAINT FK_886919D819EB6921'); + $this->addSql('ALTER TABLE commercial_report DROP CONSTRAINT FK_886919D8D182060A'); + $this->addSql('ALTER TABLE commercial_report DROP CONSTRAINT FK_886919D8F675F31B'); + $this->addSql('ALTER TABLE commercial_report DROP CONSTRAINT FK_886919D8DE12AB56'); + $this->addSql('ALTER TABLE commercial_report DROP CONSTRAINT FK_886919D816FE72E1'); + $this->addSql('ALTER TABLE directory_address DROP CONSTRAINT FK_6E5D970719EB6921'); + $this->addSql('ALTER TABLE directory_address DROP CONSTRAINT FK_6E5D9707D182060A'); + $this->addSql('ALTER TABLE directory_address DROP CONSTRAINT FK_6E5D9707DE12AB56'); + $this->addSql('ALTER TABLE directory_address DROP CONSTRAINT FK_6E5D970716FE72E1'); + $this->addSql('ALTER TABLE directory_contact DROP CONSTRAINT FK_2F711EBE19EB6921'); + $this->addSql('ALTER TABLE directory_contact DROP CONSTRAINT FK_2F711EBED182060A'); + $this->addSql('ALTER TABLE directory_contact DROP CONSTRAINT FK_2F711EBEDE12AB56'); + $this->addSql('ALTER TABLE directory_contact DROP CONSTRAINT FK_2F711EBE16FE72E1'); + $this->addSql('ALTER TABLE report_document DROP CONSTRAINT FK_D809130B4AB5D1D4'); + $this->addSql('ALTER TABLE report_document DROP CONSTRAINT FK_D809130BA2B28FE8'); + $this->addSql('DROP TABLE commercial_report'); + $this->addSql('DROP TABLE directory_address'); + $this->addSql('DROP TABLE directory_contact'); + $this->addSql('DROP TABLE report_document'); + $this->addSql('COMMENT ON COLUMN absence_balance.created_at IS \'Creation timestamp (Timestampable, set on prePersist)\''); + $this->addSql('COMMENT ON COLUMN absence_balance.updated_at IS \'Last update timestamp (Timestampable, set on prePersist/preUpdate)\''); + $this->addSql('COMMENT ON COLUMN absence_balance.created_by IS \'User who created the entry (Blamable, FK user.id, SET NULL on delete)\''); + $this->addSql('COMMENT ON COLUMN absence_balance.updated_by IS \'User who last updated the entry (Blamable, FK user.id, SET NULL on delete)\''); + $this->addSql('COMMENT ON COLUMN absence_policy.created_at IS \'Creation timestamp (Timestampable, set on prePersist)\''); + $this->addSql('COMMENT ON COLUMN absence_policy.updated_at IS \'Last update timestamp (Timestampable, set on prePersist/preUpdate)\''); + $this->addSql('COMMENT ON COLUMN absence_policy.created_by IS \'User who created the entry (Blamable, FK user.id, SET NULL on delete)\''); + $this->addSql('COMMENT ON COLUMN absence_policy.updated_by IS \'User who last updated the entry (Blamable, FK user.id, SET NULL on delete)\''); + $this->addSql('COMMENT ON COLUMN book_stack_configuration.created_at IS \'Creation timestamp (Timestampable, set on prePersist)\''); + $this->addSql('COMMENT ON COLUMN book_stack_configuration.updated_at IS \'Last update timestamp (Timestampable, set on prePersist/preUpdate)\''); + $this->addSql('COMMENT ON COLUMN book_stack_configuration.created_by IS \'User who created the entry (Blamable, FK user.id, SET NULL on delete)\''); + $this->addSql('COMMENT ON COLUMN book_stack_configuration.updated_by IS \'User who last updated the entry (Blamable, FK user.id, SET NULL on delete)\''); + $this->addSql('ALTER TABLE client ADD street VARCHAR(255) DEFAULT NULL'); + $this->addSql('ALTER TABLE client ADD city VARCHAR(255) DEFAULT NULL'); + $this->addSql('ALTER TABLE client ADD postal_code VARCHAR(20) DEFAULT NULL'); + $this->addSql('COMMENT ON COLUMN client.created_at IS \'Creation timestamp (Timestampable, set on prePersist)\''); + $this->addSql('COMMENT ON COLUMN client.updated_at IS \'Last update timestamp (Timestampable, set on prePersist/preUpdate)\''); + $this->addSql('COMMENT ON COLUMN client.created_by IS \'User who created the entry (Blamable, FK user.id, SET NULL on delete)\''); + $this->addSql('COMMENT ON COLUMN client.updated_by IS \'User who last updated the entry (Blamable, FK user.id, SET NULL on delete)\''); + $this->addSql('COMMENT ON COLUMN gitea_configuration.created_at IS \'Creation timestamp (Timestampable, set on prePersist)\''); + $this->addSql('COMMENT ON COLUMN gitea_configuration.updated_at IS \'Last update timestamp (Timestampable, set on prePersist/preUpdate)\''); + $this->addSql('COMMENT ON COLUMN gitea_configuration.created_by IS \'User who created the entry (Blamable, FK user.id, SET NULL on delete)\''); + $this->addSql('COMMENT ON COLUMN gitea_configuration.updated_by IS \'User who last updated the entry (Blamable, FK user.id, SET NULL on delete)\''); + $this->addSql('COMMENT ON COLUMN mail_configuration.created_at IS \'Creation timestamp (Timestampable, set on prePersist)\''); + $this->addSql('COMMENT ON COLUMN mail_configuration.updated_at IS \'Last update timestamp (Timestampable, set on prePersist/preUpdate)\''); + $this->addSql('COMMENT ON COLUMN mail_configuration.created_by IS \'User who created the entry (Blamable, FK user.id, SET NULL on delete)\''); + $this->addSql('COMMENT ON COLUMN mail_configuration.updated_by IS \'User who last updated the entry (Blamable, FK user.id, SET NULL on delete)\''); + $this->addSql('DROP INDEX IDX_75EA56E0FB7336F0E3BD61CE16BA31DBBF396750'); + $this->addSql('ALTER TABLE messenger_messages ALTER id SET DEFAULT nextval(\'messenger_messages_id_seq\'::regclass)'); + $this->addSql('ALTER TABLE messenger_messages ALTER id DROP IDENTITY'); + $this->addSql('CREATE INDEX idx_75ea56e016ba31db ON messenger_messages (delivered_at)'); + $this->addSql('CREATE INDEX idx_75ea56e0fb7336f0 ON messenger_messages (queue_name)'); + $this->addSql('CREATE INDEX idx_75ea56e0e3bd61ce ON messenger_messages (available_at)'); + $this->addSql('COMMENT ON COLUMN project.created_at IS \'Creation timestamp (Timestampable, set on prePersist)\''); + $this->addSql('COMMENT ON COLUMN project.updated_at IS \'Last update timestamp (Timestampable, set on prePersist/preUpdate)\''); + $this->addSql('COMMENT ON COLUMN project.created_by IS \'User who created the entry (Blamable, FK user.id, SET NULL on delete)\''); + $this->addSql('COMMENT ON COLUMN project.updated_by IS \'User who last updated the entry (Blamable, FK user.id, SET NULL on delete)\''); + $this->addSql('ALTER TABLE prospect ADD street VARCHAR(255) DEFAULT NULL'); + $this->addSql('ALTER TABLE prospect ADD city VARCHAR(255) DEFAULT NULL'); + $this->addSql('ALTER TABLE prospect ADD postal_code VARCHAR(20) DEFAULT NULL'); + $this->addSql('COMMENT ON COLUMN prospect.status IS \'Prospect pipeline status (ProspectStatus enum: new, contacted, qualified, won, lost)\''); + $this->addSql('COMMENT ON COLUMN prospect.created_at IS \'Creation timestamp (Timestampable, set on prePersist)\''); + $this->addSql('COMMENT ON COLUMN prospect.updated_at IS \'Last update timestamp (Timestampable, set on prePersist/preUpdate)\''); + $this->addSql('COMMENT ON COLUMN prospect.converted_client_id IS \'Client created when the prospect is converted (FK client.id, SET NULL on delete)\''); + $this->addSql('COMMENT ON COLUMN prospect.created_by IS \'User who created the entry (Blamable, FK user.id, SET NULL on delete)\''); + $this->addSql('COMMENT ON COLUMN prospect.updated_by IS \'User who last updated the entry (Blamable, FK user.id, SET NULL on delete)\''); + $this->addSql('COMMENT ON COLUMN share_configuration.created_at IS \'Creation timestamp (Timestampable, set on prePersist)\''); + $this->addSql('COMMENT ON COLUMN share_configuration.updated_at IS \'Last update timestamp (Timestampable, set on prePersist/preUpdate)\''); + $this->addSql('COMMENT ON COLUMN share_configuration.created_by IS \'User who created the entry (Blamable, FK user.id, SET NULL on delete)\''); + $this->addSql('COMMENT ON COLUMN share_configuration.updated_by IS \'User who last updated the entry (Blamable, FK user.id, SET NULL on delete)\''); + $this->addSql('COMMENT ON COLUMN task.created_at IS \'Creation timestamp (Timestampable, set on prePersist)\''); + $this->addSql('COMMENT ON COLUMN task.updated_at IS \'Last update timestamp (Timestampable, set on prePersist/preUpdate)\''); + $this->addSql('COMMENT ON COLUMN task.created_by IS \'User who created the entry (Blamable, FK user.id, SET NULL on delete)\''); + $this->addSql('COMMENT ON COLUMN task.updated_by IS \'User who last updated the entry (Blamable, FK user.id, SET NULL on delete)\''); + $this->addSql('COMMENT ON COLUMN time_entry.created_at IS \'Creation timestamp (Timestampable, set on prePersist)\''); + $this->addSql('COMMENT ON COLUMN time_entry.updated_at IS \'Last update timestamp (Timestampable, set on prePersist/preUpdate)\''); + $this->addSql('COMMENT ON COLUMN time_entry.created_by IS \'User who created the entry (Blamable, FK user.id, SET NULL on delete)\''); + $this->addSql('COMMENT ON COLUMN time_entry.updated_by IS \'User who last updated the entry (Blamable, FK user.id, SET NULL on delete)\''); + $this->addSql('COMMENT ON COLUMN zimbra_configuration.created_at IS \'Creation timestamp (Timestampable, set on prePersist)\''); + $this->addSql('COMMENT ON COLUMN zimbra_configuration.updated_at IS \'Last update timestamp (Timestampable, set on prePersist/preUpdate)\''); + $this->addSql('COMMENT ON COLUMN zimbra_configuration.created_by IS \'User who created the entry (Blamable, FK user.id, SET NULL on delete)\''); + $this->addSql('COMMENT ON COLUMN zimbra_configuration.updated_by IS \'User who last updated the entry (Blamable, FK user.id, SET NULL on delete)\''); + } +} diff --git a/src/DataFixtures/AppFixtures.php b/src/DataFixtures/AppFixtures.php index e6fd000..52a1d7e 100644 --- a/src/DataFixtures/AppFixtures.php +++ b/src/DataFixtures/AppFixtures.php @@ -12,6 +12,7 @@ use App\Module\Absence\Domain\Enum\AbsenceType; use App\Module\Core\Application\Rbac\RbacSeeder; use App\Module\Core\Domain\Entity\User; use App\Module\Core\Domain\Enum\ContractType; +use App\Module\Directory\Domain\Entity\Address; use App\Module\Directory\Domain\Entity\Client; use App\Module\Directory\Domain\Entity\Prospect; use App\Module\Directory\Domain\Enum\ProspectStatus; @@ -83,66 +84,102 @@ class AppFixtures extends Fixture $clientLiot->setName('LIOT'); $clientLiot->setEmail('contact@liot.fr'); $clientLiot->setPhone('05 50 50 50 50'); - $clientLiot->setStreet('14 allée d\'argenson'); - $clientLiot->setCity('Poitiers'); - $clientLiot->setPostalCode('86100'); $manager->persist($clientLiot); + $addressLiot = new Address(); + $addressLiot->setLabel('Principale'); + $addressLiot->setStreet('14 allée d\'argenson'); + $addressLiot->setCity('Poitiers'); + $addressLiot->setPostalCode('86100'); + $addressLiot->setCountry('FR'); + $addressLiot->setClient($clientLiot); + $manager->persist($addressLiot); + $clientAcme = new Client(); $clientAcme->setName('ACME Corp'); $clientAcme->setEmail('contact@acme.com'); $clientAcme->setPhone('01 23 45 67 89'); - $clientAcme->setStreet('10 rue de la Paix'); - $clientAcme->setCity('Paris'); - $clientAcme->setPostalCode('75002'); $manager->persist($clientAcme); + $addressAcme = new Address(); + $addressAcme->setLabel('Principale'); + $addressAcme->setStreet('10 rue de la Paix'); + $addressAcme->setCity('Paris'); + $addressAcme->setPostalCode('75002'); + $addressAcme->setCountry('FR'); + $addressAcme->setClient($clientAcme); + $manager->persist($addressAcme); + $clientNova = new Client(); $clientNova->setName('Nova Tech'); $clientNova->setEmail('info@novatech.io'); $clientNova->setPhone('04 56 78 90 12'); - $clientNova->setStreet('5 avenue Jean Jaurès'); - $clientNova->setCity('Lyon'); - $clientNova->setPostalCode('69007'); $manager->persist($clientNova); + $addressNova = new Address(); + $addressNova->setLabel('Principale'); + $addressNova->setStreet('5 avenue Jean Jaurès'); + $addressNova->setCity('Lyon'); + $addressNova->setPostalCode('69007'); + $addressNova->setCountry('FR'); + $addressNova->setClient($clientNova); + $manager->persist($addressNova); + // Prospects $prospectLead = new Prospect(); $prospectLead->setName('Marie Dupont'); $prospectLead->setCompany('Atelier Dupont'); $prospectLead->setEmail('marie@atelier-dupont.fr'); $prospectLead->setPhone('06 11 22 33 44'); - $prospectLead->setCity('Nantes'); - $prospectLead->setPostalCode('44000'); $prospectLead->setStatus(ProspectStatus::New); $prospectLead->setSource('Site web'); $prospectLead->setNotes('Demande de devis via le formulaire de contact.'); $manager->persist($prospectLead); + $addressLead = new Address(); + $addressLead->setLabel('Principale'); + $addressLead->setCity('Nantes'); + $addressLead->setPostalCode('44000'); + $addressLead->setCountry('FR'); + $addressLead->setProspect($prospectLead); + $manager->persist($addressLead); + $prospectQualified = new Prospect(); $prospectQualified->setName('Jean Martin'); $prospectQualified->setCompany('Martin & Fils'); $prospectQualified->setEmail('contact@martin-fils.fr'); $prospectQualified->setPhone('07 55 66 77 88'); - $prospectQualified->setStreet('22 rue du Commerce'); - $prospectQualified->setCity('Bordeaux'); - $prospectQualified->setPostalCode('33000'); $prospectQualified->setStatus(ProspectStatus::Qualified); $prospectQualified->setSource('Salon professionnel'); $manager->persist($prospectQualified); + $addressQualified = new Address(); + $addressQualified->setLabel('Principale'); + $addressQualified->setStreet('22 rue du Commerce'); + $addressQualified->setCity('Bordeaux'); + $addressQualified->setPostalCode('33000'); + $addressQualified->setCountry('FR'); + $addressQualified->setProspect($prospectQualified); + $manager->persist($addressQualified); + $prospectWon = new Prospect(); $prospectWon->setName('Sophie Bernard'); $prospectWon->setCompany('ACME Corp'); $prospectWon->setEmail('contact@acme.com'); $prospectWon->setPhone('01 23 45 67 89'); - $prospectWon->setCity('Paris'); - $prospectWon->setPostalCode('75002'); $prospectWon->setStatus(ProspectStatus::Won); $prospectWon->setSource('Recommandation'); $prospectWon->setConvertedClient($clientAcme); $manager->persist($prospectWon); + $addressWon = new Address(); + $addressWon->setLabel('Principale'); + $addressWon->setCity('Paris'); + $addressWon->setPostalCode('75002'); + $addressWon->setCountry('FR'); + $addressWon->setProspect($prospectWon); + $manager->persist($addressWon); + // Workflow par défaut $standardWorkflow = new Workflow(); $standardWorkflow->setName('Standard'); diff --git a/src/Module/Directory/Domain/Entity/Client.php b/src/Module/Directory/Domain/Entity/Client.php index eb28ae0..9d420be 100644 --- a/src/Module/Directory/Domain/Entity/Client.php +++ b/src/Module/Directory/Domain/Entity/Client.php @@ -58,18 +58,6 @@ class Client implements ClientInterface, TimestampableInterface, BlamableInterfa #[Groups(['client:read', 'client:write'])] private ?string $phone = null; - #[ORM\Column(length: 255, nullable: true)] - #[Groups(['client:read', 'client:write'])] - private ?string $street = null; - - #[ORM\Column(length: 255, nullable: true)] - #[Groups(['client:read', 'client:write'])] - private ?string $city = null; - - #[ORM\Column(length: 20, nullable: true)] - #[Groups(['client:read', 'client:write'])] - private ?string $postalCode = null; - /** @var Collection */ #[ORM\OneToMany(targetEntity: ProjectInterface::class, mappedBy: 'client')] private Collection $projects; @@ -120,42 +108,6 @@ class Client implements ClientInterface, TimestampableInterface, BlamableInterfa return $this; } - public function getStreet(): ?string - { - return $this->street; - } - - public function setStreet(?string $street): static - { - $this->street = $street; - - return $this; - } - - public function getCity(): ?string - { - return $this->city; - } - - public function setCity(?string $city): static - { - $this->city = $city; - - return $this; - } - - public function getPostalCode(): ?string - { - return $this->postalCode; - } - - public function setPostalCode(?string $postalCode): static - { - $this->postalCode = $postalCode; - - return $this; - } - /** @return Collection */ public function getProjects(): Collection { diff --git a/src/Module/Directory/Domain/Entity/Prospect.php b/src/Module/Directory/Domain/Entity/Prospect.php index 2806fd7..cd0f213 100644 --- a/src/Module/Directory/Domain/Entity/Prospect.php +++ b/src/Module/Directory/Domain/Entity/Prospect.php @@ -71,18 +71,6 @@ class Prospect implements TimestampableInterface, BlamableInterface #[Groups(['prospect:read', 'prospect:write'])] private ?string $phone = null; - #[ORM\Column(length: 255, nullable: true)] - #[Groups(['prospect:read', 'prospect:write'])] - private ?string $street = null; - - #[ORM\Column(length: 255, nullable: true)] - #[Groups(['prospect:read', 'prospect:write'])] - private ?string $city = null; - - #[ORM\Column(length: 20, nullable: true)] - #[Groups(['prospect:read', 'prospect:write'])] - private ?string $postalCode = null; - #[ORM\Column(type: Types::STRING, length: 32, enumType: ProspectStatus::class)] #[Groups(['prospect:read', 'prospect:write'])] private ProspectStatus $status = ProspectStatus::New; @@ -153,42 +141,6 @@ class Prospect implements TimestampableInterface, BlamableInterface return $this; } - public function getStreet(): ?string - { - return $this->street; - } - - public function setStreet(?string $street): static - { - $this->street = $street; - - return $this; - } - - public function getCity(): ?string - { - return $this->city; - } - - public function setCity(?string $city): static - { - $this->city = $city; - - return $this; - } - - public function getPostalCode(): ?string - { - return $this->postalCode; - } - - public function setPostalCode(?string $postalCode): static - { - $this->postalCode = $postalCode; - - return $this; - } - public function getStatus(): ProspectStatus { return $this->status; diff --git a/src/Module/Directory/Infrastructure/ApiPlatform/State/ConvertProspectProcessor.php b/src/Module/Directory/Infrastructure/ApiPlatform/State/ConvertProspectProcessor.php index 51d801a..7c62c93 100644 --- a/src/Module/Directory/Infrastructure/ApiPlatform/State/ConvertProspectProcessor.php +++ b/src/Module/Directory/Infrastructure/ApiPlatform/State/ConvertProspectProcessor.php @@ -47,9 +47,6 @@ final readonly class ConvertProspectProcessor implements ProcessorInterface $client->setName($prospect->getCompany() ?: (string) $prospect->getName()); $client->setEmail($prospect->getEmail()); $client->setPhone($prospect->getPhone()); - $client->setStreet($prospect->getStreet()); - $client->setCity($prospect->getCity()); - $client->setPostalCode($prospect->getPostalCode()); $this->entityManager->persist($client); diff --git a/src/Module/Directory/Infrastructure/Mcp/Tool/ConvertProspectTool.php b/src/Module/Directory/Infrastructure/Mcp/Tool/ConvertProspectTool.php index 22d81d3..b52595b 100644 --- a/src/Module/Directory/Infrastructure/Mcp/Tool/ConvertProspectTool.php +++ b/src/Module/Directory/Infrastructure/Mcp/Tool/ConvertProspectTool.php @@ -41,9 +41,6 @@ class ConvertProspectTool $client->setName($prospect->getCompany() ?: (string) $prospect->getName()); $client->setEmail($prospect->getEmail()); $client->setPhone($prospect->getPhone()); - $client->setStreet($prospect->getStreet()); - $client->setCity($prospect->getCity()); - $client->setPostalCode($prospect->getPostalCode()); $this->entityManager->persist($client); diff --git a/src/Module/Directory/Infrastructure/Mcp/Tool/CreateClientTool.php b/src/Module/Directory/Infrastructure/Mcp/Tool/CreateClientTool.php index af39f52..cef763d 100644 --- a/src/Module/Directory/Infrastructure/Mcp/Tool/CreateClientTool.php +++ b/src/Module/Directory/Infrastructure/Mcp/Tool/CreateClientTool.php @@ -23,9 +23,6 @@ class CreateClientTool string $name, ?string $email = null, ?string $phone = null, - ?string $street = null, - ?string $city = null, - ?string $postalCode = null, ): string { if (!$this->security->isGranted('ROLE_ADMIN')) { throw new AccessDeniedException('Access denied: ROLE_ADMIN required.'); @@ -35,9 +32,6 @@ class CreateClientTool $client->setName($name); $client->setEmail($email); $client->setPhone($phone); - $client->setStreet($street); - $client->setCity($city); - $client->setPostalCode($postalCode); $this->entityManager->persist($client); $this->entityManager->flush(); diff --git a/src/Module/Directory/Infrastructure/Mcp/Tool/CreateProspectTool.php b/src/Module/Directory/Infrastructure/Mcp/Tool/CreateProspectTool.php index ddce7c0..7230599 100644 --- a/src/Module/Directory/Infrastructure/Mcp/Tool/CreateProspectTool.php +++ b/src/Module/Directory/Infrastructure/Mcp/Tool/CreateProspectTool.php @@ -28,9 +28,6 @@ class CreateProspectTool ?string $company = null, ?string $email = null, ?string $phone = null, - ?string $street = null, - ?string $city = null, - ?string $postalCode = null, ?string $status = null, ?string $source = null, ?string $notes = null, @@ -44,9 +41,6 @@ class CreateProspectTool $prospect->setCompany($company); $prospect->setEmail($email); $prospect->setPhone($phone); - $prospect->setStreet($street); - $prospect->setCity($city); - $prospect->setPostalCode($postalCode); $prospect->setSource($source); $prospect->setNotes($notes); diff --git a/src/Module/Directory/Infrastructure/Mcp/Tool/UpdateClientTool.php b/src/Module/Directory/Infrastructure/Mcp/Tool/UpdateClientTool.php index 145cd6c..f780006 100644 --- a/src/Module/Directory/Infrastructure/Mcp/Tool/UpdateClientTool.php +++ b/src/Module/Directory/Infrastructure/Mcp/Tool/UpdateClientTool.php @@ -28,9 +28,6 @@ class UpdateClientTool ?string $name = null, ?string $email = null, ?string $phone = null, - ?string $street = null, - ?string $city = null, - ?string $postalCode = null, ): string { if (!$this->security->isGranted('ROLE_ADMIN')) { throw new AccessDeniedException('Access denied: ROLE_ADMIN required.'); @@ -50,15 +47,6 @@ class UpdateClientTool if (null !== $phone) { $client->setPhone($phone); } - if (null !== $street) { - $client->setStreet($street); - } - if (null !== $city) { - $client->setCity($city); - } - if (null !== $postalCode) { - $client->setPostalCode($postalCode); - } $this->entityManager->flush(); diff --git a/src/Module/Directory/Infrastructure/Mcp/Tool/UpdateProspectTool.php b/src/Module/Directory/Infrastructure/Mcp/Tool/UpdateProspectTool.php index e411200..d4dfb72 100644 --- a/src/Module/Directory/Infrastructure/Mcp/Tool/UpdateProspectTool.php +++ b/src/Module/Directory/Infrastructure/Mcp/Tool/UpdateProspectTool.php @@ -30,9 +30,6 @@ class UpdateProspectTool ?string $company = null, ?string $email = null, ?string $phone = null, - ?string $street = null, - ?string $city = null, - ?string $postalCode = null, ?string $status = null, ?string $source = null, ?string $notes = null, @@ -58,15 +55,6 @@ class UpdateProspectTool if (null !== $phone) { $prospect->setPhone($phone); } - if (null !== $street) { - $prospect->setStreet($street); - } - if (null !== $city) { - $prospect->setCity($city); - } - if (null !== $postalCode) { - $prospect->setPostalCode($postalCode); - } if (null !== $status) { $statusEnum = ProspectStatus::tryFrom($status); if (null === $statusEnum) { diff --git a/src/Shared/Infrastructure/Mcp/Serializer.php b/src/Shared/Infrastructure/Mcp/Serializer.php index 74ff602..c8269d7 100644 --- a/src/Shared/Infrastructure/Mcp/Serializer.php +++ b/src/Shared/Infrastructure/Mcp/Serializer.php @@ -366,13 +366,10 @@ final class Serializer public static function client(Client $c): array { return [ - 'id' => $c->getId(), - 'name' => $c->getName(), - 'email' => $c->getEmail(), - 'phone' => $c->getPhone(), - 'street' => $c->getStreet(), - 'city' => $c->getCity(), - 'postalCode' => $c->getPostalCode(), + 'id' => $c->getId(), + 'name' => $c->getName(), + 'email' => $c->getEmail(), + 'phone' => $c->getPhone(), ]; } @@ -389,9 +386,6 @@ final class Serializer 'company' => $p->getCompany(), 'email' => $p->getEmail(), 'phone' => $p->getPhone(), - 'street' => $p->getStreet(), - 'city' => $p->getCity(), - 'postalCode' => $p->getPostalCode(), 'status' => $p->getStatus()->value, 'statusLabel' => $p->getStatus()->label(), 'source' => $p->getSource(), diff --git a/tests/Functional/Module/Directory/ProspectConversionTest.php b/tests/Functional/Module/Directory/ProspectConversionTest.php index 852b2f8..5bbf7b0 100644 --- a/tests/Functional/Module/Directory/ProspectConversionTest.php +++ b/tests/Functional/Module/Directory/ProspectConversionTest.php @@ -32,9 +32,6 @@ class ProspectConversionTest extends KernelTestCase $prospect->setCompany('Lead Company '.uniqid()); $prospect->setEmail('lead@example.com'); $prospect->setPhone('06 00 00 00 00'); - $prospect->setStreet('1 rue du Test'); - $prospect->setCity('Testville'); - $prospect->setPostalCode('00000'); $prospect->setStatus(ProspectStatus::Qualified); $this->em->persist($prospect); $this->em->flush();