package net.gepafin.tendermanagement.dao; import jakarta.servlet.http.HttpServletRequest; import net.gepafin.tendermanagement.config.Translator; import net.gepafin.tendermanagement.constants.GepafinConstant; import net.gepafin.tendermanagement.entities.*; import net.gepafin.tendermanagement.enums.*; import net.gepafin.tendermanagement.model.request.ApplicationContractRequest; import net.gepafin.tendermanagement.model.request.VersionHistoryRequest; import net.gepafin.tendermanagement.model.response.ApplicationContractResponse; import net.gepafin.tendermanagement.model.response.DocumentResponseBean; import net.gepafin.tendermanagement.repositories.ApplicationContractRepository; import net.gepafin.tendermanagement.repositories.ApplicationRepository; import net.gepafin.tendermanagement.repositories.AssignedApplicationsRepository; import net.gepafin.tendermanagement.service.UserService; import net.gepafin.tendermanagement.util.DateTimeUtil; import net.gepafin.tendermanagement.util.LoggingUtil; import net.gepafin.tendermanagement.util.Utils; import net.gepafin.tendermanagement.web.rest.api.errors.CustomValidationException; import net.gepafin.tendermanagement.web.rest.api.errors.Status; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import org.springframework.web.multipart.MultipartFile; import java.time.LocalDateTime; import java.util.*; import java.util.stream.Collectors; @Component public class ApplicationContractDao { @Autowired private ApplicationDao applicationDao; @Autowired private DocumentDao documentDao; @Autowired private ApplicationContractRepository applicationContractRepository; @Autowired private ApplicationRepository applicationRepository; @Autowired private HttpServletRequest request; @Autowired private LoggingUtil loggingUtil; @Autowired private ApplicationAmendmentRequestDao applicationAmendmentRequestDao; @Autowired private EmailNotificationDao emailNotificationDao; @Autowired private ApplicationEvaluationDao applicationEvaluationDao; @Autowired private NotificationDao notificationDao; @Autowired private UserService userService; @Autowired private AssignedApplicationsRepository assignedApplicationsRepository; public ApplicationContractResponse createApplicationContract(Long applicationId, List contractDocuments, ApplicationContractRequest applicationContractRequest, UserEntity user) { ApplicationEntity applicationEntity = applicationDao.validateApplication(applicationId); Optional optionalAssignedApplicationsEntity=assignedApplicationsRepository.findByApplicationIdAndIsDeletedFalse(applicationEntity.getId()); AssignedApplicationsEntity assignedApplicationsEntity=optionalAssignedApplicationsEntity.get(); AssignedApplicationsEntity oldAssignedApplicationEntity=Utils.getClonedEntityForData(assignedApplicationsEntity); if (Boolean.FALSE.equals(applicationEntity.getStatus().equals(ApplicationStatusTypeEnum.APPROVED.getValue()))) { throw new CustomValidationException(Status.VALIDATION_ERROR, Translator.toLocale(GepafinConstant.APPLICATION_NOT_APPROVED)); } if (applicationContractRequest.getSubject() == null || applicationContractRequest.getText() == null) { throw new CustomValidationException(Status.VALIDATION_ERROR, Translator.toLocale(GepafinConstant.SUBJECT_AND_BODY_REQUIRED)); } ApplicationEntity oldApplicationData = Utils.getClonedEntityForData(applicationEntity); ApplicationContractEntity existingApplicationContractEntity = applicationContractRepository.findByApplicationIdAndIsDeletedFalse(applicationId); if (existingApplicationContractEntity != null) { throw new CustomValidationException(Status.VALIDATION_ERROR, Translator.toLocale(GepafinConstant.APPLICATION_CONTRACT_ALREADY_EXIST)); } ApplicationContractEntity applicationContractEntity = createApplicationContractEntity(applicationContractRequest, user, applicationEntity); loggingUtil.addVersionHistory(VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.INSERT).oldData(null).newData(applicationContractEntity).build()); List documentResponseBeans = setContractDocuments(contractDocuments, user, applicationContractEntity); applicationEntity.setStatus(ApplicationStatusTypeEnum.AWAITING_CONTRACT.getValue()); assignedApplicationsEntity.setStatus(AssignedApplicationEnum.AWAITING_CONTRACT.getValue()); applicationRepository.save(applicationEntity); assignedApplicationsRepository.save(assignedApplicationsEntity); loggingUtil.addVersionHistory( VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.UPDATE).oldData(oldApplicationData).newData(applicationEntity).build()); loggingUtil.addVersionHistory( VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.UPDATE).oldData(oldAssignedApplicationEntity).newData(assignedApplicationsEntity).build()); UserEntity userEntity = userService.validateUser(applicationEntity.getUserId()); emailNotificationDao.sendEmailForApplicationContracted(applicationEntity, applicationContractEntity, userEntity); return createApplicationContractResponse(applicationContractEntity, documentResponseBeans, null,applicationEntity.getCall().getName()); } private ApplicationContractResponse createApplicationContractResponse(ApplicationContractEntity applicationContractEntity, List instructorDocuments, List beneficiaryDocuments,String callName) { ApplicationContractResponse applicationContractResponse = new ApplicationContractResponse(); applicationContractResponse.setId(applicationContractEntity.getId()); applicationContractResponse.setText(applicationContractEntity.getText()); applicationContractResponse.setSubject(applicationContractEntity.getSubject()); applicationContractResponse.setInstructorId(applicationContractEntity.getInstructorId()); applicationContractResponse.setStatus(ApplicationContractStatusEnum.valueOf(applicationContractEntity.getStatus())); applicationContractResponse.setInstructorDocuments(instructorDocuments); applicationContractResponse.setBeneficiaryDocuments(beneficiaryDocuments); applicationContractResponse.setCompletionDate(applicationContractEntity.getCompletionDate()); applicationContractResponse.setBeneficiaryUserId(applicationContractEntity.getBeneficiaryUserId()); applicationContractResponse.setApplicationId(applicationContractEntity.getApplicationId()); applicationContractResponse.setCallName(callName); return applicationContractResponse; } private List setContractDocuments(List contractDocuments, UserEntity user, ApplicationContractEntity applicationContractEntity) { List documentResponseBeans = uploadContractDocument(user.getId(), contractDocuments, applicationContractEntity.getId()); List contractDocumentIds = documentResponseBeans.stream() .map(DocumentResponseBean::getId) .collect(Collectors.toList()); String contractDocumentId = contractDocumentIds.stream() .map(String::valueOf) .collect(Collectors.joining(",")); applicationContractEntity.setInstructorDocument(contractDocumentId); applicationContractRepository.save(applicationContractEntity); return documentResponseBeans; } private ApplicationContractEntity createApplicationContractEntity(ApplicationContractRequest applicationContractRequest, UserEntity user, ApplicationEntity applicationEntity) { ApplicationContractEntity applicationContractEntity = new ApplicationContractEntity(); applicationContractEntity.setSubject(applicationContractRequest.getSubject()); applicationContractEntity.setText(applicationContractRequest.getText()); applicationContractEntity.setApplicationId(applicationEntity.getId()); applicationContractEntity.setInstructorId(user.getId()); applicationContractEntity.setIsDeleted(Boolean.FALSE); applicationContractEntity.setApplicationId(applicationEntity.getId()); applicationContractEntity.setStatus(ApplicationContractStatusEnum.DRAFT.getValue()); applicationContractEntity.setBeneficiaryUserId(applicationEntity.getUserId()); applicationContractRepository.save(applicationContractEntity); return applicationContractEntity; } public List uploadContractDocument(Long userId, List files, Long applicationContractId) { if (files != null) { return documentDao.uploadFiles(userId, files, applicationContractId, DocumentSourceTypeEnum.CONTRACT, DocumentTypeEnum.DOCUMENT); } return new ArrayList<>(); } public ApplicationContractResponse updateApplicationContract(Long applicationContractId, List beneficiaryContractDocuments, UserEntity user) { ApplicationContractEntity applicationContractEntity = validateApplicationContract(applicationContractId); ApplicationContractEntity oldApplicationContract = Utils.getClonedEntityForData(applicationContractEntity); applicationContractEntity.setCompletionDate(DateTimeUtil.DateServerToUTC(LocalDateTime.now())); applicationContractEntity.setStatus(ApplicationContractStatusEnum.SIGNED.getValue()); List beneficiaryContractDocuments1 = setBeneficiaryContractDocuments(beneficiaryContractDocuments, user, applicationContractEntity); List documentResponseBeans = applicationAmendmentRequestDao.getDocumentResponseBean(applicationContractEntity.getInstructorDocument()); loggingUtil.addVersionHistory( VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.UPDATE).oldData(oldApplicationContract).newData(applicationContractEntity).build()); ApplicationEntity applicationEntity = applicationDao.validateApplication(applicationContractEntity.getApplicationId()); ApplicationEntity oldApplicationData = Utils.getClonedEntityForData(applicationEntity); Optional optionalAssignedApplicationsEntity=assignedApplicationsRepository.findByApplicationIdAndIsDeletedFalse(applicationEntity.getId()); AssignedApplicationsEntity assignedApplicationsEntity=optionalAssignedApplicationsEntity.get(); AssignedApplicationsEntity oldAssignedApplicationEntity=Utils.getClonedEntityForData(assignedApplicationsEntity); ApplicationEvaluationEntity applicationEvaluationEntity = applicationEvaluationDao.validateApplicationEvaluation(applicationEntity.getApplicationEvaluationId()); applicationEntity.setStatus(ApplicationStatusTypeEnum.CONTRACT_SIGNED.getValue()); assignedApplicationsEntity.setStatus(AssignedApplicationEnum.CONTRACT_SIGNED.getValue()); applicationRepository.save(applicationEntity); assignedApplicationsRepository.save(assignedApplicationsEntity); loggingUtil.addVersionHistory( VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.UPDATE).oldData(oldApplicationData).newData(applicationEntity).build()); loggingUtil.addVersionHistory( VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.UPDATE).oldData(oldAssignedApplicationEntity).newData(assignedApplicationsEntity).build()); Map placeHolders = new HashMap<>(); placeHolders.put("{{call_name}}", applicationEntity.getCall().getName()); String protocolNumber = applicationEntity.getProtocol().getExternalProtocolNumber(); if (protocolNumber == null) { protocolNumber = String.valueOf(applicationEntity.getProtocol().getProtocolNumber()); } placeHolders.put("{{protocol_number}}", protocolNumber); notificationDao.sendNotificationToInstructor(placeHolders, applicationEvaluationEntity, NotificationTypeEnum.CONTRACT_UPLOAD); return createApplicationContractResponse(applicationContractEntity, documentResponseBeans, beneficiaryContractDocuments1,applicationEntity.getCall().getName()); } public ApplicationContractEntity validateApplicationContract(Long applicationContractId) { ApplicationContractEntity applicationContractEntity = applicationContractRepository.findByIdAndIsDeletedFalse(applicationContractId); if (applicationContractEntity == null) { throw new CustomValidationException(Status.NOT_FOUND, Translator.toLocale(GepafinConstant.APPLICATION_CONTRACT_NOT_FOUND)); } return applicationContractEntity; } private List setBeneficiaryContractDocuments(List contractDocuments, UserEntity user, ApplicationContractEntity applicationContractEntity) { List documentResponseBeans = uploadContractDocument(user.getId(), contractDocuments, applicationContractEntity.getId()); List contractDocumentIds = documentResponseBeans.stream() .map(DocumentResponseBean::getId) .collect(Collectors.toList()); String contractDocumentId = contractDocumentIds.stream() .map(String::valueOf) .collect(Collectors.joining(",")); applicationContractEntity.setBeneficiaryDocument(contractDocumentId); applicationContractRepository.save(applicationContractEntity); return documentResponseBeans; } public ApplicationContractResponse getContractById(Long contractId) { ApplicationContractEntity applicationContractEntity = validateApplicationContract(contractId); ApplicationEntity applicationEntity = applicationDao.validateApplication(applicationContractEntity.getApplicationId()); return createApplicationContractResponseFromEntity(applicationContractEntity,applicationEntity.getCall().getName()); } private ApplicationContractResponse createApplicationContractResponseFromEntity(ApplicationContractEntity applicationContractEntity,String callName) { List instructorDocuments = applicationAmendmentRequestDao.getDocumentResponseBean(applicationContractEntity.getInstructorDocument()); List beneficiaryDocuments = applicationAmendmentRequestDao.getDocumentResponseBean(applicationContractEntity.getBeneficiaryDocument()); return createApplicationContractResponse(applicationContractEntity, instructorDocuments, beneficiaryDocuments,callName); } public ApplicationContractResponse getContractByApplicationId(Long applicationId) { ApplicationContractEntity applicationContractEntity = applicationContractRepository.findByApplicationIdAndIsDeletedFalse(applicationId); if (applicationContractEntity == null) { return null; } ApplicationEntity applicationEntity = applicationDao.validateApplication(applicationContractEntity.getApplicationId()); return createApplicationContractResponseFromEntity(applicationContractEntity,applicationEntity.getCall().getName()); } public List getContractByBeneficiaryUserId(UserEntity user) { List applicationContractEntities = applicationContractRepository.findByBeneficiaryUserIdAndStatusAndIsDeletedFalse(user.getId(), ApplicationContractStatusEnum.DRAFT.getValue()); if (applicationContractEntities.isEmpty()) { return null; } List applicationContractResponses = new ArrayList<>(); for (ApplicationContractEntity applicationContractEntity : applicationContractEntities) { ApplicationEntity applicationEntity = applicationDao.validateApplication(applicationContractEntity.getApplicationId()); ApplicationContractResponse applicationContractResponse = createApplicationContractResponseFromEntity(applicationContractEntity,applicationEntity.getCall().getName()); applicationContractResponses.add(applicationContractResponse); } return applicationContractResponses; } }