1
0
forked from PGL/Clyde

Compare commits

..

70 Commits

Author SHA1 Message Date
bc87748b31 Merge master part1 2024-04-21 00:10:33 +02:00
c15ddccbb0 Merge pull request 'Leo/InscriptionDesEtudiants' (#163) from Leo/InscriptionDesEtudiants into master
Reviewed-on: PGL/Clyde#163
2024-04-19 20:44:55 +02:00
211bf77322 Merge pull request 'master' (#162) from master into Leo/InscriptionDesEtudiants
Reviewed-on: PGL/Clyde#162
2024-04-19 20:40:58 +02:00
4e14370d4f Add the exemptions gestion and improve the navigation between requests 2024-04-19 19:25:28 +02:00
10c1c6096d
const error fix
This error seems to be there for quite some times. for some reason I
haven't seen it at all. I tried to bisect it and couldn't find the
origin so I just fix it in this commit
2024-04-19 18:04:21 +02:00
69fb4e881e Add the Teacher approval for reregister requests 2024-04-19 15:53:31 +02:00
25575fa4e0 Implements some files uploading in the inscription form and change inscriptionRequest and Curriculum for the cursus acceptance attestation feature 2024-04-19 12:26:48 +02:00
5a57fc78f3 Generalize the ExternalCurriculumList interface so it fits for inscriptionRequest, Studentlist, and inscriptionform 2024-04-19 09:31:55 +02:00
70a8e98a0e Merge pull request 'Leo/InscriptionDesEtudiant' (#161) from Leo/InscriptionDesEtudiant into master
Reviewed-on: PGL/Clyde#161
2024-04-18 21:43:47 +02:00
a9e52d34d4 Start the rework of externalCurriculum interface 2024-04-18 21:35:50 +02:00
8a5a26e2ab Add the management of changeCurriculum requests 2024-04-18 14:09:06 +02:00
c9556e1eea Merge remote-tracking branch 'origin/master' into Leo/InscriptionDesEtudiant
# Conflicts:
#	backend/src/main/java/ovh/herisson/Clyde/EndPoints/MockController.java
#	backend/src/main/java/ovh/herisson/Clyde/Services/Inscription/InscriptionService.java
#	backend/src/main/java/ovh/herisson/Clyde/Tables/User.java
2024-04-18 10:46:45 +02:00
78507f798f Merge remote-tracking branch 'origin/master' into Leo/InscriptionDesEtudiant 2024-04-18 10:36:09 +02:00
f9b12a5061 Merge pull request 'Implements the RegNo feature' (#158) from Leo/masterRegNo into master
Reviewed-on: PGL/Clyde#158
Reviewed-by: Maxime <231026@umons.ac.be>
Reviewed-by: Debucquoy Anthony <d.tonitch@gmail.com>
2024-04-18 10:32:24 +02:00
8724748642 Merge branch 'master' into Leo/masterRegNo 2024-04-18 10:30:01 +02:00
f19236b3f7 Avoid password leakage
The password should never be parsed to json ever so can be safely
ignored.
2024-04-17 21:44:30 +02:00
cba11d54ff Page to right size (#152)
Reviewed-on: PGL/Clyde#152
Reviewed-by: Maxime <231026@umons.ac.be>
Co-authored-by: Anthony Debucquoy <debucquoy.anthony@gmail.com>
Co-committed-by: Anthony Debucquoy <debucquoy.anthony@gmail.com>
2024-04-17 21:43:49 +02:00
a27cf63daf Add the post feature for differents types of changeCurriculumRequest 2024-04-17 21:42:33 +02:00
1be7b4cdbe Add the unregistration of a specific cursus only 2024-04-17 13:57:52 +02:00
058c53dbbc Add the actual in UserCurriculum
Rework the unregister procedure
Add ChangeCurriculumRequest
Add the changeCurriculumRequest submit
2024-04-17 11:55:56 +02:00
caa39696d2 Rework the profile page
Add the accept/refuse for unreg request
2024-04-17 08:53:28 +02:00
b9d7950e12 Merge branch 'master' into Leo/masterRegNo 2024-04-17 07:52:58 +02:00
c0233fce57 Merge pull request 'adding compose for launching properly everything' (#151) from tonitch/compose into master
Reviewed-on: PGL/Clyde#151
Reviewed-by: LeoMoulin <leomoulin125@gmail.com>
Reviewed-by: Wal <karpinskiwal@gmail.com>
Reviewed-by: Maxime <231026@umons.ac.be>
2024-04-17 00:26:11 +02:00
451944e4fb Implements the RegNo feature 2024-04-15 20:57:29 +02:00
c434b28fe3 Add the display for unregister requests
Rename all ocurrences of uninscription
to unregister
Rework the uninscriptionRequest so we have an history and it doesn't take an user so better security
2024-04-15 20:13:01 +02:00
a89d1b192c Add the gestion of scholarshipRequest (accept and refuse and select the amount) 2024-04-15 16:17:27 +02:00
61eac8959a Merge pull request 'Leo/InscriptionDesEtudiants' (#156) from Leo/InscriptionDesEtudiants into master
Reviewed-on: PGL/Clyde#156
2024-04-14 19:49:15 +02:00
05bff0fa77 Add the uninscription request submission 2024-04-14 18:29:23 +02:00
98c9d2d754 Link the ExternalCurriculum to a user after the inscription.
Add the ExternalCurriculum lists in AboutStudent.vue
2024-04-12 09:28:56 +02:00
8ebedec689 Fix fews things and rename the inscription app to managerequests also sort the files 2024-04-11 21:06:57 +02:00
4199663d64 Huge commit
- Rework the inscription requests system so that it considers the equivalence systems and the impact of the teacher in the inscription procedure.
2024-04-11 16:45:48 +02:00
34c0a2bfe8 Merge remote-tracking branch 'origin/master' into Leo/InscriptionDesEtudiants
# Conflicts:
#	frontend/src/rest/apps.js
2024-04-10 23:28:00 +02:00
706481ed1a Fix and simplifie the post and get for externalCurriculum 2024-04-10 23:09:38 +02:00
0c04bed799 this is a test dw 2024-04-10 22:00:08 +02:00
9d0b3da9d3 Implements the backend and frontend methods to get some scholarshipRequests and exemptionsRequest
Extends the inscription.vue so that it also list scholarship and exemptions requests (not only inscription) this vue should be renamed later. Also implements some filters and parameters to select the data displayed in the list.
2024-04-10 14:40:41 +02:00
76c3b76153 Merge pull request 'Messaging system' (#150) from tonitch/Clyde:msg into master
Reviewed-on: PGL/Clyde#150
2024-04-09 17:08:57 +02:00
21a5dbdb22 Implements the possibility to ask for a scholarship for a student 2024-04-09 15:58:10 +02:00
e6e147af26 Implements the school fees gestion for a student and a payment table containing a history of all the financial transactions of the system 2024-04-08 14:50:37 +02:00
194b14f02b Implements the backend logic for the minerval gestion 2024-04-08 10:18:28 +02:00
3c721de18b Big commit:
make some changes to profile to provide an interface for a student to manage his courses.

implements the submission of exemptions request
2024-04-06 16:12:11 +02:00
5bb7606721
signing and commenting 2024-04-05 12:54:51 +02:00
b049c46571
Avoid title reseting mid modification 2024-04-05 11:45:47 +02:00
648b73b585 Fix the implementation of externalCurriculum upload 2024-04-04 16:54:11 +02:00
7ca5c34afe
adding timestamp 2024-04-02 11:08:58 +02:00
2b9bdf8dac
fixup! show sender on message 2024-04-02 10:18:50 +02:00
ccb954e348
show sender on message 2024-04-02 10:05:17 +02:00
3761fa6f49
Adding cdn support with compose
Now when you upload a file, the path is stored to the db and the file is
accesible on the client with : `localhost:8000/cdn/3ed026aa-366f-4f33-bc51-fb59d37e35ee.png` for instance.
2024-04-02 00:21:15 +02:00
cb36aa8a30
Fixing file locations 2024-04-01 22:49:24 +02:00
8442101c40 Fixed some css 2024-04-01 11:43:42 +02:00
bce53305b3 Merge master into my branch 2024-04-01 10:40:36 +02:00
47e4fb2f8c Merge remote-tracking branch 'origin/master' into Leo/InscriptionDesEtudiants
# Conflicts:
#	frontend/src/Apps/Inscription.vue
#	frontend/src/Apps/Login.vue
#	frontend/src/Apps/Profil.vue
#	frontend/src/Apps/StudentsList.vue
2024-04-01 10:30:29 +02:00
2e2837fec4 adding info about compose 2024-03-30 23:33:16 +01:00
0e26e1a0db adding compose for launching properly everything 2024-03-30 23:23:33 +01:00
4a314449ad Add the backend logic for ExternalCurriculum class (need to do one more endpoint) 2024-03-29 15:31:02 +01:00
ce56e37a33
redesign send bar 2024-03-29 14:31:22 +01:00
1c61a356a4
update when message sent 2024-03-29 14:31:08 +01:00
2bdffe6ab4
remove member of a discussion 2024-03-29 14:30:46 +01:00
a3c9d6a7c0 Fix the profilepicture url issue (it wasn't sent to the db)
add a prototype of a more generic uploadfile function in uploads.js

makes the distinction between a master cursus and a bachelor cursus in display
2024-03-29 10:55:59 +01:00
729d1ad504
adding members management 2024-03-27 23:54:59 +01:00
1522d74ed3
messsaging on the frontend 2024-03-27 19:52:48 +01:00
b4499e04c7
Managing the message with backend
Using DTO to change the way discussions and message are sent to the
client
2024-03-27 19:50:52 +01:00
94f12f0a86 Add the date and identitycard feature to inscriptionRequest 2024-03-27 16:04:55 +01:00
839ca414ce Ajoute le détail des demandes d'inscriptions (big update) 2024-03-27 14:12:20 +01:00
eafff6ec2d Ajoute le détail des étudiants (big update) 2024-03-25 09:57:35 +01:00
914f6bdf36
fix for new discussions not appearing right away 2024-03-25 09:43:45 +01:00
66e7fa24a1
Adding the discussion architectures and creating new discussions 2024-03-25 00:08:44 +01:00
7b9f021c24
first version of the frontend for messages 2024-03-24 22:33:17 +01:00
2dfa0a0ee0
base msg 2024-03-24 22:33:14 +01:00
67fa630ecf e 2024-03-23 18:04:36 +01:00
ad0e7b3e35 - Ajoute un champ year dans UserCurriculum pour différencier les anciers cursus de l'actuel pour l'étudiant
- Ajoute la table ExemptionsRequest
- Ajoute la table ScholarshipRequest
- Ajoute la table UninscriptionRequest
2024-03-23 14:08:03 +01:00
106 changed files with 4878 additions and 609 deletions

View File

@ -9,10 +9,33 @@ Projet du groupe 01:
- William Karpinski: Extension gestion des horaires - William Karpinski: Extension gestion des horaires
- Léo Moulin: Extension inscription des étudiants - Léo Moulin: Extension inscription des étudiants
## Running
Le projet peut être lancé grace à docker compose.
```sh
$ docker compose up
```
Dans le cas ou vous modifiers des fichiers, pour éviter que les images de docker soient recrées avec les changement
```sh
$ docker compose up --force-recreate --build
```
## Dévelopement ## Dévelopement
``` Dans le cas ou vous êtes dans une phase de développement, il est plus simple d'utiliser gradle pour lancer le backend et frontend dans un mode de développement.
$ ./gradlew backend:run frontend:run --parallel **Attention**: Ce mode n'est pas fait pour être utilisé en production!
```
```sh
$ ./gradlew run --parallel
```
permet de lancer le frontend sur [http://localhost:5173](http://localhost:5173) ansi que le frontend sur [http://localhost:8080](http://localhost:8080) permet de lancer le frontend sur [http://localhost:5173](http://localhost:5173) ansi que le frontend sur [http://localhost:8080](http://localhost:8080)
Ceci requière également docker pour lancer une instance de postgresql pris en charge par spring.
Il est possible de se passer entièrement de docker en supprimant la dépendance dans le fichier `backend/build.gradle.kts`: ~~`developmentOnly("org.springframework.boot:spring-boot-docker-compose")`~~
Il est alors nécéssaire d'avoir une instance de postgresql tournant sur `localhost:5432` avec une table `clyde`, utilisateur: `devel` et password: `devel`
(cette configuration peut également être changée dans le fichier resources/application.properties de spring)

View File

@ -1,6 +1,15 @@
## Building phase
FROM gradle:jdk21-alpine AS BUILD
WORKDIR /backend
COPY . .
RUN gradle build -x test
## Running Phase
FROM eclipse-temurin:21-jdk-alpine FROM eclipse-temurin:21-jdk-alpine
VOLUME /tmp WORKDIR /backend
VOLUME /cdn VOLUME /cdn
ENV SPRING_PROFILES_ACTIVE=prod # ENV SPRING_PROFILES_ACTIVE=prod
COPY build/libs/backend-0.0.1-SNAPSHOT.jar /app.jar COPY --from=BUILD /backend/build/libs/Clyde-0.0.1-SNAPSHOT.jar /backend/app.jar
ENTRYPOINT ["java", "-jar", "/app.jar"] EXPOSE 8080
ENTRYPOINT ["java", "-jar", "/backend/app.jar"]

View File

@ -16,6 +16,8 @@ repositories {
} }
dependencies { dependencies {
compileOnly("org.projectlombok:lombok")
annotationProcessor("org.projectlombok:lombok")
implementation("org.springframework.boot:spring-boot-starter-jdbc") implementation("org.springframework.boot:spring-boot-starter-jdbc")
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-mail") implementation("org.springframework.boot:spring-boot-starter-mail")

View File

@ -0,0 +1,13 @@
/*
* This file was generated by the Gradle 'init' task.
*
* The settings file is used to specify which projects to include in your build.
* For more detailed information on multi-project builds, please refer to https://docs.gradle.org/8.6/userguide/multi_project_builds.html in the Gradle documentation.
*/
plugins {
// Apply the foojay-resolver plugin to allow automatic download of JDKs
id("org.gradle.toolchains.foojay-resolver-convention") version "0.7.0"
}
rootProject.name = "Clyde"

View File

@ -0,0 +1,34 @@
package ovh.herisson.Clyde.DTO.Msg;
/******************************************************
* @file DiscussionDTO.java
* @author Anthony Debucquoy
* @scope Extension messagerie
*
* File to format a discussion using messageDTO
******************************************************/
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import lombok.AllArgsConstructor;
import lombok.Data;
import ovh.herisson.Clyde.Tables.User;
import ovh.herisson.Clyde.Tables.Msg.Discussion;
import ovh.herisson.Clyde.DTO.Msg.MessagesDTO;
@Data
@AllArgsConstructor
public class DiscussionDTO {
private long id;
private String name;
private List<User> members;
private List<MessagesDTO> msgs;
public static DiscussionDTO construct(Discussion d, User u){
List<MessagesDTO> msgsdto = new ArrayList<>();
d.getMsgs().forEach(x -> msgsdto.add(MessagesDTO.construct(x, u)));
return new DiscussionDTO(d.getId(), d.getName(), d.getMembers(), msgsdto);
}
}

View File

@ -0,0 +1,33 @@
package ovh.herisson.Clyde.DTO.Msg;
/******************************************************
* @file MessagesDTO.java
* @author Anthony Debucquoy
* @scope Extension messagerie
*
* File to Format the response adding the sender field
******************************************************/
import lombok.AllArgsConstructor;
import lombok.Data;
import ovh.herisson.Clyde.Tables.User;
import ovh.herisson.Clyde.Tables.Msg.Message;
import java.util.Date;
@Data
@AllArgsConstructor
public class MessagesDTO {
private long id;
private String content;
private User author;
private boolean sender;
private Date created;
//TODO: Attachment
public static MessagesDTO construct(Message m, User user){
boolean sender = false;
if(m.getAuthor().equals(user))
sender = true;
return new MessagesDTO(m.getId(), m.getContent(), m.getAuthor(), sender, m.getCreated());
}
}

View File

@ -67,14 +67,17 @@ public class ApplicationsController {
if (!authServ.isNotIn(new Role[]{Role.Teacher,Role.Secretary,Role.Admin},token)) if (!authServ.isNotIn(new Role[]{Role.Teacher,Role.Secretary,Role.Admin},token))
authorizedApps.add(Applications.ManageCourses); authorizedApps.add(Applications.ManageCourses);
if (!authServ.isNotIn(new Role[]{Role.InscriptionService,Role.Admin},token)){ if (!authServ.isNotIn(new Role[]{Role.InscriptionService,Role.Admin, Role.Teacher},token)){
authorizedApps.add(Applications.Inscription); authorizedApps.add(Applications.Requests);
authorizedApps.add(Applications.StudentsList);} authorizedApps.add(Applications.StudentsList);}
if (!authServ.isNotIn(new Role[]{Role.Secretary,Role.Admin},token)){ if (!authServ.isNotIn(new Role[]{Role.Secretary,Role.Admin},token)){
authorizedApps.add(Applications.UsersList); authorizedApps.add(Applications.UsersList);
authorizedApps.add(Applications.ManageSchedules); authorizedApps.add(Applications.ManageSchedules);
authorizedApps.add(Applications.LessonRequests);} authorizedApps.add(Applications.LessonRequests);}
if (!authServ.isNotIn(new Role[]{Role.Secretary,Role.Admin, Role.InscriptionService},token)){
authorizedApps.add(Applications.Payments);}
return authorizedApps; return authorizedApps;
} }
} }

View File

@ -133,4 +133,5 @@ public class CourseController {
courseServ.delete(courseServ.findById(id)); courseServ.delete(courseServ.findById(id));
return new ResponseEntity<>(HttpStatus.OK); return new ResponseEntity<>(HttpStatus.OK);
} }
} }

View File

@ -4,11 +4,13 @@ package ovh.herisson.Clyde.EndPoints;
import org.springframework.http.HttpStatus; import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import ovh.herisson.Clyde.Repositories.Inscription.ExternalCurriculumRepository;
import ovh.herisson.Clyde.Repositories.Inscription.InscriptionRepository;
import ovh.herisson.Clyde.Responses.UnauthorizedResponse; import ovh.herisson.Clyde.Responses.UnauthorizedResponse;
import ovh.herisson.Clyde.Services.*; import ovh.herisson.Clyde.Services.*;
import ovh.herisson.Clyde.Tables.Curriculum; import ovh.herisson.Clyde.Tables.*;
import ovh.herisson.Clyde.Tables.Role;
import java.util.HashMap;
import java.util.Map; import java.util.Map;
@RestController @RestController
@ -21,12 +23,18 @@ public class CurriculumController {
private final UserCurriculumService userCurriculumServ; private final UserCurriculumService userCurriculumServ;
private final CurriculumCourseService curriculumCourseServ; private final CurriculumCourseService curriculumCourseServ;
private final InscriptionRepository ir;
private final UserService userServ;
public CurriculumController(CurriculumService curriculumServ, AuthenticatorService authServ, UserCurriculumService userCurriculumServ, CurriculumCourseService curriculumCourseServ){ private final ExternalCurriculumRepository ecr;
public CurriculumController(CurriculumService curriculumServ, AuthenticatorService authServ, UserCurriculumService userCurriculumServ, CurriculumCourseService curriculumCourseServ, InscriptionRepository ir, UserService userServ, ExternalCurriculumRepository ecr){
this.curriculumServ = curriculumServ; this.curriculumServ = curriculumServ;
this.authServ = authServ; this.authServ = authServ;
this.userCurriculumServ = userCurriculumServ; this.userCurriculumServ = userCurriculumServ;
this.curriculumCourseServ = curriculumCourseServ; this.curriculumCourseServ = curriculumCourseServ;
this.ir = ir;
this.userServ = userServ;
this.ecr = ecr;
} }
@GetMapping("/curriculum/{id}") @GetMapping("/curriculum/{id}")
@ -52,6 +60,22 @@ public class CurriculumController {
return new ResponseEntity<>(curriculumCourseServ.getDepthCurriculum(curriculum),HttpStatus.OK); return new ResponseEntity<>(curriculumCourseServ.getDepthCurriculum(curriculum),HttpStatus.OK);
} }
//Return the list of all curicullums of an user
@GetMapping("/onescurriculum/{userId}")
public ResponseEntity<Map<String ,Object>> findOnesCurriculum(@RequestHeader("Authorization") String token, @PathVariable String userId){
if (authServ.getUserFromToken(token) == null)
return new UnauthorizedResponse<>(null);
User u = userServ.getUserById(Long.parseLong(userId));
HashMap<String,Object> toReturn = userCurriculumServ.findAllCurriculumByStudent(u);
if (toReturn == null)
return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
return new ResponseEntity<>(toReturn,HttpStatus.OK);
}
@GetMapping("/curriculums") @GetMapping("/curriculums")
public ResponseEntity<Iterable<Map<String, Object>>> findAllIndDepth(){ public ResponseEntity<Iterable<Map<String, Object>>> findAllIndDepth(){
return new ResponseEntity<>(curriculumCourseServ.getAllDepthCurriculum(),HttpStatus.OK); return new ResponseEntity<>(curriculumCourseServ.getAllDepthCurriculum(),HttpStatus.OK);
@ -94,4 +118,5 @@ public class CurriculumController {
curriculumServ.delete(toDelete); curriculumServ.delete(toDelete);
return new ResponseEntity<>(HttpStatus.OK); return new ResponseEntity<>(HttpStatus.OK);
} }
} }

View File

@ -0,0 +1,62 @@
package ovh.herisson.Clyde.EndPoints.Inscription;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import ovh.herisson.Clyde.Repositories.Inscription.ExternalCurriculumRepository;
import ovh.herisson.Clyde.Repositories.Inscription.InscriptionRepository;
import ovh.herisson.Clyde.Repositories.UserRepository;
import ovh.herisson.Clyde.Tables.Inscription.ExternalCurriculum;
import ovh.herisson.Clyde.Tables.Inscription.InscriptionRequest;
import ovh.herisson.Clyde.Tables.User;
import java.util.ArrayList;
import java.util.Map;
@RestController
@CrossOrigin(originPatterns = "*", allowCredentials = "true")
public class ExternalCurriculumController {
public final ExternalCurriculumRepository ecr;
public final InscriptionRepository inscriptionRepository;
public final UserRepository userRepository;
public ExternalCurriculumController(ExternalCurriculumRepository ecr, InscriptionRepository inscriptionRepository, UserRepository userRepository) {
this.ecr = ecr;
this.inscriptionRepository = inscriptionRepository;
this.userRepository = userRepository;
}
//everyone can post some externalcurriculums (the validity of the elements is assured by the inscription service)
@PostMapping("/externalcurriculum")
public ResponseEntity<ExternalCurriculum> postExternalCurriculum(@RequestBody Map<String, Object> externalCurrInfos){
//An external curriculum can either be linked to an User or to an InscriptionRequest
InscriptionRequest ir = null;
User user = null;
if (externalCurrInfos.get("inscriptionRequestId") != null){
ir = inscriptionRepository.findById((Integer) externalCurrInfos.get("inscriptionRequestId"));
}else{
user = userRepository.findById((Integer) externalCurrInfos.get("userRegNo"));
}
ExternalCurriculum toSave = new ExternalCurriculum(ir, (String) externalCurrInfos.get("school"),(String) externalCurrInfos.get("formation"),(String) externalCurrInfos.get("completion"), (Integer)externalCurrInfos.get("startYear"), (Integer)externalCurrInfos.get("endYear"), (String)externalCurrInfos.get("justifDocUrl"), user);
return new ResponseEntity<>(ecr.save(toSave), HttpStatus.OK);
}
@GetMapping("/externalcurriculum/{inscReqId}")
public ResponseEntity<ArrayList<ExternalCurriculum>> getExternalCurrListByInscrReq(@PathVariable long inscReqId){
InscriptionRequest ir = inscriptionRepository.findById(inscReqId);
ArrayList<ExternalCurriculum> toReturn = ecr.getExternalCurriculumByInscriptionRequest(ir);
return new ResponseEntity<>(toReturn, HttpStatus.OK);
}
@GetMapping("/externalcurriculumbyuser/{userId}")
public ResponseEntity<ArrayList<ExternalCurriculum>> getExternalCurrByUser(@PathVariable long userId){
User user = userRepository.findById(userId);
ArrayList<ExternalCurriculum> toReturn = ecr.getExternalCurriculumByUser(user);
return new ResponseEntity<>(toReturn, HttpStatus.OK);
}
}

View File

@ -1,13 +1,13 @@
package ovh.herisson.Clyde.EndPoints; package ovh.herisson.Clyde.EndPoints.Inscription;
import org.springframework.http.HttpStatus; import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import ovh.herisson.Clyde.Responses.UnauthorizedResponse; import ovh.herisson.Clyde.Responses.UnauthorizedResponse;
import ovh.herisson.Clyde.Services.AuthenticatorService; import ovh.herisson.Clyde.Services.AuthenticatorService;
import ovh.herisson.Clyde.Services.InscriptionService; import ovh.herisson.Clyde.Services.Inscription.InscriptionService;
import ovh.herisson.Clyde.Services.ProtectionService; import ovh.herisson.Clyde.Services.ProtectionService;
import ovh.herisson.Clyde.Tables.InscriptionRequest; import ovh.herisson.Clyde.Tables.Inscription.InscriptionRequest;
import ovh.herisson.Clyde.Tables.RequestState; import ovh.herisson.Clyde.Tables.RequestState;
import ovh.herisson.Clyde.Tables.Role; import ovh.herisson.Clyde.Tables.Role;
import java.util.Map; import java.util.Map;
@ -79,4 +79,22 @@ public class InscriptionController {
return new ResponseEntity<>(HttpStatus.OK); return new ResponseEntity<>(HttpStatus.OK);
} }
//Allow teacher or admin to accept or refuse the equivalence
@PatchMapping("/request/registerequiv/{id}/{newstate}")
public ResponseEntity<Object> editRegisterEquiv(@RequestHeader("Authorization") String token, @PathVariable long id, @PathVariable RequestState newstate){
if (authServ.isNotIn(new Role[]{Role.Admin,Role.Teacher}, token))
return new UnauthorizedResponse<>(null);
InscriptionRequest toEdit = inscriptionServ.getById(id);
toEdit.setEquivalenceState(newstate);
inscriptionServ.save(toEdit);
if (toEdit.getState() == RequestState.Accepted && (toEdit.getEquivalenceState() == RequestState.Accepted || toEdit.getEquivalenceState() == RequestState.Unrequired))
{
inscriptionServ.createUser(toEdit);
}
return new ResponseEntity<>(HttpStatus.OK);
}
} }

View File

@ -0,0 +1,55 @@
package ovh.herisson.Clyde.EndPoints.Inscription;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import ovh.herisson.Clyde.Repositories.Inscription.MinervalRepository;
import ovh.herisson.Clyde.Responses.UnauthorizedResponse;
import ovh.herisson.Clyde.Services.AuthenticatorService;
import ovh.herisson.Clyde.Tables.Inscription.Minerval;
import ovh.herisson.Clyde.Tables.Role;
import java.util.*;
@RestController
@CrossOrigin(originPatterns = "*", allowCredentials = "true")
public class MinervalController {
private final AuthenticatorService authServ;
private final MinervalRepository mr;
public MinervalController(AuthenticatorService authServ, MinervalRepository mr) {
this.authServ = authServ;
this.mr = mr;
}
//A new minerval entry is posted when the inscription service accept a registration request
@PostMapping("/minerval/{studentRegNo}")
public ResponseEntity<Object> postMinerval(@RequestHeader("Authorization") String token, @PathVariable long studentRegNo){
if (authServ.isNotIn(new Role[]{Role.Admin,Role.Secretary,Role.InscriptionService},token))
return new UnauthorizedResponse<>(null);
Calendar c = new GregorianCalendar();
mr.save(new Minerval(studentRegNo, 0, 835, c.get(Calendar.YEAR)));
return new ResponseEntity<>(HttpStatus.OK);
}
@GetMapping("/minerval/{studentRegNo}")
public ResponseEntity<Minerval> getCurrentMinervalbyRegNo(@PathVariable long studentRegNo){
ArrayList<Minerval> mlist = mr.getMinervalsByStudentRegNoOrderByYearDesc(studentRegNo);
//The list is ordered by year in descending order then the index 0 contains the actual minerval (for this year)
Minerval m = mlist.get(0);
return new ResponseEntity<>(m, HttpStatus.OK);
}
@PatchMapping("/minerval")
public ResponseEntity<Object> updateMinerval(@RequestBody Minerval updatedMinerval){
Minerval minerval = mr.findById(updatedMinerval.getId());
minerval.setPaidAmount(updatedMinerval.getPaidAmount());
minerval.setToPay(updatedMinerval.getToPay());
mr.save(minerval);
return new ResponseEntity<>(HttpStatus.OK);
}
}

View File

@ -0,0 +1,45 @@
package ovh.herisson.Clyde.EndPoints.Inscription;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import ovh.herisson.Clyde.Repositories.Inscription.PaymentRepository;
import ovh.herisson.Clyde.Tables.Inscription.Payment;
import java.util.ArrayList;
@RestController
@CrossOrigin(originPatterns = "*", allowCredentials = "true")
public class PaymentController {
private final PaymentRepository paymentRepository;
public PaymentController(PaymentRepository paymentRepository){
this.paymentRepository = paymentRepository;
}
//Post a payment record
@PostMapping("/payment")
public ResponseEntity<Object> postPayment(@RequestBody Payment payment){
paymentRepository.save(payment);
return new ResponseEntity<>(HttpStatus.OK);
}
//Get all payment records of a student
@GetMapping("/payment/{studentRegNo}")
public ResponseEntity<ArrayList<Payment>> getPaymentsByUser(@PathVariable long studentRegNo){
ArrayList<Payment> toReturn = paymentRepository.getPaymentsByStudentRegNo(studentRegNo);
return new ResponseEntity<>(toReturn, HttpStatus.OK);
}
@GetMapping("/payment")
public ResponseEntity<ArrayList<Payment>> getAllPayments(){
ArrayList<Payment> toReturn = new ArrayList<Payment>();
paymentRepository.findAll().forEach(toReturn::add);
return new ResponseEntity<>(toReturn, HttpStatus.OK);
}
}

View File

@ -0,0 +1,312 @@
package ovh.herisson.Clyde.EndPoints.Inscription;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import ovh.herisson.Clyde.Repositories.CourseRepository;
import ovh.herisson.Clyde.Repositories.CurriculumRepository;
import ovh.herisson.Clyde.Repositories.Inscription.ChangeCurriculumRequestRepository;
import ovh.herisson.Clyde.Repositories.Inscription.ExemptionsRequestRepository;
import ovh.herisson.Clyde.Repositories.Inscription.ScholarshipRequestRepository;
import ovh.herisson.Clyde.Repositories.Inscription.UnregisterRequestRepository;
import ovh.herisson.Clyde.Repositories.UserCurriculumRepository;
import ovh.herisson.Clyde.Repositories.UserRepository;
import ovh.herisson.Clyde.Responses.UnauthorizedResponse;
import ovh.herisson.Clyde.Services.AuthenticatorService;
import ovh.herisson.Clyde.Services.UserService;
import ovh.herisson.Clyde.Tables.*;
import ovh.herisson.Clyde.Tables.Inscription.ExemptionsRequest;
import ovh.herisson.Clyde.Tables.Inscription.ScholarshipRequest;
import ovh.herisson.Clyde.Tables.Inscription.UnregisterRequest;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.Map;
@RestController
@CrossOrigin(originPatterns = "*", allowCredentials = "true")
public class RequestsController {
public final ExemptionsRequestRepository err;
public final ScholarshipRequestRepository srr;
public final UserRepository userRepository;
public final AuthenticatorService authServ;
public final UnregisterRequestRepository unregisterRequestRepository;
public final CourseRepository courseRepository;
public final UserService userService;
public final UserCurriculumRepository userCurriculumRepository;
public final CurriculumRepository curriculumRepository;
public final ChangeCurriculumRequestRepository changeCurriculumRequestRepository;
public RequestsController(ExemptionsRequestRepository err, ScholarshipRequestRepository srr, UserRepository userRepository, AuthenticatorService authServ, UnregisterRequestRepository unregisterRequestRepository, CourseRepository courseRepository, UserService userService, UserCurriculumRepository userCurriculumRepository, CurriculumRepository curriculumRepository, ChangeCurriculumRequestRepository changeCurriculumRequestRepository) {
this.err = err;
this.srr = srr;
this.userRepository = userRepository;
this.authServ = authServ;
this.unregisterRequestRepository = unregisterRequestRepository;
this.courseRepository = courseRepository;
this.userService = userService;
this.userCurriculumRepository = userCurriculumRepository;
this.curriculumRepository = curriculumRepository;
this.changeCurriculumRequestRepository = changeCurriculumRequestRepository;
}
@PostMapping(value="/exemptionreq")
public ResponseEntity<String> createExemptionReq(@RequestBody Map<String, Object> exemptionsRequestInfo){
User user = userRepository.findById((Integer) exemptionsRequestInfo.get("userRegNo"));
Course course = courseRepository.findById((Integer) exemptionsRequestInfo.get("courseId"));
ExemptionsRequest exemptionsRequest = new ExemptionsRequest(user, course, (String) exemptionsRequestInfo.get("justifDocument"), RequestState.Pending, new Date());
err.save(exemptionsRequest);
return new ResponseEntity<>(HttpStatus.CREATED);
}
@PostMapping(value="/scholarshipreq")
public ResponseEntity<String> createScholarshipReq(@RequestBody Map<String, Object> scholarshipRequestInfo){
User user = userRepository.findById((Integer)scholarshipRequestInfo.get("userId"));
ScholarshipRequest toCreate = new ScholarshipRequest(user, RequestState.Pending, 0, new Date(), (String) scholarshipRequestInfo.get("taxDocUrl"), (String) scholarshipRequestInfo.get("residencyDocUrl"));
srr.save(toCreate);
return new ResponseEntity<>(HttpStatus.CREATED);
}
//Get all the exemptions Request
@GetMapping(value = "/exemptionsreq")
public ResponseEntity<ArrayList<ExemptionsRequest>> getAllExemptionsRequests(@RequestHeader("Authorization") String token){
if (authServ.isNotIn(new Role[]{Role.Admin,Role.Secretary,Role.InscriptionService},token))
return new UnauthorizedResponse<>(null);
ArrayList<ExemptionsRequest> toReturn = new ArrayList<>();
err.findAll().forEach(toReturn::add);
return new ResponseEntity<>(toReturn, HttpStatus.OK);
}
@GetMapping(value = "/exemptionsreq/{id}")
public ResponseEntity<ExemptionsRequest> getExemptionRequestbyId(@RequestHeader("Authorization") String token, @PathVariable long id){
if (authServ.isNotIn(new Role[]{Role.Admin,Role.Secretary,Role.InscriptionService},token))
return new UnauthorizedResponse<>(null);
ExemptionsRequest exemptionsRequest = err.findById(id);
return new ResponseEntity<>(exemptionsRequest, HttpStatus.OK);
}
@PatchMapping(value = "/exemptionsreq/{id}/{newstate}")
public ResponseEntity<String> changeExemptionReqState(@RequestHeader("Authorization") String token, @PathVariable long id, @PathVariable RequestState newstate){
if (authServ.isNotIn(new Role[]{Role.Admin,Role.Secretary,Role.InscriptionService},token))
return new UnauthorizedResponse<>(null);
ExemptionsRequest exemptionsRequest = err.findById(id);
exemptionsRequest.setState(newstate);
err.save(exemptionsRequest);
return new ResponseEntity<>(HttpStatus.OK);
}
//Get all the scholarships requests
@GetMapping(value = "/scholarshipreq")
public ResponseEntity<ArrayList<ScholarshipRequest>> getAllScholarshipRequests(@RequestHeader("Authorization") String token){
if (authServ.isNotIn(new Role[]{Role.Admin,Role.Secretary,Role.InscriptionService},token))
return new UnauthorizedResponse<>(null);
ArrayList<ScholarshipRequest> toReturn = new ArrayList<>();
srr.findAll().forEach(toReturn::add);
return new ResponseEntity<>(toReturn, HttpStatus.OK);
}
@PostMapping(value = "/unregister")
public ResponseEntity<String> postUnregReq(@RequestBody Map<String,Object> uninscr){
User u = userRepository.findById((int) uninscr.get("userId"));
Curriculum c;
if (uninscr.get("curriculumId") == null){
c = null;
}else{
c = curriculumRepository.findById((Integer) uninscr.get("curriculumId"));
}
UnregisterRequest ur = new UnregisterRequest(RequestState.Pending, (String) uninscr.get("reason"), new Date(), u.getRegNo(), u.getFirstName(), u.getLastName(), u.getEmail(), c);
unregisterRequestRepository.save(ur);
return new ResponseEntity<>(HttpStatus.OK);
}
@PatchMapping(value = "/scholarshipreq/")
public ResponseEntity<String> editScholReq(@RequestBody Map<String,Object> infos){
ScholarshipRequest scholarshipRequest = srr.findById((Integer) infos.get("id"));
if (infos.get("state").equals("Accepted")){
scholarshipRequest.setState(RequestState.Accepted);
scholarshipRequest.setAmount((int) infos.get("amount"));
}else{
scholarshipRequest.setState(RequestState.Refused);
}
srr.save(scholarshipRequest);
return new ResponseEntity<>(HttpStatus.OK);
}
@GetMapping(value = "/scholarshipreq/{id}")
public ResponseEntity<ScholarshipRequest> getScholReqbyId(@PathVariable long id){
ScholarshipRequest toReturn = srr.findById(id);
return new ResponseEntity<>(toReturn, HttpStatus.OK);
}
@GetMapping(value = "/unregister")
public ResponseEntity<ArrayList<UnregisterRequest>> getAllUnregReq(){
ArrayList<UnregisterRequest> toReturn = new ArrayList<>();
unregisterRequestRepository.findAll().forEach(toReturn::add);
return new ResponseEntity<>(toReturn, HttpStatus.OK);
}
@GetMapping(value = "/unregister/{id}")
public ResponseEntity<UnregisterRequest> getUnregbyId(@PathVariable long id){
UnregisterRequest unregisterRequest = unregisterRequestRepository.findById(id);
return new ResponseEntity<>(unregisterRequest, HttpStatus.OK);
}
@PatchMapping(value = "/unregister/{id}/{newstate}")
public ResponseEntity<String> pathUnregReq(@PathVariable long id, @PathVariable RequestState newstate){
UnregisterRequest unregisterRequest = unregisterRequestRepository.findById(id);
User u = userRepository.findById(unregisterRequest.getRegNo());
unregisterRequest.setState(newstate);
if (newstate == RequestState.Accepted){
if (unregisterRequest.getCurriculum() == null){
ArrayList<UserCurriculum> userCurricula = userCurriculumRepository.findByUserOrderByCurriculum(u);
for (int i = 0; i < userCurricula.size(); i++){
userCurricula.get(i).setActual(false);
}
userCurriculumRepository.saveAll(userCurricula);
}else{
//This usercurriculum will contain the usercurriculum to set false
UserCurriculum userCurriculum = userCurriculumRepository.findByUserAndCurriculumAndActual(u, unregisterRequest.getCurriculum(), true);
userCurriculum.setActual(false);
userCurriculumRepository.save(userCurriculum);
}
}
unregisterRequestRepository.save(unregisterRequest);
return new ResponseEntity<>(HttpStatus.OK);
}
//We look in the usercursus table if the student has already the previous year of a curriculum
public boolean studentHasPrevYear(Curriculum curriculum, User user){
ArrayList<UserCurriculum> userCurrList = userCurriculumRepository.findByUserOrderByCurriculum(user);
for (int i = 0; i < userCurrList.size(); i++){
if (userCurrList.get(i).getCurriculum().getOption().equals(curriculum.getOption()) && userCurrList.get(i).getCurriculum().getYear() == curriculum.getYear()-1){
return true;
}
}
return false;
}
@PostMapping("/changecurriculumreq")
public ResponseEntity<String> addChangeCurrReq(@RequestBody Map<String,Object> reqInfos){
User user = userRepository.findById((Integer) reqInfos.get("userId"));
Curriculum actualCurriculum;
//If null then it means we are in a supplementary cursus case
if (reqInfos.get("actualcursus") == null){
actualCurriculum = null;
}else{
actualCurriculum = curriculumRepository.findById((Integer) reqInfos.get("actualcursus"));
}
Curriculum destinationCurriculum = curriculumRepository.findById((Integer) reqInfos.get("newcursus"));
ChangeCurriculumRequest changeCurriculumRequest = new ChangeCurriculumRequest(user, actualCurriculum, destinationCurriculum, new Date(), RequestState.Pending, RequestState.Unrequired);
//Si l'année du cursus est plus grande que 1 et que l'étudiant n'a pas dans sa liste de cursus l'année d'en dessous alors on demande l'accord du prof
if (destinationCurriculum.getYear() > 1 && !studentHasPrevYear(destinationCurriculum, user)){
changeCurriculumRequest.setTeacherApprovalState(RequestState.Pending);
}
changeCurriculumRequestRepository.save(changeCurriculumRequest);
return new ResponseEntity<>(HttpStatus.OK);
}
@GetMapping("/changecurriculumreq")
public ResponseEntity<ArrayList <ChangeCurriculumRequest>> getAllChangeCurrReq(@RequestHeader("Authorization") String token){
if (authServ.isNotIn(new Role[]{Role.Admin,Role.Secretary,Role.InscriptionService},token))
return new UnauthorizedResponse<>(null);
ArrayList<ChangeCurriculumRequest> toReturn = new ArrayList<>();
changeCurriculumRequestRepository.findAll().forEach(toReturn::add);
return new ResponseEntity<>(toReturn, HttpStatus.OK);
}
@GetMapping("/changecurriculumreq/{id}")
public ResponseEntity<ChangeCurriculumRequest> getCCrbyId(@RequestHeader("Authorization") String token, @PathVariable long id){
if (authServ.isNotIn(new Role[]{Role.Admin,Role.Secretary,Role.InscriptionService},token))
return new UnauthorizedResponse<>(null);
ChangeCurriculumRequest toReturn = changeCurriculumRequestRepository.findById(id);
return new ResponseEntity<>(toReturn, HttpStatus.OK);
}
@PatchMapping("/changecurriculumreq/{id}/{newState}")
public ResponseEntity<String> editCCReq(@RequestHeader("Authorization") String token, @PathVariable long id, @PathVariable RequestState newState){
if (authServ.isNotIn(new Role[]{Role.Admin,Role.Secretary,Role.InscriptionService},token))
return new UnauthorizedResponse<>(null);
ChangeCurriculumRequest toEdit = changeCurriculumRequestRepository.findById(id);
toEdit.setState(newState);
if (newState == RequestState.Accepted && (toEdit.getTeacherApprovalState() == RequestState.Accepted || toEdit.getTeacherApprovalState() == RequestState.Unrequired)){
//If actual curriculum is not null then we need to set that the user doesn't follow it anymore
acceptProcedure(toEdit);
}
changeCurriculumRequestRepository.save(toEdit);
return new ResponseEntity<>(HttpStatus.OK);
}
@PatchMapping("/changecurriculumreqteacher/{id}/{newteacherstate}")
public ResponseEntity<String> editCCReqTeacherState(@RequestHeader("Authorization") String token, @PathVariable long id, @PathVariable RequestState newteacherstate){
if (authServ.isNotIn(new Role[]{Role.Admin,Role.Secretary,Role.InscriptionService},token))
return new UnauthorizedResponse<>(null);
ChangeCurriculumRequest toEdit = changeCurriculumRequestRepository.findById(id);
toEdit.setState(newteacherstate);
if (newteacherstate == RequestState.Accepted && toEdit.getState() == RequestState.Accepted){
//If actual curriculum is not null then we need to set that the user doesn't follow it anymore
acceptProcedure(toEdit);
}
changeCurriculumRequestRepository.save(toEdit);
return new ResponseEntity<>(HttpStatus.OK);
}
private void acceptProcedure(ChangeCurriculumRequest toEdit) {
User u = toEdit.getUser();
if (toEdit.getActualCurriculum() != null){
ArrayList<UserCurriculum> listcurr = userCurriculumRepository.findByUserOrderByCurriculum(u);
for (int i = 0; i < listcurr.size(); i++){
if (listcurr.get(i).getCurriculum() == toEdit.getActualCurriculum()){
listcurr.get(i).setActual(false);
}
}
userCurriculumRepository.saveAll(listcurr);
}
Calendar c = Calendar.getInstance();
UserCurriculum userCurriculum = new UserCurriculum(u, toEdit.getDestinationCurriculum(), c.get(Calendar.YEAR), true);
userCurriculumRepository.save(userCurriculum);
}
}

View File

@ -1,5 +1,13 @@
package ovh.herisson.Clyde.EndPoints; package ovh.herisson.Clyde.EndPoints;
/******************************************************
* @file LessonController.java
* @author William Karpinski
* @scope Extension Horaire
*
* Controller of Lessons API
******************************************************/
import org.springframework.http.HttpStatus; import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
@ -28,6 +36,9 @@ public class LessonController {
this.authServ = authServ; this.authServ = authServ;
} }
/**
* Return a lesson via its id
*/
@GetMapping("/lesson/{id}") @GetMapping("/lesson/{id}")
public ResponseEntity<HashMap<String,Object>> getLesson(@PathVariable long id){ public ResponseEntity<HashMap<String,Object>> getLesson(@PathVariable long id){
Lesson lesson = lessonServ.findById(id); Lesson lesson = lessonServ.findById(id);
@ -38,6 +49,9 @@ public class LessonController {
return new ResponseEntity<>(ProtectionService.lessonWithoutPassword(lesson),HttpStatus.OK); return new ResponseEntity<>(ProtectionService.lessonWithoutPassword(lesson),HttpStatus.OK);
} }
/**
* Return all the lessons
*/
@GetMapping("/lessons") @GetMapping("/lessons")
public ResponseEntity<Iterable<HashMap<String,Object>>> getAllLessons(@RequestHeader("Authorization") String token){ public ResponseEntity<Iterable<HashMap<String,Object>>> getAllLessons(@RequestHeader("Authorization") String token){
if(authServ.isNotIn(new Role[]{Role.Admin,Role.Secretary},token)) if(authServ.isNotIn(new Role[]{Role.Admin,Role.Secretary},token))
@ -45,15 +59,29 @@ public class LessonController {
return new ResponseEntity<>(ProtectionService.lessonsWithoutPassword(lessonServ.findAll()),HttpStatus.OK); return new ResponseEntity<>(ProtectionService.lessonsWithoutPassword(lessonServ.findAll()),HttpStatus.OK);
} }
/**
* Return all the lessons of a teacher's courses
*/
@GetMapping("/lessons/owned") @GetMapping("/lessons/owned")
public ResponseEntity<Iterable<HashMap<String,Object>>> getOwnedLessons(@RequestHeader("Authorization") String token){ public ResponseEntity<Iterable<HashMap<String,Object>>> getOwnedLessons(@RequestHeader("Authorization") String token){
System.out.println(authServ);
if (authServ.isNotIn(new Role[]{Role.Admin,Role.Teacher},token)){ if (authServ.isNotIn(new Role[]{Role.Admin,Role.Teacher},token)){
return new UnauthorizedResponse<>(null);} return new UnauthorizedResponse<>(null);}
return new ResponseEntity<>(ProtectionService.lessonsWithoutPassword(lessonServ.findAllOwnedLesson(authServ.getUserFromToken(token))),HttpStatus.OK); return new ResponseEntity<>(ProtectionService.lessonsWithoutPassword(lessonServ.findAllOwnedLesson(authServ.getUserFromToken(token))),HttpStatus.OK);
} }
/**
* Return all the lessons of a student
*/
@GetMapping("/lessons/OwnCurriculum")
public ResponseEntity<Iterable<HashMap<String,Object>>> getOnesLessons(@RequestHeader("Authorization") String token){
if (authServ.isNotIn(new Role[]{Role.Admin,Role.Student},token)){
return new UnauthorizedResponse<>(null);}
return new ResponseEntity<>(ProtectionService.lessonsWithoutPassword(lessonServ.findOnesLessons(authServ.getUserFromToken(token))),HttpStatus.OK);
}
/**
* Post a new lesson
*/
@PostMapping("/lesson") @PostMapping("/lesson")
public ResponseEntity<HashMap<String, Object>> postLesson(@RequestHeader("Authorization") String token, public ResponseEntity<HashMap<String, Object>> postLesson(@RequestHeader("Authorization") String token,
@RequestBody Map<String, Object> lessonInfos){ @RequestBody Map<String, Object> lessonInfos){
@ -69,7 +97,9 @@ public class LessonController {
return new ResponseEntity<>(null,HttpStatus.BAD_REQUEST); return new ResponseEntity<>(null,HttpStatus.BAD_REQUEST);
return new ResponseEntity<>(ProtectionService.lessonWithoutPassword(createdLesson), HttpStatus.OK); return new ResponseEntity<>(ProtectionService.lessonWithoutPassword(createdLesson), HttpStatus.OK);
} }
/**
* Modify a lesson
*/
@PatchMapping("/lesson/{id}") @PatchMapping("/lesson/{id}")
public ResponseEntity<Lesson> patchLesson(@RequestHeader("Authorization") String token, public ResponseEntity<Lesson> patchLesson(@RequestHeader("Authorization") String token,
@RequestBody Map<String, Object> updates, @RequestBody Map<String, Object> updates,
@ -81,7 +111,9 @@ public class LessonController {
} }
return new ResponseEntity<>(HttpStatus.OK); return new ResponseEntity<>(HttpStatus.OK);
} }
/**
* Delete a lesson
*/
@DeleteMapping("lesson/{id}") @DeleteMapping("lesson/{id}")
public ResponseEntity<String> deleteLesson(@RequestHeader("Authorization") String token, public ResponseEntity<String> deleteLesson(@RequestHeader("Authorization") String token,
@PathVariable Long id){ @PathVariable Long id){

View File

@ -1,5 +1,13 @@
package ovh.herisson.Clyde.EndPoints; package ovh.herisson.Clyde.EndPoints;
/******************************************************
* @file LessonRequestsController.java
* @author William Karpinski
* @scope Extension Horaire
*
* Controller of lesson requests API
******************************************************/
import org.springframework.http.HttpStatus; import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
@ -27,7 +35,9 @@ public class LessonRequestsController {
this.authServ = authServ; this.authServ = authServ;
this.lessonServ = lessonServ; this.lessonServ = lessonServ;
} }
/**
* Return a lesson request via its id
*/
@GetMapping("/requests/lessonRequest/{id}") @GetMapping("/requests/lessonRequest/{id}")
public ResponseEntity<Map<String,Object>> getById(@RequestHeader("Authorization") String token, @PathVariable long id){ public ResponseEntity<Map<String,Object>> getById(@RequestHeader("Authorization") String token, @PathVariable long id){
if (authServ.isNotIn(new Role[]{Role.Admin,Role.Secretary},token)) if (authServ.isNotIn(new Role[]{Role.Admin,Role.Secretary},token))
@ -37,7 +47,9 @@ public class LessonRequestsController {
return new ResponseEntity<>(ProtectionService.lessonRequestWithoutPassword(lessonRequest), HttpStatus.OK); return new ResponseEntity<>(ProtectionService.lessonRequestWithoutPassword(lessonRequest), HttpStatus.OK);
} }
/**
* return all the requests made by a user
*/
@GetMapping("/requests/lessonRequests/owned") @GetMapping("/requests/lessonRequests/owned")
public ResponseEntity<Iterable<Map<String, Object>>> getOwnedRequests(@RequestHeader("Authorization") String token){ public ResponseEntity<Iterable<Map<String, Object>>> getOwnedRequests(@RequestHeader("Authorization") String token){
if(authServ.isNotIn(new Role[]{Role.Admin,Role.Teacher},token)) if(authServ.isNotIn(new Role[]{Role.Admin,Role.Teacher},token))
@ -47,7 +59,9 @@ public class LessonRequestsController {
return new ResponseEntity<>(ProtectionService.lessonRequestsWithoutPassword(lessonChangesRequests),HttpStatus.OK); return new ResponseEntity<>(ProtectionService.lessonRequestsWithoutPassword(lessonChangesRequests),HttpStatus.OK);
} }
/**
* Return all the lesson requests
*/
@GetMapping("/requests/lessonRequests") @GetMapping("/requests/lessonRequests")
public ResponseEntity<Iterable<Map<String,Object>>> getAllRequests(@RequestHeader("Authorization") String token){ public ResponseEntity<Iterable<Map<String,Object>>> getAllRequests(@RequestHeader("Authorization") String token){
if (authServ.isNotIn(new Role[]{Role.Admin,Role.Secretary},token)) if (authServ.isNotIn(new Role[]{Role.Admin,Role.Secretary},token))
@ -57,7 +71,9 @@ public class LessonRequestsController {
return new ResponseEntity<>(ProtectionService.lessonRequestsWithoutPassword(lessonRequests), HttpStatus.OK); return new ResponseEntity<>(ProtectionService.lessonRequestsWithoutPassword(lessonRequests), HttpStatus.OK);
} }
/**
* Post a lesson request
*/
@PostMapping("/requests/lessonRequest") @PostMapping("/requests/lessonRequest")
public ResponseEntity<Map<String, Object>> makeRequest(@RequestHeader("Authorization") String token, @RequestBody Map<String,Object> lessonRequestInfos){ public ResponseEntity<Map<String, Object>> makeRequest(@RequestHeader("Authorization") String token, @RequestBody Map<String,Object> lessonRequestInfos){
if(authServ.isNotIn(new Role[]{Role.Admin,Role.Teacher},token)) if(authServ.isNotIn(new Role[]{Role.Admin,Role.Teacher},token))
@ -68,7 +84,9 @@ public class LessonRequestsController {
return new ResponseEntity<>(null, HttpStatus.BAD_REQUEST); return new ResponseEntity<>(null, HttpStatus.BAD_REQUEST);
return new ResponseEntity<>(ProtectionService.lessonRequestWithoutPassword(lessonChangesRequest),HttpStatus.OK); return new ResponseEntity<>(ProtectionService.lessonRequestWithoutPassword(lessonChangesRequest),HttpStatus.OK);
} }
/**
* Modify a lesson Request
*/
@PatchMapping("/requests/lessonRequest/{id}") @PatchMapping("/requests/lessonRequest/{id}")
public ResponseEntity<LessonChangesRequest> changeRequestState(@PathVariable long id, public ResponseEntity<LessonChangesRequest> changeRequestState(@PathVariable long id,
@RequestHeader("Authorization") String token, @RequestHeader("Authorization") String token,
@ -116,7 +134,9 @@ public class LessonRequestsController {
} }
/**
* Delete a lesson request
*/
@DeleteMapping("/requests/lessonRequest/{id}") @DeleteMapping("/requests/lessonRequest/{id}")
public ResponseEntity<String> deleteRequest(@RequestHeader("Authorization") String token, @PathVariable long id){ public ResponseEntity<String> deleteRequest(@RequestHeader("Authorization") String token, @PathVariable long id){
if(authServ.isNotIn(new Role[]{Role.Admin,Role.Secretary,Role.Teacher},token)) if(authServ.isNotIn(new Role[]{Role.Admin,Role.Secretary,Role.Teacher},token))

View File

@ -5,10 +5,14 @@ import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus; import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import ovh.herisson.Clyde.Repositories.CurriculumRepository;
import ovh.herisson.Clyde.Responses.UnauthorizedResponse; import ovh.herisson.Clyde.Responses.UnauthorizedResponse;
import ovh.herisson.Clyde.Services.AuthenticatorService; import ovh.herisson.Clyde.Services.AuthenticatorService;
import ovh.herisson.Clyde.Services.ProtectionService; import ovh.herisson.Clyde.Services.ProtectionService;
import ovh.herisson.Clyde.Tables.InscriptionRequest; import ovh.herisson.Clyde.Tables.Curriculum;
import ovh.herisson.Clyde.Tables.Inscription.InscriptionRequest;
import ovh.herisson.Clyde.Tables.RequestState;
import java.util.Date; import java.util.Date;
import java.util.Map; import java.util.Map;
@ -16,7 +20,7 @@ import java.util.Map;
@CrossOrigin(originPatterns = "*", allowCredentials = "true") @CrossOrigin(originPatterns = "*", allowCredentials = "true")
public class LoginController { public class LoginController {
private final AuthenticatorService authServ; private final AuthenticatorService authServ;
private final CurriculumRepository curriculumRepository;
static public class RequestLogin{ static public class RequestLogin{
private final String identifier; private final String identifier;
private final String password; private final String password;
@ -29,8 +33,9 @@ public class LoginController {
} }
} }
public LoginController(AuthenticatorService authServ){ public LoginController(AuthenticatorService authServ, CurriculumRepository curriculumRepository){
this.authServ = authServ; this.authServ = authServ;
this.curriculumRepository = curriculumRepository;
} }
@PostMapping(value = "/login") @PostMapping(value = "/login")
@ -48,9 +53,18 @@ public class LoginController {
@PostMapping("/register") @PostMapping("/register")
public ResponseEntity<Map<String,Object>> register(@RequestBody InscriptionRequest inscriptionRequest){ public ResponseEntity<Map<String,Object>> register(@RequestBody InscriptionRequest inscriptionRequest){
//We ensure here that if the targeted cursus year is more than first grade then we need the teacher equivalence approval
Curriculum curr = curriculumRepository.findById(inscriptionRequest.getCurriculumId());
if (curr.getYear() > 1){
inscriptionRequest.setEquivalenceState(RequestState.Pending);
}else{
inscriptionRequest.setEquivalenceState(RequestState.Unrequired);
}
InscriptionRequest returnedInscriptionRequest = authServ.register(inscriptionRequest); InscriptionRequest returnedInscriptionRequest = authServ.register(inscriptionRequest);
return new ResponseEntity<>(ProtectionService.requestWithoutPassword(returnedInscriptionRequest), HttpStatus.CREATED); return new ResponseEntity<>(ProtectionService.requestWithoutPassword(returnedInscriptionRequest), HttpStatus.CREATED);
} }
} }

View File

@ -2,10 +2,16 @@ package ovh.herisson.Clyde.EndPoints;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import ovh.herisson.Clyde.Repositories.TokenRepository; import ovh.herisson.Clyde.Repositories.*;
import ovh.herisson.Clyde.Repositories.UserRepository; import ovh.herisson.Clyde.Repositories.Inscription.ExternalCurriculumRepository;
import ovh.herisson.Clyde.Repositories.Inscription.MinervalRepository;
import ovh.herisson.Clyde.Repositories.Inscription.ScholarshipRequestRepository;
import ovh.herisson.Clyde.Repositories.Inscription.UnregisterRequestRepository;
import ovh.herisson.Clyde.Services.*; import ovh.herisson.Clyde.Services.*;
import ovh.herisson.Clyde.Services.Inscription.InscriptionService;
import ovh.herisson.Clyde.Tables.*; import ovh.herisson.Clyde.Tables.*;
import ovh.herisson.Clyde.Tables.Inscription.*;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Date; import java.util.Date;
@ -15,14 +21,14 @@ import java.util.Date;
public class MockController { public class MockController {
private final BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder(); private final BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
public final UserService userService;
public final UserRepository userRepo; public final UserRepository userRepo;
public final TokenRepository tokenRepo; public final TokenRepository tokenRepo;
public final TokenService tokenService; public final TokenService tokenService;
public final CurriculumCourseService CurriculumCourseService; public final CurriculumCourseService CurriculumCourseService;
public final CurriculumService curriculumService; public final CurriculumService curriculumService;
public final CourseService courseService; public final CourseService courseService;
public final ExternalCurriculumRepository externalCurriculumRepository;
public final InscriptionService inscriptionService; public final InscriptionService inscriptionService;
public final LessonService lessonService; public final LessonService lessonService;
@ -32,19 +38,31 @@ public class MockController {
public final LessonRequestService lessonRequestService; public final LessonRequestService lessonRequestService;
ArrayList<User> mockUsers; ArrayList<User> mockUsers;
public final UserCurriculumRepository ucr;
public MockController(UserRepository userRepo, TokenRepository tokenRepo, TokenService tokenService, CurriculumCourseService CurriculumCourseService, CurriculumService curriculumService, CourseService courseService, InscriptionService inscriptionService, LessonService lessonService, ScheduleService scheduleService, ScheduleLessonService scheduleLessonService, LessonRequestService lessonRequestService){ public final MinervalRepository minervalRepository;
public final ScholarshipRequestRepository scholarshipRequestRepository;
public final UnregisterRequestRepository uninscriptionRequestRepository;
public MockController(UserService userService, UserRepository userRepo, TokenRepository tokenRepo, TokenService tokenService, CurriculumCourseService CurriculumCourseService, CurriculumService curriculumService, CourseService courseService, ExternalCurriculumRepository externalCurriculumRepository, InscriptionService inscriptionService, UserCurriculumRepository ucr, MinervalRepository minervalRepository, ScholarshipRequestRepository scholarshipRequestRepository, UnregisterRequestRepository unregisterRequestRepository, LessonService lessonService, ScheduleService scheduleService, ScheduleLessonService scheduleLessonService, LessonRequestService lessonRequestService){
this.userService = userService;
this.tokenRepo = tokenRepo; this.tokenRepo = tokenRepo;
this.userRepo = userRepo; this.userRepo = userRepo;
this.tokenService = tokenService; this.tokenService = tokenService;
this.CurriculumCourseService = CurriculumCourseService; this.CurriculumCourseService = CurriculumCourseService;
this.curriculumService = curriculumService; this.curriculumService = curriculumService;
this.courseService = courseService; this.courseService = courseService;
this.externalCurriculumRepository = externalCurriculumRepository;
this.inscriptionService = inscriptionService; this.inscriptionService = inscriptionService;
this.lessonService = lessonService; this.lessonService = lessonService;
this.scheduleService = scheduleService; this.scheduleService = scheduleService;
this.scheduleLessonService = scheduleLessonService; this.scheduleLessonService = scheduleLessonService;
this.lessonRequestService = lessonRequestService; this.lessonRequestService = lessonRequestService;
this.ucr = ucr;
this.minervalRepository = minervalRepository;
this.scholarshipRequestRepository = scholarshipRequestRepository;
this.uninscriptionRequestRepository = unregisterRequestRepository;
} }
/** Saves an example of each user type by : /** Saves an example of each user type by :
@ -57,28 +75,48 @@ public class MockController {
public void postMock(){ public void postMock(){
// user part // user part
User herobrine = new User("brine","hero","admin@admin.com","behind","ShadowsLand",new Date(0), null,Role.Admin,passwordEncoder.encode("admin")); User herobrine = new User("brine","hero","admin@admin.com","behind","ShadowsLand",new Date(0), null,Role.Admin,passwordEncoder.encode("admin"));
User joe = new User("Mama","Joe","student@student.com","roundabout","England",new Date(0), null,Role.Student,passwordEncoder.encode("student")); User joe = new User("Mama","Joe","student@student.com","roundabout","England",new Date(0), null,Role.Student,passwordEncoder.encode("student"));
User meh = new User("Polo","Marco","secretary@secretary.com","a Box","Monaco",new Date(0), null,Role.Secretary,passwordEncoder.encode("secretary")); User meh = new User("Polo","Marco","secretary@secretary.com","a Box","Monaco",new Date(0), null,Role.Secretary,passwordEncoder.encode("secretary"));
User joke = new User("Gaillard","Corentin","teacher@teacher.com","lab","faculty",new Date(0), null,Role.Teacher,passwordEncoder.encode("teacher")); User joke = new User("Gaillard","Corentin","teacher@teacher.com","lab","faculty",new Date(0), null,Role.Teacher,passwordEncoder.encode("teacher"));
User jojo = new User("Bridoux","Justin","teacher2@teacher2.com","lab","faculty",new Date(0), null,Role.Teacher,passwordEncoder.encode("teacher")); User jojo = new User("Bridoux","Justin","teacher2@teacher2.com","lab","faculty",new Date(0), null,Role.Teacher,passwordEncoder.encode("teacher"));
User lena = new User("Louille","Lena","inscriptionService@InscriptionService.com","no","yes",new Date(0), null,Role.InscriptionService,passwordEncoder.encode("inscriptionService")); User lena = new User("Louille","Lena","inscriptionService@InscriptionService.com","no","yes",new Date(0), null,Role.InscriptionService,passwordEncoder.encode("inscriptionService"));
mockUsers = new ArrayList<>(Arrays.asList(herobrine,joe,meh,joke,lena,jojo)); User popo = new User("Smith", "Paul", "paulsmith@gmail.com", "306 rue du poulet", "belgique", new Date(0), null, Role.Student, passwordEncoder.encode("jesuispaulleroi"));
mockUsers = new ArrayList<>(Arrays.asList(herobrine,joe,meh,joke,lena,jojo, popo));
userRepo.saveAll(mockUsers); userService.saveAll(mockUsers);
ExternalCurriculum externalCurriculum = new ExternalCurriculum(null, "HEH", "Bachelier en ingénieur", "completed", 2015, 2017, null, joe);
externalCurriculumRepository.save(externalCurriculum);
Minerval minerval = new Minerval(joe.getRegNo(), 0, 852, 2023);
minervalRepository.save(minerval);
// Course / Curriculum part // Course / Curriculum part
Curriculum infoBab1 = new Curriculum(1,"info"); Curriculum infoBab1 = new Curriculum(1,"info", false);
Curriculum chemistryBab1 = new Curriculum(1,"chemistry"); Curriculum chemistryBab1 = new Curriculum(1,"chemistry", false);
Curriculum psychologyBab1 = new Curriculum(1,"psychology"); Curriculum psychologyBab1 = new Curriculum(1,"psychology", false);
Curriculum infoBab2 = new Curriculum(2,"info", false);
Curriculum masterinfo1 = new Curriculum(4, "info", false);
Curriculum masterinfo2 = new Curriculum(5, "info", false);
Curriculum chemistryBab2 = new Curriculum(2, "chemistry", false);
Curriculum ingebab1 = new Curriculum(1, "ingénieur", true);
curriculumService.save(infoBab1); curriculumService.save(infoBab1);
curriculumService.save(chemistryBab1); curriculumService.save(chemistryBab1);
curriculumService.save(psychologyBab1); curriculumService.save(psychologyBab1);
curriculumService.save(infoBab2);
curriculumService.save(masterinfo1);
curriculumService.save(masterinfo2);
curriculumService.save(chemistryBab2);
curriculumService.save(ingebab1);
ucr.save(new UserCurriculum(joe, infoBab1, 2022, false));
ucr.save(new UserCurriculum(joe, chemistryBab1, 2023, true));
ucr.save(new UserCurriculum(joe, infoBab1, 2023, true));
ucr.save(new UserCurriculum(joe, psychologyBab1, 2020, false));
ucr.save(new UserCurriculum(popo, infoBab1, 2022, false));
ucr.save(new UserCurriculum(popo, infoBab2, 2023, true));
Course progra1 = new Course(5,"Programmation et algorithmique 1",joke); Course progra1 = new Course(5,"Programmation et algorithmique 1",joke);
Course chemistry1 = new Course(12, "Thermochimie",joke); Course chemistry1 = new Course(12, "Thermochimie",joke);
@ -90,10 +128,12 @@ public class MockController {
courseService.save(psycho1); courseService.save(psycho1);
courseService.save(commun); courseService.save(commun);
ScholarshipRequest ssr1 = new ScholarshipRequest(joe, RequestState.Pending, 0, new Date(), "test", "test");
scholarshipRequestRepository.save(ssr1);
CurriculumCourseService.save(new CurriculumCourse(infoBab1,progra1)); CurriculumCourseService.save(new CurriculumCourse(infoBab1,progra1));
CurriculumCourseService.save(new CurriculumCourse(infoBab1,commun)); CurriculumCourseService.save(new CurriculumCourse(infoBab1,commun));
CurriculumCourseService.save(new CurriculumCourse(infoBab1, psycho1));
CurriculumCourseService.save(new CurriculumCourse(psychologyBab1,psycho1)); CurriculumCourseService.save(new CurriculumCourse(psychologyBab1,psycho1));
CurriculumCourseService.save(new CurriculumCourse(psychologyBab1,commun)); CurriculumCourseService.save(new CurriculumCourse(psychologyBab1,commun));
@ -101,8 +141,7 @@ public class MockController {
CurriculumCourseService.save(new CurriculumCourse(chemistryBab1,commun)); CurriculumCourseService.save(new CurriculumCourse(chemistryBab1,commun));
CurriculumCourseService.save(new CurriculumCourse(chemistryBab1,chemistry1)); CurriculumCourseService.save(new CurriculumCourse(chemistryBab1,chemistry1));
InscriptionRequest inscriptionRequest = new InscriptionRequest("helen","prenom","non","helen@gmail.com","america",new Date(),(long) 4,RequestState.Pending,"yes.png","password", null, new Date(), RequestState.Pending, null);
InscriptionRequest inscriptionRequest = new InscriptionRequest("helen","prenom","non","helen@gmail.com","america",new Date(),(long) 1,RequestState.Pending,"yes.png","password");
inscriptionService.save(inscriptionRequest); inscriptionService.save(inscriptionRequest);
@ -149,6 +188,12 @@ public class MockController {
lessonRequestService.save(request1); lessonRequestService.save(request1);
lessonRequestService.save(request2); lessonRequestService.save(request2);
lessonRequestService.save(request3); lessonRequestService.save(request3);
UnregisterRequest unregisterRequest = new UnregisterRequest(RequestState.Pending, "je veux partir", new Date(), joe.getRegNo(), joe.getFirstName(), joe.getLastName(), joe.getEmail(), null);
uninscriptionRequestRepository.save(unregisterRequest);
externalCurriculum = new ExternalCurriculum(inscriptionRequest, "HEH", "Bachelier en informatique", "Completed", 2015, 2018, null, null);
externalCurriculumRepository.save(externalCurriculum);
} }
} }

View File

@ -0,0 +1,126 @@
package ovh.herisson.Clyde.EndPoints.Msg;
/******************************************************
* @file MessagesController.java
* @author Anthony Debucquoy
* @scope Extension messagerie
*
* Entry point for the messages application
******************************************************/
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PatchMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RestController;
import lombok.AllArgsConstructor;
import ovh.herisson.Clyde.DTO.Msg.DiscussionDTO;
import ovh.herisson.Clyde.Repositories.UserRepository;
import ovh.herisson.Clyde.Repositories.Msg.DiscussionRepository;
import ovh.herisson.Clyde.Responses.UnauthorizedResponse;
import ovh.herisson.Clyde.Services.AuthenticatorService;
import ovh.herisson.Clyde.Services.UserService;
import ovh.herisson.Clyde.Services.Msg.DiscussionService;
import ovh.herisson.Clyde.Tables.User;
import ovh.herisson.Clyde.Tables.Msg.Discussion;
import ovh.herisson.Clyde.Tables.Msg.Message;
@RestController
@CrossOrigin(originPatterns = "*", allowCredentials = "true")
@AllArgsConstructor
public class MessagesController {
private AuthenticatorService authServ;
private DiscussionService discServ;
private DiscussionRepository discRepo;
private UserService userServ;
@GetMapping("/discussions")
public ResponseEntity<Iterable<Discussion>> getDiscussions(@RequestHeader("Authorization") String token ){
User user = authServ.getUserFromToken(token);
if(user == null){
return new UnauthorizedResponse<>(null);
}
Iterable<Discussion> mock = discServ.getOwned(authServ.getUserFromToken(token));
return new ResponseEntity<>(mock, HttpStatus.OK);
}
@GetMapping("/discussion/{id}")
public ResponseEntity<DiscussionDTO> getDiscussion(@RequestHeader("Authorization") String token, @PathVariable long id){
User user = authServ.getUserFromToken(token);
if(user == null || !discServ.hasDiscussion(user, id) ){
return new UnauthorizedResponse<>(null);
}
return new ResponseEntity<>(DiscussionDTO.construct(discRepo.findById(id).orElse(null), authServ.getUserFromToken(token)), HttpStatus.OK);
}
@PatchMapping("/discussion/{id}")
public ResponseEntity<Discussion> AlterDiscussion(@RequestHeader("Authorization") String token, @PathVariable long id, @RequestBody Discussion data){
User user = authServ.getUserFromToken(token);
if(user == null){
return new UnauthorizedResponse<>(null);
}
Discussion disc = discRepo.findById(id).orElse(null);
disc.setName(data.getName());
discRepo.save(disc);
return new ResponseEntity<>(disc, HttpStatus.OK);
}
@PatchMapping("/discussion/{id}/add")
public ResponseEntity<Discussion> invite(@RequestHeader("Authorization") String token, @PathVariable long id, @RequestBody User data){
User user = authServ.getUserFromToken(token);
if(user == null){
return new UnauthorizedResponse<>(null);
}
Discussion disc = discRepo.findById(id).orElse(null);
User invited = userServ.getUserById(data.getRegNo());
disc.addMember(invited);
discRepo.save(disc);
return new ResponseEntity<>(disc, HttpStatus.OK);
}
@PatchMapping("/discussion/{id}/remove")
public ResponseEntity<Discussion> removeMember(@RequestHeader("Authorization") String token, @PathVariable long id, @RequestBody User data){
User user = authServ.getUserFromToken(token);
if(user == null){
return new UnauthorizedResponse<>(null);
}
Discussion disc = discRepo.findById(id).orElse(null);
User member = userServ.getUserById(data.getRegNo());
disc.delMember(member);
discRepo.save(disc);
return new ResponseEntity<>(disc, HttpStatus.OK);
}
@PostMapping("/discussion/{id}")
public ResponseEntity<Discussion> sendMessage(@RequestHeader("Authorization") String token, @PathVariable long id, @RequestBody Message msg){
User user = authServ.getUserFromToken(token);
if(user == null){
return new UnauthorizedResponse<>(null);
}
Discussion disc = discRepo.findById(id).orElse(null);
msg.setAuthor(user);
if(disc != null)
discServ.CreateMessage(disc, msg);
return new ResponseEntity<>(disc, HttpStatus.OK);
}
@PostMapping("/discussion")
public ResponseEntity<Discussion> createDiscussion(@RequestHeader("Authorization") String token, @RequestBody Discussion data){
return new ResponseEntity<>(discServ.create(data.getName(), authServ.getUserFromToken(token)), HttpStatus.OK);
}
}

View File

@ -1,6 +1,14 @@
package ovh.herisson.Clyde.EndPoints; package ovh.herisson.Clyde.EndPoints;
import ch.qos.logback.core.net.SyslogOutputStream; /******************************************************
* @file ScheduleController.java
* @author William Karpinski
* @scope Extension Horaire
*
* Controller of Schedule API
******************************************************/
import org.springframework.http.HttpStatus; import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
@ -37,7 +45,9 @@ public class ScheduleController {
this.curriculumServ = curriculumServ; this.curriculumServ = curriculumServ;
this.lessonServ = lessonServ; this.lessonServ = lessonServ;
} }
/**
* Return schedule via its id
*/
@GetMapping("/schedule/{id}") @GetMapping("/schedule/{id}")
public ResponseEntity<Map<String,Object>> findById(@PathVariable long id){ public ResponseEntity<Map<String,Object>> findById(@PathVariable long id){
Schedule schedule = scheduleServ.findById(id); Schedule schedule = scheduleServ.findById(id);
@ -47,17 +57,9 @@ public class ScheduleController {
return new ResponseEntity<>(scheduleLessonServ.getDepthScheduleBySchedule(schedule),HttpStatus.OK); return new ResponseEntity<>(scheduleLessonServ.getDepthScheduleBySchedule(schedule),HttpStatus.OK);
} }
/**
@GetMapping("/schedule") * Return a schedule via its curriculum id
public ResponseEntity<Map<String, Object>> findSelfSchedule(@RequestHeader("Authorization") String token){ */
if(authServ.getUserFromToken(token) == null)
return new UnauthorizedResponse<>(null);
Schedule schedule = scheduleLessonServ.getScheduleByCurriculum(userCurriculumService.findByUser(authServ.getUserFromToken(token)));
if(schedule == null)
return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
return new ResponseEntity<>(scheduleLessonServ.getDepthScheduleBySchedule(schedule),HttpStatus.OK);
}
@GetMapping("/schedule/curriculum/{id}") @GetMapping("/schedule/curriculum/{id}")
public ResponseEntity<Map<String, Object>> findCurriculumSchedule(@PathVariable Long id){ public ResponseEntity<Map<String, Object>> findCurriculumSchedule(@PathVariable Long id){
Schedule schedule = scheduleLessonServ.getScheduleByCurriculum(curriculumServ.findById(id)); Schedule schedule = scheduleLessonServ.getScheduleByCurriculum(curriculumServ.findById(id));
@ -65,12 +67,16 @@ public class ScheduleController {
return new ResponseEntity<>(HttpStatus.BAD_REQUEST); return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
return new ResponseEntity<>(scheduleLessonServ.getDepthScheduleBySchedule(schedule),HttpStatus.OK); return new ResponseEntity<>(scheduleLessonServ.getDepthScheduleBySchedule(schedule),HttpStatus.OK);
} }
/**
* Return all schedules
*/
@GetMapping("/schedules") @GetMapping("/schedules")
public ResponseEntity<Iterable<Map<String , Object>>> findAllSchedule(){ public ResponseEntity<Iterable<Map<String , Object>>> findAllSchedule(){
return new ResponseEntity<>(scheduleLessonServ.getAllSchedule(),HttpStatus.OK); return new ResponseEntity<>(scheduleLessonServ.getAllSchedule(),HttpStatus.OK);
} }
/**
* Post a new schedule
*/
@PostMapping("/schedule") @PostMapping("/schedule")
public ResponseEntity<Schedule> postSchedule(@RequestHeader("Authorization") String token, public ResponseEntity<Schedule> postSchedule(@RequestHeader("Authorization") String token,
@RequestBody Schedule schedule){ @RequestBody Schedule schedule){
@ -78,6 +84,9 @@ public class ScheduleController {
return new UnauthorizedResponse<>(null); return new UnauthorizedResponse<>(null);
return new ResponseEntity<>(scheduleServ.save(schedule),HttpStatus.OK); return new ResponseEntity<>(scheduleServ.save(schedule),HttpStatus.OK);
} }
/**
* Post a lesson to a schedule
*/
@PostMapping("/schedule/{id}") @PostMapping("/schedule/{id}")
public ResponseEntity<String> postLessonToSchedule(@RequestHeader("Authorization") String token, public ResponseEntity<String> postLessonToSchedule(@RequestHeader("Authorization") String token,
@RequestBody Long lessonId, @RequestBody Long lessonId,
@ -92,6 +101,9 @@ public class ScheduleController {
return new ResponseEntity<>(HttpStatus.OK); return new ResponseEntity<>(HttpStatus.OK);
} }
/**
* Delete a lesson from a schedule
*/
@DeleteMapping("/schedule/lesson/{id}") @DeleteMapping("/schedule/lesson/{id}")
public ResponseEntity<String> deleteLessonFromSchedule(@RequestHeader("Authorization") String token, public ResponseEntity<String> deleteLessonFromSchedule(@RequestHeader("Authorization") String token,
@RequestBody Long lessonId, @RequestBody Long lessonId,

View File

@ -1,37 +0,0 @@
package ovh.herisson.Clyde;
import javax.sql.DataSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.scheduling.annotation.EnableScheduling;
@Configuration
@EnableScheduling
public class JdbcConfig {
@Bean
@Profile("!prod")
public DataSource psqlSource(){
DriverManagerDataSource source = new DriverManagerDataSource();
source.setDriverClassName("org.postgresql.Driver");
source.setUrl("jdbc:postgresql://localhost:5442/clyde");
source.setUsername("devel");
source.setPassword("devel");
return source;
}
@Bean
@Profile("prod")
public DataSource psqlSourceProd(){
DriverManagerDataSource source = new DriverManagerDataSource();
source.setDriverClassName("org.postgresql.Driver");
source.setUrl("jdbc:postgresql:clyde?socketFactory=org.newsclub.net.unix.AFUNIXSocketFactory$FactoryArg&socketFactoryArg=/var/run/postgresql/.s.PGSQL.5432");
source.setUsername("clyde");
return source;
}
}

View File

@ -0,0 +1,9 @@
package ovh.herisson.Clyde.Repositories.Inscription;
import org.springframework.data.repository.CrudRepository;
import ovh.herisson.Clyde.Tables.ChangeCurriculumRequest;
public interface ChangeCurriculumRequestRepository extends CrudRepository<ChangeCurriculumRequest, Long> {
ChangeCurriculumRequest findById(long id);
}

View File

@ -0,0 +1,8 @@
package ovh.herisson.Clyde.Repositories.Inscription;
import org.springframework.data.repository.CrudRepository;
import ovh.herisson.Clyde.Tables.Inscription.ExemptionsRequest;
public interface ExemptionsRequestRepository extends CrudRepository<ExemptionsRequest, Long> {
ExemptionsRequest findById(long id);
}

View File

@ -0,0 +1,15 @@
package ovh.herisson.Clyde.Repositories.Inscription;
import org.springframework.data.repository.CrudRepository;
import ovh.herisson.Clyde.Tables.Inscription.ExternalCurriculum;
import ovh.herisson.Clyde.Tables.Inscription.InscriptionRequest;
import ovh.herisson.Clyde.Tables.User;
import java.util.ArrayList;
public interface ExternalCurriculumRepository extends CrudRepository<ExternalCurriculum, Long> {
ArrayList<ExternalCurriculum> getExternalCurriculumByInscriptionRequest(InscriptionRequest ir);
ArrayList<ExternalCurriculum> getExternalCurriculumByUser(User user);
ExternalCurriculum getExternalCurriculumById(long id);
}

View File

@ -1,7 +1,7 @@
package ovh.herisson.Clyde.Repositories; package ovh.herisson.Clyde.Repositories.Inscription;
import org.springframework.data.repository.CrudRepository; import org.springframework.data.repository.CrudRepository;
import ovh.herisson.Clyde.Tables.InscriptionRequest; import ovh.herisson.Clyde.Tables.Inscription.InscriptionRequest;
public interface InscriptionRepository extends CrudRepository<InscriptionRequest,Long> { public interface InscriptionRepository extends CrudRepository<InscriptionRequest,Long> {

View File

@ -0,0 +1,12 @@
package ovh.herisson.Clyde.Repositories.Inscription;
import org.springframework.data.repository.CrudRepository;
import ovh.herisson.Clyde.Tables.Inscription.Minerval;
import java.util.ArrayList;
public interface MinervalRepository extends CrudRepository<Minerval, Long> {
public ArrayList<Minerval> getMinervalsByStudentRegNoOrderByYearDesc(Long studentRegNo);
public Minerval findById(long id);
}

View File

@ -0,0 +1,10 @@
package ovh.herisson.Clyde.Repositories.Inscription;
import org.springframework.data.repository.CrudRepository;
import ovh.herisson.Clyde.Tables.Inscription.Payment;
import java.util.ArrayList;
public interface PaymentRepository extends CrudRepository<Payment, Long> {
public ArrayList<Payment> getPaymentsByStudentRegNo(long regNo);
}

View File

@ -0,0 +1,8 @@
package ovh.herisson.Clyde.Repositories.Inscription;
import org.springframework.data.repository.CrudRepository;
import ovh.herisson.Clyde.Tables.Inscription.ScholarshipRequest;
public interface ScholarshipRequestRepository extends CrudRepository<ScholarshipRequest, Long> {
public ScholarshipRequest findById(long id);
}

View File

@ -0,0 +1,8 @@
package ovh.herisson.Clyde.Repositories.Inscription;
import org.springframework.data.repository.CrudRepository;
import ovh.herisson.Clyde.Tables.Inscription.UnregisterRequest;
public interface UnregisterRequestRepository extends CrudRepository<UnregisterRequest, Long> {
public UnregisterRequest findById(long l);
}

View File

@ -1,5 +1,11 @@
package ovh.herisson.Clyde.Repositories; package ovh.herisson.Clyde.Repositories;
/******************************************************
* @file LessonChangesRequestRepository.java
* @author William Karpinski
* @scope Extension Horaire
******************************************************/
import org.springframework.data.jpa.repository.Query; import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.CrudRepository; import org.springframework.data.repository.CrudRepository;
import ovh.herisson.Clyde.Tables.LessonChangesRequest; import ovh.herisson.Clyde.Tables.LessonChangesRequest;

View File

@ -1,5 +1,11 @@
package ovh.herisson.Clyde.Repositories; package ovh.herisson.Clyde.Repositories;
/******************************************************
* @file LessonRepository.java
* @author William Karpinski
* @scope Extension Horaire
******************************************************/
import org.springframework.data.jpa.repository.Query; import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.CrudRepository; import org.springframework.data.repository.CrudRepository;
import ovh.herisson.Clyde.Tables.Course; import ovh.herisson.Clyde.Tables.Course;

View File

@ -0,0 +1,23 @@
package ovh.herisson.Clyde.Repositories.Msg;
/******************************************************
* @file DiscussionRepository.java
* @author Anthony Debucquoy
* @scope Extension messagerie
*
* Repository of Discussion allowing to fetch discussion by user
******************************************************/
import java.util.List;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.CrudRepository;
import ovh.herisson.Clyde.Tables.Msg.Discussion;
public interface DiscussionRepository extends CrudRepository<Discussion, Long>{
@Query("SELECT d FROM Discussion d INNER JOIN FETCH d.members dm WHERE dm.id = ?1")
List<Discussion> findByMembership(long userid);
}

View File

@ -0,0 +1,14 @@
package ovh.herisson.Clyde.Repositories.Msg;
/******************************************************
* @file MessageRepository.java
* @author Anthony Debucquoy
* @scope Extension messagerie
******************************************************/
import org.springframework.data.repository.CrudRepository;
import ovh.herisson.Clyde.Tables.Msg.Message;
public interface MessageRepository extends CrudRepository<Message, Long> {}

View File

@ -1,5 +1,10 @@
package ovh.herisson.Clyde.Repositories; package ovh.herisson.Clyde.Repositories;
/******************************************************
* @file ScheduleLessonRepository.java
* @author William Karpinski
* @scope Extension Horaire
******************************************************/
import jakarta.transaction.Transactional; import jakarta.transaction.Transactional;
import org.springframework.data.jpa.repository.Modifying; import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query; import org.springframework.data.jpa.repository.Query;
@ -14,18 +19,9 @@ public interface ScheduleLessonRepository extends CrudRepository<ScheduleLesson,
@Query("select distinct sl.lesson from ScheduleLesson sl where sl.schedule.curriculum = ?1") @Query("select distinct sl.lesson from ScheduleLesson sl where sl.schedule.curriculum = ?1")
Iterable<Lesson> findLessonByCurriculum(Curriculum curriculum); Iterable<Lesson> findLessonByCurriculum(Curriculum curriculum);
@Query("select distinct sl.schedule from ScheduleLesson sl")
Iterable<Schedule> findDistinctSchedule();
@Query("select distinct sl.schedule from ScheduleLesson sl where sl.schedule.curriculum = ?1") @Query("select distinct sl.schedule from ScheduleLesson sl where sl.schedule.curriculum = ?1")
Schedule findScheduleByCurriculum(Curriculum curriculum); Schedule findScheduleByCurriculum(Curriculum curriculum);
@Query("select distinct sl.lesson from ScheduleLesson sl where sl.schedule = ?1")
Iterable<Lesson> findLessonsBySchedule(Schedule schedule);
@Modifying @Modifying
@Transactional @Transactional
@Query("delete from ScheduleLesson sl where sl.lesson =?1") @Query("delete from ScheduleLesson sl where sl.lesson =?1")

View File

@ -1,5 +1,11 @@
package ovh.herisson.Clyde.Repositories; package ovh.herisson.Clyde.Repositories;
/******************************************************
* @file ScheduleRepository.java
* @author William Karpinski
* @scope Extension Horaire
******************************************************/
import org.springframework.data.jpa.repository.Query; import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.CrudRepository; import org.springframework.data.repository.CrudRepository;
import ovh.herisson.Clyde.Tables.Course; import ovh.herisson.Clyde.Tables.Course;

View File

@ -6,8 +6,14 @@ import ovh.herisson.Clyde.Tables.Curriculum;
import ovh.herisson.Clyde.Tables.User; import ovh.herisson.Clyde.Tables.User;
import ovh.herisson.Clyde.Tables.UserCurriculum; import ovh.herisson.Clyde.Tables.UserCurriculum;
import java.util.ArrayList;
public interface UserCurriculumRepository extends CrudRepository<UserCurriculum, Long> { public interface UserCurriculumRepository extends CrudRepository<UserCurriculum, Long> {
@Query("select uc.curriculum from UserCurriculum uc where uc.user = ?1") @Query("select uc.curriculum from UserCurriculum uc where uc.user = ?1")
Curriculum findByUser(User student); Curriculum findByUser(User student);
ArrayList<UserCurriculum> findByUserOrderByCurriculum(User student);
UserCurriculum findByUserAndCurriculumAndActual(User user, Curriculum curriculum, boolean actual);
} }

View File

@ -1,7 +1,10 @@
package ovh.herisson.Clyde.Services; package ovh.herisson.Clyde.Services;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import ovh.herisson.Clyde.Services.Inscription.InscriptionService;
import ovh.herisson.Clyde.Tables.*; import ovh.herisson.Clyde.Tables.*;
import ovh.herisson.Clyde.Tables.Inscription.InscriptionRequest;
import java.util.Date; import java.util.Date;
@Service @Service

View File

@ -46,7 +46,7 @@ public class CurriculumCourseService {
toReturn.put("curriculumId", curriculum.getCurriculumId()); toReturn.put("curriculumId", curriculum.getCurriculumId());
toReturn.put("year", curriculum.getYear()); toReturn.put("year", curriculum.getYear());
toReturn.put("option", curriculum.getOption()); toReturn.put("option", curriculum.getOption());
toReturn.put("requireCertificate", curriculum.isRequireCertificate());
return toReturn; return toReturn;
} }

View File

@ -18,7 +18,6 @@ public class CurriculumService {
public Curriculum findById(long id){ public Curriculum findById(long id){
return curriculumRepo.findById(id); return curriculumRepo.findById(id);
} }
public void delete(Curriculum curriculum) { public void delete(Curriculum curriculum) {
curriculumRepo.delete(curriculum); curriculumRepo.delete(curriculum);
} }

View File

@ -0,0 +1,109 @@
package ovh.herisson.Clyde.Services.Inscription;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import ovh.herisson.Clyde.Repositories.*;
import ovh.herisson.Clyde.Repositories.Inscription.ExternalCurriculumRepository;
import ovh.herisson.Clyde.Repositories.Inscription.InscriptionRepository;
import ovh.herisson.Clyde.Repositories.Inscription.MinervalRepository;
import ovh.herisson.Clyde.Services.UserService;
import ovh.herisson.Clyde.Tables.*;
import ovh.herisson.Clyde.Tables.Inscription.ExternalCurriculum;
import ovh.herisson.Clyde.Tables.Inscription.InscriptionRequest;
import ovh.herisson.Clyde.Tables.Inscription.Minerval;
import java.util.ArrayList;
import java.util.Calendar;
@Service
public class InscriptionService {
private final InscriptionRepository inscriptionRepo;
private final UserRepository userRepo;
private final UserCurriculumRepository userCurriculumRepo;
private final CurriculumRepository curriculumRepo;
private final MinervalRepository minervalRepository;
private final BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
private final ExternalCurriculumRepository externalCurriculumRepository;
private final UserService userService;
public InscriptionService(InscriptionRepository inscriptionRepo, UserRepository userRepo, UserCurriculumRepository userCurriculumRepo, CurriculumRepository curriculumRepo, MinervalRepository minervalRepository, ExternalCurriculumRepository externalCurriculumRepository, UserService userService){
this.inscriptionRepo = inscriptionRepo;
this.userRepo = userRepo;
this.userCurriculumRepo = userCurriculumRepo;
this.curriculumRepo = curriculumRepo;
this.minervalRepository = minervalRepository;
this.externalCurriculumRepository = externalCurriculumRepository;
this.userService = userService;
}
public InscriptionRequest save(InscriptionRequest inscriptionRequest){
inscriptionRequest.setPassword(passwordEncoder.encode(inscriptionRequest.getPassword()));
return inscriptionRepo.save(inscriptionRequest);
}
public InscriptionRequest getById(long id){
return inscriptionRepo.findById(id);
}
public Iterable<InscriptionRequest> getAll(){
return inscriptionRepo.findAll();
}
public boolean modifyState(long id, RequestState requestState) {
InscriptionRequest inscrRequest = getById(id);
if (inscrRequest == null)
return false;
inscrRequest.setState(requestState);
save(inscrRequest);
//saves the user from the request if accepted from teacher and inscription services
if (requestState == RequestState.Accepted && (inscrRequest.getEquivalenceState() == RequestState.Accepted || inscrRequest.getEquivalenceState() == RequestState.Unrequired))
{
return createUser(inscrRequest);
}
return true;
}
public boolean createUser(InscriptionRequest inscrRequest){
//We must send an email here
if (curriculumRepo.findById(inscrRequest.getCurriculumId()) == null)
return false;
User userFromRequest = new User(
inscrRequest.getLastName(),
inscrRequest.getFirstName(),
inscrRequest.getEmail(),
inscrRequest.getAddress(),
inscrRequest.getCountry(),
inscrRequest.getBirthDate(),
inscrRequest.getProfilePicture(),
inscrRequest.getPassword()
);
userService.save(userFromRequest);
Calendar c = Calendar.getInstance();
userCurriculumRepo.save(new UserCurriculum(userFromRequest, curriculumRepo.findById(inscrRequest.getCurriculumId()),c.get(Calendar.YEAR), true));
//Create a minerval for the new student
Minerval minerval = new Minerval(userFromRequest.getRegNo(), 0, 852, 2023);
minervalRepository.save(minerval);
//Assign the externals curriculums from the inscription request to newly created student
ArrayList<ExternalCurriculum> extCurrList = externalCurriculumRepository.getExternalCurriculumByInscriptionRequest(inscrRequest);
for (int i = 0; i < extCurrList.size(); i++){
extCurrList.get(i).setUser(userFromRequest);
externalCurriculumRepository.save(extCurrList.get(i));
}
return true;
}
public void delete(InscriptionRequest toDelete) {
inscriptionRepo.delete(toDelete);
}
}

View File

@ -1,94 +0,0 @@
package ovh.herisson.Clyde.Services;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import ovh.herisson.Clyde.Repositories.CurriculumRepository;
import ovh.herisson.Clyde.Repositories.InscriptionRepository;
import ovh.herisson.Clyde.Repositories.UserCurriculumRepository;
import ovh.herisson.Clyde.Repositories.UserRepository;
import ovh.herisson.Clyde.Tables.InscriptionRequest;
import ovh.herisson.Clyde.Tables.RequestState;
import ovh.herisson.Clyde.Tables.User;
import ovh.herisson.Clyde.Tables.UserCurriculum;
@Service
public class InscriptionService {
private final InscriptionRepository inscriptionRepo;
private final UserRepository userRepo;
private final UserCurriculumRepository userCurriculumRepo;
private final CurriculumRepository curriculumRepo;
private final BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
public InscriptionService(InscriptionRepository inscriptionRepo, UserRepository userRepo, UserCurriculumRepository userCurriculumRepo, CurriculumRepository curriculumRepo){
this.inscriptionRepo = inscriptionRepo;
this.userRepo = userRepo;
this.userCurriculumRepo = userCurriculumRepo;
this.curriculumRepo = curriculumRepo;
}
public InscriptionRequest save(InscriptionRequest inscriptionRequest){
inscriptionRequest.setPassword(passwordEncoder.encode(inscriptionRequest.getPassword()));
return inscriptionRepo.save(inscriptionRequest);
}
public InscriptionRequest getById(long id){
return inscriptionRepo.findById(id);
}
public Iterable<InscriptionRequest> getAll(){
return inscriptionRepo.findAll();
}
public boolean modifyState(long id, RequestState requestState) {
InscriptionRequest inscrRequest = getById(id);
if (inscrRequest == null)
return false;
// if th state is the same we don't send an email
if (requestState == inscrRequest.getState())
return false;
/** todo send an email to tell the poster of the inscrRequest (inscrRequest.getEmail())
* to notify them that the state of their request changed
* FooEmailFormat toSend = (String.format("Your request state changed from %s to %s"),
* inscrRequest.getState(), requestState)
* FooEmailSender.send(toSend, inscrRequest.getEmail())
*/
//saves the user from the request if accepted
if (requestState == RequestState.Accepted)
{
if (curriculumRepo.findById(inscrRequest.getCurriculumId()) == null)
return false;
User userFromRequest = new User(
inscrRequest.getLastName(),
inscrRequest.getFirstName(),
inscrRequest.getEmail(),
inscrRequest.getAddress(),
inscrRequest.getCountry(),
inscrRequest.getBirthDate(),
inscrRequest.getProfilePicture(),
inscrRequest.getPassword()
);
userRepo.save(userFromRequest);
userCurriculumRepo.save(new UserCurriculum(userFromRequest, curriculumRepo.findById(inscrRequest.getCurriculumId())));
}
inscrRequest.setState(requestState);
save(inscrRequest);
return true;
}
public void delete(InscriptionRequest toDelete) {
inscriptionRepo.delete(toDelete);
}
}

View File

@ -1,5 +1,10 @@
package ovh.herisson.Clyde.Services; package ovh.herisson.Clyde.Services;
/******************************************************
* @file LeessonRequestService.java
* @author William Karpinski
* @scope Extension Horaire
******************************************************/
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import ovh.herisson.Clyde.Repositories.*; import ovh.herisson.Clyde.Repositories.*;
import ovh.herisson.Clyde.Tables.*; import ovh.herisson.Clyde.Tables.*;
@ -40,17 +45,31 @@ public class LessonRequestService {
this.userServ = userServ; this.userServ = userServ;
this.courseRepository = courseRepository; this.courseRepository = courseRepository;
} }
public Iterable<LessonChangesRequest> findOwnRequests(User user){
return lessonChangesRepo.findOwnRequests(user); /**
} * Create a new lesson request
*/
public LessonChangesRequest save(LessonChangesRequest lessonRequest){ public LessonChangesRequest save(LessonChangesRequest lessonRequest){
return lessonChangesRepo.save(lessonRequest); return lessonChangesRepo.save(lessonRequest);
} }
/**
* Find all the requests made by a user
*/
public Iterable<LessonChangesRequest> findOwnRequests(User user){
return lessonChangesRepo.findOwnRequests(user);
}
public LessonChangesRequest findById(long id){ public LessonChangesRequest findById(long id){
return lessonChangesRepo.findById(id); return lessonChangesRepo.findById(id);
} }
/**
* Return all the requests
*/
public Iterable<LessonChangesRequest> getAll(){return lessonChangesRepo.findAll();} public Iterable<LessonChangesRequest> getAll(){return lessonChangesRepo.findAll();}
/**
* Create a lesson if a request is accepted
*/
public boolean modifyCreateRequestState(LessonChangesRequest lessonRequest, RequestState state, String local ){ public boolean modifyCreateRequestState(LessonChangesRequest lessonRequest, RequestState state, String local ){
if(lessonRequest == null || state == lessonRequest.getState() || state == null){ if(lessonRequest == null || state == lessonRequest.getState() || state == null){
return false;} return false;}
@ -78,23 +97,31 @@ public class LessonRequestService {
return lessonChangesRepo.findRequestByLessonId(id); return lessonChangesRepo.findRequestByLessonId(id);
} }
/**
* Refuse all the lesson request that depends on a certain lesson
* Used after the deletion of the lesson
*/
public void refuseAllByLessonId(long id){ public void refuseAllByLessonId(long id){
Iterable<LessonChangesRequest> toRefuse = findRequestByLessonId(id); Iterable<LessonChangesRequest> toRefuse = findRequestByLessonId(id);
for(LessonChangesRequest element : toRefuse) for(LessonChangesRequest element : toRefuse)
element.setState(RequestState.Refused); element.setState(RequestState.Refused);
} }
/**
* Modify a lesson if a request is accepted
*/
public boolean modifyChangeRequestState(Map<String, Object> updates, long lessonId,RequestState state){ public boolean modifyChangeRequestState(Map<String, Object> updates, long lessonId,RequestState state){
if(state == RequestState.Accepted){ if(state == RequestState.Accepted){
Lesson lesson = lessonServ.findById(lessonId); Lesson lesson = lessonServ.findById(lessonId);
return lessonServ.modifyData(lesson.getLessonID(),updates); return lessonServ.modifyData(lesson.getLessonID(),updates);
} }
return true; return true;
} }
/**
* Delete a lesson if a request is accepted
*/
public void modifyDeleteRequest(LessonChangesRequest lessonChangesRequest, RequestState state){ public void modifyDeleteRequest(LessonChangesRequest lessonChangesRequest, RequestState state){
if(state == RequestState.Accepted){ if(state == RequestState.Accepted){
lessonServ.delete(lessonServ.findById(lessonChangesRequest.getLessonId())); lessonServ.delete(lessonServ.findById(lessonChangesRequest.getLessonId()));
@ -102,6 +129,9 @@ public class LessonRequestService {
} }
} }
/**
* Construct a lesson request
*/
public LessonChangesRequest createLessonRequest(Map<String,Object> lessonInfos) { public LessonChangesRequest createLessonRequest(Map<String,Object> lessonInfos) {
LessonChangesRequest target = new LessonChangesRequest(); LessonChangesRequest target = new LessonChangesRequest();
@ -141,9 +171,6 @@ public class LessonRequestService {
return target; return target;
} }
public void delete (LessonChangesRequest toDelete) { public void delete (LessonChangesRequest toDelete) {
lessonChangesRepo.delete(toDelete); lessonChangesRepo.delete(toDelete);
} }

View File

@ -1,44 +1,86 @@
package ovh.herisson.Clyde.Services; package ovh.herisson.Clyde.Services;
/******************************************************
* @file LessonService.java
* @author William Karpinski
* @scope Extension Horaire
******************************************************/
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import ovh.herisson.Clyde.Repositories.CourseRepository; import ovh.herisson.Clyde.Repositories.CourseRepository;
import ovh.herisson.Clyde.Repositories.CurriculumCourseRepository;
import ovh.herisson.Clyde.Repositories.LessonRepository; import ovh.herisson.Clyde.Repositories.LessonRepository;
import ovh.herisson.Clyde.Tables.Course; import ovh.herisson.Clyde.Repositories.UserCurriculumRepository;
import ovh.herisson.Clyde.Tables.Lesson; import ovh.herisson.Clyde.Tables.*;
import ovh.herisson.Clyde.Tables.Role;
import ovh.herisson.Clyde.Tables.User;
import java.lang.reflect.GenericSignatureFormatError;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Map; import java.util.Map;
@Service @Service
public class LessonService { public class LessonService {
private final LessonRepository lessonRepo; private final LessonRepository lessonRepo;
private final UserCurriculumRepository userCurriculumRepo;
private final CourseRepository courseRepo; private final CourseRepository courseRepo;
public LessonService(LessonRepository lessonRepo, CourseRepository courseRepo){
private final CurriculumCourseRepository curriculumCourseRepo;
public LessonService(LessonRepository lessonRepo, UserCurriculumRepository userCurriculumRepo, CourseRepository courseRepo, CurriculumCourseRepository curriculumCourseRepo){
this.lessonRepo = lessonRepo; this.lessonRepo = lessonRepo;
this.userCurriculumRepo = userCurriculumRepo;
this.courseRepo = courseRepo; this.courseRepo = courseRepo;
this.curriculumCourseRepo = curriculumCourseRepo;
} }
/**
* Create a lesson
*/
public Lesson save(Lesson lesson){ public Lesson save(Lesson lesson){
return lessonRepo.save(lesson); return lessonRepo.save(lesson);
} }
/**
* Find a lesson by its id
*/
public Lesson findById(long id){ public Lesson findById(long id){
return lessonRepo.findById(id); return lessonRepo.findById(id);
} }
/**
* Return all the lessons
*/
public Iterable<Lesson> findAll(){return lessonRepo.findAll();} public Iterable<Lesson> findAll(){return lessonRepo.findAll();}
/**
* Return all a teacher's lessons
*/
public Iterable<Lesson> findAllOwnedLesson(User teacher){ public Iterable<Lesson> findAllOwnedLesson(User teacher){
ArrayList<Lesson> toReturn = new ArrayList<>(); ArrayList<Lesson> toReturn = new ArrayList<>();
ArrayList<Course> coursesOwned = (ArrayList<Course>) courseRepo.findAllOwnedCoures(teacher); ArrayList<Course> coursesOwned = (ArrayList<Course>) courseRepo.findAllOwnedCoures(teacher);
for (Course element : coursesOwned) { for (Course element : coursesOwned) {
for(Lesson lesson : lessonRepo.findLessonByCourse(element)) for(Lesson lesson : lessonRepo.findLessonByCourse(element))
toReturn.add(lesson); toReturn.add(lesson);
} }
return toReturn; return toReturn;
} }
/**
* Return all a student's lessons
*/
public Iterable<Lesson> findOnesLessons(User student){
ArrayList<Lesson> toReturn = new ArrayList<>();
ArrayList<Course> courses = new ArrayList<>();
ArrayList<UserCurriculum> userCurriculums = userCurriculumRepo.findByUserOrderByCurriculum(student);
for(UserCurriculum uc: userCurriculums){
Curriculum c = uc.getCurriculum();
if(uc.isActual())
courses.addAll((ArrayList<Course>) curriculumCourseRepo.findCoursesByCurriculum(c));
}
for (Course element : courses) {
for(Lesson lesson : lessonRepo.findLessonByCourse(element))
toReturn.add(lesson);
}
return toReturn;
}
/**
* Construct a new lesson
*/
public Lesson createLesson(Map<String,Object> lessonInfos) { public Lesson createLesson(Map<String,Object> lessonInfos) {
Lesson target = new Lesson(); Lesson target = new Lesson();
@ -66,7 +108,9 @@ public class LessonService {
} }
return target; return target;
} }
/**
* Modify a lesson
*/
public boolean modifyData(long id, Map<String ,Object> updates){ public boolean modifyData(long id, Map<String ,Object> updates){
Lesson target = lessonRepo.findById(id); Lesson target = lessonRepo.findById(id);
@ -92,7 +136,9 @@ public class LessonService {
lessonRepo.save(target); lessonRepo.save(target);
return true; return true;
} }
/**
* Delete a lesson
*/
public void delete(Lesson lesson){ public void delete(Lesson lesson){
lessonRepo.delete(lesson); lessonRepo.delete(lesson);
} }

View File

@ -0,0 +1,57 @@
package ovh.herisson.Clyde.Services.Msg;
import java.util.List;
/******************************************************
* @file DiscussionService.java
* @author Anthony Debucquoy
* @scope Extension messagerie
*
* Various function utilised by the messages application
******************************************************/
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.fasterxml.jackson.databind.util.JSONPObject;
import ovh.herisson.Clyde.Repositories.Msg.DiscussionRepository;
import ovh.herisson.Clyde.Tables.User;
import ovh.herisson.Clyde.Tables.Msg.Discussion;
import ovh.herisson.Clyde.Tables.Msg.Message;
@Service
public class DiscussionService {
@Autowired
private DiscussionRepository discRepo;
public Discussion create(String name, User author){
return discRepo.save(new Discussion(name, author));
}
/**
* list discussions owned by a certain user
*/
public Iterable<Discussion> getOwned(User author){
return discRepo.findByMembership(author.getRegNo());
}
/**
* Create a message and link it to it's discussion
*/
public Discussion CreateMessage(Discussion disc, Message msg){
disc.addMessage(msg);
return discRepo.save(disc);
}
/**
* Check if a user is in a discussion
*/
public boolean hasDiscussion(User user, long id) {
Discussion disc = discRepo.findById(id).orElse(null);
List<User> members = disc.getMembers();
return members.contains(user);
}
}

View File

@ -1,6 +1,7 @@
package ovh.herisson.Clyde.Services; package ovh.herisson.Clyde.Services;
import ovh.herisson.Clyde.Tables.*; import ovh.herisson.Clyde.Tables.*;
import ovh.herisson.Clyde.Tables.Inscription.InscriptionRequest;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
@ -112,7 +113,9 @@ public class ProtectionService {
toReturn.put("curriculum", inscriptionRequest.getCurriculumId()); toReturn.put("curriculum", inscriptionRequest.getCurriculumId());
toReturn.put("state", inscriptionRequest.getState()); toReturn.put("state", inscriptionRequest.getState());
toReturn.put("profilePictureUrl", inscriptionRequest.getProfilePicture()); toReturn.put("profilePictureUrl", inscriptionRequest.getProfilePicture());
toReturn.put("identityCard", inscriptionRequest.getIdentityCard());
toReturn.put("submissionDate", inscriptionRequest.getSubmissionDate());
toReturn.put("equivalenceState", inscriptionRequest.getEquivalenceState());
return toReturn; return toReturn;
} }

View File

@ -1,5 +1,10 @@
package ovh.herisson.Clyde.Services; package ovh.herisson.Clyde.Services;
/******************************************************
* @file ScheduleLessonService.java
* @author William Karpinski
* @scope Extension Horaire
******************************************************/
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import ovh.herisson.Clyde.Repositories.LessonRepository; import ovh.herisson.Clyde.Repositories.LessonRepository;
import ovh.herisson.Clyde.Repositories.ScheduleLessonRepository; import ovh.herisson.Clyde.Repositories.ScheduleLessonRepository;
@ -23,14 +28,15 @@ public class ScheduleLessonService {
this.lessonRepo = lessonRepo; this.lessonRepo = lessonRepo;
this.scheduleRepo = scheduleRepo; this.scheduleRepo = scheduleRepo;
} }
public boolean save(ScheduleLesson scheduleLesson){ public boolean save(ScheduleLesson scheduleLesson){
if(scheduleLesson == null) if(scheduleLesson == null)
return false; return false;
scheduleLessonRepo.save(scheduleLesson); scheduleLessonRepo.save(scheduleLesson);
return true; return true;
} }
/**
* Save a lesson to all the schedule it is linked
*/
public boolean saveToAllSchedule(Lesson lesson){ public boolean saveToAllSchedule(Lesson lesson){
Iterable<Schedule> schedules = scheduleRepo.findAllLessonSchedule(lesson.getCourse()); Iterable<Schedule> schedules = scheduleRepo.findAllLessonSchedule(lesson.getCourse());
if(schedules == null) if(schedules == null)
@ -40,7 +46,9 @@ public class ScheduleLessonService {
} }
return true; return true;
} }
/**
* Delete a scheduleLesson via its lesson
*/
public boolean delete(long lessonId){ public boolean delete(long lessonId){
if(lessonId == 0) if(lessonId == 0)
return false; return false;
@ -48,28 +56,12 @@ public class ScheduleLessonService {
return true; return true;
} }
public Schedule getScheduleByCurriculum(Curriculum curriculum){ public Schedule getScheduleByCurriculum(Curriculum curriculum){
return scheduleLessonRepo.findScheduleByCurriculum(curriculum); return scheduleLessonRepo.findScheduleByCurriculum(curriculum);
} }
/**
public Map<String , Object> getDepthScheduleByCurriculum(Curriculum curriculum){ * Return a schedule and the list of lessons that corresponds
if(curriculum == null) */
return null;
HashMap<String , Object> toReturn = new HashMap<>();
ArrayList<Map<String, Object>> lessons = new ArrayList<>();
Iterable<Lesson> foundLessons = scheduleLessonRepo.findLessonByCurriculum(curriculum);
for (Lesson l: foundLessons){
lessons.add(ProtectionService.lessonWithoutPassword(l));
}
toReturn.put("lessons",lessons);
toReturn.put("scheduleId" , scheduleLessonRepo.findScheduleByCurriculum(curriculum).getScheduleID());
toReturn.put("curriculum", curriculum);
return toReturn;
}
public Map<String , Object> getDepthScheduleBySchedule(Schedule schedule){ public Map<String , Object> getDepthScheduleBySchedule(Schedule schedule){
if(schedule == null) if(schedule == null)
return null; return null;
@ -86,7 +78,9 @@ public class ScheduleLessonService {
toReturn.put("curriculum", schedule.getCurriculum()); toReturn.put("curriculum", schedule.getCurriculum());
return toReturn; return toReturn;
} }
/**
* Return all the schedules
*/
public Iterable<Map<String,Object>> getAllSchedule(){ public Iterable<Map<String,Object>> getAllSchedule(){
ArrayList<Map<String,Object>> toReturn = new ArrayList<>(); ArrayList<Map<String,Object>> toReturn = new ArrayList<>();

View File

@ -1,20 +1,53 @@
package ovh.herisson.Clyde.Services; package ovh.herisson.Clyde.Services;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import ovh.herisson.Clyde.Repositories.CurriculumRepository;
import ovh.herisson.Clyde.Repositories.Inscription.ExternalCurriculumRepository;
import ovh.herisson.Clyde.Repositories.UserCurriculumRepository; import ovh.herisson.Clyde.Repositories.UserCurriculumRepository;
import ovh.herisson.Clyde.Tables.Curriculum; import ovh.herisson.Clyde.Tables.*;
import ovh.herisson.Clyde.Tables.User;
import java.util.ArrayList;
import java.util.HashMap;
@Service @Service
public class UserCurriculumService { public class UserCurriculumService {
private final UserCurriculumRepository userCurriculumRepository; private final UserCurriculumRepository userCurriculumRepository;
private final CurriculumRepository curriculumRepo;
public UserCurriculumService(UserCurriculumRepository userCurriculumRepository) { private final ExternalCurriculumRepository externalCurriculumRepo;
public UserCurriculumService(UserCurriculumRepository userCurriculumRepository, CurriculumRepository curriculumRepo, ExternalCurriculumRepository externalCurriculumRepo) {
this.userCurriculumRepository = userCurriculumRepository; this.userCurriculumRepository = userCurriculumRepository;
this.curriculumRepo = curriculumRepo;
this.externalCurriculumRepo = externalCurriculumRepo;
} }
public Curriculum findByUser(User student){ public Curriculum findByUser(User student){
return userCurriculumRepository.findByUser(student); return userCurriculumRepository.findByUser(student);
} }
public HashMap<String,Object> findAllCurriculumByStudent(User student) {
ArrayList<UserCurriculum> list = userCurriculumRepository.findByUserOrderByCurriculum(student);
ArrayList<HashMap<String, Object>> curriculumlist = new ArrayList<HashMap<String, Object>>();
for (int i = 0; i < list.size(); i++) {
HashMap<String, Object> element = new HashMap<>();
Curriculum c = list.get(i).getCurriculum();
element.put("curriculumId", c.getCurriculumId());
element.put("year", c.getYear());
element.put("option", c.getOption());
element.put("dateyear", list.get(i).getYear());
element.put("actual", list.get(i).isActual());
curriculumlist.add(element);
}
HashMap<String, Object> toReturn = new HashMap<String, Object>();
toReturn.put("curriculumList", curriculumlist);
return toReturn;
}
} }

View File

@ -2,6 +2,7 @@ package ovh.herisson.Clyde.Services;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import ovh.herisson.Clyde.Tables.RegNoGenerator;
import ovh.herisson.Clyde.Repositories.UserRepository; import ovh.herisson.Clyde.Repositories.UserRepository;
import ovh.herisson.Clyde.Tables.Role; import ovh.herisson.Clyde.Tables.Role;
import ovh.herisson.Clyde.Tables.User; import ovh.herisson.Clyde.Tables.User;
@ -106,10 +107,17 @@ public class UserService {
} }
public User save(User user){ public User save(User user){
RegNoGenerator.resetCount();
user.setPassword(passwordEncoder.encode(user.getPassword())); user.setPassword(passwordEncoder.encode(user.getPassword()));
return userRepo.save(user); return userRepo.save(user);
} }
public void saveAll(ArrayList<User> list){
//S'assure que le compteur est bien a 0
RegNoGenerator.resetCount();
userRepo.saveAll(list);
}
public Iterable<User> getAll(){ public Iterable<User> getAll(){
return userRepo.findAll(); return userRepo.findAll();
} }

View File

@ -26,6 +26,7 @@ public enum Applications {
LessonRequests, LessonRequests,
// InscriptionService authorization // InscriptionService authorization
Inscription, Requests,
StudentsList StudentsList,
Payments
} }

View File

@ -0,0 +1,95 @@
package ovh.herisson.Clyde.Tables;
import jakarta.persistence.*;
import java.util.Date;
@Entity
public class ChangeCurriculumRequest {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private int id;
@ManyToOne
@JoinColumn(name="Users")
private User user;
@ManyToOne
@JoinColumn(name = "ActualCurriculum")
private Curriculum actualCurriculum;
@ManyToOne
@JoinColumn(name = "DestCurriculum")
private Curriculum destinationCurriculum;
private Date date;
private RequestState state;
private RequestState teacherApprovalState;
public ChangeCurriculumRequest(){}
public ChangeCurriculumRequest(User user, Curriculum actualCurriculum, Curriculum destinationCurriculum, Date date, RequestState state, RequestState teacherApprovalState){
this.user = user;
this.actualCurriculum = actualCurriculum;
this.destinationCurriculum = destinationCurriculum;
this.date = date;
this.state = state;
this.teacherApprovalState = teacherApprovalState;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
public Curriculum getActualCurriculum() {
return actualCurriculum;
}
public void setActualCurriculum(Curriculum actualCurriculum) {
this.actualCurriculum = actualCurriculum;
}
public Curriculum getDestinationCurriculum() {
return destinationCurriculum;
}
public void setDestinationCurriculum(Curriculum destinationCurriculum) {
this.destinationCurriculum = destinationCurriculum;
}
public void setDate(Date date) {
this.date = date;
}
public Date getDate() {
return date;
}
public RequestState getState() {
return state;
}
public void setState(RequestState state) {
this.state = state;
}
public int getId() {
return id;
}
public RequestState getTeacherApprovalState() {
return teacherApprovalState;
}
public void setTeacherApprovalState(RequestState teacherApprovalState) {
this.teacherApprovalState = teacherApprovalState;
}
}

View File

@ -12,9 +12,13 @@ public class Curriculum {
private int curriculumId; private int curriculumId;
private int year; private int year;
private String option; private String option;
public Curriculum(int year, String option){
//True if the curriculum need an entry exam
private boolean requireCertificate;
public Curriculum(int year, String option, boolean requireCertificate){
this.year = year; this.year = year;
this.option = option; this.option = option;
this.requireCertificate = requireCertificate;
} }
public Curriculum() {} public Curriculum() {}
@ -39,4 +43,11 @@ public class Curriculum {
this.option = option; this.option = option;
} }
public void setRequireCertificate(boolean requireCertificate) {
this.requireCertificate = requireCertificate;
}
public boolean isRequireCertificate() {
return requireCertificate;
}
} }

View File

@ -1,8 +1,8 @@
package ovh.herisson.Clyde.Tables; package ovh.herisson.Clyde.Tables;
public enum FileType { public enum FileType {
ProfilePicture, ProfilePicture,
EducationCertificate,
EducationCertificate JustificationDocument,
IdentityCard,
} }

View File

@ -0,0 +1,87 @@
package ovh.herisson.Clyde.Tables.Inscription;
import jakarta.persistence.*;
import org.hibernate.annotations.OnDelete;
import org.hibernate.annotations.OnDeleteAction;
import ovh.herisson.Clyde.Tables.Course;
import ovh.herisson.Clyde.Tables.RequestState;
import ovh.herisson.Clyde.Tables.User;
import java.util.Date;
@Entity
public class ExemptionsRequest {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private int id;
@JoinColumn(name = "Users")
@ManyToOne(fetch = FetchType.EAGER)
private User user;
@JoinColumn(name = "Course")
@ManyToOne(fetch = FetchType.EAGER)
private Course course;
private String justifDocument;
private RequestState state;
private Date date;
public ExemptionsRequest(User user, Course course, String justifDocument, RequestState state, Date date){
this.user = user;
this.course = course;
this.justifDocument = justifDocument;
this.state = state;
this.date = date;
}
public ExemptionsRequest(){}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
public Course getCourse() {
return course;
}
public void setCourse(Course course) {
this.course = course;
}
public String getJustifDocument() {
return justifDocument;
}
public void setJustifDocument(String justifDocument) {
this.justifDocument = justifDocument;
}
public RequestState getState() {
return state;
}
public void setState(RequestState state) {
this.state = state;
}
public Date getDate() {
return date;
}
public void setDate(Date date) {
this.date = date;
}
public int getId() {
return id;
}
}

View File

@ -0,0 +1,114 @@
package ovh.herisson.Clyde.Tables.Inscription;
import jakarta.persistence.*;
import ovh.herisson.Clyde.Tables.User;
//This table stores a student's curriculum from another university
@Entity
public class ExternalCurriculum {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private int id;
//An external curriculum is first linked to an inscription request and when it is accepted and the user is created we link it to the user
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name="InscriptionRequest")
private InscriptionRequest inscriptionRequest;
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name="Users")
private User user;
private String school;
private String formation;
//This string denotes the completion of the external formation or the last year completed by the student in this formation
private String completion;
private int startYear;
private int endYear;
private String justifdocUrl;
public ExternalCurriculum(){}
public ExternalCurriculum(InscriptionRequest ir, String school, String formation, String completion, int startYear, int endYear, String justifdocUrl,User user){
this.inscriptionRequest = ir;
this.school = school;
this.formation = formation;
this.completion = completion;
this.startYear = startYear;
this.endYear = endYear;
this.justifdocUrl = justifdocUrl;
this.user = user;
}
public int getId() {
return id;
}
public InscriptionRequest getInscriptionRequest() {
return inscriptionRequest;
}
public void setInscriptionRequest(InscriptionRequest inscriptionRequest) {
this.inscriptionRequest = inscriptionRequest;
}
public String getSchool() {
return school;
}
public void setSchool(String school) {
this.school = school;
}
public String getFormation() {
return formation;
}
public void setFormation(String formation) {
this.formation = formation;
}
public String getCompletion(){
return completion;
}
public void setCompletion(String completion) {
this.completion = completion;
}
public int getStartYear() {
return startYear;
}
public void setStartYear(int startYear) {
this.startYear = startYear;
}
public int getEndYear() {
return endYear;
}
public void setEndYear(int endYear) {
this.endYear = endYear;
}
public void setJustifdocUrl(String justifdocUrl) {
this.justifdocUrl = justifdocUrl;
}
public String getJustifdocUrl() {
return justifdocUrl;
}
public void setUser(User user) {
this.user = user;
}
public User getUser() {
return user;
}
}

View File

@ -1,6 +1,8 @@
package ovh.herisson.Clyde.Tables; package ovh.herisson.Clyde.Tables.Inscription;
import jakarta.persistence.*; import jakarta.persistence.*;
import ovh.herisson.Clyde.Tables.RequestState;
import java.util.Date; import java.util.Date;
@ -15,14 +17,17 @@ public class InscriptionRequest {
private String email; private String email;
private String country; private String country;
private Date birthDate; private Date birthDate;
private Long curriculumId; private Long curriculumId;
private RequestState state; private RequestState state;
private String profilePicture; private String profilePicture;
private String password; private String password;
private String identityCard;
private String admissionDocUrl;
private Date submissionDate;
private RequestState equivalenceState;
public InscriptionRequest(){} public InscriptionRequest(){}
public InscriptionRequest(String lastName, String firstName, String address, String email, String country, Date birthDate,Long curriculumId, RequestState state, String profilePicture, String password){
public InscriptionRequest(String lastName, String firstName, String address, String email, String country, Date birthDate,Long curriculumId, RequestState state, String profilePicture, String password, String identityCard, Date submissionDate, RequestState equivalenceState, String admissionDocUrl){
this.lastName = lastName; this.lastName = lastName;
this.firstName = firstName; this.firstName = firstName;
this.address = address; this.address = address;
@ -33,6 +38,10 @@ public class InscriptionRequest {
this.state = state; this.state = state;
this.profilePicture = profilePicture; this.profilePicture = profilePicture;
this.password = password; this.password = password;
this.identityCard = identityCard;
this.submissionDate = submissionDate;
this.equivalenceState = equivalenceState;
this.admissionDocUrl = admissionDocUrl;
} }
public int getId() { public int getId() {
@ -118,4 +127,36 @@ public class InscriptionRequest {
public void setPassword(String password) { public void setPassword(String password) {
this.password = password; this.password = password;
} }
public String getIdentityCard() {
return identityCard;
}
public void setIdentityCard(String identityCard) {
this.identityCard = identityCard;
}
public Date getSubmissionDate() {
return submissionDate;
}
public void setSubmissionDate(Date submissionDate) {
this.submissionDate = submissionDate;
}
public RequestState getEquivalenceState() {
return equivalenceState;
}
public void setEquivalenceState(RequestState equivalenceState) {
this.equivalenceState = equivalenceState;
}
public String getAdmissionDocUrl() {
return admissionDocUrl;
}
public void setAdmissionDocUrl(String admissionDocUrl) {
this.admissionDocUrl = admissionDocUrl;
}
} }

View File

@ -0,0 +1,64 @@
package ovh.herisson.Clyde.Tables.Inscription;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
@Entity
public class Minerval {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private long id;
private long studentRegNo;
private int paidAmount;
private int toPay;
//If the academic year is 2023-2024 then 2023 will be stored here (we take the lowest year)
private int year;
public Minerval(){}
public Minerval(long studentRegNo, int paidAmount, int toPay, int year){
this.studentRegNo = studentRegNo;
this.paidAmount = paidAmount;
this.toPay = toPay;
this.year = year;
}
public long getStudentRegNo() {
return studentRegNo;
}
public void setStudentRegNo(long studentRegNo) {
this.studentRegNo = studentRegNo;
}
public int getPaidAmount() {
return paidAmount;
}
public void setPaidAmount(int paidAmount) {
this.paidAmount = paidAmount;
}
public int getToPay() {
return toPay;
}
public void setToPay(int toPay) {
this.toPay = toPay;
}
public int getYear() {
return year;
}
public void setYear(int year) {
this.year = year;
}
public long getId() {
return id;
}
}

View File

@ -0,0 +1,83 @@
package ovh.herisson.Clyde.Tables.Inscription;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import java.util.Date;
@Entity
public class Payment {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private long id;
private long studentRegNo;
private String card;
private String client;
private Date expDate;
private int amount;
private Date date;
public Payment(){}
public Payment(long studentRegNo, String card, String client, Date expDate, int amount, Date date){
this.studentRegNo = studentRegNo;
this.card = card;
this.client = client;
this.expDate = expDate;
this.amount = amount;
this.date = date;
}
public long getStudentRegNo() {
return studentRegNo;
}
public void setStudentRegNo(long studentRegNo) {
this.studentRegNo = studentRegNo;
}
public String getCard() {
return card;
}
public void setCard(String card) {
this.card = card;
}
public String getClient() {
return client;
}
public void setClient(String client) {
this.client = client;
}
public Date getExpDate() {
return expDate;
}
public void setExpDate(Date expDate) {
this.expDate = expDate;
}
public int getAmount() {
return amount;
}
public void setAmount(int amount) {
this.amount = amount;
}
public long getId() {
return id;
}
public Date getDate() {
return date;
}
public void setDate(Date date) {
this.date = date;
}
}

View File

@ -0,0 +1,89 @@
package ovh.herisson.Clyde.Tables.Inscription;
import jakarta.persistence.*;
import org.hibernate.annotations.OnDelete;
import org.hibernate.annotations.OnDeleteAction;
import ovh.herisson.Clyde.Tables.RequestState;
import ovh.herisson.Clyde.Tables.User;
import java.util.Date;
import java.util.Map;
@Entity
public class ScholarshipRequest {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private long id;
@JoinColumn(name="Users")
@ManyToOne(fetch = FetchType.EAGER)
@OnDelete(action = OnDeleteAction.CASCADE)
private User user;
private RequestState state;
private Date date;
private int amount;
private String taxDocUrl;
private String residencyDocUrl;
public ScholarshipRequest(User user, RequestState state, int amount, Date date, String taxDocUrl, String residencyDocUrl){
this.user = user;
this.state = state;
this.amount = amount;
this.date = date;
this.taxDocUrl = taxDocUrl;
this.residencyDocUrl = residencyDocUrl;
}
public ScholarshipRequest(){}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
public RequestState getState() {
return state;
}
public void setState(RequestState state) {
this.state = state;
}
public int getAmount() {
return amount;
}
public void setAmount(int amount) {
this.amount = amount;
}
public Date getDate() {
return date;
}
public void setDate(Date date) {
this.date = date;
}
public long getId() {
return id;
}
public String getResidencyDocUrl() {
return residencyDocUrl;
}
public void setResidencyDocUrl(String residencyDocUrl) {
this.residencyDocUrl = residencyDocUrl;
}
public String getTaxDocUrl() {
return taxDocUrl;
}
public void setTaxDocUrl(String taxDocUrl) {
this.taxDocUrl = taxDocUrl;
}
}

View File

@ -0,0 +1,115 @@
package ovh.herisson.Clyde.Tables.Inscription;
import jakarta.persistence.*;
import ovh.herisson.Clyde.Tables.Curriculum;
import ovh.herisson.Clyde.Tables.RequestState;
import ovh.herisson.Clyde.Tables.User;
import java.util.Date;
@Entity
public class UnregisterRequest {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private long id;
private RequestState state;
private String reason;
private Date date;
//We store these informations again so if the user is deleted we still have the informations for history
private long regNo;
private String firstName;
private String lastName;
private String email;
//Null if the user unregister for the academic year, contains a curriculum if the user wants to unregister from a specific curriculum
@ManyToOne
@JoinColumn(name = "Curriculum")
private Curriculum curriculum;
public UnregisterRequest(RequestState state, String reason, Date date, long regNo, String firstName, String lastName, String email, Curriculum curriculum){
this.state = state;
this.reason = reason;
this.date = date;
this.regNo = regNo;
this.firstName = firstName;
this.lastName = lastName;
this.email = email;
this.curriculum = curriculum;
}
public UnregisterRequest(){}
public RequestState getState() {
return state;
}
public void setState(RequestState state) {
this.state = state;
}
public String getReason() {
return reason;
}
public void setReason(String reason) {
this.reason = reason;
}
public long getId() {
return id;
}
public void setDate(Date date) {
this.date = date;
}
public Date getDate() {
return date;
}
public String getEmail() {
return email;
}
public String getLastName() {
return lastName;
}
public String getFirstName() {
return firstName;
}
public void setEmail(String email) {
this.email = email;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public void setRegNo(long regNo) {
this.regNo = regNo;
}
public long getRegNo() {
return regNo;
}
public void setCurriculum(Curriculum curriculum) {
this.curriculum = curriculum;
}
public Curriculum getCurriculum() {
return curriculum;
}
}

View File

@ -1,5 +1,14 @@
package ovh.herisson.Clyde.Tables; package ovh.herisson.Clyde.Tables;
/******************************************************
* @file Lesson.java
* @author William Karpinski
* @scope Extension Horaire
*
* Represent a course in a schedule
******************************************************/
import jakarta.persistence.*; import jakarta.persistence.*;
import org.hibernate.annotations.OnDelete; import org.hibernate.annotations.OnDelete;
import org.hibernate.annotations.OnDeleteAction; import org.hibernate.annotations.OnDeleteAction;

View File

@ -1,5 +1,14 @@
package ovh.herisson.Clyde.Tables; package ovh.herisson.Clyde.Tables;
/******************************************************
* @file LessonChangesRequest.java
* @author William Karpinski
* @scope Extension Horaire
*
* Represent a request about changes on schedules and lessons
******************************************************/
import jakarta.persistence.*; import jakarta.persistence.*;
import org.hibernate.annotations.OnDelete; import org.hibernate.annotations.OnDelete;
import org.hibernate.annotations.OnDeleteAction; import org.hibernate.annotations.OnDeleteAction;
@ -31,6 +40,12 @@ public class LessonChangesRequest {
private String lessonType; private String lessonType;
/**
* Can take 3 values:
* 0 : Request to CREATE a lesson
* 1 : Request to MODIFY an existing lesson
* 2 : Request to DELETE a lesson
*/
private int requestType; private int requestType;
public LessonChangesRequest(User user, RequestState state, String lessonStart, public LessonChangesRequest(User user, RequestState state, String lessonStart,

View File

@ -0,0 +1,72 @@
package ovh.herisson.Clyde.Tables.Msg;
/******************************************************
* @file Discussion.java
* @author Anthony Debucquoy
* @scope Extension messagerie
*
* Discussion allow to regroupe multiple user in and message together
* for the messages application to work
******************************************************/
import java.util.List;
import jakarta.persistence.CascadeType;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.JoinTable;
import jakarta.persistence.ManyToMany;
import jakarta.persistence.OneToMany;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import ovh.herisson.Clyde.Tables.User;
@Entity
@Getter
@Setter
@NoArgsConstructor
public class Discussion{
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private long id;
private String name;
@ManyToMany
@JoinTable(
name = "discussion_members",
joinColumns = @JoinColumn(name = "discussion_id"),
inverseJoinColumns = @JoinColumn(name = "user_id")
)
private List<User> members;
@OneToMany(mappedBy="discussion", orphanRemoval = true, cascade = CascadeType.ALL)
private List<Message> msgs;
public Discussion(String name){
this.name = name;
}
public Discussion(String name, User user){
this.name = name;
this.members = List.of(user);
}
public void addMessage(Message msg){
msg.setDiscussion(this);
msgs.add(msg);
}
public void addMember(User user) {
members.add(user);
}
public void delMember(User user) {
members.remove(user);
}
}

View File

@ -0,0 +1,66 @@
package ovh.herisson.Clyde.Tables.Msg;
/******************************************************
* @file Message.java
* @author Anthony Debucquoy
* @scope Extension messagerie
*
* Represent a message sent to a discussion
******************************************************/
import org.hibernate.annotations.CreationTimestamp;
import org.hibernate.annotations.UpdateTimestamp;
import com.fasterxml.jackson.annotation.JsonIgnore;
import java.util.Date;
import jakarta.persistence.CascadeType;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.OneToMany;
import jakarta.persistence.OneToOne;
import jakarta.persistence.PrePersist;
import jakarta.persistence.Temporal;
import jakarta.persistence.TemporalType;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import ovh.herisson.Clyde.Tables.User;
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@Entity
public class Message {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private long id;
private String content;
@CreationTimestamp
@Column(nullable = false)
private Date created;
@ManyToOne
private User author;
public User getAuthor() {
return author;
}
@OneToOne
private Message response;
@ManyToOne(optional = false)
@JsonIgnore
private Discussion discussion;
}

View File

@ -1,78 +0,0 @@
package ovh.herisson.Clyde.Tables;
import jakarta.persistence.*;
import org.hibernate.annotations.OnDelete;
import org.hibernate.annotations.OnDeleteAction;
@Entity
public class ReInscriptionRequest {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private int id;
@ManyToOne
@JoinColumn(name = "Users")
@OnDelete(action = OnDeleteAction.CASCADE)
private User user;
@ManyToOne
@JoinColumn(name = "Curriculum")
@OnDelete(action = OnDeleteAction.CASCADE)
private Curriculum newCurriculum;
private RequestState state;
//Permet de différencier les demandes de changement et une réinscription dans le même Curriculum
//Pour la réinscription on va le mettre a 0
private boolean type = false;
public ReInscriptionRequest(){}
public ReInscriptionRequest(User user, Curriculum newCurriculum, RequestState state, boolean type){
this.user = user;
this.newCurriculum = newCurriculum;
this.state = state;
this.type = type;
}
public ReInscriptionRequest(User user, Curriculum newCurriculum, RequestState state){
this.user = user;
this.newCurriculum = newCurriculum;
this.state = state;
}
public int getId() {
return id;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
public Curriculum getNewCurriculum() {
return newCurriculum;
}
public void setNewCurriculum(Curriculum newCurriculum) {
this.newCurriculum = newCurriculum;
}
public RequestState getState() {
return state;
}
public void setState(RequestState state) {
this.state = state;
}
public boolean isType() {
return type;
}
public void setType(boolean type) {
this.type = type;
}
}

View File

@ -0,0 +1,46 @@
package ovh.herisson.Clyde.Tables;
import org.hibernate.engine.jdbc.connections.spi.JdbcConnectionAccess;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.id.IdentifierGenerator;
import java.sql.*;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
public class RegNoGenerator implements IdentifierGenerator {
private static int count = 0;
@Override
public Object generate(SharedSessionContractImplementor session, Object object) {
try{
JdbcConnectionAccess jdbccon = session.getJdbcConnectionAccess();
Connection conn = jdbccon.obtainConnection();
Statement statement = conn.createStatement();
Calendar c = new GregorianCalendar();
int y = c.get(Calendar.YEAR);
String query = "select count(reg_no) + "+count+" from Users where reg_no/10000 = " + y%1000;
ResultSet set = statement.executeQuery(query);
long resp = 0;
if(set.next()){
resp = set.getLong(1)+((y%1000)*10000);
count += 1;
}
conn.close();
statement.close();
return resp;
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
public static void resetCount(){
count = 0;
}
}

View File

@ -3,5 +3,6 @@ package ovh.herisson.Clyde.Tables;
public enum RequestState { public enum RequestState {
Accepted, Accepted,
Refused, Refused,
Pending Pending,
Unrequired
} }

View File

@ -1,6 +1,14 @@
package ovh.herisson.Clyde.Tables; package ovh.herisson.Clyde.Tables;
/******************************************************
* @file Schedule.java
* @author William Karpinski
* @scope Extension Horaire
*
* Represent a schedule linked to a curriculum
******************************************************/
import jakarta.persistence.*; import jakarta.persistence.*;
import org.hibernate.annotations.OnDelete; import org.hibernate.annotations.OnDelete;
import org.hibernate.annotations.OnDeleteAction; import org.hibernate.annotations.OnDeleteAction;

View File

@ -1,11 +1,19 @@
package ovh.herisson.Clyde.Tables; package ovh.herisson.Clyde.Tables;
/******************************************************
* @file ScheduleLesson.java
* @author William Karpinski
* @scope Extension Horaire
*
* Used to link schedules and lessons to each others
******************************************************/
import jakarta.persistence.*; import jakarta.persistence.*;
import org.hibernate.annotations.OnDelete; import org.hibernate.annotations.OnDelete;
import org.hibernate.annotations.OnDeleteAction; import org.hibernate.annotations.OnDeleteAction;
@Entity @Entity
public class ScheduleLesson{ public class ScheduleLesson{
@Id @Id

View File

@ -1,14 +1,22 @@
package ovh.herisson.Clyde.Tables; package ovh.herisson.Clyde.Tables;
import com.fasterxml.jackson.annotation.JsonIgnore;
import jakarta.persistence.*; import jakarta.persistence.*;
import java.util.Date; import org.hibernate.annotations.OnDelete;
import org.hibernate.annotations.OnDeleteAction;
import org.hibernate.annotations.GenericGenerator;
import ovh.herisson.Clyde.Tables.Msg.Discussion;
import ovh.herisson.Clyde.Tables.Msg.Message;
import java.util.Date;
import java.util.List;
@Entity @Entity
@Table(name = "Users") @Table(name = "Users")
public class User { public class User {
@Id @Id
@GeneratedValue(strategy = GenerationType.AUTO) @GenericGenerator(name = "userGen", type = ovh.herisson.Clyde.Tables.RegNoGenerator.class)
@GeneratedValue(generator = "userGen")
private Long regNo; private Long regNo;
private String lastName; private String lastName;
private String firstName; private String firstName;
@ -18,8 +26,19 @@ public class User {
private String country; private String country;
private Date birthDate; private Date birthDate;
private String profilePictureUrl; private String profilePictureUrl;
private ovh.herisson.Clyde.Tables.Role role; private Role role;
@JsonIgnore
private String password; private String password;
////// Extension Messagerie /////
@OneToMany(mappedBy = "author", cascade = CascadeType.ALL)
private List<Message> msgs;
/////////////////////////////////
@ManyToMany( mappedBy = "members" )
private List<Discussion> discussions;
public User(String lastName, String firstName, String email, String address, public User(String lastName, String firstName, String email, String address,
String country, Date birthDate, String profilePictureUrl, Role role, String password) String country, Date birthDate, String profilePictureUrl, Role role, String password)
{ {

View File

@ -21,9 +21,16 @@ public class UserCurriculum {
@OnDelete(action = OnDeleteAction.CASCADE) @OnDelete(action = OnDeleteAction.CASCADE)
private Curriculum curriculum; private Curriculum curriculum;
public UserCurriculum(User user, Curriculum curriculum){ private int year;
//True if the user has that curriculum at the moment false if not
private boolean actual;
public UserCurriculum(User user, Curriculum curriculum, int year, boolean actual){
this.user = user; this.user = user;
this.curriculum = curriculum; this.curriculum = curriculum;
this.year = year;
this.actual = actual;
} }
public UserCurriculum() {} public UserCurriculum() {}
@ -47,4 +54,20 @@ public class UserCurriculum {
public void setCurriculum(Curriculum curriculum) { public void setCurriculum(Curriculum curriculum) {
this.curriculum = curriculum; this.curriculum = curriculum;
} }
public int getYear() {
return year;
}
public void setYear(int year) {
this.year = year;
}
public void setActual(boolean actual) {
this.actual = actual;
}
public boolean isActual() {
return actual;
}
} }

View File

@ -1,3 +1,12 @@
spring.jpa.hibernate.ddl-auto=create-drop spring.jpa.hibernate.ddl-auto=create-drop
spring.jpa.database-platform=org.hibernate.dialect.PostgreSQLDialect spring.jpa.database-platform=org.hibernate.dialect.PostgreSQLDialect
spring.sql.init.mode=always spring.sql.init.mode=always
# spring.datasource.url=jdbc:postgresql://localhost:5442/clyde
spring.datasource.url=jdbc:postgresql://db:5432/clyde
spring.datasource.username=devel
spring.datasource.password=devel
# spring.config.activate.on-profile=prod
# spring.datasource.url=jdbc:postgresql:clyde?socketFactory=org.newsclub.net.unix.AFUNIXSocketFactory$FactoryArg&socketFactoryArg=/var/run/postgresql/.s.PGSQL.5432
# spring.datasource.username=clyde

View File

@ -24,6 +24,7 @@ public class UserRepoTest {
@BeforeEach @BeforeEach
public void setup(){ public void setup(){
userRepo.deleteAll();
User herobrine = new User("brine","hero","admin@admin.com","in your WalLs","ShadowsLand", new GregorianCalendar(2005, 4, 3).getTime(), null, Role.Admin,"admin"); User herobrine = new User("brine","hero","admin@admin.com","in your WalLs","ShadowsLand", new GregorianCalendar(2005, 4, 3).getTime(), null, Role.Admin,"admin");
userRepo.save(herobrine); userRepo.save(herobrine);
} }
@ -34,8 +35,8 @@ public class UserRepoTest {
} }
@Test @Test
public void usertest(){ public void usertest(){
Assert.assertEquals("brine", userRepo.findById(1).getLastName()); Assert.assertEquals("brine", userRepo.findByEmail("admin@admin.com").getLastName());
Assert.assertTrue(new GregorianCalendar(2005, 4, 3).getTime().equals(userRepo.findById(1).getBirthDate())); Assert.assertTrue(new GregorianCalendar(2005, 4, 3).getTime().equals(userRepo.findByEmail("admin@admin.com").getBirthDate()));
} }
} }

29
compose.yaml Normal file
View File

@ -0,0 +1,29 @@
services:
db:
image: 'postgres:16'
environment:
- 'POSTGRES_DB=clyde'
- 'POSTGRES_USER=devel'
- 'POSTGRES_PASSWORD=devel'
# Uncomment this to allow connections to the db from outside the container
# ports:
# - '5442:5432'
back:
build: backend/.
ports:
- "8080:8080"
volumes:
- cdn:/backend/cdn
ulimits:
nofile:
soft: 65536
hard: 65536
front:
build: frontend/.
volumes:
- cdn:/app/front/dist/cdn
ports:
- "8000:8080"
volumes:
cdn:

11
frontend/Dockerfile Normal file
View File

@ -0,0 +1,11 @@
# https://v2.vuejs.org/v2/cookbook/dockerize-vuejs-app
FROM node:lts-alpine
RUN npm install -g http-server
WORKDIR /app/front
COPY package*.json ./
RUN npm install
COPY . .
ENV VITE_CLYDE_MODE=container
RUN npm run build
EXPOSE 8080
CMD [ "http-server", "dist" ]

View File

@ -31,6 +31,7 @@ app.studentList=Students List
app.users=Users app.users=Users
app.manageOwnLessons=Manage Owned Courses Schedule app.manageOwnLessons=Manage Owned Courses Schedule
app.lessonRequests=Schedule Requests app.lessonRequests=Schedule Requests
app.payments = Payments
request.moreInfos=More Infos request.moreInfos=More Infos
request.accept=Accept request.accept=Accept
request.refuse=Refuse request.refuse=Refuse

View File

@ -31,6 +31,7 @@ app.studentList=Liste des étudiants
app.users=Utilisateurs app.users=Utilisateurs
app.manageOwnLessons=Gérer ses horaires de cours app.manageOwnLessons=Gérer ses horaires de cours
app.lessonRequests=Requêtes d'horaire app.lessonRequests=Requêtes d'horaire
app.payments = Payements
request.moreInfos=Plus d'Infos request.moreInfos=Plus d'Infos
request.accept=Accepter request.accept=Accepter
request.refuse=Refuser request.refuse=Refuser
@ -55,3 +56,4 @@ Curriculum=Cursus
Credits=Credits Credits=Credits
InscriptionService=S.I. InscriptionService=S.I.
faculty=Faculté faculty=Faculté

View File

@ -32,7 +32,6 @@ window.addEventListener('hashchange', () => {
<template> <template>
<div class="container"> <div class="container">
<div class="topBar"> <div class="topBar">
<ul class="horizontal"> <ul class="horizontal">
<li title=home> <li title=home>
@ -68,7 +67,6 @@ window.addEventListener('hashchange', () => {
{{i18n("app.manage.profile")}} {{i18n("app.manage.profile")}}
</a> </a>
</div> </div>
</div> </div>
</a></li> </a></li>
</ul> </ul>
@ -98,20 +96,19 @@ window.addEventListener('hashchange', () => {
height: 100%; height: 100%;
width: 100%; width: 100%;
display:grid; display:grid;
grid-template-columns:[firstCol-start]70px[firstCol-end secondCol-start]auto[endCol];
grid-template-rows:[firstRow-start]61px[firstRow-end secondRow-start] auto [endRow]; grid-template-columns:[firstCol-start]70px[firstCol-end secondCol-start] auto [endCol];
grid-template-rows:[firstRow-start] var(--header-size) [firstRow-end secondRow-start] calc(100% - var(--header-size)) [endRow];
grid-template-areas: grid-template-areas:
"topBar topBar" "topBar topBar"
"leftBar page"; "leftBar page";
row-gap:0px;
column-gap:0px;
} }
.page { .page {
grid-area:page; grid-area:page;
height: 100%; height: 100%;
width: 100%; width: 100%;
place-self:center;
} }
.topBar{ .topBar{
@ -154,7 +151,7 @@ window.addEventListener('hashchange', () => {
ul.vertical{ ul.vertical{
list-style-type: none; list-style-type: none;
margin-top: 61px; margin-top: var(--header-size);
top:0; top:0;
left:0; left:0;
padding: 25px 0 0; padding: 25px 0 0;
@ -202,7 +199,7 @@ window.addEventListener('hashchange', () => {
left:0; left:0;
position: fixed; position: fixed;
height:61px; height:var(--header-size);
width: 100%; width: 100%;
background-color: rgb(24, 24, 24); background-color: rgb(24, 24, 24);
} }

View File

@ -1,111 +0,0 @@
<script setup>
import i18n from "@/i18n.js"
import {ref} from 'vue'
import {validateRegister, getAllRegisters } from '@/rest/ServiceInscription.js'
const requests = ref(await getAllRegisters());
console.log(requests);
async function upPage(id,review){
await validateRegister(id,review);
requests.value = await getAllRegisters();
}
</script>
<template>
<div style='display:flex; justify-content:center; min-width:1140px;' v-for="item of requests">
<div class="bodu" v-if="item.state === 'Pending'">
<div class="container">
<div class="id"><a>{{item.id}}</a></div>
<div class="surname"><a>{{item.lastName}}</a></div>
<div class="firstname"><a>{{item.firstName}}</a></div>
<div class="infos"><button style="background-color:rgb(105,05,105);" >{{i18n("request.moreInfos")}}</button></div>
<div class="accept"><button @click="upPage(item.id,'Accepted')" style="background-color:rgb(0,105,50);">{{i18n("request.accept")}}</button></div>
<div class="refuse"><button @click="upPage(item.id,'Refused')" style="background-color:rgb(105,0,0);">{{i18n("request.refuse")}}</button></div>
</div>
</div>
</div>
</template>
<style scoped>
.container{
color:white;
height:100px;
font-size:20px;
display:grid;
grid-template-columns:10% 14.2% 19% 14.2% 14.2% 14.2% 14.2%;
grid-template-areas:
"id type surname firstname infos accept refuse";
}
.infos {
grid-area:infos;
align-self:center;
}
.accept{
grid-area:accept;
align-self:center;
}
.refuse{
grid-area:refuse;
align-self:center;
}
.titles {
grid-area:titles;
background-color:rgb(215,215,215);
}
.id{
grid-area:id;
margin-left:40px;
align-self:center;
}
.type{
grid-area:type;
align-self:center;
}
.surname{
grid-area:surname;
align-self:center;
white-space: nowrap;
overflow: hidden;
text-overflow:ellipsis;
}
.firstname{
grid-area:firstname;
align-self:center;
white-space: nowrap;
overflow: hidden;
text-overflow:ellipsis;
}
button{
font-size:15px;
height:50px;
width:100px;
border:none;
border-radius:20px;
}
.bodu {
margin-top:2%;
width:66%;
border:2px solid black;
border-radius:9px;
background-color:rgb(50,50,50);
}
</style>

View File

@ -0,0 +1,128 @@
<script setup>
import {
addUninscReq, editChangeCurrReq, editChangeCurrReqTeacherState,
editScholarshipReq,
editUnregReq, getChangeCurrReqById,
getScholarshipReqById,
getUnregisterbyId
} from "@/rest/requests.js";
import i18n from "@/i18n.js";
import {getSelf, getUser} from "@/rest/Users.js";
import {reactive, ref} from "vue";
import AboutStudent from "@/Apps/Inscription/AboutStudent.vue";
const props = defineProps(["reqId"])
const req = ref(await getChangeCurrReqById(props.reqId))
const user = await getSelf()
//0 liste, 1 profil
const localwindowstate = ref(0);
const tag = req.value.user.regNo
const windowState = defineModel("windowState")
async function uploadandrefreshChangeRequest(state){
await editChangeCurrReq(req.value.id, state);
}
async function editChangeCurrReqTeacherApproval(state){
await editChangeCurrReqTeacherState(req.value.id, state)
}
</script>
<template>
<div class="body" v-if="localwindowstate === 0">
<div class="container">
<div class="globalInfos">
<div class="infosContainer">
<div>
Firstname/Name : {{req.user.firstName}} {{req.user.lastName}}
</div>
<div>
regNo : {{req.user.regNo}}
</div>
<div v-if="req.actualCurriculum !== null">
From : Bac {{req.actualCurriculum.year}} {{req.actualCurriculum.option}}
To : Bac {{req.destinationCurriculum.year}} {{req.destinationCurriculum.option}}
</div>
<div v-else>
Wanted cursus : Bac {{req.destinationCurriculum.year}} {{req.destinationCurriculum.option}}
</div>
<div>
<button @click="localwindowstate++"> See profile </button>
</div>
<div>
<button v-if="req.state === 'Pending'" @click="req.state='Accepted';uploadandrefreshChangeRequest('Accepted')">Accept</button>
<button v-if="req.state === 'Pending'" @click="req.state='Refused';uploadandrefreshChangeRequest('Refused')" style="margin-left: 2%;">Refuse</button>
</div>
<div v-if="user.role === 'Teacher' || user.role === 'Admin'">
<button v-if="req.teacherApprovalState === 'Pending'" @click="req.teacherApprovalState='Accepted';editChangeCurrReqTeacherApproval('Accepted')">Accept equivalence</button>
<button v-if="req.teacherApprovalState === 'Pending'" @click="req.teacherApprovalState='Refused';editChangeCurrReqTeacherApproval('Refused')">Refuse equivalence</button>
</div>
</div>
</div>
</div>
</div>
<div v-if="localwindowstate === 0">
<button @click="windowState = 0" style="margin-left: 10%">Back</button>
</div>
<div v-if="localwindowstate === 1">
<AboutStudent :target="tag"></AboutStudent>
<button @click="localwindowstate--;">Back</button>
</div>
</template>
<style scoped>
.container{
min-width:675px;
display:grid;
grid-template-columns:10vw 50vw;
grid-template-rows:200px auto;
column-gap:2.7%;
row-gap:45px;
grid-template-areas:
"profilPic globalInfos"
"minfos minfos";
}
.profilPic{
width:100%;
grid-area:profilPic;
}
.globalInfos {
grid-area:globalInfos;
align-self :center;
}
.body {
min-width:960px;
width:100%;
display:flex;
align-items:center;
justify-content:center;
margin-top:7%;
}
.subContainter{
width:100%;
background-color:rgb(50,50,50);
border-radius:20px;
border:4px solid black;
}
.infosContainer {
min-width:350px;
padding-bottom:50px;
border:2px solid black;
font-size:25px;
color:white;
padding:20px;
background-color:rgb(50,50,50);
border-radius:20px;
}
</style>

View File

@ -0,0 +1,116 @@
<script setup>
import {
addUninscReq,
editExempReqState,
editScholarshipReq,
getExempReq,
getScholarshipReqById
} from "@/rest/requests.js";
import i18n from "@/i18n.js";
import {getUser} from "@/rest/Users.js";
import {reactive, ref} from "vue";
import AboutStudent from "@/Apps/Inscription/AboutStudent.vue";
const props = defineProps(["reqId"])
const req = ref(await getExempReq(props.reqId))
const profile = ref(false)
const windowState = defineModel("windowState")
async function editExemp(newstate){
await editExempReqState(req.value.id, newstate)
}
</script>
<template>
<div class="body" v-if="profile === false">
<div class="container">
<div class="globalInfos">
<div class="infosContainer">
<div>
Firstname/Name : {{req.user.firstName}} {{req.user.lastName}}
</div>
<div>
Course: {{req.course.title}}
</div>
<div>
State : {{req.state}}
</div>
<div>
<button @click="profile = !profile">Voir le profil</button>
</div>
<div>
<button>Download justification document</button>
</div>
<div>
<button v-if="req.state === 'Pending'" @click="req.state='Accepted';editExemp('Accepted')">Accept</button>
<button v-if="req.state === 'Pending'" @click="req.state='Refused';editExemp('Refused')" style="margin-left: 2%;">Refuse</button>
</div>
</div>
</div>
</div>
</div>
<div v-else>
<AboutStudent :target="req.user.regNo"></AboutStudent>
<button @click="profile=!profile">Back</button>
</div>
<div>
<button v-if="profile===false" @click="windowState = 0" style="margin-left: 30%">Back</button>
</div>
</template>
<style scoped>
.container{
min-width:675px;
display:grid;
grid-template-columns:10vw 50vw;
grid-template-rows:200px auto;
column-gap:2.7%;
row-gap:45px;
grid-template-areas:
"profilPic globalInfos"
"minfos minfos";
}
.profilPic{
width:100%;
grid-area:profilPic;
}
.globalInfos {
grid-area:globalInfos;
align-self :center;
}
.body {
min-width:960px;
width:100%;
display:flex;
align-items:center;
justify-content:center;
margin-top:7%;
}
.subContainter{
width:100%;
background-color:rgb(50,50,50);
border-radius:20px;
border:4px solid black;
}
.infosContainer {
min-width:350px;
padding-bottom:50px;
border:2px solid black;
font-size:25px;
color:white;
padding:20px;
background-color:rgb(50,50,50);
border-radius:20px;
}
</style>

View File

@ -0,0 +1,137 @@
<script setup>
import i18n from "@/i18n.js"
import {getSelf, getUser} from '../../rest/Users.js'
import {getcurriculum,getSomeonesCurriculumList} from "@/rest/curriculum.js";
import {getRegisters} from "@/rest/ServiceInscription.js";
import {get} from "jsdom/lib/jsdom/named-properties-tracker.js";
import {getExternalCurriculumByInscrReq} from "@/rest/externalCurriculum.js";
import {ref} from "vue";
import ExternalCurriculumList from "@/Apps/Inscription/ExternalCurriculumList.vue";
import {editEquivalenceState} from "@/rest/requests.js";
const props = defineProps(['target']);
const request = await getRegisters(props.target);
const cursus = await getcurriculum(request.curriculum);
const user = await getSelf();
const list = ref(false);
const externalCurriculum = await getExternalCurriculumByInscrReq(request.id)
//Get the parent page windowState to display the correct button
const windowState = defineModel("windowState")
function getPP(){
if(request.profilePictureUrl === null){
return "/Clyde.png"
}
return request.profilePictureUrl;
}
async function editEquivalence(id, newstate){
await editEquivalenceState(id, newstate)
}
</script>
<template>
<div class="body" v-if="list == false">
<div class="container">
<div class="profilPic">
<img class="subContainter" :src=getPP()>
</div>
<div class = "globalInfos">
<div class="infosContainer">
<div>
FirstName/Name : {{request.firstName}} {{request.lastName}}
</div>
<div>
E-mail: {{request.email}}
</div>
<div>
Adresse : {{request.address}}
</div>
<div>
Pays : {{request.country}}
</div>
<div>
Date de naissance : {{request.birthDate}}
</div>
<div>
Cursus voulu : BAB {{cursus.year}} {{cursus.option}}
</div>
<div v-if="cursus.year > 1">
<button style="background-color:rgb(105,05,105);margin-left: 5%" @click="list=!list" v-if="(user.role == 'Teacher' || user.role == 'Admin')&& request.equivalenceState == 'Pending'">See external curriculums</button>
</div>
</div>
</div>
</div>
</div>
<div v-if="list == false">
<button @click="windowState = 0">Back</button>
</div>
<div v-if="list==true">
<ExternalCurriculumList :ext-curr-list="externalCurriculum" :mode="0"></ExternalCurriculumList>
<div style="margin-left: 15%;margin-top: 5%;">
<button style="margin-left: 2%" @click="list = false;editEquivalence(request.id, 'Accepted'); request.equivalenceState='Accepted'">Accept Equivalence</button>
<button style="margin-left: 2%" @click="list = false;editEquivalence(request.id, 'Refused'); request.equivalenceState='Refused'">Refuse Equivalence</button>
<button style="margin-left: 2%" @click="list=false">Back</button>
</div>
</div>
</template>
<style scoped>
.container{
min-width:675px;
display:grid;
grid-template-columns:10vw 50vw;
grid-template-rows:200px auto;
column-gap:2.7%;
row-gap:45px;
grid-template-areas:
"profilPic globalInfos"
"minfos minfos";
}
.profilPic{
grid-area:profilPic;
width:100%;
}
.globalInfos {
grid-area:globalInfos;
align-self :center;
}
.body {
min-width:960px;
width:100%;
display:flex;
align-items:center;
justify-content:center;
margin-top:5%;
}
.subContainter{
width:100%;
background-color:rgb(50,50,50);
border-radius:20px;
border:4px solid black;
}
.infosContainer {
padding-bottom:50px;
border:2px solid black;
font-size:25px;
color:white;
padding:20px;
background-color:rgb(50,50,50);
border-radius:20px;
}
button{
font-size:15px;
height:50px;
width:100px;
border:none;
border-radius:20px;
}
</style>

View File

@ -0,0 +1,124 @@
<script setup>
import {addUninscReq, editScholarshipReq, getScholarshipReqById} from "@/rest/requests.js";
import i18n from "@/i18n.js";
import {getUser} from "@/rest/Users.js";
import {reactive, ref} from "vue";
const props = defineProps(["reqId"])
const req = ref(await getScholarshipReqById(props.reqId))
const user = req.value.user;
const scholarshipData = reactive({
amount : 0,
id : req.value.id,
state : ""
})
function getPP(){
if(user.profilePictureUrl === null){
return "/Clyde.png"
}
return user.profilePictureUrl
}
async function uploadandrefreshScholarshipRequest(){
await editScholarshipReq(scholarshipData);
req.value = await getScholarshipReqById(props.reqId);
}
</script>
<template>
<div class="body">
<div class="container">
<div class="profilPic">
<img class="subContainter" :src=getPP()>
</div>
<div class="globalInfos">
<div class="infosContainer">
<div>
Firstname/Name : {{user.firstName}} {{user.lastName}}
</div>
<div>
E-mail: {{user.email}}
</div>
<div>
Adresse : {{user.address}}
</div>
<div>
Country : {{user.country}}
</div>
<div>
Birthdate : {{user.birthDate.slice(0,10)}}
</div>
<div>
<button>Download tax justif document</button>
<button style="margin-left: 2%">Download residency justif document</button>
</div>
<div v-if="req.state == 'Pending'">
Please enter the amount to provide :
<input type="number" v-model="scholarshipData.amount">
</div>
<div>
<button v-if="req.state === 'Pending'" @click="scholarshipData.state='Accepted';uploadandrefreshScholarshipRequest()">Accept</button>
<button v-if="req.state === 'Pending'" @click="scholarshipData.state='Refused';uploadandrefreshScholarshipRequest()" style="margin-left: 2%;">Refuse</button>
</div>
</div>
</div>
</div>
</div>
</template>
<style scoped>
.container{
min-width:675px;
display:grid;
grid-template-columns:10vw 50vw;
grid-template-rows:200px auto;
column-gap:2.7%;
row-gap:45px;
grid-template-areas:
"profilPic globalInfos"
"minfos minfos";
}
.profilPic{
width:100%;
grid-area:profilPic;
}
.globalInfos {
grid-area:globalInfos;
align-self :center;
}
.body {
min-width:960px;
width:100%;
display:flex;
align-items:center;
justify-content:center;
margin-top:7%;
}
.subContainter{
width:100%;
background-color:rgb(50,50,50);
border-radius:20px;
border:4px solid black;
}
.infosContainer {
min-width:350px;
padding-bottom:50px;
border:2px solid black;
font-size:25px;
color:white;
padding:20px;
background-color:rgb(50,50,50);
border-radius:20px;
}
</style>

View File

@ -0,0 +1,192 @@
<script setup>
import i18n from "@/i18n.js"
import {getUser} from '../../rest/Users.js'
import {getSomeonesCurriculumList} from "@/rest/curriculum.js";
import {ref} from "vue";
import ExternalCurriculumList from "@/Apps/Inscription/ExternalCurriculumList.vue";
import {getExternalCurriculumByUser} from "@/rest/externalCurriculum.js";
const props = defineProps(['target'])
const user = await getUser(props.target)
const UserCurriculum = await getSomeonesCurriculumList(props.target)
const externalcurrlist = await getExternalCurriculumByUser(user.regNo)
const extercurrlist = ref(false)
function getPP(){
if(user.profilePictureUrl === null){
return "/Clyde.png"
}
return user.profilePictureUrl
}
//Cette function renvoie l'année académique concernée si on est dans l'année 2023-2024 elle renvoie 2023
//car dans la db l'année scolaire 2023-2024 est representée juste par 2023 (le même système s'applique pour chaque années on prend la borne inférieure
function getYear(){
let date = new Date();
if (date.getMonth() <= 6){
return date.getFullYear()-1
}
return date.getFullYear()
}
</script>
<template>
<div class="body" v-if="extercurrlist==false">
<div class="container">
<div class="profilPic">
<img class="subContainter" :src=getPP()>
</div>
<div class = "globalInfos">
<div class="infosContainer">
<div>
FirstName/Name : {{user.firstName}} {{user.lastName}}
</div>
<div>
E-mail: {{user.email}}
</div>
<div>
Adresse : {{user.address}}
</div>
<div>
Pays : {{user.country}}
</div>
<div>
Date de naissance : {{user.birthDate}}
</div>
<div>
<button @click="extercurrlist=!extercurrlist">See external curriculums</button>
</div>
</div>
</div>
<div class="moreInfos">
<div class = "oldcursus">
<div class="listTitle">
Anciens Cursus
</div>
<div class="listElement">
<div class=" containerElement" v-for="item in UserCurriculum.curriculumList">
<div class="year" v-if="item.actual === false">Bac {{item.year}}</div>
<div class="option" v-if="item.actual === false">{{item.option}}</div>
<div class="dateyear" v-if="item.actual === false">Année {{item.dateyear}}-{{item.dateyear+1}}</div>
</div>
</div>
</div>
<div class="newcursus">
<div class="listTitle">
Cursus Actuel
</div>
<div class="listElement">
<div class=" containerElement" v-for="item in UserCurriculum.curriculumList" >
<div class="year" v-if="item.actual === true">Bac {{item.year}}</div>
<div class="option" v-if="item.actual === true">{{item.option}}</div>
<div class="dateyear" v-if="item.actual === true">Année {{item.dateyear}}-{{item.dateyear+1}}</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div v-if="extercurrlist==true">
<ExternalCurriculumList :ext-curr-list="externalcurrlist" :mode="1"></ExternalCurriculumList>
</div>
</template>
<style scoped>
.container{
min-width:675px;
display:grid;
grid-template-columns:10vw 50vw;
grid-template-rows:200px auto;
column-gap:2.7%;
row-gap:45px;
grid-template-areas:
"profilPic globalInfos"
"minfos minfos";
}
.profilPic{
grid-area:profilPic;
}
.globalInfos {
grid-area:globalInfos;
align-self :center;
}
.body {
min-width:960px;
width:100%;
display:flex;
align-items:center;
justify-content:center;
margin-top:5%;
}
.subContainter{
width:100%;
background-color:rgb(50,50,50);
border-radius:20px;
border:4px solid black;
}
.infosContainer {
padding-bottom:50px;
border:2px solid black;
font-size:25px;
color:white;
padding:20px;
background-color:rgb(50,50,50);
border-radius:20px;
}
.moreInfos {
display:grid;
grid-template-rows:200px auto;
column-gap:50px;
row-gap:45px;
grid-template-areas:
"minfos minfos";
grid-template-columns:600px 600px;
align-items:center;
justify-content:center;
margin-left: 320%;
}
.listTitle{
display: flex;
justify-content: center;
align-items: center;
width:250px;
margin-left:auto;
margin-right:auto;
border:2px solid black;
font-size:25px;
color:white;
padding:20px;
background-color:rgb(50,50,50);
border-radius:20px;margin-bottom:10px;
}
.listElement{
border:2px solid black;
font-size:25px;
color:white;
padding:20px;
background-color:rgb(50,50,50);
border-radius:20px;
margin-bottom:10px;
}
.containerElement{
justify-content:center;
display:grid;
grid-template-columns:100px 100px 300px;
grid-template-areas:
"year option dateyear";
column-gap:40px;
padding-left: 25px;
}
</style>

View File

@ -0,0 +1,109 @@
<script setup>
import {
addUninscReq,
editScholarshipReq,
editUnregReq,
getScholarshipReqById,
getUnregisterbyId
} from "@/rest/requests.js";
import i18n from "@/i18n.js";
import {getUser} from "@/rest/Users.js";
import {reactive, ref} from "vue";
const props = defineProps(["reqId"])
const req = ref(await getUnregisterbyId(props.reqId))
function getPP(){
if(user.profilePictureUrl === null){
return "/Clyde.png"
}
return user.profilePictureUrl
}
async function uploadandrefreshUnregRequest(state){
await editUnregReq(req.value.id, state)
req.value.state = state
}
</script>
<template>
<div class="body">
<div class="container">
<div class="globalInfos">
<div class="infosContainer">
<div>
Firstname/Name : {{req.firstName}} {{req.lastName}}
</div>
<div>
E-mail: {{req.email}}
</div>
<div>
regNo : {{req.regNo}}
</div>
<div>
Reason :
<input type="text" v-model="req.reason" readonly/>
</div>
<div>
<button v-if="req.state === 'Pending'" @click="req.state='Accepted';uploadandrefreshUnregRequest('Accepted')">Accept</button>
<button v-if="req.state === 'Pending'" @click="req.state='Refused';uploadandrefreshUnregRequest('Refused')" style="margin-left: 2%;">Refuse</button>
</div>
</div>
</div>
</div>
</div>
</template>
<style scoped>
.container{
min-width:675px;
display:grid;
grid-template-columns:10vw 50vw;
grid-template-rows:200px auto;
column-gap:2.7%;
row-gap:45px;
grid-template-areas:
"profilPic globalInfos"
"minfos minfos";
}
.profilPic{
width:100%;
grid-area:profilPic;
}
.globalInfos {
grid-area:globalInfos;
align-self :center;
}
.body {
min-width:960px;
width:100%;
display:flex;
align-items:center;
justify-content:center;
margin-top:7%;
}
.subContainter{
width:100%;
background-color:rgb(50,50,50);
border-radius:20px;
border:4px solid black;
}
.infosContainer {
min-width:350px;
padding-bottom:50px;
border:2px solid black;
font-size:25px;
color:white;
padding:20px;
background-color:rgb(50,50,50);
border-radius:20px;
}
</style>

View File

@ -0,0 +1,139 @@
<script setup>
import {reactive, ref} from "vue";
import i18n from "@/i18n.js";
import {getCourse} from "@/rest/courses.js";
import {getcurriculum} from "@/rest/curriculum.js";
import {uploadFile, uploadProfilePicture} from "@/rest/uploads.js";
import {createExemptionsRequest} from "@/rest/requests.js";
import {getSelf} from "@/rest/Users.js";
const props = defineProps(["cursuslist"])
const selectedCurriculum = ref(props.cursuslist[0])
const user = await getSelf()
const courseslist = ref(await getcurriculum(selectedCurriculum.value.curriculumId))
const list = ref(true)
const ppData = ref({})
async function updateCourseList(){
courseslist.value = await getcurriculum(selectedCurriculum.value.curriculumId)
}
async function postExemptionRequest(file, type){
const a = await uploadFile(file, type);
exemptReq.justifDocument = a.url
await createExemptionsRequest(exemptReq)
}
const exemptReq = reactive({
userRegNo : user.regNo,
courseId : null,
justifDocument : "",
})
</script>
<template style="margin-top:5%;">
<div v-if="list == true">
<span>Selected Cursus : </span>
<select v-model="selectedCurriculum" @change="updateCourseList">
<option v-for="item in props.cursuslist" :value="item">Bac {{item.year}} {{item.option}}</option>
</select>
<div style="display:flex; justify-content:center;" v-for="item in courseslist.courses">
<div class="bodu">
<div class="container">
<div class="title">{{item.title}}</div>
<div class="firstname">{{item.owner.firstName}}</div>
<div class="lastname">{{item.owner.lastName}}</div>
<div class="credits">credits : {{item.credits}}</div>
<div class="askexemption"><button style="background-color:rgb(105,0,0);" @click="list= !list;exemptReq.courseId=item.courseId">Ask exemption</button></div>
</div>
</div>
</div>
</div>
<div v-else>
<p>Please upload the justification document for the exemption </p>
<label class="browser">
<input type="file" @change="ppData.value = $event.target.files" accept="image/*" ref="filepath">
</label>
<button style="width:15%; margin-top: 5%;" @click="postExemptionRequest(ppData.value, 'JustificationDocument');">
Submit exemption request
</button>
</div>
</template>
<style scoped>
.container{
color:white;
height:100px;
font-size:30px;
display:grid;
grid-template-columns:30% 20% 15% 15% 15%;
grid-template-areas:"title firstname lastname credits askexemption";
column-gap:10px;
}
.title {
grid-area:title;
align-self:center;
white-space: nowrap;
overflow: hidden;
text-overflow:ellipsis;
font-size: 50%;
margin-left:30px;
}
.credits {
grid-area:credits;
align-self:center;
white-space: nowrap;
overflow: hidden;
text-overflow:ellipsis;
font-size: 50%;
}
.askexemption {
grid-area:askexemption;
align-self:center;
white-space: nowrap;
overflow: hidden;
text-overflow:ellipsis;
}
.lastname{
grid-area:lastname;
align-self:center;
white-space: nowrap;
overflow: hidden;
text-overflow:ellipsis;
font-size: 50%;
}
.firstname{
grid-area:firstname;
align-self:center;
white-space: nowrap;
overflow: hidden;
text-overflow:ellipsis;
font-size: 50%;
padding-left: 30%;
}
.bodu {
margin-top:2%;
width:100%;
border:2px solid black;
border-radius:9px;
background-color:rgb(50,50,50);
}
button{
border:none;
background-color:rgb(239, 60, 168);
border-radius:10px;
height:35px;
margin-top:10px;
}
</style>

View File

@ -0,0 +1,231 @@
<script setup>
import i18n from "@/i18n.js";
import {reactive, ref} from "vue";
import {getSelf} from "@/rest/Users.js";
import {createExternalCurriculum, getExternalCurriculumByUser} from "@/rest/externalCurriculum.js";
//mode 0 = externalcurr related to inscrreq, 1 = externalcurr related to user, 2 inscription procedure
const props = defineProps(["extCurrList", "mode"])
//Only usefull to pass the external curr array in the inscription procedure
const externalCurrTab = defineModel();
const extCurrList = ref({})
let extNum = 0
const User = ref({})
if (props.mode === 1){
User.value = await getSelf()
}
const list = ref(true)
const editmode = ref(false)
const notcompletedCheck = ref(false);
const externalCurr = reactive({
inscriptionRequestId : null,
school:null,
formation :null,
completion : "completed",
startYear : 0,
endYear: 0,
justifdocUrl : null,
userRegNo : null
})
if (props.mode === 1){
externalCurr.userRegNo = props.extCurrList[0].user.regNo
}else if(props.mode === 2){
extCurrList.value = externalCurrTab.value
}
if(props.mode !== 2){
extCurrList.value = props.extCurrList
console.log("oe")
}
function deleteExtCursus(extcursus){
externalCurrTab.value.splice(externalCurrTab.value.indexOf(extcursus),1)
}
async function postExternalCurr(){
if (props.mode === 1){
await createExternalCurriculum(externalCurr.inscriptionRequestId, externalCurr.school, externalCurr.formation, externalCurr.completion, externalCurr.startYear, externalCurr.endYear, externalCurr.justifdocUrl, externalCurr.userRegNo);
//We refresh the list
extCurrList.value = await getExternalCurriculumByUser(externalCurr.userRegNo);
list.value = !list.value;
}else if (props.mode === 2){
externalCurrTab.value.push({
inscriptionRequestId : externalCurr.inscriptionRequestId,
school:externalCurr.school,
formation :externalCurr.formation,
completion : externalCurr.completion,
startYear : externalCurr.startYear,
endYear: externalCurr.endYear,
justifdocUrl : externalCurr.justifdocUrl,
userRegNo : externalCurr.userRegNo
});
extCurrList.value = externalCurrTab.value
list.value = !list.value;
console.log(externalCurrTab.value)
}
}
</script>
<template style="margin-top:5%;">
<div v-if="list">
<div v-if="props.mode === 2||User.regNo === externalCurr.userRegNo" style="margin-left: 2%;margin-top: 2%">
<button @click="list = !list">Add external curriculum</button>
</div>
<div style="display:flex; justify-content:center; " v-for="(item, index) in extCurrList">
<div class="bodu">
<div class="container">
<div class="status"><a style="margin-left:30px">{{item.state}}</a></div>
<div class="school"><a>{{item.school}}</a></div>
<div class="formation"><a>{{item.formation}}</a></div>
<div class="completion"><a>{{item.completion}}</a></div>
<div class="download"><button>Download document</button></div>
<div class="edit" v-if="props.mode === 2"><button @click="list=!list;externalCurr.justifdocUrl=item.justifDocUrl; externalCurr.endYear = item.endYear; externalCurr.startYear = item.startYear; externalCurr.school = item.school;externalCurr.completion = item.completion;externalCurr.formation=item.formation;editmode=!editmode;extNum=index">Edit</button></div>
<div class="delete" v-if="props.mode === 2"><button @click="deleteExtCursus(item)">Delete</button></div>
</div>
</div>
</div>
</div>
<div v-else class="loginbox" style="margin-left: 35%; margin-top: 3%">
<form class="form">
<div class="inputBox">
<p>Ecole</p>
<input type="text" v-model="externalCurr.school">
</div>
<div class="inputBox">
<p>Formation</p>
<input type="text" v-model="externalCurr.formation">
</div>
<div class="inputBox">
<p>Cochez la case si vous n'avez terminé cette formation</p>
<input v-model="notcompletedCheck" type="checkbox" id="checkboxformation">
<div v-if="notcompletedCheck">
<p>En quelle année de la formation vous êtes vous arrété (exemple: 3ème) ?</p>
<input type="text" v-model="externalCurr.completion">
</div>
</div>
<div class="inputBox">
<p>Année de début</p>
<input type="number" v-model="externalCurr.startYear">
</div>
<div class="inputBox">
<p>Année de fin</p>
<input type="number" v-model="externalCurr.endYear">
</div>
<div class="inputBox" style="margin-top: 3%; margin-bottom: 3%">
<input v-if="!editmode" type="submit" value="Upload curriculum" @click="postExternalCurr()">
<input v-else type="submit" value="Edit curriculum" @click="externalCurrTab[extNum] = {inscriptionRequestId : externalCurr.inscriptionRequestId,school:externalCurr.school,formation :externalCurr.formation,completion : externalCurr.completion,startYear : externalCurr.startYear,endYear: externalCurr.endYear,justifdocUrl : externalCurr.justifdocUrl,userRegNo : externalCurr.userRegNo};editmode=!editmode;list=!list">
</div>
</form>
</div>
</template>
<style scoped>
.container{
color:white;
height:100px;
font-size:30px;
display:grid;
grid-template-columns:5% 10% 20% 15% 20% 10%;
grid-template-areas:
"status school formation completion download edit delete";
column-gap:10px;
}
.status {
grid-area:status;
align-self:center;
font-size: 70%;
}
.edit{
grid-area: edit;
align-self: center;
}
.delete{
grid-area: delete;
align-self: center;
}
.school{
grid-area:school;
align-self:center;
font-size: 70%;
}
.formation{
grid-area:formation;
align-self:center;
font-size: 70%;
}
.completion{
grid-area:completion;
align-self:center;
white-space: nowrap;
overflow: hidden;
text-overflow:ellipsis;
font-size: 70%;
}
.download{
grid-area: download;
align-self:center;
}
.bodu {
margin-top:2%;
width:66%;
border:2px solid black;
border-radius:9px;
background-color:rgb(50,50,50);
}
.loginbox {
background-color: rgb(24,24,24);
width: 400px;
display:flex;
justify-content: center;
border-radius: 5%;
box-shadow:0 5px 25px #000000;
}
.form {
position:relative;
width:100%;
display: flex;
flex-direction: column;
align-items:center;
gap: 3%;
}
.inputBox input,select {
width:100%;
border: none;
margin-right: 12.5%;
padding-left: 2.5%;
padding-top:2.5%;
padding-bottom:2.5%;
outline:none;
border-radius: 10px;
font-size:1.35em;
}
.inputBox p{
position:relative;
z-index: 100;
font-family:sans-serif ;
color:rgb(239,60,168);
transition: 0.5;
}
</style>

View File

@ -0,0 +1,255 @@
<script setup>
import i18n from "@/i18n.js"
import {ref, vModelSelect} from 'vue'
import {validateRegister, getAllRegisters } from '@/rest/ServiceInscription.js'
import AboutRequest from "@/Apps/Inscription/AboutRequest.vue";
import {
getAllChangeCurrReq,
getAllExemptionsRequest,
getAllScholarShipsRequest,
getAllUnregisters
} from "@/rest/requests.js";
import AboutScholarship from "@/Apps/Inscription/AboutScholarship.vue";
import AboutUnregister from "@/Apps/Inscription/AboutUnregister.vue";
import AboutChangeCurriculum from "@/Apps/Inscription/AboutChangeCurriculum.vue";
import AboutExemption from "@/Apps/Inscription/AboutExemption.vue";
const requests = ref(await getAllRegisters());
let targetId = "";
const requestType = ref("inscription");
const filterType = ref("None");
//0 = liste, 1 = détails, 2 = sure?, 3 = manage scholarship, 4 manage unregister, 5 = manage curriculum change, 6 = manage exemptions
const windowsState = ref(0);
async function upPage(id,review){
await validateRegister(id,review);
requests.value = await getAllRegisters();
}
async function loadRequests(){
switch (requestType.value){
case "inscription":
requests.value = await getAllRegisters();
break;
case "scholarship":
requests.value = await getAllScholarShipsRequest();
break;
case "exemption":
requests.value = await getAllExemptionsRequest();
break;
case "unregister":
requests.value = await getAllUnregisters();
break;
case "curriculum change":
requests.value = await getAllChangeCurrReq();
}
}
</script>
<template>
<div v-if="windowsState === 1">
<AboutRequest :target="targetId" v-model:window-state="windowsState"></AboutRequest>
</div>
<div v-if="windowsState === 0">
<div style="margin-top: 2%;margin-left: 2%">
<span>Request type : </span>
<select v-model="requestType" @change="loadRequests()">
<option>inscription</option>
<option>scholarship</option>
<option>exemption</option>
<option>unregister</option>
<option>curriculum change</option>
</select>
<span style="margin-left: 5%">
Filter :
<select v-model="filterType">
<option>None</option>
<option>Pending</option>
<option>Accepted</option>
<option>Refused</option>
</select>
</span>
</div>
<div style='display:flex; justify-content:center; min-width:1140px;' v-for="item of requests">
<div class="bodu" style="width: 95%" v-if="filterType == 'None' || filterType == item.state">
<div class="container" style="grid-template-columns:11% 15% 20% 10% 10% 9% 9%;grid-template-areas:'date state equivalencestate surname firstname accept refuse infos';" v-if="requestType === 'inscription'">
<!--
The condition below avoids an error occuring because loadRequests() finishes after the vue refresh
then submissionDate is undefined an it triggers an error in the console despite the fact that it is working
properly at the end.
-->
<div class="date" v-if="item.submissionDate !== undefined">{{item.submissionDate.slice(0, 10)}}</div>
<div class="state" style="font-size: 80%">Approval : {{item.state}}</div>
<div class="equivalencestate" style="font-size: 80%">Teacher approval : {{item.equivalenceState}}</div>
<div class="surname">{{item.lastName}}</div>
<div class="firstname">{{item.firstName}}</div>
<div class="accept" v-if="item.state === 'Pending'"><button @click="windowsState=2;targetId=item.id;" style="background-color:rgb(0,105,50);">{{i18n("request.accept")}}</button></div>
<div class="refuse" v-if="item.state === 'Pending'"><button @click="upPage(item.id,'Refused')" style="background-color:rgb(105,0,0);">{{i18n("request.refuse")}}</button></div>
<div class="infos"><button style="background-color:rgb(105,05,105);" @click="targetId=item.id;windowsState=1;">{{i18n("request.moreInfos")}}</button></div>
</div>
<div class="container" style="grid-template-columns:25% 15% 15% 25% 14.2%;grid-template-areas:'date reqState studentfirstname studentlastname infos';" v-if="requestType === 'scholarship'">
<div class="date" v-if="item.date !== undefined"> {{item.date.slice(0,10)}}</div>
<div class="studentfirstname">{{item.user.firstName}}</div>
<div class="studentlastname">{{item.user.lastName}}</div>
<div class="reqState">{{item.state}}</div>
<div class="infos" @click="windowsState = 3; targetId=item.id;"><button>More infos</button></div>
</div>
<div class="container" style="grid-template-columns:17% 15% 12% 15% 25%;grid-template-areas:'date reqState studentfirstname studentlastname course infos';"v-if="requestType === 'exemption'">
<div class="date" v-if="item.date != undefined">{{item.date.slice(0,10)}}</div>
<div class="studentfirstname">{{item.user.firstName}}</div>
<div class="studentlastname">{{item.user.lastName}}</div>
<div class="course">{{item.course.title}}</div>
<div class="reqState">{{item.state}}</div>
<div class="infos"><button @click="windowsState=6;targetId=item.id">More infos</button></div>
</div>
<div class="container" v-if="requestType === 'unregister'" style="grid-template-columns:17% 15% 12% 15%;grid-template-areas:'date reqState regno studentfirstname studentlastname infos';">
<div class="date" v-if="item.date != undefined">{{item.date.slice(0,10)}}</div>
<div class="studentfirstname">{{item.firstName}}</div>
<div class="studentlastname">{{item.lastName}}</div>
<div class="regno">id : {{item.regNo}}</div>
<div class="reqState">{{item.state}}</div>
<div class="infos"><button @click="windowsState=4;targetId=item.id">More infos</button></div>
</div>
<div class="container" v-if="requestType === 'curriculum change'" style="grid-template-columns:17% 20% 15% 5%;grid-template-areas:'date reqState teacherApproval regno studentfirstname studentlastname infos';">
<div class="date" v-if="item.date != undefined">{{item.date.slice(0,10)}}</div>
<div class="studentfirstname">{{item.user.firstName}}</div>
<div class="studentlastname">{{item.user.lastName}}</div>
<div class="reqState">IS approval : {{item.state}}</div>
<div class="teacherApproval">Teacher approval : {{item.teacherApprovalState}}</div>
<div class="infos"><button @click="windowsState=5;targetId=item.id">More infos</button></div>
</div>
</div>
</div>
</div>
<div style='display:flex; justify-content:center; min-width:1140px;margin-top: 10%' v-if="windowsState === 2">
<p>Etes vous sur de vouloir accepter cette demande ?</p>
<button style="background-color:rgb(105,05,105);" @click="upPage(targetId,'Accepted');windowsState=0;">Valider</button>
<button style="background-color:rgb(105,05,105);" @click="windowsState=0;">Retour</button>
</div>
<div v-if="windowsState === 3">
<AboutScholarship :req-id="targetId"></AboutScholarship>
<div>
<button style="margin-left: 30%" @click="loadRequests();windowsState=0">Back</button>
</div>
</div>
<div v-if="windowsState === 4">
<AboutUnregister :req-id="targetId"></AboutUnregister>
<button @click="windowsState=0">Back</button>
</div>
<div v-if="windowsState === 5">
<AboutChangeCurriculum :req-id="targetId" v-model:window-state="windowsState"></AboutChangeCurriculum>
</div>
<div v-if="windowsState === 6">
<AboutExemption :req-id="targetId" v-model:window-state="windowsState"></AboutExemption>
</div>
</template>
<style scoped>
.container{
color:white;
height:100px;
font-size:20px;
display:grid;
column-gap:10px;
}
.equivalencestate{
grid-area: equivalencestate;
align-self: center;
}
.teacherApproval{
grid-area: teacherApproval;
align-self: center;
}
.studentfirstname{
grid-area: studentfirstname;
align-self: center;
}
.studentlastname{
grid-area: studentlastname;
align-self: center;
}
.course{
grid-area: course;
align-self: center;
}
.reqState{
grid-area: reqState;
align-self: center;
}
.infos {
grid-area:infos;
align-self:center;
}
.accept{
grid-area:accept;
align-self:center;
}
.refuse{
grid-area:refuse;
align-self:center;
}
.date{
grid-area:date;
margin-left:40px;
align-self:center;
}
.regno{
grid-area: regno;
align-self: center;
}
.state{
grid-area:state;
margin-left:40px;
align-self:center;
}
.surname{
grid-area:surname;
align-self:center;
white-space: nowrap;
overflow: hidden;
text-overflow:ellipsis;
}
.firstname{
grid-area:firstname;
align-self:center;
white-space: nowrap;
overflow: hidden;
text-overflow:ellipsis;
}
button{
font-size:15px;
height:50px;
width:100px;
border:none;
border-radius:20px;
}
.bodu {
margin-top:2%;
width:66%;
border:2px solid black;
border-radius:9px;
background-color:rgb(50,50,50);
}
</style>

View File

@ -0,0 +1,77 @@
<script setup>
import i18n from "@/i18n.js";
import {ref} from "vue";
import {getAllPayments} from "@/rest/requests.js";
const paymentsList = await getAllPayments()
</script>
<template style="margin-top:5%;">
<div style="display:flex; justify-content:center; " v-for="item in paymentsList">
<div class="bodu">
<div class="container">
<div class="regNo"><a style="margin-left:30px">RegNo : {{item.studentRegNo}}</a></div>
<div class="client"><a>Client : {{item.client}}</a></div>
<div class="amount"><a>Amount : {{item.amount}}</a></div>
<div class="date" style="margin-left: 10%">{{item.date.slice(0,10)}}</div>
</div>
</div>
</div>
</template>
<style scoped>
.container{
color:white;
height:100px;
font-size:30px;
display:grid;
grid-template-columns:20% 25% 15% 17%;
grid-template-areas:
"date regNo client amount";
column-gap:10px;
}
.regNo {
grid-area:regNo;
align-self:center;
font-size: 70%;
}
.client{
grid-area:client;
align-self:center;
font-size: 70%;
}
.amount{
grid-area:amount;
align-self:center;
font-size: 70%;
}
.date{
grid-area:date;
align-self:center;
font-size: 70%;
}
button{
font-size:15px;
height:50px;
width:75%;
border:none;
border-radius:20px;
}
.bodu {
margin-top:2%;
width:66%;
border:2px solid black;
border-radius:9px;
background-color:rgb(50,50,50);
}
</style>

View File

@ -1,16 +1,18 @@
<script setup> <script setup>
import {reactive, ref } from 'vue' import {reactive, ref } from 'vue'
import i18n from '@/i18n.js' import i18n from '@/i18n.js'
import { login , register , disconnect, isLogged} from '@/rest/Users.js' import {login, register, disconnect, isLogged} from '@/rest/Users.js'
import { getAllCurriculums } from '@/rest/curriculum.js' import {getAllCurriculums, getcurriculum} from '@/rest/curriculum.js'
import { uploadProfilePicture } from '@/rest/uploads.js' import {uploadFile, uploadProfilePicture} from '@/rest/uploads.js'
import {toast} from 'vue3-toastify' import {toast} from 'vue3-toastify'
import 'vue3-toastify/dist/index.css'; import 'vue3-toastify/dist/index.css';
import {createExternalCurriculum} from "@/rest/externalCurriculum.js";
import ManageCourses from "@/Apps/ManageCourses.vue";
import ExternalCurriculumList from "@/Apps/Inscription/ExternalCurriculumList.vue";
const loginPage= ref(true) const loginPage= ref(true)
const page = ref(0) const page = ref(0)
const outputs = reactive({ const outputs = reactive({
surname:null, surname:null,
firstname:null, firstname:null,
@ -20,13 +22,35 @@
address:null, address:null,
country:null, country:null,
curriculum:null, curriculum:null,
equivalenceState: "Unrequired"
}) })
const notcompletedCheck = ref(false);
const externalCurr = reactive({
inscriptionRequestId : null,
school:null,
formation :null,
completion : null,
startYear : null,
endYear: null,
justifdocUrl : null
})
//Stores some externalCurriculums in order to upload them all at the confirmation of the registration request
const externalCurrTab = ref([]);
const submitValue= ref(i18n("login.guest.submit")) const submitValue= ref(i18n("login.guest.submit"))
const passwordConfirm=ref("") const passwordConfirm=ref("")
const imageSaved = ref(false) const imageSaved = ref(false)
const ppData = ref(false) let ppData = ""
let requiredCertif = false
//Contains the id of the newly created request (useful to link the student's formations informations to the request)
let requestId = ""
const idcardfile = ref({})
const justifcardfile = ref({})
const curricula= await getAllCurriculums(); const curricula= await getAllCurriculums();
@ -34,7 +58,7 @@
setTimeout(() => { setTimeout(() => {
window.location.href="#/home"; window.location.href="#/home";
}, "500"); }, "500");
} }
function verifyInputs(pass){ function verifyInputs(pass){
if(pass==passwordConfirm.value){ if(pass==passwordConfirm.value){
page.value++; page.value++;
@ -50,14 +74,50 @@
disconnect(); disconnect();
window.location.reload();} window.location.reload();}
async function uploadPP(arg){
const data = await uploadProfilePicture(arg);
ppData = data.url;
}
//This functions makes the distinction between a master cursus (year 4 or more) and a bachelor cursus (year 3 or less)
function getCursusDisplay(cursus){
if (cursus.year <= 3){
return "BAB " + cursus.year + " " + cursus.option;
}else{
return "MA" + (parseInt(cursus.year)-3).toString() + " " + cursus.option;
}
}
//Post the register request and return the id of the newly created request and also post the external curriculum list in the database
async function postRegisterReq(){
//We upload the two files and we get their paths on the server
const identityCardFile = await uploadFile(idcardfile.value, "IdentityCard")
const justifFile = ref(null)
if (curricula[outputs.curriculum-1].requireCertificate){
justifFile.value = await uploadFile(justifcardfile.value, "JustificationDocument")
}
let justif;
if (justifFile.value !== null){
justif = justifFile.value.url
}else{
justif = null
}
const val = await register(outputs.firstname, outputs.surname, outputs.birthday, outputs.password, outputs.email, outputs.address, outputs.country, outputs.curriculum, ppData, identityCardFile.url, new Date(), outputs.equivalenceState, justif);
for (let item in externalCurrTab.value){
await createExternalCurriculum(val.id, externalCurrTab.value[item].school, externalCurrTab.value[item].formation, externalCurrTab.value[item].completion, externalCurrTab.value[item].startYear, externalCurrTab.value[item].endYear, externalCurrTab.value[item].justifdocUrl);
}
}
</script> </script>
<template> <template>
<div class="setup"> <div class="setup" v-if="page !== 4">
<div v-if="loginPage"> <div v-if="loginPage">
<div class='loginBox' style="margin-top:30%;"> <div class='loginBox' style="margin-top:30%;">
<form @submit.prevent="login(outputs.email,outputs.password);goBackHome();"class="form"> <form @submit.prevent="login(outputs.email,outputs.password);goBackHome();"class="form">
<h1 style="color:rgb(239,60,168); font-family: sans-serif;"> <h1 style="color:rgb(239,60,168); font-family: sans-serif;">
@ -116,7 +176,7 @@
<a>{{i18n("login.guest.alregister")}}</a> <a>{{i18n("login.guest.alregister")}}</a>
</div> </div>
</div> </div>
<div v-else> <div v-if="page === 1">
<div class="inputBox"> <div class="inputBox">
<p>{{i18n("login.guest.email")}}</p> <p>{{i18n("login.guest.email")}}</p>
<input type="mail" v-model="outputs.email"> <input type="mail" v-model="outputs.email">
@ -129,23 +189,30 @@
<p>{{i18n("login.guest.country")}}</p> <p>{{i18n("login.guest.country")}}</p>
<input type="text" v-model="outputs.country"> <input type="text" v-model="outputs.country">
</div> </div>
<form class="inputBox"novalidate enctype="multipart/form-data"> <form class="inputBox" novalidate enctype="multipart/form-data">
<p>{{i18n("profile.picture").toUpperCase()}}</p> <p>{{i18n("profile.picture").toUpperCase()}}</p>
</form>
<label class="browser"> <label class="browser">
Parcourir . . . Parcourir . . .
<input type="file" :disabled="imageSaved" @change="ppData = uploadProfilePicture($event.target.files); imageSaved = true;" accept="image/*"> <input type="file" :disabled="imageSaved" @change="ppData = uploadProfilePicture($event.target.files); imageSaved = true;" accept="image/*">
</label> </label>
<form novalidate enctype="multipart/form-data" class="inputBox">
<p>{{i18n("profile.picture").toUpperCase()}}</p>
<input type="file" @change="uploadPP($event.target.files); imageSaved = true;" accept="image/*">
</form> </form>
<div class="inputBox"> <div class="inputBox">
<p>{{i18n("Curriculum").toUpperCase()}}</p> <p>{{i18n("Curriculum").toUpperCase()}}</p>
<select v-model="outputs.curriculum"> <select v-model="outputs.curriculum">
<option v-for="item in curricula">{{item.curriculumId}}</option> <option v-for="item in curricula" :value="item.curriculumId">{{getCursusDisplay(item)}}</option>
</select> </select>
</div> </div>
<p style="color:rgb(239,60,168);">
Si vous êtes déja inscrits dans cette université veuillez vous connecter a votre compte et utilisez les fonctions
changer de cursus/réinscription sinon continuez ici.
</p>
<div style="align-self:center;" class="inputBox"> <div style="align-self:center;" class="inputBox">
<button style="margin-top:25px;" @click="register(outputs.firstname, outputs.surname, outputs.birthday, outputs.password, outputs.email, outputs.address, outputs.country, outputs.curriculum, ppData);"> <button style="margin-top:25px;" @click="page++;">
{{i18n("login.guest.submit")}} {{i18n("login.guest.nextpage")}}
</button> </button>
</div> </div>
<div class="switchpage"> <div class="switchpage">
@ -155,10 +222,41 @@
<a>{{i18n("login.guest.alregister")}}</a> <a>{{i18n("login.guest.alregister")}}</a>
</div> </div>
</div> </div>
<div v-if="page === 2">
<p style="color:rgb(239,60,168);">Carte d'indentité :</p>
<label class="browser">
Parcourir . . .
<input type="file" @change="idcardfile = $event.target.files">
</label>
<div v-if="curricula[outputs.curriculum-1].requireCertificate === true" style="margin-top: 3%; margin-bottom: 4%">
<p style="color:rgb(239,60,168);">Ce cursus requiert une attestation de réussite d'un examen d'entrée</p>
<div style="margin-top: 2%">
<p style="color:rgb(239,60,168);">Attestation:</p>
<label class="browser">
Parcourir . . .
<input type="file" @change="justifcardfile = $event.target.files">
</label>
</div>
</div>
<button @click="page++;">{{i18n("login.guest.nextpage")}}</button>
</div>
<div v-if="page === 3">
<p>
Vous avez séléctionné un cursus qui possède des prérequis veuillez ajouter vos formations antérieures
dans l'enseignement supérieur, votre dossier sera vérifié par un membre du service d'inscription.
</p>
<button @click="page++">Gèrer mon parcours extérieur</button>
<button @click="postRegisterReq();">Envoyer la demande d'inscription</button>
</div>
</form> </form>
</div> </div>
</div> </div>
</div> </div>
<div v-if="page===4">
<ExternalCurriculumList v-model="externalCurrTab" :mode="2"></ExternalCurriculumList>
<button style="margin-top: 2%;width: 5%; margin-left: 2%" @click="page--">Back</button>
</div>
</template> </template>
<style scoped> <style scoped>
@ -167,18 +265,18 @@
margin-left: auto; margin-left: auto;
margin-right:auto; margin-right:auto;
min-width:400px; min-width:400px;
width:25%; width:25%;
height:60%; height:50%;
} }
.loginBox { .loginBox {
background-color: rgb(24,24,24); background-color: rgb(24,24,24);
width: 400px;
display:flex; display:flex;
justify-content: center; justify-content: center;
border-radius: 5%; border-radius: 5%;
box-shadow:0 5px 25px #000000; box-shadow:0 5px 25px #000000;
} }
.form { .form {
position:relative; position:relative;
@ -208,7 +306,7 @@
z-index: 100; z-index: 100;
font-family:sans-serif ; font-family:sans-serif ;
color:rgb(239,60,168); color:rgb(239,60,168);
transition:0.5; transition: 0.5;
} }
@ -220,9 +318,16 @@
cursor: pointer; cursor: pointer;
} }
.bodu {
margin-top:2%;
width:50%;
border:2px solid black;
border-radius:9px;
background-color:rgb(50,50,50);
}
.switchpage{ .switchpage{
width:100px; width:100px;
background:rgb(255, 0 255);
border: none; border: none;
padding-right:0; padding-right:0;
padding-top:10px; padding-top:10px;
@ -230,7 +335,7 @@
outline:none; outline:none;
border-radius: 4px; border-radius: 4px;
font-size:0.8em; font-size:0.8em;
align-self:right; align-self: right;
} }
@ -260,11 +365,22 @@ input[type=file]{
background:#FFFFFF; background:#FFFFFF;
} }
.container{
margin-top: 2%;
color:white;
height:60px;
font-size:30px;
display:grid;
grid-template-columns:30% 30% 20% 20%;
grid-template-areas:
"school formation completion edit remove";
column-gap:10px;
}
button:active ,.switchpage:active{ button:active ,.switchpage:active{
opacity:0.8; opacity:0.8;
} }
</style> </style>

213
frontend/src/Apps/Msg.vue Normal file
View File

@ -0,0 +1,213 @@
<!----------------------------------------------------
File: Msg.vue
Author: Anthony Debucquoy
Scope: Extension messagerie
Description: Main msg page
----------------------------------------------------->
<script setup>
import { ref, reactive } from 'vue'
import { discussionsList, currentDiscussion, fetchDiscussion, createDiscussion, sendMessage, updateDiscussionName, invite, removeMember} from '@/rest/msg.js'
const msgContent = ref("");
const addMember = ref(false);
const currentTitle = ref("");
function formatTime(date){
return date.getHours() + ":" + date.getMinutes() + " " + date.getDate() + "/" + date.getMonth();
}
</script>
<template>
<div id="msg">
<div id="discList">
<div @click="fetchDiscussion(discussion.id).then(e => currentTitle = currentDiscussion.name)" class="discItem" v-for="discussion in discussionsList" :key="discussion.id">{{ discussion.name }}</div>
<button id="createDiscussion" @click="createDiscussion('New Discussion')">+</button>
</div>
<div id="discussion" v-if="currentDiscussion.length != 0">
<h1 id=msgName ><input class="InputTitle" type="text" @change="updateDiscussionName(currentDiscussion.id, currentTitle)" v-model="currentTitle"></h1>
<div id=msgs>
<div class="msg" v-for="msg in currentDiscussion.msgs" :sender="msg.sender" :key="msg.id">
{{ msg.content }}<br/>
<span class="sender"><span v-if="!msg.sender">{{ msg.author.firstName }} {{ msg.author.lastName.toUpperCase() }}</span> {{formatTime(new Date(msg.created))}}</span>
</div>
</div>
<div id=messageBox>
<input type="text" @keyup.enter="sendMessage(currentDiscussion.id, msgContent, null); msgContent = ''" v-model="msgContent">
<input type="submit" @click="sendMessage(currentDiscussion.id, msgContent, null); msgContent = ''" value="send">
</div>
</div>
<div id="members" v-if="currentDiscussion.length != 0">
<div class="memberItem" v-for="member in currentDiscussion.members" @click="removeMember(currentDiscussion.id, member.regNo)" :key="member.id"><span>{{ member.firstName }} {{ member.lastName.toUpperCase() }}</span></div>
<input type=text id="addMembers" @focus="addMember = true" @blur="addMember = false;$event.target.value = ''" @change="invite(currentDiscussion.id, $event.target.value)" :placeholder="addMember ? 'Regno' : '+'"/>
</div>
</div>
</template>
<style scoped>
div#msg{
position: relative;
width: 100%;
height: 100%;
display: grid;
grid-template-columns: 20% auto 10%;
}
div#discList{
margin: 30px 0 30px 30px;
background-color: rgba(255, 255, 255, 0.05);
border-radius: 10px;
overflow: hidden;
padding: 10px;
display: flex;
flex-direction: column;
}
div#members{
margin: 30px 0;
border-radius: 10px 0 0 10px;
background-color: red;
background-color: rgba(255, 255, 255, 0.05);
overflow: hidden;
display: flex;
padding: 10px 0 0 10px;
flex-direction: column;
}
.InputTitle{
all: inherit;
margin: auto;
}
.discItem{
color: darkorange;
display: flex;
font-family: sans-serif;
font-weight: bold;
height: 4vh;
margin: 5px;
border-radius: 0 30px 30px 0;
align-items: center;
justify-content: center;
border: 1px solid darkorange;
}
.memberItem{
color: darkorange;
display: flex;
font-family: sans-serif;
font-weight: bold;
height: 4vh;
margin: 5px;
border-radius: 30px 0 0 30px;
align-items: center;
justify-content: center;
border: 1px solid darkorange;
}
.memberItem:hover span{
display: none;
}
.memberItem:hover{
background-color: red;
}
.memberItem:hover:before{
color: white;
content: "X"
}
#createDiscussion{
height: 4vh;
margin: 5px;
color: white;
background-color: green;
border-radius: 0 30px 30px 0;
border: none;
font-weight: 900;
font-size: 2em;
}
#addMembers{
height: 4vh;
margin: 5px;
text-align: center;
color: white;
background-color: green;
border-radius: 30px 0 0 30px;
border: none;
font-weight: 900;
font-size: 2em;
}
div#discussion{
display: flex;
flex-direction: column;
margin: 30px;
background-color: rgba(255, 255, 255, 0.05);
border-radius: 10px;
overflow: hidden;
}
#msgName{
text-align: center;
display: block;
background-color: #2a1981;
border-radius: 5px;
color: white;
width: 75%;
margin: 30px auto;
}
.discItem:hover{
background-color: gray;
}
#msgs{
display: flex;
flex-grow: 1;
flex-direction: column;
}
.msg {
background-color: aliceblue;
font-family: sans-serif;
margin: 10px;
padding: 5px;
border-radius: 3px;
max-width: 50%;
align-self: start;
}
.sender{
display: inline-block;
color: gray;
font-size: 0.5em;
}
.msg[sender=true]{
background-color: darkorange;
align-self: end;
}
#messageBox{
width: 100%;
height: 30px;
background-color: white;
display: flex;
}
#messageBox input[type="text"]{
all: inherit;
padding: 0 10px;
}
#messageBox input[type="submit"]{
border: inherit;
padding: 0 10px;
}
</style>

View File

@ -1,24 +1,39 @@
<script setup> <script setup>
import {reactive, ref } from 'vue' import {reactive, ref } from 'vue'
import {getSelf,alterSelf,disconnect,deleteUser} from '../rest/Users.js' import {getSelf,alterSelf,disconnect,deleteUser} from '../rest/Users.js'
import {getSelfCurriculum, getAllCurriculums} from '../rest/curriculum.js' import {getSelfCurriculum, getAllCurriculums, getSomeonesCurriculumList, getcurriculum} from '../rest/curriculum.js'
import {getCourses} from "../rest/courses.js" import {getCourses} from "../rest/courses.js"
import i18n from "@/i18n.js" import i18n from "@/i18n.js"
import { uploadProfilePicture } from '@/rest/uploads.js' import {uploadFile, uploadProfilePicture} from '@/rest/uploads.js'
import CourseList from "@/Apps/Inscription/CourseList.vue";
import {editMinerval, getCurrentMinerval} from "@/rest/minerval.js";
import {postPayment} from "@/rest/payment.js";
import {addUninscReq, createScholarshipRequest, postChangeCurrReq} from "@/rest/requests.js";
import ExternalCurriculumList from "@/Apps/Inscription/ExternalCurriculumList.vue";
import {getExternalCurriculumByUser} from "@/rest/externalCurriculum.js";
const user = ref(await getSelf()); const user = ref(await getSelf());
const UserCurriculum = ref(""); const UserCurriculum = ref("");
const curricula = ref (await getAllCurriculums()); const curricula = ref (await getAllCurriculums());
const minerv = ref({});
const extcurrlist = ref(await getExternalCurriculumByUser(user.value.regNo))
if(user.value.role === "Student"){ if(user.value.role === "Student"){
UserCurriculum.value = await getSelfCurriculum(); minerv.value = ref(await getCurrentMinerval(user.value.regNo));
UserCurriculum.value = await getSomeonesCurriculumList(user.value.regNo);
} }
if(user.role === "Teacher"){ if(user.role === "Teacher"){
UserCurriculum.value = await getCourses("Teacher"); UserCurriculum.value = await getCourses("Teacher");
} }
const modif = ref(false);
const curric = ref(false); const sure = ref(0);
const reg = ref(false);
//0 base, 1 modif, 2 curriculum, 3 register, 4 courselist, 5 minerval, 6 payment, 7 scholarship, 8 scholarshipinfos, 9 unregister, 10 sure, 11 aboutunregister, 12 manage external curriculums
const windowState = ref(0);
const isChecked = ref(false);
const reRegState = ref(0);
const pattern = { const pattern = {
profilPictureUrl:null, profilPictureUrl:null,
@ -34,27 +49,61 @@
id:null, id:null,
} }
//Used to modelize a payment
const paymentData={
studentRegNo: user.value.regNo,
date:null,
card:null,
client:null,
expDate:null,
amount: null
}
//Used to modelize a scholarship request
const scholarshipData=reactive({
userId: user.value.regNo,
state:null,
date:null,
amount:0,
taxDocUrl : "",
residencyDocUrl : ""
})
const changecurrdata = reactive({
userId : user.value.regNo,
actualcursus:null,
newcursus:1
})
//Used to post a uninscription request
const uninscriptionData = reactive({
reason : null,
userId : user.value.regNo,
curriculumId:null
})
const paymentAmount = ref(0);
let toModify= Object.assign({}, pattern); let toModify= Object.assign({}, pattern);
let personnalInfos = Object.assign({}, patternInfos); let personnalInfos = Object.assign({}, patternInfos);
//Used to store the year of the new cursus selected in change cursus feature
const selectedYear = ref(0);
function resetInputs(inputs,list){ function resetInputs(inputs,list){
inputs=Object.assign({},list); inputs=Object.assign({},list);
} }
async function ChangeInfos(){ async function ChangeInfos(){
for (let element in toModify){ for (let element in toModify){
if (element =="email" && (toModify[element] !== null)){ if (element ==="email" && (toModify[element] !== null)){
await alterSelf(user.value.regNo,{email : toModify[element]}); await alterSelf(user.value.regNo,{email : toModify[element]});
} }
if (element =="profilPictureUrl" && (toModify[element] !== null)){ if (element ==="profilPictureUrl" && (toModify[element] !== null)){
await alterSelf(user.value.regNo,{ profilPictureUrl : toModify[element]}); await alterSelf(user.value.regNo,{ profilPictureUrl : toModify[element]});
} }
else if(element == "address" && (toModify[element] !== null)){ else if(element === "address" && (toModify[element] !== null)){
await alterSelf(user.value.regNo,{address : toModify[element]}); await alterSelf(user.value.regNo,{address : toModify[element]});
} }
else if(element == "password" && (toModify[element] !== null)){ else if(element === "password" && (toModify[element] !== null)){
await alterSelf(user.value.regNo,{password : toModify[element]}); await alterSelf(user.value.regNo,{password : toModify[element]});
} }
} }
@ -86,17 +135,75 @@
} }
return user.profilePictureUrl return user.profilePictureUrl
} }
function getYear(){
let date = new Date();
if (date.getMonth() <= 6){
return date.getFullYear()-1
}
return date.getFullYear()
}
async function refreshExtCurrList(){
extcurrlist.value = await getExternalCurriculumByUser(user.value.regNo)
}
//This function travels through the student cursus array and extract the current cursus of the student
function getActualCurriculumList(){
let actualCurriculumList = [];
for (let i = 0; i < UserCurriculum.value.curriculumList.length; i++){
if (UserCurriculum.value.curriculumList[i].actual === true){
actualCurriculumList.push(UserCurriculum.value.curriculumList[i]);
}
}
return actualCurriculumList
}
async function postScholarshipRequest(file1, type1, file2, type2){
const a = await uploadFile(file1, type1)
scholarshipData.taxDocUrl = a.url;
const b = await uploadFile(file2, type2)
scholarshipData.residencyDocUrl = b.url;
scholarshipData.date = Date.now();
await createScholarshipRequest(scholarshipData)
}
//1 = previous 0 = next
function getCurriculumsNextYear(){
const currlist = getActualCurriculumList()
let list = []
for (let i = 0; i < currlist.length; i++){
for (let j = 0; j < curricula.value.length; j++){
if (curricula.value[j].option === currlist[i].option && curricula.value[j].year === currlist[i].year + 1){
list.push(curricula.value[j])
}
}
}
return list
}
async function getActualCurr(curr){
const cursus = await getcurriculum(curr);
for (let i = 0; i < curricula.value.length; i++){
if (curricula.value[i].option === cursus.option && curricula.value[i].year === cursus.year - 1){
changecurrdata.actualcursus = curricula.value[i].curriculumId;
}
}
}
</script> </script>
<template> <template>
<div class="body"> <div class="body" v-if="windowState !== 12">
<div class="container"> <div class="container" v-if="windowState!==4">
<div class="profilPic"> <div class="profilPic" v-if="windowState===0">
<img class="subContainter" :src=getPP()> <img class="subContainter" :src=getPP()>
</div> </div>
<div class="globalInfos"> <div class="globalInfos">
<div v-if="modif==false && curric==false && reg==false " class="infosContainer" > <div v-if="windowState === 0" class="infosContainer">
<div> <div>
{{user.firstName}} {{user.lastName}} {{user.firstName}} {{user.lastName}}
</div> </div>
@ -110,24 +217,111 @@
Role: {{i18n((user.role))}} Role: {{i18n((user.role))}}
</div> </div>
<div> <div>
<button @click="modif=!modif; setModify(user)"> {{i18n("profile.modify.data")}} </button> <button @click="windowState=1; setModify(user)"> {{i18n("profile.modify.data")}} </button>
</div> </div>
<div v-if="(user.role==='Student')"> <div v-if="(user.role==='Student')">
<button @click="reg=!reg">{{i18n("profile.reRegister")}}</button> <button @click="windowState=3">{{i18n("profile.reRegister")}}</button>
<button @click="unRegister()" style="float:right;background-color:rgb(150,0,0);">{{i18n("profile.unRegister")}}</button> <button @click="windowState=9" style="float:right;background-color:rgb(150,0,0);">{{i18n("profile.unRegister")}}</button>
</div> </div>
<div v-if="(user.role==='Student')"> <div v-if="(user.role==='Student')">
<button @click="curric=!curric">{{i18n("profile.change.curriculum")}}</button> <button @click="windowState=2">{{i18n("profile.change.curriculum")}}</button>
<button @click="windowState=12;refreshExtCurrList() ">Manage external curriculums</button>
</div>
<div v-if="(user.role==='Student')">
<button @click="windowState=4">Manage Courses</button>
<button @click="windowState=5" style="margin-left: 2%">Manage minerval</button>
</div> </div>
</div> </div>
<div v-else-if="modif" class="infosContainer"> <div v-else-if="windowState === 9" class="infosContainer">
<div v-if="sure !== 2">Please enter the reason you leave</div>
<textarea v-if="sure !== 2" v-model="uninscriptionData.reason"></textarea>
<div v-if="sure !== 2">
I only want to unregister from a specific cursus
<input type="checkbox" v-model="isChecked">
</div>
<div v-if="sure !== 2 && isChecked">
Please select that cursus
<select v-model="uninscriptionData.curriculumId">
<option v-for="item in getActualCurriculumList()" :value="item.curriculumId">Bac {{item.year}} {{item.option}}</option>
</select>
</div>
<div v-if="sure !== 2">
<button @click="sure++">Submit</button>
</div>
<div v-if="sure==1">
Are you sure that you want to unregister ?
<button @click="addUninscReq(uninscriptionData.userId, uninscriptionData.reason, uninscriptionData.curriculumId);sure++">Yes</button>
<button @click="sure=0">No</button>
</div>
<p v-if="sure==2">You request has been send !</p>
</div>
<div v-else-if="windowState === 5" class="infosContainer">
<div v-if="minerv.value.toPay !== 0">
Payment : {{minerv.value.toPay}} left to pay
<div v-if="minerv.value.paidAmount <= 50">
<button @click="windowState=6; paymentAmount = 50">Pay deposit (50)</button>
</div>
<div>
<button @click="windowState=6; paymentAmount = minerv.value.toPay">Pay all the rest ({{minerv.value.toPay}})</button>
</div>
</div>
<div v-else>
Payment : School fees have already been paid this year
</div>
<div>
<button @click="windowState=7">Ask for a scholarship</button>
</div>
</div>
<div v-else-if="windowState === 7" class="infosContainer">
<p>Please upload the required documents</p>
<div>
Tax justification document :
<input type="file" @change="scholarshipData.taxDocUrl = $event.target.files">
</div>
<div>
Residency justification document :
<input type="file" style="margin-top:2%" @change="scholarshipData.residencyDocUrl = $event.target.files">
</div>
<button style="margin-top: 5%" @click="windowState=8;postScholarshipRequest(scholarshipData.taxDocUrl, 'JustificationDocument',scholarshipData.residencyDocUrl, 'JustificationDocument');">Submit scholarship request</button>
</div>
<div v-else-if="windowState === 8" class="infosContainer">
<div>
Your request has been sent to the inscription service you will get notified when
the request is reviewed.
</div>
<button @click="windowState = 0">
Go back to profile
</button>
</div>
<div v-else-if="windowState === 6" class="infosContainer">
Proceed to payment of {{paymentAmount}}
<div style="margin-top: 1%">
Client:
<input type="text" v-model="paymentData.client">
</div>
<div style="margin-top: 1%">
Card:
<input type="text" v-model="paymentData.card">
</div>
<div style="margin-top: 1%">
ExpDate:
<input type="date" v-model="paymentData.expDate">
</div>
<div style="margin-top: 1%">
<button @click="windowState=5;paymentData.amount=paymentAmount;paymentData.date=new Date();postPayment(paymentData);minerv.value.toPay -= paymentAmount; minerv.value.paidAmount += paymentAmount; editMinerval(minerv.value)">Process Payment</button>
</div>
<div>
<button @click="windowState = 5">Back</button>
</div>
</div>
<div v-else-if="windowState === 1" class="infosContainer">
<div> <div>
{{i18n("profile.picture")}}: {{i18n("profile.picture")}}:
<input type="file" @change="user.profilPicture = uploadProfilePicture($event.target.files);" accept="image/*"> <input type="file" @change="user.profilPicture = uploadProfilePicture($event.target.files);" accept="image/*">
</div> </div>
<div> <div>
E-mail: E-mail:
<input type="mail" v-model="toModify.email" /> <input type="email" v-model="toModify.email" />
</div> </div>
<div> <div>
{{i18n("profile.address")}}: {{i18n("profile.address")}}:
@ -142,27 +336,53 @@
<input type="password" v-model="toModify.passwordConfirm"> <input type="password" v-model="toModify.passwordConfirm">
</div> </div>
<div> <div>
<button @click=" modif=!modif; ChangeInfos();">{{i18n("courses.confirm")}}</button> <button @click="windowState = 0; ChangeInfos();">{{i18n("courses.confirm")}}</button>
<button @click="modif=!modif; resetInputs(toModify,pattern);" style="float:right;">{{i18n("courses.back")}}</button> <button @click="windowState = 0; resetInputs(toModify,pattern);" style="float:right;">{{i18n("courses.back")}}</button>
</div> </div>
</div> </div>
<div v-else-if="curric" class="infosContainer"> <div v-else-if="windowState === 2" class="infosContainer">
<div style="height:40px;"> <div>
{{i18n("Curriculum")}}: I would like to :
<select v-model="curriculum" > <select v-model="reRegState">
<option v-for="item in curricula" style="font-size:20px;" :value="item">{{item.option}}</option> <option :value="1">Reregister in the next year of one of my cursus</option>
<option :value="2">Register for a supplementary cursus</option>
<option :value="3">Change from a cursus to another</option>
</select> </select>
</div> </div>
<div style="height:40px;" v-if="reRegState === 3">
{{i18n("Curriculum")}}:
<select v-model="changecurrdata.actualcursus" style="margin-right: 3%">
<option v-for="item in getActualCurriculumList()" style="font-size:20px;" :value="item.curriculumId">Bac {{item.year}} {{item.option}}</option>
</select>
New Curriculum :
<select v-model="changecurrdata.newcursus">
<option v-for="item in curricula" :value="item.curriculumId">Bac {{item.year}} {{item.option}}</option>
</select>
</div>
<div style="height:40px;" v-if="reRegState === 2">
New Curriculum :
<select v-model="changecurrdata.newcursus">
<option v-for="item in curricula" :value="item.curriculumId">Bac {{item.year}} {{item.option}}</option>
</select>
</div>
<div style="height:40px;" v-if="reRegState === 1">
New Curriculum :
<select v-model="changecurrdata.newcursus" @change="getActualCurr(changecurrdata.newcursus);">
<option v-for="item in getCurriculumsNextYear()" :value="item.curriculumId">Bac {{item.year}} {{item.option}}</option>
</select>
</div>
<div v-if="curricula[changecurrdata.newcursus-1].year > 1 && reRegState !== 1">
The cursus you selected has some prerequisites
</div>
<div> <div>
<button @click=" curric=!curric;">{{i18n("courses.confirm")}}</button> <button @click=" windowState = 0;postChangeCurrReq(changecurrdata);changecurrdata.actualcursus=null;changecurrdata.newcursus=1">{{i18n("courses.confirm")}}</button>
<button @click="curric=!curric; resetInputs(personnalInfos,patternInfos);" style="float:right;">{{i18n("courses.back")}}</button> <button @click="windowState = 0; resetInputs(personnalInfos,patternInfos);" style="float:right;">{{i18n("courses.back")}}</button>
</div> </div>
</div> </div>
<div v-else-if="reg" class="infosContainer"> <div v-else-if="windowState === 3" class="infosContainer">
<div> <div>
E-mail: E-mail:
<input type="mail" v-model="toModify.email" /> <input type="email" v-model="toModify.email" />
</div> </div>
<div> <div>
ID : ID :
@ -178,34 +398,47 @@
</div> </div>
<div> <div>
<button @click=" reg=!reg;">{{i18n("courses.confirm")}}</button> <button @click=" windowState=0;">{{i18n("courses.confirm")}}</button>
<button @click=" reg=!reg; resetInputs(personnalInfos,patternInfos);" style="float:right;">{{i18n("courses.back")}}</button> <button @click=" windowState=0; resetInputs(personnalInfos,patternInfos);" style="float:right;">{{i18n("courses.back")}}</button>
</div> </div>
</div> </div>
</div> </div>
<div v-if="windowState === 0" class="moreInfos">
<div v-if="modif==false && curric==false && reg==false "class="moreInfos"> <div class = "oldcursus">
<div class="listTitle">
<div v-if="(user.role ==='Student')"> Anciens Cursus
<div class="listTitle"> </div>
{{i18n("profile.course.list")}} <div class="listElement">
<div class=" containerElement" v-for="item in UserCurriculum.curriculumList">
<div class="year" v-if="item.actual === false">Bac {{item.year}}</div>
<div class="option" v-if="item.actual === false">{{item.option}}</div>
<div class="dateyear" v-if="item.actual === false">Année {{item.dateyear}}-{{item.dateyear+1}}</div>
</div>
</div>
</div> </div>
<div class="listElement" v-for="item in UserCurriculum.courses"> <div class="actualcursus">
<div class=" containerElement"> <div class="listTitle">
<div class="name"> {{item.title}} </div> Cursus Actuel
<div class="teacher">{{item.owner.lastName}}</div> </div>
<div class="credits">Credits:{{item.credits}}</div> <div class="listElement">
<div class=" containerElement" v-for="item in UserCurriculum.curriculumList" >
<div class="year" v-if="item.actual === true">Bac {{item.year}}</div>
<div class="option" v-if="item.actual === true">{{item.option}}</div>
<div class="dateyear" v-if="item.actual === true">Année {{item.dateyear}}-{{item.dateyear+1}}</div>
</div>
</div>
</div> </div>
</div>
</div>
<div>
</div>
</div> </div>
</div> </div>
<div v-if="windowState===4" style="width: 80%">
<CourseList :cursuslist="getActualCurriculumList()"/>
<button style="width: 10%; margin-top: 5%" @click="windowState = 0">Return to profile</button>
</div>
</div> </div>
<div v-if="windowState === 12">
<ExternalCurriculumList :ext-curr-list="extcurrlist" :mode="1"></ExternalCurriculumList>
<button @click="windowState = 0;refreshExtCurrList()">Back to profile</button>
</div>
</template> </template>
<style scoped> <style scoped>
@ -240,7 +473,32 @@
} }
.moreInfos { .moreInfos {
grid-area:minfos; margin-top: 50%;
display:grid;
grid-template-rows:200px auto;
column-gap:50px;
row-gap:45px;
grid-template-areas:
"minfos minfos";
grid-template-columns:600px 600px;
align-items:center;
justify-content:center;
margin-left: 320%;
}
.listTitle{
display: flex;
justify-content: center;
align-items: center;
width:250px;
margin-left:auto;
margin-right:auto;
border:2px solid black;
font-size:25px;
color:white;
padding:20px;
background-color:rgb(50,50,50);
border-radius:20px;margin-bottom:10px;
} }
.body { .body {
min-width:960px; min-width:960px;
@ -248,51 +506,21 @@
display:flex; display:flex;
align-items:center; align-items:center;
justify-content:center; justify-content:center;
margin-top:5%; margin-top:7%;
} }
.containerElement{ .containerElement{
justify-content:center; justify-content:center;
display:grid; display:grid;
grid-template-columns:38.8% 38.8% 22.4%; grid-template-columns:100px 100px 300px;
grid-template-areas: grid-template-areas:
"name teacher credits"; "year option dateyear";
column-gap:10px; column-gap:40px;
padding-left: 25px;
} }
.name {
grid-area:name;
align-self:center;
}
.teacher{
grid-area:teacher;
align-self:center;
}
.credits{
grid-area:credits;
align-self:center;
}
.listTitle{
min-width:197px;
display: flex;
justify-content: center;
align-items: center;
width:8vw;
margin-left:auto;
margin-right:auto;
border:2px solid black;
font-size:25px;
color:white;
padding:20px;
background-color:rgb(50,50,50);
border-radius:20px;margin-bottom:10px;
}
.listElement{ .listElement{
min-width:625px;
border:2px solid black; border:2px solid black;
font-size:25px; font-size:25px;
color:white; color:white;

View File

@ -1,11 +1,10 @@
<script setup> <script setup>
import { ref } from 'vue' import { ref } from 'vue'
import {getDifferenceTime,lastDateOfMonth,formatDate,getFirstDay,sortByDate,matrixFromList,sundayToTheEnd,getMarginTop,getHoursMinutes, monthFromList} from '../scheduleFunctions.js' import {getDifferenceTime,lastDateOfMonth,formatDate,getFirstDay,sortByDate,matrixFromList,sundayToTheEnd,getMarginTop,getHoursMinutes, monthFromList} from '../scheduleFunctions.js'
import {getAllSchedule, getOwnSchedule, getCurriculumSchedule} from "@/rest/scheduleRest.js"; import {getAllSchedule} from "@/rest/scheduleRest.js";
import {getLessons, getOwnedLessons } from "@/rest/lessonSchedule.js" import {getOnesLessons, getOwnedLessons } from "@/rest/lessonSchedule.js"
import {isLogged, getSelf,getTeachers} from "@/rest/Users.js" import {isLogged, getSelf,getTeachers} from "@/rest/Users.js"
import {getAllCurriculums, getcurriculum} from "@/rest/curriculum.js"
const trueSchedule = ref() const trueSchedule = ref()
const log = await isLogged(); const log = await isLogged();
const schedule = ref(); const schedule = ref();
@ -42,9 +41,7 @@
} }
if(user.role == "Student"){ if(user.role == "Student"){
trueSchedule.value = await getOwnSchedule(); ownSchedule.value = await getOnesLessons();}
ownSchedule.value = trueSchedule.value.lessons;
curriculum.value = trueSchedule.value.curriculum;}
schedule.value = ownSchedule.value; schedule.value = ownSchedule.value;
@ -507,7 +504,7 @@
<div class="settings"> <div class="settings">
<div class="body" style="background-color:rgb(50,50,50);margin:5% 0 5% 0;">Settings</div> <div class="body" style="background-color:rgb(50,50,50);margin:5% 0 5% 0;">Settings</div>
<select @change="changeSchedule()" v-model="trueSchedule"> <select @change="changeSchedule()" v-model="trueSchedule">
<option v-for="item in allSchedules" :value='item'>{{item.curriculum.option}}</option> <option v-for="item in allSchedules" :value='item'>{{item.curriculum.option}}-{{item.curriculum.year}}</option>
</select> </select>
<button v-if="display=='Week'" @click="display='Month'">Week</button> <button v-if="display=='Week'" @click="display='Month'">Week</button>
<button v-if="display=='Month'" @click="display='Week'; value=1;">Month</button> <button v-if="display=='Month'" @click="display='Week'; value=1;">Month</button>

View File

@ -1,19 +1,29 @@
<script setup> <script setup>
import i18n from "@/i18n.js" import i18n from "@/i18n.js"
import { reactive } from 'vue' import {provide, reactive, ref} from 'vue'
import { getStudents } from '../rest/Users.js' import { getStudents } from '../rest/Users.js'
import AboutStudent from "@/Apps/Inscription/AboutStudent.vue";
const users = await getStudents(); const users = await getStudents();
</script>
let targetRegNo = "";
let list = ref(true);
</script>
<template style="margin-top:5%;"> <template style="margin-top:5%;">
<div style="display:flex; justify-content:center; " v-for="item in users"> <div v-if="list === false">
<AboutStudent :target=targetRegNo />
<button style="background-color:rgb(105,05,105);width:5%; margin-left: 10%;" @click="list = true;">Back</button>
</div>
<div style="display:flex; justify-content:center; " v-for="item in users" v-if="list === true">
<div class="bodu"> <div class="bodu">
<div class="container"> <div class="container">
<div class="status"><a style="margin-left:30px">{{item.status}}</a></div> <div class="status"><a style="margin-left:30px">{{item.status}}</a></div>
<div class="option"><a>{{item.role}}</a></div> <div class="option"><a>{{item.role}}</a></div>
<div class="surname"><a>{{item.lastName}}</a></div> <div class="surname"><a>{{item.lastName}}</a></div>
<div class="firstname"><a>{{item.firstName}}</a></div> <div class="firstname"><a>{{item.firstName}}</a></div>
<div class="infos"><button style="background-color:rgb(105,05,105);" >{{i18n("request.moreInfos")}} </button></div> <div class="infos">
<button style="background-color:rgb(105,05,105);" @click="list = false; targetRegNo = item.regNo;">{{i18n("request.moreInfos")}} </button>
</div>
</div> </div>
</div> </div>
</div> </div>
@ -25,10 +35,10 @@
height:100px; height:100px;
font-size:30px; font-size:30px;
display:grid; display:grid;
grid-template-columns:21.7% 21.7% 21.7% 21.7% 13.1%; grid-template-columns:21.7% 21.7% 21.7% 20% 13.1%;
grid-template-areas: grid-template-areas:
"status option surname firstname infos"; "status option surname firstname infos";
column-gap:10px;
} }
.infos { .infos {
@ -64,8 +74,8 @@
button{ button{
font-size:15px; font-size:15px;
height:50px; height:50px;
width:75%; width:75%;
border:none; border:none;
border-radius:20px; border-radius:20px;

View File

@ -1,3 +1,7 @@
:root {
--header-size: 61px;
}
body { body {
background-color: rgb(53, 25, 60); background-color: rgb(53, 25, 60);
margin:0; margin:0;

View File

@ -3,7 +3,7 @@
* *
* TODO: On time of writing, the backend doesn't support these endpoints so it could be modified in the future. * TODO: On time of writing, the backend doesn't support these endpoints so it could be modified in the future.
*/ */
import {restGet, restPatch} from './restConsumer.js' import {restGet, restPatch, restPost} from './restConsumer.js'
/** /**
* create a new register requests that can be recovered by the registering service * create a new register requests that can be recovered by the registering service
@ -43,3 +43,4 @@ export async function getAllRegisters(){
export async function validateRegister(id, state){ export async function validateRegister(id, state){
return restPatch("/request/register/" + id, state); return restPatch("/request/register/" + id, state);
} }

View File

@ -26,7 +26,7 @@ export function disconnect(){
* @param curriculum * @param curriculum
* @param imageId id of the image in database returned when uploaded * @param imageId id of the image in database returned when uploaded
*/ */
export async function register(firstname, lastname, birthDate, password, email, address, country, curriculumId, imageId){ export async function register(firstname, lastname, birthDate, password, email, address, country, curriculumId, imageId, identityCardId, submissionDate, equivalence,admissionDocUrl){
return restPost("/register", { return restPost("/register", {
firstName: firstname, firstName: firstname,
lastName: lastname, lastName: lastname,
@ -36,7 +36,11 @@ export async function register(firstname, lastname, birthDate, password, email,
address: address, address: address,
country: country, country: country,
curriculumId: curriculumId, curriculumId: curriculumId,
profilePictureUrl: imageId, profilePicture: imageId,
identityCard : identityCardId,
submissionDate : submissionDate,
equivalenceState : equivalence,
admissionDocUrl: admissionDocUrl
}); });
} }
@ -52,7 +56,7 @@ export async function register(firstname, lastname, birthDate, password, email,
* @param country * @param country
* @param imageId id of the image in database returned when uploaded * @param imageId id of the image in database returned when uploaded
* *
* PS: the password is not is not required as it is generated by the backend and sent to the user * PS: the password is not required as it is generated by the backend and sent to the user
* by mail. it's up to the user to change it if he cares about security * by mail. it's up to the user to change it if he cares about security
*/ */
export async function createUser(firstname, lastname, birthDate, email, address, country, role, imageId){ export async function createUser(firstname, lastname, birthDate, email, address, country, role, imageId){

View File

@ -4,7 +4,6 @@ import i18n from '@/i18n.js'
// Liste des apps // Liste des apps
import LoginPage from '@/Apps/Login.vue' import LoginPage from '@/Apps/Login.vue'
import Inscription from "@/Apps/Inscription.vue"
import Profil from "@/Apps/Profil.vue" import Profil from "@/Apps/Profil.vue"
import Courses from "@/Apps/ManageCourses.vue" import Courses from "@/Apps/ManageCourses.vue"
import Users from "@/Apps/UsersList.vue" import Users from "@/Apps/UsersList.vue"
@ -13,18 +12,23 @@ import Schedule from "@/Apps/Schedule.vue"
import ManageSchedule from "@/Apps/ManageSchedule.vue" import ManageSchedule from "@/Apps/ManageSchedule.vue"
import ManageOwnedLessons from "@/Apps/ManageOwnLessons.vue"; import ManageOwnedLessons from "@/Apps/ManageOwnLessons.vue";
import LessonRequests from "@/Apps/LessonRequests.vue"; import LessonRequests from "@/Apps/LessonRequests.vue";
import Msg from "@/Apps/Msg.vue"
import Payments from "@/Apps/Inscription/PaymentInfo.vue";
import ManageRequests from "@/Apps/Inscription/ManageRequests.vue";
const apps = { const apps = {
'/schedule': Schedule, '/schedule': Schedule,
'/manage-schedule': ManageSchedule, '/manage-schedule': ManageSchedule,
'/login': LoginPage, '/login': LoginPage,
'/inscription': Inscription, '/requests': ManageRequests,
'/profil': Profil, '/profil': Profil,
'/manage-courses' : Courses, '/manage-courses' : Courses,
'/users-list' : Users, '/users-list' : Users,
'/students-list' : Students, '/students-list' : Students,
'/manage-owned-lessons': ManageOwnedLessons, '/manage-owned-lessons': ManageOwnedLessons,
'/manage-schedule-requests' : LessonRequests, '/manage-schedule-requests' : LessonRequests,
'/msg' : Msg,
'/payments': Payments
} }
const appsList = { const appsList = {
@ -33,13 +37,13 @@ const appsList = {
'Forum': { path: '#/forum', icon: 'fa-envelope', text: i18n("app.forum") }, 'Forum': { path: '#/forum', icon: 'fa-envelope', text: i18n("app.forum") },
'Schedule': { path: '#/schedule', icon: 'fa-calendar-days', text: i18n("app.schedules") }, 'Schedule': { path: '#/schedule', icon: 'fa-calendar-days', text: i18n("app.schedules") },
'ManageSchedules': { path: '#/manage-schedule', icon: 'fa-calendar-days', text: i18n("app.manageSchedules")}, 'ManageSchedules': { path: '#/manage-schedule', icon: 'fa-calendar-days', text: i18n("app.manageSchedules")},
'Inscription': { path: '#/inscription', icon: 'fa-users', text: i18n("app.inscription.requests") },
'ManageCourses': { path: '#/manage-courses', icon: 'fa-book', text: i18n("app.manage.courses") }, 'ManageCourses': { path: '#/manage-courses', icon: 'fa-book', text: i18n("app.manage.courses") },
'StudentsList':{ path: '#/students-list',icon: 'fa-users',text: i18n("app.studentList")}, 'StudentsList':{ path: '#/students-list',icon: 'fa-users',text: i18n("app.studentList")},
'UsersList':{ path: '#/users-list',icon: 'fa-users',text: i18n("app.users")}, 'UsersList':{ path: '#/users-list',icon: 'fa-users',text: i18n("app.users")},
'ManageOwnedLessons':{path: '#/manage-owned-lessons',icon:'fa-calendar-days',text: i18n("app.manageOwnLessons")}, 'ManageOwnedLessons':{path: '#/manage-owned-lessons',icon:'fa-calendar-days',text: i18n("app.manageOwnLessons")},
'LessonRequests':{path: '#/manage-schedule-requests', icon:'fa-book', text: i18n("app.lessonRequests")}, 'LessonRequests':{path: '#/manage-schedule-requests', icon:'fa-book', text: i18n("app.lessonRequests")},
'Requests': { path: '#/requests', icon: 'fa-users', text: "Requests" },
'Payments':{path: '#/payments', icon:'fa-users', text:i18n("app.payments")}
} }
const currentPath = ref(window.location.hash) const currentPath = ref(window.location.hash)

View File

@ -48,3 +48,9 @@ export async function altercurriculum(id, courses){
export async function getSelfCurriculum(){ export async function getSelfCurriculum(){
return restGet("/curriculum"); return restGet("/curriculum");
} }
export async function getSomeonesCurriculumList(user){
return restGet("/onescurriculum/"+user)
}

View File

@ -0,0 +1,24 @@
import {restGet, restPatch, restPost} from "@/rest/restConsumer.js";
import {parseInteger} from "jsdom/lib/jsdom/living/helpers/strings.js";
export async function createExternalCurriculum(inscriptionRequestId,school, formation, completion, startYear, endYear, justifdocUrl, userRegNo){
return restPost("/externalcurriculum", {
inscriptionRequestId: inscriptionRequestId,
school:school,
formation :formation,
completion : completion,
startYear : startYear,
endYear: endYear,
justifdocUrl : justifdocUrl,
userRegNo : userRegNo
})
}
export async function getExternalCurriculumByInscrReq(inscrReqId){
return restGet("/externalcurriculum/"+inscrReqId)
}
export async function getExternalCurriculumByUser(userId){
return restGet("/externalcurriculumbyuser/"+userId)
}

View File

@ -45,7 +45,10 @@ export async function getLessons(){
export async function getOwnedLessons(){ export async function getOwnedLessons(){
return restGet("/lessons/owned") return restGet("/lessons/owned")
}
export async function getOnesLessons(){
return restGet("/lessons/OwnCurriculum");
} }
/** /**

Some files were not shown because too many files have changed in this diff Show More