Skip to content

Commit

Permalink
Merge pull request #61 from Informatik-Projekt-Kurs/IPK-236-Appointme…
Browse files Browse the repository at this point in the history
…nt-Mutations

Ipk 236 appointment mutations
  • Loading branch information
Gugi-Games authored Oct 14, 2024
2 parents 6269274 + a8cdea2 commit 6df6f23
Show file tree
Hide file tree
Showing 5 changed files with 205 additions and 60 deletions.
28 changes: 13 additions & 15 deletions src/main/java/com/MeetMate/appointment/Appointment.java
Original file line number Diff line number Diff line change
@@ -1,30 +1,28 @@
package com.MeetMate.appointment;

import com.MeetMate.enums.AppointmentStatus;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.data.mongodb.core.mapping.Document;

import java.time.LocalDateTime;

@Document(collection = "appointments")
@Data
@NoArgsConstructor
public class Appointment {
long id;
LocalDateTime from;
LocalDateTime to;
long companyID;
long clientID;
long assigneeID;
// Select Prompt → f.E. medical industry: Untersuchung, Operation
String description;
String location;
AppointmentStatus status;
private long id;
private String from;
private String to;
private long companyId;
private long clientId;
private long assigneeId;
// Select Prompt → f.E. medical industry: Untersuchung, Operation
private String description;
private String location;
private AppointmentStatus status;

public Appointment(long id, long companyID, long clientID) {
public Appointment(long id, long companyId) {
this.id = id;
this.companyID = companyID;
this.clientID = clientID;
this.companyId = companyId;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
//
// @Bean
// public CommandLineRunner run(AppointmentRepository appointmentRepository) throws Exception {
// System.out.println("Yeehaaaa");
// return args -> {
// Appointment appointment = new Appointment();
// appointment.setId(1L);
Expand Down
94 changes: 72 additions & 22 deletions src/main/java/com/MeetMate/appointment/AppointmentController.java
Original file line number Diff line number Diff line change
@@ -1,30 +1,32 @@
package com.MeetMate.appointment;

import com.MeetMate.enums.AppointmentStatus;
import jakarta.persistence.EntityNotFoundException;
import lombok.RequiredArgsConstructor;
import org.springframework.graphql.data.method.annotation.Argument;
import org.springframework.graphql.data.method.annotation.ContextValue;
import org.springframework.graphql.data.method.annotation.MutationMapping;
import org.springframework.graphql.data.method.annotation.QueryMapping;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.bind.annotation.RequestMapping;

import java.lang.reflect.InaccessibleObjectException;
import java.util.Map;

@Controller
@RequestMapping(path = "api/appointment")
@RequiredArgsConstructor
public class AppointmentController {

private final AppointmentService appointmentService;

@QueryMapping
public Appointment getAppointment(@Argument long id) {
public Appointment getAppointment(
@ContextValue String token,
@Argument long id
) {
token = token.substring(7);
try {
return appointmentService.getAppointment(id);

return appointmentService.getAppointment(token, id);
} catch (Throwable t) {
Class<? extends Throwable> tc = t.getClass();
return null;
Expand All @@ -48,25 +50,73 @@ public ResponseEntity<?> createAppointment(
// @Argument Select Prompt → f.E. medical industry: Untersuchung, Operation,
@Argument String description,
@Argument String location,
@Argument String status) {
@Argument String status
) {
try {
Map<String, Object> appointmentData = Map.of(
"from", from,
"to", to,
"assigneeId", assigneeId,
// "prompt", Select Prompt → f.E. medical industry: Untersuchung, Operation);
"description", description,
"location", location,
"status", status
);

appointmentService.createAppointment(companyId, clientId, appointmentData);
appointmentService.createAppointment(from, to, companyId, clientId, assigneeId, description, location, AppointmentStatus.valueOf(status));
return ResponseEntity.ok().build();

} catch (Throwable t) {
Class<? extends Throwable> tc = t.getClass();
if (tc == InaccessibleObjectException.class)
return ResponseEntity.status(HttpStatus.PRECONDITION_FAILED).body("message: " + t.getMessage());

if (tc == EntityNotFoundException.class)
return ResponseEntity.status(HttpStatus.NOT_FOUND).body("message: " + t.getMessage());

return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("message: " + t.getMessage());
}
}

@MutationMapping
public ResponseEntity<?> editAppointment(
@ContextValue String token,
@Argument long id,
@Argument String from,
@Argument String to,
@Argument long clientId,
@Argument long assigneeId,
// @Argument Select Prompt → f.E. medical industry: Untersuchung, Operation,
@Argument String description,
@Argument String location,
@Argument String status
) {
token = token.substring(7);
try {
appointmentService.editAppointment(token, id, from, to, clientId, assigneeId, description, location, AppointmentStatus.valueOf(status));
return ResponseEntity.ok().build();

} catch (Throwable t) {
Class<? extends Throwable> tc = t.getClass();
if (tc == EntityNotFoundException.class)
return ResponseEntity.status(HttpStatus.NOT_FOUND).body("message: " + t.getMessage());

if (tc == IllegalStateException.class)
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("message: " + t.getMessage());

if (tc == IllegalArgumentException.class)
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("message: " + t.getMessage());

return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("message: " + t.getMessage());
}
}

@MutationMapping
public ResponseEntity<?> deleteAppointment(
@ContextValue String token,
@Argument long id
) {
token = token.substring(7);
try {
appointmentService.deleteAppointment(token, id);
return ResponseEntity.ok().build();

} catch (Throwable t) {
Class<? extends Throwable> tc = t.getClass();

if (tc == IllegalStateException.class)
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("message: " + t.getMessage());

if (tc == IllegalArgumentException.class)
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("message: " + t.getMessage());

return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("message: " + t.getMessage());
}
Expand Down
106 changes: 94 additions & 12 deletions src/main/java/com/MeetMate/appointment/AppointmentService.java
Original file line number Diff line number Diff line change
@@ -1,38 +1,120 @@
package com.MeetMate.appointment;

import com.MeetMate.appointment.sequence.AppointmentSequenceService;
import com.MeetMate.company.Company;
import com.MeetMate.company.CompanyRepository;
import com.MeetMate.enums.AppointmentStatus;
import com.MeetMate.security.JwtService;
import com.MeetMate.user.User;
import com.MeetMate.user.UserRepository;
import jakarta.persistence.EntityNotFoundException;
import jakarta.transaction.Transactional;
import lombok.RequiredArgsConstructor;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Service;

import java.lang.reflect.Field;
import java.util.Map;

@Service
@RequiredArgsConstructor
public class AppointmentService {

private final AppointmentRepository appointmentRepository;
private final AppointmentSequenceService appointmentSequenceService;
private final MongoTemplate mongoTemplate;
private final JwtService jwtService;
private final UserRepository userRepository;
private final CompanyRepository companyRepository;

public Appointment getAppointment(long id) {
return appointmentRepository.findAppointmentById(id)
public Appointment getAppointment(String token, long appointmentId) {
if (userNotInAppointment(token, appointmentId))
throw new IllegalArgumentException("User is not eligible to edit this appointment");
return appointmentRepository.findAppointmentById(appointmentId)
.orElseThrow(() -> new EntityNotFoundException("Appointment not found"));
}

@Transactional
public void createAppointment(long companyId, long clientId, Map<String, Object> appointmentData) throws IllegalAccessException {
public void createAppointment(String from, String to, long companyId, long clientId, long assigneeId, String description, String location, AppointmentStatus status) {
//Check if IDs are valid
if (companyRepository.findCompanyById(companyId).isEmpty())
throw new EntityNotFoundException("Company not found");
if (clientId != 0 && userRepository.findUserById(clientId).isEmpty())
throw new EntityNotFoundException("Client not found");
if (assigneeId != 0 && userRepository.findUserById(assigneeId).isEmpty())
throw new EntityNotFoundException("Assignee not found");

long appointmentId = appointmentSequenceService.getCurrentValue();

Appointment appointment = new Appointment(appointmentId, companyId, clientId);
Field[] fields = Appointment.class.getDeclaredFields();
for(Field field : fields) {
field.setAccessible(true);
field.set(appointment, appointmentData.get(field.getName()));
}
Appointment appointment = new Appointment(appointmentId, companyId);
if (from != null && !from.isEmpty()) appointment.setFrom(from);
if (to != null && !to.isEmpty()) appointment.setTo(to);
if (clientId != 0) appointment.setClientId(clientId);
if (assigneeId != 0) appointment.setAssigneeId(assigneeId);
if (description != null && !description.isEmpty()) appointment.setDescription(description);
if (location != null && !location.isEmpty()) appointment.setLocation(location);
if (status != null) appointment.setStatus(status);

appointmentRepository.save(appointment);
appointmentSequenceService.incrementId();
}

@Transactional
public void editAppointment(String token, long appointmentId, String from, String to, long clientId, long assigneeId, String description, String location, AppointmentStatus status) throws IllegalAccessException {
if (userNotInAppointment(token, appointmentId))
throw new IllegalArgumentException("User is not eligible to edit this appointment");

//Check if IDs are valid
if (clientId != 0 && userRepository.findUserById(clientId).isEmpty())
throw new EntityNotFoundException("Client not found");
if (assigneeId != 0 && userRepository.findUserById(assigneeId).isEmpty())
throw new EntityNotFoundException("Assignee not found");

Query query = new Query(Criteria.where("appointmentId").is(appointmentId));
Update update = new Update();

if (from != null && !from.isEmpty()) update.set("from", from);
if (to != null && !to.isEmpty()) update.set("to", to);
if (clientId != 0) update.set("clientId", clientId);
if (assigneeId != 0) update.set("assigneeId", assigneeId);
if (description != null && !description.isEmpty()) update.set("description", description);
if (location != null && !location.isEmpty()) update.set("location", location);
if (status != null) update.set("status", status);

mongoTemplate.updateFirst(query, update, Company.class);
}

@Transactional
public void deleteAppointment(String token, long appointmentId) {
if (userNotInAppointment(token, appointmentId))
throw new IllegalArgumentException("User is not eligible to edit this appointment");
Appointment appointment = appointmentRepository.findAppointmentById(appointmentId)
.orElseThrow(() -> new EntityNotFoundException("Appointment not found"));

appointmentRepository.delete(appointment);
}

private boolean userNotInAppointment(String token, long appointmentId) throws IllegalArgumentException {
String userEmail = jwtService.extractUserEmail(token);
User user = userRepository.findUserByEmail(userEmail)
.orElseThrow(() -> new EntityNotFoundException("User not found!"));
Appointment appointment = appointmentRepository.findAppointmentById(appointmentId)
.orElseThrow(() -> new EntityNotFoundException("Appointment not found!"));

switch (user.getRole()) {
case COMPANY_OWNER, COMPANY_MEMBER -> {
if (appointment.getCompanyId() == user.getAssociatedCompany())
return false;
}
case CLIENT -> {
if (appointment.getClientId() == user.getId())
return false;
}
default -> {
throw new IllegalStateException("Role of user not found!");
}
}
return true;
}

}
36 changes: 26 additions & 10 deletions src/main/resources/graphql/schema.graphqls
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,29 @@ type Mutation {
createAppointment(
from: String,
to: String,
companyID: ID!,
clientID: ID!,
assigneeID: ID,
# Select Prompt → f.E. medical industry: Untersuchung, Operation
companyId: ID!,
clientId: ID,
assigneeId: ID,
#
description: String,
location: String
appointmentStatus: String
location: String,
status: String
): String

editAppointment(
id: ID!,
from: String,
to: String,
clientId: ID,
assigneeId: ID,

description: String,
location: String,
status: String
): String

deleteAppointment(
id: ID!
): String
}

Expand All @@ -54,11 +70,11 @@ type Appointment {
id: ID
from: String
to: String
companyID: ID
clientID: ID
assigneeID: ID
companyId: ID
clientId: ID
assigneeId: ID
# Select Prompt → f.E. medical industry: Untersuchung, Operation
description: String
location: String
AppointmentStatus: String
Status: String
}

0 comments on commit 6df6f23

Please sign in to comment.