Skip to content

Commit

Permalink
add saving gradings to repo and publishing content progress event, no…
Browse files Browse the repository at this point in the history
… tests
  • Loading branch information
julianlxs committed Nov 22, 2024
1 parent 9cb880e commit 81cbd80
Showing 1 changed file with 103 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,11 @@
import de.unistuttgart.iste.meitrex.assignment_service.persistence.repository.GradingRepository;
import de.unistuttgart.iste.meitrex.assignment_service.validation.AssignmentValidator;
import de.unistuttgart.iste.meitrex.common.dapr.TopicPublisher;
import de.unistuttgart.iste.meitrex.common.event.ContentProgressedEvent;
import de.unistuttgart.iste.meitrex.common.event.Response;
import de.unistuttgart.iste.meitrex.common.exception.NoAccessToCourseException;
import de.unistuttgart.iste.meitrex.common.user_handling.LoggedInUser;
import de.unistuttgart.iste.meitrex.generated.dto.ExternalAssignment;
import de.unistuttgart.iste.meitrex.generated.dto.Grading;
import de.unistuttgart.iste.meitrex.generated.dto.*;
import jakarta.persistence.EntityNotFoundException;
import jakarta.validation.ValidationException;
import lombok.RequiredArgsConstructor;
Expand Down Expand Up @@ -51,9 +52,19 @@ public Grading getGradingForAssignmentForStudent(final UUID assignmentId, final
return assignmentMapper.gradingEntityToDto(gradingEntity);
}

