diff --git a/symfony/Makefile b/symfony/Makefile index 442b8211..f7af24ca 100644 --- a/symfony/Makefile +++ b/symfony/Makefile @@ -28,11 +28,12 @@ sf: ## List all Symfony commands or pass the parameter "c=" to run a given comma cc: c=c:c ## Clear the cache cc: sf -reset-database-schema: - @$(SYMFONY) do:s:u -f +recreate-database: drop-database create-database configure-database -create-database: +drop-database: @$(SYMFONY) do:da:dr -f + +create-database: @$(SYMFONY) do:da:cr run-migration rerun-migration: @@ -50,10 +51,14 @@ make-entity: regenerate-entity: @$(SYMFONY) make:entity --regenerate +enable-postgis: + @$(SYMFONY) dbal:run-sql 'CREATE extension postgis;' + make-run-migration: make-migration run-migration -reset-database: create-database run-migration +reset-database: recreate-database run-migration rerun-database: reset-database run-fixtures -create-short-migration: create-database run-migration make-migration rerun-migration +configure-database: enable-postgis +create-short-migration: recreate-database run-migration make-migration rerun-migration init-jwt-keypair: @$(SYMFONY) lexik:jwt:generate-keypair \ No newline at end of file diff --git a/symfony/compose.override.yaml b/symfony/compose.override.yaml deleted file mode 100644 index c5612b0a..00000000 --- a/symfony/compose.override.yaml +++ /dev/null @@ -1,7 +0,0 @@ - -services: -###> doctrine/doctrine-bundle ### - database: - ports: - - "5432" -###< doctrine/doctrine-bundle ### diff --git a/symfony/compose.yaml b/symfony/compose.yaml deleted file mode 100644 index 89c74d18..00000000 --- a/symfony/compose.yaml +++ /dev/null @@ -1,25 +0,0 @@ - -services: -###> doctrine/doctrine-bundle ### - database: - image: postgres:${POSTGRES_VERSION:-16}-alpine - environment: - POSTGRES_DB: ${POSTGRES_DB:-app} - # You should definitely change the password in production - POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-!ChangeMe!} - POSTGRES_USER: ${POSTGRES_USER:-app} - healthcheck: - test: ["CMD", "pg_isready", "-d", "${POSTGRES_DB:-app}", "-U", "${POSTGRES_USER:-app}"] - timeout: 5s - retries: 5 - start_period: 60s - volumes: - - database_data:/var/lib/postgresql/data:rw - # You may use a bind-mounted host directory instead, so that it is harder to accidentally remove the volume and lose all your data! - # - ./docker/db/data:/var/lib/postgresql/data:rw -###< doctrine/doctrine-bundle ### - -volumes: -###> doctrine/doctrine-bundle ### - database_data: -###< doctrine/doctrine-bundle ### diff --git a/symfony/fixtures/actors.yaml b/symfony/fixtures/actors.yaml new file mode 100644 index 00000000..f6fdf961 --- /dev/null +++ b/symfony/fixtures/actors.yaml @@ -0,0 +1,21 @@ +App\Entity\Actor: + actor_{1..40}: + name: + acronym: + createdBy: '@user_' + category: ')>' + expertises: 'x @actorexpertise_*' + thematics: 'x @thematic_*' + creationDate: + lastUpdate: + description: + administrativeScopes: 'x @administrative_scope_*' + officeName: + officeAddress: + contactName: + contactPosition: + website: + phone: + email: + logo: + projects: 'x @project_*' \ No newline at end of file diff --git a/symfony/fixtures/actorsExpertise.yaml b/symfony/fixtures/actorsExpertise.yaml new file mode 100644 index 00000000..43ad933d --- /dev/null +++ b/symfony/fixtures/actorsExpertise.yaml @@ -0,0 +1,7 @@ +App\Entity\ActorExpertise: + actorexpertise_1: + name: Planification urbaine + actorexpertise_2: + name: Elaboration et mise en œuvre de la politique algorithmique de la nation ainsi que de l’aménagement du territoire + actorexpertise_3: + name: Production de l’Information Géospatiale \ No newline at end of file diff --git a/symfony/fixtures/administrativeScopes.yaml b/symfony/fixtures/administrativeScopes.yaml new file mode 100644 index 00000000..765d6779 --- /dev/null +++ b/symfony/fixtures/administrativeScopes.yaml @@ -0,0 +1,9 @@ +App\Entity\AdministrativeScope: + administrative_scope_1: + name: National + administrative_scope_2: + name: Régional + administrative_scope_3: + name: Départemental + administrative_scope_4: + name: Communal \ No newline at end of file diff --git a/symfony/fixtures/projects.yaml b/symfony/fixtures/projects.yaml index 58944902..d625c09e 100644 --- a/symfony/fixtures/projects.yaml +++ b/symfony/fixtures/projects.yaml @@ -1,25 +1,14 @@ - -# Il faut également générer des `Actor` et des `Thematic` pour que les relations ManyToMany fonctionnent bien. -App\Entity\Actor: - actor_{1..100}: - name: - # Ajoute d'autres champs en fonction de l'entité `Actor` - -App\Entity\Thematic: - thematic_{1..50}: - name: - App\Entity\Project: project_{1..500}: name: Urban Development location: # coords: 'POINT( )' coords: 'POINT( )' - status: ')>' # Remplace par les valeurs de ton Enum Status + status: ')>' description: images: [] partners: [] - interventionZone: ')>' # Remplace par les valeurs de ton Enum AdminLevel + interventionZone: ')>' financialActors: 'x @actor_*' actor: '@actor_*' contractingActors: 'x @actor_*' diff --git a/symfony/fixtures/thematics.yaml b/symfony/fixtures/thematics.yaml new file mode 100644 index 00000000..5796a152 --- /dev/null +++ b/symfony/fixtures/thematics.yaml @@ -0,0 +1,23 @@ +App\Entity\Thematic: + thematic_1: + name: Appui/Gouvernance + thematic_2: + name: Assainissement + thematic_3: + name: Concertation + thematic_4: + name: Environnement + thematic_5: + name: Equipements + thematic_6: + name: Études urbaines + thematic_7: + name: Numérique + thematic_8: + name: Plannification + thematic_9: + name: Renforcement des capacités + thematic_10: + name: Infrastructures légères + thematic_11: + name: Infrastructures structurantes \ No newline at end of file diff --git a/symfony/migrations/Version20240920210657.php b/symfony/migrations/Version20240920210657.php deleted file mode 100644 index 49950de7..00000000 --- a/symfony/migrations/Version20240920210657.php +++ /dev/null @@ -1,41 +0,0 @@ -addSql('CREATE SEQUENCE "user_id_seq" INCREMENT BY 1 MINVALUE 1 START 1'); - $this->addSql('CREATE TABLE actor (id UUID NOT NULL, created_by_id INT NOT NULL, name VARCHAR(255) NOT NULL, acronym VARCHAR(10) NOT NULL, is_validated BOOLEAN NOT NULL, PRIMARY KEY(id))'); - $this->addSql('CREATE INDEX IDX_447556F9B03A8386 ON actor (created_by_id)'); - $this->addSql('COMMENT ON COLUMN actor.id IS \'(DC2Type:uuid)\''); - $this->addSql('CREATE TABLE "user" (id INT NOT NULL, first_name VARCHAR(255) NOT NULL, last_name VARCHAR(255) NOT NULL, email VARCHAR(180) NOT NULL, roles JSON NOT NULL, password VARCHAR(255) NOT NULL, is_validated BOOLEAN NOT NULL, requested_roles JSON DEFAULT NULL, PRIMARY KEY(id))'); - $this->addSql('CREATE UNIQUE INDEX UNIQ_IDENTIFIER_EMAIL ON "user" (email)'); - $this->addSql('ALTER TABLE actor ADD CONSTRAINT FK_447556F9B03A8386 FOREIGN KEY (created_by_id) REFERENCES "user" (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('DROP SEQUENCE "user_id_seq" CASCADE'); - $this->addSql('ALTER TABLE actor DROP CONSTRAINT FK_447556F9B03A8386'); - $this->addSql('DROP TABLE actor'); - $this->addSql('DROP TABLE "user"'); - } -} diff --git a/symfony/migrations/Version20240922205429.php b/symfony/migrations/Version20240922205429.php deleted file mode 100644 index 134a781d..00000000 --- a/symfony/migrations/Version20240922205429.php +++ /dev/null @@ -1,38 +0,0 @@ -addSql('ALTER TABLE "user" ADD organisation VARCHAR(255) DEFAULT NULL'); - $this->addSql('ALTER TABLE "user" ADD position VARCHAR(255) DEFAULT NULL'); - $this->addSql('ALTER TABLE "user" ADD phone VARCHAR(20) DEFAULT NULL'); - $this->addSql('ALTER TABLE "user" ADD sign_in_message TEXT 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 "user" DROP organisation'); - $this->addSql('ALTER TABLE "user" DROP position'); - $this->addSql('ALTER TABLE "user" DROP phone'); - $this->addSql('ALTER TABLE "user" DROP sign_in_message'); - } -} diff --git a/symfony/migrations/Version20241001093511.php b/symfony/migrations/Version20241001093511.php deleted file mode 100644 index 5853e023..00000000 --- a/symfony/migrations/Version20241001093511.php +++ /dev/null @@ -1,28 +0,0 @@ -addSql('CREATE extension postgis;'); } - - public function down(Schema $schema): void - { - } -} diff --git a/symfony/migrations/Version20241001101921.php b/symfony/migrations/Version20241001101921.php deleted file mode 100644 index 1a59b714..00000000 --- a/symfony/migrations/Version20241001101921.php +++ /dev/null @@ -1,71 +0,0 @@ -addSql('CREATE SEQUENCE actor_id_seq INCREMENT BY 1 MINVALUE 1 START 1'); - $this->addSql('CREATE SEQUENCE project_id_seq INCREMENT BY 1 MINVALUE 1 START 1'); - $this->addSql('CREATE SEQUENCE thematic_id_seq INCREMENT BY 1 MINVALUE 1 START 1'); - $this->addSql('CREATE TABLE actor (id INT NOT NULL, name VARCHAR(255) NOT NULL, PRIMARY KEY(id))'); - $this->addSql('CREATE TABLE project (id INT NOT NULL, actor_id INT NOT NULL, title VARCHAR(255) NOT NULL, location VARCHAR(255) NOT NULL, coords geometry(POINT, 0) NOT NULL, status VARCHAR(255) NOT NULL, description TEXT DEFAULT NULL, images JSON DEFAULT NULL, partners JSON DEFAULT NULL, intervention_zone VARCHAR(255) NOT NULL, project_manager_name VARCHAR(255) DEFAULT NULL, project_manager_position VARCHAR(255) DEFAULT NULL, project_manager_email VARCHAR(255) DEFAULT NULL, project_manager_tel VARCHAR(255) DEFAULT NULL, project_manager_photo VARCHAR(255) DEFAULT NULL, website VARCHAR(255) DEFAULT NULL, logo VARCHAR(255) DEFAULT NULL, updated_at TIMESTAMP(0) WITHOUT TIME ZONE DEFAULT NULL, created_at TIMESTAMP(0) WITHOUT TIME ZONE NOT NULL, PRIMARY KEY(id))'); - $this->addSql('CREATE INDEX IDX_2FB3D0EE10DAF24A ON project (actor_id)'); - $this->addSql('COMMENT ON COLUMN project.updated_at IS \'(DC2Type:datetime_immutable)\''); - $this->addSql('COMMENT ON COLUMN project.created_at IS \'(DC2Type:datetime_immutable)\''); - $this->addSql('CREATE TABLE project_thematic (project_id INT NOT NULL, thematic_id INT NOT NULL, PRIMARY KEY(project_id, thematic_id))'); - $this->addSql('CREATE INDEX IDX_415254A9166D1F9C ON project_thematic (project_id)'); - $this->addSql('CREATE INDEX IDX_415254A92395FCED ON project_thematic (thematic_id)'); - $this->addSql('CREATE TABLE financed_projects_actors (project_id INT NOT NULL, actor_id INT NOT NULL, PRIMARY KEY(project_id, actor_id))'); - $this->addSql('CREATE INDEX IDX_50C6B8EC166D1F9C ON financed_projects_actors (project_id)'); - $this->addSql('CREATE INDEX IDX_50C6B8EC10DAF24A ON financed_projects_actors (actor_id)'); - $this->addSql('CREATE TABLE contracted_projects_actors (project_id INT NOT NULL, actor_id INT NOT NULL, PRIMARY KEY(project_id, actor_id))'); - $this->addSql('CREATE INDEX IDX_E73AB790166D1F9C ON contracted_projects_actors (project_id)'); - $this->addSql('CREATE INDEX IDX_E73AB79010DAF24A ON contracted_projects_actors (actor_id)'); - $this->addSql('CREATE TABLE thematic (id INT NOT NULL, name VARCHAR(255) NOT NULL, PRIMARY KEY(id))'); - $this->addSql('ALTER TABLE project ADD CONSTRAINT FK_2FB3D0EE10DAF24A FOREIGN KEY (actor_id) REFERENCES actor (id) NOT DEFERRABLE INITIALLY IMMEDIATE'); - $this->addSql('ALTER TABLE project_thematic ADD CONSTRAINT FK_415254A9166D1F9C FOREIGN KEY (project_id) REFERENCES project (id) ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE'); - $this->addSql('ALTER TABLE project_thematic ADD CONSTRAINT FK_415254A92395FCED FOREIGN KEY (thematic_id) REFERENCES thematic (id) ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE'); - $this->addSql('ALTER TABLE financed_projects_actors ADD CONSTRAINT FK_50C6B8EC166D1F9C FOREIGN KEY (project_id) REFERENCES project (id) ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE'); - $this->addSql('ALTER TABLE financed_projects_actors ADD CONSTRAINT FK_50C6B8EC10DAF24A FOREIGN KEY (actor_id) REFERENCES actor (id) ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE'); - $this->addSql('ALTER TABLE contracted_projects_actors ADD CONSTRAINT FK_E73AB790166D1F9C FOREIGN KEY (project_id) REFERENCES project (id) ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE'); - $this->addSql('ALTER TABLE contracted_projects_actors ADD CONSTRAINT FK_E73AB79010DAF24A FOREIGN KEY (actor_id) REFERENCES actor (id) ON DELETE CASCADE 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('DROP SEQUENCE actor_id_seq CASCADE'); - $this->addSql('DROP SEQUENCE project_id_seq CASCADE'); - $this->addSql('DROP SEQUENCE thematic_id_seq CASCADE'); - $this->addSql('ALTER TABLE project DROP CONSTRAINT FK_2FB3D0EE10DAF24A'); - $this->addSql('ALTER TABLE project_thematic DROP CONSTRAINT FK_415254A9166D1F9C'); - $this->addSql('ALTER TABLE project_thematic DROP CONSTRAINT FK_415254A92395FCED'); - $this->addSql('ALTER TABLE financed_projects_actors DROP CONSTRAINT FK_50C6B8EC166D1F9C'); - $this->addSql('ALTER TABLE financed_projects_actors DROP CONSTRAINT FK_50C6B8EC10DAF24A'); - $this->addSql('ALTER TABLE contracted_projects_actors DROP CONSTRAINT FK_E73AB790166D1F9C'); - $this->addSql('ALTER TABLE contracted_projects_actors DROP CONSTRAINT FK_E73AB79010DAF24A'); - $this->addSql('DROP TABLE actor'); - $this->addSql('DROP TABLE project'); - $this->addSql('DROP TABLE project_thematic'); - $this->addSql('DROP TABLE financed_projects_actors'); - $this->addSql('DROP TABLE contracted_projects_actors'); - $this->addSql('DROP TABLE thematic'); - } -} diff --git a/symfony/migrations/Version20241001151351.php b/symfony/migrations/Version20241001151351.php deleted file mode 100644 index 758a0bf5..00000000 --- a/symfony/migrations/Version20241001151351.php +++ /dev/null @@ -1,40 +0,0 @@ -addSql('CREATE SEQUENCE "user_id_seq" INCREMENT BY 1 MINVALUE 1 START 1'); - $this->addSql('CREATE TABLE actor (id UUID NOT NULL, created_by_id INT NOT NULL, name VARCHAR(255) NOT NULL, acronym VARCHAR(10) NOT NULL, is_validated BOOLEAN NOT NULL, PRIMARY KEY(id))'); - $this->addSql('CREATE INDEX IDX_447556F9B03A8386 ON actor (created_by_id)'); - $this->addSql('COMMENT ON COLUMN actor.id IS \'(DC2Type:uuid)\''); - $this->addSql('CREATE TABLE "user" (id INT NOT NULL, first_name VARCHAR(255) NOT NULL, last_name VARCHAR(255) NOT NULL, email VARCHAR(180) NOT NULL, roles JSON NOT NULL, password VARCHAR(255) NOT NULL, is_validated BOOLEAN NOT NULL, requested_roles JSON DEFAULT NULL, organisation VARCHAR(255) DEFAULT NULL, position VARCHAR(255) DEFAULT NULL, phone VARCHAR(20) DEFAULT NULL, sign_up_message TEXT DEFAULT NULL, PRIMARY KEY(id))'); - $this->addSql('ALTER TABLE actor ADD CONSTRAINT FK_447556F9B03A8386 FOREIGN KEY (created_by_id) REFERENCES "user" (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('DROP SEQUENCE "user_id_seq" CASCADE'); - $this->addSql('ALTER TABLE actor DROP CONSTRAINT FK_447556F9B03A8386'); - $this->addSql('DROP TABLE actor'); - $this->addSql('DROP TABLE "user"'); - } -} diff --git a/symfony/migrations/Version20241002093519.php b/symfony/migrations/Version20241002093519.php deleted file mode 100644 index 3204f1c1..00000000 --- a/symfony/migrations/Version20241002093519.php +++ /dev/null @@ -1,42 +0,0 @@ -addSql('ALTER TABLE project ALTER updated_at TYPE TIMESTAMP(0) WITHOUT TIME ZONE'); - $this->addSql('ALTER TABLE project ALTER updated_at SET NOT NULL'); - $this->addSql('ALTER TABLE project ALTER created_at TYPE TIMESTAMP(0) WITHOUT TIME ZONE'); - $this->addSql('ALTER TABLE project RENAME COLUMN title TO name'); - $this->addSql('COMMENT ON COLUMN project.updated_at IS NULL'); - $this->addSql('COMMENT ON COLUMN project.created_at IS 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 project ALTER created_at TYPE TIMESTAMP(0) WITHOUT TIME ZONE'); - $this->addSql('ALTER TABLE project ALTER updated_at TYPE TIMESTAMP(0) WITHOUT TIME ZONE'); - $this->addSql('ALTER TABLE project ALTER updated_at DROP NOT NULL'); - $this->addSql('ALTER TABLE project RENAME COLUMN name TO title'); - $this->addSql('COMMENT ON COLUMN project.created_at IS \'(DC2Type:datetime_immutable)\''); - $this->addSql('COMMENT ON COLUMN project.updated_at IS \'(DC2Type:datetime_immutable)\''); - } -} diff --git a/symfony/migrations/Version20241008065301.php b/symfony/migrations/Version20241008065301.php new file mode 100644 index 00000000..7449bbce --- /dev/null +++ b/symfony/migrations/Version20241008065301.php @@ -0,0 +1,113 @@ +addSql('CREATE SEQUENCE actor_expertise_id_seq INCREMENT BY 1 MINVALUE 1 START 1'); + $this->addSql('CREATE SEQUENCE administrative_scope_id_seq INCREMENT BY 1 MINVALUE 1 START 1'); + $this->addSql('CREATE SEQUENCE project_id_seq INCREMENT BY 1 MINVALUE 1 START 1'); + $this->addSql('CREATE SEQUENCE thematic_id_seq INCREMENT BY 1 MINVALUE 1 START 1'); + $this->addSql('CREATE SEQUENCE "user_id_seq" INCREMENT BY 1 MINVALUE 1 START 1'); + $this->addSql('CREATE TABLE actor (id UUID NOT NULL, created_by_id INT NOT NULL, name VARCHAR(255) NOT NULL, acronym VARCHAR(255) NOT NULL, is_validated BOOLEAN NOT NULL, category VARCHAR(255) NOT NULL, creation_date TIMESTAMP(0) WITHOUT TIME ZONE NOT NULL, last_update TIMESTAMP(0) WITHOUT TIME ZONE NOT NULL, description TEXT NOT NULL, office_name VARCHAR(255) DEFAULT NULL, office_address VARCHAR(255) DEFAULT NULL, contact_name VARCHAR(255) DEFAULT NULL, contact_position VARCHAR(255) DEFAULT NULL, website VARCHAR(255) DEFAULT NULL, phone VARCHAR(255) DEFAULT NULL, email VARCHAR(255) DEFAULT NULL, logo VARCHAR(255) DEFAULT NULL, PRIMARY KEY(id))'); + $this->addSql('CREATE INDEX IDX_447556F9B03A8386 ON actor (created_by_id)'); + $this->addSql('COMMENT ON COLUMN actor.id IS \'(DC2Type:uuid)\''); + $this->addSql('CREATE TABLE actor_actor_expertise (actor_id UUID NOT NULL, actor_expertise_id INT NOT NULL, PRIMARY KEY(actor_id, actor_expertise_id))'); + $this->addSql('CREATE INDEX IDX_4A438EAD10DAF24A ON actor_actor_expertise (actor_id)'); + $this->addSql('CREATE INDEX IDX_4A438EAD916905AC ON actor_actor_expertise (actor_expertise_id)'); + $this->addSql('COMMENT ON COLUMN actor_actor_expertise.actor_id IS \'(DC2Type:uuid)\''); + $this->addSql('CREATE TABLE actor_thematic (actor_id UUID NOT NULL, thematic_id INT NOT NULL, PRIMARY KEY(actor_id, thematic_id))'); + $this->addSql('CREATE INDEX IDX_D159A26410DAF24A ON actor_thematic (actor_id)'); + $this->addSql('CREATE INDEX IDX_D159A2642395FCED ON actor_thematic (thematic_id)'); + $this->addSql('COMMENT ON COLUMN actor_thematic.actor_id IS \'(DC2Type:uuid)\''); + $this->addSql('CREATE TABLE actor_administrative_scope (actor_id UUID NOT NULL, administrative_scope_id INT NOT NULL, PRIMARY KEY(actor_id, administrative_scope_id))'); + $this->addSql('CREATE INDEX IDX_65EBE3CC10DAF24A ON actor_administrative_scope (actor_id)'); + $this->addSql('CREATE INDEX IDX_65EBE3CCC1892E43 ON actor_administrative_scope (administrative_scope_id)'); + $this->addSql('COMMENT ON COLUMN actor_administrative_scope.actor_id IS \'(DC2Type:uuid)\''); + $this->addSql('CREATE TABLE actor_expertise (id INT NOT NULL, name VARCHAR(255) NOT NULL, PRIMARY KEY(id))'); + $this->addSql('CREATE TABLE administrative_scope (id INT NOT NULL, name VARCHAR(255) NOT NULL, PRIMARY KEY(id))'); + $this->addSql('CREATE TABLE project (id INT NOT NULL, actor_id UUID NOT NULL, name VARCHAR(255) NOT NULL, location VARCHAR(255) NOT NULL, coords geometry(POINT, 0) NOT NULL, status VARCHAR(255) NOT NULL, description TEXT DEFAULT NULL, images JSON DEFAULT NULL, partners JSON DEFAULT NULL, intervention_zone VARCHAR(255) NOT NULL, project_manager_name VARCHAR(255) DEFAULT NULL, project_manager_position VARCHAR(255) DEFAULT NULL, project_manager_email VARCHAR(255) DEFAULT NULL, project_manager_tel VARCHAR(255) DEFAULT NULL, project_manager_photo VARCHAR(255) DEFAULT NULL, website VARCHAR(255) DEFAULT NULL, logo VARCHAR(255) DEFAULT NULL, created_at TIMESTAMP(0) WITHOUT TIME ZONE NOT NULL, updated_at TIMESTAMP(0) WITHOUT TIME ZONE NOT NULL, PRIMARY KEY(id))'); + $this->addSql('CREATE INDEX IDX_2FB3D0EE10DAF24A ON project (actor_id)'); + $this->addSql('COMMENT ON COLUMN project.actor_id IS \'(DC2Type:uuid)\''); + $this->addSql('CREATE TABLE project_thematic (project_id INT NOT NULL, thematic_id INT NOT NULL, PRIMARY KEY(project_id, thematic_id))'); + $this->addSql('CREATE INDEX IDX_415254A9166D1F9C ON project_thematic (project_id)'); + $this->addSql('CREATE INDEX IDX_415254A92395FCED ON project_thematic (thematic_id)'); + $this->addSql('CREATE TABLE financed_projects_actors (project_id INT NOT NULL, actor_id UUID NOT NULL, PRIMARY KEY(project_id, actor_id))'); + $this->addSql('CREATE INDEX IDX_50C6B8EC166D1F9C ON financed_projects_actors (project_id)'); + $this->addSql('CREATE INDEX IDX_50C6B8EC10DAF24A ON financed_projects_actors (actor_id)'); + $this->addSql('COMMENT ON COLUMN financed_projects_actors.actor_id IS \'(DC2Type:uuid)\''); + $this->addSql('CREATE TABLE contracted_projects_actors (project_id INT NOT NULL, actor_id UUID NOT NULL, PRIMARY KEY(project_id, actor_id))'); + $this->addSql('CREATE INDEX IDX_E73AB790166D1F9C ON contracted_projects_actors (project_id)'); + $this->addSql('CREATE INDEX IDX_E73AB79010DAF24A ON contracted_projects_actors (actor_id)'); + $this->addSql('COMMENT ON COLUMN contracted_projects_actors.actor_id IS \'(DC2Type:uuid)\''); + $this->addSql('CREATE TABLE thematic (id INT NOT NULL, name VARCHAR(255) NOT NULL, PRIMARY KEY(id))'); + $this->addSql('CREATE TABLE "user" (id INT NOT NULL, first_name VARCHAR(255) NOT NULL, last_name VARCHAR(255) NOT NULL, email VARCHAR(180) NOT NULL, roles JSON NOT NULL, password VARCHAR(255) NOT NULL, is_validated BOOLEAN NOT NULL, requested_roles JSON DEFAULT NULL, organisation VARCHAR(255) DEFAULT NULL, position VARCHAR(255) DEFAULT NULL, phone VARCHAR(20) DEFAULT NULL, sign_up_message TEXT DEFAULT NULL, PRIMARY KEY(id))'); + $this->addSql('ALTER TABLE actor ADD CONSTRAINT FK_447556F9B03A8386 FOREIGN KEY (created_by_id) REFERENCES "user" (id) NOT DEFERRABLE INITIALLY IMMEDIATE'); + $this->addSql('ALTER TABLE actor_actor_expertise ADD CONSTRAINT FK_4A438EAD10DAF24A FOREIGN KEY (actor_id) REFERENCES actor (id) ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE'); + $this->addSql('ALTER TABLE actor_actor_expertise ADD CONSTRAINT FK_4A438EAD916905AC FOREIGN KEY (actor_expertise_id) REFERENCES actor_expertise (id) ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE'); + $this->addSql('ALTER TABLE actor_thematic ADD CONSTRAINT FK_D159A26410DAF24A FOREIGN KEY (actor_id) REFERENCES actor (id) ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE'); + $this->addSql('ALTER TABLE actor_thematic ADD CONSTRAINT FK_D159A2642395FCED FOREIGN KEY (thematic_id) REFERENCES thematic (id) ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE'); + $this->addSql('ALTER TABLE actor_administrative_scope ADD CONSTRAINT FK_65EBE3CC10DAF24A FOREIGN KEY (actor_id) REFERENCES actor (id) ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE'); + $this->addSql('ALTER TABLE actor_administrative_scope ADD CONSTRAINT FK_65EBE3CCC1892E43 FOREIGN KEY (administrative_scope_id) REFERENCES administrative_scope (id) ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE'); + $this->addSql('ALTER TABLE project ADD CONSTRAINT FK_2FB3D0EE10DAF24A FOREIGN KEY (actor_id) REFERENCES actor (id) NOT DEFERRABLE INITIALLY IMMEDIATE'); + $this->addSql('ALTER TABLE project_thematic ADD CONSTRAINT FK_415254A9166D1F9C FOREIGN KEY (project_id) REFERENCES project (id) ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE'); + $this->addSql('ALTER TABLE project_thematic ADD CONSTRAINT FK_415254A92395FCED FOREIGN KEY (thematic_id) REFERENCES thematic (id) ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE'); + $this->addSql('ALTER TABLE financed_projects_actors ADD CONSTRAINT FK_50C6B8EC166D1F9C FOREIGN KEY (project_id) REFERENCES project (id) ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE'); + $this->addSql('ALTER TABLE financed_projects_actors ADD CONSTRAINT FK_50C6B8EC10DAF24A FOREIGN KEY (actor_id) REFERENCES actor (id) ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE'); + $this->addSql('ALTER TABLE contracted_projects_actors ADD CONSTRAINT FK_E73AB790166D1F9C FOREIGN KEY (project_id) REFERENCES project (id) ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE'); + $this->addSql('ALTER TABLE contracted_projects_actors ADD CONSTRAINT FK_E73AB79010DAF24A FOREIGN KEY (actor_id) REFERENCES actor (id) ON DELETE CASCADE 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('DROP SEQUENCE actor_expertise_id_seq CASCADE'); + $this->addSql('DROP SEQUENCE administrative_scope_id_seq CASCADE'); + $this->addSql('DROP SEQUENCE project_id_seq CASCADE'); + $this->addSql('DROP SEQUENCE thematic_id_seq CASCADE'); + $this->addSql('DROP SEQUENCE "user_id_seq" CASCADE'); + $this->addSql('ALTER TABLE actor DROP CONSTRAINT FK_447556F9B03A8386'); + $this->addSql('ALTER TABLE actor_actor_expertise DROP CONSTRAINT FK_4A438EAD10DAF24A'); + $this->addSql('ALTER TABLE actor_actor_expertise DROP CONSTRAINT FK_4A438EAD916905AC'); + $this->addSql('ALTER TABLE actor_thematic DROP CONSTRAINT FK_D159A26410DAF24A'); + $this->addSql('ALTER TABLE actor_thematic DROP CONSTRAINT FK_D159A2642395FCED'); + $this->addSql('ALTER TABLE actor_administrative_scope DROP CONSTRAINT FK_65EBE3CC10DAF24A'); + $this->addSql('ALTER TABLE actor_administrative_scope DROP CONSTRAINT FK_65EBE3CCC1892E43'); + $this->addSql('ALTER TABLE project DROP CONSTRAINT FK_2FB3D0EE10DAF24A'); + $this->addSql('ALTER TABLE project_thematic DROP CONSTRAINT FK_415254A9166D1F9C'); + $this->addSql('ALTER TABLE project_thematic DROP CONSTRAINT FK_415254A92395FCED'); + $this->addSql('ALTER TABLE financed_projects_actors DROP CONSTRAINT FK_50C6B8EC166D1F9C'); + $this->addSql('ALTER TABLE financed_projects_actors DROP CONSTRAINT FK_50C6B8EC10DAF24A'); + $this->addSql('ALTER TABLE contracted_projects_actors DROP CONSTRAINT FK_E73AB790166D1F9C'); + $this->addSql('ALTER TABLE contracted_projects_actors DROP CONSTRAINT FK_E73AB79010DAF24A'); + $this->addSql('DROP TABLE actor'); + $this->addSql('DROP TABLE actor_actor_expertise'); + $this->addSql('DROP TABLE actor_thematic'); + $this->addSql('DROP TABLE actor_administrative_scope'); + $this->addSql('DROP TABLE actor_expertise'); + $this->addSql('DROP TABLE administrative_scope'); + $this->addSql('DROP TABLE project'); + $this->addSql('DROP TABLE project_thematic'); + $this->addSql('DROP TABLE financed_projects_actors'); + $this->addSql('DROP TABLE contracted_projects_actors'); + $this->addSql('DROP TABLE thematic'); + $this->addSql('DROP TABLE "user"'); + } +} diff --git a/symfony/src/Entity/Actor.php b/symfony/src/Entity/Actor.php index 97411e57..801311ae 100644 --- a/symfony/src/Entity/Actor.php +++ b/symfony/src/Entity/Actor.php @@ -2,13 +2,19 @@ namespace App\Entity; +use App\Entity\Thematic; +use ApiPlatform\Metadata\Get; use ApiPlatform\Metadata\Put; +use App\Enum\ActorCategory; use ApiPlatform\Metadata\Post; +use App\Entity\ActorExpertise; use App\Model\Enums\UserRoles; +use Doctrine\DBAL\Types\Types; use ApiPlatform\Metadata\Patch; use Symfony\Component\Uid\Uuid; use Doctrine\ORM\Mapping as ORM; use App\Security\Voter\ActorVoter; +use App\Entity\AdministrativeScope; use App\Repository\ActorRepository; use ApiPlatform\Metadata\ApiResource; use ApiPlatform\Metadata\GetCollection; @@ -17,13 +23,18 @@ use App\Services\State\Processor\ActorProcessor; use Doctrine\Common\Collections\ArrayCollection; use Symfony\Component\Serializer\Annotation\Groups; +use Symfony\Component\Validator\Constraints as Assert; +use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity; #[ORM\Entity(repositoryClass: ActorRepository::class)] +#[UniqueEntity('name')] #[ApiResource( operations: [ new GetCollection( - provider: ActorProvider::class + provider: ActorProvider::class, + normalizationContext: ['groups' => self::ACTOR_READ_ITEM_COLLECTION] ), + new Get(), new Post( processor: ActorProcessor::class, security: "is_granted('".UserRoles::ROLE_EDITOR_ACTORS."')" @@ -36,45 +47,120 @@ security: 'is_granted("'.ActorVoter::EDIT.'", object)' ) ], - normalizationContext: ['groups' => [self::GROUP_READ]], - denormalizationContext: ['groups' => [self::GROUP_WRITE]], + normalizationContext: ['groups' => [self::ACTOR_READ_ITEM]], + denormalizationContext: ['groups' => [self::ACTOR_WRITE]], )] class Actor { - private const GROUP_READ = 'actor:read'; - private const GROUP_WRITE = 'actor:write'; + public const ACTOR_READ_ITEM_COLLECTION = 'actor:read_collection'; + public const ACTOR_READ_ITEM = 'actor:read_item'; + private const ACTOR_WRITE = 'actor:write'; #[ORM\Id] #[ORM\Column(type: 'uuid', unique: true)] #[ORM\GeneratedValue(strategy: 'CUSTOM')] #[ORM\CustomIdGenerator('doctrine.uuid_generator')] - #[Groups([self::GROUP_READ])] + #[Groups([self::ACTOR_READ_ITEM_COLLECTION, self::ACTOR_READ_ITEM, Project::PROJECT_READ_ALL])] private ?Uuid $id = null; #[ORM\Column(length: 255)] - #[Groups([self::GROUP_READ, self::GROUP_WRITE, Project::PROJECT_READ_ALL])] + #[Groups([self::ACTOR_READ_ITEM_COLLECTION, self::ACTOR_READ_ITEM, self::ACTOR_WRITE, Project::PROJECT_READ_ALL])] private ?string $name = null; - #[ORM\Column(length: 10)] - #[Groups([self::GROUP_READ, self::GROUP_WRITE])] + #[ORM\Column(length: 255)] + #[Groups([self::ACTOR_READ_ITEM_COLLECTION, self::ACTOR_READ_ITEM, self::ACTOR_WRITE])] private ?string $acronym = null; #[ORM\ManyToOne(inversedBy: 'actorsCreated')] #[ORM\JoinColumn(nullable: false)] - #[Groups([self::GROUP_READ])] + #[Groups([self::ACTOR_READ_ITEM])] private ?User $createdBy = null; #[ORM\Column] - #[Groups([self::GROUP_READ])] - private ?bool $isValidated = null; + #[Groups([self::ACTOR_READ_ITEM])] + private ?bool $isValidated = false; + + #[ORM\Column(enumType: ActorCategory::class)] + #[Groups([self::ACTOR_READ_ITEM_COLLECTION, self::ACTOR_READ_ITEM, self::ACTOR_WRITE])] + private ?ActorCategory $category = null; + + /** + * @var Collection + */ + #[ORM\ManyToMany(targetEntity: ActorExpertise::class, inversedBy: 'actors')] + #[Groups([self::ACTOR_READ_ITEM_COLLECTION, self::ACTOR_READ_ITEM, self::ACTOR_WRITE])] + private Collection $expertises; + + /** + * @var Collection + */ + #[ORM\ManyToMany(targetEntity: Thematic::class, inversedBy: 'actors')] + #[Groups([self::ACTOR_READ_ITEM, self::ACTOR_WRITE])] + private Collection $thematics; + + #[ORM\Column(type: Types::DATETIME_MUTABLE)] + #[Groups([self::ACTOR_READ_ITEM, self::ACTOR_WRITE])] + private ?\DateTimeInterface $creationDate = null; + + #[ORM\Column(type: Types::DATETIME_MUTABLE)] + #[Groups([self::ACTOR_READ_ITEM, self::ACTOR_WRITE])] + private ?\DateTimeInterface $lastUpdate = null; + + #[ORM\Column(type: Types::TEXT)] + #[Groups([self::ACTOR_READ_ITEM, self::ACTOR_WRITE])] + private ?string $description = null; + + /** + * @var Collection + */ + #[ORM\ManyToMany(targetEntity: AdministrativeScope::class, inversedBy: 'actors')] + #[Groups([self::ACTOR_READ_ITEM, self::ACTOR_WRITE])] + private Collection $administrativeScopes; + + #[ORM\Column(length: 255, nullable: true)] + #[Groups([self::ACTOR_READ_ITEM, self::ACTOR_WRITE])] + private ?string $officeName = null; + + #[ORM\Column(length: 255, nullable: true)] + #[Groups([self::ACTOR_READ_ITEM, self::ACTOR_WRITE])] + private ?string $officeAddress = null; + + #[ORM\Column(length: 255, nullable: true)] + #[Groups([self::ACTOR_READ_ITEM, self::ACTOR_WRITE])] + private ?string $contactName = null; + + #[ORM\Column(length: 255, nullable: true)] + #[Groups([self::ACTOR_READ_ITEM, self::ACTOR_WRITE])] + private ?string $contactPosition = null; + + #[ORM\Column(length: 255, nullable: true)] + #[Groups([self::ACTOR_READ_ITEM, self::ACTOR_WRITE])] + private ?string $website = null; + + #[ORM\Column(length: 255, nullable: true)] + #[Groups([self::ACTOR_READ_ITEM, self::ACTOR_WRITE])] + private ?string $phone = null; + + #[ORM\Column(length: 255, nullable: true)] + #[Groups([self::ACTOR_READ_ITEM, self::ACTOR_WRITE])] + #[Assert\Email] + private ?string $email = null; /** * @var Collection */ #[ORM\OneToMany(targetEntity: Project::class, mappedBy: 'actor')] + #[Groups([self::ACTOR_READ_ITEM, self::ACTOR_WRITE])] private Collection $projects; + #[ORM\Column(length: 255, nullable: true)] + #[Groups([self::ACTOR_READ_ITEM_COLLECTION,self::ACTOR_READ_ITEM, self::ACTOR_WRITE])] + private ?string $logo = null; + public function __construct() { + $this->expertises = new ArrayCollection(); + $this->thematics = new ArrayCollection(); + $this->administrativeScopes = new ArrayCollection(); $this->projects = new ArrayCollection(); } @@ -130,8 +216,212 @@ public function setValidated(bool $isValidated): static return $this; } + public function getCategory(): ?ActorCategory + { + return $this->category; + } + + public function setCategory(ActorCategory $category): static + { + $this->category = $category; + + return $this; + } + + /** + * @return Collection + */ + public function getExpertises(): Collection + { + return $this->expertises; + } + + public function addExpertise(ActorExpertise $expertise): static + { + if (!$this->expertises->contains($expertise)) { + $this->expertises->add($expertise); + } + + return $this; + } + + public function removeExpertise(ActorExpertise $expertise): static + { + $this->expertises->removeElement($expertise); + + return $this; + } + /** - * @return Collection + * @return Collection + */ + public function getThematics(): Collection + { + return $this->thematics; + } + + public function addThematic(Thematic $thematic): static + { + if (!$this->thematics->contains($thematic)) { + $this->thematics->add($thematic); + } + + return $this; + } + + public function removeThematic(Thematic $thematic): static + { + $this->thematics->removeElement($thematic); + + return $this; + } + + public function getCreationDate(): ?\DateTimeInterface + { + return $this->creationDate; + } + + public function setCreationDate(\DateTimeInterface $creationDate): static + { + $this->creationDate = $creationDate; + + return $this; + } + + public function getLastUpdate(): ?\DateTimeInterface + { + return $this->lastUpdate; + } + + public function setLastUpdate(\DateTimeInterface $lastUpdate): static + { + $this->lastUpdate = $lastUpdate; + + return $this; + } + + public function getDescription(): ?string + { + return $this->description; + } + + public function setDescription(string $description): static + { + $this->description = $description; + + return $this; + } + + /** + * @return Collection + */ + public function getAdministrativeScopes(): Collection + { + return $this->administrativeScopes; + } + + public function addAdministrativeScope(AdministrativeScope $administrativeScope): static + { + if (!$this->administrativeScopes->contains($administrativeScope)) { + $this->administrativeScopes->add($administrativeScope); + } + + return $this; + } + + public function removeAdministrativeScope(AdministrativeScope $administrativeScope): static + { + $this->administrativeScopes->removeElement($administrativeScope); + + return $this; + } + + public function getOfficeName(): ?string + { + return $this->officeName; + } + + public function setOfficeName(?string $officeName): static + { + $this->officeName = $officeName; + + return $this; + } + + public function getofficeAddress(): ?string + { + return $this->officeAddress; + } + + public function setofficeAddress(?string $officeAddress): static + { + $this->officeAddress = $officeAddress; + + return $this; + } + + public function getContactName(): ?string + { + return $this->contactName; + } + + public function setContactName(?string $contactName): static + { + $this->contactName = $contactName; + + return $this; + } + + public function getContactPosition(): ?string + { + return $this->contactPosition; + } + + public function setContactPosition(?string $contactPosition): static + { + $this->contactPosition = $contactPosition; + + return $this; + } + + public function getWebsite(): ?string + { + return $this->website; + } + + public function setWebsite(?string $website): static + { + $this->website = $website; + + return $this; + } + + public function getPhone(): ?string + { + return $this->phone; + } + + public function setPhone(?string $phone): static + { + $this->phone = $phone; + + return $this; + } + + public function getEmail(): ?string + { + return $this->email; + } + + public function setEmail(?string $email): static + { + $this->email = $email; + + return $this; + } + + /** + * @return Collection */ public function getProjects(): Collection { @@ -147,7 +437,7 @@ public function addProject(Project $project): static return $this; } - + public function removeProject(Project $project): static { if ($this->projects->removeElement($project)) { @@ -159,4 +449,17 @@ public function removeProject(Project $project): static return $this; } + + public function getLogo(): ?string + { + return $this->logo; + } + + public function setLogo(?string $logo): static + { + $this->logo = $logo; + + return $this; + } } + \ No newline at end of file diff --git a/symfony/src/Entity/ActorExpertise.php b/symfony/src/Entity/ActorExpertise.php new file mode 100644 index 00000000..d774b0bf --- /dev/null +++ b/symfony/src/Entity/ActorExpertise.php @@ -0,0 +1,81 @@ + + */ + #[ORM\ManyToMany(targetEntity: Actor::class, mappedBy: 'expertises')] + private Collection $actors; + + public function __construct() + { + $this->actors = new ArrayCollection(); + } + + public function getId(): ?int + { + return $this->id; + } + + public function getName(): ?string + { + return $this->name; + } + + public function setName(string $name): static + { + $this->name = $name; + + return $this; + } + + /** + * @return Collection + */ + public function getActors(): Collection + { + return $this->actors; + } + + public function addActor(Actor $actor): static + { + if (!$this->actors->contains($actor)) { + $this->actors->add($actor); + $actor->addExpertise($this); + } + + return $this; + } + + public function removeActor(Actor $actor): static + { + if ($this->actors->removeElement($actor)) { + $actor->removeExpertise($this); + } + + return $this; + } +} \ No newline at end of file diff --git a/symfony/src/Entity/AdministrativeScope.php b/symfony/src/Entity/AdministrativeScope.php new file mode 100644 index 00000000..161cacf7 --- /dev/null +++ b/symfony/src/Entity/AdministrativeScope.php @@ -0,0 +1,81 @@ + + */ + #[ORM\ManyToMany(targetEntity: Actor::class, mappedBy: 'administrativeScopes')] + private Collection $actors; + + public function __construct() + { + $this->actors = new ArrayCollection(); + } + + public function getId(): ?int + { + return $this->id; + } + + public function getName(): ?string + { + return $this->name; + } + + public function setName(string $name): static + { + $this->name = $name; + + return $this; + } + + /** + * @return Collection + */ + public function getActors(): Collection + { + return $this->actors; + } + + public function addActor(Actor $actor): static + { + if (!$this->actors->contains($actor)) { + $this->actors->add($actor); + $actor->addAdministrativeScope($this); + } + + return $this; + } + + public function removeActor(Actor $actor): static + { + if ($this->actors->removeElement($actor)) { + $actor->removeAdministrativeScope($this); + } + + return $this; + } +} \ No newline at end of file diff --git a/symfony/src/Entity/Project.php b/symfony/src/Entity/Project.php index ce87d7e6..7c836f65 100644 --- a/symfony/src/Entity/Project.php +++ b/symfony/src/Entity/Project.php @@ -5,7 +5,7 @@ use ApiPlatform\Metadata\ApiResource; use ApiPlatform\Metadata\GetCollection; use App\Entity\Trait\TimestampableEntity; -use App\Enum\AdminLevel; +use App\Enum\AdministrativeScope; use App\Enum\Status; use App\Repository\ProjectRepository; use Doctrine\Common\Collections\ArrayCollection; @@ -53,6 +53,7 @@ class Project private ?string $coords = null; #[ORM\Column(enumType: Status::class)] + #[Groups([self::PROJECT_READ_ALL])] private ?Status $status = null; #[ORM\Column(type: Types::TEXT, nullable: true)] @@ -64,8 +65,9 @@ class Project #[ORM\Column(type: Types::JSON, nullable: true)] private ?array $partners = null; - #[ORM\Column(enumType: AdminLevel::class)] - private ?AdminLevel $interventionZone = null; + #[ORM\Column(enumType: AdministrativeScope::class)] + #[Groups([self::PROJECT_READ_ALL])] + private ?AdministrativeScope $interventionZone = null; /** * @var Collection @@ -101,6 +103,7 @@ class Project */ #[ORM\JoinTable(name: 'financed_projects_actors')] #[ORM\ManyToMany(targetEntity: Actor::class)] + #[Groups([self::PROJECT_READ_ALL])] private Collection $financialActors; /** @@ -109,6 +112,7 @@ class Project #[ORM\JoinTable(name: 'contracted_projects_actors')] #[ORM\ManyToMany(targetEntity: Actor::class)] + #[Groups([self::PROJECT_READ_ALL])] private Collection $contractingActors; #[ORM\ManyToOne(inversedBy: 'projects')] @@ -217,12 +221,12 @@ public function setPartners(?array $partners): static return $this; } - public function getInterventionZone(): ?AdminLevel + public function getInterventionZone(): ?AdministrativeScope { return $this->interventionZone; } - public function setInterventionZone(AdminLevel $interventionZone): static + public function setInterventionZone(AdministrativeScope $interventionZone): static { $this->interventionZone = $interventionZone; diff --git a/symfony/src/Entity/Thematic.php b/symfony/src/Entity/Thematic.php index 41c74a45..88acae79 100644 --- a/symfony/src/Entity/Thematic.php +++ b/symfony/src/Entity/Thematic.php @@ -3,6 +3,7 @@ namespace App\Entity; use ApiPlatform\Metadata\ApiResource; +use ApiPlatform\Metadata\GetCollection; use App\Repository\ThematicRepository; use Doctrine\Common\Collections\ArrayCollection; use Doctrine\Common\Collections\Collection; @@ -10,16 +11,25 @@ use Symfony\Component\Serializer\Attribute\Groups; #[ORM\Entity(repositoryClass: ThematicRepository::class)] -#[ApiResource()] +#[ApiResource( + paginationEnabled: false, + operations: [ + new GetCollection( + normalizationContext: ['groups' => [self::THEMATIC_READ]] + ) + ])] class Thematic { + public const THEMATIC_READ = 'thematic:read'; + #[ORM\Id] #[ORM\GeneratedValue] #[ORM\Column] + #[Groups([self::THEMATIC_READ, Project::PROJECT_READ_ALL])] private ?int $id = null; #[ORM\Column(length: 255)] - #[Groups([Project::PROJECT_READ_ALL])] + #[Groups([self::THEMATIC_READ, Project::PROJECT_READ_ALL])] private ?string $name = null; /** diff --git a/symfony/src/Enum/ActorCategory.php b/symfony/src/Enum/ActorCategory.php new file mode 100644 index 00000000..24afbd5b --- /dev/null +++ b/symfony/src/Enum/ActorCategory.php @@ -0,0 +1,16 @@ + + */ +class ActorExpertiseRepository extends ServiceEntityRepository +{ + public function __construct(ManagerRegistry $registry) + { + parent::__construct($registry, ActorExpertise::class); + } + + // /** + // * @return ActorExpertise[] Returns an array of ActorExpertise objects + // */ + // public function findByExampleField($value): array + // { + // return $this->createQueryBuilder('a') + // ->andWhere('a.exampleField = :val') + // ->setParameter('val', $value) + // ->orderBy('a.id', 'ASC') + // ->setMaxResults(10) + // ->getQuery() + // ->getResult() + // ; + // } + + // public function findOneBySomeField($value): ?ActorExpertise + // { + // return $this->createQueryBuilder('a') + // ->andWhere('a.exampleField = :val') + // ->setParameter('val', $value) + // ->getQuery() + // ->getOneOrNullResult() + // ; + // } +} \ No newline at end of file diff --git a/symfony/src/Repository/AdministrativeScopeRepository.php b/symfony/src/Repository/AdministrativeScopeRepository.php new file mode 100644 index 00000000..2f7bb4b9 --- /dev/null +++ b/symfony/src/Repository/AdministrativeScopeRepository.php @@ -0,0 +1,43 @@ + + */ +class AdministrativeScopeRepository extends ServiceEntityRepository +{ + public function __construct(ManagerRegistry $registry) + { + parent::__construct($registry, AdministrativeScope::class); + } + + // /** + // * @return AdministrativeScope[] Returns an array of AdministrativeScope objects + // */ + // public function findByExampleField($value): array + // { + // return $this->createQueryBuilder('a') + // ->andWhere('a.exampleField = :val') + // ->setParameter('val', $value) + // ->orderBy('a.id', 'ASC') + // ->setMaxResults(10) + // ->getQuery() + // ->getResult() + // ; + // } + + // public function findOneBySomeField($value): ?AdministrativeScope + // { + // return $this->createQueryBuilder('a') + // ->andWhere('a.exampleField = :val') + // ->setParameter('val', $value) + // ->getQuery() + // ->getOneOrNullResult() + // ; + // } +} \ No newline at end of file diff --git a/vue/src/assets/images/icons/map/mdi-filter.svg b/vue/src/assets/images/icons/map/mdi-filter.svg new file mode 100644 index 00000000..2d314b94 --- /dev/null +++ b/vue/src/assets/images/icons/map/mdi-filter.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/vue/src/assets/styles/global/app.scss b/vue/src/assets/styles/global/app.scss index 56fb3535..db9633b4 100644 --- a/vue/src/assets/styles/global/app.scss +++ b/vue/src/assets/styles/global/app.scss @@ -23,6 +23,15 @@ transition: all .15s ease-in; } +.text-action { + text-decoration: underline; + cursor: pointer; + + &:hover { + font-weight: 500; + } +} + a { color: #000; } diff --git a/vue/src/assets/styles/global/vuetifyOverrides.scss b/vue/src/assets/styles/global/vuetifyOverrides.scss index 0d267fcb..2737627b 100644 --- a/vue/src/assets/styles/global/vuetifyOverrides.scss +++ b/vue/src/assets/styles/global/vuetifyOverrides.scss @@ -9,4 +9,11 @@ } .v-select.fit .v-select__selection--comma { text-overflow: unset; +} + +.v-dialog { + button { + min-width: 0; + min-height: 2.75rem; + } } \ No newline at end of file diff --git a/vue/src/assets/translations/fr/common.json b/vue/src/assets/translations/fr/common.json index 13ac24df..2960f440 100644 --- a/vue/src/assets/translations/fr/common.json +++ b/vue/src/assets/translations/fr/common.json @@ -68,6 +68,10 @@ "search": "Rechercher..." }, "labels": { - "updatedAt": "Mis à jour le" + "updatedAt": "Mis à jour le", + "reset": "Réinitialiser" + }, + "placeholders": { + "all": "Tous" } } \ No newline at end of file diff --git a/vue/src/assets/translations/fr/projects.json b/vue/src/assets/translations/fr/projects.json index 5a2b27a0..2063bde0 100644 --- a/vue/src/assets/translations/fr/projects.json +++ b/vue/src/assets/translations/fr/projects.json @@ -1,6 +1,42 @@ { "projects": { "project": "projet", - "projects": "projets" + "projects": "projets", + "status": { + "ongoing": "En cours", + "finalized": "Finalisé" + }, + "scope": { + "national": "National", + "regional": "Régional", + "state": "Département", + "city": "Ville" + }, + "map": { + "filterProjects": "Filtrer les projets" + }, + "popup": { + "filters": { + "projectOwner": { + "label" : "Maitre d'ouvrage" + }, + "financial": { + "label" : "Financement" + }, + "beneficiaries": { + "label" : "Bénéficiaires" + }, + "interventionZones": { + "label" : "Zones d'intervention" + }, + "thematics": { + "label" : "Thématiques" + }, + "status": { + "label" : "Statut" + } + }, + "showTheProjects": "Afficher les {count} projets" + } } } \ No newline at end of file diff --git a/vue/src/components/generic-components/Dialog.vue b/vue/src/components/generic-components/Dialog.vue index e95efc75..fb8cc24f 100644 --- a/vue/src/components/generic-components/Dialog.vue +++ b/vue/src/components/generic-components/Dialog.vue @@ -72,11 +72,6 @@ const closeDialog = () => router.replace({ query: { dialog: undefined }}); align-items: center; justify-content: center; - button { - min-width: 0; - min-height: 2.75rem; - } - .Link--withoutUnderline { width: fit-content; } diff --git a/vue/src/components/generic-components/Map.vue b/vue/src/components/generic-components/Map.vue index a3b3e7a9..7a595d48 100644 --- a/vue/src/components/generic-components/Map.vue +++ b/vue/src/components/generic-components/Map.vue @@ -216,7 +216,6 @@ defineExpose({ } .maplibregl-popup-tip { - z-index: 9999999; display: none; pointer-events: none; } diff --git a/vue/src/components/generic-components/Modal.vue b/vue/src/components/generic-components/Modal.vue new file mode 100644 index 00000000..89c9b139 --- /dev/null +++ b/vue/src/components/generic-components/Modal.vue @@ -0,0 +1,96 @@ + + + + + \ No newline at end of file diff --git a/vue/src/components/views-components/actors/ActorCard.vue b/vue/src/components/views-components/actors/ActorCard.vue index 06c9561a..45dce57e 100644 --- a/vue/src/components/views-components/actors/ActorCard.vue +++ b/vue/src/components/views-components/actors/ActorCard.vue @@ -14,9 +14,8 @@ - diff --git a/vue/src/components/views-components/projects/ProjectFilterModal.vue b/vue/src/components/views-components/projects/ProjectFilterModal.vue new file mode 100644 index 00000000..061baf01 --- /dev/null +++ b/vue/src/components/views-components/projects/ProjectFilterModal.vue @@ -0,0 +1,82 @@ + + \ No newline at end of file diff --git a/vue/src/components/views-components/projects/ProjectMap.vue b/vue/src/components/views-components/projects/ProjectMap.vue index 42e38f2a..d8b1ab74 100644 --- a/vue/src/components/views-components/projects/ProjectMap.vue +++ b/vue/src/components/views-components/projects/ProjectMap.vue @@ -1,6 +1,10 @@