Skip to content

Commit

Permalink
Merge pull request #12 from bcgov/feature/EAC-20
Browse files Browse the repository at this point in the history
Changes to support history - EAC-20
  • Loading branch information
arcshiftsolutions authored Oct 17, 2024
2 parents 3794dd3 + 20854c6 commit b072d2d
Show file tree
Hide file tree
Showing 10 changed files with 172 additions and 12 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
package ca.bc.gov.educ.eas.api.constants;

public enum EventType {
INITIATED, //Default. Used by BaseOrchestrator.
MARK_SAGA_COMPLETE, //Default. Used by BaseOrchestrator.
GET_PAGINATED_SCHOOLS,
CREATE_STUDENT_REGISTRATION,
GET_STUDENT_REGISTRATION
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
package ca.bc.gov.educ.eas.api.model.v1;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import jakarta.persistence.*;
import jakarta.validation.constraints.PastOrPresent;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.hibernate.annotations.UuidGenerator;

import java.time.LocalDateTime;
import java.util.UUID;

@Data
@NoArgsConstructor
@AllArgsConstructor
@Entity
@Builder
@Table(name = "ASSESSMENT_STUDENT_HISTORY")
@JsonIgnoreProperties(ignoreUnknown = true)
public class AssessmentStudentHistoryEntity {

@Id
@GeneratedValue(generator = "UUID")
@UuidGenerator
@Column(name = "ASSESSMENT_STUDENT_HISTORY_ID", unique = true, updatable = false, columnDefinition = "BINARY(16)")
private UUID assessmentStudentHistoryID;

@Basic
@Column(name = "ASSESSMENT_STUDENT_ID", columnDefinition = "BINARY(16)")
private UUID assessmentStudentID;

@Basic
@Column(name = "ASSESSMENT_ID", columnDefinition = "BINARY(16)")
private UUID assessmentID;

@Column(name = "SCHOOL_ID", nullable = false, columnDefinition = "BINARY(16)")
private UUID schoolID;

@Column(name = "STUDENT_ID", nullable = false, columnDefinition = "BINARY(16)")
private UUID studentID;

@Column(name = "PEN", nullable = false, length = 9)
private String pen;

@Column(name = "LOCAL_ID", length = 12)
private String localID;

@Column(name = "IS_ELECTRONIC_EXAM", length = 1)
private Boolean isElectronicExam;

@Column(name = "FINAL_PERCENTAGE", length = 3)
private String finalPercentage;

@Column(name = "PROVINCIAL_SPECIAL_CASE_CODE", length = 1)
private String provincialSpecialCaseCode;

@Column(name = "COURSE_STATUS_CODE", length = 1)
private String courseStatusCode;

@Column(name = "CREATE_USER", updatable = false, length = 100)
private String createUser;

@PastOrPresent
@Column(name = "CREATE_DATE", updatable = false)
private LocalDateTime createDate;

@Column(name = "UPDATE_USER", length = 100)
private String updateUser;

@PastOrPresent
@Column(name = "UPDATE_DATE")
private LocalDateTime updateDate;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package ca.bc.gov.educ.eas.api.repository.v1;

import ca.bc.gov.educ.eas.api.model.v1.AssessmentStudentHistoryEntity;
import org.springframework.data.jpa.repository.JpaRepository;

import java.util.List;
import java.util.UUID;

public interface AssessmentStudentHistoryRepository extends JpaRepository<AssessmentStudentHistoryEntity, UUID> {
List<AssessmentStudentHistoryEntity> findAllByAssessmentIDAndAssessmentStudentID(UUID asessmentID, UUID assessmentStudentID);

}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@


import ca.bc.gov.educ.eas.api.model.v1.AssessmentStudentEntity;
import ca.bc.gov.educ.eas.api.model.v1.EasEventEntity;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.stereotype.Repository;
Expand All @@ -12,5 +11,5 @@

@Repository
public interface AssessmentStudentRepository extends JpaRepository<AssessmentStudentEntity, UUID>, JpaSpecificationExecutor<AssessmentStudentEntity> {
Optional<AssessmentStudentEntity> findByAssessmentIDAndStudentID(UUID assessmentID, String studentID);
Optional<AssessmentStudentEntity> findByAssessmentEntity_AssessmentIDAndStudentID(UUID assessmentID, UUID studentID);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package ca.bc.gov.educ.eas.api.service.v1;

import ca.bc.gov.educ.eas.api.model.v1.AssessmentStudentEntity;
import ca.bc.gov.educ.eas.api.model.v1.AssessmentStudentHistoryEntity;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;

@Service
@Slf4j
public class AssessmentStudentHistoryService {

@Transactional(propagation = Propagation.MANDATORY)
public AssessmentStudentHistoryEntity createAssessmentStudentHistoryEntity(AssessmentStudentEntity assessmentStudentEntity, String updateUser) {
final AssessmentStudentHistoryEntity assessmentStudentHistoryEntity = new AssessmentStudentHistoryEntity();
BeanUtils.copyProperties(assessmentStudentEntity, assessmentStudentHistoryEntity);
assessmentStudentHistoryEntity.setAssessmentStudentID(assessmentStudentEntity.getAssessmentStudentID());
assessmentStudentHistoryEntity.setAssessmentID(assessmentStudentEntity.getAssessmentEntity().getAssessmentID());
assessmentStudentHistoryEntity.setCreateUser(updateUser);
assessmentStudentHistoryEntity.setCreateDate(LocalDateTime.now());
assessmentStudentHistoryEntity.setUpdateUser(updateUser);
assessmentStudentHistoryEntity.setUpdateDate(LocalDateTime.now());
return assessmentStudentHistoryEntity;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import ca.bc.gov.educ.eas.api.exception.EntityNotFoundException;
import ca.bc.gov.educ.eas.api.model.v1.AssessmentStudentEntity;
import ca.bc.gov.educ.eas.api.repository.v1.AssessmentStudentHistoryRepository;
import ca.bc.gov.educ.eas.api.repository.v1.AssessmentStudentRepository;
import ca.bc.gov.educ.eas.api.struct.v1.AssessmentStudent;
import ca.bc.gov.educ.eas.api.util.TransformUtil;
Expand All @@ -19,11 +20,15 @@
public class AssessmentStudentService {

private final AssessmentStudentRepository assessmentStudentRepository;
private final AssessmentStudentHistoryRepository assessmentStudentHistoryRepository;

private final AssessmentStudentHistoryService assessmentStudentHistoryService;

@Autowired
public AssessmentStudentService(final AssessmentStudentRepository assessmentStudentRepository) {
public AssessmentStudentService(final AssessmentStudentRepository assessmentStudentRepository, AssessmentStudentHistoryRepository assessmentStudentHistoryRepository, AssessmentStudentHistoryService assessmentStudentHistoryService) {
this.assessmentStudentRepository = assessmentStudentRepository;
this.assessmentStudentHistoryRepository = assessmentStudentHistoryRepository;
this.assessmentStudentHistoryService = assessmentStudentHistoryService;
}

public AssessmentStudentEntity getStudentByID(UUID assessmentStudentID) {
Expand All @@ -40,12 +45,18 @@ public AssessmentStudentEntity updateStudent(AssessmentStudentEntity assessmentS

BeanUtils.copyProperties(assessmentStudentEntity, currentAssessmentStudentEntity, "assessmentEntity", "createUser", "createDate");
TransformUtil.uppercaseFields(currentAssessmentStudentEntity);
return assessmentStudentRepository.save(currentAssessmentStudentEntity);
return createAssessmentStudentWithHistory(currentAssessmentStudentEntity);
}

@Transactional(propagation = Propagation.REQUIRES_NEW)
public AssessmentStudentEntity createStudent(AssessmentStudentEntity assessmentStudentEntity) {
return assessmentStudentRepository.save(assessmentStudentEntity);
return createAssessmentStudentWithHistory(assessmentStudentEntity);
}

public AssessmentStudentEntity createAssessmentStudentWithHistory(AssessmentStudentEntity assessmentStudentEntity) {
AssessmentStudentEntity savedEntity = assessmentStudentRepository.save(assessmentStudentEntity);
assessmentStudentHistoryRepository.save(this.assessmentStudentHistoryService.createAssessmentStudentHistoryEntity(assessmentStudentEntity, assessmentStudentEntity.getUpdateUser()));
return savedEntity;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ public Pair<byte[], EasEventEntity> handleCreateStudentRegistrationEvent(Event e
log.info(NO_RECORD_SAGA_ID_EVENT_TYPE);
log.trace(EVENT_PAYLOAD, event);
AssessmentStudent student = JsonUtil.getJsonObjectFromString(AssessmentStudent.class, event.getEventPayload());
val optionalStudent = assessmentStudentRepository.findByAssessmentIDAndStudentID(UUID.fromString(student.getAssessmentID()), student.getStudentID());
val optionalStudent = assessmentStudentRepository.findByAssessmentEntity_AssessmentIDAndStudentID(UUID.fromString(student.getAssessmentID()), UUID.fromString(student.getStudentID()));
easEvent = createAssessmentStudentEventRecord(event);
} else {
log.info(RECORD_FOUND_FOR_SAGA_ID_EVENT_TYPE);
Expand All @@ -88,7 +88,7 @@ public Pair<byte[], EasEventEntity> handleCreateStudentRegistrationEvent(Event e
public byte[] handleGetStudentRegistrationEvent(Event event, boolean isSynchronous) throws JsonProcessingException {
AssessmentStudentGet student = JsonUtil.getJsonObjectFromString(AssessmentStudentGet.class, event.getEventPayload());
if (isSynchronous) {
val optionalStudentEntity = assessmentStudentRepository.findByAssessmentIDAndStudentID(UUID.fromString(student.getAssessmentID()), student.getStudentID());
val optionalStudentEntity = assessmentStudentRepository.findByAssessmentEntity_AssessmentIDAndStudentID(UUID.fromString(student.getAssessmentID()), UUID.fromString(student.getStudentID()));
if (optionalStudentEntity.isPresent()) {
return JsonUtil.getJsonBytesFromObject(assessmentStudentMapper.toStructure(optionalStudentEntity.get()));
} else {
Expand All @@ -97,7 +97,7 @@ public byte[] handleGetStudentRegistrationEvent(Event event, boolean isSynchrono
}

log.trace(EVENT_PAYLOAD, event);
val optionalStudentEntity = assessmentStudentRepository.findByAssessmentIDAndStudentID(UUID.fromString(student.getAssessmentID()), student.getStudentID());
val optionalStudentEntity = assessmentStudentRepository.findByAssessmentEntity_AssessmentIDAndStudentID(UUID.fromString(student.getAssessmentID()), UUID.fromString(student.getStudentID()));
if (optionalStudentEntity.isPresent()) {
AssessmentStudent structStud = assessmentStudentMapper.toStructure(optionalStudentEntity.get()); // need to convert to structure MANDATORY otherwise jackson will break.
event.setEventPayload(JsonUtil.getJsonStringFromObject(structStud));
Expand Down
19 changes: 19 additions & 0 deletions api/src/main/resources/db/migration/V1.0.3__EAS.API.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
CREATE TABLE ASSESSMENT_STUDENT_HISTORY
(
ASSESSMENT_STUDENT_HISTORY_ID UUID NOT NULL,
ASSESSMENT_STUDENT_ID UUID NOT NULL,
ASSESSMENT_ID UUID NOT NULL,
SCHOOL_ID UUID NOT NULL,
STUDENT_ID UUID NOT NULL,
PEN VARCHAR(9) NOT NULL,
LOCAL_ID VARCHAR(12),
IS_ELECTRONIC_EXAM BOOLEAN,
FINAL_PERCENTAGE VARCHAR(3),
PROVINCIAL_SPECIAL_CASE_CODE VARCHAR(1),
COURSE_STATUS_CODE VARCHAR(1),
CREATE_USER VARCHAR(100) NOT NULL,
CREATE_DATE TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL,
UPDATE_USER VARCHAR(100) NOT NULL,
UPDATE_DATE TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL,
CONSTRAINT ASSESSMENT_STUDENT_HISTORY_ID_PK PRIMARY KEY (ASSESSMENT_STUDENT_HISTORY_ID)
);
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package ca.bc.gov.educ.eas.api;

import ca.bc.gov.educ.eas.api.constants.v1.AssessmentTypeCodes;
import ca.bc.gov.educ.eas.api.model.v1.AssessmentEntity;
import ca.bc.gov.educ.eas.api.model.v1.AssessmentStudentEntity;
import ca.bc.gov.educ.eas.api.model.v1.SessionEntity;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,10 @@
import ca.bc.gov.educ.eas.api.exception.EntityNotFoundException;
import ca.bc.gov.educ.eas.api.model.v1.AssessmentEntity;
import ca.bc.gov.educ.eas.api.model.v1.AssessmentStudentEntity;
import ca.bc.gov.educ.eas.api.model.v1.AssessmentStudentHistoryEntity;
import ca.bc.gov.educ.eas.api.model.v1.SessionEntity;
import ca.bc.gov.educ.eas.api.repository.v1.AssessmentRepository;
import ca.bc.gov.educ.eas.api.repository.v1.AssessmentStudentHistoryRepository;
import ca.bc.gov.educ.eas.api.repository.v1.AssessmentStudentRepository;
import ca.bc.gov.educ.eas.api.repository.v1.SessionRepository;
import lombok.extern.slf4j.Slf4j;
Expand All @@ -19,6 +21,7 @@
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.junit4.SpringRunner;

import java.util.List;
import java.util.UUID;

import static org.assertj.core.api.Assertions.assertThat;
Expand All @@ -40,6 +43,9 @@ class AssessmentStudentServiceTest extends BaseEasAPITest {
@Autowired
AssessmentStudentRepository assessmentStudentRepository;

@Autowired
AssessmentStudentHistoryRepository assessmentStudentHistoryRepository;

@Autowired
SessionRepository sessionRepository;

Expand All @@ -49,6 +55,7 @@ class AssessmentStudentServiceTest extends BaseEasAPITest {
@AfterEach
public void after() {
this.assessmentStudentRepository.deleteAll();
this.assessmentStudentHistoryRepository.deleteAll();
this.assessmentRepository.deleteAll();
this.sessionRepository.deleteAll();
}
Expand Down Expand Up @@ -85,16 +92,20 @@ void testCreateStudent_WhenStudentDoesNotExistInDB_ShouldReturnStudent() {

//when creating an assessment student
AssessmentStudentEntity student = service.createStudent(AssessmentStudentEntity.builder().pen("120164447").schoolID(UUID.randomUUID()).studentID(UUID.randomUUID()).assessmentEntity(assessmentEntity).build());

List<AssessmentStudentHistoryEntity> studentHistory = assessmentStudentHistoryRepository.findAllByAssessmentIDAndAssessmentStudentID(assessmentEntity.getAssessmentID(), student.getAssessmentStudentID());
//then assessment student is created
assertNotNull(student);
assertNotNull(repository.findById(student.getStudentID()));
assertThat(studentHistory).hasSize(1);
}

@Test
void testCreateStudent_WhenSessionIDDoesNotExistInDB_ShouldThrowError() {
SessionEntity sessionEntity = sessionRepository.save(createMockSessionEntity());
AssessmentEntity assessmentEntity = assessmentRepository.save(createMockAssessmentEntity(sessionEntity, AssessmentTypeCodes.LTP12.getCode()));
assessmentEntity.setAssessmentID(UUID.randomUUID());
//when attempting to create student with invalid session id
AssessmentStudentEntity student = AssessmentStudentEntity.builder().pen("120164447").schoolID(UUID.randomUUID()).studentID(UUID.randomUUID()).build();
AssessmentStudentEntity student = AssessmentStudentEntity.builder().pen("120164447").schoolID(UUID.randomUUID()).studentID(UUID.randomUUID()).assessmentEntity(assessmentEntity).build();
//then throw exception
assertThrows(DataIntegrityViolationException.class, () -> service.createStudent(student));
}
Expand All @@ -105,15 +116,17 @@ void testUpdateStudent_WhenStudentExistInDB_ShouldReturnUpdatedStudent() {
SessionEntity sessionEntity = sessionRepository.save(createMockSessionEntity());
AssessmentEntity assessmentEntity = assessmentRepository.save(createMockAssessmentEntity(sessionEntity, AssessmentTypeCodes.LTP10.getCode()));

AssessmentStudentEntity assessmentStudentEntity = repository.save(AssessmentStudentEntity.builder().pen("120164447").schoolID(UUID.randomUUID()).studentID(UUID.randomUUID()).assessmentEntity(assessmentEntity).build());
AssessmentStudentEntity assessmentStudentEntity = service.createStudent(AssessmentStudentEntity.builder().pen("120164447").schoolID(UUID.randomUUID()).studentID(UUID.randomUUID()).assessmentEntity(assessmentEntity).build());
//when updating the student
AssessmentStudentEntity student = service.updateStudent(assessmentStudentEntity);
assertNotNull(student);
List<AssessmentStudentHistoryEntity> studentHistory = assessmentStudentHistoryRepository.findAllByAssessmentIDAndAssessmentStudentID(assessmentEntity.getAssessmentID(), student.getAssessmentStudentID());

//then student is updated and saved
var updatedStudent = repository.findById(student.getAssessmentStudentID());
assertThat(updatedStudent).isPresent();
assertThat(updatedStudent.get().getAssessmentEntity().getAssessmentTypeCode()).isEqualTo(AssessmentTypeCodes.LTP10.getCode());
assertThat(studentHistory).hasSize(2);
}

@Test
Expand Down

0 comments on commit b072d2d

Please sign in to comment.