private void getGradingsForAssignment(final UUID assignmentId, final LoggedInUser currentUser) {
/**
* Handles importing all gradings for one assignment from TMS.
* <br><br>
* All gradings for one assignment are requested from TMS via HTTP. The response is parsed to gradingEntities. <br>
* These gradingEntities are saved in the grading repository. <br>
* A contentProgressedEvent is published for each grading (i.e. each student).
*
* @param assignmentId id of the assignment of which the gradings should be imported
* @param currentUser the user requesting the import (needs to be admin)
*/
private void importGradingsForAssignment(final UUID assignmentId, final LoggedInUser currentUser) {
final AssignmentEntity assignment = assignmentService.requireAssignmentExists(assignmentId); // throws EntityNotFoundException "Assignment with assessmentId %s not found"
validateUserHasAccessToCourse(currentUser, LoggedInUser.UserRoleInCourse.STUDENT, assignment.getCourseId());
validateUserHasAccessToCourse(currentUser, LoggedInUser.UserRoleInCourse.ADMINISTRATOR, assignment.getCourseId());

String externalId = assignment.getExternalId();

Expand All @@ -74,9 +85,20 @@ private void getGradingsForAssignment(final UUID assignmentId, final LoggedInUse

List<GradingEntity> gradingEntities = parseStringIntoGradingEntityList(body, assignment);

// TODO add them to repo, publish user progress events
for (GradingEntity gradingEntity : gradingEntities) {
gradingRepository.save(gradingEntity);
logGradingImported(gradingEntity);
}

}

/**
* Parses a JSON String to a list of grading entities.
*
* @param string JSON Array containing a list of TMS-gradings
* @param assignmentEntity the assignment id which the gradings belong to
* @return List of parsed grading entities
*/
private List<GradingEntity> parseStringIntoGradingEntityList(final String string, final AssignmentEntity assignmentEntity) {
JSONArray gradingArray = new JSONArray(string);
final List<GradingEntity> gradingEntityList = new ArrayList<>(gradingArray.length());
Expand All @@ -87,6 +109,13 @@ private List<GradingEntity> parseStringIntoGradingEntityList(final String string
return gradingEntityList;
}

/**
* Parses a single JSON Object into a grading entity.
*
* @param jsonObject JSON Object containing a single TMS-grading
* @param assignmentEntity the assignment id which the grading belongs to
* @return parsed grading entity
*/
private GradingEntity parseIntoGradingEntity(final JSONObject jsonObject, final AssignmentEntity assignmentEntity) {
final GradingEntity gradingEntity = new GradingEntity();

Expand Down Expand Up @@ -140,6 +169,68 @@ private GradingEntity parseIntoGradingEntity(final JSONObject jsonObject, final
return gradingEntity;
}


/**
* Takes gradingEntity and publishes the {@link ContentProgressedEvent} to the dapr pubsub.
*
* @param gradingEntity gradingEntity containing all information
*/
private void logGradingImported(final GradingEntity gradingEntity) {
final AssignmentEntity assignmentEntity = assignmentService.requireAssignmentExists(gradingEntity.getId().getAssessmentId());
assignmentValidator.validateGradingEntityFitsAssignmentEntity(assignmentEntity, gradingEntity);

final double requiredPercentage = assignmentEntity.getRequiredPercentage() == null ? 0.5 : assignmentEntity.getRequiredPercentage();

final double achievedCredits = gradingEntity.getAchievedCredits();
final double totalCredits = assignmentEntity.getTotalCredits();

final boolean success = achievedCredits >= requiredPercentage * totalCredits;
final double correctness = totalCredits == 0 ? 1.0f : achievedCredits / totalCredits;

// create Responses for each exercise and subexercise
final List<Response> responses = new ArrayList<>();
for (final ExerciseGradingEntity exerciseGradingEntity : gradingEntity.getExerciseGradings()) {
final UUID exerciseId = exerciseGradingEntity.getPrimaryKey().getItemId();
final ExerciseEntity exerciseEntity = assignmentService.findExerciseEntityInAssignmentEntity(exerciseId, assignmentEntity);
final double totalExerciseCredits = exerciseEntity.getTotalExerciseCredits();
final float achievedExercisePercentage = totalExerciseCredits == 0 ? 1.0f : (float) (exerciseGradingEntity.getAchievedCredits() / totalExerciseCredits);
final Response exerciseResponse = new Response(exerciseId, achievedExercisePercentage);
responses.add(exerciseResponse);

for (final SubexerciseGradingEntity subexerciseGradingEntity : exerciseGradingEntity.getSubexerciseGradings()) {
final UUID subexerciseId = subexerciseGradingEntity.getPrimaryKey().getItemId();
final SubexerciseEntity subexerciseEntity = assignmentService.findSubexerciseEntityInExerciseEntity(subexerciseId, exerciseEntity);
final double totalSubexerciseCredits = subexerciseEntity.getTotalSubexerciseCredits();
final float achievedSubexercisePercentage = totalSubexerciseCredits == 0 ? 1.0f : (float) (subexerciseGradingEntity.getAchievedCredits() / totalSubexerciseCredits);
final Response subexerciseResponse = new Response(subexerciseId, achievedSubexercisePercentage);
responses.add(subexerciseResponse);
}
}

// create new user progress event message
final ContentProgressedEvent userProgressLogEvent = ContentProgressedEvent.builder()
.userId(gradingEntity.getPrimaryKey().getStudentId())
.contentId(assignmentEntity.getAssessmentId())
.hintsUsed(0)
.success(success)
.timeToComplete(null)
.correctness(correctness)
.responses(responses)
.build();

// publish new user progress event message
topicPublisher.notifyUserWorkedOnContent(userProgressLogEvent);
}


/**
* Gets external assignment information from TMS. <br>
* This is needed for mapping MEITREX-Assignments to TMS-Assignments.
*
* @param courseId current course needed for role check
* @param currentUser logged in user
* @return list of ExternalAssignments, i.e. the external id and its sheet number
*/
public List<ExternalAssignment> getExternalAssignments(final UUID courseId, final LoggedInUser currentUser) {
try {
validateUserHasAccessToCourse(currentUser, LoggedInUser.UserRoleInCourse.ADMINISTRATOR, courseId);
Expand Down Expand Up @@ -167,6 +258,13 @@ public List<ExternalAssignment> getExternalAssignments(final UUID courseId, fina
return externalAssignments;
}


/**
* Parses external assignments into a list of ExternalAssignments containing an external id and sheet number.
*
* @param string JSON Array containing external sheets
* @return list of ExternalAssignments, i.e. the external id and its sheet number
*/
private List<ExternalAssignment> parseStringIntoExternalAssignmentList(final String string) {

JSONArray sheetArray = new JSONArray(string);
Expand Down

0 comments on commit 81cbd80

Please sign in to comment.