Compare commits
	
		
			346 Commits
		
	
	
		
			7a9955b781
			...
			front_foun
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|  | 47be7d340b | ||
|  | 232d10b164 | ||
| bc7ce888ad | |||
| ed67a3734a | |||
| 95eb154556 | |||
| 19fef63b0e | |||
| 1fd95265ea | |||
|  | 3ef2d8a198 | ||
|  | 6b49bbbe57 | ||
|  | 4c15cab607 | ||
|  | abfe92bc87 | ||
|  | 85b4fe6a4c | ||
| f2448a029f | |||
|  | cef4daef15 | ||
|  | f5aba70017 | ||
|  | 27adc81ddc | ||
|  | 48f14e8a04 | ||
| d4533ea725 | |||
|  | 7fc06035c7 | ||
|  | 1b559f29b7 | ||
| 63327bc312 | |||
|  | f0cef41e2b | ||
| 7f16cdc86f | |||
| 72d6f49995 | |||
| 695ec5d9b8 | |||
| 0abafb4f7f | |||
| 3cd63e78e9 | |||
| 255af7ee7f | |||
| 3b308cfa6d | |||
| d039105f0a | |||
| 0a15dbbf2d | |||
| d1fce63ac5 | |||
| d9aaa225aa | |||
| d31bf259dd | |||
| 43b40c9432 | |||
|  | e84f69c21a | ||
| cc1fc9b45b | |||
|  | c76e83f2bf | ||
| 0d0ec255a5 | |||
| e0c43a5c95 | |||
|  | 1f0f9196c4 | ||
| 40e577ef07 | |||
| 60302c44d2 | |||
| a6e4f80a01 | |||
| 02bff19de0 | |||
| ae36549de9 | |||
| b1a4c874ec | |||
| 829baac85e | |||
| 2e9d841709 | |||
| 25235f418a | |||
| 13845394e3 | |||
|  | 73aac1875a | ||
|  | c3ad092512 | ||
|  | f4589c6306 | ||
|  | 6004bce4e8 | ||
|  | 0730275e75 | ||
| 4356a01e4a | |||
| 592331236e | |||
| 49e52e1826 | |||
| efcea7f680 | |||
| 8154814805 | |||
|  | 7d41da97de | ||
|  | 35f314498f | ||
|  | f46c3756f0 | ||
| 92696c3e16 | |||
| 5130c00796 | |||
| 5183a088e7 | |||
| 8ec569e6ff | |||
| b503cae235 | |||
| fcf4e1c01d | |||
|  | 4f90da69f3 | ||
|  | 0fe64fd844 | ||
| eb302268ba | |||
| 3f18304028 | |||
| bbb4debcd8 | |||
| 6f7fc70c4c | |||
|  | 4044a95dd1 | ||
| aee8e8797c | |||
| 3d57ecb01a | |||
| 1f91ab72d8 | |||
| a4e13b0f0a | |||
| b116771375 | |||
| cbef042e97 | |||
| 63f6f16d83 | |||
| 864bbbb9fd | |||
| e890a03a48 | |||
| 351727f3d5 | |||
| b5637e4552 | |||
|  | 8024b8070b | ||
|  | 008e003207 | ||
| 820c979c94 | |||
| 2ebea35e5d | |||
|  | c3dded1e05 | ||
|  | 8b48a55bf0 | ||
|  | 32de0d6ca8 | ||
| 7534d0d9c6 | |||
| a0cbd5e324 | |||
|  | 09eeaacfa6 | ||
|  | de09ab2891 | ||
| 6ae50f9cf7 | |||
| 0199e9d0dc | |||
| 05a56dc022 | |||
| 9f4596d0ba | |||
|  | be73815861 | ||
| 6d84b3ff93 | |||
|  | 549028b1d0 | ||
|  | 3de1ec71ff | ||
|  | a895b0afda | ||
|  | bb55209946 | ||
|  | a8e22de4a3 | ||
| f9ee12ab6f | |||
| 4d3aae1249 | |||
|  | fa96bd2b0d | ||
| 3673aa379c | |||
| b672b2e9f9 | |||
| 193876e51c | |||
| b8c7c6f587 | |||
|  | bee47473d5 | ||
|  | e7739af80b | ||
| 32557f8f87 | |||
| 8ee06b93a6 | |||
| fcc20d1f42 | |||
| 28b0e69da1 | |||
|  | 6861d07dfc | ||
| 6226c9f632 | |||
| 7fce831c75 | |||
| 8403bc0592 | |||
| 5edcf9ffc8 | |||
| 5615b0fb11 | |||
| 8a13993d8a | |||
| 561f6d16b3 | |||
|  | 7199e7ebbf | ||
|  | 9762ca27fb | ||
| ca8c5d9209 | |||
| 4b6d501adc | |||
|  | 08706af6c2 | ||
|  | 01f062211a | ||
| bca88a7b20 | |||
|  | c60fb8945b | ||
|  | e20556ed0f | ||
|  | d9c5f7bacf | ||
|  | fdae3e4c04 | ||
| 36db3c2968 | |||
| a0eeb6715e | |||
|  | 6d875d9df1 | ||
|  | 7c8f3ba36a | ||
| 832539f43b | |||
| dfea20b9c4 | |||
|  | 8b863ee4b1 | ||
|  | f96872fb6b | ||
|  | 0140672812 | ||
|  | 7df2c768c8 | ||
| 6b3cb2610d | |||
|  | 6029457735 | ||
| ba99b3c2b0 | |||
| 31d82f6271 | |||
| 37e631a096 | |||
| 6306a00eca | |||
| 55112c8508 | |||
| 676f1204cb | |||
|  | c4ba7646d5 | ||
|  | 4e1908d528 | ||
|  | 03bbc77e8a | ||
| ad1fd45bed | |||
| f0c4a3a10d | |||
|  | 70658e4fb9 | ||
|  | 2b31753265 | ||
| f8991e90ab | |||
|  | 66be0baca6 | ||
|  | 60290956ec | ||
|  | b9647ce36e | ||
| 8c4b9ceb9d | |||
|  | 84d8d4523b | ||
| 647812576e | |||
|  | 2dfee66958 | ||
| 7e1271cfe2 | |||
| 801ecb3817 | |||
|  | cc89d4c79f | ||
| adf9a93e2e | |||
|  | 37d8bcc719 | ||
|  | 385c5cd8d0 | ||
|  | b672dd200c | ||
|  | 9e1f568ea4 | ||
|  | aaa6e46d0c | ||
|  | 2b1666c949 | ||
|  | 0c724cae7f | ||
|  | 6de45801d2 | ||
| 03897e1139 | |||
|  | 9b9cfbdb2e | ||
| 00a733c03b | |||
|  | 5b6b647697 | ||
| 3dc8131c33 | |||
|  | 7c271d8c47 | ||
|  | 81ce4fdb4c | ||
|  | ebd76a30ee | ||
| ead11215ba | |||
| 259d56271c | |||
|  | b9f3bbbe15 | ||
| 14a2a59786 | |||
| 0ae6e7dfda | |||
| 15ccb5630a | |||
| 4ec292cca7 | |||
| 14a953536a | |||
| 288f983816 | |||
| dd6032f3ef | |||
|  | 7e2f5bc506 | ||
|  | 4ef92efd0e | ||
| e769dd6757 | |||
|  | 550a51523f | ||
| 323cb05388 | |||
|  | 6ff6ce5052 | ||
|  | 7e0851bfef | ||
|  | 98b6d167e8 | ||
| 79baddb8f6 | |||
| 60ec920cff | |||
| 900a4c5bdc | |||
| d0b615c59d | |||
|  | 0f8c83c2e2 | ||
|  | fad52644d2 | ||
|  | 5f51a1008b | ||
| eccf116f49 | |||
| 8491c9b3cf | |||
|  | 137bc84c21 | ||
|  | 3c61fdca93 | ||
|  | 5ee3755548 | ||
| 279c171ba2 | |||
| 9ba8e3e84e | |||
|  | 52511dd4c4 | ||
| 6de38a9725 | |||
|  | 84b70f8f38 | ||
|  | 834d68949c | ||
|  | fea8687664 | ||
|  | c94d3654ce | ||
|  | d5c89bf8f4 | ||
|  | 78c72bdd72 | ||
|  | 307c7e700b | ||
|  | 8d486dce89 | ||
|  | 653f923693 | ||
|  | 64da3c9ab0 | ||
|  | 419ceec1bc | ||
|  | e011a5534e | ||
|  | ef964c4d35 | ||
|  | 5608b12f84 | ||
|  | 467babab79 | ||
|  | a2e2395cc2 | ||
|  | e3393c8834 | ||
|  | 5f8fe4a374 | ||
|  | c5e7736a16 | ||
|  | 04589392cb | ||
|  | 1106cf8478 | ||
|  | 215d80ad70 | ||
|  | dded62c25a | ||
|  | 3de7ebe2b1 | ||
|  | 8153496a0f | ||
|  | 861e7495a7 | ||
|  | d78e43f7e0 | ||
|  | 3ca97cf378 | ||
|  | e6a8d98d63 | ||
|  | 8894fea6d4 | ||
|  | 236bb0d167 | ||
|  | d4dcc95d9b | ||
|  | dc843299eb | ||
|  | f3eaf8fe34 | ||
|  | 628c61fb8b | ||
|  | 4880f3829c | ||
|  | 80b2d087e4 | ||
|  | b5c03798fc | ||
|  | 1d970ce5f5 | ||
|  | f9de5ed6bf | ||
|  | e75a5c9d2c | ||
|  | 5c3b2b138d | ||
|  | 8d4dc7916d | ||
|  | 1a6db7c953 | ||
|  | 3890aed158 | ||
|  | dd5ca2cbd7 | ||
|  | 024deeba41 | ||
|  | 1cebebf1a5 | ||
|  | d8bc7cc9b6 | ||
| 067eeb9494 | |||
|  | e66fa33577 | ||
|  | f48b570494 | ||
|  | 0733f8d5af | ||
|  | 8071c01c5d | ||
| b355463dd9 | |||
|  | 27e70ee109 | ||
|  | 153501c8d4 | ||
|  | 40afde89b7 | ||
| 4ee3d9bc44 | |||
|  | 4698aa549f | ||
| d75d45e204 | |||
| 79e949bdd4 | |||
|  | 9f3754776f | ||
|  | 04a73073c1 | ||
|  | 11ab5e1dc4 | ||
|  | 820757c836 | ||
|  | 730aa5f450 | ||
|  | dda3e5fcfd | ||
|  | 5e8e875a37 | ||
|  | 86e7dc7c75 | ||
|  | 6235fe7e68 | ||
|  | 3cb12dab4f | ||
| 651fb2b1a1 | |||
|  | aa5988ce75 | ||
|  | 9ae18e1e4b | ||
|  | 0a9d83655f | ||
| ef8c8e896d | |||
|  | fc73293122 | ||
|  | e26f8da662 | ||
|  | b4c05f8c59 | ||
|  | ca282378ec | ||
|  | 746fa97cf3 | ||
|  | 8b24456b48 | ||
|  | 6befd10735 | ||
|  | db094a8d86 | ||
|  | c739b4d26d | ||
|  | dacb0dd179 | ||
|  | b00c28a02a | ||
|  | 208cbbfa1d | ||
|  | d77f38b405 | ||
|  | 525f98a054 | ||
|  | 43aadac503 | ||
|  | 07f66f65ed | ||
|  | 6e5651c527 | ||
|  | 1ed976b039 | ||
|  | 013b97cec0 | ||
|  | e7cb8cf469 | ||
|  | 184642a750 | ||
|  | a8ae5f14d4 | ||
|  | e6565275c8 | ||
|   | f629fb4a4e | ||
| 22ebb0e1f4 | |||
| 09e4b3262f | |||
|  | 249d00177c | ||
| 6a3d4239ab | |||
| 9d71c93b5b | |||
| b1df7421dc | |||
| 7a03146bf8 | |||
|  | 5145b833ae | ||
| f0a371dc52 | |||
|  | ac19d33bdb | ||
|  | 3d4d5b90d1 | ||
|  | 4080cee818 | ||
|  | f4d73654d1 | ||
| 4fda5513a9 | |||
| 32407b0e8f | |||
| b30e1196f4 | 
| @@ -12,8 +12,7 @@ jobs: | |||||||
|         with: |         with: | ||||||
|           distribution: 'temurin' # See 'Supported distributions' for available options |           distribution: 'temurin' # See 'Supported distributions' for available options | ||||||
|           java-version: '21' |           java-version: '21' | ||||||
|  |  | ||||||
|       - uses: axel-op/googlejavaformat-action@v3 |       - uses: axel-op/googlejavaformat-action@v3 | ||||||
|         with: |         with: | ||||||
|           args: "--replace --skip-sorting-imports --aosp" |           args: "--set-exit-if-changed --skip-sorting-imports --skip-reflowing-long-strings --aosp -n" | ||||||
|       - name: Print diffs |  | ||||||
|         run: git --no-pager diff --exit-code |  | ||||||
|   | |||||||
							
								
								
									
										32
									
								
								.gitea/workflows/build-back.yaml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								.gitea/workflows/build-back.yaml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,32 @@ | |||||||
|  | name: Build | ||||||
|  |  | ||||||
|  | on: | ||||||
|  |   push: | ||||||
|  |  | ||||||
|  | jobs: | ||||||
|  |   build: | ||||||
|  |     runs-on: ubuntu-latest | ||||||
|  |     steps: | ||||||
|  |     - name: Checkout sources | ||||||
|  |       uses: actions/checkout@v4 | ||||||
|  |  | ||||||
|  |     - name: Load .env file | ||||||
|  |       uses: xom9ikk/dotenv@v2.3.0 | ||||||
|  |       with: | ||||||
|  |         path: ./config/ | ||||||
|  |         mode: dev | ||||||
|  |         load-mode: strict | ||||||
|  |  | ||||||
|  |     - name: Setup Java | ||||||
|  |       uses: actions/setup-java@v4 | ||||||
|  |       with: | ||||||
|  |         distribution: 'temurin' | ||||||
|  |         java-version: 21 | ||||||
|  |      | ||||||
|  |     - name: Setup Gradle | ||||||
|  |       uses: gradle/actions/setup-gradle@v4 | ||||||
|  |       with:  | ||||||
|  |         cache-disabled: true # Once the code has been pushed once in main, this should be reenabled.  | ||||||
|  |     - name: init gradle | ||||||
|  |       working-directory: ./MyINPulse-back/ | ||||||
|  |       run: ./gradlew build # todo: run test, currently fail because no database is present  | ||||||
							
								
								
									
										5
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										5
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @@ -1,5 +1,8 @@ | |||||||
| .env | .env | ||||||
| .idea | .idea | ||||||
| keycloak/CAS/target | keycloak/CAS/target | ||||||
|  | keycloak/.installed | ||||||
| docker-compose.yaml | docker-compose.yaml | ||||||
| postgres/data | node_modules | ||||||
|  | .vscode | ||||||
|  | postgres/data | ||||||
|   | |||||||
							
								
								
									
										58
									
								
								Makefile
									
									
									
									
									
								
							
							
						
						
									
										58
									
								
								Makefile
									
									
									
									
									
								
							| @@ -1,13 +1,16 @@ | |||||||
| help: | help: | ||||||
| 	@echo "make [clean dev-front prod dev-back]" | 	@echo "make [clean dev-front prod dev-back dev]" | ||||||
|  |  | ||||||
| clean:  | clean:  | ||||||
|  | 	@cp config/frontdev.env front/MyINPulse-front/.env | ||||||
|  | 	@cp config/frontdev.env .env | ||||||
|  | 	@cp config/frontdev.env MyINPulse-back/.env | ||||||
| 	@cp config/prod.docker-compose.yaml docker-compose.yaml | 	@cp config/prod.docker-compose.yaml docker-compose.yaml | ||||||
| 	@docker compose down | 	@docker compose down | ||||||
| 	@rm -f docker-compose.yaml | 	@rm -f docker-compose.yaml | ||||||
| 	@rm -f .env | 	@rm -f .env | ||||||
| 	@rm -f front/MyINPulse-front/.env | 	@rm -f front/MyINPulse-front/.env | ||||||
|  | 	@rm -f MyINPulse-back/.env | ||||||
|  |  | ||||||
| # Install npm packages | # Install npm packages | ||||||
| front/MyINPulse-front/.installed: | front/MyINPulse-front/.installed: | ||||||
| @@ -16,26 +19,55 @@ front/MyINPulse-front/.installed: | |||||||
|  |  | ||||||
| vite: ./front/MyINPulse-front/.installed | vite: ./front/MyINPulse-front/.installed | ||||||
|  |  | ||||||
|  | keycloak: ./keycloak/.installed | ||||||
|  |  | ||||||
| dev-front: clean vite | keycloak/.installed: | ||||||
| 	@cp config/frontdev.front.env front/MyINPulse-front/.env | 	@echo "running one time install" | ||||||
| 	@cp config/frontdev.main.env .env | 	@cd keycloak/CAS && sudo sh build.sh | ||||||
|  | 	@touch ./keycloak/.installed | ||||||
|  |  | ||||||
|  | dev-front: clean vite keycloak | ||||||
|  | 	@cp config/frontdev.env front/MyINPulse-front/.env | ||||||
|  | 	@cp config/frontdev.env .env | ||||||
|  | 	@cp config/frontdev.env MyINPulse-back/.env | ||||||
| 	@cp config/frontdev.docker-compose.yaml docker-compose.yaml | 	@cp config/frontdev.docker-compose.yaml docker-compose.yaml | ||||||
| 	@docker compose up -d --build | 	@docker compose up -d --build | ||||||
| 	@cd ./front/MyINPulse-front/ && npm run dev | 	@cd ./front/MyINPulse-front/ && npm run dev | ||||||
|  |  | ||||||
| prod: clean | prod: clean keycloak | ||||||
| 	@cp config/prod.front.env front/MyINPulse-front/.env | 	@cp config/prod.env front/MyINPulse-front/.env | ||||||
| 	@cp config/prod.main.env .env | 	@cp config/prod.env .env | ||||||
|  | 	@cp config/prod.env .env | ||||||
| 	@cp config/prod.docker-compose.yaml docker-compose.yaml | 	@cp config/prod.docker-compose.yaml docker-compose.yaml | ||||||
| 	@docker compose up -d --build | 	@docker compose up -d --build | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
| dev-back: | dev-back: keycloak | ||||||
| 	@cp config/backdev.front.env front/MyINPulse-front/.env | 	@cp config/backdev.env front/MyINPulse-front/.env | ||||||
| 	@cp config/backdev.main.env .env | 	@cp config/backdev.env .env | ||||||
|  | 	@cp config/backdev.env MyINPulse-back/.env | ||||||
| 	@cp config/backdev.docker-compose.yaml docker-compose.yaml | 	@cp config/backdev.docker-compose.yaml docker-compose.yaml | ||||||
| 	@docker compose up -d --build | 	@docker compose up -d --build | ||||||
| 	@echo "cd MyINPulse-back" | 	@echo "cd MyINPulse-back" && echo 'export $$(cat .env | xargs)' | ||||||
| 	@echo "./gradlew bootRun --args='--server.port=8081'" | 	@echo "./gradlew bootRun --args='--server.port=8081'" | ||||||
|  | 	 | ||||||
|  | dev: clean vite keycloak | ||||||
|  | 	@cp config/dev.env front/MyINPulse-front/.env | ||||||
|  | 	@cp config/dev.env .env | ||||||
|  | 	@cp config/dev.env MyINPulse-back/.env | ||||||
|  | 	@cp config/dev.docker-compose.yaml docker-compose.yaml | ||||||
|  | 	@docker compose up -d --build | ||||||
|  | 	@echo "cd MyINPulse-back" && echo 'export $$(cat .env | xargs)' | ||||||
|  | 	@echo "./gradlew bootRun --args='--server.port=8081'" | ||||||
|  | 	@cd ./front/MyINPulse-front/ && npm run dev & | ||||||
|  |  | ||||||
|  | test-back: clean keycloak | ||||||
|  | 	@cp config/dev.env front/MyINPulse-front/.env | ||||||
|  | 	@cp config/dev.env .env | ||||||
|  | 	@cp config/dev.env MyINPulse-back/.env | ||||||
|  | 	@cp config/dev.docker-compose.yaml docker-compose.yaml | ||||||
|  | 	@docker compose up -d --build | ||||||
|  | 	@echo "cd MyINPulse-back" && echo 'export $$(cat .env | xargs)' | ||||||
|  | 	@cd ./MyINPulse-back/ && ./gradlew test && ./gradlew jacocoTestReport | ||||||
|  | 	@firefox ./MyINPulse-back/build/jacocoHtml/index.html | ||||||
|   | |||||||
| @@ -1,33 +1,61 @@ | |||||||
| plugins { | plugins { | ||||||
| 	id 'java' |     id 'java' | ||||||
| 	id 'org.springframework.boot' version '3.4.2' |     id 'org.springframework.boot' version '3.4.2' | ||||||
| 	id 'io.spring.dependency-management' version '1.1.7' |     id 'io.spring.dependency-management' version '1.1.7' | ||||||
|  |     id 'jacoco' | ||||||
| } | } | ||||||
|  |  | ||||||
| group = 'enseirb' | group = 'enseirb' | ||||||
| version = '0.0.1-SNAPSHOT' | version = '0.0.1-SNAPSHOT' | ||||||
|  |  | ||||||
| java { | java { | ||||||
| 	toolchain { |     toolchain { | ||||||
| 		languageVersion = JavaLanguageVersion.of(21) |         languageVersion = JavaLanguageVersion.of(21) | ||||||
| 	} |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| repositories { | repositories { | ||||||
| 	mavenCentral() |     mavenCentral() | ||||||
| } | } | ||||||
|  |  | ||||||
| dependencies { | dependencies { | ||||||
| 	implementation 'org.springframework.boot:spring-boot-starter-oauth2-resource-server' |     implementation 'org.springframework.boot:spring-boot-starter-oauth2-resource-server' | ||||||
| 	implementation 'org.springframework.boot:spring-boot-starter-web' |     implementation 'org.springframework.boot:spring-boot-starter-web' | ||||||
| 	implementation 'org.springframework.boot:spring-boot-starter-data-jpa' |     implementation 'org.springframework.boot:spring-boot-starter-data-jpa' | ||||||
| 	implementation('org.springframework.boot:spring-boot-starter-validation') |     implementation 'org.springframework.boot:spring-boot-starter-validation' | ||||||
| 	implementation('org.springframework.boot:spring-boot-starter-data-rest') |     implementation 'org.springframework.boot:spring-boot-starter-data-rest' | ||||||
| 	implementation 'org.postgresql:postgresql' |     implementation group: 'org.apache.logging.log4j', name: 'log4j-api', version: '2.+' | ||||||
| 	testImplementation 'org.springframework.boot:spring-boot-starter-test' |     implementation group: 'org.apache.logging.log4j', name: 'log4j-core', version: '2.+' | ||||||
| 	testRuntimeOnly 'org.junit.platform:junit-platform-launcher' |     implementation 'org.postgresql:postgresql' | ||||||
|  |     implementation group: 'com.itextpdf', name: 'itextpdf', version: '5.5.13.3' | ||||||
|  |  | ||||||
|  |     runtimeOnly 'com.h2database:h2' | ||||||
|  |  | ||||||
|  |     testImplementation 'org.springframework.boot:spring-boot-starter-test' | ||||||
|  |     testImplementation 'com.h2database:h2' | ||||||
|  |  | ||||||
|  |     testRuntimeOnly 'org.junit.platform:junit-platform-launcher' | ||||||
| } | } | ||||||
|  |  | ||||||
| tasks.named('test') { | tasks.named('test') { | ||||||
| 	useJUnitPlatform() |     useJUnitPlatform() | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | test { | ||||||
|  |     finalizedBy jacocoTestReport // report is always generated after tests run | ||||||
|  | } | ||||||
|  | jacocoTestReport { | ||||||
|  |     dependsOn test // tests are required to run before generating the report | ||||||
|  |     reports { | ||||||
|  |         xml.required = false | ||||||
|  |         csv.required = false | ||||||
|  |         html.outputLocation = layout.buildDirectory.dir('jacocoHtml') | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | jacoco { | ||||||
|  |     toolVersion = "0.8.12" | ||||||
|  |     reportsDirectory = layout.buildDirectory.dir('customJacocoReportDir') | ||||||
| } | } | ||||||
|   | |||||||
| @@ -1,43 +0,0 @@ | |||||||
| package enseirb.myinpulse.api; |  | ||||||
|  |  | ||||||
| import org.springframework.boot.autoconfigure.SpringBootApplication; |  | ||||||
| import org.springframework.security.core.context.SecurityContextHolder; |  | ||||||
| import org.springframework.web.bind.annotation.GetMapping; |  | ||||||
| import org.springframework.web.bind.annotation.RequestMethod; |  | ||||||
| import org.springframework.web.bind.annotation.RestController; |  | ||||||
| import org.springframework.web.bind.annotation.CrossOrigin; |  | ||||||
|  |  | ||||||
| import java.security.Principal; |  | ||||||
|  |  | ||||||
| @SpringBootApplication |  | ||||||
| @RestController |  | ||||||
| public class GetUserInfo { |  | ||||||
|     // TODO: understand how to get data |  | ||||||
|     @GetMapping("/getUserInfo") |  | ||||||
|     public Object user(Principal principal) { |  | ||||||
|         System.out.println("GetUserInfo + " + principal); |  | ||||||
|         System.out.println(SecurityContextHolder.getContext().getAuthentication()); |  | ||||||
|         return SecurityContextHolder.getContext().getAuthentication().getPrincipal(); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     @CrossOrigin(methods = {RequestMethod.GET, RequestMethod.OPTIONS}) |  | ||||||
|     @GetMapping("/random") |  | ||||||
|     public boolean rand() { |  | ||||||
|         System.err.println("HELLO"); |  | ||||||
|         return Math.random() > 0.5; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     @CrossOrigin(methods = {RequestMethod.GET, RequestMethod.OPTIONS}) |  | ||||||
|     @GetMapping("/random2") |  | ||||||
|     public boolean rand2() { |  | ||||||
|         System.err.println("HELLO2"); |  | ||||||
|         return Math.random() > 0.5; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     @CrossOrigin(methods = {RequestMethod.GET, RequestMethod.OPTIONS}) |  | ||||||
|     @GetMapping("/random3") |  | ||||||
|     public boolean rand3() { |  | ||||||
|         System.err.println("HELLO"); |  | ||||||
|         return Math.random() > 0.5; |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @@ -1,4 +1,10 @@ | |||||||
| package enseirb.myinpulse.security; | /* | ||||||
|  |  * Source: https://github.com/ChristianHuff-DEV/secure-spring-rest-api-using-keycloak/blob/main/src/main/java/io/betweendata/RestApi/security/oauth2/KeycloakJwtRolesConverter.java | ||||||
|  |  * edited by Pierre Tellier | ||||||
|  |  */ | ||||||
|  | package enseirb.myinpulse.config; | ||||||
|  | 
 | ||||||
|  | import static java.util.stream.Collectors.toSet; | ||||||
| 
 | 
 | ||||||
| import org.springframework.core.convert.converter.Converter; | import org.springframework.core.convert.converter.Converter; | ||||||
| import org.springframework.security.authentication.AbstractAuthenticationToken; | import org.springframework.security.authentication.AbstractAuthenticationToken; | ||||||
| @@ -14,8 +20,6 @@ import java.util.Map; | |||||||
| import java.util.stream.Collectors; | import java.util.stream.Collectors; | ||||||
| import java.util.stream.Stream; | import java.util.stream.Stream; | ||||||
| 
 | 
 | ||||||
| import static java.util.stream.Collectors.toSet; |  | ||||||
| 
 |  | ||||||
| public class KeycloakJwtRolesConverter implements Converter<Jwt, AbstractAuthenticationToken> { | public class KeycloakJwtRolesConverter implements Converter<Jwt, AbstractAuthenticationToken> { | ||||||
|     /** Prefix used for realm level roles. */ |     /** Prefix used for realm level roles. */ | ||||||
|     public static final String PREFIX_REALM_ROLE = "ROLE_REALM_"; |     public static final String PREFIX_REALM_ROLE = "ROLE_REALM_"; | ||||||
| @@ -38,7 +42,7 @@ public class KeycloakJwtRolesConverter implements Converter<Jwt, AbstractAuthent | |||||||
|                 source, |                 source, | ||||||
|                 Stream.concat( |                 Stream.concat( | ||||||
|                                 new JwtGrantedAuthoritiesConverter().convert(source).stream(), |                                 new JwtGrantedAuthoritiesConverter().convert(source).stream(), | ||||||
|                                 TEMPORARNAME(source).stream()) |                                 tokenRolesExtractor(source).stream()) | ||||||
|                         .collect(toSet())); |                         .collect(toSet())); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| @@ -46,7 +50,7 @@ public class KeycloakJwtRolesConverter implements Converter<Jwt, AbstractAuthent | |||||||
|      * Extracts the realm and resource level roles from a JWT token distinguishing between them |      * Extracts the realm and resource level roles from a JWT token distinguishing between them | ||||||
|      * using prefixes. |      * using prefixes. | ||||||
|      */ |      */ | ||||||
|     public Collection<GrantedAuthority> TEMPORARNAME(Jwt jwt) { |     public Collection<GrantedAuthority> tokenRolesExtractor(Jwt jwt) { | ||||||
|         // Collection that will hold the extracted roles |         // Collection that will hold the extracted roles | ||||||
|         Collection<GrantedAuthority> grantedAuthorities = new ArrayList<>(); |         Collection<GrantedAuthority> grantedAuthorities = new ArrayList<>(); | ||||||
| 
 | 
 | ||||||
| @@ -1,6 +1,8 @@ | |||||||
| package enseirb.myinpulse.config; | package enseirb.myinpulse.config; | ||||||
|  |  | ||||||
| import enseirb.myinpulse.security.KeycloakJwtRolesConverter; | import static org.springframework.security.authorization.AuthorityAuthorizationManager.hasRole; | ||||||
|  |  | ||||||
|  | import org.springframework.beans.factory.annotation.Value; | ||||||
| import org.springframework.context.annotation.Bean; | import org.springframework.context.annotation.Bean; | ||||||
| import org.springframework.context.annotation.Configuration; | import org.springframework.context.annotation.Configuration; | ||||||
| import org.springframework.security.config.annotation.web.builders.HttpSecurity; | import org.springframework.security.config.annotation.web.builders.HttpSecurity; | ||||||
| @@ -12,42 +14,60 @@ import org.springframework.web.cors.UrlBasedCorsConfigurationSource; | |||||||
| import java.util.Arrays; | import java.util.Arrays; | ||||||
| import java.util.List; | import java.util.List; | ||||||
|  |  | ||||||
| import static org.springframework.security.authorization.AuthorityAuthorizationManager.hasRole; |  | ||||||
|  |  | ||||||
| @Configuration | @Configuration | ||||||
| public class WebSecurityCustomConfiguration { | public class WebSecurityCustomConfiguration { | ||||||
|     // CORS configuration |     // CORS configuration | ||||||
|     // TODO: make sure to only accept our own domains |  | ||||||
|  |     @Value("${VITE_APP_URL}") | ||||||
|  |     private String frontendUrl; | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Configure the CORS (Cross Origin Ressource Sharing -- a security feature) configuration. The | ||||||
|  |      * only allowed website is the frontend, defined in the .env file. | ||||||
|  |      * | ||||||
|  |      * @return the CORS configuration used by the backend | ||||||
|  |      */ | ||||||
|     @Bean |     @Bean | ||||||
|     public CorsConfigurationSource corsConfigurationSource() { |     public CorsConfigurationSource corsConfigurationSource() { | ||||||
|         CorsConfiguration configuration = new CorsConfiguration(); |         CorsConfiguration configuration = new CorsConfiguration(); | ||||||
|         configuration.setAllowedOrigins(List.of("*")); |         configuration.setAllowedOrigins(List.of(frontendUrl)); | ||||||
|         configuration.setAllowedMethods(Arrays.asList("GET", "OPTIONS")); |         configuration.setAllowedMethods(Arrays.asList("GET", "OPTIONS", "POST", "PUT", "DELETE")); | ||||||
|         configuration.setAllowedHeaders( |         configuration.setAllowedHeaders( | ||||||
|                 Arrays.asList( |                 Arrays.asList("authorization", "content-type", "x-auth-token")); | ||||||
|                         "authorization", |  | ||||||
|                         "content-type", |  | ||||||
|                         "x-auth-token")); // Do not remove, this fixes the CORS errors when |  | ||||||
|         // unauthenticated |  | ||||||
|         UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); |         UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); | ||||||
|         source.registerCorsConfiguration("/**", configuration); |         source.registerCorsConfiguration("/**", configuration); | ||||||
|  |  | ||||||
|         return source; |         return source; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Configure the authorisation required for each path. | ||||||
|  |      * | ||||||
|  |      * <p>admin endpoints are under /admin/* and entrepreneur are under /entrepreneur/* | ||||||
|  |      * | ||||||
|  |      * <p>If endpoints dont require authentication, they are under /unauth/ | ||||||
|  |      * | ||||||
|  |      * @param http automatically filled in by spring. | ||||||
|  |      * @return a securityfilterchain, automatically used by spring. | ||||||
|  |      * @throws Exception TODO: figure out when the exception are raised | ||||||
|  |      */ | ||||||
|     @Bean |     @Bean | ||||||
|     public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { |     public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { | ||||||
|         http.authorizeHttpRequests( |         http.authorizeHttpRequests( | ||||||
|                         authorize -> |                         authorize -> | ||||||
|                                 authorize |                                 authorize | ||||||
|                                         .requestMatchers("/random2") |                                         .requestMatchers("/entrepreneur/**") | ||||||
|                                         .access(hasRole("REALM_MyINPulse-entrepreneur")) |                                         .access(hasRole("REALM_MyINPulse-entrepreneur")) | ||||||
|                                         .requestMatchers("/random") |                                         .requestMatchers("/admin/**") | ||||||
|                                         .access(hasRole("REALM_MyINPulse-admin")) |                                         .access(hasRole("REALM_MyINPulse-admin")) | ||||||
|                                         .requestMatchers("/random3") |                                         .requestMatchers("/shared/**") | ||||||
|                                         .permitAll() |                                         .hasAnyRole( | ||||||
|  |                                                 "REALM_MyINPulse-admin", | ||||||
|  |                                                 "REALM_MyINPulse-entrepreneur") | ||||||
|  |                                         .requestMatchers("/unauth/**") | ||||||
|  |                                         .authenticated() | ||||||
|                                         .anyRequest() |                                         .anyRequest() | ||||||
|                                         .authenticated()) |                                         .denyAll()) | ||||||
|                 .oauth2ResourceServer( |                 .oauth2ResourceServer( | ||||||
|                         oauth2 -> |                         oauth2 -> | ||||||
|                                 oauth2.jwt( |                                 oauth2.jwt( | ||||||
|   | |||||||
| @@ -0,0 +1,129 @@ | |||||||
|  | package enseirb.myinpulse.controller; | ||||||
|  |  | ||||||
|  | import enseirb.myinpulse.model.*; | ||||||
|  | import enseirb.myinpulse.service.AdminApiService; | ||||||
|  |  | ||||||
|  | import org.springframework.beans.factory.annotation.Autowired; | ||||||
|  | import org.springframework.boot.autoconfigure.SpringBootApplication; | ||||||
|  | import org.springframework.security.core.annotation.AuthenticationPrincipal; | ||||||
|  | import org.springframework.security.oauth2.jwt.Jwt; | ||||||
|  | import org.springframework.web.bind.annotation.*; | ||||||
|  |  | ||||||
|  | @SpringBootApplication | ||||||
|  | @RestController | ||||||
|  | public class AdminApi { | ||||||
|  |  | ||||||
|  |     private final AdminApiService adminApiService; | ||||||
|  |  | ||||||
|  |     @Autowired | ||||||
|  |     AdminApi(AdminApiService adminApiService) { | ||||||
|  |         this.adminApiService = adminApiService; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * TODO: description | ||||||
|  |      * | ||||||
|  |      * @return a list of all project managed by the current admin user | ||||||
|  |      */ | ||||||
|  |     @GetMapping("/admin/projects") | ||||||
|  |     public Iterable<Project> getProjects(@AuthenticationPrincipal Jwt principal) { | ||||||
|  |         return adminApiService.getProjectsOfAdmin(principal.getClaimAsString("email")); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * TODO: Why in admin instead of shared ? + desc | ||||||
|  |      * | ||||||
|  |      * @return a list of upcoming appointments for the current user | ||||||
|  |      */ | ||||||
|  |     @GetMapping("/admin/appointments/upcoming") | ||||||
|  |     public Iterable<Appointment> getUpcomingAppointments(@AuthenticationPrincipal Jwt principal) { | ||||||
|  |         return adminApiService.getUpcomingAppointments(principal.getClaimAsString("email")); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * TODO: description | ||||||
|  |      * | ||||||
|  |      * @return a list of current unvalidated projects, waiting to be accepted | ||||||
|  |      */ | ||||||
|  |     @GetMapping("/admin/projects/pending") | ||||||
|  |     public Iterable<Project> getPendingProjects() { | ||||||
|  |         return adminApiService.getPendingProjects(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Endpoint used to make a decision about a project. | ||||||
|  |      * | ||||||
|  |      * <p>The decision must contain the administrator | ||||||
|  |      * | ||||||
|  |      * @return the status code of the request | ||||||
|  |      */ | ||||||
|  |     @PostMapping("/admin/projects/pending/decision") | ||||||
|  |     public void validateProject(@RequestBody ProjectDecision decision) { | ||||||
|  |         adminApiService.validateProject(decision); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Endpoint used to manually add a project by an admin | ||||||
|  |      * | ||||||
|  |      * @return the status code of the request | ||||||
|  |      */ | ||||||
|  |     @PostMapping("/admin/project") | ||||||
|  |     public void addNewProject(@RequestBody Project project) { | ||||||
|  |         adminApiService.addNewProject(project); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * TODO: shouldn't it be an PUT request ? / What is the rerun type | ||||||
|  |      * | ||||||
|  |      * <p>Endpoint used to add a new report to an appointment | ||||||
|  |      * | ||||||
|  |      * @return the status code of the request | ||||||
|  |      */ | ||||||
|  |     @PostMapping("/admin/appointments/report/{appointmentId}") | ||||||
|  |     public void createAppointmentReport( | ||||||
|  |             @PathVariable long appointmentId, | ||||||
|  |             @RequestBody Report report, | ||||||
|  |             @AuthenticationPrincipal Jwt principal) { | ||||||
|  |         adminApiService.createAppointmentReport( | ||||||
|  |                 appointmentId, report, principal.getClaimAsString("email")); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * TODO: Shouldn't a project be kept in history ? 2 different endpoints ? | ||||||
|  |      * | ||||||
|  |      * <p>Endpoint used to completely remove a project. | ||||||
|  |      * | ||||||
|  |      * @return the status code of the request | ||||||
|  |      */ | ||||||
|  |     @DeleteMapping("/admin/projects/{projectId}") | ||||||
|  |     public void deleteProject(@PathVariable long projectId) { | ||||||
|  |         adminApiService.deleteProject(projectId); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @PostMapping("/admin/make-admin/{userId}") | ||||||
|  |     public void setAdmin(@PathVariable long userId, @AuthenticationPrincipal Jwt principal) { | ||||||
|  |         this.adminApiService.setAdmin(userId, principal.getTokenValue()); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @PostMapping("/admin/accounts/validate/{userId}") | ||||||
|  |     public void validateEntrepreneurAcc( | ||||||
|  |             @PathVariable long userId, @AuthenticationPrincipal Jwt principal) { | ||||||
|  |         this.adminApiService.validateEntrepreneurAccount(userId, principal.getTokenValue()); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @GetMapping("/admin/pending-accounts") | ||||||
|  |     public Iterable<User> validateEntrepreneurAcc() { | ||||||
|  |         return this.adminApiService.getPendingUsers(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @PostMapping("/admin/create-account") | ||||||
|  |     public void createAccount(@AuthenticationPrincipal Jwt principal) { | ||||||
|  |         String userSurname = principal.getClaimAsString("userSurname"); | ||||||
|  |         String username = principal.getClaimAsString("preferred_username"); | ||||||
|  |         String primaryMail = principal.getClaimAsString("email"); | ||||||
|  |         String secondaryMail = principal.getClaimAsString("secondaryMail"); | ||||||
|  |         String phoneNumber = principal.getClaimAsString("phoneNumber"); | ||||||
|  |         this.adminApiService.createAccount( | ||||||
|  |                 userSurname, username, primaryMail, secondaryMail, phoneNumber); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -0,0 +1,116 @@ | |||||||
|  | package enseirb.myinpulse.controller; | ||||||
|  |  | ||||||
|  | import org.springframework.beans.factory.annotation.Autowired; | ||||||
|  | import org.springframework.boot.autoconfigure.SpringBootApplication; | ||||||
|  | import org.springframework.security.core.annotation.AuthenticationPrincipal; | ||||||
|  | import org.springframework.security.oauth2.jwt.Jwt; | ||||||
|  | import org.springframework.web.bind.annotation.DeleteMapping; | ||||||
|  | import org.springframework.web.bind.annotation.GetMapping; | ||||||
|  | import org.springframework.web.bind.annotation.PathVariable; | ||||||
|  | import org.springframework.web.bind.annotation.PostMapping; | ||||||
|  | import org.springframework.web.bind.annotation.PutMapping; | ||||||
|  | import org.springframework.web.bind.annotation.RequestBody; | ||||||
|  | import org.springframework.web.bind.annotation.RestController; | ||||||
|  |  | ||||||
|  | import enseirb.myinpulse.model.Project; | ||||||
|  | import enseirb.myinpulse.model.SectionCell; | ||||||
|  | import enseirb.myinpulse.service.EntrepreneurApiService; | ||||||
|  |  | ||||||
|  | @SpringBootApplication | ||||||
|  | @RestController | ||||||
|  | public class EntrepreneurApi { | ||||||
|  |  | ||||||
|  |     private final EntrepreneurApiService entrepreneurApiService; | ||||||
|  |  | ||||||
|  |     @Autowired | ||||||
|  |     EntrepreneurApi(EntrepreneurApiService entrepreneurApiService) { | ||||||
|  |         this.entrepreneurApiService = entrepreneurApiService; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * TODO: check return type | ||||||
|  |      * | ||||||
|  |      * <p>Endpoint used to update a LC section. | ||||||
|  |      * | ||||||
|  |      * @return status code | ||||||
|  |      */ | ||||||
|  |     @PutMapping("/entrepreneur/sectionCells/{sectionCellId}") | ||||||
|  |     public void editSectionCell( | ||||||
|  |             @PathVariable Long sectionCellId, | ||||||
|  |             @RequestBody String content, | ||||||
|  |             @AuthenticationPrincipal Jwt principal) { | ||||||
|  |         entrepreneurApiService.editSectionCell( | ||||||
|  |                 sectionCellId, content, principal.getClaimAsString("email")); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Endpoint used to update a LC section. | ||||||
|  |      * | ||||||
|  |      * @return status code | ||||||
|  |      */ | ||||||
|  |     @GetMapping("/entrepreneur/projects") | ||||||
|  |     public Iterable<Project> getEntrepreneurProjectId( | ||||||
|  |             @PathVariable Long sectionCellId, | ||||||
|  |             @RequestBody String content, | ||||||
|  |             @AuthenticationPrincipal Jwt principal) { | ||||||
|  |         return entrepreneurApiService.getProjectIdViaClaim(principal.getClaimAsString("email")); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * TODO: checkReturn Type | ||||||
|  |      * | ||||||
|  |      * <p>Endpoint used to delete a LC section | ||||||
|  |      * | ||||||
|  |      * @return status code | ||||||
|  |      */ | ||||||
|  |     @DeleteMapping("/entrepreneur/sectionCells/{sectionCellId}") | ||||||
|  |     public void removeSectionCell( | ||||||
|  |             @PathVariable Long sectionCellId, @AuthenticationPrincipal Jwt principal) { | ||||||
|  |         entrepreneurApiService.removeSectionCell( | ||||||
|  |                 sectionCellId, principal.getClaimAsString("email")); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * TODO: check return type | ||||||
|  |      * | ||||||
|  |      * <p>Endpoint used to create a new LC section | ||||||
|  |      * | ||||||
|  |      * @return status code | ||||||
|  |      */ | ||||||
|  |     @PostMapping("/entrepreneur/sectionCells") | ||||||
|  |     public void addLCSection( | ||||||
|  |             @RequestBody SectionCell sectionCell, @AuthenticationPrincipal Jwt principal) { | ||||||
|  |         entrepreneurApiService.addSectionCell(sectionCell, principal.getClaimAsString("email")); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * TODO: check return type | ||||||
|  |      * | ||||||
|  |      * <p>Endpoint used to request the creation of a new project | ||||||
|  |      * | ||||||
|  |      * @return status code | ||||||
|  |      */ | ||||||
|  |     @PostMapping("/entrepreneur/projects/request") | ||||||
|  |     public void requestNewProject( | ||||||
|  |             @RequestBody Project project, @AuthenticationPrincipal Jwt principal) { | ||||||
|  |         entrepreneurApiService.requestNewProject(project, principal.getClaimAsString("email")); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /* | ||||||
|  |      * <p>Endpoint to check if project is has already been validated by an admin | ||||||
|  |      */ | ||||||
|  |     @GetMapping("/entrepreneur/projects/project-is-active") | ||||||
|  |     public Boolean checkIfProjectValidated(@AuthenticationPrincipal Jwt principal) { | ||||||
|  |         return entrepreneurApiService.checkIfEntrepreneurProjectActive( | ||||||
|  |                 principal.getClaimAsString("email")); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /* | ||||||
|  |      * <p>Endpoint to check if a user requested a project (used when project is pending) | ||||||
|  |      */ | ||||||
|  |     @GetMapping("/entrepreneur/projects/has-pending-request") | ||||||
|  |     public Boolean checkIfHasRequested(@AuthenticationPrincipal Jwt principal) { | ||||||
|  |         return entrepreneurApiService.entrepreneurHasPendingRequestedProject( | ||||||
|  |                 principal.getClaimAsString("email")); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -0,0 +1,105 @@ | |||||||
|  | package enseirb.myinpulse.controller; | ||||||
|  |  | ||||||
|  | import com.itextpdf.text.DocumentException; | ||||||
|  |  | ||||||
|  | import enseirb.myinpulse.model.*; | ||||||
|  | import enseirb.myinpulse.service.SharedApiService; | ||||||
|  |  | ||||||
|  | import org.springframework.beans.factory.annotation.Autowired; | ||||||
|  | import org.springframework.boot.autoconfigure.SpringBootApplication; | ||||||
|  | import org.springframework.security.core.annotation.AuthenticationPrincipal; | ||||||
|  | import org.springframework.security.oauth2.jwt.Jwt; | ||||||
|  | import org.springframework.web.bind.annotation.*; | ||||||
|  |  | ||||||
|  | import java.io.IOException; | ||||||
|  | import java.net.URISyntaxException; | ||||||
|  |  | ||||||
|  | @SpringBootApplication | ||||||
|  | @RestController | ||||||
|  | public class SharedApi { | ||||||
|  |  | ||||||
|  |     private final SharedApiService sharedApiService; | ||||||
|  |  | ||||||
|  |     @Autowired | ||||||
|  |     SharedApi(SharedApiService sharedApiService) { | ||||||
|  |         this.sharedApiService = sharedApiService; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Endpoint used to get the data inside the lean canvas | ||||||
|  |      * | ||||||
|  |      * @return a list of lean canvas sections | ||||||
|  |      */ | ||||||
|  |     @GetMapping("/shared/projects/sectionCells/{projectId}/{sectionId}/{date}") | ||||||
|  |     public Iterable<SectionCell> getLCSection( | ||||||
|  |             @PathVariable("projectId") Long projectId, | ||||||
|  |             @PathVariable("sectionId") Long sectionId, | ||||||
|  |             @PathVariable("date") String date, | ||||||
|  |             @AuthenticationPrincipal Jwt principal) { | ||||||
|  |         return sharedApiService.getSectionCells( | ||||||
|  |                 projectId, sectionId, date, principal.getClaimAsString("email")); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Endpoint used to get entrepreneurs details | ||||||
|  |      * | ||||||
|  |      * @return a list of all entrepreneurs in a project | ||||||
|  |      */ | ||||||
|  |     @GetMapping("/shared/projects/entrepreneurs/{projectId}") | ||||||
|  |     public Iterable<Entrepreneur> getEntrepreneursByProjectId( | ||||||
|  |             @PathVariable int projectId, @AuthenticationPrincipal Jwt principal) { | ||||||
|  |         return sharedApiService.getEntrepreneursByProjectId( | ||||||
|  |                 projectId, principal.getClaimAsString("email")); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Endpoint used to get the administrator of a project. | ||||||
|  |      * | ||||||
|  |      * @return the admin of a project | ||||||
|  |      */ | ||||||
|  |     @GetMapping("/shared/projects/admin/{projectId}") | ||||||
|  |     public Administrator getAdminByProjectId( | ||||||
|  |             @PathVariable int projectId, @AuthenticationPrincipal Jwt principal) { | ||||||
|  |         return sharedApiService.getAdminByProjectId(projectId, principal.getClaimAsString("email")); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Endpoint used to get all appointments of a single project. | ||||||
|  |      * | ||||||
|  |      * @return a list of all appointments. | ||||||
|  |      */ | ||||||
|  |     @GetMapping("/shared/projects/appointments/{projectId}") | ||||||
|  |     public Iterable<Appointment> getAppointmentsByProjectId( | ||||||
|  |             @PathVariable int projectId, @AuthenticationPrincipal Jwt principal) { | ||||||
|  |         return sharedApiService.getAppointmentsByProjectId( | ||||||
|  |                 projectId, principal.getClaimAsString("email")); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Endpoint used to generate a PDF report | ||||||
|  |      * | ||||||
|  |      * @return a PDF file? TODO: how does that works ? | ||||||
|  |      */ | ||||||
|  |     @GetMapping("/shared/appointments/report/{appointmentId}") | ||||||
|  |     public void getPDFReport( | ||||||
|  |             @PathVariable int appointmentId, @AuthenticationPrincipal Jwt principal) { | ||||||
|  |         try { | ||||||
|  |             sharedApiService.getPDFReport(appointmentId, principal.getClaimAsString("email")); | ||||||
|  |         } catch (DocumentException e) { | ||||||
|  |             System.out.println(e + "Document exception"); | ||||||
|  |         } catch (URISyntaxException e) { | ||||||
|  |             System.out.println(e + "Error with URI"); | ||||||
|  |         } catch (IOException e) { | ||||||
|  |             System.out.println(e + "Failed to access file"); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * @return TODO | ||||||
|  |      */ | ||||||
|  |     @PostMapping("/shared/appointments/request") | ||||||
|  |     public void createAppointmentRequest( | ||||||
|  |             @RequestBody Appointment appointment, @AuthenticationPrincipal Jwt principal) { | ||||||
|  |         sharedApiService.createAppointmentRequest(appointment, principal.getClaimAsString("email")); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -0,0 +1,61 @@ | |||||||
|  | package enseirb.myinpulse.controller; | ||||||
|  |  | ||||||
|  | import enseirb.myinpulse.model.Entrepreneur; | ||||||
|  | import enseirb.myinpulse.service.EntrepreneurApiService; | ||||||
|  | import enseirb.myinpulse.service.UtilsService; | ||||||
|  |  | ||||||
|  | import org.springframework.beans.factory.annotation.Autowired; | ||||||
|  | import org.springframework.boot.autoconfigure.SpringBootApplication; | ||||||
|  | import org.springframework.security.core.annotation.AuthenticationPrincipal; | ||||||
|  | import org.springframework.security.oauth2.jwt.Jwt; | ||||||
|  | import org.springframework.web.bind.annotation.*; | ||||||
|  |  | ||||||
|  | @SpringBootApplication | ||||||
|  | @RestController | ||||||
|  | public class UnauthApi { | ||||||
|  |  | ||||||
|  |     private final EntrepreneurApiService entrepreneurApiService; | ||||||
|  |     private final UtilsService utilsService; | ||||||
|  |  | ||||||
|  |     @Autowired | ||||||
|  |     UnauthApi(EntrepreneurApiService entrepreneurApiService, UtilsService utilsService) { | ||||||
|  |         this.entrepreneurApiService = entrepreneurApiService; | ||||||
|  |         this.utilsService = utilsService; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @PostMapping("/unauth/finalize") | ||||||
|  |     public void createAccount(@AuthenticationPrincipal Jwt principal) { | ||||||
|  |         boolean sneeStatus; | ||||||
|  |         if (principal.getClaimAsString("sneeStatus") != null) { | ||||||
|  |             sneeStatus = principal.getClaimAsString("sneeStatus").equals("true"); | ||||||
|  |         } else { | ||||||
|  |             sneeStatus = false; | ||||||
|  |         } | ||||||
|  |         String userSurname = principal.getClaimAsString("userSurname"); | ||||||
|  |         String username = principal.getClaimAsString("preferred_username"); | ||||||
|  |         String primaryMail = principal.getClaimAsString("email"); | ||||||
|  |         String secondaryMail = principal.getClaimAsString("secondaryMail"); | ||||||
|  |         String phoneNumber = principal.getClaimAsString("phoneNumber"); | ||||||
|  |         String school = principal.getClaimAsString("school"); | ||||||
|  |         String course = principal.getClaimAsString("course"); | ||||||
|  |         Entrepreneur e = | ||||||
|  |                 new Entrepreneur( | ||||||
|  |                         userSurname, | ||||||
|  |                         username, | ||||||
|  |                         primaryMail, | ||||||
|  |                         secondaryMail, | ||||||
|  |                         phoneNumber, | ||||||
|  |                         school, | ||||||
|  |                         course, | ||||||
|  |                         sneeStatus, | ||||||
|  |                         true); | ||||||
|  |  | ||||||
|  |         entrepreneurApiService.createAccount(e); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @GetMapping("/unauth/check-if-not-pending") | ||||||
|  |     public Boolean checkAccountStatus(@AuthenticationPrincipal Jwt principal) { | ||||||
|  |         // Throws 404 if user not found | ||||||
|  |         return utilsService.checkEntrepreneurNotPending(principal.getClaimAsString("email")); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -0,0 +1,7 @@ | |||||||
|  | package enseirb.myinpulse.exception; | ||||||
|  |  | ||||||
|  | public class RoleNotFoudException extends RuntimeException { | ||||||
|  |     public RoleNotFoudException(String message) { | ||||||
|  |         super(message); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -0,0 +1,7 @@ | |||||||
|  | package enseirb.myinpulse.exception; | ||||||
|  |  | ||||||
|  | public class UserNotFoundException extends RuntimeException { | ||||||
|  |     public UserNotFoundException(String message) { | ||||||
|  |         super(message); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -0,0 +1,66 @@ | |||||||
|  | package enseirb.myinpulse.model; | ||||||
|  |  | ||||||
|  | import jakarta.persistence.*; | ||||||
|  | import jakarta.persistence.PrimaryKeyJoinColumn; | ||||||
|  | import jakarta.persistence.Table; | ||||||
|  |  | ||||||
|  | import java.util.ArrayList; | ||||||
|  | import java.util.List; | ||||||
|  |  | ||||||
|  | @Entity | ||||||
|  | @Table(name = "administrator") | ||||||
|  | @PrimaryKeyJoinColumn(name = "idAdministrator", referencedColumnName = "idUser") | ||||||
|  | public class Administrator extends User { | ||||||
|  |  | ||||||
|  |     @OneToMany(mappedBy = "projectAdministrator", fetch = FetchType.LAZY, orphanRemoval = true) | ||||||
|  |     private final List<Project> listProject = new ArrayList<>(); | ||||||
|  |  | ||||||
|  |     /*@OneToMany(mappedBy = "administratorSectionCell", fetch = FetchType.LAZY, orphanRemoval = true) | ||||||
|  |     private List<SectionCell> listSectionCell = new ArrayList<>();*/ | ||||||
|  |     // should now be useless | ||||||
|  |  | ||||||
|  |     @OneToMany(mappedBy = "administratorAnnotation", fetch = FetchType.LAZY, orphanRemoval = true) | ||||||
|  |     private final List<Annotation> listAnnotation = new ArrayList<>(); | ||||||
|  |  | ||||||
|  |     /*@OneToMany(mappedBy = "administratorAppointment", fetch = FetchType.LAZY, orphanRemoval = true) | ||||||
|  |     private final List<Appointment> listAppointment = new ArrayList<>();*/ | ||||||
|  |     // should now be useless | ||||||
|  |  | ||||||
|  |     @OneToOne(mappedBy = "administratorAppointment", fetch = FetchType.LAZY, orphanRemoval = true) | ||||||
|  |     private MakeAppointment makeAppointment; | ||||||
|  |  | ||||||
|  |     public Administrator() {} | ||||||
|  |  | ||||||
|  |     public Administrator( | ||||||
|  |             String userSurname, | ||||||
|  |             String username, | ||||||
|  |             String primaryMail, | ||||||
|  |             String secondaryMail, | ||||||
|  |             String phoneNumber) { | ||||||
|  |         super(userSurname, username, primaryMail, secondaryMail, phoneNumber, false); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public List<Project> getListProject() { | ||||||
|  |         return listProject; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public void updateListProject(Project project) { | ||||||
|  |         listProject.add(project); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public List<Annotation> getListAnnotation() { | ||||||
|  |         return listAnnotation; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public void updateListAnnotation(Annotation annotation) { | ||||||
|  |         listAnnotation.add(annotation); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public MakeAppointment getMakeAppointment() { | ||||||
|  |         return makeAppointment; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public void setMakeAppointment(MakeAppointment makeAppointment) { | ||||||
|  |         this.makeAppointment = makeAppointment; | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -0,0 +1,61 @@ | |||||||
|  | package enseirb.myinpulse.model; | ||||||
|  |  | ||||||
|  | import jakarta.persistence.*; | ||||||
|  |  | ||||||
|  | @Entity | ||||||
|  | @Table(name = "annotation") | ||||||
|  | public class Annotation { | ||||||
|  |  | ||||||
|  |     @Id | ||||||
|  |     @GeneratedValue(strategy = GenerationType.IDENTITY) | ||||||
|  |     private Long idAnnotation; | ||||||
|  |  | ||||||
|  |     private String comment; | ||||||
|  |  | ||||||
|  |     @ManyToOne(fetch = FetchType.LAZY) | ||||||
|  |     @JoinColumn(name = "idSectionCell") | ||||||
|  |     private SectionCell sectionCellAnnotation; | ||||||
|  |  | ||||||
|  |     @ManyToOne(fetch = FetchType.LAZY) | ||||||
|  |     @JoinColumn(name = "idAdministrator") | ||||||
|  |     private Administrator administratorAnnotation; | ||||||
|  |  | ||||||
|  |     public Annotation() {} | ||||||
|  |  | ||||||
|  |     public Annotation(Long idAnnotation, String commentary) { | ||||||
|  |         this.idAnnotation = idAnnotation; | ||||||
|  |         this.comment = comment; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public String getComment() { | ||||||
|  |         return comment; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public void setComment(String comment) { | ||||||
|  |         this.comment = comment; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public Long getIdAnnotation() { | ||||||
|  |         return idAnnotation; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public void setIdAnnotation(Long idAnnotation) { | ||||||
|  |         this.idAnnotation = idAnnotation; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public SectionCell getSectionCellAnnotation() { | ||||||
|  |         return sectionCellAnnotation; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public void setSectionCellAnnotation(SectionCell sectionCellAnnotation) { | ||||||
|  |         this.sectionCellAnnotation = sectionCellAnnotation; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public Administrator getAdministratorAnnotation() { | ||||||
|  |         return administratorAnnotation; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public void setAdministratorAnnotation(Administrator administratorAnnotation) { | ||||||
|  |         this.administratorAnnotation = administratorAnnotation; | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -0,0 +1,126 @@ | |||||||
|  | package enseirb.myinpulse.model; | ||||||
|  |  | ||||||
|  | import jakarta.persistence.*; | ||||||
|  |  | ||||||
|  | import java.time.LocalDate; | ||||||
|  | import java.time.LocalTime; | ||||||
|  | import java.util.ArrayList; | ||||||
|  | import java.util.List; | ||||||
|  |  | ||||||
|  | @Entity | ||||||
|  | @Table(name = "appointment") | ||||||
|  | public class Appointment { | ||||||
|  |  | ||||||
|  |     /*@OneToMany(mappedBy = "appointmentEntrepreneurs", fetch = FetchType.LAZY, orphanRemoval = true) | ||||||
|  |     private final List<Entrepreneur> listEntrepreneur = | ||||||
|  |             new ArrayList<>(); */ | ||||||
|  |     // should now be useless | ||||||
|  |  | ||||||
|  |     @ManyToMany( | ||||||
|  |             fetch = FetchType.LAZY, | ||||||
|  |             cascade = {CascadeType.ALL}) | ||||||
|  |     @JoinTable( | ||||||
|  |             name = "concern", | ||||||
|  |             joinColumns = @JoinColumn(name = "idAppointment"), | ||||||
|  |             inverseJoinColumns = @JoinColumn(name = "idSectionCell")) | ||||||
|  |     List<SectionCell> listSectionCell = new ArrayList<>(); | ||||||
|  |  | ||||||
|  |     @OneToOne(mappedBy = "appointmentReport", fetch = FetchType.LAZY, orphanRemoval = true) | ||||||
|  |     private Report report; | ||||||
|  |  | ||||||
|  |     @Id | ||||||
|  |     @GeneratedValue(strategy = GenerationType.IDENTITY) | ||||||
|  |     private Long idAppointment; | ||||||
|  |  | ||||||
|  |     private LocalDate appointmentDate; | ||||||
|  |  | ||||||
|  |     private LocalTime appointmentTime; | ||||||
|  |  | ||||||
|  |     private LocalTime appointmentDuration; | ||||||
|  |  | ||||||
|  |     @Column(length = 255) | ||||||
|  |     private String appointmentPlace; | ||||||
|  |  | ||||||
|  |     private String appointmentSubject; | ||||||
|  |  | ||||||
|  |     public Appointment() {} | ||||||
|  |  | ||||||
|  |     public Appointment( | ||||||
|  |             Long idAppointment, | ||||||
|  |             LocalDate appointmentDate, | ||||||
|  |             LocalTime appointmentTime, | ||||||
|  |             LocalTime appointmentDuration, | ||||||
|  |             String appointmentPlace, | ||||||
|  |             String appointmentSubject) { | ||||||
|  |         this.idAppointment = idAppointment; | ||||||
|  |         this.appointmentDate = appointmentDate; | ||||||
|  |         this.appointmentTime = appointmentTime; | ||||||
|  |         this.appointmentDuration = appointmentDuration; | ||||||
|  |         this.appointmentPlace = appointmentPlace; | ||||||
|  |         this.appointmentSubject = appointmentSubject; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public Long getIdAppointment() { | ||||||
|  |         return idAppointment; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public void setIdAppointment(Long idAppointment) { | ||||||
|  |         this.idAppointment = idAppointment; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public LocalDate getAppointmentDate() { | ||||||
|  |         return appointmentDate; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public void setAppointmentDate(LocalDate appointmentDate) { | ||||||
|  |         this.appointmentDate = appointmentDate; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public LocalTime getAppointmentTime() { | ||||||
|  |         return appointmentTime; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public void setAppointmentTime(LocalTime appointmentTime) { | ||||||
|  |         this.appointmentTime = appointmentTime; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public LocalTime getAppointmentDuration() { | ||||||
|  |         return appointmentDuration; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public void setAppointmentDuration(LocalTime appointmentDuration) { | ||||||
|  |         this.appointmentDuration = appointmentDuration; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public String getAppointmentPlace() { | ||||||
|  |         return appointmentPlace; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public void setAppointmentPlace(String appointmentPlace) { | ||||||
|  |         this.appointmentPlace = appointmentPlace; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public String getAppointmentSubject() { | ||||||
|  |         return appointmentSubject; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public void setAppointmentSubject(String appointmentSubject) { | ||||||
|  |         this.appointmentSubject = appointmentSubject; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public List<SectionCell> getAppointmentListSectionCell() { | ||||||
|  |         return listSectionCell; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public void updateListSectionCell(SectionCell sectionCell) { | ||||||
|  |         listSectionCell.add(sectionCell); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public Report getAppointmentReport() { | ||||||
|  |         return report; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public void setAppointmentReport(Report report) { | ||||||
|  |         this.report = report; | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -0,0 +1,139 @@ | |||||||
|  | package enseirb.myinpulse.model; | ||||||
|  |  | ||||||
|  | import jakarta.persistence.*; | ||||||
|  | import jakarta.persistence.Entity; | ||||||
|  | import jakarta.persistence.Table; | ||||||
|  |  | ||||||
|  | @Entity | ||||||
|  | @Table(name = "entrepreneur") | ||||||
|  | @PrimaryKeyJoinColumn(name = "idEntrepreneur", referencedColumnName = "idUser") | ||||||
|  | public class Entrepreneur extends User { | ||||||
|  |  | ||||||
|  |     @Column(length = 255) | ||||||
|  |     private String school; | ||||||
|  |  | ||||||
|  |     @Column(length = 255) | ||||||
|  |     private String course; | ||||||
|  |  | ||||||
|  |     private boolean sneeStatus; | ||||||
|  |  | ||||||
|  |     @ManyToOne(fetch = FetchType.LAZY) | ||||||
|  |     @JoinColumn(name = "idProjectParticipation", referencedColumnName = "idProject") | ||||||
|  |     private Project projectParticipation; | ||||||
|  |  | ||||||
|  |     // @Column(insertable=false, updatable=false) | ||||||
|  |     @OneToOne(fetch = FetchType.LAZY) | ||||||
|  |     @JoinColumn(name = "idProjectProposed", referencedColumnName = "idProject") | ||||||
|  |     private Project projectProposed; | ||||||
|  |  | ||||||
|  |     /*@ManyToOne(fetch = FetchType.LAZY) | ||||||
|  |     @JoinColumn(name = "idAppointment") | ||||||
|  |     private Appointment appointmentEntrepreneur;*/ | ||||||
|  |     // should now be useless | ||||||
|  |  | ||||||
|  |     @OneToOne(mappedBy = "entrepreneurAppointment", fetch = FetchType.LAZY, orphanRemoval = true) | ||||||
|  |     private MakeAppointment makeAppointment; | ||||||
|  |  | ||||||
|  |     public Entrepreneur() {} | ||||||
|  |  | ||||||
|  |     public Entrepreneur( | ||||||
|  |             String userSurname, | ||||||
|  |             String username, | ||||||
|  |             String primaryMail, | ||||||
|  |             String secondaryMail, | ||||||
|  |             String phoneNumber, | ||||||
|  |             String school, | ||||||
|  |             String course, | ||||||
|  |             boolean sneeStatus, | ||||||
|  |             boolean pending) { | ||||||
|  |         super(userSurname, username, primaryMail, secondaryMail, phoneNumber, pending); | ||||||
|  |         this.school = school; | ||||||
|  |         this.course = course; | ||||||
|  |         this.sneeStatus = sneeStatus; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public Entrepreneur( | ||||||
|  |             String userSurname, | ||||||
|  |             String username, | ||||||
|  |             String primaryMail, | ||||||
|  |             String secondaryMail, | ||||||
|  |             String phoneNumber, | ||||||
|  |             String school, | ||||||
|  |             String course, | ||||||
|  |             boolean sneeStatus) { | ||||||
|  |         super(userSurname, username, primaryMail, secondaryMail, phoneNumber, true); | ||||||
|  |         this.school = school; | ||||||
|  |         this.course = course; | ||||||
|  |         this.sneeStatus = sneeStatus; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public Entrepreneur( | ||||||
|  |             String userSurname, | ||||||
|  |             String userName, | ||||||
|  |             String primaryMail, | ||||||
|  |             String secondaryMail, | ||||||
|  |             String phoneNumber, | ||||||
|  |             String school, | ||||||
|  |             String course, | ||||||
|  |             boolean sneeStatus, | ||||||
|  |             Project projectParticipation, | ||||||
|  |             Project projectProposed, | ||||||
|  |             MakeAppointment makeAppointment, | ||||||
|  |             boolean pending) { | ||||||
|  |         super(userSurname, userName, primaryMail, secondaryMail, phoneNumber, pending); | ||||||
|  |         this.school = school; | ||||||
|  |         this.course = course; | ||||||
|  |         this.sneeStatus = sneeStatus; | ||||||
|  |         this.projectParticipation = projectParticipation; | ||||||
|  |         this.projectProposed = projectProposed; | ||||||
|  |         this.makeAppointment = makeAppointment; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public String getSchool() { | ||||||
|  |         return school; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public void setSchool(String school) { | ||||||
|  |         this.school = school; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public String getCourse() { | ||||||
|  |         return course; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public void setCourse(String course) { | ||||||
|  |         this.course = course; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public boolean isSneeStatus() { | ||||||
|  |         return sneeStatus; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public void setSneeStatus(boolean statusSnee) { | ||||||
|  |         this.sneeStatus = sneeStatus; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public Project getProjectParticipation() { | ||||||
|  |         return projectParticipation; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public void setProjectParticipation(Project projectParticipation) { | ||||||
|  |         this.projectParticipation = projectParticipation; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public Project getProjectProposed() { | ||||||
|  |         return projectProposed; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public void setProjectProposed(Project projectProposed) { | ||||||
|  |         this.projectProposed = projectProposed; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public MakeAppointment getMakeAppointment() { | ||||||
|  |         return makeAppointment; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public void setMakeAppointment(MakeAppointment makeAppointment) { | ||||||
|  |         this.makeAppointment = makeAppointment; | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -0,0 +1,26 @@ | |||||||
|  | package enseirb.myinpulse.model; | ||||||
|  |  | ||||||
|  | import jakarta.persistence.*; | ||||||
|  |  | ||||||
|  | @Entity | ||||||
|  | @Table(name = "make_appointment") | ||||||
|  | public class MakeAppointment { | ||||||
|  |  | ||||||
|  |     @Id | ||||||
|  |     @GeneratedValue(strategy = GenerationType.IDENTITY) | ||||||
|  |     private Long idMakeAppointment; | ||||||
|  |  | ||||||
|  |     @OneToOne(fetch = FetchType.LAZY) | ||||||
|  |     @JoinColumn(name = "idAdministrator") | ||||||
|  |     private Administrator administratorAppointment; | ||||||
|  |  | ||||||
|  |     @OneToOne(fetch = FetchType.LAZY) | ||||||
|  |     @JoinColumn(name = "idEntrepreneur") | ||||||
|  |     private Entrepreneur entrepreneurAppointment; | ||||||
|  |  | ||||||
|  |     public MakeAppointment() {} | ||||||
|  |  | ||||||
|  |     public MakeAppointment(Long idMakeAppointment) { | ||||||
|  |         this.idMakeAppointment = idMakeAppointment; | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -0,0 +1,149 @@ | |||||||
|  | package enseirb.myinpulse.model; | ||||||
|  |  | ||||||
|  | import jakarta.persistence.*; | ||||||
|  |  | ||||||
|  | import java.time.LocalDate; | ||||||
|  | import java.util.ArrayList; | ||||||
|  | import java.util.List; | ||||||
|  |  | ||||||
|  | @Entity | ||||||
|  | @Table(name = "project") | ||||||
|  | public class Project { | ||||||
|  |  | ||||||
|  |     @OneToMany(mappedBy = "projectParticipation", fetch = FetchType.LAZY, orphanRemoval = true) | ||||||
|  |     private final List<Entrepreneur> listEntrepreneurParticipation = new ArrayList<>(); | ||||||
|  |  | ||||||
|  |     @OneToMany(mappedBy = "projectSectionCell", fetch = FetchType.LAZY, orphanRemoval = true) | ||||||
|  |     private final List<SectionCell> listSectionCell = new ArrayList<>(); | ||||||
|  |  | ||||||
|  |     @Id | ||||||
|  |     @GeneratedValue(strategy = GenerationType.IDENTITY) | ||||||
|  |     private Long idProject; | ||||||
|  |  | ||||||
|  |     @Column(length = 255) | ||||||
|  |     private String projectName; | ||||||
|  |  | ||||||
|  |     private byte[] logo; | ||||||
|  |     private LocalDate creationDate; | ||||||
|  |  | ||||||
|  |     @Column private ProjectDecisionValue projectStatus; | ||||||
|  |  | ||||||
|  |     @ManyToOne(fetch = FetchType.LAZY) | ||||||
|  |     @JoinColumn(name = "idAdministrator") | ||||||
|  |     private Administrator projectAdministrator; | ||||||
|  |  | ||||||
|  |     @OneToOne(mappedBy = "projectProposed", fetch = FetchType.LAZY, orphanRemoval = true) | ||||||
|  |     private Entrepreneur entrepreneurProposed; | ||||||
|  |  | ||||||
|  |     public Project() {} | ||||||
|  |  | ||||||
|  |     public Project( | ||||||
|  |             String projectName, | ||||||
|  |             byte[] logo, | ||||||
|  |             LocalDate creationDate, | ||||||
|  |             ProjectDecisionValue projectStatus, | ||||||
|  |             Administrator projectAdministrator) { | ||||||
|  |         this.projectName = projectName; | ||||||
|  |         this.logo = logo; | ||||||
|  |         this.creationDate = creationDate; | ||||||
|  |         // this.projectStatus = (long) projectStatus.ordinal(); | ||||||
|  |         this.projectStatus = projectStatus; | ||||||
|  |         this.projectAdministrator = projectAdministrator; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public Project( | ||||||
|  |             String projectName, | ||||||
|  |             byte[] logo, | ||||||
|  |             LocalDate creationDate, | ||||||
|  |             ProjectDecisionValue projectStatus, | ||||||
|  |             Administrator projectAdministrator, | ||||||
|  |             Entrepreneur entrepreneurProposed) { | ||||||
|  |         this.projectName = projectName; | ||||||
|  |         this.logo = logo; | ||||||
|  |         this.creationDate = creationDate; | ||||||
|  |         this.projectStatus = projectStatus; | ||||||
|  |         this.projectAdministrator = projectAdministrator; | ||||||
|  |         this.entrepreneurProposed = entrepreneurProposed; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public boolean equals(Object o) { | ||||||
|  |         if (o == this) { | ||||||
|  |             return true; | ||||||
|  |         } | ||||||
|  |         Project project = (Project) o; | ||||||
|  |         return this.idProject == project.idProject; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public Long getIdProject() { | ||||||
|  |         return idProject; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public void setIdProject(Long idProject) { | ||||||
|  |         this.idProject = idProject; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public String getProjectName() { | ||||||
|  |         return projectName; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public void setProjectName(String projectName) { | ||||||
|  |         this.projectName = projectName; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public byte[] getLogo() { | ||||||
|  |         return logo; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public void setLogo(byte[] logo) { | ||||||
|  |         this.logo = logo; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public LocalDate getCreationDate() { | ||||||
|  |         return creationDate; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public void setCreationDate(LocalDate creationDate) { | ||||||
|  |         this.creationDate = creationDate; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public ProjectDecisionValue getProjectStatus() { | ||||||
|  |         return projectStatus; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public void setProjectStatus(ProjectDecisionValue projectStatus) { | ||||||
|  |         this.projectStatus = projectStatus; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public List<Entrepreneur> getListEntrepreneurParticipation() { | ||||||
|  |         return listEntrepreneurParticipation; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public void updateListEntrepreneurParticipation(Entrepreneur projectParticipant) { | ||||||
|  |         listEntrepreneurParticipation.add(projectParticipant); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public List<SectionCell> getListSectionCell() { | ||||||
|  |         return listSectionCell; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public void updateListSectionCell(SectionCell projectSectionCell) { | ||||||
|  |         listSectionCell.add(projectSectionCell); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public Administrator getProjectAdministrator() { | ||||||
|  |         return projectAdministrator; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public void setProjectAdministrator(Administrator projectAdministrator) { | ||||||
|  |         this.projectAdministrator = projectAdministrator; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public Entrepreneur getEntrepreneurProposed() { | ||||||
|  |         return entrepreneurProposed; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public void setEntrepreneurProposed(Entrepreneur entrepreneurProposed) { | ||||||
|  |         this.entrepreneurProposed = entrepreneurProposed; | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -0,0 +1,25 @@ | |||||||
|  | package enseirb.myinpulse.model; | ||||||
|  |  | ||||||
|  | public class ProjectDecision { | ||||||
|  |     public long projectId; | ||||||
|  |     public long adminId; | ||||||
|  |     public long isAccepted; | ||||||
|  |  | ||||||
|  |     public ProjectDecision(long projectId, long adminId, long isAccepted) { | ||||||
|  |         this.projectId = projectId; | ||||||
|  |         this.adminId = adminId; | ||||||
|  |         this.isAccepted = isAccepted; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public String toString() { | ||||||
|  |         return "ProjectDecision{" | ||||||
|  |                 + "projectId=" | ||||||
|  |                 + projectId | ||||||
|  |                 + ", adminId=" | ||||||
|  |                 + adminId | ||||||
|  |                 + ", isAccepted=" | ||||||
|  |                 + isAccepted | ||||||
|  |                 + '}'; | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -0,0 +1,9 @@ | |||||||
|  | package enseirb.myinpulse.model; | ||||||
|  |  | ||||||
|  | public enum ProjectDecisionValue { | ||||||
|  |     PENDING, | ||||||
|  |     ACTIVE, | ||||||
|  |     ENDED, | ||||||
|  |     ABORTED, | ||||||
|  |     REJECTED, | ||||||
|  | } | ||||||
| @@ -0,0 +1,48 @@ | |||||||
|  | package enseirb.myinpulse.model; | ||||||
|  |  | ||||||
|  | import jakarta.persistence.*; | ||||||
|  | import jakarta.persistence.Entity; | ||||||
|  | import jakarta.persistence.Id; | ||||||
|  | import jakarta.persistence.Table; | ||||||
|  |  | ||||||
|  | @Entity | ||||||
|  | @Table(name = "report") | ||||||
|  | public class Report { | ||||||
|  |  | ||||||
|  |     @Id | ||||||
|  |     @GeneratedValue(strategy = GenerationType.IDENTITY) | ||||||
|  |     private Long idReport; | ||||||
|  |  | ||||||
|  |     private String reportContent; | ||||||
|  |  | ||||||
|  |     @OneToOne(fetch = FetchType.LAZY) | ||||||
|  |     @JoinColumn(name = "idAppointment") | ||||||
|  |     private Appointment appointmentReport; | ||||||
|  |  | ||||||
|  |     public Report() {} | ||||||
|  |  | ||||||
|  |     public Report(Long idReport, String reportContent) { | ||||||
|  |         this.idReport = idReport; | ||||||
|  |         this.reportContent = reportContent; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public Long getIdReport() { | ||||||
|  |         return idReport; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public String getReportContent() { | ||||||
|  |         return reportContent; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public void setReportContent(String reportContent) { | ||||||
|  |         this.reportContent = reportContent; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public Appointment getAppointmentReport() { | ||||||
|  |         return appointmentReport; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public void setAppointmentReport(Appointment appointmentReport) { | ||||||
|  |         this.appointmentReport = appointmentReport; | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -0,0 +1,7 @@ | |||||||
|  | package enseirb.myinpulse.model; | ||||||
|  |  | ||||||
|  | public class RoleRepresentation { | ||||||
|  |     public String id; | ||||||
|  |     public String name; | ||||||
|  |     public String description; | ||||||
|  | } | ||||||
| @@ -0,0 +1,125 @@ | |||||||
|  | package enseirb.myinpulse.model; | ||||||
|  |  | ||||||
|  | import jakarta.persistence.*; | ||||||
|  |  | ||||||
|  | import org.hibernate.annotations.Generated; | ||||||
|  | import org.hibernate.generator.EventType; | ||||||
|  |  | ||||||
|  | import java.time.LocalDateTime; | ||||||
|  | import java.util.ArrayList; | ||||||
|  | import java.util.List; | ||||||
|  |  | ||||||
|  | @Entity | ||||||
|  | @Table(name = "section_cell") | ||||||
|  | public class SectionCell { | ||||||
|  |  | ||||||
|  |     @ManyToMany(mappedBy = "listSectionCell") | ||||||
|  |     private final List<Appointment> listAppointment = new ArrayList<>(); | ||||||
|  |  | ||||||
|  |     @OneToMany(mappedBy = "sectionCellAnnotation", fetch = FetchType.LAZY, orphanRemoval = true) | ||||||
|  |     private final List<Annotation> listAnnotation = new ArrayList<>(); | ||||||
|  |  | ||||||
|  |     @Id | ||||||
|  |     @GeneratedValue(strategy = GenerationType.IDENTITY) | ||||||
|  |     private Long idSectionCell; | ||||||
|  |  | ||||||
|  |     @Column(columnDefinition = "serial") | ||||||
|  |     @Generated(event = EventType.INSERT) | ||||||
|  |     private Long idReference; | ||||||
|  |  | ||||||
|  |     @Column() private long sectionId; | ||||||
|  |     private String contentSectionCell; | ||||||
|  |  | ||||||
|  |     /*@ManyToOne(fetch = FetchType.LAZY) | ||||||
|  |     @JoinColumn(name = "idAdministrator") | ||||||
|  |     private Administrator administratorSectionCell;*/ | ||||||
|  |     // should now be useless | ||||||
|  |     private LocalDateTime modificationDate; | ||||||
|  |  | ||||||
|  |     @ManyToOne(fetch = FetchType.LAZY) | ||||||
|  |     @JoinColumn(name = "idProject") | ||||||
|  |     private Project projectSectionCell; | ||||||
|  |  | ||||||
|  |     public SectionCell() {} | ||||||
|  |  | ||||||
|  |     public SectionCell( | ||||||
|  |             Long idSectionCell, | ||||||
|  |             Long sectionId, | ||||||
|  |             String contentSectionCell, | ||||||
|  |             LocalDateTime modificationDate, | ||||||
|  |             Project projectSectionCell) { | ||||||
|  |         this.idSectionCell = idSectionCell; | ||||||
|  |         this.sectionId = sectionId; | ||||||
|  |         this.contentSectionCell = contentSectionCell; | ||||||
|  |         this.modificationDate = modificationDate; | ||||||
|  |         this.projectSectionCell = projectSectionCell; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public Long getIdSectionCell() { | ||||||
|  |         return idSectionCell; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public void setIdSectionCell(Long idSectionCell) { | ||||||
|  |         this.idSectionCell = idSectionCell; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public Long getIdReference() { | ||||||
|  |         return idReference; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public void setIdReference(Long idReference) { | ||||||
|  |         this.idReference = idReference; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public Long getSectionId() { | ||||||
|  |         return sectionId; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public void setSectionId(Long sectionId) { | ||||||
|  |         this.sectionId = sectionId; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public String getContentSectionCell() { | ||||||
|  |         return contentSectionCell; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public void setContentSectionCell(String contentSectionCell) { | ||||||
|  |         this.contentSectionCell = contentSectionCell; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public LocalDateTime getModificationDate() { | ||||||
|  |         return modificationDate; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public void setModificationDate(LocalDateTime modificationDate) { | ||||||
|  |         this.modificationDate = modificationDate; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public Project getProjectSectionCell() { | ||||||
|  |         return projectSectionCell; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public List<Appointment> getAppointmentSectionCell() { | ||||||
|  |         return listAppointment; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public void updateAppointmentSectionCell(Appointment appointment) { | ||||||
|  |         listAppointment.add(appointment); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public List<Annotation> getListAnnotation() { | ||||||
|  |         return listAnnotation; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public void updateListAnnotation(Annotation annotation) { | ||||||
|  |         listAnnotation.add(annotation); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public void setSectionId(long sectionId) { | ||||||
|  |         this.sectionId = sectionId; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public void setProjectSectionCell(Project projectSectionCell) { | ||||||
|  |         this.projectSectionCell = projectSectionCell; | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										103
									
								
								MyINPulse-back/src/main/java/enseirb/myinpulse/model/User.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										103
									
								
								MyINPulse-back/src/main/java/enseirb/myinpulse/model/User.java
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,103 @@ | |||||||
|  | package enseirb.myinpulse.model; | ||||||
|  |  | ||||||
|  | import jakarta.persistence.*; | ||||||
|  |  | ||||||
|  | @Entity | ||||||
|  | @Table(name = "user_inpulse") | ||||||
|  | @Inheritance(strategy = InheritanceType.JOINED) | ||||||
|  | public class User { | ||||||
|  |  | ||||||
|  |     @Id | ||||||
|  |     @GeneratedValue(strategy = GenerationType.IDENTITY) | ||||||
|  |     private Long idUser; | ||||||
|  |  | ||||||
|  |     @Column(length = 255) | ||||||
|  |     private String userSurname; | ||||||
|  |  | ||||||
|  |     @Column(length = 255) | ||||||
|  |     private String userName; | ||||||
|  |  | ||||||
|  |     @Column(length = 255) | ||||||
|  |     private String primaryMail; | ||||||
|  |  | ||||||
|  |     @Column(length = 255) | ||||||
|  |     private String secondaryMail; | ||||||
|  |  | ||||||
|  |     @Column(length = 20) | ||||||
|  |     private String phoneNumber; | ||||||
|  |  | ||||||
|  |     @Column private boolean pending; | ||||||
|  |  | ||||||
|  |     public User() {} | ||||||
|  |  | ||||||
|  |     public User( | ||||||
|  |             String userSurname, | ||||||
|  |             String userName, | ||||||
|  |             String primaryMail, | ||||||
|  |             String secondaryMail, | ||||||
|  |             String phoneNumber, | ||||||
|  |             boolean pending) { | ||||||
|  |         this.userSurname = userSurname; | ||||||
|  |         this.userName = userName; | ||||||
|  |         this.primaryMail = primaryMail; | ||||||
|  |         this.secondaryMail = secondaryMail; | ||||||
|  |         this.phoneNumber = phoneNumber; | ||||||
|  |         this.pending = pending; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public Long getIdUser() { | ||||||
|  |         return idUser; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public void setIdUser(Long idUser) { | ||||||
|  |         this.idUser = idUser; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public String getUserSurname() { | ||||||
|  |         return userSurname; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public void setUserSurname(String userSurname) { | ||||||
|  |         userSurname = userSurname; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public String getUserName() { | ||||||
|  |         return userName; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public void setUserName(String userName) { | ||||||
|  |         userName = userName; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public String getPrimaryMail() { | ||||||
|  |         return primaryMail; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public void setPrimaryMail(String primaryMail) { | ||||||
|  |         this.primaryMail = primaryMail; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public String getSecondaryMail() { | ||||||
|  |         return secondaryMail; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public void setSecondaryMail(String secondaryMail) { | ||||||
|  |         this.secondaryMail = secondaryMail; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public String getPhoneNumber() { | ||||||
|  |         return phoneNumber; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public void setPhoneNumber(String phoneNumber) { | ||||||
|  |         phoneNumber = phoneNumber; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public boolean isPending() { | ||||||
|  |         return pending; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public void setPending(boolean pending) { | ||||||
|  |         this.pending = pending; | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -0,0 +1,6 @@ | |||||||
|  | package enseirb.myinpulse.model; | ||||||
|  |  | ||||||
|  | public class UserRepresentation { | ||||||
|  |     public String id; | ||||||
|  |     public String name; | ||||||
|  | } | ||||||
| @@ -1,35 +0,0 @@ | |||||||
| package enseirb.myinpulse.postgres_db.controller; |  | ||||||
|  |  | ||||||
| import enseirb.myinpulse.postgres_db.model.Administrateurs; |  | ||||||
| import enseirb.myinpulse.postgres_db.repository.AdministrateursRepository; |  | ||||||
| import java.util.Optional; |  | ||||||
| import org.springframework.beans.factory.annotation.Autowired; |  | ||||||
| import org.springframework.http.HttpStatus; |  | ||||||
| import org.springframework.web.bind.annotation.*; |  | ||||||
| import org.springframework.web.server.ResponseStatusException; |  | ||||||
|  |  | ||||||
| @RestController |  | ||||||
| public class AdministrateursController { |  | ||||||
|  |  | ||||||
|   @Autowired AdministrateursRepository administrateursRepository; |  | ||||||
|  |  | ||||||
|   @GetMapping("/Administrateurs") |  | ||||||
|   @ResponseBody |  | ||||||
|   public Iterable<Administrateurs> allAdministrateurs() { |  | ||||||
|     return this.administrateursRepository.findAll(); |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   @GetMapping("/Administrateurs/{id}") |  | ||||||
|   public Administrateurs getAdministrateursById(@PathVariable Long id) { |  | ||||||
|     Optional<Administrateurs> administrateur = this.administrateursRepository.findById(id); |  | ||||||
|     if (administrateur.isEmpty()) { |  | ||||||
|       throw new ResponseStatusException(HttpStatus.NOT_FOUND, "Cet administrateur n'existe pas"); |  | ||||||
|     } |  | ||||||
|     return administrateur.get(); |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   @PostMapping("/Administrateurs") |  | ||||||
|   public Administrateurs addAdministrateurs(@RequestBody Administrateurs administrateurs) { |  | ||||||
|     return this.administrateursRepository.save(administrateurs); |  | ||||||
|   } |  | ||||||
| } |  | ||||||
| @@ -1,47 +0,0 @@ | |||||||
| package enseirb.myinpulse.postgres_db.controller; |  | ||||||
|  |  | ||||||
| import enseirb.myinpulse.postgres_db.model.ComptesRendus; |  | ||||||
| import enseirb.myinpulse.postgres_db.repository.ComptesRendusRepository; |  | ||||||
| import java.util.Optional; |  | ||||||
| import org.springframework.beans.factory.annotation.Autowired; |  | ||||||
| import org.springframework.http.HttpStatus; |  | ||||||
| import org.springframework.web.bind.annotation.*; |  | ||||||
| import org.springframework.web.server.ResponseStatusException; |  | ||||||
|  |  | ||||||
| @RestController |  | ||||||
| public class ComptesRendusController { |  | ||||||
|  |  | ||||||
|   @Autowired ComptesRendusRepository comptesRendusRepository; |  | ||||||
|  |  | ||||||
|   @GetMapping("/ComptesRendus") |  | ||||||
|   @ResponseBody |  | ||||||
|   public Iterable<ComptesRendus> allComptesRendus() { |  | ||||||
|     return this.comptesRendusRepository.findAll(); |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   @GetMapping("/ComptesRendus/{id}") |  | ||||||
|   public ComptesRendus getComptesRendusById(@PathVariable Long id) { |  | ||||||
|     Optional<ComptesRendus> compteRendu = this.comptesRendusRepository.findById(id); |  | ||||||
|     if (compteRendu.isEmpty()) { |  | ||||||
|       throw new ResponseStatusException(HttpStatus.NOT_FOUND, "Ce compte rendu n'existe pas"); |  | ||||||
|     } |  | ||||||
|     return compteRendu.get(); |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   @PostMapping("/ComptesRendus") |  | ||||||
|   public ComptesRendus addComptesRendus(@RequestBody ComptesRendus comptesRendus) { |  | ||||||
|     return this.comptesRendusRepository.save(comptesRendus); |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   @PostMapping("/ComptesRendus/{id}") |  | ||||||
|   public ComptesRendus updateProjets(@PathVariable Long id, String contenu_compte_rendu) { |  | ||||||
|     Optional<ComptesRendus> compteRendu = this.comptesRendusRepository.findById(id); |  | ||||||
|     if (compteRendu.isEmpty()) { |  | ||||||
|       throw new ResponseStatusException(HttpStatus.NOT_FOUND, "Ce compte rendu n'existe pas"); |  | ||||||
|     } |  | ||||||
|     if (contenu_compte_rendu != null) { |  | ||||||
|       compteRendu.get().setContenu_compte_rendu(contenu_compte_rendu); |  | ||||||
|     } |  | ||||||
|     return compteRendu.get(); |  | ||||||
|   } |  | ||||||
| } |  | ||||||
| @@ -1,54 +0,0 @@ | |||||||
| package enseirb.myinpulse.postgres_db.controller; |  | ||||||
|  |  | ||||||
| import enseirb.myinpulse.postgres_db.model.Entrepreneurs; |  | ||||||
| import enseirb.myinpulse.postgres_db.repository.EntrepreneursRepository; |  | ||||||
| import java.util.Optional; |  | ||||||
| import org.springframework.beans.factory.annotation.Autowired; |  | ||||||
| import org.springframework.http.HttpStatus; |  | ||||||
| import org.springframework.web.bind.annotation.*; |  | ||||||
| import org.springframework.web.server.ResponseStatusException; |  | ||||||
|  |  | ||||||
| @RestController |  | ||||||
| public class EntrepreneursController { |  | ||||||
|  |  | ||||||
|   @Autowired EntrepreneursRepository entrepreneursRepository; |  | ||||||
|  |  | ||||||
|   @GetMapping("/Entrepreneurs") |  | ||||||
|   @ResponseBody |  | ||||||
|   public Iterable<Entrepreneurs> allEntrepreneurs() { |  | ||||||
|     return this.entrepreneursRepository.findAll(); |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   @GetMapping("/Entrepreneurs/{id}") |  | ||||||
|   public Entrepreneurs getEntrepreneursById(@PathVariable Long id) { |  | ||||||
|     Optional<Entrepreneurs> entrepreneur = entrepreneursRepository.findById(id); |  | ||||||
|     if (entrepreneur.isEmpty()) { |  | ||||||
|       throw new ResponseStatusException(HttpStatus.NOT_FOUND, "Cet entrepreneur n'existe pas"); |  | ||||||
|     } |  | ||||||
|     return entrepreneur.get(); |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   @PostMapping("/Entrepreneurs") |  | ||||||
|   public Entrepreneurs addEntrepreneurs(@RequestBody Entrepreneurs entrepreneurs) { |  | ||||||
|     return this.entrepreneursRepository.save(entrepreneurs); |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   @PostMapping("/Entrepreneurs/{id}") |  | ||||||
|   public Entrepreneurs updateEntrepreneurs( |  | ||||||
|       @PathVariable Long id, String ecole, String filiere, Boolean status_snee) { |  | ||||||
|     Optional<Entrepreneurs> entrepreneur = entrepreneursRepository.findById(id); |  | ||||||
|     if (entrepreneur.isEmpty()) { |  | ||||||
|       throw new ResponseStatusException(HttpStatus.NOT_FOUND, "Cet entrepreneur n'existe pas"); |  | ||||||
|     } |  | ||||||
|     if (ecole != null) { |  | ||||||
|       entrepreneur.get().setEcole(ecole); |  | ||||||
|     } |  | ||||||
|     if (filiere != null) { |  | ||||||
|       entrepreneur.get().setFiliere(filiere); |  | ||||||
|     } |  | ||||||
|     if (status_snee != null) { |  | ||||||
|       entrepreneur.get().setStatus_snee(status_snee); |  | ||||||
|     } |  | ||||||
|     return entrepreneur.get(); |  | ||||||
|   } |  | ||||||
| } |  | ||||||
| @@ -1,62 +0,0 @@ | |||||||
| package enseirb.myinpulse.postgres_db.controller; |  | ||||||
|  |  | ||||||
| import enseirb.myinpulse.postgres_db.model.Projets; |  | ||||||
| import enseirb.myinpulse.postgres_db.repository.ProjetsRepository; |  | ||||||
| import java.time.LocalDate; |  | ||||||
| import java.util.Optional; |  | ||||||
| import org.springframework.beans.factory.annotation.Autowired; |  | ||||||
| import org.springframework.http.HttpStatus; |  | ||||||
| import org.springframework.web.bind.annotation.*; |  | ||||||
| import org.springframework.web.server.ResponseStatusException; |  | ||||||
|  |  | ||||||
| @RestController |  | ||||||
| public class ProjetsController { |  | ||||||
|  |  | ||||||
|   @Autowired ProjetsRepository projetsRepository; |  | ||||||
|  |  | ||||||
|   @GetMapping("/Projets") |  | ||||||
|   @ResponseBody |  | ||||||
|   public Iterable<Projets> allProjets() { |  | ||||||
|     return this.projetsRepository.findAll(); |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   @GetMapping("/Projets/{id}") |  | ||||||
|   public Projets getProjetsById(@PathVariable Long id) { |  | ||||||
|     Optional<Projets> projet = this.projetsRepository.findById(id); |  | ||||||
|     if (projet.isEmpty()) { |  | ||||||
|       throw new ResponseStatusException(HttpStatus.NOT_FOUND, "Ce projet n'existe pas"); |  | ||||||
|     } |  | ||||||
|     return projet.get(); |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   @PostMapping("/Projets") |  | ||||||
|   public Projets addProjets(@RequestBody Projets projet) { |  | ||||||
|     return this.projetsRepository.save(projet); |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   @PostMapping("/Projets/{id}") |  | ||||||
|   public Projets updateProjets( |  | ||||||
|       @PathVariable Long id, |  | ||||||
|       String nom_projet, |  | ||||||
|       byte[] logo, |  | ||||||
|       LocalDate date_creation, |  | ||||||
|       String status_projet) { |  | ||||||
|     Optional<Projets> projet = this.projetsRepository.findById(id); |  | ||||||
|     if (projet.isEmpty()) { |  | ||||||
|       throw new ResponseStatusException(HttpStatus.NOT_FOUND, "Ce projet n'existe pas"); |  | ||||||
|     } |  | ||||||
|     if (nom_projet != null) { |  | ||||||
|       projet.get().setNom_projet(nom_projet); |  | ||||||
|     } |  | ||||||
|     if (logo != null) { |  | ||||||
|       projet.get().setLogo(logo); |  | ||||||
|     } |  | ||||||
|     if (date_creation != null) { |  | ||||||
|       projet.get().setDate_creation(date_creation); |  | ||||||
|     } |  | ||||||
|     if (status_projet != null) { |  | ||||||
|       projet.get().setStatus_projet(status_projet); |  | ||||||
|     } |  | ||||||
|     return projet.get(); |  | ||||||
|   } |  | ||||||
| } |  | ||||||
| @@ -1,67 +0,0 @@ | |||||||
| package enseirb.myinpulse.postgres_db.controller; |  | ||||||
|  |  | ||||||
| import enseirb.myinpulse.postgres_db.model.RendezVous; |  | ||||||
| import enseirb.myinpulse.postgres_db.repository.RendezVousRepository; |  | ||||||
| import java.time.LocalDate; |  | ||||||
| import java.time.LocalDateTime; |  | ||||||
| import java.util.Optional; |  | ||||||
| import org.springframework.beans.factory.annotation.Autowired; |  | ||||||
| import org.springframework.http.HttpStatus; |  | ||||||
| import org.springframework.web.bind.annotation.*; |  | ||||||
| import org.springframework.web.server.ResponseStatusException; |  | ||||||
|  |  | ||||||
| @RestController |  | ||||||
| public class RendezVousController { |  | ||||||
|  |  | ||||||
|   @Autowired RendezVousRepository rendezVousRepository; |  | ||||||
|  |  | ||||||
|   @GetMapping("/RendezVous") |  | ||||||
|   @ResponseBody |  | ||||||
|   public Iterable<RendezVous> allRendezVous() { |  | ||||||
|     return this.rendezVousRepository.findAll(); |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   @GetMapping("/RendezVous/{id}") |  | ||||||
|   public RendezVous getRendezVousById(@PathVariable Long id) { |  | ||||||
|     Optional<RendezVous> rendezVous = this.rendezVousRepository.findById(id); |  | ||||||
|     if (rendezVous.isEmpty()) { |  | ||||||
|       throw new ResponseStatusException(HttpStatus.NOT_FOUND, "Ce rendez vous n'existe pas"); |  | ||||||
|     } |  | ||||||
|     return rendezVous.get(); |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   @PostMapping("/RendezVous") |  | ||||||
|   public RendezVous addRendezVous(@RequestBody RendezVous rendezVous) { |  | ||||||
|     return this.rendezVousRepository.save(rendezVous); |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   @PostMapping("/RendezVous/{id}") |  | ||||||
|   public RendezVous updateRendezVous( |  | ||||||
|       @PathVariable Long id, |  | ||||||
|       LocalDate date_rdv, |  | ||||||
|       LocalDateTime heure_rdv, |  | ||||||
|       LocalDateTime duree_rdv, |  | ||||||
|       String lieu_rdv, |  | ||||||
|       String sujet_rdv) { |  | ||||||
|     Optional<RendezVous> rendezVous = this.rendezVousRepository.findById(id); |  | ||||||
|     if (rendezVous.isEmpty()) { |  | ||||||
|       throw new ResponseStatusException(HttpStatus.NOT_FOUND, "Ce rendez vous n'existe pas"); |  | ||||||
|     } |  | ||||||
|     if (date_rdv != null) { |  | ||||||
|       rendezVous.get().setDate_rdv(date_rdv); |  | ||||||
|     } |  | ||||||
|     if (heure_rdv != null) { |  | ||||||
|       rendezVous.get().setHeure_rdv(heure_rdv); |  | ||||||
|     } |  | ||||||
|     if (duree_rdv != null) { |  | ||||||
|       rendezVous.get().setDuree_rdv(duree_rdv); |  | ||||||
|     } |  | ||||||
|     if (lieu_rdv != null) { |  | ||||||
|       rendezVous.get().setLieu_rdv(lieu_rdv); |  | ||||||
|     } |  | ||||||
|     if (sujet_rdv != null) { |  | ||||||
|       rendezVous.get().setSujet_rdv(sujet_rdv); |  | ||||||
|     } |  | ||||||
|     return rendezVous.get(); |  | ||||||
|   } |  | ||||||
| } |  | ||||||
| @@ -1,58 +0,0 @@ | |||||||
| package enseirb.myinpulse.postgres_db.controller; |  | ||||||
|  |  | ||||||
| import enseirb.myinpulse.postgres_db.model.Sections; |  | ||||||
| import enseirb.myinpulse.postgres_db.repository.SectionsRepository; |  | ||||||
| import java.time.LocalDateTime; |  | ||||||
| import java.util.Optional; |  | ||||||
| import org.springframework.beans.factory.annotation.Autowired; |  | ||||||
| import org.springframework.http.HttpStatus; |  | ||||||
| import org.springframework.web.bind.annotation.*; |  | ||||||
| import org.springframework.web.server.ResponseStatusException; |  | ||||||
|  |  | ||||||
| @RestController |  | ||||||
| public class SectionsController { |  | ||||||
|  |  | ||||||
|   @Autowired SectionsRepository sectionsRepository; |  | ||||||
|  |  | ||||||
|   @GetMapping("/Sections") |  | ||||||
|   @ResponseBody |  | ||||||
|   public Iterable<Sections> allSections() { |  | ||||||
|     return this.sectionsRepository.findAll(); |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   @GetMapping("/Sections/{id}") |  | ||||||
|   public Sections getSectionsById(@PathVariable Long id) { |  | ||||||
|     Optional<Sections> section = this.sectionsRepository.findById(id); |  | ||||||
|     if (section.isEmpty()) { |  | ||||||
|       throw new ResponseStatusException(HttpStatus.NOT_FOUND, "Cette section n'extise pas"); |  | ||||||
|     } |  | ||||||
|     return section.get(); |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   @PostMapping("/Sections") |  | ||||||
|   public Sections addSections(@RequestBody Sections sections) { |  | ||||||
|     return this.sectionsRepository.save(sections); |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   @PostMapping("/Sections/{id}") |  | ||||||
|   public Sections updateSections( |  | ||||||
|       @PathVariable Long id, |  | ||||||
|       String titre, |  | ||||||
|       String contenu_section, |  | ||||||
|       LocalDateTime date_modification) { |  | ||||||
|     Optional<Sections> section = this.sectionsRepository.findById(id); |  | ||||||
|     if (section.isEmpty()) { |  | ||||||
|       throw new ResponseStatusException(HttpStatus.NOT_FOUND, "Cette section n'extise pas"); |  | ||||||
|     } |  | ||||||
|     if (titre != null) { |  | ||||||
|       section.get().setTitre(titre); |  | ||||||
|     } |  | ||||||
|     if (contenu_section != null) { |  | ||||||
|       section.get().setContenu_section(contenu_section); |  | ||||||
|     } |  | ||||||
|     if (date_modification != null) { |  | ||||||
|       section.get().setDate_modification(date_modification); |  | ||||||
|     } |  | ||||||
|     return section.get(); |  | ||||||
|   } |  | ||||||
| } |  | ||||||
| @@ -1,65 +0,0 @@ | |||||||
| package enseirb.myinpulse.postgres_db.controller; |  | ||||||
|  |  | ||||||
| import enseirb.myinpulse.postgres_db.model.Utilisateurs; |  | ||||||
| import enseirb.myinpulse.postgres_db.repository.UtilisateursRepository; |  | ||||||
| import java.util.Optional; |  | ||||||
| import org.springframework.beans.factory.annotation.Autowired; |  | ||||||
| import org.springframework.http.HttpStatus; |  | ||||||
| import org.springframework.web.bind.annotation.*; |  | ||||||
| import org.springframework.web.server.ResponseStatusException; |  | ||||||
|  |  | ||||||
| @RestController |  | ||||||
| public class UtilisateursController { |  | ||||||
|  |  | ||||||
|   @Autowired UtilisateursRepository utilisateursRepository; |  | ||||||
|  |  | ||||||
|   @GetMapping("/Utilisateurs") |  | ||||||
|   @ResponseBody |  | ||||||
|   public Iterable<Utilisateurs> allUtilisateurs() { |  | ||||||
|     return this.utilisateursRepository.findAll(); |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   @GetMapping("/Utilisateurs/{id}") |  | ||||||
|   public Utilisateurs getUtilisateursById(@PathVariable Long id) { |  | ||||||
|     Optional<Utilisateurs> utilisateur = utilisateursRepository.findById(id); |  | ||||||
|     if (utilisateur.isEmpty()) { |  | ||||||
|       throw new ResponseStatusException(HttpStatus.NOT_FOUND, "Cet utilisateur n'existe pas"); |  | ||||||
|     } |  | ||||||
|     return utilisateur.get(); |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   @PostMapping("/Utilisateurs") |  | ||||||
|   public Utilisateurs addUtilisateurs(@RequestBody Utilisateurs utilisateurs) { |  | ||||||
|     return this.utilisateursRepository.save(utilisateurs); |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   @PostMapping("/Utilisateurs/{id}") |  | ||||||
|   public Utilisateurs updateUtilisateurs( |  | ||||||
|       @PathVariable Long id, |  | ||||||
|       String nom_utilisateur, |  | ||||||
|       String prenom_utilisateur, |  | ||||||
|       String mail_principal, |  | ||||||
|       String mail_secondaire, |  | ||||||
|       String numero_telephone) { |  | ||||||
|     Optional<Utilisateurs> utilisateur = utilisateursRepository.findById(id); |  | ||||||
|     if (utilisateur.isEmpty()) { |  | ||||||
|       throw new ResponseStatusException(HttpStatus.NOT_FOUND, "Cet utilisateur n'existe pas"); |  | ||||||
|     } |  | ||||||
|     if (nom_utilisateur != null) { |  | ||||||
|       utilisateur.get().setNom_utilisateur(nom_utilisateur); |  | ||||||
|     } |  | ||||||
|     if (prenom_utilisateur != null) { |  | ||||||
|       utilisateur.get().setPrenom_utilisateur(prenom_utilisateur); |  | ||||||
|     } |  | ||||||
|     if (mail_principal != null) { |  | ||||||
|       utilisateur.get().setMail_principal(mail_principal); |  | ||||||
|     } |  | ||||||
|     if (mail_secondaire != null) { |  | ||||||
|       utilisateur.get().setMail_secondaire(mail_secondaire); |  | ||||||
|     } |  | ||||||
|     if (numero_telephone != null) { |  | ||||||
|       utilisateur.get().setNumero_telephone(numero_telephone); |  | ||||||
|     } |  | ||||||
|     return utilisateur.get(); |  | ||||||
|   } |  | ||||||
| } |  | ||||||
| @@ -1,42 +0,0 @@ | |||||||
| package enseirb.myinpulse.postgres_db.model; |  | ||||||
|  |  | ||||||
| import jakarta.persistence.*; |  | ||||||
| import jakarta.persistence.PrimaryKeyJoinColumn; |  | ||||||
| import jakarta.persistence.Table; |  | ||||||
| import java.util.ArrayList; |  | ||||||
| import java.util.List; |  | ||||||
|  |  | ||||||
| @Entity |  | ||||||
| @Table(name = "administrateurs") |  | ||||||
| @PrimaryKeyJoinColumn(name = "id_administrateur") |  | ||||||
| public class Administrateurs extends Utilisateurs { |  | ||||||
|  |  | ||||||
|   @ManyToOne(fetch = FetchType.LAZY) |  | ||||||
|   @JoinColumn(name = "id_projet") |  | ||||||
|   private Projets projetsAdministrateurs; |  | ||||||
|  |  | ||||||
|   @OneToMany(mappedBy = "administrateursSections", fetch = FetchType.LAZY, orphanRemoval = true) |  | ||||||
|   private List<Sections> ListSections = new ArrayList<>(); |  | ||||||
|  |  | ||||||
|   @ManyToOne(fetch = FetchType.LAZY) |  | ||||||
|   @JoinColumn(name = "id_rdv") |  | ||||||
|   private RendezVous rendezVousAdministrateurs; |  | ||||||
|  |  | ||||||
|   public Administrateurs() {} |  | ||||||
|  |  | ||||||
|   public Administrateurs( |  | ||||||
|       String nom_utilisateur, |  | ||||||
|       Long id_utilisateur, |  | ||||||
|       String prenom_utilisateur, |  | ||||||
|       String mail_principal, |  | ||||||
|       String mail_secondaire, |  | ||||||
|       String numero_telephone) { |  | ||||||
|     super( |  | ||||||
|         nom_utilisateur, |  | ||||||
|         id_utilisateur, |  | ||||||
|         prenom_utilisateur, |  | ||||||
|         mail_principal, |  | ||||||
|         mail_secondaire, |  | ||||||
|         numero_telephone); |  | ||||||
|   } |  | ||||||
| } |  | ||||||
| @@ -1,46 +0,0 @@ | |||||||
| package enseirb.myinpulse.postgres_db.model; |  | ||||||
|  |  | ||||||
| import jakarta.persistence.*; |  | ||||||
| import jakarta.persistence.Entity; |  | ||||||
| import jakarta.persistence.Id; |  | ||||||
| import jakarta.persistence.Table; |  | ||||||
| import jakarta.validation.constraints.NotNull; |  | ||||||
|  |  | ||||||
| @Entity |  | ||||||
| @Table(name = "comptes_rendus") |  | ||||||
| public class ComptesRendus { |  | ||||||
|  |  | ||||||
|   @Id |  | ||||||
|   @NotNull |  | ||||||
|   @GeneratedValue(strategy = GenerationType.IDENTITY) |  | ||||||
|   private Long id_compte_rendu; |  | ||||||
|  |  | ||||||
|   private String contenu_compte_rendu; |  | ||||||
|  |  | ||||||
|   @ManyToOne(fetch = FetchType.LAZY) |  | ||||||
|   @JoinColumn(name = "id_rdv") |  | ||||||
|   private RendezVous rendezVousComptesRendus; |  | ||||||
|  |  | ||||||
|   public ComptesRendus() {} |  | ||||||
|  |  | ||||||
|   public ComptesRendus(Long id_compte_rendu, String contenu_compte_rendu) { |  | ||||||
|     this.id_compte_rendu = id_compte_rendu; |  | ||||||
|     this.contenu_compte_rendu = contenu_compte_rendu; |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   public Long getId_compte_rendu() { |  | ||||||
|     return id_compte_rendu; |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   public void setId_compte_rendu(Long id_compte_rendu) { |  | ||||||
|     this.id_compte_rendu = id_compte_rendu; |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   public String getContenu_compte_rendu() { |  | ||||||
|     return contenu_compte_rendu; |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   public void setContenu_compte_rendu(String contenu_compte_rendu) { |  | ||||||
|     this.contenu_compte_rendu = contenu_compte_rendu; |  | ||||||
|   } |  | ||||||
| } |  | ||||||
| @@ -1,80 +0,0 @@ | |||||||
| package enseirb.myinpulse.postgres_db.model; |  | ||||||
|  |  | ||||||
| import jakarta.persistence.*; |  | ||||||
| import jakarta.persistence.Entity; |  | ||||||
| import jakarta.persistence.Table; |  | ||||||
|  |  | ||||||
| @Entity |  | ||||||
| @Table(name = "entrepreneurs") |  | ||||||
| @PrimaryKeyJoinColumn(name = "id_entrepreneur") |  | ||||||
| public class Entrepreneurs extends Utilisateurs { |  | ||||||
|  |  | ||||||
|   @Column(length = 255) |  | ||||||
|   private String ecole; |  | ||||||
|  |  | ||||||
|   @Column(length = 255) |  | ||||||
|   private String filiere; |  | ||||||
|  |  | ||||||
|   private boolean status_snee; |  | ||||||
|  |  | ||||||
|   @ManyToOne(fetch = FetchType.LAZY) |  | ||||||
|   @JoinColumn(name = "id_projet_participation", referencedColumnName = "id_projet") |  | ||||||
|   private Projets projetsParticipation; |  | ||||||
|  |  | ||||||
|   // @Column(insertable=false, updatable=false) |  | ||||||
|   @OneToOne(fetch = FetchType.LAZY) |  | ||||||
|   @JoinColumn(name = "id_projet_propose", referencedColumnName = "id_projet") |  | ||||||
|   private Projets projetsPropose; |  | ||||||
|  |  | ||||||
|   @ManyToOne(fetch = FetchType.LAZY) |  | ||||||
|   @JoinColumn(name = "id_rdv") |  | ||||||
|   private RendezVous rendezVousEntrepreneurs; |  | ||||||
|  |  | ||||||
|   public Entrepreneurs() {} |  | ||||||
|  |  | ||||||
|   public Entrepreneurs( |  | ||||||
|       String nom_utilisateur, |  | ||||||
|       Long id_utilisateur, |  | ||||||
|       String prenom_utilisateur, |  | ||||||
|       String mail_principal, |  | ||||||
|       String mail_secondaire, |  | ||||||
|       String numero_telephone, |  | ||||||
|       String ecole, |  | ||||||
|       boolean status_snee, |  | ||||||
|       String filiere) { |  | ||||||
|     super( |  | ||||||
|         nom_utilisateur, |  | ||||||
|         id_utilisateur, |  | ||||||
|         prenom_utilisateur, |  | ||||||
|         mail_principal, |  | ||||||
|         mail_secondaire, |  | ||||||
|         numero_telephone); |  | ||||||
|     this.ecole = ecole; |  | ||||||
|     this.status_snee = status_snee; |  | ||||||
|     this.filiere = filiere; |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   public String getEcole() { |  | ||||||
|     return ecole; |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   public void setEcole(String ecole) { |  | ||||||
|     this.ecole = ecole; |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   public String getFiliere() { |  | ||||||
|     return filiere; |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   public void setFiliere(String filiere) { |  | ||||||
|     this.filiere = filiere; |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   public boolean isStatus_snee() { |  | ||||||
|     return status_snee; |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   public void setStatus_snee(boolean status_snee) { |  | ||||||
|     this.status_snee = status_snee; |  | ||||||
|   } |  | ||||||
| } |  | ||||||
| @@ -1,97 +0,0 @@ | |||||||
| package enseirb.myinpulse.postgres_db.model; |  | ||||||
|  |  | ||||||
| import jakarta.persistence.*; |  | ||||||
| import jakarta.validation.constraints.NotNull; |  | ||||||
| import java.time.LocalDate; |  | ||||||
| import java.util.ArrayList; |  | ||||||
| import java.util.List; |  | ||||||
|  |  | ||||||
| @Entity |  | ||||||
| @Table(name = "projets") |  | ||||||
| public class Projets { |  | ||||||
|  |  | ||||||
|   @Id |  | ||||||
|   @NotNull |  | ||||||
|   @GeneratedValue(strategy = GenerationType.IDENTITY) |  | ||||||
|   private Long id_projet; |  | ||||||
|  |  | ||||||
|   @Column(length = 255) |  | ||||||
|   private String nom_projet; |  | ||||||
|  |  | ||||||
|   private byte[] logo; |  | ||||||
|  |  | ||||||
|   private LocalDate date_creation; |  | ||||||
|  |  | ||||||
|   @Column(length = 255) |  | ||||||
|   private String status_projet; |  | ||||||
|  |  | ||||||
|   @OneToMany(mappedBy = "projetsAdministrateurs", fetch = FetchType.LAZY, orphanRemoval = true) |  | ||||||
|   private List<Administrateurs> listAdministrateurs = new ArrayList<>(); |  | ||||||
|  |  | ||||||
|   @OneToMany(mappedBy = "projetsParticipation", fetch = FetchType.LAZY, orphanRemoval = true) |  | ||||||
|   private List<Entrepreneurs> ListEntrepreneursParticipation = new ArrayList<>(); |  | ||||||
|  |  | ||||||
|   @OneToOne(mappedBy = "projetsPropose", fetch = FetchType.LAZY, orphanRemoval = true) |  | ||||||
|   private Entrepreneurs entrepreneursPropose; |  | ||||||
|  |  | ||||||
|   @OneToMany(mappedBy = "projetsSections", fetch = FetchType.LAZY, orphanRemoval = true) |  | ||||||
|   private List<Sections> ListSections = new ArrayList<>(); |  | ||||||
|  |  | ||||||
|   // Hibernate expects entities to have a no-arg constructor, |  | ||||||
|   // though it does not necessarily have to be public. |  | ||||||
|  |  | ||||||
|   public Projets() {} |  | ||||||
|  |  | ||||||
|   public Projets( |  | ||||||
|       Long id_projet, |  | ||||||
|       String nom_projet, |  | ||||||
|       byte[] logo, |  | ||||||
|       LocalDate date_creation, |  | ||||||
|       String status_projet) { |  | ||||||
|     this.id_projet = id_projet; |  | ||||||
|     this.nom_projet = nom_projet; |  | ||||||
|     this.logo = logo; |  | ||||||
|     this.date_creation = date_creation; |  | ||||||
|     this.status_projet = status_projet; |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   public Long getId_projet() { |  | ||||||
|     return id_projet; |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   public void setId_projet(Long id_projet) { |  | ||||||
|     this.id_projet = id_projet; |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   public String getNom_projet() { |  | ||||||
|     return nom_projet; |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   public void setNom_projet(String nom_projet) { |  | ||||||
|     this.nom_projet = nom_projet; |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   public byte[] getLogo() { |  | ||||||
|     return logo; |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   public void setLogo(byte[] logo) { |  | ||||||
|     this.logo = logo; |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   public LocalDate getDate_creation() { |  | ||||||
|     return date_creation; |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   public void setDate_creation(LocalDate date_creation) { |  | ||||||
|     this.date_creation = date_creation; |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   public String getStatus_projet() { |  | ||||||
|     return status_projet; |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   public void setStatus_projet(String status_projet) { |  | ||||||
|     this.status_projet = status_projet; |  | ||||||
|   } |  | ||||||
| } |  | ||||||
| @@ -1,113 +0,0 @@ | |||||||
| package enseirb.myinpulse.postgres_db.model; |  | ||||||
|  |  | ||||||
| import jakarta.persistence.*; |  | ||||||
| import jakarta.validation.constraints.NotNull; |  | ||||||
|  |  | ||||||
| import java.time.LocalDate; |  | ||||||
| import java.time.LocalDateTime; |  | ||||||
| import java.util.ArrayList; |  | ||||||
| import java.util.List; |  | ||||||
|  |  | ||||||
| @Entity |  | ||||||
| @Table(name = "rendez_vous") |  | ||||||
| public class RendezVous { |  | ||||||
|  |  | ||||||
|   @Id |  | ||||||
|   @NotNull |  | ||||||
|   @GeneratedValue(strategy = GenerationType.IDENTITY) |  | ||||||
|   private Long id_rdv; |  | ||||||
|  |  | ||||||
|   private LocalDate date_rdv; |  | ||||||
|  |  | ||||||
|   private LocalDateTime heure_rdv; |  | ||||||
|  |  | ||||||
|   private LocalDateTime duree_rdv; |  | ||||||
|  |  | ||||||
|   @Column(length = 255) |  | ||||||
|   private String lieu_rdv; |  | ||||||
|  |  | ||||||
|   private String sujet_rdv; |  | ||||||
|  |  | ||||||
|   @OneToMany(mappedBy = "rendezVousEntrepreneurs", fetch = FetchType.LAZY, orphanRemoval = true) |  | ||||||
|   private List<Entrepreneurs> ListEntrepreneurs = new ArrayList<>(); |  | ||||||
|  |  | ||||||
|   @OneToMany(mappedBy = "rendezVousAdministrateurs", fetch = FetchType.LAZY, orphanRemoval = true) |  | ||||||
|   private List<Administrateurs> ListAdministrateurs = new ArrayList<>(); |  | ||||||
|  |  | ||||||
|   @OneToMany(mappedBy = "rendezVousComptesRendus", fetch = FetchType.LAZY, orphanRemoval = true) |  | ||||||
|   private List<ComptesRendus> ListComptesRendus = new ArrayList<>(); |  | ||||||
|  |  | ||||||
|   @ManyToMany( |  | ||||||
|       fetch = FetchType.LAZY, |  | ||||||
|       cascade = {CascadeType.ALL}) |  | ||||||
|   @JoinTable( |  | ||||||
|       name = "concerner", |  | ||||||
|       joinColumns = @JoinColumn(name = "id_rdv"), |  | ||||||
|       inverseJoinColumns = @JoinColumn(name = "id_section")) |  | ||||||
|   List<Sections> ListSections = new ArrayList<>(); |  | ||||||
|  |  | ||||||
|   public RendezVous() {} |  | ||||||
|  |  | ||||||
|   public RendezVous( |  | ||||||
|       Long id_rdv, |  | ||||||
|       LocalDate date_rdv, |  | ||||||
|       LocalDateTime heure_rdv, |  | ||||||
|       LocalDateTime duree_rdv, |  | ||||||
|       String lieu_rdv, |  | ||||||
|       String sujet_rdv) { |  | ||||||
|     this.id_rdv = id_rdv; |  | ||||||
|     this.date_rdv = date_rdv; |  | ||||||
|     this.heure_rdv = heure_rdv; |  | ||||||
|     this.duree_rdv = duree_rdv; |  | ||||||
|     this.lieu_rdv = lieu_rdv; |  | ||||||
|     this.sujet_rdv = sujet_rdv; |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   public Long getId_rdv() { |  | ||||||
|     return id_rdv; |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   public void setId_rdv(Long id_rdv) { |  | ||||||
|     this.id_rdv = id_rdv; |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   public LocalDate getDate_rdv() { |  | ||||||
|     return date_rdv; |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   public void setDate_rdv(LocalDate date_rdv) { |  | ||||||
|     this.date_rdv = date_rdv; |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   public LocalDateTime getHeure_rdv() { |  | ||||||
|     return heure_rdv; |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   public void setHeure_rdv(LocalDateTime heure_rdv) { |  | ||||||
|     this.heure_rdv = heure_rdv; |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   public LocalDateTime getDuree_rdv() { |  | ||||||
|     return duree_rdv; |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   public void setDuree_rdv(LocalDateTime duree_rdv) { |  | ||||||
|     this.duree_rdv = duree_rdv; |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   public String getLieu_rdv() { |  | ||||||
|     return lieu_rdv; |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   public void setLieu_rdv(String lieu_rdv) { |  | ||||||
|     this.lieu_rdv = lieu_rdv; |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   public String getSujet_rdv() { |  | ||||||
|     return sujet_rdv; |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   public void setSujet_rdv(String sujet_rdv) { |  | ||||||
|     this.sujet_rdv = sujet_rdv; |  | ||||||
|   } |  | ||||||
| } |  | ||||||
| @@ -1,78 +0,0 @@ | |||||||
| package enseirb.myinpulse.postgres_db.model; |  | ||||||
|  |  | ||||||
| import jakarta.persistence.*; |  | ||||||
| import jakarta.validation.constraints.NotNull; |  | ||||||
|  |  | ||||||
| import java.time.LocalDateTime; |  | ||||||
| import java.util.ArrayList; |  | ||||||
| import java.util.List; |  | ||||||
|  |  | ||||||
| @Entity |  | ||||||
| @Table(name = "sections") |  | ||||||
| public class Sections { |  | ||||||
|  |  | ||||||
|   @Id |  | ||||||
|   @NotNull |  | ||||||
|   @GeneratedValue(strategy = GenerationType.IDENTITY) |  | ||||||
|   private Long id_section; |  | ||||||
|  |  | ||||||
|   @Column(length = 255) |  | ||||||
|   private String titre; |  | ||||||
|  |  | ||||||
|   private String contenu_section; |  | ||||||
|  |  | ||||||
|   private LocalDateTime date_modification; |  | ||||||
|  |  | ||||||
|   @ManyToOne(fetch = FetchType.LAZY) |  | ||||||
|   @JoinColumn(name = "id_projet") |  | ||||||
|   private Projets projetsSections; |  | ||||||
|  |  | ||||||
|   @ManyToOne(fetch = FetchType.LAZY) |  | ||||||
|   @JoinColumn(name = "id_admnistrateur") |  | ||||||
|   private Administrateurs administrateursSections; |  | ||||||
|  |  | ||||||
|   @ManyToMany(mappedBy = "ListSections") |  | ||||||
|   private List<RendezVous> rendezVous = new ArrayList<>(); |  | ||||||
|  |  | ||||||
|   public Sections() {} |  | ||||||
|  |  | ||||||
|   public Sections( |  | ||||||
|       Long id_section, String titre, String contenu_section, LocalDateTime date_modification) { |  | ||||||
|     this.id_section = id_section; |  | ||||||
|     this.titre = titre; |  | ||||||
|     this.contenu_section = contenu_section; |  | ||||||
|     this.date_modification = date_modification; |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   public String getTitre() { |  | ||||||
|     return titre; |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   public void setTitre(String titre) { |  | ||||||
|     this.titre = titre; |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   public Long getId_section() { |  | ||||||
|     return id_section; |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   public void setId_section(Long id_section) { |  | ||||||
|     this.id_section = id_section; |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   public String getContenu_section() { |  | ||||||
|     return contenu_section; |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   public void setContenu_section(String contenu_section) { |  | ||||||
|     this.contenu_section = contenu_section; |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   public LocalDateTime getDate_modification() { |  | ||||||
|     return date_modification; |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   public void setDate_modification(LocalDateTime date_modification) { |  | ||||||
|     this.date_modification = date_modification; |  | ||||||
|   } |  | ||||||
| } |  | ||||||
| @@ -1,95 +0,0 @@ | |||||||
| package enseirb.myinpulse.postgres_db.model; |  | ||||||
|  |  | ||||||
| import jakarta.persistence.*; |  | ||||||
| import jakarta.validation.constraints.NotNull; |  | ||||||
|  |  | ||||||
| @Entity |  | ||||||
| @Table(name = "utilisateurs") |  | ||||||
| @Inheritance(strategy = InheritanceType.JOINED) |  | ||||||
| public class Utilisateurs { |  | ||||||
|  |  | ||||||
|   @Id |  | ||||||
|   @NotNull |  | ||||||
|   @GeneratedValue(strategy = GenerationType.IDENTITY) |  | ||||||
|   private Long id_utilisateur; |  | ||||||
|  |  | ||||||
|   @Column(length = 255) |  | ||||||
|   private String nom_utilisateur; |  | ||||||
|  |  | ||||||
|   @Column(length = 255) |  | ||||||
|   private String prenom_utilisateur; |  | ||||||
|  |  | ||||||
|   @Column(length = 255) |  | ||||||
|   private String mail_principal; |  | ||||||
|  |  | ||||||
|   @Column(length = 255) |  | ||||||
|   private String mail_secondaire; |  | ||||||
|  |  | ||||||
|   @Column(length = 15) |  | ||||||
|   private String numero_telephone; |  | ||||||
|  |  | ||||||
|   public Utilisateurs() {} |  | ||||||
|  |  | ||||||
|   public Utilisateurs( |  | ||||||
|       String nom_utilisateur, |  | ||||||
|       Long id_utilisateur, |  | ||||||
|       String prenom_utilisateur, |  | ||||||
|       String mail_principal, |  | ||||||
|       String mail_secondaire, |  | ||||||
|       String numero_telephone) { |  | ||||||
|     this.nom_utilisateur = nom_utilisateur; |  | ||||||
|     this.id_utilisateur = id_utilisateur; |  | ||||||
|     this.prenom_utilisateur = prenom_utilisateur; |  | ||||||
|     this.mail_principal = mail_principal; |  | ||||||
|     this.mail_secondaire = mail_secondaire; |  | ||||||
|     this.numero_telephone = numero_telephone; |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   public Long getId_utilisateur() { |  | ||||||
|     return id_utilisateur; |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   public void setId_utilisateur(Long id_utilisateur) { |  | ||||||
|     this.id_utilisateur = id_utilisateur; |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   public String getNom_utilisateur() { |  | ||||||
|     return nom_utilisateur; |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   public void setNom_utilisateur(String nom_utilisateur) { |  | ||||||
|     this.nom_utilisateur = nom_utilisateur; |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   public String getPrenom_utilisateur() { |  | ||||||
|     return prenom_utilisateur; |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   public void setPrenom_utilisateur(String prenom_utilisateur) { |  | ||||||
|     this.prenom_utilisateur = prenom_utilisateur; |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   public String getMail_principal() { |  | ||||||
|     return mail_principal; |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   public void setMail_principal(String mail_principal) { |  | ||||||
|     this.mail_principal = mail_principal; |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   public String getMail_secondaire() { |  | ||||||
|     return mail_secondaire; |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   public void setMail_secondaire(String mail_secondaire) { |  | ||||||
|     this.mail_secondaire = mail_secondaire; |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   public String getNumero_telephone() { |  | ||||||
|     return numero_telephone; |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   public void setNumero_telephone(String numero_telephone) { |  | ||||||
|     this.numero_telephone = numero_telephone; |  | ||||||
|   } |  | ||||||
| } |  | ||||||
| @@ -1,13 +0,0 @@ | |||||||
| package enseirb.myinpulse.postgres_db.repository; |  | ||||||
|  |  | ||||||
| import enseirb.myinpulse.postgres_db.model.Administrateurs; |  | ||||||
| import org.springframework.data.jpa.repository.JpaRepository; |  | ||||||
| import org.springframework.data.rest.core.annotation.RepositoryRestResource; |  | ||||||
|  |  | ||||||
| @RepositoryRestResource |  | ||||||
| public interface AdministrateursRepository extends JpaRepository<Administrateurs, Long> { |  | ||||||
|  |  | ||||||
|   /* @Query("SELECT a from Administrateurs a") |  | ||||||
|   Administrateurs findAllAdministrateurs(); */ |  | ||||||
|  |  | ||||||
| } |  | ||||||
| @@ -1,8 +0,0 @@ | |||||||
| package enseirb.myinpulse.postgres_db.repository; |  | ||||||
|  |  | ||||||
| import enseirb.myinpulse.postgres_db.model.ComptesRendus; |  | ||||||
| import org.springframework.data.jpa.repository.JpaRepository; |  | ||||||
| import org.springframework.data.rest.core.annotation.RepositoryRestResource; |  | ||||||
|  |  | ||||||
| @RepositoryRestResource |  | ||||||
| public interface ComptesRendusRepository extends JpaRepository<ComptesRendus, Long> {} |  | ||||||
| @@ -1,13 +0,0 @@ | |||||||
| package enseirb.myinpulse.postgres_db.repository; |  | ||||||
|  |  | ||||||
| import enseirb.myinpulse.postgres_db.model.Entrepreneurs; |  | ||||||
| import org.springframework.data.jpa.repository.JpaRepository; |  | ||||||
| import org.springframework.data.rest.core.annotation.RepositoryRestResource; |  | ||||||
|  |  | ||||||
| @RepositoryRestResource |  | ||||||
| public interface EntrepreneursRepository extends JpaRepository<Entrepreneurs, Long> { |  | ||||||
|  |  | ||||||
|   /* @Query("SELECT e from Entrepreneurs e") |  | ||||||
|   Entrepreneurs findAllEntrepreneurs(); */ |  | ||||||
|  |  | ||||||
| } |  | ||||||
| @@ -1,8 +0,0 @@ | |||||||
| package enseirb.myinpulse.postgres_db.repository; |  | ||||||
|  |  | ||||||
| import enseirb.myinpulse.postgres_db.model.Projets; |  | ||||||
| import org.springframework.data.jpa.repository.JpaRepository; |  | ||||||
| import org.springframework.data.rest.core.annotation.RepositoryRestResource; |  | ||||||
|  |  | ||||||
| @RepositoryRestResource |  | ||||||
| public interface ProjetsRepository extends JpaRepository<Projets, Long> {} |  | ||||||
| @@ -1,8 +0,0 @@ | |||||||
| package enseirb.myinpulse.postgres_db.repository; |  | ||||||
|  |  | ||||||
| import enseirb.myinpulse.postgres_db.model.RendezVous; |  | ||||||
| import org.springframework.data.jpa.repository.JpaRepository; |  | ||||||
| import org.springframework.data.rest.core.annotation.RepositoryRestResource; |  | ||||||
|  |  | ||||||
| @RepositoryRestResource |  | ||||||
| public interface RendezVousRepository extends JpaRepository<RendezVous, Long> {} |  | ||||||
| @@ -1,8 +0,0 @@ | |||||||
| package enseirb.myinpulse.postgres_db.repository; |  | ||||||
|  |  | ||||||
| import enseirb.myinpulse.postgres_db.model.Sections; |  | ||||||
| import org.springframework.data.jpa.repository.JpaRepository; |  | ||||||
| import org.springframework.data.rest.core.annotation.RepositoryRestResource; |  | ||||||
|  |  | ||||||
| @RepositoryRestResource |  | ||||||
| public interface SectionsRepository extends JpaRepository<Sections, Long> {} |  | ||||||
| @@ -1,13 +0,0 @@ | |||||||
| package enseirb.myinpulse.postgres_db.repository; |  | ||||||
|  |  | ||||||
| import enseirb.myinpulse.postgres_db.model.Utilisateurs; |  | ||||||
| import org.springframework.data.jpa.repository.JpaRepository; |  | ||||||
| import org.springframework.data.rest.core.annotation.RepositoryRestResource; |  | ||||||
|  |  | ||||||
| @RepositoryRestResource |  | ||||||
| public interface UtilisateursRepository extends JpaRepository<Utilisateurs, Long> { |  | ||||||
|  |  | ||||||
|   /* @Query("SELECT u from Utilisateurs u") |  | ||||||
|   Utilisateurs findAllUtilisateurs(); */ |  | ||||||
|  |  | ||||||
| } |  | ||||||
| @@ -0,0 +1,17 @@ | |||||||
|  | package enseirb.myinpulse.repository; | ||||||
|  |  | ||||||
|  | import enseirb.myinpulse.model.Administrator; | ||||||
|  |  | ||||||
|  | import org.springframework.data.jpa.repository.JpaRepository; | ||||||
|  | import org.springframework.data.rest.core.annotation.RepositoryRestResource; | ||||||
|  |  | ||||||
|  | import java.util.Optional; | ||||||
|  |  | ||||||
|  | @RepositoryRestResource | ||||||
|  | public interface AdministratorRepository extends JpaRepository<Administrator, Long> { | ||||||
|  |  | ||||||
|  |     /* @Query("SELECT a from Administrators a") | ||||||
|  |     Administrator findAllAdministrator(); */ | ||||||
|  |  | ||||||
|  |     Optional<Administrator> findByPrimaryMail(String PrimaryMail); | ||||||
|  | } | ||||||
| @@ -0,0 +1,9 @@ | |||||||
|  | package enseirb.myinpulse.repository; | ||||||
|  |  | ||||||
|  | import enseirb.myinpulse.model.Annotation; | ||||||
|  |  | ||||||
|  | import org.springframework.data.jpa.repository.JpaRepository; | ||||||
|  | import org.springframework.data.rest.core.annotation.RepositoryRestResource; | ||||||
|  |  | ||||||
|  | @RepositoryRestResource | ||||||
|  | public interface AnnotationRepository extends JpaRepository<Annotation, Long> {} | ||||||
| @@ -0,0 +1,9 @@ | |||||||
|  | package enseirb.myinpulse.repository; | ||||||
|  |  | ||||||
|  | import enseirb.myinpulse.model.Appointment; | ||||||
|  |  | ||||||
|  | import org.springframework.data.jpa.repository.JpaRepository; | ||||||
|  | import org.springframework.data.rest.core.annotation.RepositoryRestResource; | ||||||
|  |  | ||||||
|  | @RepositoryRestResource | ||||||
|  | public interface AppointmentRepository extends JpaRepository<Appointment, Long> {} | ||||||
| @@ -0,0 +1,17 @@ | |||||||
|  | package enseirb.myinpulse.repository; | ||||||
|  |  | ||||||
|  | import enseirb.myinpulse.model.Entrepreneur; | ||||||
|  | import enseirb.myinpulse.model.Project; | ||||||
|  |  | ||||||
|  | import org.springframework.data.jpa.repository.JpaRepository; | ||||||
|  | import org.springframework.data.rest.core.annotation.RepositoryRestResource; | ||||||
|  |  | ||||||
|  | @RepositoryRestResource | ||||||
|  | public interface EntrepreneurRepository extends JpaRepository<Entrepreneur, Long> { | ||||||
|  |  | ||||||
|  |     Iterable<Entrepreneur> getEntrepreneurByProjectParticipation(Project project); | ||||||
|  |  | ||||||
|  |     /* @Query("SELECT e from Entrepreneur e") | ||||||
|  |     Entrepreneur findAllEntrepreneurl(); */ | ||||||
|  |  | ||||||
|  | } | ||||||
| @@ -0,0 +1,9 @@ | |||||||
|  | package enseirb.myinpulse.repository; | ||||||
|  |  | ||||||
|  | import enseirb.myinpulse.model.MakeAppointment; | ||||||
|  |  | ||||||
|  | import org.springframework.data.jpa.repository.JpaRepository; | ||||||
|  | import org.springframework.data.rest.core.annotation.RepositoryRestResource; | ||||||
|  |  | ||||||
|  | @RepositoryRestResource | ||||||
|  | public interface MakeAppointmentRepository extends JpaRepository<MakeAppointment, Long> {} | ||||||
| @@ -0,0 +1,19 @@ | |||||||
|  | package enseirb.myinpulse.repository; | ||||||
|  |  | ||||||
|  | import enseirb.myinpulse.model.Administrator; | ||||||
|  | import enseirb.myinpulse.model.Project; | ||||||
|  | import enseirb.myinpulse.model.ProjectDecisionValue; | ||||||
|  |  | ||||||
|  | import org.springframework.data.jpa.repository.JpaRepository; | ||||||
|  | import org.springframework.data.rest.core.annotation.RepositoryRestResource; | ||||||
|  |  | ||||||
|  | import java.util.Optional; | ||||||
|  |  | ||||||
|  | @RepositoryRestResource | ||||||
|  | public interface ProjectRepository extends JpaRepository<Project, Long> { | ||||||
|  |     Iterable<Project> findByProjectAdministrator(Administrator administrator); | ||||||
|  |  | ||||||
|  |     Iterable<Project> findByProjectStatus(ProjectDecisionValue status); | ||||||
|  |  | ||||||
|  |     Optional<Project> findByProjectName(String projectName); | ||||||
|  | } | ||||||
| @@ -0,0 +1,9 @@ | |||||||
|  | package enseirb.myinpulse.repository; | ||||||
|  |  | ||||||
|  | import enseirb.myinpulse.model.Report; | ||||||
|  |  | ||||||
|  | import org.springframework.data.jpa.repository.JpaRepository; | ||||||
|  | import org.springframework.data.rest.core.annotation.RepositoryRestResource; | ||||||
|  |  | ||||||
|  | @RepositoryRestResource | ||||||
|  | public interface ReportRepository extends JpaRepository<Report, Long> {} | ||||||
| @@ -0,0 +1,20 @@ | |||||||
|  | package enseirb.myinpulse.repository; | ||||||
|  |  | ||||||
|  | import enseirb.myinpulse.model.Project; | ||||||
|  | import enseirb.myinpulse.model.SectionCell; | ||||||
|  |  | ||||||
|  | import org.springframework.data.jpa.repository.JpaRepository; | ||||||
|  | import org.springframework.data.rest.core.annotation.RepositoryRestResource; | ||||||
|  |  | ||||||
|  | import java.time.LocalDateTime; | ||||||
|  |  | ||||||
|  | @RepositoryRestResource | ||||||
|  | public interface SectionCellRepository extends JpaRepository<SectionCell, Long> { | ||||||
|  |  | ||||||
|  |     Iterable<SectionCell> findByProjectSectionCellAndSectionId(Project project, long sectionId); | ||||||
|  |  | ||||||
|  |     Iterable<SectionCell> findByProjectSectionCellAndSectionIdAndModificationDateBefore( | ||||||
|  |             Project project, long sectionId, LocalDateTime date); | ||||||
|  |  | ||||||
|  |     Iterable<SectionCell> findByProjectSectionCell(Project project); | ||||||
|  | } | ||||||
| @@ -0,0 +1,18 @@ | |||||||
|  | package enseirb.myinpulse.repository; | ||||||
|  |  | ||||||
|  | import enseirb.myinpulse.model.User; | ||||||
|  |  | ||||||
|  | import org.springframework.data.jpa.repository.JpaRepository; | ||||||
|  | import org.springframework.data.rest.core.annotation.RepositoryRestResource; | ||||||
|  |  | ||||||
|  | import java.util.Optional; | ||||||
|  |  | ||||||
|  | @RepositoryRestResource | ||||||
|  | public interface UserRepository extends JpaRepository<User, Long> { | ||||||
|  |     Optional<User> findByPrimaryMail(String primaryMail); | ||||||
|  |  | ||||||
|  |     Iterable<User> findAllByPendingEquals(boolean pending); | ||||||
|  |     /* @Query("SELECT u from User u") | ||||||
|  |     User findAllUser(); */ | ||||||
|  |  | ||||||
|  | } | ||||||
| @@ -0,0 +1,224 @@ | |||||||
|  | package enseirb.myinpulse.service; | ||||||
|  |  | ||||||
|  | import static enseirb.myinpulse.model.ProjectDecisionValue.ACTIVE; | ||||||
|  | import static enseirb.myinpulse.model.ProjectDecisionValue.REJECTED; | ||||||
|  |  | ||||||
|  | import enseirb.myinpulse.model.*; | ||||||
|  | import enseirb.myinpulse.service.database.*; | ||||||
|  |  | ||||||
|  | import org.apache.logging.log4j.LogManager; | ||||||
|  | import org.apache.logging.log4j.Logger; | ||||||
|  | import org.springframework.beans.factory.annotation.Autowired; | ||||||
|  | import org.springframework.http.HttpStatus; | ||||||
|  | import org.springframework.stereotype.Service; | ||||||
|  | import org.springframework.web.server.ResponseStatusException; | ||||||
|  |  | ||||||
|  | import java.util.ArrayList; | ||||||
|  | import java.util.List; | ||||||
|  |  | ||||||
|  | @Service | ||||||
|  | public class AdminApiService { | ||||||
|  |  | ||||||
|  |     protected static final Logger logger = LogManager.getLogger(); | ||||||
|  |  | ||||||
|  |     private final ProjectService projectService; | ||||||
|  |     private final UserService userService; | ||||||
|  |     private final AdministratorService administratorService; | ||||||
|  |     private final EntrepreneurService entrepreneurService; | ||||||
|  |     private final UtilsService utilsService; | ||||||
|  |     private final AppointmentService appointmentService; | ||||||
|  |     private final ReportService reportService; | ||||||
|  |     private final SectionCellService sectionCellService; | ||||||
|  |  | ||||||
|  |     @Autowired | ||||||
|  |     AdminApiService( | ||||||
|  |             ProjectService projectService, | ||||||
|  |             UserService userService, | ||||||
|  |             AdministratorService administratorService, | ||||||
|  |             UtilsService utilsService, | ||||||
|  |             EntrepreneurService entrepreneurService, | ||||||
|  |             AppointmentService appointmentService, | ||||||
|  |             ReportService reportService, | ||||||
|  |             SectionCellService sectionCellService) { | ||||||
|  |         this.projectService = projectService; | ||||||
|  |         this.userService = userService; | ||||||
|  |         this.administratorService = administratorService; | ||||||
|  |         this.utilsService = utilsService; | ||||||
|  |         this.appointmentService = appointmentService; | ||||||
|  |         this.reportService = reportService; | ||||||
|  |         this.sectionCellService = sectionCellService; | ||||||
|  |         this.entrepreneurService = entrepreneurService; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     // TODO: check if tests are sufficient - peer verification required | ||||||
|  |     public Iterable<Project> getProjectsOfAdmin(String mail) { | ||||||
|  |         return projectService.getProjectsByAdminId( | ||||||
|  |                 administratorService.getAdministratorById( | ||||||
|  |                         this.userService.getUserByEmail(mail).getIdUser())); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public Iterable<Appointment> getUpcomingAppointments(String mail) { | ||||||
|  |         logger.info("User {} check their upcoming appointments", mail); | ||||||
|  |         User user = this.userService.getUserByEmail(mail); | ||||||
|  |         List<Appointment> appointments = new ArrayList<>(); | ||||||
|  |         if (user instanceof Administrator) { | ||||||
|  |             List<Project> projects = new ArrayList<>(((Administrator) user).getListProject()); | ||||||
|  |             projects.forEach( | ||||||
|  |                     project -> { | ||||||
|  |                         project.getListSectionCell() | ||||||
|  |                                 .forEach( | ||||||
|  |                                         sectionCell -> { | ||||||
|  |                                             appointments.addAll( | ||||||
|  |                                                     this.sectionCellService | ||||||
|  |                                                             .getAppointmentsBySectionCellId( | ||||||
|  |                                                                     sectionCell | ||||||
|  |                                                                             .getIdSectionCell())); | ||||||
|  |                                         }); | ||||||
|  |                     }); | ||||||
|  |         } | ||||||
|  |         if (user instanceof Entrepreneur) { | ||||||
|  |             Project project = ((Entrepreneur) user).getProjectParticipation(); | ||||||
|  |             if (project == null) { | ||||||
|  |                 throw new ResponseStatusException( | ||||||
|  |                         HttpStatus.NOT_FOUND, | ||||||
|  |                         "The user has no project, thus no appointments. No users should have no project"); | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |             project.getListSectionCell() | ||||||
|  |                     .forEach( | ||||||
|  |                             sectionCell -> { | ||||||
|  |                                 appointments.addAll( | ||||||
|  |                                         this.sectionCellService.getAppointmentsBySectionCellId( | ||||||
|  |                                                 sectionCell.getIdSectionCell())); | ||||||
|  |                             }); | ||||||
|  |         } | ||||||
|  |         return appointments; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     // TODO: check if tests are sufficient - peer verification required | ||||||
|  |     public Iterable<Project> getPendingProjects() { | ||||||
|  |         return this.projectService.getPendingProjects(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     // TODO: check if tests are sufficient - peer verification required | ||||||
|  |     public void validateProject(ProjectDecision decision) { | ||||||
|  |         projectService.updateProject( | ||||||
|  |                 decision.projectId, | ||||||
|  |                 null, | ||||||
|  |                 null, | ||||||
|  |                 (decision.isAccepted == 1) ? ACTIVE : REJECTED, | ||||||
|  |                 null, | ||||||
|  |                 null, | ||||||
|  |                 this.administratorService.getAdministratorById(decision.adminId)); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     // TODO: check if tests are sufficient - peer verification required | ||||||
|  |     public Project addNewProject(Project project) { | ||||||
|  |         project.setIdProject(null); | ||||||
|  |         // We remove the ID from the request to be sure that it will be auto generated | ||||||
|  |         try { | ||||||
|  |             this.projectService.getProjectByName(project.getProjectName(), true); | ||||||
|  |             throw new ResponseStatusException(HttpStatus.CONFLICT, "Project already exists"); | ||||||
|  |         } catch (ResponseStatusException e) { | ||||||
|  |             if (e.getStatusCode() == HttpStatus.CONFLICT) { | ||||||
|  |                 throw new ResponseStatusException(HttpStatus.CONFLICT, "Project already exists"); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         Project newProject = projectService.addNewProject(project); | ||||||
|  |         if (project.getProjectAdministrator() != null) { | ||||||
|  |             newProject.getProjectAdministrator().updateListProject(newProject); | ||||||
|  |         } | ||||||
|  |         if (newProject.getEntrepreneurProposed() != null) { | ||||||
|  |             Entrepreneur proposed = newProject.getEntrepreneurProposed(); | ||||||
|  |             proposed.setProjectProposed(newProject); | ||||||
|  |             proposed.setProjectParticipation(newProject); | ||||||
|  |         } | ||||||
|  |         newProject | ||||||
|  |                 .getListEntrepreneurParticipation() | ||||||
|  |                 .forEach( | ||||||
|  |                         participation -> { | ||||||
|  |                             participation.setProjectParticipation(newProject); | ||||||
|  |                         }); | ||||||
|  |         newProject | ||||||
|  |                 .getListSectionCell() | ||||||
|  |                 .forEach( | ||||||
|  |                         sectionCell -> { | ||||||
|  |                             sectionCell.setProjectSectionCell(newProject); | ||||||
|  |                         }); | ||||||
|  |         return newProject; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public void createAppointmentReport(long appointmentId, Report report, String mail) { | ||||||
|  |         long projectId = | ||||||
|  |                 this.appointmentService | ||||||
|  |                         .getAppointmentById(appointmentId) | ||||||
|  |                         .getAppointmentListSectionCell() | ||||||
|  |                         .getFirst() | ||||||
|  |                         .getProjectSectionCell() | ||||||
|  |                         .getIdProject(); | ||||||
|  |         if (!utilsService.isAllowedToCheckProject(mail, projectId)) { | ||||||
|  |             logger.warn( | ||||||
|  |                     "User {} tried to add an report for appointment {} but is not allowed to.", | ||||||
|  |                     mail, | ||||||
|  |                     projectId); | ||||||
|  |             throw new ResponseStatusException( | ||||||
|  |                     HttpStatus.UNAUTHORIZED, "You're not allowed to check this project"); | ||||||
|  |         } | ||||||
|  |         logger.info("User {} added a report for appointment {}", mail, projectId); | ||||||
|  |         Report addedReport = this.reportService.addNewReport(report); | ||||||
|  |         addedReport.setAppointmentReport(this.appointmentService.getAppointmentById(appointmentId)); | ||||||
|  |         this.appointmentService.getAppointmentById(appointmentId).setAppointmentReport(addedReport); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     // TODO: test | ||||||
|  |     public void deleteProject(long projectId) { | ||||||
|  |         this.projectService.deleteProjectById(projectId); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public void setAdmin(long userId, String token) { | ||||||
|  |         Entrepreneur e = this.entrepreneurService.getEntrepreneurById(userId); | ||||||
|  |         Administrator a = | ||||||
|  |                 new Administrator( | ||||||
|  |                         e.getUserSurname(), | ||||||
|  |                         e.getUserName(), | ||||||
|  |                         e.getPrimaryMail(), | ||||||
|  |                         e.getSecondaryMail(), | ||||||
|  |                         e.getPhoneNumber()); | ||||||
|  |         this.entrepreneurService.deleteEntrepreneur(e); | ||||||
|  |         this.administratorService.addAdministrator(a); | ||||||
|  |         try { | ||||||
|  |             KeycloakApi.setRoleToUser(a.getUserName(), "MyINPulse-admin", token); | ||||||
|  |         } catch (Exception err) { | ||||||
|  |             logger.error(err); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public void validateEntrepreneurAccount(long userId, String token) { | ||||||
|  |         Entrepreneur e = this.entrepreneurService.getEntrepreneurById(userId); | ||||||
|  |         try { | ||||||
|  |             KeycloakApi.setRoleToUser(e.getUserName(), "MyINPulse-entrepreneur", token); | ||||||
|  |         } catch (Exception err) { | ||||||
|  |             logger.error(err); | ||||||
|  |         } | ||||||
|  |         this.entrepreneurService.validateEntrepreneurById(userId); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public Iterable<User> getPendingUsers() { | ||||||
|  |         return this.userService.getPendingAccounts(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public void createAccount( | ||||||
|  |             String username, | ||||||
|  |             String userSurname, | ||||||
|  |             String primaryMail, | ||||||
|  |             String secondaryMail, | ||||||
|  |             String phoneNumber) { | ||||||
|  |         Administrator a = | ||||||
|  |                 new Administrator(username, userSurname, primaryMail, secondaryMail, phoneNumber); | ||||||
|  |         this.administratorService.addAdministrator(a); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public Iterable<Administrator> getAllAdmins() { | ||||||
|  |         return this.administratorService.allAdministrators(); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -0,0 +1,284 @@ | |||||||
|  | package enseirb.myinpulse.service; | ||||||
|  |  | ||||||
|  | import static enseirb.myinpulse.model.ProjectDecisionValue.PENDING; | ||||||
|  | import static enseirb.myinpulse.model.ProjectDecisionValue.ACTIVE; | ||||||
|  |  | ||||||
|  | import enseirb.myinpulse.model.Entrepreneur; | ||||||
|  | import enseirb.myinpulse.model.Project; | ||||||
|  | import enseirb.myinpulse.model.SectionCell; | ||||||
|  | import enseirb.myinpulse.model.User; | ||||||
|  | import enseirb.myinpulse.service.database.*; | ||||||
|  |  | ||||||
|  | import org.apache.logging.log4j.LogManager; | ||||||
|  | import org.apache.logging.log4j.Logger; | ||||||
|  | import org.springframework.beans.factory.annotation.Autowired; | ||||||
|  | import org.springframework.http.HttpStatus; | ||||||
|  | import org.springframework.stereotype.Service; | ||||||
|  | import org.springframework.web.server.ResponseStatusException; | ||||||
|  |  | ||||||
|  | import java.time.LocalDateTime; | ||||||
|  | import java.util.ArrayList; | ||||||
|  | import java.util.List; | ||||||
|  |  | ||||||
|  | @Service | ||||||
|  | public class EntrepreneurApiService { | ||||||
|  |  | ||||||
|  |     protected static final Logger logger = LogManager.getLogger(); | ||||||
|  |  | ||||||
|  |     private final SectionCellService sectionCellService; | ||||||
|  |     private final ProjectService projectService; | ||||||
|  |     private final UtilsService utilsService; | ||||||
|  |     private final UserService userService; | ||||||
|  |     private final EntrepreneurService entrepreneurService; | ||||||
|  |     private final AdministratorService administratorService; | ||||||
|  |     private final AppointmentService appointmentService; | ||||||
|  |     private final AnnotationService annotationService; | ||||||
|  |  | ||||||
|  |     @Autowired | ||||||
|  |     EntrepreneurApiService( | ||||||
|  |             SectionCellService sectionCellService, | ||||||
|  |             ProjectService projectService, | ||||||
|  |             UtilsService utilsService, | ||||||
|  |             UserService userService, | ||||||
|  |             EntrepreneurService entrepreneurService, | ||||||
|  |             AdministratorService administratorService, | ||||||
|  |             AppointmentService appointmentService, | ||||||
|  |             AnnotationService annotationService) { | ||||||
|  |         this.sectionCellService = sectionCellService; | ||||||
|  |         this.projectService = projectService; | ||||||
|  |         this.utilsService = utilsService; | ||||||
|  |         this.userService = userService; | ||||||
|  |         this.entrepreneurService = entrepreneurService; | ||||||
|  |         this.administratorService = administratorService; | ||||||
|  |         this.appointmentService = appointmentService; | ||||||
|  |         this.annotationService = annotationService; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public void editSectionCell(Long sectionCellId, String content, String mail) { | ||||||
|  |         if (sectionCellId == null) { | ||||||
|  |             logger.warn("Trying to edit unknown section cell"); | ||||||
|  |             throw new ResponseStatusException( | ||||||
|  |                     HttpStatus.NOT_FOUND, "Cette cellule de section n'existe pas"); | ||||||
|  |         } | ||||||
|  |         SectionCell sectionCell = sectionCellService.getSectionCellById(sectionCellId); | ||||||
|  |         if (!utilsService.isAllowedToCheckProject( | ||||||
|  |                 mail, this.sectionCellService.getProjectId(sectionCellId))) { | ||||||
|  |             logger.warn( | ||||||
|  |                     "User {} tried to edit section cells {} of the project {} but is not allowed to.", | ||||||
|  |                     mail, | ||||||
|  |                     sectionCellId, | ||||||
|  |                     this.sectionCellService.getProjectId(sectionCellId)); | ||||||
|  |             throw new ResponseStatusException( | ||||||
|  |                     HttpStatus.UNAUTHORIZED, "You're not allowed to check this project"); | ||||||
|  |         } | ||||||
|  |         logger.info( | ||||||
|  |                 "User {} edited section cell {} of the project with id {}", | ||||||
|  |                 mail, | ||||||
|  |                 sectionCellId, | ||||||
|  |                 this.sectionCellService.getProjectId(sectionCellId)); | ||||||
|  |         SectionCell newSectionCell = | ||||||
|  |                 new SectionCell( | ||||||
|  |                         null, | ||||||
|  |                         sectionCell.getSectionId(), | ||||||
|  |                         content, | ||||||
|  |                         LocalDateTime.now(), | ||||||
|  |                         sectionCell.getProjectSectionCell()); | ||||||
|  |         newSectionCell.setIdReference(sectionCell.getIdReference()); | ||||||
|  |         this.addSectionCell(newSectionCell, mail); | ||||||
|  |         sectionCell | ||||||
|  |                 .getAppointmentSectionCell() | ||||||
|  |                 .forEach( | ||||||
|  |                         appointment -> { | ||||||
|  |                             this.appointmentService.updateAppointmentListSectionCell( | ||||||
|  |                                     appointment.getIdAppointment(), newSectionCell); | ||||||
|  |                         }); | ||||||
|  |         sectionCell | ||||||
|  |                 .getListAnnotation() | ||||||
|  |                 .forEach( | ||||||
|  |                         annotation -> { | ||||||
|  |                             this.annotationService.updateAnnotationSectionCell( | ||||||
|  |                                     annotation.getIdAnnotation(), newSectionCell); | ||||||
|  |                         }); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public void removeSectionCell(Long sectionCellId, String mail) { | ||||||
|  |         if (sectionCellId == null) { | ||||||
|  |             logger.warn("Trying to remove unknown section cell"); | ||||||
|  |             throw new ResponseStatusException( | ||||||
|  |                     HttpStatus.NOT_FOUND, "Cette cellule de section n'existe pas"); | ||||||
|  |         } | ||||||
|  |         SectionCell editSectionCell = sectionCellService.getSectionCellById(sectionCellId); | ||||||
|  |         if (!utilsService.isAllowedToCheckProject( | ||||||
|  |                 mail, this.sectionCellService.getProjectId(sectionCellId))) { | ||||||
|  |             logger.warn( | ||||||
|  |                     "User {} tried to remove section cells {} of the project {} but is not allowed to.", | ||||||
|  |                     mail, | ||||||
|  |                     sectionCellId, | ||||||
|  |                     this.sectionCellService.getProjectId(sectionCellId)); | ||||||
|  |             throw new ResponseStatusException( | ||||||
|  |                     HttpStatus.UNAUTHORIZED, "You're not allowed to check this project"); | ||||||
|  |         } | ||||||
|  |         logger.info( | ||||||
|  |                 "User {} removed section cell {} of the project with id {}", | ||||||
|  |                 mail, | ||||||
|  |                 sectionCellId, | ||||||
|  |                 this.sectionCellService.getProjectId(sectionCellId)); | ||||||
|  |         SectionCell removedSectionCell = | ||||||
|  |                 new SectionCell( | ||||||
|  |                         null, | ||||||
|  |                         -1L, | ||||||
|  |                         "", | ||||||
|  |                         LocalDateTime.now(), | ||||||
|  |                         this.projectService.getProjectById( | ||||||
|  |                                 editSectionCell.getProjectSectionCell().getIdProject())); | ||||||
|  |         sectionCellService.addNewSectionCell(removedSectionCell); | ||||||
|  |         this.sectionCellService.updateSectionCellReferenceId( | ||||||
|  |                 removedSectionCell.getIdSectionCell(), editSectionCell.getIdReference()); | ||||||
|  |         projectService.updateProjectListSectionCell( | ||||||
|  |                 sectionCellService.getProjectId(sectionCellId), removedSectionCell); | ||||||
|  |         // sectionCellService.removeSectionCellById(sectionCellId); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public void addSectionCell(SectionCell sectionCell, String mail) { | ||||||
|  |         if (sectionCell == null) { | ||||||
|  |             logger.warn("Trying to create an empty section cell"); | ||||||
|  |             throw new ResponseStatusException( | ||||||
|  |                     HttpStatus.BAD_REQUEST, "La cellule de section fournie est vide"); | ||||||
|  |         } | ||||||
|  |         if (sectionCell.getSectionId() == -1) { | ||||||
|  |             logger.warn("Trying to create an illegal section cell"); | ||||||
|  |             throw new ResponseStatusException( | ||||||
|  |                     HttpStatus.BAD_REQUEST, "La cellule de section fournie n'est pas valide"); | ||||||
|  |         } | ||||||
|  |         if (!utilsService.isAllowedToCheckProject( | ||||||
|  |                 mail, sectionCell.getProjectSectionCell().getIdProject())) { | ||||||
|  |             logger.warn( | ||||||
|  |                     "User {} tried to add a section cell to the project {} but is not allowed to.", | ||||||
|  |                     mail, | ||||||
|  |                     sectionCell.getProjectSectionCell().getIdProject()); | ||||||
|  |             throw new ResponseStatusException( | ||||||
|  |                     HttpStatus.UNAUTHORIZED, "You're not allowed to check this project"); | ||||||
|  |         } | ||||||
|  |         logger.info( | ||||||
|  |                 "User {} added a new section cell {} to the project {}", | ||||||
|  |                 mail, | ||||||
|  |                 sectionCell.getIdSectionCell(), | ||||||
|  |                 sectionCell.getProjectSectionCell().getIdProject()); | ||||||
|  |         SectionCell newSectionCell = | ||||||
|  |                 sectionCellService.addNewSectionCell( | ||||||
|  |                         sectionCell); // if here, logger fails cause id is null (not added yet) | ||||||
|  |         newSectionCell.getProjectSectionCell().updateListSectionCell(newSectionCell); | ||||||
|  |         newSectionCell | ||||||
|  |                 .getAppointmentSectionCell() | ||||||
|  |                 .forEach( | ||||||
|  |                         appointment -> { | ||||||
|  |                             this.appointmentService.updateAppointmentListSectionCell( | ||||||
|  |                                     appointment.getIdAppointment(), newSectionCell); | ||||||
|  |                         }); | ||||||
|  |         newSectionCell | ||||||
|  |                 .getListAnnotation() | ||||||
|  |                 .forEach( | ||||||
|  |                         annotation -> { | ||||||
|  |                             this.annotationService.updateAnnotationSectionCell( | ||||||
|  |                                     annotation.getIdAnnotation(), newSectionCell); | ||||||
|  |                         }); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public void requestNewProject(Project project, String mail) { | ||||||
|  |         if (project == null) { | ||||||
|  |             logger.warn("Trying to request the creation of a null project"); | ||||||
|  |             throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "Le projet fourni est vide"); | ||||||
|  |         } | ||||||
|  |         logger.info("User {} created a new project named {}", mail, project.getProjectName()); | ||||||
|  |         project.setEntrepreneurProposed((Entrepreneur) this.userService.getUserByEmail(mail)); | ||||||
|  |         projectService.addNewProject(project); | ||||||
|  |         this.projectService.updateProjectStatus(project.getIdProject(), PENDING); | ||||||
|  |         if (project.getProjectAdministrator() != null) { | ||||||
|  |             this.administratorService.updateAdministratorListProject( | ||||||
|  |                     project.getProjectAdministrator().getIdUser(), project); | ||||||
|  |         } | ||||||
|  |         this.entrepreneurService.updateEntrepreneurProjectProposed( | ||||||
|  |                 this.userService.getUserByEmail(mail).getIdUser(), project); | ||||||
|  |         this.entrepreneurService.updateEntrepreneurProjectParticipation( | ||||||
|  |                 this.userService.getUserByEmail(mail).getIdUser(), project); | ||||||
|  |         project.getListEntrepreneurParticipation() | ||||||
|  |                 .forEach( | ||||||
|  |                         entrepreneur -> | ||||||
|  |                                 this.entrepreneurService.updateEntrepreneurProjectParticipation( | ||||||
|  |                                         entrepreneur.getIdUser(), project)); | ||||||
|  |         project.getListSectionCell() | ||||||
|  |                 .forEach( | ||||||
|  |                         sectionCell -> | ||||||
|  |                                 this.sectionCellService.updateSectionCellProject( | ||||||
|  |                                         sectionCell.getIdSectionCell(), project)); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public void createAccount(Entrepreneur e) { | ||||||
|  |         try { | ||||||
|  |             userService.getUserByEmail(e.getPrimaryMail()); | ||||||
|  |             logger.error("The user {} already exists in the system", e.getPrimaryMail()); | ||||||
|  |         } catch (ResponseStatusException err) { | ||||||
|  |             this.entrepreneurService.addEntrepreneur(e); | ||||||
|  |             return; | ||||||
|  |         } | ||||||
|  |         throw new ResponseStatusException(HttpStatus.CONFLICT, "User already exists in the system"); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public Iterable<Project> getProjectIdViaClaim(String email) { | ||||||
|  |         Long UserId = this.userService.getUserByEmail(email).getIdUser(); | ||||||
|  |         Entrepreneur entrepreneur = this.entrepreneurService.getEntrepreneurById(UserId); | ||||||
|  |         List<Project> Project_List = new ArrayList<>(); | ||||||
|  |  | ||||||
|  |         Project_List.add(entrepreneur.getProjectParticipation()); | ||||||
|  |         return Project_List; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public Iterable<Entrepreneur> getAllEntrepreneurs() { | ||||||
|  |         return entrepreneurService.getAllEntrepreneurs(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Checks if an entrepreneur with the given email has a project that is ACTIVE. | ||||||
|  |      * | ||||||
|  |      * @param email The email of the entrepreneur. | ||||||
|  |      * @return true if the entrepreneur has an active project, false otherwise. | ||||||
|  |      */ | ||||||
|  |     public Boolean checkIfEntrepreneurProjectActive(String email) { | ||||||
|  |         User user = this.userService.getUserByEmail(email); | ||||||
|  |         if (user == null) { | ||||||
|  |             return false; | ||||||
|  |         } | ||||||
|  |         Long userId = user.getIdUser(); | ||||||
|  |  | ||||||
|  |         Entrepreneur entrepreneur = this.entrepreneurService.getEntrepreneurById(userId); | ||||||
|  |         if (entrepreneur == null) { | ||||||
|  |             return false; | ||||||
|  |         } | ||||||
|  |         Project proposedProject = entrepreneur.getProjectProposed(); | ||||||
|  |         return proposedProject != null && proposedProject.getProjectStatus() == ACTIVE; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Checks if an entrepreneur with the given email has proposed a project. | ||||||
|  |      * | ||||||
|  |      * @param email The email of the entrepreneur. | ||||||
|  |      * @return true if the entrepreneur has a proposed project, false otherwise. | ||||||
|  |      */ | ||||||
|  |     public Boolean entrepreneurHasPendingRequestedProject(String email) { | ||||||
|  |         User user = this.userService.getUserByEmail(email); | ||||||
|  |         if (user == null) { | ||||||
|  |             return false; | ||||||
|  |         } | ||||||
|  |         Long userId = user.getIdUser(); | ||||||
|  |  | ||||||
|  |         Entrepreneur entrepreneur = this.entrepreneurService.getEntrepreneurById(userId); | ||||||
|  |         if (entrepreneur == null) { | ||||||
|  |             return false; | ||||||
|  |         } | ||||||
|  |         Project proposedProject = entrepreneur.getProjectProposed(); | ||||||
|  |         if (entrepreneur.getProjectProposed() == null) { | ||||||
|  |             return false; | ||||||
|  |         } | ||||||
|  |         return proposedProject.getProjectStatus() == PENDING; | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -0,0 +1,143 @@ | |||||||
|  | package enseirb.myinpulse.service; | ||||||
|  |  | ||||||
|  | import static org.springframework.http.MediaType.APPLICATION_JSON; | ||||||
|  |  | ||||||
|  | import enseirb.myinpulse.exception.UserNotFoundException; | ||||||
|  | import enseirb.myinpulse.model.RoleRepresentation; | ||||||
|  | import enseirb.myinpulse.model.UserRepresentation; | ||||||
|  |  | ||||||
|  | import org.apache.logging.log4j.LogManager; | ||||||
|  | import org.apache.logging.log4j.Logger; | ||||||
|  | import org.springframework.web.client.RestClient; | ||||||
|  |  | ||||||
|  | import java.util.List; | ||||||
|  |  | ||||||
|  | import javax.management.relation.RoleNotFoundException; | ||||||
|  |  | ||||||
|  | public class KeycloakApi { | ||||||
|  |  | ||||||
|  |     protected static final Logger logger = LogManager.getLogger(); | ||||||
|  |     static final String keycloakUrl; | ||||||
|  |     static final String realmName; | ||||||
|  |  | ||||||
|  |     static { | ||||||
|  |         if (System.getenv("VITE_KEYCLOAK_URL") == null) { | ||||||
|  |             System.exit(-1); | ||||||
|  |         } | ||||||
|  |         keycloakUrl = System.getenv("VITE_KEYCLOAK_URL"); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     static { | ||||||
|  |         if (System.getenv("VITE_KEYCLOAK_REALM") == null) { | ||||||
|  |             System.exit(-1); | ||||||
|  |         } | ||||||
|  |         realmName = System.getenv("VITE_KEYCLOAK_REALM"); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     static String toBearer(String b) { | ||||||
|  |         return "Bearer " + b; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Uses Keycloak API to retrieve a role representation of a role by its name | ||||||
|  |      * | ||||||
|  |      * @param roleName name of the role | ||||||
|  |      * @param token authorization header used by the client to authenticate to keycloak | ||||||
|  |      */ | ||||||
|  |     public static RoleRepresentation getRoleRepresentationByName(String roleName, String token) | ||||||
|  |             throws RoleNotFoundException { | ||||||
|  |         RoleRepresentation response = | ||||||
|  |                 RestClient.builder() | ||||||
|  |                         .baseUrl(keycloakUrl) | ||||||
|  |                         .defaultHeader("Authorization", toBearer(token)) | ||||||
|  |                         .build() | ||||||
|  |                         .get() | ||||||
|  |                         .uri("/admin/realms/{realmName}/roles/{roleName}", realmName, roleName) | ||||||
|  |                         .retrieve() | ||||||
|  |                         .body(RoleRepresentation.class); | ||||||
|  |         /* | ||||||
|  |         {"id":"7a845f2e-c832-4465-8cd8-894d72bc13f1","name":"MyINPulse-entrepreneur","description":"Role for entrepreneur","composite":false,"clientRole":false,"containerId":"0d6f691b-e328-471a-b89e-c30bd7e5b6b0","attributes":{}} | ||||||
|  |          */ | ||||||
|  |         // TODO: check what happens when role does not exist | ||||||
|  |         return response; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Use keycloak API to to retreive a userID via his name or email. | ||||||
|  |      * | ||||||
|  |      * @param username username or mail of the user | ||||||
|  |      * @param token bearer of the user, allowing access to database | ||||||
|  |      * @return the userid, as a String | ||||||
|  |      * @throws UserNotFoundException | ||||||
|  |      */ | ||||||
|  |     public static String getUserIdByName(String username, String token) | ||||||
|  |             throws UserNotFoundException { | ||||||
|  |         UserRepresentation[] response = | ||||||
|  |                 RestClient.builder() | ||||||
|  |                         .baseUrl(keycloakUrl) | ||||||
|  |                         .defaultHeader("Authorization", toBearer(token)) | ||||||
|  |                         .build() | ||||||
|  |                         .get() | ||||||
|  |                         .uri( | ||||||
|  |                                 "/admin/realms/{realmName}/users?username={username}", | ||||||
|  |                                 realmName, | ||||||
|  |                                 username) | ||||||
|  |                         .retrieve() | ||||||
|  |                         .body(UserRepresentation[].class); | ||||||
|  |  | ||||||
|  |         if (response == null || response.length == 0) { | ||||||
|  |             throw new UserNotFoundException("User not found"); | ||||||
|  |         } | ||||||
|  |         return response[0].id; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * TODO: check for error | ||||||
|  |      * | ||||||
|  |      * <p>Set a keycloak role to a keycloak user. | ||||||
|  |      * | ||||||
|  |      * <p>Usual roles should be `MyINPulse-admin` and `MyINPulse-entrepreneur` | ||||||
|  |      * | ||||||
|  |      * @param username | ||||||
|  |      * @param roleName | ||||||
|  |      * @param token | ||||||
|  |      * @throws RoleNotFoundException | ||||||
|  |      * @throws UserNotFoundException | ||||||
|  |      */ | ||||||
|  |     public static void setRoleToUser(String username, String roleName, String token) | ||||||
|  |             throws RoleNotFoundException, UserNotFoundException { | ||||||
|  |         RoleRepresentation roleRepresentation = getRoleRepresentationByName(roleName, token); | ||||||
|  |         String userId = getUserIdByName(username, token); | ||||||
|  |         List<RoleRepresentation> rolesToAdd = List.of(roleRepresentation); | ||||||
|  |         logger.debug("Adding role {} to user {}", roleRepresentation.id, userId); | ||||||
|  |         RestClient.builder() | ||||||
|  |                 .baseUrl(keycloakUrl) | ||||||
|  |                 .defaultHeader("Authorization", toBearer(token)) | ||||||
|  |                 .build() | ||||||
|  |                 .post() | ||||||
|  |                 .uri("/admin/realms/" + realmName + "/users/" + userId + "/role-mappings/realm") | ||||||
|  |                 .body(rolesToAdd) | ||||||
|  |                 .contentType(APPLICATION_JSON) | ||||||
|  |                 .retrieve() | ||||||
|  |                 .toBodilessEntity(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Delete a user from Keycloak database. TODO: check the bearer permission. | ||||||
|  |      * | ||||||
|  |      * @param username | ||||||
|  |      * @param bearer | ||||||
|  |      * @throws UserNotFoundException | ||||||
|  |      */ | ||||||
|  |     public static void deleteUser(String username, String bearer) throws UserNotFoundException { | ||||||
|  |         String userId = getUserIdByName(username, bearer); | ||||||
|  |  | ||||||
|  |         RestClient.builder() | ||||||
|  |                 .baseUrl(keycloakUrl) | ||||||
|  |                 .defaultHeader("Authorization", bearer) | ||||||
|  |                 .build() | ||||||
|  |                 .delete() | ||||||
|  |                 .uri("/admin/realms/${realmName}/users/${userId}", realmName, userId) | ||||||
|  |                 .retrieve(); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -0,0 +1,324 @@ | |||||||
|  | package enseirb.myinpulse.service; | ||||||
|  |  | ||||||
|  | import com.itextpdf.text.*; | ||||||
|  | import com.itextpdf.text.pdf.PdfWriter; | ||||||
|  | import enseirb.myinpulse.controller.AdminApi; | ||||||
|  | import enseirb.myinpulse.controller.EntrepreneurApi; | ||||||
|  | import enseirb.myinpulse.model.*; | ||||||
|  | import enseirb.myinpulse.service.database.*; | ||||||
|  |  | ||||||
|  | import org.apache.logging.log4j.LogManager; | ||||||
|  | import org.apache.logging.log4j.Logger; | ||||||
|  | import org.springframework.beans.factory.annotation.Autowired; | ||||||
|  | import org.springframework.http.HttpStatus; | ||||||
|  | import org.springframework.stereotype.Service; | ||||||
|  | import org.springframework.web.server.ResponseStatusException; | ||||||
|  |  | ||||||
|  | import java.io.File; | ||||||
|  | import java.io.FileOutputStream; | ||||||
|  | import java.io.IOException; | ||||||
|  | import java.net.URI; | ||||||
|  | import java.net.URISyntaxException; | ||||||
|  | import java.nio.file.Files; | ||||||
|  | import java.nio.file.Paths; | ||||||
|  | import java.nio.file.StandardCopyOption; | ||||||
|  | import java.time.LocalDateTime; | ||||||
|  | import java.time.format.DateTimeFormatter; | ||||||
|  | import java.util.ArrayList; | ||||||
|  | import java.util.HashMap; | ||||||
|  | import java.util.HashSet; | ||||||
|  | import java.util.List; | ||||||
|  | import java.util.Map; | ||||||
|  | import java.util.Set; | ||||||
|  |  | ||||||
|  | @Service | ||||||
|  | public class SharedApiService { | ||||||
|  |  | ||||||
|  |     private final AdminApi adminApi; | ||||||
|  |  | ||||||
|  |     private final EntrepreneurApi entrepreneurApi; | ||||||
|  |  | ||||||
|  |     protected static final Logger logger = LogManager.getLogger(); | ||||||
|  |  | ||||||
|  |     private final ProjectService projectService; | ||||||
|  |     private final EntrepreneurService entrepreneurService; | ||||||
|  |     private final SectionCellService sectionCellService; | ||||||
|  |     private final AppointmentService appointmentService; | ||||||
|  |  | ||||||
|  |     private final UtilsService utilsService; | ||||||
|  |  | ||||||
|  |     @Autowired | ||||||
|  |     SharedApiService( | ||||||
|  |             ProjectService projectService, | ||||||
|  |             EntrepreneurService entrepreneurService, | ||||||
|  |             SectionCellService sectionCellService, | ||||||
|  |             AppointmentService appointmentService, | ||||||
|  |             UtilsService utilsService, | ||||||
|  |             EntrepreneurApi entrepreneurApi, | ||||||
|  |             AdminApi adminApi) { | ||||||
|  |         this.projectService = projectService; | ||||||
|  |         this.entrepreneurService = entrepreneurService; | ||||||
|  |         this.sectionCellService = sectionCellService; | ||||||
|  |         this.appointmentService = appointmentService; | ||||||
|  |         this.utilsService = utilsService; | ||||||
|  |         this.entrepreneurApi = entrepreneurApi; | ||||||
|  |         this.adminApi = adminApi; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     // TODO filter this with date | ||||||
|  |     public Iterable<SectionCell> getSectionCells( | ||||||
|  |             long projectId, long sectionId, String date, String mail) { | ||||||
|  |  | ||||||
|  |         if (!utilsService.isAllowedToCheckProject(mail, projectId)) { | ||||||
|  |             logger.warn( | ||||||
|  |                     "User {} tried to check section cells of the project {} but is not allowed to.", | ||||||
|  |                     mail, | ||||||
|  |                     projectId); | ||||||
|  |             throw new ResponseStatusException( | ||||||
|  |                     HttpStatus.UNAUTHORIZED, "You're not allowed to check this project"); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm"); | ||||||
|  |         LocalDateTime dateTime = LocalDateTime.parse(date, formatter); | ||||||
|  |  | ||||||
|  |         Project project = this.projectService.getProjectById(projectId); | ||||||
|  |         return this.sectionCellService.getLatestSectionCellsByIdReferenceBeforeDate( | ||||||
|  |                 project, sectionId, dateTime); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     // Retrieve all up to date (for every sectionId) sectionCells of a project | ||||||
|  |     public Iterable<SectionCell> getAllSectionCells(long projectId, String mail) { | ||||||
|  |         if (!utilsService.isAllowedToCheckProject(mail, projectId)) { | ||||||
|  |             logger.warn( | ||||||
|  |                     "User {} tried to check section cells of the project {} but is not allowed to.", | ||||||
|  |                     mail, | ||||||
|  |                     projectId); | ||||||
|  |             throw new ResponseStatusException( | ||||||
|  |                     HttpStatus.UNAUTHORIZED, "You're not allowed to check this project"); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         Project project = this.projectService.getProjectById(projectId); | ||||||
|  |  | ||||||
|  |         Map<Long, SectionCell> latestSectionCellsMap = | ||||||
|  |                 new HashMap<>(); // List for the intermediate result | ||||||
|  |  | ||||||
|  |         // Iterate through all SectionCells associated with the project | ||||||
|  |         // This loop iterates over project.getListSectionCell() but does NOT modify it which causes | ||||||
|  |         // ConcurrentModificationException. | ||||||
|  |         // Modifications are done only on the latestSectionCellsMap (which is safe). | ||||||
|  |         project.getListSectionCell() // <-- Iterating over the original list (read-only) | ||||||
|  |                 .forEach( | ||||||
|  |                         projectCell -> { | ||||||
|  |                             Long idReference = projectCell.getIdReference(); | ||||||
|  |                             // Check if we have already seen a SectionCell with this idReference in | ||||||
|  |                             // our map | ||||||
|  |                             if (latestSectionCellsMap.containsKey(idReference)) { | ||||||
|  |                                 SectionCell existingCell = latestSectionCellsMap.get(idReference); | ||||||
|  |                                 // Compare modification dates. If the current cell is newer, replace | ||||||
|  |                                 // the one in the map. | ||||||
|  |                                 if (projectCell | ||||||
|  |                                         .getModificationDate() | ||||||
|  |                                         .isAfter(existingCell.getModificationDate())) { | ||||||
|  |                                     latestSectionCellsMap.put(idReference, projectCell); | ||||||
|  |                                 } | ||||||
|  |                             } else { | ||||||
|  |                                 // If this is the first time we encounter this idReference, add the | ||||||
|  |                                 // cell to the map. | ||||||
|  |                                 latestSectionCellsMap.put(idReference, projectCell); | ||||||
|  |                             } | ||||||
|  |                         }); | ||||||
|  |         return new ArrayList<>(latestSectionCellsMap.values()); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     // TODO: test | ||||||
|  |     public Iterable<Entrepreneur> getEntrepreneursByProjectId(long projectId, String mail) { | ||||||
|  |         if (!utilsService.isAllowedToCheckProject(mail, projectId)) { | ||||||
|  |             logger.warn( | ||||||
|  |                     "User {} tried to check the member of the project {} but is not allowed to.", | ||||||
|  |                     mail, | ||||||
|  |                     projectId); | ||||||
|  |             throw new ResponseStatusException( | ||||||
|  |                     HttpStatus.UNAUTHORIZED, "You're not allowed to check this project"); | ||||||
|  |         } | ||||||
|  |         Project project = this.projectService.getProjectById(projectId); | ||||||
|  |         return this.entrepreneurService.GetEntrepreneurByProject(project); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     // TODO: test | ||||||
|  |     public Administrator getAdminByProjectId(long projectId, String mail) { | ||||||
|  |         if (!utilsService.isAllowedToCheckProject(mail, projectId)) { | ||||||
|  |             logger.warn( | ||||||
|  |                     "User {} tried to check the admin of the project {} but is not allowed to.", | ||||||
|  |                     mail, | ||||||
|  |                     projectId); | ||||||
|  |             throw new ResponseStatusException( | ||||||
|  |                     HttpStatus.UNAUTHORIZED, "You're not allowed to check this project"); | ||||||
|  |         } | ||||||
|  |         Project project = this.projectService.getProjectById(projectId); | ||||||
|  |         return project.getProjectAdministrator(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public Iterable<Appointment> getAppointmentsByProjectId(long projectId, String mail) { | ||||||
|  |         if (!utilsService.isAllowedToCheckProject(mail, projectId)) { | ||||||
|  |             logger.warn( | ||||||
|  |                     "User {} tried to check the appointments related to the project {} but is not allowed to.", | ||||||
|  |                     mail, | ||||||
|  |                     projectId); | ||||||
|  |             throw new ResponseStatusException( | ||||||
|  |                     HttpStatus.UNAUTHORIZED, "You're not allowed to check this project"); | ||||||
|  |         } | ||||||
|  |         logger.info( | ||||||
|  |                 "User {} tried to check the appointments related to the project {}", | ||||||
|  |                 mail, | ||||||
|  |                 projectId); | ||||||
|  |  | ||||||
|  |         Project project = projectService.getProjectById(projectId); | ||||||
|  |  | ||||||
|  |         Iterable<SectionCell> sectionCellsIterable = | ||||||
|  |                 this.sectionCellService.getSectionCellsByProject(project); | ||||||
|  |  | ||||||
|  |         // Use a Set to collect unique appointments | ||||||
|  |         Set<Appointment> uniqueAppointments = new HashSet<>(); | ||||||
|  |  | ||||||
|  |         sectionCellsIterable.forEach( | ||||||
|  |                 sectionCell -> { | ||||||
|  |                     List<Appointment> sectionAppointments = | ||||||
|  |                             this.sectionCellService.getAppointmentsBySectionCellId( | ||||||
|  |                                     sectionCell.getIdSectionCell()); | ||||||
|  |                     // Add all appointments from this section cell to the Set | ||||||
|  |                     uniqueAppointments.addAll(sectionAppointments); | ||||||
|  |                 }); | ||||||
|  |  | ||||||
|  |         // Convert the Set back to a List for the return value | ||||||
|  |         return new ArrayList<>(uniqueAppointments); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public void getPDFReport(long appointmentId, String mail) | ||||||
|  |             throws DocumentException, URISyntaxException, IOException { | ||||||
|  |         long projectId = | ||||||
|  |                 this.appointmentService | ||||||
|  |                         .getAppointmentById(appointmentId) | ||||||
|  |                         .getAppointmentListSectionCell() | ||||||
|  |                         .getFirst() | ||||||
|  |                         .getProjectSectionCell() | ||||||
|  |                         .getIdProject(); | ||||||
|  |         if (!utilsService.isAllowedToCheckProject(mail, projectId)) { | ||||||
|  |             logger.warn( | ||||||
|  |                     "User {} tried to generate the PDF report {} related to the appointment {} but is not allowed to.", | ||||||
|  |                     mail, | ||||||
|  |                     this.appointmentService | ||||||
|  |                             .getAppointmentById(appointmentId) | ||||||
|  |                             .getAppointmentReport() | ||||||
|  |                             .getIdReport(), | ||||||
|  |                     appointmentId); | ||||||
|  |             throw new ResponseStatusException( | ||||||
|  |                     HttpStatus.UNAUTHORIZED, "You're not allowed to check this project"); | ||||||
|  |         } | ||||||
|  |         logger.info( | ||||||
|  |                 "User {} generated the PDF report related to appointment {}", mail, appointmentId); | ||||||
|  |  | ||||||
|  |         String reportContent = | ||||||
|  |                 this.appointmentService | ||||||
|  |                         .getAppointmentById(appointmentId) | ||||||
|  |                         .getAppointmentReport() | ||||||
|  |                         .getReportContent(); | ||||||
|  |  | ||||||
|  |         // PDF generation | ||||||
|  |         Document document = new Document(); | ||||||
|  |         PdfWriter.getInstance(document, new FileOutputStream("Report" + appointmentId + ".pdf")); | ||||||
|  |         document.open(); | ||||||
|  |  | ||||||
|  |         Paragraph title = | ||||||
|  |                 new Paragraph( | ||||||
|  |                         new Phrase( | ||||||
|  |                                 "Compte Rendu - Réunion du " | ||||||
|  |                                         + this.appointmentService | ||||||
|  |                                                 .getAppointmentById(appointmentId) | ||||||
|  |                                                 .getAppointmentDate() | ||||||
|  |                                                 .toString(), | ||||||
|  |                                 FontFactory.getFont( | ||||||
|  |                                         FontFactory.HELVETICA, | ||||||
|  |                                         20, | ||||||
|  |                                         Font.BOLDITALIC, | ||||||
|  |                                         BaseColor.BLACK))); | ||||||
|  |         title.setAlignment(Element.ALIGN_CENTER); | ||||||
|  |         document.add(title); | ||||||
|  |  | ||||||
|  |         Font subsection = | ||||||
|  |                 FontFactory.getFont(FontFactory.HELVETICA, 14, Font.UNDERLINE, BaseColor.DARK_GRAY); | ||||||
|  |         Font body = FontFactory.getFont(FontFactory.COURIER, 12, BaseColor.BLACK); | ||||||
|  |  | ||||||
|  |         String[] split = reportContent.split(" "); | ||||||
|  |  | ||||||
|  |         String tmp = ""; | ||||||
|  |         int counter = 1; | ||||||
|  |         for (String s : split) { | ||||||
|  |             if (s.equals("//")) { | ||||||
|  |                 Chunk chunk = new Chunk(tmp, body); | ||||||
|  |                 document.add(chunk); | ||||||
|  |                 document.add(new Paragraph("\n")); | ||||||
|  |                 tmp = ""; | ||||||
|  |                 Paragraph paragraph = new Paragraph("Point n°" + counter + " : ", subsection); | ||||||
|  |                 document.add(paragraph); | ||||||
|  |                 document.add(new Paragraph("\n")); | ||||||
|  |                 counter++; | ||||||
|  |             } else { | ||||||
|  |                 tmp = tmp.concat(s + " "); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         Chunk chunk = new Chunk(tmp, body); | ||||||
|  |         document.add(chunk); | ||||||
|  |         document.add(new Paragraph("\n")); | ||||||
|  |  | ||||||
|  |         document.close(); | ||||||
|  |  | ||||||
|  |         // Replace uri with website address | ||||||
|  |         Files.copy( | ||||||
|  |                 new URI( | ||||||
|  |                                 "http://localhost:8080/shared/projects/appointments/report/" | ||||||
|  |                                         + appointmentId) | ||||||
|  |                         .toURL() | ||||||
|  |                         .openStream(), | ||||||
|  |                 Paths.get("Report" + appointmentId + ".pdf"), | ||||||
|  |                 StandardCopyOption.REPLACE_EXISTING); | ||||||
|  |  | ||||||
|  |         // delete file, we don't want to stock all reports on the server | ||||||
|  |         File file = new File("Report" + appointmentId + ".pdf"); | ||||||
|  |         if (!file.delete()) { | ||||||
|  |             logger.warn("Failed to delete report {}", file.getAbsolutePath()); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public void createAppointmentRequest(Appointment appointment, String mail) { | ||||||
|  |         long projectId = | ||||||
|  |                 appointment | ||||||
|  |                         .getAppointmentListSectionCell() | ||||||
|  |                         .getFirst() | ||||||
|  |                         .getProjectSectionCell() | ||||||
|  |                         .getIdProject(); | ||||||
|  |         if (!utilsService.isAllowedToCheckProject(mail, projectId)) { | ||||||
|  |             logger.warn( | ||||||
|  |                     "User {} tried to create for the project {} but is not allowed to.", | ||||||
|  |                     mail, | ||||||
|  |                     projectId); | ||||||
|  |             throw new ResponseStatusException( | ||||||
|  |                     HttpStatus.UNAUTHORIZED, "You're not allowed to check this project"); | ||||||
|  |         } | ||||||
|  |         logger.info("User {} tried to create an appointment for project {}", mail, projectId); | ||||||
|  |         Appointment newAppointment = this.appointmentService.addNewAppointment(appointment); | ||||||
|  |         newAppointment | ||||||
|  |                 .getAppointmentListSectionCell() | ||||||
|  |                 .forEach( | ||||||
|  |                         sectionCell -> { | ||||||
|  |                             sectionCell.updateAppointmentSectionCell(newAppointment); | ||||||
|  |                         }); | ||||||
|  |  | ||||||
|  |         /* | ||||||
|  |          * On initial insertion, the resport value is null unless that report does already exist in the db somewhere | ||||||
|  |          * If a non null value is passed and it does not exist in db it will throw an exception | ||||||
|  |          */ | ||||||
|  |         if (newAppointment.getAppointmentReport() != null) { | ||||||
|  |             newAppointment.getAppointmentReport().setAppointmentReport(newAppointment); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -0,0 +1,81 @@ | |||||||
|  | package enseirb.myinpulse.service; | ||||||
|  |  | ||||||
|  | import enseirb.myinpulse.model.Administrator; | ||||||
|  | import enseirb.myinpulse.model.Entrepreneur; | ||||||
|  | import enseirb.myinpulse.model.Project; | ||||||
|  | import enseirb.myinpulse.model.User; | ||||||
|  | import enseirb.myinpulse.service.database.AdministratorService; | ||||||
|  | import enseirb.myinpulse.service.database.EntrepreneurService; | ||||||
|  | import enseirb.myinpulse.service.database.ProjectService; | ||||||
|  | import enseirb.myinpulse.service.database.UserService; | ||||||
|  |  | ||||||
|  | import org.apache.logging.log4j.LogManager; | ||||||
|  | import org.apache.logging.log4j.Logger; | ||||||
|  | import org.springframework.beans.factory.annotation.Autowired; | ||||||
|  | import org.springframework.stereotype.Service; | ||||||
|  | import org.springframework.web.server.ResponseStatusException; | ||||||
|  |  | ||||||
|  | import java.util.Objects; | ||||||
|  |  | ||||||
|  | @Service | ||||||
|  | public class UtilsService { | ||||||
|  |  | ||||||
|  |     protected static final Logger logger = LogManager.getLogger(); | ||||||
|  |  | ||||||
|  |     private final UserService userService; | ||||||
|  |     private final ProjectService projectService; | ||||||
|  |     private final EntrepreneurService entrepreneurService; | ||||||
|  |     private final AdministratorService administratorService; | ||||||
|  |  | ||||||
|  |     @Autowired | ||||||
|  |     UtilsService( | ||||||
|  |             ProjectService projectService, | ||||||
|  |             UserService userService, | ||||||
|  |             EntrepreneurService entrepreneurService, | ||||||
|  |             AdministratorService administratorService) { | ||||||
|  |         this.userService = userService; | ||||||
|  |         this.projectService = projectService; | ||||||
|  |         this.entrepreneurService = entrepreneurService; | ||||||
|  |         this.administratorService = administratorService; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     // TODO: test? | ||||||
|  |     public Boolean isAllowedToCheckProject(String mail, long projectId) { | ||||||
|  |         if (isAnAdmin(mail)) { | ||||||
|  |             return true; | ||||||
|  |         } | ||||||
|  |         User user = this.userService.getUserByEmail(mail); | ||||||
|  |         Entrepreneur entrepreneur = this.entrepreneurService.getEntrepreneurById(user.getIdUser()); | ||||||
|  |         if (entrepreneur == null) { | ||||||
|  |             logger.debug("testing access with an unknown Entrepreneur"); | ||||||
|  |             return false; | ||||||
|  |         } | ||||||
|  |         if (entrepreneur.getProjectParticipation() == null) { | ||||||
|  |             logger.debug("testing access with an user with no project participation"); | ||||||
|  |             return false; | ||||||
|  |         } | ||||||
|  |         Project project = this.projectService.getProjectById(projectId); | ||||||
|  |         // We compare the ID instead of the project themselves | ||||||
|  |         return Objects.equals( | ||||||
|  |                 entrepreneur.getProjectParticipation().getIdProject(), project.getIdProject()); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     // TODO: test | ||||||
|  |     public Boolean isAnAdmin(String mail) { | ||||||
|  |         try { | ||||||
|  |             long userId = this.userService.getUserByEmail(mail).getIdUser(); | ||||||
|  |             Administrator a = this.administratorService.getAdministratorById(userId); | ||||||
|  |             return true; | ||||||
|  |         } catch (ResponseStatusException e) { | ||||||
|  |             logger.info(e); | ||||||
|  |  | ||||||
|  |             return false; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public Boolean checkEntrepreneurNotPending(String email) { | ||||||
|  |         // Throws 404 if user not found | ||||||
|  |         User user = userService.getUserByEmail(email); | ||||||
|  |         return !user.isPending(); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -0,0 +1,106 @@ | |||||||
|  | package enseirb.myinpulse.service.database; | ||||||
|  |  | ||||||
|  | import enseirb.myinpulse.model.Administrator; | ||||||
|  | import enseirb.myinpulse.model.Annotation; | ||||||
|  | import enseirb.myinpulse.model.MakeAppointment; | ||||||
|  | import enseirb.myinpulse.model.Project; | ||||||
|  | import enseirb.myinpulse.repository.AdministratorRepository; | ||||||
|  |  | ||||||
|  | import org.apache.logging.log4j.LogManager; | ||||||
|  | import org.apache.logging.log4j.Logger; | ||||||
|  | import org.springframework.beans.factory.annotation.Autowired; | ||||||
|  | import org.springframework.http.HttpStatus; | ||||||
|  | import org.springframework.stereotype.Service; | ||||||
|  | import org.springframework.web.server.ResponseStatusException; | ||||||
|  |  | ||||||
|  | import java.util.Optional; | ||||||
|  |  | ||||||
|  | @Service | ||||||
|  | public class AdministratorService { | ||||||
|  |     protected static final Logger logger = LogManager.getLogger(); | ||||||
|  |  | ||||||
|  |     private final AdministratorRepository administratorRepository; | ||||||
|  |  | ||||||
|  |     @Autowired | ||||||
|  |     AdministratorService(AdministratorRepository administratorRepository) { | ||||||
|  |         this.administratorRepository = administratorRepository; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public Iterable<Administrator> allAdministrators() { | ||||||
|  |         return this.administratorRepository.findAll(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public Administrator getAdministratorById(long id) { | ||||||
|  |         Optional<Administrator> administrator = this.administratorRepository.findById(id); | ||||||
|  |         if (administrator.isEmpty()) { | ||||||
|  |             logger.error("No administrator found with id {}", id); | ||||||
|  |             throw new ResponseStatusException( | ||||||
|  |                     HttpStatus.NOT_FOUND, "Cet administrateur n'existe pas"); | ||||||
|  |         } | ||||||
|  |         return administrator.get(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public Administrator getAdministratorByPrimaryMain(String primaryMail) { | ||||||
|  |         Optional<Administrator> administrator = | ||||||
|  |                 this.administratorRepository.findByPrimaryMail(primaryMail); | ||||||
|  |         if (administrator.isEmpty()) { | ||||||
|  |             logger.error("No administrator found with the mail {}", primaryMail); | ||||||
|  |             throw new ResponseStatusException( | ||||||
|  |                     HttpStatus.NOT_FOUND, "Cet administrateur n'existe pas"); | ||||||
|  |         } | ||||||
|  |         return administrator.get(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public Administrator addAdministrator(Administrator administrator) { | ||||||
|  |         return this.administratorRepository.save(administrator); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public void updateAdministratorListProject(long idAdministrator, Project project) { | ||||||
|  |         Administrator administrator = getAdministratorById(idAdministrator); | ||||||
|  |         administrator.updateListProject(project); | ||||||
|  |         this.administratorRepository.save(administrator); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public void updateAdministratorListAnnotation(long idAdministrator, Annotation annotation) { | ||||||
|  |         Administrator administrator = getAdministratorById(idAdministrator); | ||||||
|  |         administrator.updateListAnnotation(annotation); | ||||||
|  |         this.administratorRepository.save(administrator); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public void updateAdministratorMakeAppointment( | ||||||
|  |             long idAdministrator, MakeAppointment makeAppointment) { | ||||||
|  |         Administrator administrator = getAdministratorById(idAdministrator); | ||||||
|  |         administrator.setMakeAppointment(makeAppointment); | ||||||
|  |         this.administratorRepository.save(administrator); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public Administrator updateAdministrator( | ||||||
|  |             Long idAdministrator, | ||||||
|  |             Project project, | ||||||
|  |             Annotation annotation, | ||||||
|  |             MakeAppointment makeAppointment) { | ||||||
|  |         Optional<Administrator> administrator = administratorRepository.findById(idAdministrator); | ||||||
|  |         if (administrator.isEmpty()) { | ||||||
|  |             logger.error( | ||||||
|  |                     "updateAdministrator : No administrator found with id {}", idAdministrator); | ||||||
|  |             throw new ResponseStatusException( | ||||||
|  |                     HttpStatus.NOT_FOUND, "Cet administrateur n'existe pas"); | ||||||
|  |         } | ||||||
|  |         if (project != null) { | ||||||
|  |             administrator.get().updateListProject(project); | ||||||
|  |         } | ||||||
|  |         if (annotation != null) { | ||||||
|  |             administrator.get().updateListAnnotation(annotation); | ||||||
|  |         } | ||||||
|  |         if (makeAppointment != null) { | ||||||
|  |             administrator.get().setMakeAppointment(makeAppointment); | ||||||
|  |         } | ||||||
|  |         return this.administratorRepository.save(administrator.get()); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /* | ||||||
|  |     public Administrator getAdministratorByProject(Project project) { | ||||||
|  |         r | ||||||
|  |     } | ||||||
|  |      */ | ||||||
|  | } | ||||||
| @@ -0,0 +1,81 @@ | |||||||
|  | package enseirb.myinpulse.service.database; | ||||||
|  |  | ||||||
|  | import enseirb.myinpulse.model.Administrator; | ||||||
|  | import enseirb.myinpulse.model.Annotation; | ||||||
|  | import enseirb.myinpulse.model.SectionCell; | ||||||
|  | import enseirb.myinpulse.repository.AnnotationRepository; | ||||||
|  |  | ||||||
|  | import org.apache.logging.log4j.LogManager; | ||||||
|  | import org.apache.logging.log4j.Logger; | ||||||
|  | import org.springframework.beans.factory.annotation.Autowired; | ||||||
|  | import org.springframework.http.HttpStatus; | ||||||
|  | import org.springframework.stereotype.Service; | ||||||
|  | import org.springframework.web.server.ResponseStatusException; | ||||||
|  |  | ||||||
|  | import java.util.Optional; | ||||||
|  |  | ||||||
|  | @Service | ||||||
|  | public class AnnotationService { | ||||||
|  |  | ||||||
|  |     protected static final Logger logger = LogManager.getLogger(); | ||||||
|  |  | ||||||
|  |     private final AnnotationRepository annotationRepository; | ||||||
|  |  | ||||||
|  |     @Autowired | ||||||
|  |     AnnotationService(AnnotationRepository annotationRepository) { | ||||||
|  |         this.annotationRepository = annotationRepository; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public Iterable<Annotation> getAllAnnotations() { | ||||||
|  |         return annotationRepository.findAll(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public Annotation getAnnotationById(Long id) { | ||||||
|  |         Optional<Annotation> annotation = annotationRepository.findById(id); | ||||||
|  |         if (annotation.isEmpty()) { | ||||||
|  |             logger.error("getAnnotationById : No annotation found with id {}", id); | ||||||
|  |             throw new ResponseStatusException( | ||||||
|  |                     HttpStatus.NOT_FOUND, "Cette annotation n'existe pas"); | ||||||
|  |         } | ||||||
|  |         return annotation.get(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public Annotation addNewAnnotation(Annotation annotation) { | ||||||
|  |         return this.annotationRepository.save(annotation); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public void deleteAnnotationById(Long id) { | ||||||
|  |         this.annotationRepository.deleteById(id); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public void updateAnnotationComment(long idAnnotation, String comment) { | ||||||
|  |         Annotation annotation = getAnnotationById(idAnnotation); | ||||||
|  |         annotation.setComment(comment); | ||||||
|  |         this.annotationRepository.save(annotation); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public Annotation updateAnnotation(Long id, String comment) { | ||||||
|  |         Optional<Annotation> annotation = annotationRepository.findById(id); | ||||||
|  |         if (annotation.isEmpty()) { | ||||||
|  |             logger.error("updateAnnotation : No annotation found with id {}", id); | ||||||
|  |             throw new ResponseStatusException( | ||||||
|  |                     HttpStatus.NOT_FOUND, "Cette annotation n'existe pas"); | ||||||
|  |         } | ||||||
|  |         if (comment != null) { | ||||||
|  |             annotation.get().setComment(comment); | ||||||
|  |         } | ||||||
|  |         return this.annotationRepository.save(annotation.get()); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public void updateAnnotationSectionCell(long idAnnotation, SectionCell sectionCell) { | ||||||
|  |         Annotation annotation = getAnnotationById(idAnnotation); | ||||||
|  |         annotation.setSectionCellAnnotation(sectionCell); | ||||||
|  |         this.annotationRepository.save(annotation); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public void updateAnnotationAdministrator(long idAnnotation, Administrator administrator) { | ||||||
|  |         Annotation annotation = getAnnotationById(idAnnotation); | ||||||
|  |         annotation.setAdministratorAnnotation(administrator); | ||||||
|  |         this.annotationRepository.save(annotation); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -0,0 +1,120 @@ | |||||||
|  | package enseirb.myinpulse.service.database; | ||||||
|  |  | ||||||
|  | import enseirb.myinpulse.model.Appointment; | ||||||
|  | import enseirb.myinpulse.model.SectionCell; | ||||||
|  | import enseirb.myinpulse.repository.AppointmentRepository; | ||||||
|  |  | ||||||
|  | import org.apache.logging.log4j.LogManager; | ||||||
|  | import org.apache.logging.log4j.Logger; | ||||||
|  | import org.springframework.beans.factory.annotation.Autowired; | ||||||
|  | import org.springframework.http.HttpStatus; | ||||||
|  | import org.springframework.stereotype.Service; | ||||||
|  | import org.springframework.web.server.ResponseStatusException; | ||||||
|  |  | ||||||
|  | import java.time.LocalDate; | ||||||
|  | import java.time.LocalTime; | ||||||
|  | import java.util.Optional; | ||||||
|  |  | ||||||
|  | @Service | ||||||
|  | public class AppointmentService { | ||||||
|  |  | ||||||
|  |     private static final Logger logger = LogManager.getLogger(AppointmentService.class); | ||||||
|  |  | ||||||
|  |     private AppointmentRepository appointmentRepository; | ||||||
|  |  | ||||||
|  |     @Autowired | ||||||
|  |     AppointmentService(AppointmentRepository appointmentRepository) { | ||||||
|  |         this.appointmentRepository = appointmentRepository; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public Iterable<Appointment> getallAppointments() { | ||||||
|  |         return this.appointmentRepository.findAll(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public Appointment getAppointmentById(Long id) { | ||||||
|  |         Optional<Appointment> appointment = this.appointmentRepository.findById(id); | ||||||
|  |         if (appointment.isEmpty()) { | ||||||
|  |             logger.error("getAppointmentById : No appointment found with id {}", id); | ||||||
|  |             throw new ResponseStatusException(HttpStatus.NOT_FOUND, "Ce rendez vous n'existe pas"); | ||||||
|  |         } | ||||||
|  |         return appointment.get(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public Appointment addNewAppointment(Appointment appointment) { | ||||||
|  |         return this.appointmentRepository.save(appointment); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public void deleteAppointmentById(Long id) { | ||||||
|  |         this.appointmentRepository.deleteById(id); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public void updateAppointmentDate(long idAppointment, LocalDate date) { | ||||||
|  |         Appointment appointment = getAppointmentById(idAppointment); | ||||||
|  |         appointment.setAppointmentDate(date); | ||||||
|  |         this.appointmentRepository.save(appointment); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public void updateAppointmentTime(long idAppointment, LocalTime time) { | ||||||
|  |         Appointment appointment = getAppointmentById(idAppointment); | ||||||
|  |         appointment.setAppointmentTime(time); | ||||||
|  |         this.appointmentRepository.save(appointment); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public void updateAppointmentDuration(long idAppointment, LocalTime duration) { | ||||||
|  |         Appointment appointment = getAppointmentById(idAppointment); | ||||||
|  |         appointment.setAppointmentDuration(duration); | ||||||
|  |         this.appointmentRepository.save(appointment); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public void updateAppointmentPlace(long idAppointment, String place) { | ||||||
|  |         Appointment appointment = getAppointmentById(idAppointment); | ||||||
|  |         appointment.setAppointmentPlace(place); | ||||||
|  |         this.appointmentRepository.save(appointment); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public void updateAppointmentSubject(long idAppointment, String subject) { | ||||||
|  |         Appointment appointment = getAppointmentById(idAppointment); | ||||||
|  |         appointment.setAppointmentSubject(subject); | ||||||
|  |         this.appointmentRepository.save(appointment); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public void updateAppointmentListSectionCell(long idAppointment, SectionCell sectionCell) { | ||||||
|  |         Appointment appointment = getAppointmentById(idAppointment); | ||||||
|  |         appointment.updateListSectionCell(sectionCell); | ||||||
|  |         this.appointmentRepository.save(appointment); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public Appointment updateAppointment( | ||||||
|  |             Long id, | ||||||
|  |             LocalDate appointmentDate, | ||||||
|  |             LocalTime appointmentTime, | ||||||
|  |             LocalTime appointmentDuration, | ||||||
|  |             String appointmentPlace, | ||||||
|  |             String appointmentSubject, | ||||||
|  |             SectionCell sectionCell) { | ||||||
|  |         Optional<Appointment> appointment = this.appointmentRepository.findById(id); | ||||||
|  |         if (appointment.isEmpty()) { | ||||||
|  |             logger.error("updateAppointment : No appointment found with id {}", id); | ||||||
|  |             throw new ResponseStatusException(HttpStatus.NOT_FOUND, "Ce rendez vous n'existe pas"); | ||||||
|  |         } | ||||||
|  |         if (appointmentDate != null) { | ||||||
|  |             appointment.get().setAppointmentDate(appointmentDate); | ||||||
|  |         } | ||||||
|  |         if (appointmentTime != null) { | ||||||
|  |             appointment.get().setAppointmentTime(appointmentTime); | ||||||
|  |         } | ||||||
|  |         if (appointmentDuration != null) { | ||||||
|  |             appointment.get().setAppointmentDuration(appointmentDuration); | ||||||
|  |         } | ||||||
|  |         if (appointmentPlace != null) { | ||||||
|  |             appointment.get().setAppointmentPlace(appointmentPlace); | ||||||
|  |         } | ||||||
|  |         if (appointmentSubject != null) { | ||||||
|  |             appointment.get().setAppointmentSubject(appointmentSubject); | ||||||
|  |         } | ||||||
|  |         if (sectionCell != null) { | ||||||
|  |             appointment.get().updateListSectionCell(sectionCell); | ||||||
|  |         } | ||||||
|  |         return this.appointmentRepository.save(appointment.get()); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -0,0 +1,135 @@ | |||||||
|  | package enseirb.myinpulse.service.database; | ||||||
|  |  | ||||||
|  | import enseirb.myinpulse.model.Entrepreneur; | ||||||
|  | import enseirb.myinpulse.model.MakeAppointment; | ||||||
|  | import enseirb.myinpulse.model.Project; | ||||||
|  | import enseirb.myinpulse.repository.EntrepreneurRepository; | ||||||
|  |  | ||||||
|  | import org.apache.logging.log4j.LogManager; | ||||||
|  | import org.apache.logging.log4j.Logger; | ||||||
|  | import org.springframework.http.HttpStatus; | ||||||
|  | import org.springframework.stereotype.Service; | ||||||
|  | import org.springframework.web.server.ResponseStatusException; | ||||||
|  |  | ||||||
|  | import java.util.Optional; | ||||||
|  |  | ||||||
|  | @Service | ||||||
|  | public class EntrepreneurService { | ||||||
|  |  | ||||||
|  |     protected static final Logger logger = LogManager.getLogger(); | ||||||
|  |  | ||||||
|  |     private final EntrepreneurRepository entrepreneurRepository; | ||||||
|  |  | ||||||
|  |     EntrepreneurService(EntrepreneurRepository entrepreneurRepository) { | ||||||
|  |         this.entrepreneurRepository = entrepreneurRepository; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public Iterable<Entrepreneur> getAllEntrepreneurs() { | ||||||
|  |         return this.entrepreneurRepository.findAll(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public Entrepreneur getEntrepreneurById(Long id) { | ||||||
|  |         Optional<Entrepreneur> entrepreneur = entrepreneurRepository.findById(id); | ||||||
|  |         if (entrepreneur.isEmpty()) { | ||||||
|  |             logger.error("getEntrepreneurById : No entrepreneur found with id {}", id); | ||||||
|  |             throw new ResponseStatusException( | ||||||
|  |                     HttpStatus.NOT_FOUND, "Cet entrepreneur n'existe pas"); | ||||||
|  |         } | ||||||
|  |         return entrepreneur.get(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public Entrepreneur addEntrepreneur(Entrepreneur entrepreneur) { | ||||||
|  |         return this.entrepreneurRepository.save(entrepreneur); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public void updateEntrepreneurSchool(long idEntrepreneur, String school) { | ||||||
|  |         Entrepreneur entrepreneur = getEntrepreneurById(idEntrepreneur); | ||||||
|  |         entrepreneur.setSchool(school); | ||||||
|  |         this.entrepreneurRepository.save(entrepreneur); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public void updateEntrepreneurCourse(long idEntrepreneur, String course) { | ||||||
|  |         Entrepreneur entrepreneur = getEntrepreneurById(idEntrepreneur); | ||||||
|  |         entrepreneur.setCourse(course); | ||||||
|  |         this.entrepreneurRepository.save(entrepreneur); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public void updateEntrepreneurSneeStatus(long idEntrepreneur, boolean status) { | ||||||
|  |         Entrepreneur entrepreneur = getEntrepreneurById(idEntrepreneur); | ||||||
|  |         entrepreneur.setSneeStatus(status); | ||||||
|  |         this.entrepreneurRepository.save(entrepreneur); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public void updateEntrepreneurProjectParticipation( | ||||||
|  |             long idEntrepreneur, Project projectParticipation) { | ||||||
|  |         Entrepreneur entrepreneur = getEntrepreneurById(idEntrepreneur); | ||||||
|  |         entrepreneur.setProjectParticipation(projectParticipation); | ||||||
|  |         this.entrepreneurRepository.save(entrepreneur); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public void updateEntrepreneurProjectProposed(long idEntrepreneur, Project projectProposed) { | ||||||
|  |         Entrepreneur entrepreneur = getEntrepreneurById(idEntrepreneur); | ||||||
|  |         entrepreneur.setProjectParticipation(projectProposed); | ||||||
|  |         this.entrepreneurRepository.save(entrepreneur); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public void updateEntrepreneurMakeAppointment( | ||||||
|  |             long idEntrepreneur, MakeAppointment makeAppointment) { | ||||||
|  |         Entrepreneur entrepreneur = getEntrepreneurById(idEntrepreneur); | ||||||
|  |         entrepreneur.setMakeAppointment(makeAppointment); | ||||||
|  |         this.entrepreneurRepository.save(entrepreneur); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public Entrepreneur updateEntrepreneur( | ||||||
|  |             Long id, | ||||||
|  |             String school, | ||||||
|  |             String course, | ||||||
|  |             Boolean sneeStatus, | ||||||
|  |             Project projectParticipation, | ||||||
|  |             Project projectProposed, | ||||||
|  |             MakeAppointment makeAppointment) { | ||||||
|  |         Optional<Entrepreneur> entrepreneur = entrepreneurRepository.findById(id); | ||||||
|  |         if (entrepreneur.isEmpty()) { | ||||||
|  |             logger.error("updateEntrepreneur : No entrepreneur found with id {}", id); | ||||||
|  |             throw new ResponseStatusException( | ||||||
|  |                     HttpStatus.NOT_FOUND, "Cet entrepreneur n'existe pas"); | ||||||
|  |         } | ||||||
|  |         if (school != null) { | ||||||
|  |             entrepreneur.get().setSchool(school); | ||||||
|  |         } | ||||||
|  |         if (course != null) { | ||||||
|  |             entrepreneur.get().setCourse(course); | ||||||
|  |         } | ||||||
|  |         if (sneeStatus != null) { | ||||||
|  |             entrepreneur.get().setSneeStatus(sneeStatus); | ||||||
|  |         } | ||||||
|  |         if (projectParticipation != null) { | ||||||
|  |             entrepreneur.get().setProjectParticipation(projectParticipation); | ||||||
|  |         } | ||||||
|  |         if (projectProposed != null) { | ||||||
|  |             entrepreneur.get().setProjectParticipation(projectProposed); | ||||||
|  |         } | ||||||
|  |         if (makeAppointment != null) { | ||||||
|  |             entrepreneur.get().setMakeAppointment(makeAppointment); | ||||||
|  |         } | ||||||
|  |         return this.entrepreneurRepository.save(entrepreneur.get()); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public Iterable<Entrepreneur> GetEntrepreneurByProject(Project project) { | ||||||
|  |         return this.entrepreneurRepository.getEntrepreneurByProjectParticipation(project); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public void deleteEntrepreneur(Entrepreneur e) { | ||||||
|  |         this.entrepreneurRepository.delete(e); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public void validateEntrepreneurById(Long id) { | ||||||
|  |         System.out.println("\nVALIDATING\n"); | ||||||
|  |         Optional<Entrepreneur> e = this.entrepreneurRepository.findById(id); | ||||||
|  |         if (e.isEmpty()) { | ||||||
|  |             throw new ResponseStatusException(HttpStatus.NOT_FOUND, "Entrepreneur n'existe pas"); | ||||||
|  |         } | ||||||
|  |         e.get().setPending(false); | ||||||
|  |         this.entrepreneurRepository.save(e.get()); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -0,0 +1,159 @@ | |||||||
|  | package enseirb.myinpulse.service.database; | ||||||
|  |  | ||||||
|  | import static enseirb.myinpulse.model.ProjectDecisionValue.PENDING; | ||||||
|  |  | ||||||
|  | import enseirb.myinpulse.model.*; | ||||||
|  | import enseirb.myinpulse.repository.ProjectRepository; | ||||||
|  |  | ||||||
|  | import org.apache.logging.log4j.LogManager; | ||||||
|  | import org.apache.logging.log4j.Logger; | ||||||
|  | import org.springframework.beans.factory.annotation.Autowired; | ||||||
|  | import org.springframework.http.HttpStatus; | ||||||
|  | import org.springframework.stereotype.Service; | ||||||
|  | import org.springframework.web.server.ResponseStatusException; | ||||||
|  |  | ||||||
|  | import java.util.List; | ||||||
|  | import java.util.Optional; | ||||||
|  |  | ||||||
|  | @Service | ||||||
|  | public class ProjectService { | ||||||
|  |  | ||||||
|  |     protected static final Logger logger = LogManager.getLogger(); | ||||||
|  |  | ||||||
|  |     private final ProjectRepository projectRepository; | ||||||
|  |  | ||||||
|  |     @Autowired | ||||||
|  |     ProjectService(ProjectRepository projectRepository) { | ||||||
|  |         this.projectRepository = projectRepository; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public Iterable<Project> getAllProjects() { | ||||||
|  |         return this.projectRepository.findAll(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public Project getProjectById(Long id) { | ||||||
|  |         Optional<Project> project = this.projectRepository.findById(id); | ||||||
|  |         if (project.isEmpty()) { | ||||||
|  |             logger.error("No project found with id {}", id); | ||||||
|  |             throw new ResponseStatusException(HttpStatus.NOT_FOUND, "Ce projet n'existe pas"); | ||||||
|  |         } | ||||||
|  |         return project.get(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public Iterable<Project> getProjectsByAdminId(Administrator administrator) { | ||||||
|  |         return this.projectRepository.findByProjectAdministrator(administrator); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     // TODO: validation | ||||||
|  |     public Project addNewProject(Project project) { | ||||||
|  |         return this.projectRepository.save(project); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public void updateProjectName(long idProject, String name) { | ||||||
|  |         Project project = getProjectById(idProject); | ||||||
|  |         project.setProjectName(name); | ||||||
|  |         this.projectRepository.save(project); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public void updateProjectLogo(long idProject, byte[] logo) { | ||||||
|  |         Project project = getProjectById(idProject); | ||||||
|  |         project.setLogo(logo); | ||||||
|  |         this.projectRepository.save(project); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public void updateProjectStatus(long idProject, ProjectDecisionValue status) { | ||||||
|  |         Project project = getProjectById(idProject); | ||||||
|  |         project.setProjectStatus(status); | ||||||
|  |         this.projectRepository.save(project); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public void updateProjectEntrepreneurParticipation( | ||||||
|  |             long idProject, Entrepreneur entrepreneurParticipation) { | ||||||
|  |         Project project = getProjectById(idProject); | ||||||
|  |         project.updateListEntrepreneurParticipation(entrepreneurParticipation); | ||||||
|  |         this.projectRepository.save(project); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public void updateProjectListSectionCell(long idProject, SectionCell sectionCell) { | ||||||
|  |         Project project = getProjectById(idProject); | ||||||
|  |         project.updateListSectionCell(sectionCell); | ||||||
|  |         this.projectRepository.save(project); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public void updateProjectAdministrator(long idProject, Administrator administrator) { | ||||||
|  |         Project project = getProjectById(idProject); | ||||||
|  |         project.setProjectAdministrator(administrator); | ||||||
|  |         this.projectRepository.save(project); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public Project updateProject( | ||||||
|  |             Long id, | ||||||
|  |             String projectName, | ||||||
|  |             byte[] logo, | ||||||
|  |             ProjectDecisionValue projectStatus, | ||||||
|  |             Entrepreneur entrepreneurParticipation, | ||||||
|  |             SectionCell sectionCell, | ||||||
|  |             Administrator administrator) { | ||||||
|  |         Optional<Project> project = this.projectRepository.findById(id); | ||||||
|  |  | ||||||
|  |         if (project.isEmpty()) { | ||||||
|  |             logger.error("Project with id {} not found.", id); | ||||||
|  |             throw new ResponseStatusException(HttpStatus.NOT_FOUND, "Ce projet n'existe pas"); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         if (projectName != null) { | ||||||
|  |             project.get().setProjectName(projectName); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         if (logo != null) { | ||||||
|  |             project.get().setLogo(logo); | ||||||
|  |         } | ||||||
|  |         if (projectStatus != null) { | ||||||
|  |             // TODO: check if this is really useful | ||||||
|  |             /* | ||||||
|  |             if (!validateStatus(projectStatus)) { | ||||||
|  |                 logger.error("updateProjectStatus: Invalid status {}", projectStatus); | ||||||
|  |                 throw new ResponseStatusException( | ||||||
|  |                         HttpStatus.NOT_ACCEPTABLE, "Ce status n'est pas accepté"); | ||||||
|  |             } | ||||||
|  |             */ | ||||||
|  |             project.get().setProjectStatus(projectStatus); | ||||||
|  |         } | ||||||
|  |         if (entrepreneurParticipation != null) { | ||||||
|  |             project.get().updateListEntrepreneurParticipation(entrepreneurParticipation); | ||||||
|  |         } | ||||||
|  |         if (sectionCell != null) { | ||||||
|  |             project.get().updateListSectionCell(sectionCell); | ||||||
|  |         } | ||||||
|  |         if (administrator != null) { | ||||||
|  |             project.get().setProjectAdministrator(administrator); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         return this.projectRepository.save(project.get()); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public Boolean validateStatus(String status) { | ||||||
|  |         return List.of("PENDING", "ACTIVE", "ENDED").contains(status); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public Iterable<Project> getPendingProjects() { | ||||||
|  |         return this.projectRepository.findByProjectStatus(PENDING); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public void deleteProjectById(Long id) { | ||||||
|  |         this.projectRepository.deleteById(id); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public Project getProjectByName(String name, boolean noerror) { | ||||||
|  |         Optional<Project> project = this.projectRepository.findByProjectName(name); | ||||||
|  |         if (project.isEmpty()) { | ||||||
|  |             if (noerror) logger.error("No project found with name {}", name); | ||||||
|  |             throw new ResponseStatusException(HttpStatus.NOT_FOUND, "Ce projet n'existe pas"); | ||||||
|  |         } | ||||||
|  |         return project.get(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public Project getProjectByName(String name) { | ||||||
|  |         return getProjectByName(name, false); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -0,0 +1,76 @@ | |||||||
|  | package enseirb.myinpulse.service.database; | ||||||
|  |  | ||||||
|  | import enseirb.myinpulse.model.Appointment; | ||||||
|  | import enseirb.myinpulse.model.Report; | ||||||
|  | import enseirb.myinpulse.repository.ReportRepository; | ||||||
|  |  | ||||||
|  | import org.apache.logging.log4j.LogManager; | ||||||
|  | import org.apache.logging.log4j.Logger; | ||||||
|  | import org.springframework.beans.factory.annotation.Autowired; | ||||||
|  | import org.springframework.http.HttpStatus; | ||||||
|  | import org.springframework.stereotype.Service; | ||||||
|  | import org.springframework.web.server.ResponseStatusException; | ||||||
|  |  | ||||||
|  | import java.util.Optional; | ||||||
|  |  | ||||||
|  | @Service | ||||||
|  | public class ReportService { | ||||||
|  |  | ||||||
|  |     protected static final Logger logger = LogManager.getLogger(); | ||||||
|  |  | ||||||
|  |     private final ReportRepository reportRepository; | ||||||
|  |  | ||||||
|  |     @Autowired | ||||||
|  |     ReportService(ReportRepository reportRepository) { | ||||||
|  |         this.reportRepository = reportRepository; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public Iterable<Report> getAllReports() { | ||||||
|  |         return this.reportRepository.findAll(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public Report getReportById(Long id) { | ||||||
|  |         Optional<Report> report = this.reportRepository.findById(id); | ||||||
|  |         if (report.isEmpty()) { | ||||||
|  |             logger.error("getReportById : No report found with id {}", id); | ||||||
|  |             throw new ResponseStatusException(HttpStatus.NOT_FOUND, "Ce compte rendu n'existe pas"); | ||||||
|  |         } | ||||||
|  |         return report.get(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     // TODO: do some validation | ||||||
|  |     public Report addNewReport(Report report) { | ||||||
|  |         return this.reportRepository.save(report); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public void deleteReportById(Long id) { | ||||||
|  |         this.reportRepository.deleteById(id); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public void updateReportContent(long idReport, String content) { | ||||||
|  |         Report report = getReportById(idReport); | ||||||
|  |         report.setReportContent(content); | ||||||
|  |         this.reportRepository.save(report); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public void updateReportAppointment(long idReport, Appointment appointment) { | ||||||
|  |         Report report = getReportById(idReport); | ||||||
|  |         report.setAppointmentReport(appointment); | ||||||
|  |         this.reportRepository.save(report); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public Report updateReport(Long id, String reportContent, Appointment appointment) { | ||||||
|  |         Optional<Report> report = this.reportRepository.findById(id); | ||||||
|  |         if (report.isEmpty()) { | ||||||
|  |             logger.error("updateReport : No report found with id {}", id); | ||||||
|  |             throw new ResponseStatusException(HttpStatus.NOT_FOUND, "Ce compte rendu n'existe pas"); | ||||||
|  |         } | ||||||
|  |         if (reportContent != null) { | ||||||
|  |             report.get().setReportContent(reportContent); | ||||||
|  |         } | ||||||
|  |         if (appointment != null) { | ||||||
|  |             report.get().setAppointmentReport(appointment); | ||||||
|  |         } | ||||||
|  |         return this.reportRepository.save(report.get()); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -0,0 +1,183 @@ | |||||||
|  | package enseirb.myinpulse.service.database; | ||||||
|  |  | ||||||
|  | import enseirb.myinpulse.model.Annotation; | ||||||
|  | import enseirb.myinpulse.model.Appointment; | ||||||
|  | import enseirb.myinpulse.model.Project; | ||||||
|  | import enseirb.myinpulse.model.SectionCell; | ||||||
|  | import enseirb.myinpulse.repository.SectionCellRepository; | ||||||
|  |  | ||||||
|  | import org.apache.logging.log4j.LogManager; | ||||||
|  | import org.apache.logging.log4j.Logger; | ||||||
|  | import org.springframework.beans.factory.annotation.Autowired; | ||||||
|  | import org.springframework.http.HttpStatus; | ||||||
|  | import org.springframework.stereotype.Service; | ||||||
|  | import org.springframework.web.server.ResponseStatusException; | ||||||
|  |  | ||||||
|  | import java.time.LocalDateTime; | ||||||
|  | import java.util.ArrayList; | ||||||
|  | import java.util.HashMap; | ||||||
|  | import java.util.List; | ||||||
|  | import java.util.Map; | ||||||
|  | import java.util.Optional; | ||||||
|  |  | ||||||
|  | @Service | ||||||
|  | public class SectionCellService { | ||||||
|  |  | ||||||
|  |     protected static final Logger logger = LogManager.getLogger(); | ||||||
|  |  | ||||||
|  |     private final SectionCellRepository sectionCellRepository; | ||||||
|  |  | ||||||
|  |     @Autowired | ||||||
|  |     SectionCellService(SectionCellRepository sectionCellRepository) { | ||||||
|  |         this.sectionCellRepository = sectionCellRepository; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public Iterable<SectionCell> getAllSectionCells() { | ||||||
|  |         return this.sectionCellRepository.findAll(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public SectionCell getSectionCellById(Long id) { | ||||||
|  |         Optional<SectionCell> sectionCell = this.sectionCellRepository.findById(id); | ||||||
|  |         if (sectionCell.isEmpty()) { | ||||||
|  |             logger.error("getSectionCellById : No sectionCell found with id {}", id); | ||||||
|  |             throw new ResponseStatusException( | ||||||
|  |                     HttpStatus.NOT_FOUND, "Cette cellule de section n'existe pas"); | ||||||
|  |         } | ||||||
|  |         return sectionCell.get(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public SectionCell addNewSectionCell(SectionCell sectionCell) { | ||||||
|  |         return this.sectionCellRepository.save(sectionCell); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public void removeSectionCellById(Long id) { | ||||||
|  |         this.sectionCellRepository.deleteById(id); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public void updateSectionCellReferenceId(Long idSectionCell, Long referenceId) { | ||||||
|  |         SectionCell sectionCell = this.getSectionCellById(idSectionCell); | ||||||
|  |         sectionCell.setIdReference(referenceId); | ||||||
|  |         this.sectionCellRepository.save(sectionCell); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public void updateSectionCellContent(long idSectionCell, String content) { | ||||||
|  |         SectionCell sectionCell = getSectionCellById(idSectionCell); | ||||||
|  |         sectionCell.setContentSectionCell(content); | ||||||
|  |         this.sectionCellRepository.save(sectionCell); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public void updateSectionCellListAppointment(long idSectionCell, Appointment appointment) { | ||||||
|  |         SectionCell sectionCell = getSectionCellById(idSectionCell); | ||||||
|  |         sectionCell.updateAppointmentSectionCell(appointment); | ||||||
|  |         this.sectionCellRepository.save(sectionCell); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public void updateSectionCellListAnnotation(long idSectionCell, Annotation annotation) { | ||||||
|  |         SectionCell sectionCell = getSectionCellById(idSectionCell); | ||||||
|  |         sectionCell.updateListAnnotation(annotation); | ||||||
|  |         this.sectionCellRepository.save(sectionCell); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public void updateSectionCellProject(long idSectionCell, Project project) { | ||||||
|  |         SectionCell sectionCell = getSectionCellById(idSectionCell); | ||||||
|  |         sectionCell.setProjectSectionCell(project); | ||||||
|  |         this.sectionCellRepository.save(sectionCell); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public SectionCell updateSectionCell( | ||||||
|  |             Long id, | ||||||
|  |             String contentSectionCell, | ||||||
|  |             Appointment appointment, | ||||||
|  |             Annotation annotation, | ||||||
|  |             Project project) { | ||||||
|  |         Optional<SectionCell> sectionCell = this.sectionCellRepository.findById(id); | ||||||
|  |         if (sectionCell.isEmpty()) { | ||||||
|  |             logger.error("updateSectionCell : No sectionCell found with id {}", id); | ||||||
|  |             throw new ResponseStatusException( | ||||||
|  |                     HttpStatus.NOT_FOUND, "Cette cellule de section n'existe pas"); | ||||||
|  |         } | ||||||
|  |         if (contentSectionCell != null) { | ||||||
|  |             sectionCell.get().setContentSectionCell(contentSectionCell); | ||||||
|  |             sectionCell.get().setModificationDate(LocalDateTime.now()); | ||||||
|  |         } | ||||||
|  |         if (appointment != null) { | ||||||
|  |             sectionCell.get().updateAppointmentSectionCell(appointment); | ||||||
|  |             sectionCell.get().setModificationDate(LocalDateTime.now()); | ||||||
|  |         } | ||||||
|  |         if (annotation != null) { | ||||||
|  |             sectionCell.get().updateListAnnotation(annotation); | ||||||
|  |             sectionCell.get().setModificationDate(LocalDateTime.now()); | ||||||
|  |         } | ||||||
|  |         if (project != null) { | ||||||
|  |             sectionCell.get().setProjectSectionCell(project); | ||||||
|  |             sectionCell.get().setModificationDate(LocalDateTime.now()); | ||||||
|  |         } | ||||||
|  |         return this.sectionCellRepository.save(sectionCell.get()); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public Iterable<SectionCell> getSectionCellsByProject(Project project, Long sectionId) { | ||||||
|  |         return this.sectionCellRepository.findByProjectSectionCellAndSectionId(project, sectionId); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public Iterable<SectionCell> getSectionCellsByProject(Project project) { | ||||||
|  |         logger.info("Fetching SectionCells for Project ID: {}", project.getIdProject()); | ||||||
|  |         Iterable<SectionCell> sectionCells = | ||||||
|  |                 this.sectionCellRepository.findByProjectSectionCell(project); | ||||||
|  |         List<SectionCell> sectionCellList = new ArrayList<>(); | ||||||
|  |         sectionCells.forEach( | ||||||
|  |                 cell -> { | ||||||
|  |                     sectionCellList.add(cell); | ||||||
|  |                 }); | ||||||
|  |         return sectionCellList; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public Long getProjectId(Long sectionCellId) { | ||||||
|  |         SectionCell sectionCell = getSectionCellById(sectionCellId); | ||||||
|  |         Project sectionProject = sectionCell.getProjectSectionCell(); | ||||||
|  |         return sectionProject.getIdProject(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public List<Appointment> getAppointmentsBySectionCellId(Long sectionCellId) { | ||||||
|  |         SectionCell sectionCell = getSectionCellById(sectionCellId); | ||||||
|  |         return sectionCell.getAppointmentSectionCell(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public Iterable<SectionCell> getSectionCellsByProjectAndSectionIdBeforeDate( | ||||||
|  |             Project project, long sectionId, LocalDateTime date) { | ||||||
|  |         return sectionCellRepository.findByProjectSectionCellAndSectionIdAndModificationDateBefore( | ||||||
|  |                 project, sectionId, date); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public Iterable<SectionCell> getLatestSectionCellsByIdReferenceBeforeDate( | ||||||
|  |             Project project, long sectionId, LocalDateTime date) { | ||||||
|  |  | ||||||
|  |         // 1. Fetch ALL relevant SectionCells modified before the date | ||||||
|  |         Iterable<SectionCell> allMatchingCells = | ||||||
|  |                 sectionCellRepository.findByProjectSectionCellAndSectionIdAndModificationDateBefore( | ||||||
|  |                         project, sectionId, date); | ||||||
|  |  | ||||||
|  |         // 2. Find the latest for each idReference | ||||||
|  |         Map<Long, SectionCell> latestCellsByIdReference = new HashMap<>(); | ||||||
|  |  | ||||||
|  |         for (SectionCell cell : allMatchingCells) { | ||||||
|  |             Long idReference = cell.getIdReference(); | ||||||
|  |  | ||||||
|  |             // Check if we've seen this idReference before | ||||||
|  |             if (latestCellsByIdReference.containsKey(idReference)) { | ||||||
|  |                 // If yes, compare modification dates | ||||||
|  |                 SectionCell existingLatest = latestCellsByIdReference.get(idReference); | ||||||
|  |  | ||||||
|  |                 // If the current cell is more recent, update the map | ||||||
|  |                 if (cell.getModificationDate().isAfter(existingLatest.getModificationDate())) { | ||||||
|  |                     latestCellsByIdReference.put(idReference, cell); | ||||||
|  |                 } | ||||||
|  |             } else { | ||||||
|  |                 // If this is the first time we see this idReference, add it to the map | ||||||
|  |                 latestCellsByIdReference.put(idReference, cell); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         // 3. Return the collection of the latest cells (the values from the map) | ||||||
|  |         return latestCellsByIdReference.values(); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -0,0 +1,124 @@ | |||||||
|  | package enseirb.myinpulse.service.database; | ||||||
|  |  | ||||||
|  | import enseirb.myinpulse.model.User; | ||||||
|  | import enseirb.myinpulse.repository.UserRepository; | ||||||
|  |  | ||||||
|  | import org.apache.logging.log4j.LogManager; | ||||||
|  | import org.apache.logging.log4j.Logger; | ||||||
|  | import org.springframework.beans.factory.annotation.Autowired; | ||||||
|  | import org.springframework.http.HttpStatus; | ||||||
|  | import org.springframework.stereotype.Service; | ||||||
|  | import org.springframework.web.bind.annotation.PathVariable; | ||||||
|  | import org.springframework.web.bind.annotation.RequestBody; | ||||||
|  | import org.springframework.web.server.ResponseStatusException; | ||||||
|  |  | ||||||
|  | import java.util.Optional; | ||||||
|  |  | ||||||
|  | @Service | ||||||
|  | public class UserService { | ||||||
|  |  | ||||||
|  |     protected static final Logger logger = LogManager.getLogger(); | ||||||
|  |  | ||||||
|  |     private final UserRepository userRepository; | ||||||
|  |  | ||||||
|  |     @Autowired | ||||||
|  |     UserService(UserRepository userRepository) { | ||||||
|  |         this.userRepository = userRepository; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public Iterable<User> getAllUsers() { | ||||||
|  |         return this.userRepository.findAll(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public User getUserById(long id) { | ||||||
|  |         Optional<User> user = this.userRepository.findById(id); | ||||||
|  |         if (user.isEmpty()) { | ||||||
|  |             logger.error("getUserById : No user found with id {}", id); | ||||||
|  |             throw new ResponseStatusException(HttpStatus.NOT_FOUND, "Cet utilisateur n'existe pas"); | ||||||
|  |         } | ||||||
|  |         return user.get(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     // TODO | ||||||
|  |     public User getUserByEmail(String email) { | ||||||
|  |         Optional<User> opt_user = this.userRepository.findByPrimaryMail(email); | ||||||
|  |  | ||||||
|  |         if (opt_user.isEmpty()) { | ||||||
|  |             logger.error("getUserByEmail : No user found with email {}", email); | ||||||
|  |             throw new ResponseStatusException(HttpStatus.NOT_FOUND, "Cet utilisateur n'existe pas"); | ||||||
|  |         } | ||||||
|  |         return opt_user.get(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public Iterable<User> allUsers() { | ||||||
|  |         return this.userRepository.findAll(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public User addUser(@RequestBody User user) { | ||||||
|  |         return this.userRepository.save(user); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public void updateUserSurname(long idUser, String surname) { | ||||||
|  |         User user = getUserById(idUser); | ||||||
|  |         user.setUserSurname(surname); | ||||||
|  |         this.userRepository.save(user); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public void updateUserName(long idUser, String name) { | ||||||
|  |         User user = getUserById(idUser); | ||||||
|  |         user.setUserName(name); | ||||||
|  |         this.userRepository.save(user); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public void updateUserPrimaryMail(long idUser, String primaryMail) { | ||||||
|  |         User user = getUserById(idUser); | ||||||
|  |         user.setPrimaryMail(primaryMail); | ||||||
|  |         this.userRepository.save(user); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public void updateUserSecondaryMail(long idUser, String secondaryMail) { | ||||||
|  |         User user = getUserById(idUser); | ||||||
|  |         user.setSecondaryMail(secondaryMail); | ||||||
|  |         this.userRepository.save(user); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public void updateUserPhoneNumber(long idUser, String phoneNumber) { | ||||||
|  |         User user = getUserById(idUser); | ||||||
|  |         user.setPhoneNumber(phoneNumber); | ||||||
|  |         this.userRepository.save(user); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public User updateUser( | ||||||
|  |             @PathVariable Long id, | ||||||
|  |             String userSurname, | ||||||
|  |             String userName, | ||||||
|  |             String primaryMail, | ||||||
|  |             String secondaryMail, | ||||||
|  |             String phoneNumber) { | ||||||
|  |         Optional<User> user = userRepository.findById(id); | ||||||
|  |         if (user.isEmpty()) { | ||||||
|  |             logger.error("updateUser : No user found with id {}", id); | ||||||
|  |             throw new ResponseStatusException(HttpStatus.NOT_FOUND, "Cet utilisateur n'existe pas"); | ||||||
|  |         } | ||||||
|  |         if (userName != null) { | ||||||
|  |             user.get().setUserName(userName); | ||||||
|  |         } | ||||||
|  |         if (userSurname != null) { | ||||||
|  |             user.get().setUserSurname(userSurname); | ||||||
|  |         } | ||||||
|  |         if (primaryMail != null) { | ||||||
|  |             user.get().setPrimaryMail(primaryMail); | ||||||
|  |         } | ||||||
|  |         if (secondaryMail != null) { | ||||||
|  |             user.get().setSecondaryMail(secondaryMail); | ||||||
|  |         } | ||||||
|  |         if (phoneNumber != null) { | ||||||
|  |             user.get().setPhoneNumber(phoneNumber); | ||||||
|  |         } | ||||||
|  |         return this.userRepository.save(user.get()); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public Iterable<User> getPendingAccounts() { | ||||||
|  |         return this.userRepository.findAllByPendingEquals(true); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -1,11 +1,8 @@ | |||||||
| spring.application.name=myinpulse | spring.application.name=myinpulse | ||||||
| spring.security.oauth2.resourceserver.jwt.jwk-set-uri=http://localhost:7080/realms/test/protocol/openid-connect/certs | spring.security.oauth2.resourceserver.jwt.jwk-set-uri=http://localhost:7080/realms/${VITE_KEYCLOAK_REALM}/protocol/openid-connect/certs | ||||||
| spring.security.oauth2.resourceserver.jwt.issuer-uri=http://localhost:7080/realms/test | spring.security.oauth2.resourceserver.jwt.issuer-uri=http://localhost:7080/realms/${VITE_KEYCLOAK_REALM} | ||||||
| logging.level.org.springframework.security=DEBUG | spring.datasource.url=jdbc:postgresql://${DATABASE_URL}/${BACKEND_DB} | ||||||
| spring.datasource.url=jdbc:postgresql://postgres/${POSTGRES_DB} | spring.datasource.username=${BACKEND_USER} | ||||||
| spring.datasource.username=${POSTGRES_USER} | spring.datasource.password=${BACKEND_PASSWORD} | ||||||
| spring.datasource.password=${POSTGRES_PASSWORD} |  | ||||||
| spring.jpa.hibernate.ddl-auto=update | spring.jpa.hibernate.ddl-auto=update | ||||||
| spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect | logging.pattern.console=%d{yyyy-MMM-dd HH:mm:ss.SSS} [%thread] %highlight(%-5level) %cyan(%logger{15}) - %msg %n | ||||||
|  |  | ||||||
| spring.data.rest.base-path=/my/base/path |  | ||||||
| @@ -0,0 +1,13 @@ | |||||||
|  | spring.application.name=myinpulse | ||||||
|  | spring.security.oauth2.resourceserver.jwt.jwk-set-uri=http://localhost:7080/realms/test/protocol/openid-connect/certs | ||||||
|  | spring.security.oauth2.resourceserver.jwt.issuer-uri=http://localhost:7080/realms/test | ||||||
|  |  | ||||||
|  | logging.pattern.console=%d{yyyy-MMM-dd HH:mm:ss.SSS} [%thread] %highlight(%-5level) %cyan(%logger{15}) - %msg %n | ||||||
|  |  | ||||||
|  | spring.datasource.url=jdbc:h2:mem:testdb;DB_CLOSE_DELAY=-1 | ||||||
|  | spring.datasource.driverClassName=org.h2.Driver | ||||||
|  | spring.datasource.username=sa | ||||||
|  | spring.datasource.password= | ||||||
|  | spring.jpa.database-platform=org.hibernate.dialect.H2Dialect | ||||||
|  |  | ||||||
|  | spring.jpa.hibernate.ddl-auto=create | ||||||
| @@ -1,61 +0,0 @@ | |||||||
| INSERT INTO projets (nom_projet, logo, date_creation, status_projet) VALUES |  | ||||||
| ('Eau du robinet', decode('013d7d16d7ad4fefb61bd95b765c8ceb', 'hex'), TO_DATE('01-OCT-2023', 'DD-MON-YYYY'), 'En cours'), |  | ||||||
| ('Air oxygéné', decode('150647a0984e8f228cd14b54', 'hex'), TO_DATE('04-APR-2024', 'DD-MON-YYYY'), 'En cours'), |  | ||||||
| ('Débat concours', decode('022024abd5486e245c145dda65116f', 'hex'), TO_DATE('22-NOV-2023', 'DD-MON-YYYY'), 'Suspendu'), |  | ||||||
| ('HDeirbMI', decode('ab548d6c1d595a2975e6476f544d14c55a', 'hex'), TO_DATE('07-DEC-2024', 'DD-MON-YYYY'), 'Lancement'); |  | ||||||
|  |  | ||||||
| INSERT INTO utilisateurs (nom, prenom, mail_principal, mail_secondaire, numero_telephone) VALUES |  | ||||||
| ('Dupont', 'Dupond', 'super@mail.fr', 'super2@mail.fr', '06 45 72 45 98'), |  | ||||||
| ('Martin', 'Matin', 'genial@mail.fr', 'genial2@mail.fr', '06 52 14 58 73'), |  | ||||||
| ('Charvet', 'Lautre', 'mieux@tmail.fr', 'mieux2@tmail.fr', '07 49 82 16 35'), |  | ||||||
| ('Leguez', 'Theo', 'bof@mesmails.fr', 'bof2@mesmails.fr', '+33 6 78 14 25 29'), |  | ||||||
| ('Kia', 'Bi', 'special@mail.fr', 'special2@mail.fr', '07 65 31 38 95'); |  | ||||||
|  |  | ||||||
| INSERT INTO entrepreneurs (ecole, filiere, status_snee) VALUES |  | ||||||
| ('ENSEIRB-MATMECA', 'INFO', TRUE), |  | ||||||
| ('ENSC', 'Cognitique', TRUE), |  | ||||||
| ('ENSEIRB-MATMECA', 'MATMECA', FALSE), |  | ||||||
| ('SupOptique', 'Classique', TRUE), |  | ||||||
| ('ENSEGID', 'Géoscience', FALSE), |  | ||||||
| ('ENSMAC', 'Matériaux composites - Mécanique', FALSE); |  | ||||||
|  |  | ||||||
| INSERT INTO sections (titre, contenu_section, date_modification) VALUES |  | ||||||
| ("Problème", "les problèmes...", TO_DATE('15-JAN-2025', 'DD-MON-YYYY')), |  | ||||||
| ("Segment de client", "Le segment AB passant le client n°8 est de longueur 32mm.  |  | ||||||
|     Le segment BC a quant à lui un longueur de 28mm. Quelle la longueur du segment AC ?", TO_DATE('12-OCT-2022', 'DD-MON-YYYY')), |  | ||||||
| ("Proposition de valeur unique", "'Son prix est de 2594€' 'Ah oui c'est unique en effet'", TO_DATE('25-MAY-2024', 'DD-MON-YYYY')), |  | ||||||
| ("Solution", "Un problème ? Une solution", TO_DATE('08-FEB-2024', 'DD-MON-YYYY')), |  | ||||||
| ("Canaux", "Ici nous avons la Seine, là-bas le Rhin, oh et plus loin le canal de Suez", TO_DATE('19-JUL-2023', 'DD-MON-YYYY')), |  | ||||||
| ("Sources de revenus", "Y'en n'a pas on est pas payé. Enfin y'a du café quoi", TO_DATE('12-JAN-2025', 'DD-MON-YYYY')), |  | ||||||
| ("Structure des coûts", "'Ah oui là ça va faire au moins 1000€ par mois', Eirbware", TO_DATE('06-FEB-2025', 'DD-MON-YYYY')), |  | ||||||
| ("Indicateurs clés", "On apprend les clés comme des badges, ça se fait", TO_DATE('05-FEB-2025', 'DD-MON-YYYY')), |  | ||||||
| ("Avantages concurrentiel", "On est meilleur", TO_DATE('23-APR-2024', 'DD-MON-YYYY')); |  | ||||||
|  |  | ||||||
| INSERT INTO rendez_vous (date_rdv, heure_rdv, duree_rdv, lieu_rdv, sujet_rdv) VALUES |  | ||||||
| (TO_DATE('24-DEC-2023', 'DD-MON-YYYY'), '00:00:00', '00:37:53', "À la maison", "Ouvrir les cadeaux"), |  | ||||||
| (TO_DATE('15-AUG-2024', 'DD-MON-YYYY'), '22:35:00', '00:12:36', "Sur les quais ou dans un champ probablement", "BOUM BOUM les feux d'artifices (on fête quoi déjà ?)"), |  | ||||||
| (TO_DATE('29-FEB-2023', 'DD-MON-YYYY'), '14:20:00', '00:20:00', "Salle TD 15", "Ah mince c'est pas une année bissextile !"), |  | ||||||
| (TO_DATE('23-JAN-2024', 'DD-MON-YYYY'), '12:56:27', '11:03:33', "Là où le vent nous porte", "Journée la plus importante de l'année"), |  | ||||||
| (TO_DATE('25-AUG-2025', 'DD-MON-YYYY'), '00:09:00', '01:00:00', "Euh c'est par où l'amphi 56 ?", "Rentrée scolaire (il fait trop froid c'est quoi ça on est en août)"); |  | ||||||
|  |  | ||||||
| INSERT INTO comptes_rendus (contenu_compte_rendu) VALUES |  | ||||||
| ("Ah oui ça c'est super, ah ouais j'aime bien, bien vu de penser à ça"), |  | ||||||
| ("Bonne réunion"), |  | ||||||
| ("Ouais, j'ai rien compris mais niquel on fait comme vous avez dit"), |  | ||||||
| ("Non non ça va pas du tout ce que tu me proposes, faut tout refaire"), |  | ||||||
| ("Réponse de la DSI : non"), |  | ||||||
| ("Trop dommage qu'Apple ait sorti leur logiciel avant nous, on avait la même idée et tout on aurait tellement pu leur faire de la concurrence"); |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
							
								
								
									
										92
									
								
								MyINPulse-back/src/main/resources/import.sql
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										92
									
								
								MyINPulse-back/src/main/resources/import.sql
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,92 @@ | |||||||
|  | -- Initial Database State Script | ||||||
|  |  | ||||||
|  | -- Insert Administrators | ||||||
|  | INSERT INTO administrator (idAdministrator) VALUES | ||||||
|  | (1), | ||||||
|  | (2), | ||||||
|  | (3); -- Added more administrators | ||||||
|  |  | ||||||
|  | -- Insert User Inpulse (some pending) | ||||||
|  | INSERT INTO user_inpulse (idUser, userSurname, userName, primaryMail, secondaryMail, phoneNumber, pending) VALUES | ||||||
|  | (1, 'Doe', 'John', 'john.doe@example.com', NULL, '123-456-7890', FALSE), | ||||||
|  | (2, 'Smith', 'Jane', 'jane.smith@example.com', 'jane.s@altmail.com', '987-654-3210', FALSE), | ||||||
|  | (3, 'Williams', 'Peter', 'peter.w@example.com', NULL, NULL, TRUE), -- Pending user | ||||||
|  | (4, 'Jones', 'Mary', 'mary.j@example.com', NULL, '555-123-4567', FALSE), | ||||||
|  | (5, 'Brown', 'Michael', 'michael.b@example.com', 'mike.brown@work.com', '111-222-3333', FALSE), | ||||||
|  | (6, 'Garcia', 'Maria', 'maria.g@example.com', NULL, '444-555-6666', TRUE), -- Another pending user | ||||||
|  | (7, 'Miller', 'David', 'david.m@example.com', NULL, '777-888-9999', FALSE); | ||||||
|  |  | ||||||
|  | -- Insert Entrepreneurs | ||||||
|  | INSERT INTO entrepreneur (idEntrepreneur, school, course, sneeStatus, idProjectParticipation, idProjectProposed, idMakeAppointment) VALUES | ||||||
|  | (1, 'Business School A', 'MBA', TRUE, NULL, NULL, NULL), | ||||||
|  | (2, 'Tech University B', 'Computer Science', FALSE, NULL, NULL, NULL), | ||||||
|  | (3, 'Art Institute C', 'Graphic Design', TRUE, NULL, NULL, NULL), | ||||||
|  | (4, 'Science College D', 'Biology', FALSE, NULL, NULL, NULL), | ||||||
|  | (5, 'Engineering School E', 'Mechanical Engineering', TRUE, NULL, NULL, NULL); -- Added more entrepreneurs | ||||||
|  |  | ||||||
|  | -- Insert Projects | ||||||
|  | -- Main project | ||||||
|  | INSERT INTO project (IdProject, projectName, loga, creationDate, projectStatus, pending, idAdministrator, entrepreneurProposed) VALUES | ||||||
|  | (101, 'Innovative Startup Idea', NULL, '2023-10-26', 'In Progress', FALSE, 1, NULL), | ||||||
|  | (102, 'Pending Project Alpha', NULL, '2024-01-15', 'Planning', TRUE, 1, NULL), -- Pending project | ||||||
|  | (103, 'Pending Project Beta', NULL, '2024-02-20', 'Idea Stage', TRUE, NULL, 1), -- Another pending project, proposed by entrepreneur 1 | ||||||
|  | (104, 'E-commerce Platform Development', NULL, '2024-03-10', 'Completed', FALSE, 2, NULL), -- Completed project | ||||||
|  | (105, 'Mobile App for Education', NULL, '2024-04-01', 'In Progress', FALSE, 3, NULL), | ||||||
|  | (106, 'Pending Research Proposal', NULL, '2024-04-25', 'Drafting', TRUE, NULL, 4); -- Pending project proposed by entrepreneur 4 | ||||||
|  |  | ||||||
|  | -- Link Entrepreneurs to projects (Project Participation and Proposed) | ||||||
|  | -- Based on the current schema, we'll update the entrepreneur table directly. | ||||||
|  | -- This might need adjustment based on actual application logic if it's a many-to-many. | ||||||
|  | UPDATE entrepreneur SET idProjectParticipation = 101 WHERE idEntrepreneur IN (1, 2); -- Entrepreneurs 1 and 2 participate in Project 101 | ||||||
|  | UPDATE entrepreneur SET idProjectParticipation = 104 WHERE idEntrepreneur = 3; -- Entrepreneur 3 participates in Project 104 | ||||||
|  | UPDATE entrepreneur SET idProjectProposed = 103 WHERE idEntrepreneur = 1; -- Entrepreneur 1 proposed Project 103 | ||||||
|  | UPDATE entrepreneur SET idProjectProposed = 106 WHERE idEntrepreneur = 4; -- Entrepreneur 4 proposed Project 106 | ||||||
|  |  | ||||||
|  | -- Insert Section Cells for the main project (Project 101) and other projects | ||||||
|  | INSERT INTO section_cell (idSectionCell, IdReference, sectionid, contentSectionCell, modificationDate, idProject) VALUES | ||||||
|  | (1001, NULL, 1, 'Initial project description for Project 101.', '2023-10-26 10:00:00', 101), | ||||||
|  | (1002, 1001, 2, 'Market analysis summary for Project 101.', '2023-10-27 14:30:00', 101), | ||||||
|  | (1003, NULL, 3, 'Team member profiles for Project 101.', '2023-10-28 09:00:00', 101), | ||||||
|  | (1004, NULL, 1, 'Project brief for Project 104.', '2024-03-10 11:00:00', 104), | ||||||
|  | (1005, 1004, 2, 'Technical specifications for Project 104.', '2024-03-15 16:00:00', 104), | ||||||
|  | (1006, NULL, 1, 'Initial concept for Project 105.', '2024-04-01 09:30:00', 105); | ||||||
|  |  | ||||||
|  | -- Insert Appointments | ||||||
|  | INSERT INTO appointment (idAppointment, appointmentDate, appointmentTime, appointmentDuration, appointmentPlace, appointmentSubject) VALUES | ||||||
|  | (2001, '2023-11-05', '11:00:00', '01:00:00', 'Meeting Room A', 'Project 101 Kick-off Meeting'), | ||||||
|  | (2002, '2023-11-10', '14:00:00', '00:30:00', 'Online', 'Project 101 Follow-up Discussion'), | ||||||
|  | (2003, '2024-03-20', '10:00:00', '01:30:00', 'Client Office', 'Project 104 Final Review'), | ||||||
|  | (2004, '2024-04-10', '15:00:00', '00:45:00', 'Video Call', 'Project 105 Initial Sync'); -- Added more appointments | ||||||
|  |  | ||||||
|  | -- Insert Concerns (linking Appointments and Section Cells) | ||||||
|  | INSERT INTO concern (IdAppointment, idSectionCell) VALUES | ||||||
|  | (2001, 1001), -- Kick-off meeting concerns section 1001 (Project 101) | ||||||
|  | (2001, 1002), -- Kick-off meeting concerns section 1002 (Project 101) | ||||||
|  | (2002, 1002), -- Follow-up concerns section 1002 (Project 101) | ||||||
|  | (2003, 1004), -- Project 104 review concerns section 1004 | ||||||
|  | (2003, 1005), -- Project 104 review concerns section 1005 | ||||||
|  | (2004, 1006); -- Project 105 sync concerns section 1006 | ||||||
|  |  | ||||||
|  | -- Insert Make Appointments (linking Appointments, Administrators, and Entrepreneurs) | ||||||
|  | INSERT INTO make_appointment (idMakeAppointment, idAppointment, idAdministrator, idEntrepreneur) VALUES | ||||||
|  | (3001, 2001, 1, 1), -- Admin 1 scheduled appointment 2001 with Entrepreneur 1 | ||||||
|  | (3002, 2001, 1, 2), -- Admin 1 scheduled appointment 2001 with Entrepreneur 2 | ||||||
|  | (3003, 2002, 1, 1), -- Admin 1 scheduled appointment 2002 with Entrepreneur 1 | ||||||
|  | (3004, 2003, 2, 3), -- Admin 2 scheduled appointment 2003 with Entrepreneur 3 | ||||||
|  | (3005, 2004, 3, 5); -- Admin 3 scheduled appointment 2004 with Entrepreneur 5 | ||||||
|  |  | ||||||
|  | -- Insert Annotations (linking to Section Cells and Administrators) | ||||||
|  | INSERT INTO annotation (IdAnnotation, comment, idSectionCell, idAdministrator) VALUES | ||||||
|  | (4001, 'Needs more detail on market size.', 1002, 1), | ||||||
|  | (4002, 'Looks good.', 1001, 1), | ||||||
|  | (4003, 'Confirm technical requirements.', 1005, 2), | ||||||
|  | (4004, 'Initial thoughts on UI/UX.', 1006, 3); -- Added more annotations | ||||||
|  |  | ||||||
|  | -- Insert Reports (linking to Make Appointments) | ||||||
|  | INSERT INTO report (IdReport, reportContent, idMakeAppointment) VALUES | ||||||
|  | (5001, 'Discussed project scope and timelines for Project 101.', 3001), | ||||||
|  | (5002, 'Reviewed market analysis feedback for Project 101.', 3003), | ||||||
|  | (5003, 'Final sign-off on Project 104 deliverables.', 3004), | ||||||
|  | (5004, 'Discussed initial concepts for Project 105.', 3005); -- Added more reports | ||||||
|  |  | ||||||
|  | -- The project ID for the main project is 101. | ||||||
| @@ -1,121 +0,0 @@ | |||||||
| DROP TABLE IF EXISTS projets CASCADE; |  | ||||||
| DROP TABLE IF EXISTS utilisateurs CASCADE; |  | ||||||
| DROP TABLE IF EXISTS entrepreneurs CASCADE; |  | ||||||
| DROP TABLE IF EXISTS administrateurs CASCADE; |  | ||||||
| DROP TABLE IF EXISTS sections CASCADE; |  | ||||||
| DROP TABLE IF EXISTS rendez_vous CASCADE; |  | ||||||
| DROP TABLE IF EXISTS comptes_rendus CASCADE; |  | ||||||
| DROP TABLE IF EXISTS concerner CASCADE; |  | ||||||
| DROP TABLE IF EXISTS formes CASCADE; |  | ||||||
|  |  | ||||||
| CREATE TABLE projets |  | ||||||
| ( |  | ||||||
| id_projet       SERIAL    NOT NULL, |  | ||||||
| nom_projet      VARCHAR(255)      , |  | ||||||
| logo            BYTEA             , |  | ||||||
| date_creation   DATE              , |  | ||||||
| status_projet   VARCHAR(255)      , |  | ||||||
| CONSTRAINT pk_projet PRIMARY KEY (id_projet) ); |  | ||||||
|  |  | ||||||
| CREATE TABLE utilisateurs |  | ||||||
| ( |  | ||||||
| id_utilisateur      SERIAL    NOT NULL, |  | ||||||
| nom_utilisateur     VARCHAR(255)      , |  | ||||||
| prenom_utilisateur  VARCHAR(255)      , |  | ||||||
| mail_principal      VARCHAR(255)      , |  | ||||||
| mail_secondaire     VARCHAR(255)      , |  | ||||||
| numero_telephone    VARCHAR(15)       , |  | ||||||
| CONSTRAINT pk_utilisateur PRIMARY KEY (id_utilisateur) ); |  | ||||||
|  |  | ||||||
| CREATE TABLE entrepreneurs |  | ||||||
| ( |  | ||||||
| id_entrepreneur SERIAL REFERENCES utilisateurs (id_utilisateur),  |  | ||||||
| ecole         VARCHAR(255)         , |  | ||||||
| filiere       VARCHAR(255)         , |  | ||||||
| status_snee   BOOLEAN              , |  | ||||||
| CONSTRAINT pk_entrepreneur PRIMARY KEY (id_entrepreneur) ); |  | ||||||
|  |  | ||||||
| CREATE TABLE administrateurs |  | ||||||
| (  |  | ||||||
| id_administrateur SERIAL REFERENCES utilisateurs (id_utilisateur),  |  | ||||||
| CONSTRAINT pk_administrateur PRIMARY KEY (id_administrateur) ); |  | ||||||
|  |  | ||||||
| CREATE TABLE sections |  | ||||||
| ( |  | ||||||
| id_section          SERIAL    NOT NULL, |  | ||||||
| titre               VARCHAR(255)      , |  | ||||||
| contenu_section     TEXT              , |  | ||||||
| date_modification   TIMESTAMP         , |  | ||||||
| CONSTRAINT pk_section PRIMARY KEY (id_section) ); |  | ||||||
|  |  | ||||||
| CREATE TABLE rendez_vous |  | ||||||
| ( |  | ||||||
| id_rdv      SERIAL    NOT NULL, |  | ||||||
| date_rdv    DATE              , |  | ||||||
| heure_rdv   TIME              , |  | ||||||
| duree_rdv   TIME              , |  | ||||||
| lieu_rdv    VARCHAR(255)      , |  | ||||||
| sujet_rdv   TEXT              , |  | ||||||
| CONSTRAINT pk_rdv PRIMARY KEY (id_rdv) ); |  | ||||||
|  |  | ||||||
| CREATE TABLE comptes_rendus  |  | ||||||
| ( |  | ||||||
| id_compte_rendu         SERIAL    NOT NULL, |  | ||||||
| contenu_compte_rendu    TEXT              , |  | ||||||
| CONSTRAINT pk_compte_rendu PRIMARY KEY (id_compte_rendu) ); |  | ||||||
|  |  | ||||||
| CREATE TABLE concerner |  | ||||||
| ( |  | ||||||
| id_section SERIAL REFERENCES sections (id_section), |  | ||||||
| id_rdv SERIAL REFERENCES sections (id_rdv), |  | ||||||
| CONSTRAINT pk_concerner PRIMARY KEY (id_section, id_rdv)  );  |  | ||||||
|  |  | ||||||
|  |  | ||||||
| ALTER TABLE projets |  | ||||||
|           ADD CONSTRAINT fk1_projet  FOREIGN KEY (id_administrateur) |  | ||||||
|           REFERENCES administrateurs (id_administrateur) |  | ||||||
|           ON DELETE CASCADE; |  | ||||||
|  |  | ||||||
| ALTER TABLE projets |  | ||||||
|     ADD CONSTRAINT fk2_projet FOREIGN KEY (id_entrepreneur_participation) |  | ||||||
|         REFERENCES entrepreneurs (id_entrepreneur) |  | ||||||
|         ON DELETE CASCADE; |  | ||||||
|  |  | ||||||
| ALTER TABLE entrepreneurs  |  | ||||||
|           ADD CONSTRAINT fk1_entrepreneur FOREIGN KEY (id_projet_propose) |  | ||||||
|           REFERENCES projets (id_projet) |  | ||||||
|           ON DELETE CASCADE; |  | ||||||
|  |  | ||||||
| ALTER TABLE sections  |  | ||||||
|           ADD CONSTRAINT fk1_section FOREIGN KEY (id_projet) |  | ||||||
|           REFERENCES projets (id_projet) |  | ||||||
|           ON DELETE CASCADE; |  | ||||||
|  |  | ||||||
| ALTER TABLE sections  |  | ||||||
|           ADD CONSTRAINT fk2_section FOREIGN KEY (id_administrateur) |  | ||||||
|           REFERENCES administrateurs (id_administrateur) |  | ||||||
|           ON DELETE CASCADE; |  | ||||||
|  |  | ||||||
| ALTER TABLE rendez-vous  |  | ||||||
|           ADD CONSTRAINT fk1_rdv FOREIGN KEY (id_entrepreneur) |  | ||||||
|           REFERENCES entrepreneurs (id_entrepreneur) |  | ||||||
|           ON DELETE CASCADE; |  | ||||||
|  |  | ||||||
| ALTER TABLE rendez-vous  |  | ||||||
|           ADD CONSTRAINT fk2_rdv FOREIGN KEY (id_administrateur) |  | ||||||
|           REFERENCES administrateurs (id_administrateur) |  | ||||||
|           ON DELETE CASCADE; |  | ||||||
|  |  | ||||||
| ALTER TABLE comptes-rendus  |  | ||||||
|           ADD CONSTRAINT fk1_compte_rendu FOREIGN KEY (id_rdv) |  | ||||||
|           REFERENCES rendez_vous (id_rdv) |  | ||||||
|           ON DELETE CASCADE; |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
| @@ -0,0 +1,331 @@ | |||||||
|  | package enseirb.myinpulse; | ||||||
|  |  | ||||||
|  | import static enseirb.myinpulse.model.ProjectDecisionValue.*; | ||||||
|  |  | ||||||
|  | import static org.junit.jupiter.api.Assertions.*; | ||||||
|  |  | ||||||
|  | import enseirb.myinpulse.model.*; | ||||||
|  | import enseirb.myinpulse.service.AdminApiService; | ||||||
|  | import enseirb.myinpulse.service.UtilsService; | ||||||
|  | import enseirb.myinpulse.service.database.*; | ||||||
|  |  | ||||||
|  | import org.junit.jupiter.api.BeforeAll; | ||||||
|  | import org.junit.jupiter.api.Test; | ||||||
|  | import org.springframework.beans.factory.annotation.Autowired; | ||||||
|  | import org.springframework.boot.test.context.SpringBootTest; | ||||||
|  | import org.springframework.transaction.annotation.Transactional; | ||||||
|  | import org.springframework.web.server.ResponseStatusException; | ||||||
|  |  | ||||||
|  | import java.time.LocalDate; | ||||||
|  | import java.time.LocalDateTime; | ||||||
|  | import java.time.LocalTime; | ||||||
|  | import java.util.ArrayList; | ||||||
|  | import java.util.List; | ||||||
|  |  | ||||||
|  | @SpringBootTest | ||||||
|  | @Transactional | ||||||
|  | public class AdminApiServiceTest { | ||||||
|  |     private static long administratorid; | ||||||
|  |     private static Administrator administrator; | ||||||
|  |     private static Entrepreneur entrepreneur; | ||||||
|  |     private static Appointment appt; | ||||||
|  |     private static Project p; | ||||||
|  |     @Autowired private AdminApiService adminApiService; | ||||||
|  |     @Autowired private ProjectService projectService; | ||||||
|  |     @Autowired private EntrepreneurService entrepreneurService; | ||||||
|  |     @Autowired private SectionCellService sectionCellService; | ||||||
|  |     @Autowired private AppointmentService appointmentService; | ||||||
|  |     @Autowired private UtilsService utilsService; | ||||||
|  |  | ||||||
|  |     @BeforeAll | ||||||
|  |     static void setup( | ||||||
|  |             @Autowired AdministratorService administratorService, | ||||||
|  |             @Autowired ProjectService projectService, | ||||||
|  |             @Autowired EntrepreneurService entrepreneurService, | ||||||
|  |             @Autowired AppointmentService appoitmentService, | ||||||
|  |             @Autowired SectionCellService sectionCellService) { | ||||||
|  |         administratorService.addAdministrator( | ||||||
|  |                 new Administrator( | ||||||
|  |                         "admin", | ||||||
|  |                         "admin", | ||||||
|  |                         "testAdminEmpty@example.com", | ||||||
|  |                         "testAdmin@example.com", | ||||||
|  |                         "")); | ||||||
|  |         administrator = | ||||||
|  |                 administratorService.addAdministrator( | ||||||
|  |                         new Administrator( | ||||||
|  |                                 "admin2", | ||||||
|  |                                 "admin2", | ||||||
|  |                                 "testAdminFull@example.com", | ||||||
|  |                                 "testAdmin@example.com", | ||||||
|  |                                 "")); | ||||||
|  |         administratorid = administrator.getIdUser(); | ||||||
|  |  | ||||||
|  |         entrepreneur = | ||||||
|  |                 new Entrepreneur( | ||||||
|  |                         "JeSuisUnEntrepreneurDeCompet", | ||||||
|  |                         "EtUé", | ||||||
|  |                         "Entrepreneur@inpulse.com", | ||||||
|  |                         "mail2", | ||||||
|  |                         "phone", | ||||||
|  |                         "Ensimag    nan jdeconne ENSEIRB (-matmeca mais on s'en fout)", | ||||||
|  |                         "info ofc", | ||||||
|  |                         false); | ||||||
|  |         entrepreneurService.addEntrepreneur(entrepreneur); | ||||||
|  |  | ||||||
|  |         Entrepreneur entrepreneur2 = | ||||||
|  |                 new Entrepreneur( | ||||||
|  |                         "GDProjets", "", "Entrepreneur2@inpulse.com", "", "", "", "info ofc", true); | ||||||
|  |         entrepreneurService.addEntrepreneur(entrepreneur2); | ||||||
|  |  | ||||||
|  |         p = | ||||||
|  |                 projectService.addNewProject( | ||||||
|  |                         new Project( | ||||||
|  |                                 "sampleProjectAdminApiService", | ||||||
|  |                                 null, | ||||||
|  |                                 LocalDate.now(), | ||||||
|  |                                 ACTIVE, | ||||||
|  |                                 administratorService.getAdministratorByPrimaryMain( | ||||||
|  |                                         "testAdminFull@example.com"))); | ||||||
|  |  | ||||||
|  |         entrepreneurService.updateEntrepreneurProjectParticipation(entrepreneur2.getIdUser(), p); | ||||||
|  |  | ||||||
|  |         appt = | ||||||
|  |                 new Appointment( | ||||||
|  |                         null, | ||||||
|  |                         LocalDate.now(), | ||||||
|  |                         LocalTime.now(), | ||||||
|  |                         LocalTime.now(), | ||||||
|  |                         "Salle TD 03", | ||||||
|  |                         "Discussion importante"); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     private <T> List<T> IterableToList(Iterable<T> iterable) { | ||||||
|  |         List<T> l = new ArrayList<>(); | ||||||
|  |         iterable.forEach(l::add); | ||||||
|  |         return l; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Test | ||||||
|  |     void getProjectOfAdminIsEmpty() { | ||||||
|  |         Iterable<Project> projects = | ||||||
|  |                 adminApiService.getProjectsOfAdmin("testAdminEmpty@example.com"); | ||||||
|  |         assertEquals(0, IterableToList(projects).size()); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Test | ||||||
|  |     void getProjectOfInexistantAdminFails() { | ||||||
|  |         String nonExistentAdminEmail = "testInexistantAdmin@example.com"; | ||||||
|  |  | ||||||
|  |         assertThrows( | ||||||
|  |                 ResponseStatusException.class, | ||||||
|  |                 () -> { | ||||||
|  |                     adminApiService.getProjectsOfAdmin(nonExistentAdminEmail); | ||||||
|  |                 }); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Test | ||||||
|  |     void getProjectOfAdminNotEmpty() { | ||||||
|  |         Iterable<Project> projects = | ||||||
|  |                 adminApiService.getProjectsOfAdmin("testAdminFull@example.com"); | ||||||
|  |         List<Project> l = IterableToList(projects); | ||||||
|  |         assertEquals(1, l.size()); | ||||||
|  |         Project p = l.getFirst(); | ||||||
|  |         assertEquals("sampleProjectAdminApiService", p.getProjectName()); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Test | ||||||
|  |     void getPendingProjectsEmpty() { | ||||||
|  |         assertEquals(0, IterableToList(this.adminApiService.getPendingProjects()).size()); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Test | ||||||
|  |     void getPendingProjectsNotEmpty() { | ||||||
|  |         this.projectService.addNewProject( | ||||||
|  |                 new Project( | ||||||
|  |                         "PendingProjectAdminApiService1", null, LocalDate.now(), PENDING, null)); | ||||||
|  |         this.projectService.addNewProject( | ||||||
|  |                 new Project( | ||||||
|  |                         "PendingProjectAdminApiService2", null, LocalDate.now(), PENDING, null)); | ||||||
|  |         Iterable<Project> pendingProjects = this.adminApiService.getPendingProjects(); | ||||||
|  |         List<Project> pendingProjectsList = IterableToList(pendingProjects); | ||||||
|  |         assertEquals(2, pendingProjectsList.size()); | ||||||
|  |         assertTrue( | ||||||
|  |                 List.of("PendingProjectAdminApiService1", "PendingProjectAdminApiService2") | ||||||
|  |                         .contains(pendingProjectsList.getFirst().getProjectName())); | ||||||
|  |         assertTrue( | ||||||
|  |                 List.of("PendingProjectAdminApiService1", "PendingProjectAdminApiService2") | ||||||
|  |                         .contains(pendingProjectsList.getLast().getProjectName())); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Test | ||||||
|  |     void validateInexistantProject() { | ||||||
|  |         ProjectDecision d = new ProjectDecision(-1, 0, 1); | ||||||
|  |         assertThrows(ResponseStatusException.class, () -> this.adminApiService.validateProject(d)); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Test | ||||||
|  |     void validateExistantProject() { | ||||||
|  |         Project p = | ||||||
|  |                 new Project("PendingProjectAdminApiService2", null, LocalDate.now(), PENDING, null); | ||||||
|  |         this.projectService.addNewProject(p); | ||||||
|  |         assertEquals(PENDING, p.getProjectStatus()); | ||||||
|  |         ProjectDecision d = new ProjectDecision(p.getIdProject(), administratorid, 1); | ||||||
|  |         this.adminApiService.validateProject(d); | ||||||
|  |         assertEquals(ACTIVE, p.getProjectStatus()); | ||||||
|  |  | ||||||
|  |         // Check if the project was really updated in the database | ||||||
|  |         assertEquals(0, IterableToList(this.adminApiService.getPendingProjects()).size()); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Test | ||||||
|  |     void refuseExistantProject() { | ||||||
|  |         Project p = | ||||||
|  |                 new Project("PendingProjectAdminApiService2", null, LocalDate.now(), PENDING, null); | ||||||
|  |         this.projectService.addNewProject(p); | ||||||
|  |         assertEquals(PENDING, p.getProjectStatus()); | ||||||
|  |         ProjectDecision d = new ProjectDecision(p.getIdProject(), administratorid, 0); | ||||||
|  |         this.adminApiService.validateProject(d); | ||||||
|  |         assertEquals(REJECTED, p.getProjectStatus()); | ||||||
|  |  | ||||||
|  |         // Check if the project was really updated in the database | ||||||
|  |         assertEquals(0, IterableToList(this.adminApiService.getPendingProjects()).size()); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Test | ||||||
|  |     void addProject() { | ||||||
|  |         assertEquals(0, IterableToList(this.adminApiService.getPendingProjects()).size()); | ||||||
|  |         Project p1 = | ||||||
|  |                 new Project("PendingProjectAdminApiService2", null, LocalDate.now(), PENDING, null); | ||||||
|  |         this.adminApiService.addNewProject(p1); | ||||||
|  |  | ||||||
|  |         assertEquals(1, IterableToList(this.adminApiService.getPendingProjects()).size()); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Test | ||||||
|  |     void addProjectToAdmin() { | ||||||
|  |         assertEquals(0, administrator.getListProject().size()); | ||||||
|  |         Project p1 = new Project("addProjectToAdmin", null, LocalDate.now(), ACTIVE, administrator); | ||||||
|  |         this.adminApiService.addNewProject(p1); | ||||||
|  |         assertEquals(1, administrator.getListProject().size()); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Test | ||||||
|  |     void addProjectToUser() { | ||||||
|  |         assertNull(entrepreneur.getProjectParticipation()); | ||||||
|  |         Project p1 = | ||||||
|  |                 new Project("addProjectToAdmin", null, LocalDate.now(), ACTIVE, null, entrepreneur); | ||||||
|  |         this.adminApiService.addNewProject(p1); | ||||||
|  |         assertEquals(p1, entrepreneur.getProjectParticipation()); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Test | ||||||
|  |     void addProjectWithManyUsers() { | ||||||
|  |         Entrepreneur e1 = new Entrepreneur(); | ||||||
|  |         Entrepreneur e2 = new Entrepreneur(); | ||||||
|  |         Entrepreneur e3 = new Entrepreneur(); | ||||||
|  |         assertNull(e1.getProjectParticipation()); | ||||||
|  |         assertNull(e2.getProjectParticipation()); | ||||||
|  |         assertNull(e3.getProjectParticipation()); | ||||||
|  |         Project p1 = new Project("addProjectToAdmin", null, LocalDate.now(), ACTIVE, null, null); | ||||||
|  |         p1.updateListEntrepreneurParticipation(e1); | ||||||
|  |         p1.updateListEntrepreneurParticipation(e2); | ||||||
|  |         p1.updateListEntrepreneurParticipation(e3); | ||||||
|  |         this.adminApiService.addNewProject(p1); | ||||||
|  |         assertEquals(p1, e1.getProjectParticipation()); | ||||||
|  |         assertEquals(p1, e2.getProjectParticipation()); | ||||||
|  |         assertEquals(p1, e3.getProjectParticipation()); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Test | ||||||
|  |     void addDuplicateProject() { | ||||||
|  |         Project p1 = | ||||||
|  |                 new Project("PendingProjectAdminApiService2", null, LocalDate.now(), PENDING, null); | ||||||
|  |         Project p2 = | ||||||
|  |                 new Project("PendingProjectAdminApiService2", null, LocalDate.now(), PENDING, null); | ||||||
|  |         this.adminApiService.addNewProject(p1); | ||||||
|  |         assertThrows(ResponseStatusException.class, () -> this.adminApiService.addNewProject(p2)); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     // We could do a delete active project, but it's not really useful. | ||||||
|  |     @Test | ||||||
|  |     void deletePendingProject() { | ||||||
|  |         int oldsize = IterableToList(this.adminApiService.getPendingProjects()).size(); | ||||||
|  |         Project p1 = | ||||||
|  |                 new Project("PendingProjectAdminApiService2", null, LocalDate.now(), PENDING, null); | ||||||
|  |         Project p2 = this.adminApiService.addNewProject(p1); | ||||||
|  |  | ||||||
|  |         assertEquals(oldsize + 1, IterableToList(this.adminApiService.getPendingProjects()).size()); | ||||||
|  |         this.adminApiService.deleteProject(p2.getIdProject()); | ||||||
|  |  | ||||||
|  |         assertEquals(oldsize, IterableToList(this.adminApiService.getPendingProjects()).size()); | ||||||
|  |         for (int i = 0; i < oldsize; i++) { | ||||||
|  |             assertNotEquals( | ||||||
|  |                     p1.getIdProject(), | ||||||
|  |                     IterableToList(this.adminApiService.getPendingProjects()) | ||||||
|  |                             .get(i) | ||||||
|  |                             .getIdProject()); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Test | ||||||
|  |     void getUpcommingAppointmentUnkwnownUser() { | ||||||
|  |         assertThrows( | ||||||
|  |                 ResponseStatusException.class, | ||||||
|  |                 () -> { | ||||||
|  |                     Iterable<Appointment> a = | ||||||
|  |                             this.adminApiService.getUpcomingAppointments( | ||||||
|  |                                     "entrepreneur-inexistent@mail.fr"); | ||||||
|  |                 }); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Test | ||||||
|  |     void getUpcommingAppointmentNoProject() { | ||||||
|  |         assertThrows( | ||||||
|  |                 ResponseStatusException.class, | ||||||
|  |                 () -> { | ||||||
|  |                     Iterable<Appointment> a = | ||||||
|  |                             this.adminApiService.getUpcomingAppointments( | ||||||
|  |                                     "Entrepreneur@inpulse.com"); | ||||||
|  |                 }); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Test | ||||||
|  |     void getUpcommingAppointmentEmpty() { | ||||||
|  |         Iterable<Appointment> a = | ||||||
|  |                 this.adminApiService.getUpcomingAppointments("Entrepreneur2@inpulse.com"); | ||||||
|  |         assertEquals(0, IterableToList(a).size()); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Test | ||||||
|  |     void validateEntrepreneurAccount() { | ||||||
|  |         assertTrue(entrepreneurService.getEntrepreneurById(entrepreneur.getIdUser()).isPending()); | ||||||
|  |         assertEquals(2, IterableToList(adminApiService.getPendingUsers()).size()); | ||||||
|  |         adminApiService.validateEntrepreneurAccount(entrepreneur.getIdUser(), ""); | ||||||
|  |         assertFalse(entrepreneurService.getEntrepreneurById(entrepreneur.getIdUser()).isPending()); | ||||||
|  |         assertEquals(1, IterableToList(adminApiService.getPendingUsers()).size()); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Test | ||||||
|  |     void testCreateApptRepport() { | ||||||
|  |         System.err.println(appt.getIdAppointment()); | ||||||
|  |         SectionCell s = | ||||||
|  |                 sectionCellService.addNewSectionCell( | ||||||
|  |                         new SectionCell(null, 1L, "jaja", LocalDateTime.now(), p)); | ||||||
|  |         appointmentService.addNewAppointment(appt); | ||||||
|  |  | ||||||
|  |         appointmentService.updateAppointmentListSectionCell(appt.getIdAppointment(), s); | ||||||
|  |         projectService.updateProjectListSectionCell(p.getIdProject(), s); | ||||||
|  |         this.adminApiService.createAppointmentReport( | ||||||
|  |                 appt.getIdAppointment(), | ||||||
|  |                 new Report(null, "je rapporte de fou"), | ||||||
|  |                 "testAdminFull@example.com"); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Test | ||||||
|  |     void testSetAdmin() { | ||||||
|  |         assertFalse(utilsService.isAnAdmin(entrepreneur.getPrimaryMail())); | ||||||
|  |         adminApiService.setAdmin(entrepreneur.getIdUser(), ""); | ||||||
|  |         assertTrue(utilsService.isAnAdmin(entrepreneur.getPrimaryMail())); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -0,0 +1,324 @@ | |||||||
|  | package enseirb.myinpulse; | ||||||
|  |  | ||||||
|  | import static enseirb.myinpulse.model.ProjectDecisionValue.*; | ||||||
|  |  | ||||||
|  | import static org.junit.jupiter.api.Assertions.*; | ||||||
|  |  | ||||||
|  | import enseirb.myinpulse.model.*; | ||||||
|  | import enseirb.myinpulse.service.EntrepreneurApiService; | ||||||
|  | import enseirb.myinpulse.service.database.*; | ||||||
|  |  | ||||||
|  | import org.junit.jupiter.api.BeforeAll; | ||||||
|  | import org.junit.jupiter.api.Test; | ||||||
|  | import org.springframework.beans.factory.annotation.Autowired; | ||||||
|  | import org.springframework.boot.test.context.SpringBootTest; | ||||||
|  | import org.springframework.transaction.annotation.Transactional; | ||||||
|  | import org.springframework.web.server.ResponseStatusException; | ||||||
|  |  | ||||||
|  | import java.time.LocalDate; | ||||||
|  | import java.time.LocalDateTime; | ||||||
|  | import java.time.LocalTime; | ||||||
|  | import java.util.ArrayList; | ||||||
|  | import java.util.List; | ||||||
|  |  | ||||||
|  | @SpringBootTest | ||||||
|  | @Transactional | ||||||
|  | public class EntrepreneurApiServiceTest { | ||||||
|  |     private static Entrepreneur entrepreneur; | ||||||
|  |     private static Project project; | ||||||
|  |     private static Iterable<SectionCell> sectionCells2; | ||||||
|  |     private static Iterable<SectionCell> sectionCells3; | ||||||
|  |     @Autowired private EntrepreneurApiService entrepreneurApiService; | ||||||
|  |     @Autowired private EntrepreneurService entrepreneurService; | ||||||
|  |     @Autowired private ProjectService projectService; | ||||||
|  |     @Autowired private SectionCellService sectionCellService; | ||||||
|  |     @Autowired private AnnotationService annotationService; | ||||||
|  |     @Autowired private AppointmentService appointmentService; | ||||||
|  |  | ||||||
|  |     @BeforeAll | ||||||
|  |     static void setup( | ||||||
|  |             @Autowired EntrepreneurService entrepreneurService, | ||||||
|  |             @Autowired ProjectService projectService, | ||||||
|  |             @Autowired SectionCellService sectionCellService) { | ||||||
|  |         entrepreneur = | ||||||
|  |                 entrepreneurService.addEntrepreneur( | ||||||
|  |                         new Entrepreneur( | ||||||
|  |                                 "entre", | ||||||
|  |                                 "preneur", | ||||||
|  |                                 "entrepreneur@mail.fr", | ||||||
|  |                                 "entrepreneur2@mail.fr", | ||||||
|  |                                 "01 45 71 25 48", | ||||||
|  |                                 "ENSEIRB", | ||||||
|  |                                 "Info", | ||||||
|  |                                 false)); | ||||||
|  |         entrepreneurService.addEntrepreneur( | ||||||
|  |                 new Entrepreneur( | ||||||
|  |                         "entre2", | ||||||
|  |                         "preneur2", | ||||||
|  |                         "testentrepreneur@mail.fr", | ||||||
|  |                         "testentrepreneur2@mail.fr", | ||||||
|  |                         "", | ||||||
|  |                         "ENSEGID", | ||||||
|  |                         "", | ||||||
|  |                         true)); | ||||||
|  |         project = | ||||||
|  |                 projectService.addNewProject( | ||||||
|  |                         new Project("Project", null, LocalDate.now(), ACTIVE, null, entrepreneur)); | ||||||
|  |         entrepreneurService.updateEntrepreneurProjectProposed(entrepreneur.getIdUser(), project); | ||||||
|  |         entrepreneurService.updateEntrepreneurProjectParticipation( | ||||||
|  |                 entrepreneur.getIdUser(), project); | ||||||
|  |         SectionCell s1 = | ||||||
|  |                 sectionCellService.addNewSectionCell( | ||||||
|  |                         new SectionCell( | ||||||
|  |                                 null, | ||||||
|  |                                 2L, | ||||||
|  |                                 "contenu très intéressant", | ||||||
|  |                                 LocalDateTime.now(), | ||||||
|  |                                 project)); | ||||||
|  |  | ||||||
|  |         SectionCell s2 = | ||||||
|  |                 sectionCellService.addNewSectionCell( | ||||||
|  |                         new SectionCell( | ||||||
|  |                                 null, | ||||||
|  |                                 3L, | ||||||
|  |                                 "contenu très intéressant2", | ||||||
|  |                                 LocalDateTime.now(), | ||||||
|  |                                 project)); | ||||||
|  |         sectionCells2 = sectionCellService.getSectionCellsByProject(project, 2L); | ||||||
|  |         sectionCells3 = sectionCellService.getSectionCellsByProject(project, 3L); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     private <T> List<T> IterableToList(Iterable<T> iterable) { | ||||||
|  |         List<T> l = new ArrayList<>(); | ||||||
|  |         iterable.forEach(l::add); | ||||||
|  |         return l; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Test | ||||||
|  |     void editValidSectionCell() { | ||||||
|  |         System.out.println("editValidSectionCell : "); | ||||||
|  |         SectionCell modified = IterableToList(sectionCells2).getLast(); | ||||||
|  |         this.sectionCellService.updateSectionCellListAnnotation( | ||||||
|  |                 modified.getIdSectionCell(), | ||||||
|  |                 annotationService.addNewAnnotation(new Annotation(null, "oui j'annote encore"))); | ||||||
|  |         this.sectionCellService.updateSectionCellListAppointment( | ||||||
|  |                 modified.getIdSectionCell(), | ||||||
|  |                 appointmentService.addNewAppointment( | ||||||
|  |                         new Appointment( | ||||||
|  |                                 null, | ||||||
|  |                                 LocalDate.now(), | ||||||
|  |                                 LocalTime.now(), | ||||||
|  |                                 LocalTime.of(2, 5), | ||||||
|  |                                 "TD14", | ||||||
|  |                                 "clément s'est plaint"))); | ||||||
|  |         entrepreneurApiService.editSectionCell( | ||||||
|  |                 modified.getIdSectionCell(), "modified content", "entrepreneur@mail.fr"); | ||||||
|  |         // We get the data from the database again. | ||||||
|  |         SectionCell s = | ||||||
|  |                 IterableToList(sectionCellService.getSectionCellsByProject(project, 2L)).getLast(); | ||||||
|  |         assertEquals("modified content", s.getContentSectionCell()); | ||||||
|  |         assertEquals( | ||||||
|  |                 2, IterableToList(sectionCellService.getSectionCellsByProject(project, 2L)).size()); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Test | ||||||
|  |     void editInvalidSectionCell() { | ||||||
|  |         System.out.println("editInvalidSectionCell : "); | ||||||
|  |         assertThrows( | ||||||
|  |                 ResponseStatusException.class, | ||||||
|  |                 () -> | ||||||
|  |                         entrepreneurApiService.editSectionCell( | ||||||
|  |                                 -1L, "should not be modified", "entrepreneur@mail.fr")); | ||||||
|  |         SectionCell s = | ||||||
|  |                 IterableToList(sectionCellService.getSectionCellsByProject(project, 2L)).getLast(); | ||||||
|  |         assertEquals("contenu très intéressant", s.getContentSectionCell()); | ||||||
|  |         assertEquals( | ||||||
|  |                 1, IterableToList(sectionCellService.getSectionCellsByProject(project, 2L)).size()); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Test | ||||||
|  |     void editSectionCellInvalidAccess() { | ||||||
|  |         System.out.println("editSectionCellInvalidAccess : "); | ||||||
|  |         assertThrows( | ||||||
|  |                 ResponseStatusException.class, | ||||||
|  |                 () -> | ||||||
|  |                         entrepreneurApiService.editSectionCell( | ||||||
|  |                                 IterableToList(sectionCells3).getFirst().getIdSectionCell(), | ||||||
|  |                                 "should not be modified", | ||||||
|  |                                 "testentrepreneur@mail.fr")); | ||||||
|  |         SectionCell s = | ||||||
|  |                 IterableToList(sectionCellService.getSectionCellsByProject(project, 2L)).getFirst(); | ||||||
|  |  | ||||||
|  |         assertEquals("contenu très intéressant", s.getContentSectionCell()); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Test | ||||||
|  |     void editNullSectionCell() { | ||||||
|  |         System.out.println("editNullSectionCell : "); | ||||||
|  |         assertThrows( | ||||||
|  |                 ResponseStatusException.class, | ||||||
|  |                 () -> | ||||||
|  |                         entrepreneurApiService.editSectionCell( | ||||||
|  |                                 null, "modified content", "entrepreneur@mail.fr")); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Test | ||||||
|  |     void removeValidSectionCell() { | ||||||
|  |         System.out.println("removeValidSectionCell : "); | ||||||
|  |         SectionCell tmpCell = | ||||||
|  |                 sectionCellService.addNewSectionCell( | ||||||
|  |                         new SectionCell( | ||||||
|  |                                 null, 2L, "contenu temporaire", LocalDateTime.now(), project)); | ||||||
|  |         assertEquals( | ||||||
|  |                 2, IterableToList(sectionCellService.getSectionCellsByProject(project, 2L)).size()); | ||||||
|  |         assertDoesNotThrow( | ||||||
|  |                 () -> | ||||||
|  |                         entrepreneurApiService.removeSectionCell( | ||||||
|  |                                 tmpCell.getIdSectionCell(), "entrepreneur@mail.fr")); | ||||||
|  |         assertEquals( | ||||||
|  |                 tmpCell.getIdReference(), | ||||||
|  |                 IterableToList(sectionCellService.getSectionCellsByProject(project, -1L)) | ||||||
|  |                         .getLast() | ||||||
|  |                         .getIdReference()); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Test | ||||||
|  |     void removeInvalidSectionCell() { | ||||||
|  |         System.out.println("removeInvalidSectionCell : "); | ||||||
|  |         assertThrows( | ||||||
|  |                 ResponseStatusException.class, | ||||||
|  |                 () -> entrepreneurApiService.removeSectionCell(-1L, "entrepreneur@mail.fr")); | ||||||
|  |         SectionCell s = | ||||||
|  |                 IterableToList(sectionCellService.getSectionCellsByProject(project, 2L)).getFirst(); | ||||||
|  |  | ||||||
|  |         assertEquals("contenu très intéressant", s.getContentSectionCell()); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Test | ||||||
|  |     void removeNullSectionCell() { | ||||||
|  |         System.out.println("removeNullSectionCell : "); | ||||||
|  |         assertThrows( | ||||||
|  |                 ResponseStatusException.class, | ||||||
|  |                 () -> entrepreneurApiService.removeSectionCell(null, "entrepreneur@mail.fr")); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Test | ||||||
|  |     void addValidSectionCell() { | ||||||
|  |         System.out.println("addValidSectionCell : "); | ||||||
|  |         SectionCell added = | ||||||
|  |                 sectionCellService.addNewSectionCell( | ||||||
|  |                         new SectionCell(null, 2L, "contenu ajouté", LocalDateTime.now(), project)); | ||||||
|  |         added.updateListAnnotation( | ||||||
|  |                 annotationService.addNewAnnotation(new Annotation(null, "oui j'annote"))); | ||||||
|  |         added.updateAppointmentSectionCell( | ||||||
|  |                 appointmentService.addNewAppointment( | ||||||
|  |                         new Appointment( | ||||||
|  |                                 null, | ||||||
|  |                                 LocalDate.now(), | ||||||
|  |                                 LocalTime.now(), | ||||||
|  |                                 LocalTime.of(2, 5), | ||||||
|  |                                 "TD15", | ||||||
|  |                                 "clément qui se plaint"))); | ||||||
|  |         entrepreneurApiService.addSectionCell(added, "entrepreneur@mail.fr"); | ||||||
|  |         SectionCell s = | ||||||
|  |                 IterableToList(sectionCellService.getSectionCellsByProject(project, 2L)).getLast(); | ||||||
|  |         assertEquals("contenu ajouté", s.getContentSectionCell()); | ||||||
|  |         assertEquals( | ||||||
|  |                 2, IterableToList(sectionCellService.getSectionCellsByProject(project, 2L)).size()); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Test | ||||||
|  |     void addSectionCellInvalidAccess() { | ||||||
|  |         System.out.println("addSectionCellInvalidAccess : "); | ||||||
|  |         SectionCell added = | ||||||
|  |                 new SectionCell(null, 2L, "contenu ajouté", LocalDateTime.now(), project); | ||||||
|  |         assertThrows( | ||||||
|  |                 ResponseStatusException.class, | ||||||
|  |                 () -> entrepreneurApiService.addSectionCell(added, "fauxentrepreneur@mail.fr")); | ||||||
|  |         SectionCell s = | ||||||
|  |                 IterableToList(sectionCellService.getSectionCellsByProject(project, 2L)).getLast(); | ||||||
|  |         assertEquals( | ||||||
|  |                 1, IterableToList(sectionCellService.getSectionCellsByProject(project, 2L)).size()); | ||||||
|  |         assertEquals("contenu très intéressant", s.getContentSectionCell()); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Test | ||||||
|  |     void addInvalidSectionCell() { | ||||||
|  |         System.out.println("addInvalidSectionCell : "); | ||||||
|  |         SectionCell added = | ||||||
|  |                 sectionCellService.addNewSectionCell( | ||||||
|  |                         new SectionCell(null, -1L, "contenu ajouté", LocalDateTime.now(), project)); | ||||||
|  |         assertThrows( | ||||||
|  |                 ResponseStatusException.class, | ||||||
|  |                 () -> entrepreneurApiService.addSectionCell(added, "entrepreneur@mail.fr")); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Test | ||||||
|  |     void addNullSectionCell() { | ||||||
|  |         System.out.println("addNullSectionCell : "); | ||||||
|  |         assertThrows( | ||||||
|  |                 ResponseStatusException.class, | ||||||
|  |                 () -> entrepreneurApiService.addSectionCell(null, "entrepreneur@mail.fr")); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Test | ||||||
|  |     void requestValidProject() { | ||||||
|  |         System.out.println("requestValidProject : "); | ||||||
|  |         int nb_project = IterableToList(this.projectService.getAllProjects()).size(); | ||||||
|  |         Project validProject = | ||||||
|  |                 new Project("validProject", null, LocalDate.now(), ACTIVE, null, entrepreneur); | ||||||
|  |         validProject.updateListEntrepreneurParticipation( | ||||||
|  |                 IterableToList(entrepreneurService.getAllEntrepreneurs()).getLast()); | ||||||
|  |         validProject.updateListSectionCell((IterableToList(sectionCells2).getFirst())); | ||||||
|  |         entrepreneurApiService.requestNewProject(validProject, "entrepreneur@mail.fr"); | ||||||
|  |         assertEquals(PENDING, validProject.getProjectStatus()); | ||||||
|  |         assertEquals((nb_project + 1), IterableToList(this.projectService.getAllProjects()).size()); | ||||||
|  |         assertEquals( | ||||||
|  |                 IterableToList(entrepreneurService.getAllEntrepreneurs()).getLast(), | ||||||
|  |                 validProject.getListEntrepreneurParticipation().getLast()); | ||||||
|  |         assertEquals( | ||||||
|  |                 IterableToList(sectionCells2).getFirst().getIdSectionCell(), | ||||||
|  |                 validProject.getListSectionCell().getFirst().getIdSectionCell()); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Test | ||||||
|  |     void requestNullProject() { | ||||||
|  |         System.out.println("requestNullProject : "); | ||||||
|  |         assertThrows( | ||||||
|  |                 ResponseStatusException.class, | ||||||
|  |                 () -> entrepreneurApiService.requestNewProject(null, "entrepreneur@mail.fr")); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Test | ||||||
|  |     void createNewValidAccount() { | ||||||
|  |         System.out.println("createNewValidAccount : "); | ||||||
|  |         int nb_entrepreneur = IterableToList(this.entrepreneurService.getAllEntrepreneurs()).size(); | ||||||
|  |         Entrepreneur newEntrepreneur = | ||||||
|  |                 new Entrepreneur( | ||||||
|  |                         "New", | ||||||
|  |                         "Test", | ||||||
|  |                         "mailtest@test.fr", | ||||||
|  |                         "mailtest2@test.fr", | ||||||
|  |                         "0888888888", | ||||||
|  |                         "ENSEIRB", | ||||||
|  |                         "ELEC", | ||||||
|  |                         false, | ||||||
|  |                         true); | ||||||
|  |         assertDoesNotThrow(() -> entrepreneurApiService.createAccount(newEntrepreneur)); | ||||||
|  |         assertEquals( | ||||||
|  |                 (nb_entrepreneur + 1), | ||||||
|  |                 IterableToList(this.entrepreneurService.getAllEntrepreneurs()).size()); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Test | ||||||
|  |     void createExistingAccount() { | ||||||
|  |         System.out.println("createExistingAccount : "); | ||||||
|  |         int nb_entrepreneur = IterableToList(this.entrepreneurService.getAllEntrepreneurs()).size(); | ||||||
|  |         assertThrows( | ||||||
|  |                 ResponseStatusException.class, | ||||||
|  |                 () -> entrepreneurApiService.createAccount(entrepreneur)); | ||||||
|  |         assertEquals( | ||||||
|  |                 nb_entrepreneur, | ||||||
|  |                 IterableToList(this.entrepreneurService.getAllEntrepreneurs()).size()); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -1,5 +1,6 @@ | |||||||
| package enseirb.myinpulse; | package enseirb.myinpulse; | ||||||
|  |  | ||||||
|  | import org.junit.jupiter.api.DisplayName; | ||||||
| import org.junit.jupiter.api.Test; | import org.junit.jupiter.api.Test; | ||||||
| import org.springframework.boot.test.context.SpringBootTest; | import org.springframework.boot.test.context.SpringBootTest; | ||||||
|  |  | ||||||
| @@ -7,5 +8,6 @@ import org.springframework.boot.test.context.SpringBootTest; | |||||||
| class MyinpulseApplicationTests { | class MyinpulseApplicationTests { | ||||||
|  |  | ||||||
|     @Test |     @Test | ||||||
|  |     @DisplayName("contextLoad => Test if the context can load, i.e. the application can start") | ||||||
|     void contextLoads() {} |     void contextLoads() {} | ||||||
| } | } | ||||||
|   | |||||||
| @@ -0,0 +1,922 @@ | |||||||
|  | package enseirb.myinpulse; | ||||||
|  |  | ||||||
|  | import static enseirb.myinpulse.model.ProjectDecisionValue.*; | ||||||
|  | import static org.junit.jupiter.api.Assertions.*; | ||||||
|  | import static org.mockito.ArgumentMatchers.*; | ||||||
|  | import static org.mockito.Mockito.when; | ||||||
|  |  | ||||||
|  | import enseirb.myinpulse.model.*; | ||||||
|  | import enseirb.myinpulse.service.SharedApiService; | ||||||
|  | import enseirb.myinpulse.service.database.*; | ||||||
|  | import jakarta.persistence.EntityManager; | ||||||
|  | import jakarta.persistence.PersistenceContext; | ||||||
|  | import enseirb.myinpulse.service.UtilsService; | ||||||
|  |  | ||||||
|  | import org.junit.jupiter.api.BeforeAll; // Use BeforeAll for static setup | ||||||
|  | import org.junit.jupiter.api.BeforeEach; | ||||||
|  | import org.junit.jupiter.api.Test; // Keep this import | ||||||
|  | import org.mockito.MockitoAnnotations; | ||||||
|  | import org.springframework.beans.factory.annotation.Autowired; | ||||||
|  | import org.springframework.boot.test.context.SpringBootTest; | ||||||
|  | import org.springframework.transaction.annotation.Transactional; | ||||||
|  | import org.springframework.web.server.ResponseStatusException; | ||||||
|  | import org.springframework.http.HttpStatus; | ||||||
|  | import org.springframework.test.context.bean.override.mockito.MockitoBean; | ||||||
|  |  | ||||||
|  | import java.time.LocalDate; | ||||||
|  | import java.time.LocalDateTime; | ||||||
|  | import java.time.LocalTime; | ||||||
|  | import java.time.format.DateTimeFormatter; | ||||||
|  | import java.util.ArrayList; | ||||||
|  | import java.util.List; | ||||||
|  | import java.util.Optional; | ||||||
|  |  | ||||||
|  | // Helper to easily convert Iterable to List | ||||||
|  | class TestUtils { | ||||||
|  |     static <T> List<T> toList(Iterable<T> iterable) { | ||||||
|  |         List<T> list = new ArrayList<>(); | ||||||
|  |         if (iterable != null) { | ||||||
|  |             iterable.forEach(list::add); | ||||||
|  |         } | ||||||
|  |         return list; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | @SpringBootTest | ||||||
|  | @Transactional // Each @Test method runs in a transaction that is rolled back | ||||||
|  | public class SharedApiServiceTest { | ||||||
|  |  | ||||||
|  |     @Autowired private SharedApiService sharedApiService; | ||||||
|  |  | ||||||
|  |     // Autowire actual services to use in setup and test verification | ||||||
|  |     @Autowired private ProjectService projectService; | ||||||
|  |     @Autowired private AdministratorService administratorService; | ||||||
|  |     @Autowired private EntrepreneurService entrepreneurService; | ||||||
|  |     @Autowired private SectionCellService sectionCellService; | ||||||
|  |     @Autowired private AppointmentService appointmentService; | ||||||
|  |  | ||||||
|  |     // Mock UtilsService to control authorization logic | ||||||
|  |     @MockitoBean private UtilsService mockUtilsService; | ||||||
|  |  | ||||||
|  |     // Static variables for data created once before all tests | ||||||
|  |     private static Project staticAuthorizedProject; | ||||||
|  |     private static String staticAuthorizedMail; | ||||||
|  |     private static Administrator staticAuthorizedAdmin; | ||||||
|  |  | ||||||
|  |     private static Project staticUnauthorizedProject; | ||||||
|  |     private static String staticUnauthorizedMail; | ||||||
|  |  | ||||||
|  |     // --- Static Setup (Runs once before all tests) --- | ||||||
|  |     // Use @BeforeAll static method with injected services | ||||||
|  |     @BeforeAll | ||||||
|  |     static void setupOnce( | ||||||
|  |             @Autowired AdministratorService administratorService, | ||||||
|  |             @Autowired ProjectService projectService, | ||||||
|  |             @Autowired EntrepreneurService entrepreneurService) { | ||||||
|  |  | ||||||
|  |         // Create and Save core test data here using injected services | ||||||
|  |         staticAuthorizedAdmin = | ||||||
|  |                 administratorService.addAdministrator(getTestAdmin("static_authorized_admin")); | ||||||
|  |         staticAuthorizedMail = staticAuthorizedAdmin.getPrimaryMail(); | ||||||
|  |  | ||||||
|  |         staticUnauthorizedProject = | ||||||
|  |                 projectService.addNewProject( | ||||||
|  |                         getTestProject( | ||||||
|  |                                 "static_unauthorized_project", | ||||||
|  |                                 administratorService.addAdministrator( | ||||||
|  |                                         getTestAdmin("static_unauthorized_admin")))); | ||||||
|  |         staticUnauthorizedMail = | ||||||
|  |                 administratorService | ||||||
|  |                         .addAdministrator(getTestAdmin("static_unauthorized_user")) | ||||||
|  |                         .getPrimaryMail(); // User who is NOT admin of the unauthorized project | ||||||
|  |  | ||||||
|  |         staticAuthorizedProject = | ||||||
|  |                 projectService.addNewProject( | ||||||
|  |                         getTestProject("static_authorized_project", staticAuthorizedAdmin)); | ||||||
|  |  | ||||||
|  |         // Link a static entrepreneur to the authorized project if needed for some tests | ||||||
|  |         // Entrepreneur staticLinkedEntrepreneur = | ||||||
|  |         // entrepreneurService.addEntrepreneur(getTestEntrepreneur("static_linked_entrepreneur")); | ||||||
|  |         // staticAuthorizedProject.updateListEntrepreneurParticipation(staticLinkedEntrepreneur); | ||||||
|  |         // projectService.addNewProject(staticAuthorizedProject); // Re-save the project after | ||||||
|  |         // updating lists | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     // --- Per-Test Setup (Runs before each test method) --- | ||||||
|  |     @BeforeEach | ||||||
|  |     void setupForEach() { | ||||||
|  |         // Reset mock expectations before each test | ||||||
|  |         MockitoAnnotations.openMocks( | ||||||
|  |                 this); // Needed for mocks if not using @ExtendWith(MockitoExtension.class) | ||||||
|  |  | ||||||
|  |         // --- Configure the mock UtilsService based on the actual authorization rules --- | ||||||
|  |  | ||||||
|  |         // Rule: Any admin can check any project. | ||||||
|  |         // Assuming staticAuthorizedMail is an admin: | ||||||
|  |         when(mockUtilsService.isAllowedToCheckProject(eq(staticAuthorizedMail), anyLong())) | ||||||
|  |                 .thenReturn(true); // Admin allowed for ANY project ID | ||||||
|  |  | ||||||
|  |         // Rule: An entrepreneur can only check their own stuff. | ||||||
|  |         // Assuming staticUnauthorizedMail is an entrepreneur NOT linked to staticAuthorizedProject | ||||||
|  |         // or staticUnauthorizedProject: | ||||||
|  |         when(mockUtilsService.isAllowedToCheckProject(eq(staticUnauthorizedMail), anyLong())) | ||||||
|  |                 .thenReturn(false); // Unauthorized entrepreneur NOT allowed for ANY project ID by | ||||||
|  |         // default | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     // --- Helper Methods (Can remain non-static or static as needed) --- | ||||||
|  |     private static Administrator getTestAdmin(String name) { | ||||||
|  |         return new Administrator( | ||||||
|  |                 name + "_surname", | ||||||
|  |                 name, | ||||||
|  |                 name + "@example.com", | ||||||
|  |                 "secondary_" + name + "@example.com", | ||||||
|  |                 "0123456789"); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     private static Entrepreneur getTestEntrepreneur(String name) { | ||||||
|  |         return new Entrepreneur( | ||||||
|  |                 name + "_surname", | ||||||
|  |                 name, | ||||||
|  |                 name + "@example.com", | ||||||
|  |                 "secondary_" + name + "@example.com", | ||||||
|  |                 "0123456789", | ||||||
|  |                 "Test School", | ||||||
|  |                 "Test Course", | ||||||
|  |                 false); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     private static Project getTestProject(String name, Administrator admin) { | ||||||
|  |         Project project = new Project(name, null, LocalDate.now(), ACTIVE, admin); | ||||||
|  |         return project; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     private static SectionCell getTestSectionCell( | ||||||
|  |             Project project, Long sectionId, String content, LocalDateTime date) { | ||||||
|  |         SectionCell sectionCell = new SectionCell(); | ||||||
|  |         sectionCell.setProjectSectionCell(project); | ||||||
|  |         sectionCell.setSectionId(sectionId); | ||||||
|  |         sectionCell.setContentSectionCell(content); | ||||||
|  |         sectionCell.setModificationDate(date); | ||||||
|  |         return sectionCell; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     private static SectionCell getTestSectionCell( | ||||||
|  |             Project project, Long sectionId, String content, LocalDateTime date, Long refrenceId) { | ||||||
|  |         SectionCell sectionCell = new SectionCell(); | ||||||
|  |         sectionCell.setProjectSectionCell(project); | ||||||
|  |         sectionCell.setSectionId(sectionId); | ||||||
|  |         sectionCell.setContentSectionCell(content); | ||||||
|  |         sectionCell.setModificationDate(date); | ||||||
|  |         sectionCell.setIdReference(refrenceId); | ||||||
|  |         return sectionCell; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     private static Appointment getTestAppointment( | ||||||
|  |             LocalDate date, | ||||||
|  |             LocalTime time, | ||||||
|  |             LocalTime duration, | ||||||
|  |             String place, | ||||||
|  |             String subject, | ||||||
|  |             List<SectionCell> sectionCells, | ||||||
|  |             Report report) { | ||||||
|  |         Appointment appointment = new Appointment(); | ||||||
|  |         appointment.setAppointmentDate(date); | ||||||
|  |         appointment.setAppointmentTime(time); | ||||||
|  |         appointment.setAppointmentDuration(duration); | ||||||
|  |         appointment.setAppointmentPlace(place); | ||||||
|  |         appointment.setAppointmentSubject(subject); | ||||||
|  |  | ||||||
|  |         if (sectionCells != null) { | ||||||
|  |             sectionCells.forEach(appointment::updateListSectionCell); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         if (report != null) { | ||||||
|  |             appointment.setAppointmentReport(report); | ||||||
|  |             report.setAppointmentReport(appointment); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         return appointment; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     private static Report getTestReport(String content) { | ||||||
|  |         Report report = new Report(); | ||||||
|  |         report.setReportContent(content); | ||||||
|  |         return report; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /* | ||||||
|  |      *        _____         _   ____            _   _              ____     _ _ | ||||||
|  |      *       |_   _|__  ___| |_/ ___|  ___  ___| |_(_) ___  _ __  / ___|___| | | | ||||||
|  |      *         | |/ _ \/ __| __\___ \ / _ \/ __| __| |/ _ \| '_ \| |   / _ \ | | | ||||||
|  |      *         | |  __/\__ \ |_ ___) |  __/ (__| |_| | (_) | | | | |__|  __/ | | | ||||||
|  |      *         |_|\___||___/\__|____/ \___|\___|\__|_|\___/|_| |_|\____\___|_|_| | ||||||
|  |      */ | ||||||
|  |  | ||||||
|  |     /* | ||||||
|  |      * Tests retrieving section cells for a specific project and section ID before a given date | ||||||
|  |      * when the user is authorized but no matching cells exist. | ||||||
|  |      * Verifies that an empty list is returned. | ||||||
|  |      */ | ||||||
|  |     @Test | ||||||
|  |     void testGetSectionCells_Authorized_NotFound() { | ||||||
|  |         // Arrange: No specific section cells needed for this test, rely on clean @BeforeEach state | ||||||
|  |         Long targetSectionId = 1L; | ||||||
|  |         LocalDateTime dateFilter = LocalDateTime.now().plusDays(1); | ||||||
|  |  | ||||||
|  |         // Act | ||||||
|  |         Iterable<SectionCell> result = | ||||||
|  |                 sharedApiService.getSectionCells( | ||||||
|  |                         staticAuthorizedProject.getIdProject(), | ||||||
|  |                         targetSectionId, | ||||||
|  |                         dateFilter.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm")), | ||||||
|  |                         staticAuthorizedMail); | ||||||
|  |  | ||||||
|  |         List<SectionCell> resultList = TestUtils.toList(result); | ||||||
|  |  | ||||||
|  |         // Assert | ||||||
|  |         assertTrue(resultList.isEmpty()); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /* | ||||||
|  |      * Tests retrieving section cells when the user is not authorized for the project. | ||||||
|  |      * Verifies that an Unauthorized ResponseStatusException is thrown. | ||||||
|  |      */ | ||||||
|  |     @Test | ||||||
|  |     void testGetSectionCells_Unauthorized() { | ||||||
|  |         // Arrange: mockUtilsService configured in BeforeEach | ||||||
|  |         // Act & Assert | ||||||
|  |         ResponseStatusException exception = | ||||||
|  |                 assertThrows( | ||||||
|  |                         ResponseStatusException.class, | ||||||
|  |                         () -> { | ||||||
|  |                             sharedApiService.getSectionCells( | ||||||
|  |                                     staticAuthorizedProject | ||||||
|  |                                             .getIdProject(), // Project static user is not | ||||||
|  |                                     // authorized for | ||||||
|  |                                     1L, | ||||||
|  |                                     LocalDateTime.now() | ||||||
|  |                                             .format( | ||||||
|  |                                                     DateTimeFormatter.ofPattern( | ||||||
|  |                                                             "yyyy-MM-dd HH:mm")), | ||||||
|  |                                     staticUnauthorizedMail); // Static unauthorized user mail | ||||||
|  |                         }); | ||||||
|  |  | ||||||
|  |         assertEquals(HttpStatus.UNAUTHORIZED, exception.getStatusCode()); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /* | ||||||
|  |      * Tests retrieving all section cells for a project when the user is authorized | ||||||
|  |      * but the project has no section cells. | ||||||
|  |      * Verifies that an empty list is returned. | ||||||
|  |      */ | ||||||
|  |     @Test | ||||||
|  |     void testGetAllSectionCells_Authorized_NoCells() { | ||||||
|  |         // Arrange: staticAuthorizedProject has no section cells initially in BeforeAll | ||||||
|  |         // Act | ||||||
|  |         Iterable<SectionCell> result = | ||||||
|  |                 sharedApiService.getAllSectionCells( | ||||||
|  |                         staticAuthorizedProject.getIdProject(), staticAuthorizedMail); | ||||||
|  |  | ||||||
|  |         List<SectionCell> resultList = TestUtils.toList(result); | ||||||
|  |  | ||||||
|  |         // Assert | ||||||
|  |         assertTrue(resultList.isEmpty()); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /* | ||||||
|  |      * Tests retrieving all section cells when the user is not authorized for the project. | ||||||
|  |      * Verifies that an Unauthorized ResponseStatusException is thrown. | ||||||
|  |      */ | ||||||
|  |     @Test | ||||||
|  |     void testGetAllSectionCells_Unauthorized() { | ||||||
|  |         // Arrange: mockUtilsService configured in BeforeEach | ||||||
|  |         // Act & Assert | ||||||
|  |         ResponseStatusException exception = | ||||||
|  |                 assertThrows( | ||||||
|  |                         ResponseStatusException.class, | ||||||
|  |                         () -> { | ||||||
|  |                             sharedApiService.getAllSectionCells( | ||||||
|  |                                     staticAuthorizedProject.getIdProject(), staticUnauthorizedMail); | ||||||
|  |                         }); | ||||||
|  |  | ||||||
|  |         assertEquals(HttpStatus.UNAUTHORIZED, exception.getStatusCode()); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /* | ||||||
|  |      * Tests retrieving section cells for a specific project and section ID before a given date | ||||||
|  |      * when the user is authorized and matching cells exist. | ||||||
|  |      * Verifies that only the correct cells are returned. | ||||||
|  |      */ | ||||||
|  |     @Test | ||||||
|  |     // Commenting out failing test | ||||||
|  |     void testGetSectionCells_Authorized_Found() { | ||||||
|  |         Long targetSectionId = 1L; | ||||||
|  |         // Set a date filter slightly in the future so our "latest before" cell is included | ||||||
|  |         LocalDateTime dateFilter = LocalDateTime.now().plusMinutes(5); | ||||||
|  |  | ||||||
|  |         // Creating versions of the SAME SectionCell (share the same idReference) | ||||||
|  |  | ||||||
|  |         // the first version. This will get a GENERATED idReference. | ||||||
|  |         SectionCell firstVersion = | ||||||
|  |                 getTestSectionCell( | ||||||
|  |                         staticAuthorizedProject, | ||||||
|  |                         targetSectionId, | ||||||
|  |                         "Content V1 (Oldest)", | ||||||
|  |                         LocalDateTime.now().minusDays(3) // Oldest date | ||||||
|  |                         ); | ||||||
|  |         sectionCellService.addNewSectionCell(firstVersion); | ||||||
|  |  | ||||||
|  |         Long sharedIdReference = firstVersion.getIdReference(); | ||||||
|  |         assertNotNull( | ||||||
|  |                 sharedIdReference, | ||||||
|  |                 "idReference should be generated after saving the first version"); | ||||||
|  |         System.out.println("Generated sharedIdReference: " + sharedIdReference); | ||||||
|  |  | ||||||
|  |         // Create subsequent versions and MANUALLY set the SAME idReference. | ||||||
|  |         // These represent updates to the cell identified by sharedIdReference. | ||||||
|  |  | ||||||
|  |         SectionCell middleVersion = | ||||||
|  |                 getTestSectionCell( | ||||||
|  |                         staticAuthorizedProject, | ||||||
|  |                         targetSectionId, | ||||||
|  |                         "Content V2 (Middle)", | ||||||
|  |                         LocalDateTime.now().minusDays(2), // Middle date, before filter | ||||||
|  |                         sharedIdReference); | ||||||
|  |         middleVersion = sectionCellService.addNewSectionCell(middleVersion); | ||||||
|  |         sectionCellService.updateSectionCellReferenceId( | ||||||
|  |                 middleVersion.getIdSectionCell(), sharedIdReference); | ||||||
|  |  | ||||||
|  |         SectionCell latestBeforeFilter = | ||||||
|  |                 getTestSectionCell( | ||||||
|  |                         staticAuthorizedProject, | ||||||
|  |                         targetSectionId, | ||||||
|  |                         "Content V3 (Latest Before Filter)", | ||||||
|  |                         LocalDateTime.now().minusDays(1), // Latest date before filter | ||||||
|  |                         sharedIdReference); | ||||||
|  |         latestBeforeFilter = sectionCellService.addNewSectionCell(latestBeforeFilter); | ||||||
|  |         sectionCellService.updateSectionCellReferenceId( | ||||||
|  |                 latestBeforeFilter.getIdSectionCell(), sharedIdReference); | ||||||
|  |  | ||||||
|  |         SectionCell futureVersion = | ||||||
|  |                 getTestSectionCell( | ||||||
|  |                         staticAuthorizedProject, | ||||||
|  |                         targetSectionId, | ||||||
|  |                         "Content V4 (Future - Should Be Excluded)", | ||||||
|  |                         LocalDateTime.now().plusDays(1), // Date is AFTER the filter | ||||||
|  |                         sharedIdReference); | ||||||
|  |         futureVersion = sectionCellService.addNewSectionCell(futureVersion); | ||||||
|  |         sectionCellService.updateSectionCellReferenceId( | ||||||
|  |                 futureVersion.getIdSectionCell(), sharedIdReference); | ||||||
|  |  | ||||||
|  |         // --- Create other SectionCells that should NOT be included (different sectionId or | ||||||
|  |         // project) --- | ||||||
|  |  | ||||||
|  |         // Cell in a different section ID | ||||||
|  |         sectionCellService.addNewSectionCell( | ||||||
|  |                 getTestSectionCell( | ||||||
|  |                         staticAuthorizedProject, | ||||||
|  |                         99L, // Different sectionId | ||||||
|  |                         "Content in Different Section", | ||||||
|  |                         LocalDateTime.now())); | ||||||
|  |  | ||||||
|  |         // Act | ||||||
|  |         Iterable<SectionCell> result = | ||||||
|  |                 sharedApiService.getSectionCells( | ||||||
|  |                         staticAuthorizedProject.getIdProject(), // Use static project ID | ||||||
|  |                         targetSectionId, | ||||||
|  |                         dateFilter.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm")), | ||||||
|  |                         staticAuthorizedMail); // Use static authorized mail | ||||||
|  |  | ||||||
|  |         List<SectionCell> resultList = TestUtils.toList(result); | ||||||
|  |  | ||||||
|  |         assertEquals(1, resultList.size()); | ||||||
|  |         // Verify that the returned cell is the 'latestBeforeFilter' cell | ||||||
|  |         // Comparing by idSectionCell is a good way to verify the exact entity | ||||||
|  |         assertEquals( | ||||||
|  |                 latestBeforeFilter.getIdSectionCell(), | ||||||
|  |                 resultList.get(0).getIdSectionCell(), | ||||||
|  |                 "The returned SectionCell should be the one with the latest modification date before the filter."); | ||||||
|  |  | ||||||
|  |         // Also assert the idReference and content | ||||||
|  |         assertEquals( | ||||||
|  |                 sharedIdReference, | ||||||
|  |                 resultList.get(0).getIdReference(), | ||||||
|  |                 "The returned cell should have the shared idReference."); | ||||||
|  |         assertEquals( | ||||||
|  |                 "Content V3 (Latest Before Filter)", | ||||||
|  |                 resultList.get(0).getContentSectionCell(), | ||||||
|  |                 "The returned cell should have the correct content."); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /* | ||||||
|  |      * Tests retrieving the most recent section cell for each unique idReference | ||||||
|  |      * within a project when the user is authorized and cells exist. | ||||||
|  |      * Verifies that only the latest version of each referenced cell is returned. | ||||||
|  |      */ | ||||||
|  |     // Tests getAllSectionCells | ||||||
|  |     @Test | ||||||
|  |     // Commenting out failing test - Removed this comment as we are fixing it | ||||||
|  |     void testGetAllSectionCells_Authorized_FoundLatest() { | ||||||
|  |         // Arrange: Create specific SectionCells for this test | ||||||
|  |         // Define the idReference values we will use for grouping | ||||||
|  |         Long refIdGroup1 = 101L; | ||||||
|  |         Long refIdGroup2 = 102L; | ||||||
|  |         Long refIdOtherProject = 103L; | ||||||
|  |  | ||||||
|  |         // --- Create and Add Cells for Group 1 (refIdGroup1) --- | ||||||
|  |         // Create the older cell for group 1 | ||||||
|  |         SectionCell tempOldCell1 = | ||||||
|  |                 getTestSectionCell( | ||||||
|  |                         staticAuthorizedProject, // Project | ||||||
|  |                         1L, // Section ID (assuming this groups by section within refId) | ||||||
|  |                         "Ref1 Old", // Name | ||||||
|  |                         LocalDateTime.now().minusDays(3), // Date (older) | ||||||
|  |                         null); // Pass null or let getTestSectionCell handle it, we'll set | ||||||
|  |         // idReference later | ||||||
|  |         final SectionCell oldCell1 = | ||||||
|  |                 sectionCellService.addNewSectionCell(tempOldCell1); // Add to DB | ||||||
|  |  | ||||||
|  |         // Create the newer cell for group 1 | ||||||
|  |         SectionCell tempNewerCell1 = | ||||||
|  |                 getTestSectionCell( | ||||||
|  |                         staticAuthorizedProject, // Project | ||||||
|  |                         1L, // Section ID | ||||||
|  |                         "Ref1 Newer", // Name | ||||||
|  |                         LocalDateTime.now().minusDays(2), // Date (newer than oldCell1) | ||||||
|  |                         null); // Pass null | ||||||
|  |         final SectionCell newerCell1 = | ||||||
|  |                 sectionCellService.addNewSectionCell(tempNewerCell1); // Add to DB | ||||||
|  |  | ||||||
|  |         // Now, update the idReference for both cells in Group 1 to the desired value | ||||||
|  |         sectionCellService.updateSectionCellReferenceId(oldCell1.getIdSectionCell(), refIdGroup1); | ||||||
|  |         sectionCellService.updateSectionCellReferenceId(newerCell1.getIdSectionCell(), refIdGroup1); | ||||||
|  |  | ||||||
|  |         // --- Create and Add Cells for Group 2 (refIdGroup2) --- | ||||||
|  |         // Create the older cell for group 2 | ||||||
|  |         SectionCell tempOldCell2 = | ||||||
|  |                 getTestSectionCell( | ||||||
|  |                         staticAuthorizedProject, // Project | ||||||
|  |                         2L, // Section ID (different section) | ||||||
|  |                         "Ref2 Old", // Name | ||||||
|  |                         LocalDateTime.now().minusDays(1), // Date (older than newerCell2) | ||||||
|  |                         null); // Pass null | ||||||
|  |         final SectionCell oldCell2 = | ||||||
|  |                 sectionCellService.addNewSectionCell(tempOldCell2); // Add to DB | ||||||
|  |  | ||||||
|  |         // Create the newer cell for group 2 | ||||||
|  |         SectionCell tempNewerCell2 = | ||||||
|  |                 getTestSectionCell( | ||||||
|  |                         staticAuthorizedProject, // Project | ||||||
|  |                         2L, // Section ID | ||||||
|  |                         "Ref2 Newer", // Name | ||||||
|  |                         LocalDateTime.now(), // Date (latest) | ||||||
|  |                         null); // Pass null | ||||||
|  |         final SectionCell newerCell2 = | ||||||
|  |                 sectionCellService.addNewSectionCell(tempNewerCell2); // Add to DB | ||||||
|  |  | ||||||
|  |         // Now, update the idReference for both cells in Group 2 to the desired value | ||||||
|  |         sectionCellService.updateSectionCellReferenceId(oldCell2.getIdSectionCell(), refIdGroup2); | ||||||
|  |         sectionCellService.updateSectionCellReferenceId(newerCell2.getIdSectionCell(), refIdGroup2); | ||||||
|  |  | ||||||
|  |         // --- Create and Add Cell for Other Project (refIdOtherProject) --- | ||||||
|  |         Project otherProject = | ||||||
|  |                 projectService.addNewProject( | ||||||
|  |                         getTestProject( | ||||||
|  |                                 "other_project_for_cell_test", | ||||||
|  |                                 administratorService.addAdministrator( | ||||||
|  |                                         getTestAdmin("other_admin_cell_test")))); | ||||||
|  |  | ||||||
|  |         SectionCell tempOtherProjectCell = | ||||||
|  |                 getTestSectionCell( | ||||||
|  |                         otherProject, // DIFFERENT Project | ||||||
|  |                         1L, // Section ID | ||||||
|  |                         "Other Project Cell", // Name | ||||||
|  |                         LocalDateTime.now(), // Date | ||||||
|  |                         null); // Pass null | ||||||
|  |         final SectionCell otherProjectCell = | ||||||
|  |                 sectionCellService.addNewSectionCell(tempOtherProjectCell); // Add to DB | ||||||
|  |  | ||||||
|  |         // Now, update the idReference for the Other Project cell | ||||||
|  |         sectionCellService.updateSectionCellReferenceId( | ||||||
|  |                 otherProjectCell.getIdSectionCell(), refIdOtherProject); | ||||||
|  |  | ||||||
|  |         // Act | ||||||
|  |         // Ensure the service call uses the correct project ID and mail | ||||||
|  |         Iterable<SectionCell> result = | ||||||
|  |                 sharedApiService.getAllSectionCells( | ||||||
|  |                         staticAuthorizedProject.getIdProject(), // Use static project ID | ||||||
|  |                         staticAuthorizedMail); // Use static authorized mail | ||||||
|  |  | ||||||
|  |         List<SectionCell> resultList = TestUtils.toList(result); | ||||||
|  |  | ||||||
|  |         // Assert | ||||||
|  |         // We expect 2 cells from the staticAuthorizedProject: | ||||||
|  |         // - The latest one from refIdGroup1 (newerCell1) | ||||||
|  |         // - The latest one from refIdGroup2 (newerCell2) | ||||||
|  |         assertEquals(2, resultList.size()); | ||||||
|  |  | ||||||
|  |         // Assert that the result list contains the LATEST cell from each group within the correct | ||||||
|  |         // project | ||||||
|  |         assertTrue( | ||||||
|  |                 resultList.stream() | ||||||
|  |                         .anyMatch( | ||||||
|  |                                 cell -> | ||||||
|  |                                         cell.getIdSectionCell() | ||||||
|  |                                                 .equals(newerCell1.getIdSectionCell())), | ||||||
|  |                 "Should contain the latest cell for Group 1"); // Add assertion message | ||||||
|  |         assertTrue( | ||||||
|  |                 resultList.stream() | ||||||
|  |                         .anyMatch( | ||||||
|  |                                 cell -> | ||||||
|  |                                         cell.getIdSectionCell() | ||||||
|  |                                                 .equals(newerCell2.getIdSectionCell())), | ||||||
|  |                 "Should contain the latest cell for Group 2"); // Add assertion message | ||||||
|  |  | ||||||
|  |         // Assert that the result list does NOT contain the OLDER cells from the correct project | ||||||
|  |         assertFalse( | ||||||
|  |                 resultList.stream() | ||||||
|  |                         .anyMatch( | ||||||
|  |                                 cell -> | ||||||
|  |                                         cell.getIdSectionCell() | ||||||
|  |                                                 .equals(oldCell1.getIdSectionCell())), | ||||||
|  |                 "Should not contain the older cell for Group 1"); // Add assertion message | ||||||
|  |         assertFalse( | ||||||
|  |                 resultList.stream() | ||||||
|  |                         .anyMatch( | ||||||
|  |                                 cell -> | ||||||
|  |                                         cell.getIdSectionCell() | ||||||
|  |                                                 .equals(oldCell2.getIdSectionCell())), | ||||||
|  |                 "Should not contain the older cell for Group 2"); // Add assertion message | ||||||
|  |  | ||||||
|  |         // Assert that the result list does NOT contain the cell from the other project | ||||||
|  |         assertFalse( | ||||||
|  |                 resultList.stream() | ||||||
|  |                         .anyMatch( | ||||||
|  |                                 cell -> | ||||||
|  |                                         cell.getIdSectionCell() | ||||||
|  |                                                 .equals(otherProjectCell.getIdSectionCell())), | ||||||
|  |                 "Should not contain cells from other projects"); // Add assertion message | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /* | ||||||
|  |      *        _____         _    ____      _   ____            _           _   ____ | ||||||
|  |      *       |_   _|__  ___| |_ / ___| ___| |_|  _ \ _ __ ___ (_) ___  ___| |_| __ ) _   _ | ||||||
|  |      *         | |/ _ \/ __| __| |  _ / _ \ __| |_) | '__/ _ \| |/ _ \/ __| __|  _ \| | | | | ||||||
|  |      *         | |  __/\__ \ |_| |_| |  __/ |_|  __/| | | (_) | |  __/ (__| |_| |_) | |_| | | ||||||
|  |      *        _|_|\___||___/\__|\____|\___|\__|_|   |_|  \___// |\___|\___|\__|____/ \__, | | ||||||
|  |      *       |_ _|  _ \                                     |__/                     |___/ | ||||||
|  |      *        | || | | | | ||||||
|  |      *        | || |_| | | ||||||
|  |      *       |___|____/ | ||||||
|  |      */ | ||||||
|  |  | ||||||
|  |     /* | ||||||
|  |      * Tests retrieving entrepreneurs linked to a project when the user is authorized | ||||||
|  |      * but no entrepreneurs are linked. | ||||||
|  |      * Verifies that an empty list is returned. | ||||||
|  |      */ | ||||||
|  |     @Test | ||||||
|  |     void testGetEntrepreneursByProjectId_Authorized_NotFound() { | ||||||
|  |         // Arrange: staticAuthorizedProject has no entrepreneurs linked initially in BeforeAll | ||||||
|  |         // Act | ||||||
|  |         Iterable<Entrepreneur> result = | ||||||
|  |                 sharedApiService.getEntrepreneursByProjectId( | ||||||
|  |                         staticAuthorizedProject.getIdProject(), staticAuthorizedMail); | ||||||
|  |  | ||||||
|  |         List<Entrepreneur> resultList = TestUtils.toList(result); | ||||||
|  |  | ||||||
|  |         // Assert | ||||||
|  |         assertTrue(resultList.isEmpty()); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /* | ||||||
|  |      * Tests retrieving entrepreneurs linked to a project when the user is not authorized. | ||||||
|  |      * Verifies that an Unauthorized ResponseStatusException is thrown. | ||||||
|  |      */ | ||||||
|  |     @Test | ||||||
|  |     void testGetEntrepreneursByProjectId_Unauthorized() { | ||||||
|  |         // Arrange: mockUtilsService configured in BeforeEach | ||||||
|  |         // Act & Assert | ||||||
|  |         ResponseStatusException exception = | ||||||
|  |                 assertThrows( | ||||||
|  |                         ResponseStatusException.class, | ||||||
|  |                         () -> { | ||||||
|  |                             sharedApiService.getEntrepreneursByProjectId( | ||||||
|  |                                     staticAuthorizedProject.getIdProject(), staticUnauthorizedMail); | ||||||
|  |                         }); | ||||||
|  |  | ||||||
|  |         assertEquals(HttpStatus.UNAUTHORIZED, exception.getStatusCode()); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /* | ||||||
|  |      *    _____         _    ____      _      _       _           _       ____ | ||||||
|  |      *   |_   _|__  ___| |_ / ___| ___| |_   / \   __| |_ __ ___ (_)_ __ | __ ) _   _ | ||||||
|  |      *     | |/ _ \/ __| __| |  _ / _ \ __| / _ \ / _` | '_ ` _ \| | '_ \|  _ \| | | | | ||||||
|  |      *     | |  __/\__ \ |_| |_| |  __/ |_ / ___ \ (_| | | | | | | | | | | |_) | |_| | | ||||||
|  |      *    _|_|\___||___/\__|\____|\___|\__/_/   \_\__,_|_| |_| |_|_|_| |_|____/ \__, | | ||||||
|  |      *   |_ _|  _ \                                                             |___/ | ||||||
|  |      *    | || | | | | ||||||
|  |      *    | || |_| | | ||||||
|  |      *   |___|____/ | ||||||
|  |      * | ||||||
|  |      */ | ||||||
|  |  | ||||||
|  |     /* | ||||||
|  |      * Tests retrieving appointments linked to a project's section cells when the user is authorized | ||||||
|  |      * but no such appointments exist. | ||||||
|  |      * Verifies that an empty list is returned. | ||||||
|  |      */ | ||||||
|  |     @Test | ||||||
|  |     void testGetAppointmentsByProjectId_Authorized_NotFound() { | ||||||
|  |         // Arrange: staticAuthorizedProject has no linked section cells or appointments initially | ||||||
|  |         // Act | ||||||
|  |         Iterable<Appointment> result = | ||||||
|  |                 sharedApiService.getAppointmentsByProjectId( | ||||||
|  |                         staticAuthorizedProject.getIdProject(), staticAuthorizedMail); | ||||||
|  |  | ||||||
|  |         List<Appointment> resultList = TestUtils.toList(result); | ||||||
|  |  | ||||||
|  |         // Assert | ||||||
|  |         assertTrue(resultList.isEmpty()); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /* | ||||||
|  |      * Tests retrieving the administrator linked to a project when the user is authorized | ||||||
|  |      * and an administrator is linked. | ||||||
|  |      * Verifies that the correct administrator is returned. | ||||||
|  |      */ | ||||||
|  |     // Tests getAdminByProjectId | ||||||
|  |     @Test | ||||||
|  |     void testGetAdminByProjectId_Authorized_Found() { | ||||||
|  |         // Arrange: staticAuthorizedProject is created with staticAuthorizedAdmin in BeforeAll | ||||||
|  |         // Act | ||||||
|  |         Administrator result = | ||||||
|  |                 sharedApiService.getAdminByProjectId( | ||||||
|  |                         staticAuthorizedProject.getIdProject(), staticAuthorizedMail); | ||||||
|  |  | ||||||
|  |         // Assert | ||||||
|  |         assertNotNull(result); | ||||||
|  |         assertEquals(staticAuthorizedAdmin.getIdUser(), result.getIdUser()); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /* | ||||||
|  |      * Tests retrieving the administrator linked to a project when the user is not authorized. | ||||||
|  |      * Verifies that an Unauthorized ResponseStatusException is thrown. | ||||||
|  |      */ | ||||||
|  |     @Test | ||||||
|  |     void testGetAdminByProjectId_Unauthorized() { | ||||||
|  |         // Arrange: mockUtilsService configured in BeforeEach | ||||||
|  |         // Act & Assert | ||||||
|  |         ResponseStatusException exception = | ||||||
|  |                 assertThrows( | ||||||
|  |                         ResponseStatusException.class, | ||||||
|  |                         () -> { | ||||||
|  |                             sharedApiService.getAdminByProjectId( | ||||||
|  |                                     staticAuthorizedProject.getIdProject(), staticUnauthorizedMail); | ||||||
|  |                         }); | ||||||
|  |  | ||||||
|  |         assertEquals(HttpStatus.UNAUTHORIZED, exception.getStatusCode()); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /* | ||||||
|  |      *    _____         _ | ||||||
|  |      *   |_   _|__  ___| |_ | ||||||
|  |      *     | |/ _ \/ __| __| | ||||||
|  |      *     | |  __/\__ \ |_ | ||||||
|  |      *     |_|\___||___/\__|        _       _                            _ | ||||||
|  |      *      / \   _ __  _ __   ___ (_)_ __ | |_ ___ _ __ ___   ___ _ __ | |_ ___ | ||||||
|  |      *     / _ \ | '_ \| '_ \ / _ \| | '_ \| __/ _ \ '_ ` _ \ / _ \ '_ \| __/ __| | ||||||
|  |      *    / ___ \| |_) | |_) | (_) | | | | | ||  __/ | | | | |  __/ | | | |_\__ \ | ||||||
|  |      *   /_/   \_\ .__/| .__/ \___/|_|_| |_|\__\___|_| |_| |_|\___|_| |_|\__|___/ | ||||||
|  |      *           |_|   |_| | ||||||
|  |      */ | ||||||
|  |  | ||||||
|  |     /* | ||||||
|  |      * Tests retrieving appointments linked to a project's section cells when the user is not authorized. | ||||||
|  |      * Verifies that an Unauthorized ResponseStatusException is thrown. | ||||||
|  |      */ | ||||||
|  |     @Test | ||||||
|  |     void testGetAppointmentsByProjectId_Unauthorized() { | ||||||
|  |         // Arrange: mockUtilsService configured in BeforeEach | ||||||
|  |         // Act & Assert | ||||||
|  |         ResponseStatusException exception = | ||||||
|  |                 assertThrows( | ||||||
|  |                         ResponseStatusException.class, | ||||||
|  |                         () -> { | ||||||
|  |                             sharedApiService.getAppointmentsByProjectId( | ||||||
|  |                                     staticAuthorizedProject.getIdProject(), staticUnauthorizedMail); | ||||||
|  |                         }); | ||||||
|  |  | ||||||
|  |         assertEquals(HttpStatus.UNAUTHORIZED, exception.getStatusCode()); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @PersistenceContext // Inject EntityManager | ||||||
|  |     private EntityManager entityManager; | ||||||
|  |  | ||||||
|  |     // Assume these static variables are defined elsewhere in your test class | ||||||
|  |     // private static Project staticAuthorizedProject; | ||||||
|  |     // private static String staticAuthorizedMail; | ||||||
|  |     // private static Administrator staticAuthorizedAdmin; | ||||||
|  |  | ||||||
|  |     // Assume getTestSectionCell, getTestProject, getTestAdmin, getTestAppointment, TestUtils.toList | ||||||
|  |     // are defined elsewhere | ||||||
|  |  | ||||||
|  |     @Test | ||||||
|  |     void testGetAppointmentsByProjectId_Authorized_Found() { | ||||||
|  |         // Arrange: Create specific SectionCells and Appointments for this test | ||||||
|  |         SectionCell cell1 = | ||||||
|  |                 sectionCellService.addNewSectionCell( | ||||||
|  |                         getTestSectionCell( | ||||||
|  |                                 staticAuthorizedProject, 1L, "Cell 1 Test", LocalDateTime.now())); | ||||||
|  |         SectionCell cell2 = | ||||||
|  |                 sectionCellService.addNewSectionCell( | ||||||
|  |                         getTestSectionCell( | ||||||
|  |                                 staticAuthorizedProject, 2L, "Cell 2 Test", LocalDateTime.now())); | ||||||
|  |         Project otherProject = | ||||||
|  |                 projectService.addNewProject( | ||||||
|  |                         getTestProject( | ||||||
|  |                                 "other_project_app_test", | ||||||
|  |                                 administratorService.addAdministrator( | ||||||
|  |                                         getTestAdmin("other_admin_app_test")))); | ||||||
|  |         SectionCell otherProjectCell = | ||||||
|  |                 sectionCellService.addNewSectionCell( | ||||||
|  |                         getTestSectionCell( | ||||||
|  |                                 otherProject, | ||||||
|  |                                 1L, | ||||||
|  |                                 "Other Project Cell App Test", | ||||||
|  |                                 LocalDateTime.now())); | ||||||
|  |  | ||||||
|  |         // Create Appointments with SectionCells lists (Owning side) | ||||||
|  |         Appointment app1 = | ||||||
|  |                 getTestAppointment( | ||||||
|  |                         LocalDate.now().plusDays(10), | ||||||
|  |                         LocalTime.NOON, | ||||||
|  |                         LocalTime.of(0, 30), | ||||||
|  |                         "Place 1 App Test", | ||||||
|  |                         "Subject 1 App Test", | ||||||
|  |                         List.of(cell1), // This links Appointment to SectionCell | ||||||
|  |                         null); | ||||||
|  |         Appointment savedApp1 = appointmentService.addNewAppointment(app1); | ||||||
|  |  | ||||||
|  |         Appointment app2 = | ||||||
|  |                 getTestAppointment( | ||||||
|  |                         LocalDate.now().plusDays(11), | ||||||
|  |                         LocalTime.NOON.plusHours(1), | ||||||
|  |                         LocalTime.of(1, 0), | ||||||
|  |                         "Place 2 App Test", | ||||||
|  |                         "Subject 2 App Test", | ||||||
|  |                         List.of(cell1, cell2), // This links Appointment to SectionCells | ||||||
|  |                         null); | ||||||
|  |         Appointment savedApp2 = appointmentService.addNewAppointment(app2); | ||||||
|  |  | ||||||
|  |         Appointment otherApp = | ||||||
|  |                 getTestAppointment( | ||||||
|  |                         LocalDate.now().plusDays(12), | ||||||
|  |                         LocalTime.MIDNIGHT, | ||||||
|  |                         LocalTime.of(0, 15), | ||||||
|  |                         "Other Place App Test", | ||||||
|  |                         "Other Subject App Test", | ||||||
|  |                         List.of(otherProjectCell), // This links Appointment to SectionCell | ||||||
|  |                         null); | ||||||
|  |         Appointment savedOtherApp = | ||||||
|  |                 appointmentService.addNewAppointment(otherApp); // Capture saved entity | ||||||
|  |  | ||||||
|  |         // --- IMPORTANT DEBUGGING STEPS --- | ||||||
|  |         // Flush pending changes to the database (including join table inserts) | ||||||
|  |         entityManager.flush(); | ||||||
|  |         // Clear the persistence context cache to ensure entities are loaded fresh from the database | ||||||
|  |         entityManager.clear(); | ||||||
|  |         // --- END IMPORTANT DEBUGGING STEPS --- | ||||||
|  |  | ||||||
|  |         // --- Add Debug Logging Here --- | ||||||
|  |         // Re-fetch cells to see their state after saving Appointments and flushing/clearing cache | ||||||
|  |         // These fetches should load from the database due to entityManager.clear() | ||||||
|  |         SectionCell fetchedCell1_postPersist = | ||||||
|  |                 sectionCellService.getSectionCellById(cell1.getIdSectionCell()); | ||||||
|  |         SectionCell fetchedCell2_postPersist = | ||||||
|  |                 sectionCellService.getSectionCellById(cell2.getIdSectionCell()); | ||||||
|  |         SectionCell fetchedOtherCell_postPersist = | ||||||
|  |                 sectionCellService.getSectionCellById(otherProjectCell.getIdSectionCell()); | ||||||
|  |  | ||||||
|  |         // Access the lazy collections to see if they are populated from the DB | ||||||
|  |         // This access should trigger lazy loading if the data is in the DB | ||||||
|  |         List<Appointment> cell1Apps_postPersist = | ||||||
|  |                 fetchedCell1_postPersist.getAppointmentSectionCell(); | ||||||
|  |         List<Appointment> cell2Apps_postPersist = | ||||||
|  |                 fetchedCell2_postPersist.getAppointmentSectionCell(); | ||||||
|  |         List<Appointment> otherCellApps_postPersist = | ||||||
|  |                 fetchedOtherCell_postPersist.getAppointmentSectionCell(); | ||||||
|  |  | ||||||
|  |         // Ensure logging is enabled in SharedApiService and SectionCellService methods called below | ||||||
|  |         Iterable<Appointment> result = | ||||||
|  |                 sharedApiService.getAppointmentsByProjectId( | ||||||
|  |                         staticAuthorizedProject.getIdProject(), // Use static project ID | ||||||
|  |                         staticAuthorizedMail); // Use static authorized mail | ||||||
|  |  | ||||||
|  |         List<Appointment> resultList = TestUtils.toList(result); | ||||||
|  |  | ||||||
|  |         // Assert | ||||||
|  |         assertEquals(2, resultList.size()); | ||||||
|  |  | ||||||
|  |         assertTrue( | ||||||
|  |                 resultList.stream() | ||||||
|  |                         .anyMatch(a -> a.getIdAppointment().equals(savedApp1.getIdAppointment()))); | ||||||
|  |         assertTrue( | ||||||
|  |                 resultList.stream() | ||||||
|  |                         .anyMatch(a -> a.getIdAppointment().equals(savedApp2.getIdAppointment()))); | ||||||
|  |  | ||||||
|  |         assertFalse( | ||||||
|  |                 resultList.stream() | ||||||
|  |                         .anyMatch( | ||||||
|  |                                 a -> | ||||||
|  |                                         a.getIdAppointment() | ||||||
|  |                                                 .equals(savedOtherApp.getIdAppointment()))); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /* | ||||||
|  |      * Tests creating a new appointment request when the user is authorized | ||||||
|  |      * for the project linked to the appointment's section cell. | ||||||
|  |      * Verifies that the appointment and its relationships are saved correctly in the database. | ||||||
|  |      */ | ||||||
|  |     // Tests createAppointmentRequest | ||||||
|  |     @Test | ||||||
|  |     // Commenting out failing test | ||||||
|  |     void testCreateAppointmentRequest_Authorized_Success() { | ||||||
|  |         // Arrange: Create transient appointment linked to a cell in the static authorized project | ||||||
|  |         LocalDate date = LocalDate.parse("2026-01-01"); | ||||||
|  |         LocalTime time = LocalTime.parse("10:00:00"); | ||||||
|  |         LocalTime duration = LocalTime.parse("00:30:00"); | ||||||
|  |         String place = "Meeting Room Integrated"; | ||||||
|  |         String subject = "Discuss Project Integrated"; | ||||||
|  |  | ||||||
|  |         SectionCell linkedCell = | ||||||
|  |                 sectionCellService.addNewSectionCell( | ||||||
|  |                         getTestSectionCell( | ||||||
|  |                                 staticAuthorizedProject, | ||||||
|  |                                 0L, | ||||||
|  |                                 "Related Section Content Integrated", | ||||||
|  |                                 LocalDateTime.now())); | ||||||
|  |  | ||||||
|  |         Report newReport = null; // getTestReport(reportContent); // Uses no-arg constructor | ||||||
|  |  | ||||||
|  |         Appointment newAppointment = | ||||||
|  |                 getTestAppointment( | ||||||
|  |                         date, time, duration, place, subject, List.of(linkedCell), newReport); | ||||||
|  |  | ||||||
|  |         // mockUtilsService is configured in BeforeEach to allow staticAuthorizedMail for | ||||||
|  |         // staticAuthorizedProject | ||||||
|  |  | ||||||
|  |         // Act | ||||||
|  |         // Allow the service method to call the actual appointmentService.addNewAppointment | ||||||
|  |         assertDoesNotThrow( | ||||||
|  |                 () -> | ||||||
|  |                         sharedApiService.createAppointmentRequest( | ||||||
|  |                                 newAppointment, staticAuthorizedMail)); | ||||||
|  |  | ||||||
|  |         // Assert: Retrieve the appointment from the DB and verify it and its relationships were | ||||||
|  |         // saved | ||||||
|  |         // We find it by looking for appointments linked to the authorized project's cells | ||||||
|  |         Iterable<SectionCell> projectCells = | ||||||
|  |                 sectionCellService.getSectionCellsByProject( | ||||||
|  |                         staticAuthorizedProject, linkedCell.getSectionId()); // Fetch relevant cells | ||||||
|  |         List<Appointment> projectAppointmentsList = new ArrayList<>(); | ||||||
|  |         projectCells.forEach( | ||||||
|  |                 cell -> | ||||||
|  |                         projectAppointmentsList.addAll( | ||||||
|  |                                 sectionCellService.getAppointmentsBySectionCellId( | ||||||
|  |                                         cell.getIdSectionCell()))); // Get appointments for | ||||||
|  |         // those cells | ||||||
|  |  | ||||||
|  |         Optional<Appointment> createdAppointmentOpt = | ||||||
|  |                 projectAppointmentsList.stream() | ||||||
|  |                         .filter( | ||||||
|  |                                 a -> | ||||||
|  |                                         a.getAppointmentDate().equals(date) | ||||||
|  |                                                 && a.getAppointmentTime().equals(time) | ||||||
|  |                                                 && a.getAppointmentPlace().equals(place) | ||||||
|  |                                                 && a.getAppointmentSubject().equals(subject)) | ||||||
|  |                         .findFirst(); | ||||||
|  |  | ||||||
|  |         assertTrue(createdAppointmentOpt.isPresent()); | ||||||
|  |         Appointment createdAppointment = createdAppointmentOpt.get(); | ||||||
|  |  | ||||||
|  |         // FIX: Corrected bidirectional link check | ||||||
|  |         assertEquals(1, createdAppointment.getAppointmentListSectionCell().size()); | ||||||
|  |         assertTrue( | ||||||
|  |                 createdAppointment.getAppointmentListSectionCell().stream() | ||||||
|  |                         .anyMatch( | ||||||
|  |                                 sc -> sc.getIdSectionCell().equals(linkedCell.getIdSectionCell()))); | ||||||
|  |  | ||||||
|  |         List<Appointment> appointmentsLinkedToCell = | ||||||
|  |                 TestUtils.toList( | ||||||
|  |                         sectionCellService.getAppointmentsBySectionCellId( | ||||||
|  |                                 linkedCell.getIdSectionCell())); | ||||||
|  |         assertTrue( | ||||||
|  |                 appointmentsLinkedToCell.stream() | ||||||
|  |                         .anyMatch( | ||||||
|  |                                 a -> | ||||||
|  |                                         a.getIdAppointment() | ||||||
|  |                                                 .equals(createdAppointment.getIdAppointment()))); | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										10
									
								
								MyINPulse-back/src/test/resources/application.properties
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								MyINPulse-back/src/test/resources/application.properties
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,10 @@ | |||||||
|  | spring.datasource.driver-class-name=org.h2.Driver | ||||||
|  | spring.datasource.url=jdbc:h2:mem:db;DB_CLOSE_DELAY=-1 | ||||||
|  | spring.datasource.username=sa | ||||||
|  | spring.datasource.password=sa | ||||||
|  | spring.sql.init.mode=never | ||||||
|  | spring.application.name=myinpulse-test | ||||||
|  | spring.security.oauth2.resourceserver.jwt.jwk-set-uri=http://localhost:7080/realms/test/protocol/openid-connect/certs | ||||||
|  | spring.security.oauth2.resourceserver.jwt.issuer-uri=http://localhost:7080/realms/test | ||||||
|  | spring.jpa.hibernate.ddl-auto=update | ||||||
|  | logging.pattern.console=%d{yyyy-MMM-dd HH:mm:ss.SSS} [%thread] %highlight(%-5level) %cyan(%logger{15}) - %msg %n | ||||||
							
								
								
									
										22
									
								
								config/.env.dev
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								config/.env.dev
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,22 @@ | |||||||
|  | POSTGRES_DB=postgres_db | ||||||
|  | POSTGRES_USER=postgres | ||||||
|  | POSTGRES_PASSWORD=postgres_db_user_password | ||||||
|  |  | ||||||
|  | KEYCLOAK_ADMIN=admin | ||||||
|  | KEYCLOAK_ADMIN_PASSWORD=admin | ||||||
|  | KEYCLOAK_HOSTNAME=localhost | ||||||
|  | KEYCLOAK_DB=keycloak_db | ||||||
|  | KEYCLOAK_USER=keycloak_db_user | ||||||
|  | KEYCLOAK_PASSWORD=keycloak_db_user_password | ||||||
|  |  | ||||||
|  | BACKEND_DB=backend_db | ||||||
|  | BACKEND_USER=backend_db_user | ||||||
|  | BACKEND_PASSWORD=backend_db_user_password | ||||||
|  |  | ||||||
|  | DATABASE_URL=localhost:5433 | ||||||
|  |  | ||||||
|  | VITE_KEYCLOAK_URL=http://localhost:7080 | ||||||
|  | VITE_KEYCLOAK_CLIENT_ID=myinpulse-dev | ||||||
|  | VITE_KEYCLOAK_REALM=test | ||||||
|  | VITE_APP_URL=http://localhost:5173 | ||||||
|  | VITE_BACKEND_URL=http://localhost:8081/ | ||||||
| @@ -12,3 +12,11 @@ KEYCLOAK_PASSWORD=keycloak_db_user_password | |||||||
| BACKEND_DB=backend_db | BACKEND_DB=backend_db | ||||||
| BACKEND_USER=backend_db_user | BACKEND_USER=backend_db_user | ||||||
| BACKEND_PASSWORD=backend_db_user_password | BACKEND_PASSWORD=backend_db_user_password | ||||||
|  | 
 | ||||||
|  | DATABASE_URL=localhost:5433 | ||||||
|  | 
 | ||||||
|  | VITE_KEYCLOAK_URL=http://localhost:7080 | ||||||
|  | VITE_KEYCLOAK_CLIENT_ID=myinpulse | ||||||
|  | VITE_KEYCLOAK_REALM=test | ||||||
|  | VITE_APP_URL=http://localhost:8080 | ||||||
|  | VITE_BACKEND_URL=http://localhost:8081/ | ||||||
| @@ -1,5 +0,0 @@ | |||||||
| VITE_KEYCLOAK_URL=http://localhost:7080 |  | ||||||
| VITE_KEYCLOAK_CLIENT_ID=myinpulse |  | ||||||
| VITE_KEYCLOAK_REALM=test |  | ||||||
| VITE_APP_URL=http://localhost:8080 |  | ||||||
| VITE_BACKEND_URL=http://localhost:8081/ |  | ||||||
							
								
								
									
										52
									
								
								config/dev.docker-compose.yaml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										52
									
								
								config/dev.docker-compose.yaml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,52 @@ | |||||||
|  | services: | ||||||
|  |   postgres: | ||||||
|  |     env_file: .env | ||||||
|  |     build: | ||||||
|  |       context: postgres/ | ||||||
|  |       dockerfile: Dockerfile | ||||||
|  |     container_name: MyINPulse-DB | ||||||
|  |     ports: | ||||||
|  |       - 5433:5432 | ||||||
|  |     volumes: | ||||||
|  |       - ./postgres/data:/var/lib/postgresql/data | ||||||
|  |  | ||||||
|  |  | ||||||
|  |   keycloak: | ||||||
|  |     container_name: MyINPulse-keycloak | ||||||
|  |     build: | ||||||
|  |       context: ./keycloak | ||||||
|  |       dockerfile: Dockerfile | ||||||
|  |       args: | ||||||
|  |         KC_DB: postgres | ||||||
|  |         KC_DB_URL: jdbc:postgresql://postgres/${POSTGRES_DB} | ||||||
|  |         KC_DB_USERNAME: ${POSTGRES_USER} | ||||||
|  |         KC_DB_PASSWORD: ${POSTGRES_PASSWORD} | ||||||
|  |     environment: | ||||||
|  |       KC_HOSTNAME_PORT: 7080 | ||||||
|  |       KC_HOSTNAME_STRICT_BACKCHANNEL: "true" | ||||||
|  |       KC_BOOTSTRAP_ADMIN_USERNAME: ${KEYCLOAK_ADMIN} | ||||||
|  |       KC_BOOTSTRAP_ADMIN_PASSWORD: ${KEYCLOAK_ADMIN_PASSWORD} | ||||||
|  |       KC_LOG_LEVEL: info | ||||||
|  |     command: ["start-dev", "--http-port", "7080", "--https-port", "7443", "--hostname", "${KEYCLOAK_HOSTNAME}"] | ||||||
|  |     ports: | ||||||
|  |       - "7080:7080" | ||||||
|  |       - "7443:7443" | ||||||
|  |     depends_on: | ||||||
|  |       - postgres | ||||||
|  |  | ||||||
|  |   #front: | ||||||
|  |   #  build: | ||||||
|  |   #    context: ./front/ | ||||||
|  |   #    dockerfile: Dockerfile | ||||||
|  |   #  container_name: MyINPulse-front | ||||||
|  |   #  ports: | ||||||
|  |   #    - "8080:80" | ||||||
|  |  | ||||||
|  |   #back: | ||||||
|  |   #  build: | ||||||
|  |   #    context: ./MyINPulse-back/ | ||||||
|  |   #    dockerfile: Dockerfile | ||||||
|  |   #  container_name: MyINPulse-back | ||||||
|  |   #  ports: | ||||||
|  |   #    - "8081:8080" | ||||||
|  |    | ||||||
							
								
								
									
										22
									
								
								config/dev.env
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								config/dev.env
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,22 @@ | |||||||
|  | POSTGRES_DB=postgres_db | ||||||
|  | POSTGRES_USER=postgres | ||||||
|  | POSTGRES_PASSWORD=postgres_db_user_password | ||||||
|  |  | ||||||
|  | KEYCLOAK_ADMIN=admin | ||||||
|  | KEYCLOAK_ADMIN_PASSWORD=admin | ||||||
|  | KEYCLOAK_HOSTNAME=localhost | ||||||
|  | KEYCLOAK_DB=keycloak_db | ||||||
|  | KEYCLOAK_USER=keycloak_db_user | ||||||
|  | KEYCLOAK_PASSWORD=keycloak_db_user_password | ||||||
|  |  | ||||||
|  | BACKEND_DB=backend_db | ||||||
|  | BACKEND_USER=backend_db_user | ||||||
|  | BACKEND_PASSWORD=backend_db_user_password | ||||||
|  |  | ||||||
|  | DATABASE_URL=localhost:5433 | ||||||
|  |  | ||||||
|  | VITE_KEYCLOAK_URL=http://localhost:7080 | ||||||
|  | VITE_KEYCLOAK_CLIENT_ID=MyINPulse-vite | ||||||
|  | VITE_KEYCLOAK_REALM=MyINPulse | ||||||
|  | VITE_APP_URL=http://localhost:5173 | ||||||
|  | VITE_BACKEND_URL=http://localhost:8081/ | ||||||
| @@ -11,4 +11,12 @@ KEYCLOAK_PASSWORD=keycloak_db_user_password | |||||||
| 
 | 
 | ||||||
| BACKEND_DB=backend_db | BACKEND_DB=backend_db | ||||||
| BACKEND_USER=backend_db_user | BACKEND_USER=backend_db_user | ||||||
| BACKEND_PASSWORD=backend_db_user_password | BACKEND_PASSWORD=backend_db_user_password | ||||||
|  | 
 | ||||||
|  | DATABASE_URL=MyINPulse-DB | ||||||
|  | 
 | ||||||
|  | VITE_KEYCLOAK_URL=http://localhost:7080 | ||||||
|  | VITE_KEYCLOAK_CLIENT_ID=myinpulse-dev | ||||||
|  | VITE_KEYCLOAK_REALM=test | ||||||
|  | VITE_APP_URL=http://localhost:5173 | ||||||
|  | VITE_BACKEND_URL=http://localhost:8081/ | ||||||
| @@ -1,5 +0,0 @@ | |||||||
| VITE_KEYCLOAK_URL=http://localhost:7080 |  | ||||||
| VITE_KEYCLOAK_CLIENT_ID=myinpulse-dev |  | ||||||
| VITE_KEYCLOAK_REALM=test |  | ||||||
| VITE_APP_URL=http://localhost:5173 |  | ||||||
| VITE_BACKEND_URL=http://localhost:8081/ |  | ||||||
| @@ -30,10 +30,10 @@ services: | |||||||
|       KC_BOOTSTRAP_ADMIN_USERNAME: ${KEYCLOAK_ADMIN} |       KC_BOOTSTRAP_ADMIN_USERNAME: ${KEYCLOAK_ADMIN} | ||||||
|       KC_BOOTSTRAP_ADMIN_PASSWORD: ${KEYCLOAK_ADMIN_PASSWORD} |       KC_BOOTSTRAP_ADMIN_PASSWORD: ${KEYCLOAK_ADMIN_PASSWORD} | ||||||
|       KC_LOG_LEVEL: info |       KC_LOG_LEVEL: info | ||||||
|     command: ["start-dev", "--http-port", "7080", "--https-port", "7443", "--hostname", "${KEYCLOAK_HOSTNAME}"] |     command: ["start-dev", "--http-port", "7080", "--https-port", "7443", "--hostname", "${KEYCLOAK_HOSTNAME}"] # TODO: remove start-dev | ||||||
|     ports: |     #ports: | ||||||
|       - "7080:7080" |     #  - "7080:7080" | ||||||
|       - "7443:7443" |     #  - "7443:7443" | ||||||
|     depends_on: |     depends_on: | ||||||
|       - postgres |       - postgres | ||||||
|  |  | ||||||
| @@ -50,6 +50,6 @@ services: | |||||||
|       context: ./MyINPulse-back/ |       context: ./MyINPulse-back/ | ||||||
|       dockerfile: Dockerfile |       dockerfile: Dockerfile | ||||||
|     container_name: MyINPulse-back |     container_name: MyINPulse-back | ||||||
|     ports: |     #ports: | ||||||
|       - "8081:8080" |     #  - "8081:8080" | ||||||
|    |    | ||||||
| @@ -12,3 +12,11 @@ KEYCLOAK_PASSWORD=keycloak_db_user_password | |||||||
| BACKEND_DB=backend_db | BACKEND_DB=backend_db | ||||||
| BACKEND_USER=backend_db_user | BACKEND_USER=backend_db_user | ||||||
| BACKEND_PASSWORD=backend_db_user_password | BACKEND_PASSWORD=backend_db_user_password | ||||||
|  | 
 | ||||||
|  | DATABASE_URL=MyINPulse-DB | ||||||
|  | 
 | ||||||
|  | VITE_KEYCLOAK_URL=https://0549cd63f912d5dc9b31278d6f.eirb.fr | ||||||
|  | VITE_KEYCLOAK_CLIENT_ID=myinpulse-eirb | ||||||
|  | VITE_KEYCLOAK_REALM=test | ||||||
|  | VITE_APP_URL=https://0549cd63f912d5dc9b31278d6f.piair.dev | ||||||
|  | VITE_BACKEND_URL=http://TODO/ | ||||||
| @@ -1,5 +0,0 @@ | |||||||
| VITE_KEYCLOAK_URL=https://0549cd63f912d5dc9b31278d6f.eirb.fr |  | ||||||
| VITE_KEYCLOAK_CLIENT_ID=myinpulse-eirb |  | ||||||
| VITE_KEYCLOAK_REALM=test |  | ||||||
| VITE_APP_URL=https://0549cd63f912d5dc9b31278d6f.piair.dev |  | ||||||
| VITE_BACKEND_URL=http://TODO/ |  | ||||||
							
								
								
									
										12
									
								
								documentation/Doc.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								documentation/Doc.txt
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,12 @@ | |||||||
|  | Format des comptes rendus de réunion : | ||||||
|  | Texte organisé par bullet point, chaque bullet point est séparé par "//" pour pouvoir être correctement généré. | ||||||
|  |  | ||||||
|  | Exemple : | ||||||
|  | Le texte "// blablabla // oui bonjour" | ||||||
|  | donne le résultat | ||||||
|  |  | ||||||
|  | Point n°1 : | ||||||
|  |   blablabla | ||||||
|  |  | ||||||
|  | Point n°2 : | ||||||
|  |   oui bonjour | ||||||
							
								
								
									
										13
									
								
								documentation/openapi/notes.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								documentation/openapi/notes.md
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,13 @@ | |||||||
|  | ## API Endpoints notes | ||||||
|  |  | ||||||
|  | ### EntrepreneurApi and SharedApi | ||||||
|  | #### Endpoint Name Changes | ||||||
|  | - `/entrepreneur/lcsection/modify/{sectionId}` → `/entrepreneur/sectionCell/modify/{sectionId}` | ||||||
|  |  | ||||||
|  | ### Admin api | ||||||
|  | - `/admin/appointments/report/{appointmentId}` has no PUT and DELETE | ||||||
|  | - `/admin/request-join` and `/admin/request-join/decision/{joinRequestId}` have not yet been implemented | ||||||
|  |  | ||||||
|  | ### Unauth api | ||||||
|  | - `/unauth/request-join/{projectId}` has not yet been implemented | ||||||
|  |  | ||||||
							
								
								
									
										11
									
								
								documentation/openapi/run_doc.sh
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										11
									
								
								documentation/openapi/run_doc.sh
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,11 @@ | |||||||
|  | #!/bin/bash | ||||||
|  |  | ||||||
|  | cd ./swagger-ui | ||||||
|  |  | ||||||
|  | if [ ! -d "./node_modules/" ] | ||||||
|  | then | ||||||
|  |     npm install | ||||||
|  |     npm install swagger-cli | ||||||
|  | fi | ||||||
|  |  | ||||||
|  | npm start | ||||||
							
								
								
									
										387
									
								
								documentation/openapi/src/adminApi.yaml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										387
									
								
								documentation/openapi/src/adminApi.yaml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,387 @@ | |||||||
|  | # Admin API Endpoints | ||||||
|  | paths: | ||||||
|  |   /admin/projects: | ||||||
|  |     get: | ||||||
|  |       operationId: getAdminProjects | ||||||
|  |       summary: Get projects associated with the admin | ||||||
|  |       tags: | ||||||
|  |         - Admin API | ||||||
|  |       security: | ||||||
|  |         - MyINPulse: [MyINPulse-admin] | ||||||
|  |       description: Retrieves a list of projects managed by the requesting admin, including details for overview. | ||||||
|  |       responses: | ||||||
|  |         "200": | ||||||
|  |           description: OK - List of projects returned successfully. | ||||||
|  |           content: | ||||||
|  |             application/json: | ||||||
|  |               schema: | ||||||
|  |                 type: array | ||||||
|  |                 items: | ||||||
|  |                   $ref: "./main.yaml#/components/schemas/project" | ||||||
|  |         "400": | ||||||
|  |           description: Bad Request - Invalid project data provided (e.g., missing required fields). | ||||||
|  |         "401": | ||||||
|  |           description: Unauthorized - Authentication required or invalid token. | ||||||
|  |         "403": | ||||||
|  |           description: Bad Token - Invalid Keycloack configuration. | ||||||
|  |            | ||||||
|  |     post: | ||||||
|  |       operationId: addProjectManually | ||||||
|  |       summary: Manually add a new project | ||||||
|  |       description: Creates a new project with the provided details. (NOTE that this meant for manually inserting projects, for example importing already existing projects). | ||||||
|  |       tags: | ||||||
|  |         - Admin API | ||||||
|  |       security: | ||||||
|  |         - MyINPulse: [MyINPulse-admin] | ||||||
|  |       requestBody: | ||||||
|  |         required: true | ||||||
|  |         description: Project details to create. `idProject` and `creationDate` will be ignored if sent and set by the server. | ||||||
|  |         content: | ||||||
|  |           application/json: | ||||||
|  |             schema: | ||||||
|  |               $ref: "./main.yaml#/components/schemas/project" | ||||||
|  |       responses: | ||||||
|  |         "200": # Use 200 Created for successful creation | ||||||
|  |           description: Created - Project added successfully. Returns the created project. | ||||||
|  |           content: | ||||||
|  |             application/json: | ||||||
|  |               schema: | ||||||
|  |                 $ref: "./main.yaml#/components/schemas/project" | ||||||
|  |         "409": | ||||||
|  |           description: Bad Request - Project already exists. | ||||||
|  |         "401": | ||||||
|  |           description: Unauthorized. | ||||||
|  |         "403": | ||||||
|  |           description: Bad Token - Invalid Keycloack configuration. | ||||||
|  |            | ||||||
|  |  | ||||||
|  |   /admin/projects/pending: | ||||||
|  |     get: | ||||||
|  |       operationId: getPendingProjects | ||||||
|  |       summary: Get projects awaiting validation | ||||||
|  |       tags: | ||||||
|  |         - Admin API | ||||||
|  |       security: | ||||||
|  |         - MyINPulse: [MyINPulse-admin] | ||||||
|  |       description: Retrieves a list of projects submitted by entrepreneurs that are pending admin approval. | ||||||
|  |       responses: | ||||||
|  |         "200": | ||||||
|  |           description: OK - List of pending projects returned. | ||||||
|  |           content: | ||||||
|  |             application/json: | ||||||
|  |               schema: | ||||||
|  |                 type: array | ||||||
|  |                 items: | ||||||
|  |                   $ref: "./main.yaml#/components/schemas/project" # Assuming pending projects use the same schema | ||||||
|  |         "401": | ||||||
|  |           description: Unauthorized. | ||||||
|  |         "403": | ||||||
|  |           description: Bad Token - Invalid Keycloack configuration.       | ||||||
|  |  | ||||||
|  |   /admin/request-join: | ||||||
|  |     get: | ||||||
|  |       operationId: getPendingProjects | ||||||
|  |       summary: Get entrepreneurs project join requests | ||||||
|  |       tags: | ||||||
|  |         - Admin API | ||||||
|  |       security: | ||||||
|  |         - MyINPulse: [MyINPulse-admin] | ||||||
|  |       description:  Retrieves a list of pending requests from entrepreneurs to join an existing project. | ||||||
|  |       responses: | ||||||
|  |         "200": | ||||||
|  |           description: OK - List of pending project join requests. | ||||||
|  |           content: | ||||||
|  |             application/json: | ||||||
|  |               schema: | ||||||
|  |                 type: array | ||||||
|  |                 items: | ||||||
|  |                   $ref: "./main.yaml#/components/schemas/joinRequest" | ||||||
|  |         "401": | ||||||
|  |           description: Unauthorized. | ||||||
|  |         "403": | ||||||
|  |           description: Bad Token - Invalid Keycloack configuration. | ||||||
|  |    | ||||||
|  |   /admin/request-join/decision/{joinRequestId}: | ||||||
|  |     post: | ||||||
|  |       summary: Approve or reject a pending project join request | ||||||
|  |       tags: | ||||||
|  |         - Admin API | ||||||
|  |       security: | ||||||
|  |         - MyINPulse: [MyINPulse-admin] | ||||||
|  |       parameters: | ||||||
|  |         - in: path | ||||||
|  |           name: joinRequestId | ||||||
|  |           required: true | ||||||
|  |           schema: | ||||||
|  |             type: integer | ||||||
|  |           description: The ID of the pending join request to decide upon. | ||||||
|  |          | ||||||
|  |       description: |- | ||||||
|  |         Allows an admin to make a decision on an ebtrepreneur's request to join an existing project awaiting validation. | ||||||
|  |         If approved (isAccepted=true), the entrepreneur is linked to the project with ID joinRequestId. | ||||||
|  |         If rejected (isAccepted=false), the pending request data might be archived or deleted based on business logic. | ||||||
|  |       responses: | ||||||
|  |         "200": | ||||||
|  |           description: OK - No Content, decision processed successfully.. | ||||||
|  |           content: | ||||||
|  |             application/json: | ||||||
|  |               $ref: "./main.yaml#/components/schemas/joinRequestDecision" | ||||||
|  |         "400": | ||||||
|  |           description: Bad Request - Invalid input (e.g., missing decision). | ||||||
|  |         "401": | ||||||
|  |           description: Unauthorized. | ||||||
|  |         "403": | ||||||
|  |           description: Bad Token - Invalid Keycloack configuration.    | ||||||
|  |  | ||||||
|  |  | ||||||
|  |   /admin/projects/pending/decision: | ||||||
|  |     post: | ||||||
|  |       operationId: decidePendingProject | ||||||
|  |       summary: Approve or reject a pending project | ||||||
|  |       tags: | ||||||
|  |         - Admin API | ||||||
|  |       description: |- | ||||||
|  |         Allows an admin to make a decision on a project awaiting validation. | ||||||
|  |         If approved (isAccepted=true), the project status changes, and it's linked to the involved users. | ||||||
|  |         If rejected (isAccepted=false), the pending project data might be archived or deleted based on business logic. | ||||||
|  |       security: | ||||||
|  |           - MyINPulse: [MyINPulse-admin] | ||||||
|  |       requestBody: | ||||||
|  |         required: true | ||||||
|  |         description: Decision payload. | ||||||
|  |         content: | ||||||
|  |           application/json: | ||||||
|  |             schema: | ||||||
|  |               $ref: './main.yaml#/components/schemas/projectDecision' | ||||||
|  |       responses: | ||||||
|  |         "200": # Use 200 No Content for successful action with no body | ||||||
|  |           description: No Content - Decision processed successfully. | ||||||
|  |         "400": | ||||||
|  |           description: Bad Request - Invalid input (e.g., missing decision). | ||||||
|  |         "401": | ||||||
|  |           description: Unauthorized. | ||||||
|  |         "403": | ||||||
|  |           description: Bad Token - Invalid Keycloack configuration. | ||||||
|  |            | ||||||
|  |  | ||||||
|  |   /admin/pending-accounts: # Path updated | ||||||
|  |     get: | ||||||
|  |       operationId: getPendingAccounts | ||||||
|  |       summary: Get accounts awaiting validation | ||||||
|  |       description: Retrieves a list of entrepreneur user accounts that are pending admin validation. | ||||||
|  |       tags: | ||||||
|  |         - Admin API | ||||||
|  |       security: | ||||||
|  |           - MyINPulse: [MyINPulse-admin] | ||||||
|  |       responses: | ||||||
|  |         "200": | ||||||
|  |           description: OK - List of pending accounts returned. | ||||||
|  |           content: | ||||||
|  |             application/json: | ||||||
|  |               schema: | ||||||
|  |                 type: array | ||||||
|  |                 items: | ||||||
|  |                   $ref: "./main.yaml#/components/schemas/user-entrepreneur" | ||||||
|  |         "401": | ||||||
|  |           description: Unauthorized. | ||||||
|  |         "403": | ||||||
|  |           description: Bad Token - Invalid Keycloack configuration. | ||||||
|  |  | ||||||
|  |   /admin/accounts/validate/{userId}: | ||||||
|  |     post: # Changed to POST as it changes state | ||||||
|  |       operationId: validateUserAccount | ||||||
|  |       summary: Validate a pending user account | ||||||
|  |       description: Marks the user account specified by userId as validated/active. | ||||||
|  |       tags: | ||||||
|  |         - Admin API | ||||||
|  |       security: | ||||||
|  |           - MyINPulse: [MyINPulse-admin] | ||||||
|  |       parameters: | ||||||
|  |         - in: path | ||||||
|  |           name: userId | ||||||
|  |           required: true | ||||||
|  |           schema: | ||||||
|  |             type: integer | ||||||
|  |           description: The ID of the user account to validate. | ||||||
|  |           example: 102 | ||||||
|  |       responses: | ||||||
|  |         "200": | ||||||
|  |           description: No Content - Account validated successfully. | ||||||
|  |         "400": | ||||||
|  |           description: Bad Request - Invalid user ID format. | ||||||
|  |         "403": | ||||||
|  |           description: Bad Token - Invalid Keycloack configuration.   | ||||||
|  |         "401": | ||||||
|  |           description: Unauthorized. | ||||||
|  |  | ||||||
|  |   /admin/appointments/upcoming: | ||||||
|  |     get: | ||||||
|  |       operationId: getUpcomingAppointments | ||||||
|  |       summary: Get upcoming appointments for an admin | ||||||
|  |       tags: | ||||||
|  |         - Admin API | ||||||
|  |       security: | ||||||
|  |         - MyINPulse: [MyINPulse-admin] | ||||||
|  |       description: Retrieves a list of appointments scheduled for an admin in the future. | ||||||
|  |       responses: | ||||||
|  |         "200": | ||||||
|  |           description: OK - List of upcoming appointments. | ||||||
|  |           content: | ||||||
|  |             application/json: | ||||||
|  |               schema: | ||||||
|  |                 type: array | ||||||
|  |                 items: | ||||||
|  |                   $ref: "./main.yaml#/components/schemas/appointment" | ||||||
|  |         "403": | ||||||
|  |           description: Bad Token - Invalid Keycloack configuration. | ||||||
|  |         "404": | ||||||
|  |           description: no appointments found. | ||||||
|  |         "401": | ||||||
|  |           description: Unauthorized. | ||||||
|  |  | ||||||
|  |   /admin/appointments/report/{appointmentId}: | ||||||
|  |     post: | ||||||
|  |       operationId: createAppointmentReport | ||||||
|  |       summary: Create a report for an appointment | ||||||
|  |       description: Creates and links a new report (e.g., meeting minutes) to the specified appointment using the provided content. | ||||||
|  |       tags: | ||||||
|  |         - Admin API | ||||||
|  |       security: | ||||||
|  |         - MyINPulse: [MyINPulse-admin] | ||||||
|  |       parameters: | ||||||
|  |         - in: path | ||||||
|  |           name: appointmentId | ||||||
|  |           required: true | ||||||
|  |           schema: | ||||||
|  |             type: integer | ||||||
|  |           description: ID of the appointment to add a report to. | ||||||
|  |           example: 303 | ||||||
|  |       requestBody: | ||||||
|  |         required: true | ||||||
|  |         description: Report content. `idReport` will be ignored if sent. | ||||||
|  |         content: | ||||||
|  |           application/json: | ||||||
|  |             schema: | ||||||
|  |               $ref: "./main.yaml#/components/schemas/report" | ||||||
|  |       responses: | ||||||
|  |         "200": | ||||||
|  |           description: Created - Report created and linked successfully. Returns the created report. | ||||||
|  |           content: | ||||||
|  |              application/json: | ||||||
|  |                 schema: { $ref: "./main.yaml#/components/schemas/report" } | ||||||
|  |         "400": | ||||||
|  |           description: Bad Request - Invalid input (e.g., missing content, invalid appointment ID format). | ||||||
|  |         "403": | ||||||
|  |           description: Bad Token - Invalid Keycloack configuration. | ||||||
|  |         "401": | ||||||
|  |           description: Unauthorized. | ||||||
|  |            | ||||||
|  |     put: # Changed to PUT for update/replacement | ||||||
|  |       operationId: updateAppointmentReport | ||||||
|  |       summary: Update an existing appointment report | ||||||
|  |       description: Updates the content of an existing report linked to the specified appointment. Replaces the entire report content. | ||||||
|  |       tags: | ||||||
|  |         - Admin API | ||||||
|  |       security: | ||||||
|  |         - MyINPulse: [MyINPulse-admin] | ||||||
|  |       parameters: | ||||||
|  |         - in: path | ||||||
|  |           name: appointmentId | ||||||
|  |           required: true | ||||||
|  |           schema: | ||||||
|  |             type: integer | ||||||
|  |           description: ID of the appointment whose report needs updating. | ||||||
|  |           example: 303 | ||||||
|  |       requestBody: | ||||||
|  |         required: true | ||||||
|  |         description: New report content. `idReport` in the body should match the existing report's ID or will be ignored. | ||||||
|  |         content: | ||||||
|  |           application/json: | ||||||
|  |             schema: | ||||||
|  |               $ref: "./main.yaml#/components/schemas/report" | ||||||
|  |       responses: | ||||||
|  |         "200": | ||||||
|  |           description: OK - Report updated successfully. Returns the updated report. | ||||||
|  |           content: | ||||||
|  |              application/json: | ||||||
|  |                 schema: { $ref: "./main.yaml#/components/schemas/report" } | ||||||
|  |         "400": | ||||||
|  |           description: Bad Request - Invalid input (e.g., missing content). | ||||||
|  |         "403": | ||||||
|  |           description: Bad Token - Invalid Keycloack configuration. | ||||||
|  |         "401": | ||||||
|  |           description: Unauthorized. | ||||||
|  |  | ||||||
|  |  | ||||||
|  |   /admin/projects/{projectId}: | ||||||
|  |     delete: | ||||||
|  |       operationId: removeProject | ||||||
|  |       summary: Remove a project | ||||||
|  |       description: Permanently removes the project specified by projectId and potentially related data (use with caution). | ||||||
|  |       tags: | ||||||
|  |         - Admin API | ||||||
|  |       security: | ||||||
|  |           - MyINPulse: [MyINPulse-admin] | ||||||
|  |       parameters: | ||||||
|  |         - in: path | ||||||
|  |           name: projectId | ||||||
|  |           required: true | ||||||
|  |           schema: | ||||||
|  |             type: integer | ||||||
|  |           description: The ID of the project to remove. | ||||||
|  |           example: 12 | ||||||
|  |       responses: | ||||||
|  |         "200": | ||||||
|  |           description: No Content - Project removed successfully. | ||||||
|  |         "400": | ||||||
|  |           description: Bad Request - Invalid project ID format. | ||||||
|  |         "403": | ||||||
|  |           description: Bad Token - Invalid Keycloack configuration. | ||||||
|  |         "401": | ||||||
|  |           description: Unauthorized. | ||||||
|  |            | ||||||
|  |  | ||||||
|  |  | ||||||
|  |   /admin/make-admin/{userId}: | ||||||
|  |     post: | ||||||
|  |       operationId: grantAdminRights | ||||||
|  |       summary: Grant admin rights to a user | ||||||
|  |       tags: | ||||||
|  |         - Admin API | ||||||
|  |       security: | ||||||
|  |         - MyINPulse: [MyINPulse-admin] | ||||||
|  |       description: Elevates the specified user to also have administrator privileges. Assumes the user already exists. | ||||||
|  |       parameters: | ||||||
|  |         - in: path | ||||||
|  |           name: userId | ||||||
|  |           required: true | ||||||
|  |           schema: | ||||||
|  |             type: integer | ||||||
|  |           description: The ID of the user to grant admin rights. | ||||||
|  |           example: 103 | ||||||
|  |       responses: | ||||||
|  |         "200": # Use 200 No Content | ||||||
|  |           description: No Content - Admin rights granted successfully. | ||||||
|  |         "400": | ||||||
|  |           description: Bad Request - Invalid user ID format or user is already an admin. | ||||||
|  |         "403": | ||||||
|  |           description: Bad Token - Invalid Keycloack configuration. | ||||||
|  |         "401": | ||||||
|  |           description: Unauthorized. | ||||||
|  |          | ||||||
|  |   /admin/create-account: | ||||||
|  |     post: | ||||||
|  |       summary: Creates Admin out Jwt Token | ||||||
|  |       tags: | ||||||
|  |         - Admin API | ||||||
|  |       security: | ||||||
|  |         - MyINPulse: [MyINPulse-admin] | ||||||
|  |       description: Create an admin instance in the MyINPulse DB of the information provided from the authenticated user's keycloack token. | ||||||
|  |        The information required in the token are `userSurname`, `username`, `primaryMail`, `secondaryMail`, `phoneNumber`. | ||||||
|  |       responses: | ||||||
|  |         "200":  | ||||||
|  |           description: No Content - Admin user created successfully. | ||||||
|  |         "401": | ||||||
|  |           description: Unauthorized. | ||||||
|  |         "403": | ||||||
|  |           description: Bad Token - Invalid Keycloack configuration. | ||||||
							
								
								
									
										197
									
								
								documentation/openapi/src/entrepreneurApi.yaml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										197
									
								
								documentation/openapi/src/entrepreneurApi.yaml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,197 @@ | |||||||
|  | # Entrepreneur API Endpoints | ||||||
|  | paths: | ||||||
|  |   /entrepreneur/projects/request: | ||||||
|  |     post: | ||||||
|  |       operationId: requestProjectCreation | ||||||
|  |       summary: Request creation and validation of a new project | ||||||
|  |       tags: | ||||||
|  |         - Entrepreneurs API | ||||||
|  |       description: |- | ||||||
|  |         Submits a request for a new project. The project details are provided in the request body. | ||||||
|  |         The requesting entrepreneur (identified by the token) will be associated to it. | ||||||
|  |         The project is created with a 'pending' status, awaiting admin approval. | ||||||
|  |       security: | ||||||
|  |         - MyINPulse: [MyINPulse-entrepreneur] | ||||||
|  |       requestBody: | ||||||
|  |         required: true | ||||||
|  |         description: Project details for the request. `status`, `creationDate` are required by the model when being sent but is ignored by the server;  | ||||||
|  |           primarily expects a valid `projectId`, `name`, `logo`. | ||||||
|  |         content: | ||||||
|  |           application/json: | ||||||
|  |             schema: | ||||||
|  |               $ref: "./main.yaml#/components/schemas/project" | ||||||
|  |       responses: | ||||||
|  |         "200": | ||||||
|  |           description: Accepted - Project creation request received and is pending validation. | ||||||
|  |         "400": | ||||||
|  |           description: Bad Request - Invalid input (e.g., missing name). | ||||||
|  |         "401": | ||||||
|  |           description: Unauthorized. | ||||||
|  |         "403": | ||||||
|  |           description: Bad Token - Invalid Keycloack configuration. | ||||||
|  |          | ||||||
|  |   /entrepreneur/sectionCells: # Base path | ||||||
|  |     post: | ||||||
|  |       operationId: addSectionCell | ||||||
|  |       summary: Add a cell to a Lean Canvas section | ||||||
|  |       description: Adds a new cell (like a sticky note) with the provided content to a specific section of the entrepreneur's project's Lean Canvas. Assumes project context is known based on user's token. | ||||||
|  |         `idSectionCell` and `modificationDate` are server-generated so they're values in the request are ignored by the server. | ||||||
|  |       tags: | ||||||
|  |        - Entrepreneurs API | ||||||
|  |       security: | ||||||
|  |         - MyINPulse: [MyINPulse-entrepreneur] | ||||||
|  |       requestBody: | ||||||
|  |         required: true | ||||||
|  |         description: Section cell details. `idSectionCell` and `modificationDate` will be ignored if sent. | ||||||
|  |         content: | ||||||
|  |           application/json: | ||||||
|  |             schema: | ||||||
|  |               $ref: "./main.yaml#/components/schemas/sectionCell" | ||||||
|  |       responses: | ||||||
|  |         "200": | ||||||
|  |           description: Created - Section cell added successfully. Returns the created cell. | ||||||
|  |         "400": | ||||||
|  |           description: Bad Request - Invalid input (e.g., missing content or sectionId). | ||||||
|  |         "401": | ||||||
|  |           description: Unauthorized. | ||||||
|  |         "403": | ||||||
|  |           description: Bad Token - Invalid Keycloack configuration. | ||||||
|  |            | ||||||
|  |   /entrepreneur/sectionCells/{sectionCellId}: | ||||||
|  |     put: | ||||||
|  |       operationId: modifySectionCell | ||||||
|  |       summary: Modify data in a Lean Canvas section cell | ||||||
|  |       description: Updates the content of an existing Lean Canvas section cell specified by `sectionCellId`. The server "updates" (it keeps a record of the previous version to keep a history of all the sectionCells and creates a new ones with the specified modifications) the `modificationDate`. | ||||||
|  |       tags: | ||||||
|  |        - Entrepreneurs API | ||||||
|  |       security: | ||||||
|  |         - MyINPulse: [MyINPulse-entrepreneur] | ||||||
|  |       parameters: | ||||||
|  |         - in: path | ||||||
|  |           name: sectionCellId | ||||||
|  |           required: true | ||||||
|  |           schema: | ||||||
|  |             type: integer | ||||||
|  |           description: The ID of the section cell to modify. | ||||||
|  |           example: 508 | ||||||
|  |       requestBody: | ||||||
|  |         required: true | ||||||
|  |         description: Updated section cell details. `sectionCellId` "the path parameter" is the only id that's consideredn the `sectionCellId` id in the request body is ignored. `modificationDate` should be updated by the server. | ||||||
|  |         content: | ||||||
|  |           application/json: | ||||||
|  |             schema: | ||||||
|  |               $ref: "./main.yaml#/components/schemas/sectionCell" | ||||||
|  |       responses: | ||||||
|  |         "200": | ||||||
|  |           description: OK - Section cell updated successfully. Returns the updated cell. | ||||||
|  |         "404": | ||||||
|  |           description: Bad Request - Invalid input or ID mismatch. | ||||||
|  |         "401": | ||||||
|  |           description: Unauthorized. | ||||||
|  |         "403": | ||||||
|  |           description: Bad Token - Invalid Keycloack configuration. | ||||||
|  |  | ||||||
|  |     delete: | ||||||
|  |       operationId: removeSectionCell | ||||||
|  |       summary: Remove a Lean Canvas section cell | ||||||
|  |       description: Deletes the Lean Canvas section cell specified by `sectionCellId`. | ||||||
|  |       tags: | ||||||
|  |         - Entrepreneurs API | ||||||
|  |       security: | ||||||
|  |         - MyINPulse: [MyINPulse-entrepreneur] | ||||||
|  |       parameters: | ||||||
|  |         - in: path | ||||||
|  |           name: sectionCellId | ||||||
|  |           required: true | ||||||
|  |           schema: | ||||||
|  |             type: integer | ||||||
|  |           description: The ID of the section cell to remove. | ||||||
|  |           example: 509 | ||||||
|  |       responses: | ||||||
|  |         "200": | ||||||
|  |           description: No Content - Section cell removed successfully. | ||||||
|  |         "400": | ||||||
|  |           description: Bad Request - Invalid ID format. | ||||||
|  |         "404": | ||||||
|  |           description: Bad Request - sectionCell not found. | ||||||
|  |         "401": | ||||||
|  |           description: Unauthorized. | ||||||
|  |         "403": | ||||||
|  |           description: Bad Token - Invalid Keycloack configuration. | ||||||
|  |  | ||||||
|  |  | ||||||
|  |   /entrepreneur/projects: | ||||||
|  |     get: | ||||||
|  |       summary: gets the projectId of the project associated with the entrepreneur  | ||||||
|  |       description: returns a list of projectIds of the projects associated with the entrepreneur | ||||||
|  |       tags: | ||||||
|  |        - Entrepreneurs API | ||||||
|  |       security: | ||||||
|  |         - MyINPulse: [MyINPulse-entrepreneur] | ||||||
|  |       parameters: | ||||||
|  |       responses: | ||||||
|  |         "200": | ||||||
|  |           description: OK - Section cell updated successfully. Returns the updated cell. | ||||||
|  |           content: | ||||||
|  |             application/json: | ||||||
|  |               schema: | ||||||
|  |                 type: array | ||||||
|  |                 items: | ||||||
|  |                   $ref: "./main.yaml#/components/schemas/project" | ||||||
|  |         "404": | ||||||
|  |           description: Bad Request - Invalid input or ID mismatch. | ||||||
|  |         "401": | ||||||
|  |           description: Unauthorized or identity not found | ||||||
|  |         "403": | ||||||
|  |           description: Bad Token - Invalid Keycloack configuration. | ||||||
|  |  | ||||||
|  |  | ||||||
|  |   /entrepreneur/projects/project-is-active: | ||||||
|  |     get: | ||||||
|  |       summary: checks if the project associated with an entrepreneur is active  | ||||||
|  |       description: returns a boolean if the project associated with an entrepreneur has an active status  | ||||||
|  |         (i.e has been validated by an admin). The user should be routed to LeanCanvas. any other response code  | ||||||
|  |         should be treated as false | ||||||
|  |       tags: | ||||||
|  |        - Entrepreneurs API | ||||||
|  |       security: | ||||||
|  |         - MyINPulse: [MyINPulse-entrepreneur] | ||||||
|  |       parameters: | ||||||
|  |       responses: | ||||||
|  |         "200": | ||||||
|  |           description: OK - got the value successfully any other response code should be treated as false. | ||||||
|  |           content: | ||||||
|  |             application/json: | ||||||
|  |               schema: | ||||||
|  |                 type: boolean | ||||||
|  |         "404": | ||||||
|  |           description: Bad Request - Invalid input or ID mismatch. | ||||||
|  |         "401": | ||||||
|  |           description: Unauthorized or identity not found | ||||||
|  |         "403": | ||||||
|  |           description: Bad Token - Invalid Keycloack configuration. | ||||||
|  |  | ||||||
|  |   /entrepreneur/projects/has-pending-request: | ||||||
|  |     get: | ||||||
|  |       summary: checks if the user has a pending projectRequest  | ||||||
|  |       description: returns a boolean if the project associated with an entrepreneur has a pending status  | ||||||
|  |         (i.e has not yet been validated by an admin). The user should be routed to a page telling him that he should  | ||||||
|  |         wait for admin validation. any other response code should be treated as false. | ||||||
|  |       tags: | ||||||
|  |        - Entrepreneurs API | ||||||
|  |       security: | ||||||
|  |         - MyINPulse: [MyINPulse-entrepreneur] | ||||||
|  |       parameters: | ||||||
|  |       responses: | ||||||
|  |         "200": | ||||||
|  |           description: OK - got the value successfully any other response code should be treated as false. | ||||||
|  |           content: | ||||||
|  |             application/json: | ||||||
|  |               schema: | ||||||
|  |                 type: boolean | ||||||
|  |         "404": | ||||||
|  |           description: Bad Request - Invalid input or ID mismatch. | ||||||
|  |         "401": | ||||||
|  |           description: Unauthorized or identity not found | ||||||
|  |         "403": | ||||||
|  |           description: Bad Token - Invalid Keycloack configuration. | ||||||
							
								
								
									
										159
									
								
								documentation/openapi/src/main.yaml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										159
									
								
								documentation/openapi/src/main.yaml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,159 @@ | |||||||
|  | openapi: 3.0.3 | ||||||
|  | info: | ||||||
|  |   title: MyInpulse Backend API | ||||||
|  |   description: This serves as an OpenAPI documentation for the MyInpulse backend service, covering operations for Entrepreneurs, Admins, and shared functionalities. | ||||||
|  |   version: 0.2.1 | ||||||
|  |  | ||||||
|  | tags: | ||||||
|  |   - name: Entrepreneurs API | ||||||
|  |     description: API endpoints primarily for Entrepreneur users. | ||||||
|  |   - name: Admin API | ||||||
|  |     description: API endpoints restricted to Admin users for management tasks. | ||||||
|  |   - name: Shared API | ||||||
|  |     description: API endpoints accessible by both Entrepreneurs and Admins. | ||||||
|  |   - name: Unauth API | ||||||
|  |     description: API endpoints related to user account management. | ||||||
|  |  | ||||||
|  | components: | ||||||
|  |   schemas: | ||||||
|  |     user: | ||||||
|  |       $ref: "models.yaml#/user" | ||||||
|  |     user-entrepreneur: | ||||||
|  |       $ref: "models.yaml#/user-entrepreneur" | ||||||
|  |     user-admin: | ||||||
|  |       $ref: "models.yaml#/user-admin" | ||||||
|  |     sectionCell: | ||||||
|  |       $ref: "models.yaml#/sectionCell" | ||||||
|  |     project: | ||||||
|  |       $ref: "models.yaml#/project" | ||||||
|  |     report: | ||||||
|  |       $ref: "models.yaml#/report" | ||||||
|  |     appointment: | ||||||
|  |       $ref: "models.yaml#/appointment" | ||||||
|  |     joinRequest: | ||||||
|  |       $ref: "models.yaml#/joinRequest" | ||||||
|  |     projectDecision: | ||||||
|  |       $ref: "models.yaml#/projectDecision" | ||||||
|  |     joinRequestDecision: | ||||||
|  |       $ref: "models.yaml#/joinRequestDecision" | ||||||
|  |  | ||||||
|  |   securitySchemes: | ||||||
|  |       MyINPulse: | ||||||
|  |         type: oauth2 | ||||||
|  |         description: OAuth2 authentication using Keycloak. | ||||||
|  |         flows: | ||||||
|  |           implicit: | ||||||
|  |             authorizationUrl: '{keycloakBaseUrl}/realms/{keycloakRealm}/protocol/openid-connect/auth' | ||||||
|  |             scopes: | ||||||
|  |               MyINPulse-admin: Grants administrator access. | ||||||
|  |               MyINPulse-entrepreneur: Grants standard entrepreneur user access. | ||||||
|  |  | ||||||
|  | servers: | ||||||
|  |     - url: '{serverProtocol}://{serverHost}:{serverPort}' | ||||||
|  |       description: API Server | ||||||
|  |       variables: | ||||||
|  |         serverProtocol: | ||||||
|  |           enum: [http, https] | ||||||
|  |           default: http | ||||||
|  |         serverHost: | ||||||
|  |           default: localhost | ||||||
|  |         serverPort: | ||||||
|  |           enum: ['8081']  | ||||||
|  |           default: '8081' | ||||||
|  |         keycloakBaseUrl: | ||||||
|  |           default: http://localhost:7080 | ||||||
|  |           description: Base URL for the Keycloak server. | ||||||
|  |         keycloakRealm: | ||||||
|  |           default: MyInpulseRealm  | ||||||
|  |           description: Keycloak realm name. | ||||||
|  |  | ||||||
|  | paths: | ||||||
|  |   #       _   _                   _   _        _          _  | ||||||
|  |   #      | | | |_ __   __ _ _   _| |_| |__    / \   _ __ (_) | ||||||
|  |   #      | | | | '_ \ / _` | | | | __| '_ \  / _ \ | '_ \| | | ||||||
|  |   #      | |_| | | | | (_| | |_| | |_| | | |/ ___ \| |_) | | | ||||||
|  |   #       \___/|_| |_|\__,_|\__,_|\__|_| |_/_/   \_\ .__/|_| | ||||||
|  |   #                                                |_|       | ||||||
|  |  | ||||||
|  |   /unauth/finalize: | ||||||
|  |     $ref: "./unauthApi.yaml#/paths/~1unauth~1finalize" | ||||||
|  |   /unauth/request-join/{projectId}: | ||||||
|  |     $ref: "./unauthApi.yaml#/paths/~1unauth~1request-join~1{projectId}" | ||||||
|  |   /unauth/request-admin-role: | ||||||
|  |     $ref: "./unauthApi.yaml#/paths/~1unauth~1request-admin-role" | ||||||
|  |   /unauth/check-if-not-pending: | ||||||
|  |     $ref: "./unauthApi.yaml#/paths/~1unauth~1check-if-not-pending" | ||||||
|  |  | ||||||
|  |   #          _    ____  __  __ ___ _   _      _    ____ ___ | ||||||
|  |   #         / \  |  _ \|  \/  |_ _| \ | |    / \  |  _ \_ _| | ||||||
|  |   #        / _ \ | | | | |\/| || ||  \| |   / _ \ | |_) | | | ||||||
|  |   #       / ___ \| |_| | |  | || || |\  |  / ___ \|  __/| | | ||||||
|  |   #      /_/   \_\____/|_|  |_|___|_| \_| /_/   \_\_|  |___| | ||||||
|  |   # | ||||||
|  |   /admin/pending-accounts: | ||||||
|  |     $ref: "./adminApi.yaml#/paths/~1admin~1pending-accounts" | ||||||
|  |   /admin/accounts/validate/{userId}: | ||||||
|  |     $ref: "./adminApi.yaml#/paths/~1admin~1accounts~1validate~1{userId}" | ||||||
|  |   /admin/request-join: | ||||||
|  |     $ref: "./adminApi.yaml#/paths/~1admin~1request-join" | ||||||
|  |   /admin/request-join/decision/{joinRequestId}: | ||||||
|  |     $ref: "./adminApi.yaml#/paths/~1admin~1request-join~1decision~1{joinRequestId}" | ||||||
|  |   /admin/projects: | ||||||
|  |     $ref: "./adminApi.yaml#/paths/~1admin~1projects" | ||||||
|  |   /admin/projects/pending: | ||||||
|  |     $ref: "./adminApi.yaml#/paths/~1admin~1projects~1pending" | ||||||
|  |   /admin/projects/pending/decision: | ||||||
|  |     $ref: "./adminApi.yaml#/paths/~1admin~1projects~1pending~1decision" | ||||||
|  |   /admin/appointments/report/{appointmentId}: | ||||||
|  |     $ref: "./adminApi.yaml#/paths/~1admin~1appointments~1report~1{appointmentId}" | ||||||
|  |   /admin/appointments/upcoming: | ||||||
|  |     $ref: "./adminApi.yaml#/paths/~1admin~1appointments~1upcoming" | ||||||
|  |   /admin/projects/{projectId}: | ||||||
|  |     $ref: "./adminApi.yaml#/paths/~1admin~1projects~1{projectId}"  | ||||||
|  |   /admin/make-admin/{userId}: | ||||||
|  |     $ref: "./adminApi.yaml#/paths/~1admin~1make-admin~1{userId}" | ||||||
|  |   /admin/create-account: | ||||||
|  |     $ref: "./adminApi.yaml#/paths/~1admin~1create-account" | ||||||
|  |  | ||||||
|  |   #       ____  _                        _      _    ____ ___ | ||||||
|  |   #      / ___|| |__   __ _ _ __ ___  __| |    / \  |  _ \_ _| | ||||||
|  |   #      \___ \| '_ \ / _` | '__/ _ \/ _` |   / _ \ | |_) | | | ||||||
|  |   #       ___) | | | | (_| | | |  __/ (_| |  / ___ \|  __/| | | ||||||
|  |   #      |____/|_| |_|\__,_|_|  \___|\__,_| /_/   \_\_|  |___| | ||||||
|  |   # | ||||||
|  |   /shared/projects/sectionCells/{projectId}/{sectionId}/{date}: | ||||||
|  |     $ref: "./sharedApi.yaml#/paths/~1shared~1projects~1sectionCells~1{projectId}~1{sectionId}~1{date}" | ||||||
|  |   /shared/projects/entrepreneurs/{projectId}: | ||||||
|  |     $ref: "./sharedApi.yaml#/paths/~1shared~1projects~1entrepreneurs~1{projectId}" | ||||||
|  |   /shared/projects/admin/{projectId}: | ||||||
|  |     $ref: "./sharedApi.yaml#/paths/~1shared~1projects~1admin~1{projectId}" | ||||||
|  |   /shared/projects/appointments/{projectId}: | ||||||
|  |     $ref: "./sharedApi.yaml#/paths/~1shared~1projects~1appointments~1{projectId}" | ||||||
|  |   /shared/appointments/report/{appointmentId}: | ||||||
|  |     $ref: "./sharedApi.yaml#/paths/~1shared~1appointments~1report~1{appointmentId}" | ||||||
|  |   /shared/appointments/request: | ||||||
|  |     $ref: "./sharedApi.yaml#/paths/~1shared~1appointments~1request" | ||||||
|  |  | ||||||
|  |   #      _____ _   _ _____ ____  _____ ____  ____  _____ _   _ _____ _   _ ____ | ||||||
|  |   #     | ____| \ | |_   _|  _ \| ____|  _ \|  _ \| ____| \ | | ____| | | |  _ \ | ||||||
|  |   #     |  _| |  \| | | | | |_) |  _| | |_) | |_) |  _| |  \| |  _| | | | | |_) | | ||||||
|  |   #     | |___| |\  | | | |  _ <| |___|  __/|  _ <| |___| |\  | |___| |_| |  _ < | ||||||
|  |   #     |_____|_|_\_| |_| |_| \_\_____|_|   |_| \_\_____|_| \_|_____|\___/|_| \_\ | ||||||
|  |   #        / \  |  _ \_ _| | ||||||
|  |   #       / _ \ | |_) | | | ||||||
|  |   #      / ___ \|  __/| | | ||||||
|  |   #     /_/   \_\_|  |___| | ||||||
|  |   # | ||||||
|  |  | ||||||
|  |   /entrepreneur/projects: | ||||||
|  |     $ref: "./entrepreneurApi.yaml#/paths/~1entrepreneur~1projects" | ||||||
|  |   /entrepreneur/projects/request: | ||||||
|  |     $ref: "./entrepreneurApi.yaml#/paths/~1entrepreneur~1projects~1request" | ||||||
|  |   /entrepreneur/sectionCells: | ||||||
|  |     $ref: "./entrepreneurApi.yaml#/paths/~1entrepreneur~1sectionCells" | ||||||
|  |   /entrepreneur/sectionCells/{sectionCellId}: | ||||||
|  |     $ref: "./entrepreneurApi.yaml#/paths/~1entrepreneur~1sectionCells~1{sectionCellId}" | ||||||
|  |   /entrepreneur/projects/project-is-active: | ||||||
|  |     $ref: "./entrepreneurApi.yaml#/paths/~1entrepreneur~1projects~1project-is-active" | ||||||
|  |   /entrepreneur/projects/has-pending-request: | ||||||
|  |     $ref: "./entrepreneurApi.yaml#/paths/~1entrepreneur~1projects~1has-pending-request" | ||||||
							
								
								
									
										210
									
								
								documentation/openapi/src/models.yaml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										210
									
								
								documentation/openapi/src/models.yaml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,210 @@ | |||||||
|  | # models.yaml | ||||||
|  | user: | ||||||
|  |   type: object | ||||||
|  |   properties: | ||||||
|  |     idUser: | ||||||
|  |       type: integer | ||||||
|  |       description: Unique identifier for the user. | ||||||
|  |       #readOnly: true # Typically generated by the server | ||||||
|  |       example: 101 | ||||||
|  |     userSurname: | ||||||
|  |       type: string | ||||||
|  |       description: User's surname (last name). | ||||||
|  |       example: "Doe" | ||||||
|  |     userName: | ||||||
|  |       type: string | ||||||
|  |       description: User's given name (first name). | ||||||
|  |       example: "John" | ||||||
|  |     primaryMail: | ||||||
|  |       type: string | ||||||
|  |       format: email | ||||||
|  |       description: User's primary email address. | ||||||
|  |       example: "john.doe@example.com" | ||||||
|  |     secondaryMail: | ||||||
|  |       type: string | ||||||
|  |       format: email | ||||||
|  |       description: User's secondary email address (optional). | ||||||
|  |       example: "j.doe@personal.com" | ||||||
|  |     phoneNumber: | ||||||
|  |       type: string | ||||||
|  |       description: User's phone number. | ||||||
|  |       example: "+33612345678" # Example using international format | ||||||
|  |  | ||||||
|  | user-entrepreneur: | ||||||
|  |   allOf: | ||||||
|  |     - $ref: "#/user" | ||||||
|  |     - type: object | ||||||
|  |       properties: | ||||||
|  |         school: | ||||||
|  |           type: string | ||||||
|  |           description: The school the entrepreneur attends/attended. | ||||||
|  |           example: "ENSEIRB-MATMECA" | ||||||
|  |         course: | ||||||
|  |           type: string | ||||||
|  |           description: The specific course or program of study. | ||||||
|  |           example: "Electronics" | ||||||
|  |         sneeStatus: | ||||||
|  |           type: boolean | ||||||
|  |           description: Indicates if the user has SNEE status (Statut National d'Étudiant-Entrepreneur). | ||||||
|  |           example: true | ||||||
|  |   example: # Added full object example | ||||||
|  |     idUser: 101 | ||||||
|  |     userSurname: "Doe" | ||||||
|  |     userName: "John" | ||||||
|  |     primaryMail: "john.doe@example.com" | ||||||
|  |     secondaryMail: "j.doe@personal.com" | ||||||
|  |     phoneNumber: "+33612345678" | ||||||
|  |     school: "ENSEIRB-MATMECA" | ||||||
|  |     course: "Electronics" | ||||||
|  |     sneeStatus: true | ||||||
|  |  | ||||||
|  | user-admin: | ||||||
|  |   allOf: | ||||||
|  |     - $ref: "#/user" | ||||||
|  |   # No additional properties needed for this example | ||||||
|  |   example: # Added full object example | ||||||
|  |     idUser: 55 | ||||||
|  |     userSurname: "Admin" | ||||||
|  |     userName: "Super" | ||||||
|  |     primaryMail: "admin@myinpulse.com" | ||||||
|  |     phoneNumber: "+33512345678" | ||||||
|  |  | ||||||
|  | sectionCell: | ||||||
|  |   type: object | ||||||
|  |   description: Represents a cell (like a sticky note) within a specific section of a project's Lean Canvas. | ||||||
|  |   properties: | ||||||
|  |     idSectionCell: | ||||||
|  |       type: integer | ||||||
|  |       description: Unique identifier for the section cell. | ||||||
|  |       #readOnly: true # Generated by server | ||||||
|  |       example: 508 | ||||||
|  |     sectionId: | ||||||
|  |       type: integer | ||||||
|  |       description: Identifier of the Lean Canvas section this cell belongs to (e.g., 1 for Problem, 2 for Solution). | ||||||
|  |       example: 1 | ||||||
|  |     contentSectionCell: | ||||||
|  |       type: string | ||||||
|  |       description: The text content of the section cell. | ||||||
|  |       example: "Users find it hard to track project progress." | ||||||
|  |     modificationDate: | ||||||
|  |       type: string | ||||||
|  |       format: date # Using Java LocalDate -> YYYY-MM-DD | ||||||
|  |       description: The date when this cell was last modified. | ||||||
|  |       #readOnly: true # Typically updated by the server on modification | ||||||
|  |       example: "yyyy-MM-dd HH:mm" | ||||||
|  |  | ||||||
|  | project: | ||||||
|  |   type: object | ||||||
|  |   description: Represents a project being managed or developed. | ||||||
|  |   properties: | ||||||
|  |     idProject: | ||||||
|  |       type: integer | ||||||
|  |       description: Unique identifier for the project. | ||||||
|  |       #readOnly: true # Generated by server | ||||||
|  |       example: 12 | ||||||
|  |     projectName: | ||||||
|  |       type: string | ||||||
|  |       description: The name of the project. | ||||||
|  |       example: "MyInpulse Mobile App" | ||||||
|  |     creationDate: | ||||||
|  |       type: string | ||||||
|  |       format: date # Using Java LocalDate -> YYYY-MM-DD | ||||||
|  |       description: The date when the project was created in the system. | ||||||
|  |       #readOnly: true # Set by server | ||||||
|  |       example: "yyyy-MM-dd HH:mm" | ||||||
|  |     logo: | ||||||
|  |       type: string | ||||||
|  |       format: byte | ||||||
|  |       description: Base64 encoded string representing the project logo image. | ||||||
|  |       example: "/*Base64 encoded string representing the project logo image*/" | ||||||
|  |     status: | ||||||
|  |       type: string | ||||||
|  |       enum: [PENDING, ACTIVE, ENDED, ABORTED, REJECTED] | ||||||
|  |       description: Corresponds to a status enum internal to the backend, it's value in in requests | ||||||
|  |         incoming to the server should be ignored as the client shouldn't be specifying them. | ||||||
|  |       example: "NaN" | ||||||
|  |  | ||||||
|  | joinRequest: | ||||||
|  |   type: object | ||||||
|  |   description: Represents a request from an entrepreneur to join an already existing project. | ||||||
|  |   properties: | ||||||
|  |     idProject: | ||||||
|  |       type: integer | ||||||
|  |       description: the ID of the project the entrepreneur wants to join. | ||||||
|  |       example: 42 | ||||||
|  |     entrepreneur: | ||||||
|  |       $ref: "#/user-entrepreneur" | ||||||
|  |        | ||||||
|  |  | ||||||
|  | report: | ||||||
|  |   type: object | ||||||
|  |   description: Represents a report associated with an appointment. | ||||||
|  |   properties: | ||||||
|  |     idReport: | ||||||
|  |       type: integer | ||||||
|  |       description: Unique identifier for the report. | ||||||
|  |       #readOnly: true # Generated by server | ||||||
|  |       example: 987 | ||||||
|  |     reportContent: | ||||||
|  |       type: string | ||||||
|  |       description: The textual content of the report. Could be plain text or Markdown (specify if known). | ||||||
|  |       example: "Discussed roadmap milestones for Q3. Agreed on preliminary UI mockups." | ||||||
|  |  | ||||||
|  | appointment: # Corrected typo | ||||||
|  |   type: object | ||||||
|  |   description: Represents a scheduled meeting or appointment. | ||||||
|  |   properties: | ||||||
|  |     idAppointment: # Assuming there's an ID | ||||||
|  |         type: integer | ||||||
|  |         description: Unique identifier for the appointment. | ||||||
|  |         #readOnly: true | ||||||
|  |         example: 303 | ||||||
|  |     appointmentDate: | ||||||
|  |       type: string | ||||||
|  |       format: date # Using Java LocalDate -> YYYY-MM-DD | ||||||
|  |       description: The date of the appointment. | ||||||
|  |       example: "2025-05-10" | ||||||
|  |     appointmentTime: | ||||||
|  |       type: string | ||||||
|  |       format: time # Using Java LocalTime -> HH:mm:ss | ||||||
|  |       description: The time of the appointment (local time). | ||||||
|  |       example: "14:30:00" | ||||||
|  |     appointmentDuration: | ||||||
|  |       type: string | ||||||
|  |       description: Duration of the appointment in ISO 8601 duration format (e.g., PT1H30M for 1 hour 30 minutes). | ||||||
|  |       example: "PT1H" # Example for 1 hour | ||||||
|  |     appointmentPlace: | ||||||
|  |       type: string | ||||||
|  |       description: Location or meeting link for the appointment. | ||||||
|  |       example: "Meeting Room 3 / https://meet.example.com/abc-def-ghi" | ||||||
|  |     appointmentSubject: | ||||||
|  |       type: string | ||||||
|  |       description: The main topic or subject of the appointment. | ||||||
|  |       example: "Q3 Roadmap Planning" | ||||||
|  |     # Consider adding project ID or user IDs if relevant association exists | ||||||
|  |  | ||||||
|  | projectDecision: | ||||||
|  |   type: object | ||||||
|  |   description: Represents a decision from an admin to accept a pending project. | ||||||
|  |   properties: | ||||||
|  |     projectId: | ||||||
|  |       type: integer | ||||||
|  |       description: The ID of the project the entrepreneur wants to join. | ||||||
|  |       example: 12 | ||||||
|  |     adminId:  | ||||||
|  |       type: integer | ||||||
|  |       description: The ID of the project the admin who will supervise the project in case of admission. | ||||||
|  |       example: 2 | ||||||
|  |     isAccepted: | ||||||
|  |       type: boolean | ||||||
|  |       description: The boolean value of the decision. | ||||||
|  |       example: "true" | ||||||
|  |  | ||||||
|  | joinRequestDecision: | ||||||
|  |   type: object | ||||||
|  |   description: Represents a decision from an admin to accept a pending project join request. | ||||||
|  |   properties: | ||||||
|  |     isAccepted: | ||||||
|  |       type: boolean | ||||||
|  |       description: The boolean value of the decision. | ||||||
|  |       example: "true" | ||||||
							
								
								
									
										193
									
								
								documentation/openapi/src/sharedApi.yaml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										193
									
								
								documentation/openapi/src/sharedApi.yaml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,193 @@ | |||||||
|  | # Shared API Endpoints | ||||||
|  | paths:     | ||||||
|  |  | ||||||
|  |   /shared/projects/sectionCells/{projectId}/{sectionId}/{date}:  | ||||||
|  |     get: | ||||||
|  |       operationId: getSectionCellsByDate | ||||||
|  |       summary: Get project section cells modified on a specific date | ||||||
|  |       tags: | ||||||
|  |         - Shared API | ||||||
|  |       security: | ||||||
|  |         - MyINPulse: [MyINPulse-entrepreneur, MyINPulse-admin] | ||||||
|  |       description: Retrieves section cells belonging to a specific section of a project, filtered by the last modification date. Requires user to have access to the project. | ||||||
|  |       parameters: | ||||||
|  |         - in: path | ||||||
|  |           name: projectId | ||||||
|  |           required: true | ||||||
|  |           schema: { type: integer } | ||||||
|  |           description: ID of the project. | ||||||
|  |         - in: path | ||||||
|  |           name: sectionId | ||||||
|  |           required: true | ||||||
|  |           schema: { type: integer } | ||||||
|  |           description: ID of the Lean Canvas section. | ||||||
|  |         - in: path | ||||||
|  |           name: date | ||||||
|  |           required: true | ||||||
|  |           schema: { type: string, format: date } # Expect YYYY-MM-DD | ||||||
|  |           description: The modification date to filter by (YYYY-MM-DD HH:mm). | ||||||
|  |       responses: | ||||||
|  |         "200": | ||||||
|  |           description: OK - List of section cells matching the criteria. | ||||||
|  |           content: | ||||||
|  |             application/json: | ||||||
|  |               schema: | ||||||
|  |                 type: array | ||||||
|  |                 items: | ||||||
|  |                   $ref: "./main.yaml#/components/schemas/sectionCell" | ||||||
|  |         "400": | ||||||
|  |           description: Bad Request - Invalid parameter format. | ||||||
|  |         "403": | ||||||
|  |           description: Bad Token - Invalid Keycloack configuration. | ||||||
|  |         "401": | ||||||
|  |           description: Unauthorized. | ||||||
|  |            | ||||||
|  |  | ||||||
|  |   /shared/projects/entrepreneurs/{projectId}: | ||||||
|  |     get: | ||||||
|  |       operationId: getProjectEntrepreneurs | ||||||
|  |       summary: Get entrepreneurs associated with a project | ||||||
|  |       tags: | ||||||
|  |         - Shared API | ||||||
|  |       security: | ||||||
|  |         - MyINPulse: [MyINPulse-entrepreneur, MyINPulse-admin] | ||||||
|  |       description: Retrieves a list of entrepreneur users associated with the specified project. Requires access to the project. | ||||||
|  |       parameters: | ||||||
|  |         - in: path | ||||||
|  |           name: projectId | ||||||
|  |           required: true | ||||||
|  |           schema: { type: integer } | ||||||
|  |           description: ID of the project. | ||||||
|  |       responses: | ||||||
|  |         "200": | ||||||
|  |           description: OK - List of entrepreneurs. | ||||||
|  |           content: | ||||||
|  |             application/json: | ||||||
|  |               schema: | ||||||
|  |                 type: array | ||||||
|  |                 items: | ||||||
|  |                   $ref: "./main.yaml#/components/schemas/user-entrepreneur" | ||||||
|  |         "401": | ||||||
|  |           description: Unauthorized.        | ||||||
|  |         "403": | ||||||
|  |           description: Bad Token - Invalid Keycloack configuration.          | ||||||
|  |         "404": | ||||||
|  |           description: Not Found - Project not found.        | ||||||
|  |  | ||||||
|  |   /shared/projects/admin/{projectId}: # Path updated | ||||||
|  |     get: | ||||||
|  |       operationId: getProjectAdmin | ||||||
|  |       summary: Get admin associated with a project | ||||||
|  |       tags: | ||||||
|  |         - Shared API | ||||||
|  |       security: | ||||||
|  |         - MyINPulse: [MyINPulse-entrepreneur, MyINPulse-admin] | ||||||
|  |       description: Retrieves a list of admin users associated with the specified project. Requires access to the project. | ||||||
|  |       parameters: | ||||||
|  |         - in: path | ||||||
|  |           name: projectId | ||||||
|  |           required: true | ||||||
|  |           schema: { type: integer } | ||||||
|  |           description: ID of the project. | ||||||
|  |       responses: | ||||||
|  |         "200": | ||||||
|  |           description: OK - admin. | ||||||
|  |           content: | ||||||
|  |             application/json: | ||||||
|  |               schema: | ||||||
|  |                 $ref: "./main.yaml#/components/schemas/user-admin" | ||||||
|  |         "401": | ||||||
|  |           description: Unauthorized.        | ||||||
|  |         "403": | ||||||
|  |           description: Bad Token - Invalid Keycloack configuration.     | ||||||
|  |         "404": | ||||||
|  |           description: Not Found - Project not found. | ||||||
|  |            | ||||||
|  |  | ||||||
|  |   /shared/projects/appointments/{projectId}: | ||||||
|  |     get: | ||||||
|  |       operationId: getProjectAppointments | ||||||
|  |       summary: Get appointments related to a project | ||||||
|  |       tags: | ||||||
|  |         - Shared API | ||||||
|  |       security: | ||||||
|  |         - MyINPulse: [MyINPulse-entrepreneur, MyINPulse-admin] | ||||||
|  |       description: Retrieves a list of appointments associated with the specified project. Requires access to the project. | ||||||
|  |       parameters: | ||||||
|  |         - in: path | ||||||
|  |           name: projectId | ||||||
|  |           required: true | ||||||
|  |           schema: { type: integer } | ||||||
|  |           description: ID of the project. | ||||||
|  |       responses: | ||||||
|  |         "200": | ||||||
|  |           description: OK - List of appointments. | ||||||
|  |           content: | ||||||
|  |             application/json: | ||||||
|  |               schema: | ||||||
|  |                 type: array | ||||||
|  |                 items: | ||||||
|  |                   $ref: "./main.yaml#/components/schemas/appointment" | ||||||
|  |         "403": | ||||||
|  |           description: Bad Token - Invalid Keycloack configuration. | ||||||
|  |         "401": | ||||||
|  |           description: Unauthorized. | ||||||
|  |            | ||||||
|  |  | ||||||
|  |   /shared/appointments/report/{appointmentId}: # Path updated | ||||||
|  |     get: | ||||||
|  |       operationId: getAppointmentReport # Shared endpoint implies read-only access might be possible | ||||||
|  |       summary: Get the report for an appointment | ||||||
|  |       tags: | ||||||
|  |         - Shared API | ||||||
|  |       security: | ||||||
|  |         - MyINPulse: [MyINPulse-entrepreneur, MyINPulse-admin] | ||||||
|  |       description: Retrieves the report associated with a specific appointment. Requires user to have access to the appointment/project. | ||||||
|  |       parameters: | ||||||
|  |         - in: path | ||||||
|  |           name: appointmentId | ||||||
|  |           required: true | ||||||
|  |           schema: { type: integer } | ||||||
|  |           description: ID of the appointment. | ||||||
|  |       responses: | ||||||
|  |         "200": | ||||||
|  |           description: OK - Report PDF returned. | ||||||
|  |           content: | ||||||
|  |             application/pdf: | ||||||
|  |               schema: | ||||||
|  |                 schema: | ||||||
|  |                 type: string | ||||||
|  |                 format: binary | ||||||
|  |         "401": | ||||||
|  |           description: Unauthorized. | ||||||
|  |         "403": | ||||||
|  |           description: Bad Token - Invalid Keycloack configuration. | ||||||
|  |            | ||||||
|  |  | ||||||
|  |   /shared/appointments/request: | ||||||
|  |     post: | ||||||
|  |       operationId: requestAppointment | ||||||
|  |       summary: Request a new appointment | ||||||
|  |       tags: | ||||||
|  |         - Shared API | ||||||
|  |       security: | ||||||
|  |         - MyINPulse: [MyINPulse-entrepreneur, MyINPulse-admin] | ||||||
|  |       description: Allows a user (entrepreneur or admin) to request a new appointment, potentially with another user or regarding a project. Details in the body. The request might need confirmation or create a pending appointment. | ||||||
|  |       requestBody: | ||||||
|  |         required: true | ||||||
|  |         description: Details of the appointment request. | ||||||
|  |         content: | ||||||
|  |           application/json: | ||||||
|  |             schema: | ||||||
|  |               $ref: "./main.yaml#/components/schemas/appointment" # Assuming request uses same model structure | ||||||
|  |                 # Potentially add projectId or targetUserId here | ||||||
|  |       responses: | ||||||
|  |         "200": # Accepted seems appropriate for a request | ||||||
|  |           description: Accepted - Appointment request submitted. | ||||||
|  |         "400": | ||||||
|  |           description: Bad Request - Invalid appointment details. | ||||||
|  |         "401": | ||||||
|  |           description: Unauthorized. | ||||||
|  |         "403": | ||||||
|  |           description: Bad Token - Invalid Keycloack configuration. | ||||||
|  |            | ||||||
							
								
								
									
										90
									
								
								documentation/openapi/src/unauthApi.yaml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										90
									
								
								documentation/openapi/src/unauthApi.yaml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,90 @@ | |||||||
|  |  | ||||||
|  | #       _   _                   _   _        _          _  | ||||||
|  | #      | | | |_ __   __ _ _   _| |_| |__    / \   _ __ (_) | ||||||
|  | #      | | | | '_ \ / _` | | | | __| '_ \  / _ \ | '_ \| | | ||||||
|  | #      | |_| | | | | (_| | |_| | |_| | | |/ ___ \| |_) | | | ||||||
|  | #       \___/|_| |_|\__,_|\__,_|\__|_| |_/_/   \_\ .__/|_| | ||||||
|  | #                                                |_|       | ||||||
|  |  | ||||||
|  | paths: | ||||||
|  |   /unauth/finalize: | ||||||
|  |     post: | ||||||
|  |       summary: Finalize account setup using authentication token | ||||||
|  |       description: |- | ||||||
|  |         Completes the user account creation/setup process in the MyInpulse system. | ||||||
|  |         This endpoint requires the user to be authenticated via Keycloak (e.g., after initial login). | ||||||
|  |         User details (name, email, etc.) are extracted from the authenticated user's token (e.g., Keycloak JWT). | ||||||
|  |         No request body is needed. The account is marked as pending admin validation upon successful finalization. | ||||||
|  |       tags: | ||||||
|  |         - Unauth API | ||||||
|  |       responses: | ||||||
|  |         "200": | ||||||
|  |           description: Created - Account finalized and pending admin validation. Returns the user profile. | ||||||
|  |         "400": | ||||||
|  |           description: Bad Request - Problem processing the token or user data derived from it. | ||||||
|  |         "401": | ||||||
|  |           description: Unauthorized - Valid authentication token required. | ||||||
|  |         "403": | ||||||
|  |           description: Bad Token - Invalid Keycloack configuration. | ||||||
|  |   /unauth/request-join/{projectId}: | ||||||
|  |     post: | ||||||
|  |       summary: Request to join an existing project | ||||||
|  |       description: Submits a request for the authenticated user (keycloack authenticated) to join the project specified by projectId. Their role is then changed to entrepreneur in server and Keycloak. This requires approval from a project admin. | ||||||
|  |       tags: | ||||||
|  |        - Unauth API | ||||||
|  |       parameters: | ||||||
|  |         - in: path | ||||||
|  |           name: projectId | ||||||
|  |           required: true | ||||||
|  |           schema: | ||||||
|  |             type: integer | ||||||
|  |           description: The ID of the project to request joining. | ||||||
|  |           example: 15 | ||||||
|  |       responses: # Moved responses block to correct level | ||||||
|  |         "200": | ||||||
|  |           description: Accepted - Join request submitted and pending approval. | ||||||
|  |         "400": | ||||||
|  |           description: Bad Request - Invalid project ID format  | ||||||
|  |         "409": | ||||||
|  |           description: Already member/request pending. | ||||||
|  |         "401": | ||||||
|  |           description: Unauthorized. | ||||||
|  |         "403": | ||||||
|  |           description: Bad Token - Invalid Keycloack configuration. | ||||||
|  |   /unauth/request-admin-role: | ||||||
|  |     post: | ||||||
|  |       summary: Request to become an admin | ||||||
|  |       description: Submits a request for the authenticated user (keycloack authenticated) to become an admin. Their role is then changed to admin in server and Keycloak. This requires approval from a project admin. | ||||||
|  |       tags: | ||||||
|  |        - Unauth API | ||||||
|  |       responses: | ||||||
|  |         "200": | ||||||
|  |           description: Accepted - Become admin request submitted and pending approval. | ||||||
|  |         "400": | ||||||
|  |           description: Bad Request - Invalid project ID format or already member/request pending. | ||||||
|  |         "401": | ||||||
|  |           description: Unauthorized. | ||||||
|  |         "403": | ||||||
|  |           description: Bad Token - Invalid Keycloack configuration. | ||||||
|  |  | ||||||
|  |   /unauth/check-if-not-pending: | ||||||
|  |     get: | ||||||
|  |       summary: Returns a boolean of whether the user's account is not pending | ||||||
|  |       description: Returns a boolean with value `true` if the user's account is not pending and `false` if it is. | ||||||
|  |       tags: | ||||||
|  |        - Unauth API | ||||||
|  |       responses: | ||||||
|  |         "200": | ||||||
|  |           description: Accepted - Become admin request submitted and pending approval. | ||||||
|  |           content: | ||||||
|  |             application/json: | ||||||
|  |               schema: | ||||||
|  |                 type: boolean   | ||||||
|  |         "400": | ||||||
|  |           description: Bad Request - Invalid project ID format or already member/request pending. | ||||||
|  |         "401": | ||||||
|  |           description: Unauthorized. | ||||||
|  |         "404": | ||||||
|  |           description: Bad Request - User not found in database. | ||||||
|  |         "403": | ||||||
|  |           description: Bad Token - Invalid Keycloack configuration. | ||||||
							
								
								
									
										14
									
								
								documentation/openapi/swagger-ui/main.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								documentation/openapi/swagger-ui/main.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,14 @@ | |||||||
|  | const express = require("express"); | ||||||
|  | const swaggerUi = require("swagger-ui-express"); | ||||||
|  | const yaml = require("js-yaml"); | ||||||
|  | const fs = require("fs"); | ||||||
|  |  | ||||||
|  | const app = express(); | ||||||
|  |  | ||||||
|  | const swaggerDocument = yaml.load(fs.readFileSync("../src/bundled.yaml", "utf8")); | ||||||
|  |  | ||||||
|  | app.use("/api-docs", swaggerUi.serve, swaggerUi.setup(swaggerDocument)); | ||||||
|  |  | ||||||
|  | app.listen(3000, () => { | ||||||
|  |     console.log("Swagger UI running at http://localhost:3000/api-docs"); | ||||||
|  | }); | ||||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user