Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ipk 236 appointment mutations #61

Merged
merged 7 commits into from
Oct 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
}
Loading