package net.gepafin.tendermanagement.dao; import jakarta.persistence.criteria.Predicate; import jakarta.servlet.http.HttpServletRequest; import net.gepafin.tendermanagement.config.Translator; import net.gepafin.tendermanagement.constants.GepafinConstant; import net.gepafin.tendermanagement.entities.ApplicationEntity; import net.gepafin.tendermanagement.entities.AssignedApplicationsEntity; import net.gepafin.tendermanagement.entities.UserEntity; import net.gepafin.tendermanagement.enums.ApplicationStatusTypeEnum; import net.gepafin.tendermanagement.enums.AssignedApplicationEnum; import net.gepafin.tendermanagement.model.request.AssignedApplicationsRequest; import net.gepafin.tendermanagement.model.response.AssignedApplicationsResponse; import net.gepafin.tendermanagement.repositories.ApplicationRepository; import net.gepafin.tendermanagement.repositories.AssignedApplicationsRepository; import net.gepafin.tendermanagement.service.ApplicationService; import net.gepafin.tendermanagement.service.UserService; import net.gepafin.tendermanagement.util.DateTimeUtil; import net.gepafin.tendermanagement.util.Validator; import net.gepafin.tendermanagement.web.rest.api.errors.CustomValidationException; import net.gepafin.tendermanagement.web.rest.api.errors.ResourceNotFoundException; import net.gepafin.tendermanagement.web.rest.api.errors.Status; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.jpa.domain.Specification; import org.springframework.stereotype.Component; import java.time.LocalDateTime; import java.util.List; import java.util.stream.Collectors; import static net.gepafin.tendermanagement.util.Utils.log; import static net.gepafin.tendermanagement.util.Utils.setIfUpdated; @Component public class AssignedApplicationsDao { @Autowired private ApplicationService applicationService; @Autowired private ApplicationRepository applicationRepository; @Autowired private AssignedApplicationsRepository assignedApplicationsRepository; @Autowired private UserService userService; @Autowired private Validator validator; public AssignedApplicationsResponse createAssignedApplications(Long applicationId, Long userId, UserEntity assignedByUser, AssignedApplicationsRequest assignedApplicationsRequest){ log.info("Assigning application to pre-Instructor with details: {}", applicationId,userId); AssignedApplicationsEntity assignedApplications = assignedApplicationsRepository.findByApplicationIdAndIsDeletedFalse(applicationId).orElse(null); if(assignedApplications!=null){ throw new CustomValidationException(Status.BAD_REQUEST, Translator.toLocale(GepafinConstant.APPLICATION_ALREADY_ASSIGNED)); } ApplicationEntity application = applicationService.validateApplication(applicationId); if (Boolean.FALSE.equals(ApplicationStatusTypeEnum.SUBMIT.getValue().equals(application.getStatus()))) { throw new CustomValidationException( Status.BAD_REQUEST, Translator.toLocale(GepafinConstant.INVALID_APPLICATION_STATUS) ); } application.setStatus(ApplicationStatusTypeEnum.EVALUATION.getValue()); applicationRepository.save(application); UserEntity user = userService.validateUser(userId); AssignedApplicationsEntity assignment = createAssignmentEntity(application, user.getId(), assignedByUser, assignedApplicationsRequest); AssignedApplicationsResponse assignApplicationToInstructorResponse = convertEntityToResponse(assignment); log.info("Application assigned succesfully {}", assignApplicationToInstructorResponse); return assignApplicationToInstructorResponse; } public AssignedApplicationsEntity createAssignmentEntity(ApplicationEntity application, Long userId, UserEntity assignedByUser, AssignedApplicationsRequest assignedApplicationsRequest){ AssignedApplicationsEntity assignApplication= new AssignedApplicationsEntity(); assignApplication.setApplication(application); assignApplication.setAssignedBy(assignedByUser.getId()); assignApplication.setUserId(userId); assignApplication.setStatus(AssignedApplicationEnum.ASSIGNED.getValue()); if(assignedApplicationsRequest.getStatus() != null) { assignApplication.setStatus(assignedApplicationsRequest.getStatus().getValue()); } assignApplication.setNote(assignedApplicationsRequest.getNote()); assignApplication.setIsDeleted(false); assignApplication.setAssignedAt(DateTimeUtil.DateServerToUTC(LocalDateTime.now())); AssignedApplicationsEntity assignedApplicationsEntity = saveAssignedApplication(assignApplication); return assignedApplicationsEntity; } public AssignedApplicationsEntity saveAssignedApplication(AssignedApplicationsEntity assignedApplicationsEntity){ AssignedApplicationsEntity assignedApplication= assignedApplicationsRepository.save(assignedApplicationsEntity); return assignedApplication; } public AssignedApplicationsResponse convertEntityToResponse(AssignedApplicationsEntity assignedApplications){ AssignedApplicationsResponse assignedApplicationsResponse = new AssignedApplicationsResponse(); assignedApplicationsResponse.setId(assignedApplications.getId()); assignedApplicationsResponse.setApplicationId(assignedApplications.getApplication().getId()); ApplicationEntity application = applicationService.validateApplication(assignedApplications.getApplication().getId()); String callName = application.getCall() != null ? application.getCall().getName() : ""; LocalDateTime callEndDate = application.getCall().getEndDate(); LocalDateTime callStartDate = application.getCall().getStartDate(); Long protocolNumber = (application.getProtocol() != null && application.getProtocol().getProtocolNumber() != null) ? application.getProtocol().getProtocolNumber() : 0; LocalDateTime submissionDate = application.getSubmissionDate(); UserEntity userEntity = userService.validateUser(application.getUserId()); String firstName = userEntity.getBeneficiary() != null ? userEntity.getBeneficiary().getFirstName() : null; String lastName = userEntity.getBeneficiary() != null ? userEntity.getBeneficiary().getLastName() : null; String beneficiaryName = (firstName != null && !firstName.isBlank() ? firstName : "") + (lastName != null && !lastName.isBlank() ? " " + lastName : ""); beneficiaryName = beneficiaryName.isBlank() ? "" : beneficiaryName; assignedApplicationsResponse.setAssignedBy(assignedApplications.getAssignedBy()); assignedApplicationsResponse.setUserId(assignedApplications.getUserId()); assignedApplicationsResponse.setCreatedDate(assignedApplications.getCreatedDate()); assignedApplicationsResponse.setUpdatedDate(assignedApplications.getUpdatedDate()); assignedApplicationsResponse.setNote(assignedApplications.getNote()); assignedApplicationsResponse.setStatus(AssignedApplicationEnum.valueOf(assignedApplications.getStatus())); assignedApplicationsResponse.setAssignedAt(assignedApplications.getAssignedAt()); assignedApplicationsResponse.setProtocolNumber(protocolNumber); assignedApplicationsResponse.setCallName(callName); assignedApplicationsResponse.setBeneficiaryName(beneficiaryName); assignedApplicationsResponse.setSubmissionDate(submissionDate); assignedApplicationsResponse.setCallEndDate(callEndDate); assignedApplicationsResponse.setCallStartDate(callStartDate); return assignedApplicationsResponse; } public AssignedApplicationsEntity validateAssignedApplication(Long id){ AssignedApplicationsEntity assignedApplication = assignedApplicationsRepository.findByIdAndIsDeletedFalse(id).orElseThrow(()-> new ResourceNotFoundException(Status.NOT_FOUND,Translator.toLocale(GepafinConstant.ASSIGNED_APPLICATION_NOT_FOUND_MSG))); return assignedApplication; } public void deleteById(HttpServletRequest request, Long id) { log.info("Deleting assigned application with ID: {}", id); AssignedApplicationsEntity assignedApplicationsEntity= validateAssignedApplication(id); validator.validatePreInstructor(request, assignedApplicationsEntity.getUserId()); assignedApplicationsEntity.setIsDeleted(true); assignedApplicationsEntity= saveAssignedApplication(assignedApplicationsEntity); log.info("Assigned Application deleted with ID: {}", id); } public List getAllAssignedApplications(HttpServletRequest request, Long userId) { UserEntity user = validator.validateUser(request); if(validator.checkIsPreInstructor() && userId == null) { throw new CustomValidationException(Status.BAD_REQUEST, Translator.toLocale(GepafinConstant.USER_ID_NOT_NULL_MSG)); } if(userId != null) { validator.validatePreInstructor(request, userId); } Specification spec = search(user.getHub().getId() ,userId); List assignedApplicationsEntityList = assignedApplicationsRepository.findAll(spec); return assignedApplicationsEntityList.stream() .map(entity -> convertEntityToResponse(entity)) .collect(Collectors.toList()); } private Specification search(Long hubId, Long userId) { return (root, query, builder) -> { Predicate predicate = builder.isFalse(root.get("isDeleted")); if (userId != null) { predicate = builder.and(predicate, builder.equal(root.get("userId"), userId)); } predicate = builder.and(predicate, builder.equal(root.get("application").get("hubId"), hubId)); return predicate; }; } public AssignedApplicationsResponse updateAssignedApplication(HttpServletRequest request, Long id, AssignedApplicationsRequest updateRequest) { UserEntity updatedByUser = validator.validateUser(request); log.info("Updating assigned application with ID: {}", id); AssignedApplicationsEntity existingAssignment = validateAssignedApplication(id); validator.validatePreInstructor(request, existingAssignment.getUserId()); setIfUpdated(existingAssignment::getNote, existingAssignment::setNote, updateRequest.getNote()); setIfUpdated(existingAssignment::getStatus, existingAssignment::setStatus, updateRequest.getStatus().name()); setIfUpdated(existingAssignment::getAssignedBy, existingAssignment::setAssignedBy, updatedByUser.getId()); existingAssignment.setUpdatedDate(DateTimeUtil.DateServerToUTC(LocalDateTime.now())); AssignedApplicationsEntity updatedAssignment = saveAssignedApplication(existingAssignment); AssignedApplicationsResponse response = convertEntityToResponse(updatedAssignment); log.info("Assigned application updated successfully: {}", response); return response; } public AssignedApplicationsResponse getAssignedApplicationById(HttpServletRequest request, Long id) { log.info("Fetching assigned application with ID: {}", id); AssignedApplicationsEntity assignedApplication = validateAssignedApplication(id); validator.validatePreInstructor(request, assignedApplication.getUserId()); AssignedApplicationsResponse response = convertEntityToResponse(assignedApplication); log.info("Assigned application fetched successfully: {}", response); return response; } }