package net.gepafin.tendermanagement.dao; import net.gepafin.tendermanagement.config.Translator; import net.gepafin.tendermanagement.constants.GepafinConstant; import net.gepafin.tendermanagement.entities.*; import net.gepafin.tendermanagement.entities.SystemEmailTemplatesEntity.SystemEmailTemplatesEntityTypeEnum; import net.gepafin.tendermanagement.enums.ApplicationSignedDocumentStatusEnum; import net.gepafin.tendermanagement.enums.ApplicationStatusTypeEnum; import net.gepafin.tendermanagement.enums.DocumentSourceTypeEnum; import net.gepafin.tendermanagement.enums.RoleStatusEnum; import net.gepafin.tendermanagement.enums.UserCompanyDelegationStatusEnum; import net.gepafin.tendermanagement.model.request.ApplicationFormFieldRequestBean; import net.gepafin.tendermanagement.model.request.ApplicationRequest; import net.gepafin.tendermanagement.model.request.ApplicationRequestBean; import net.gepafin.tendermanagement.model.response.*; import net.gepafin.tendermanagement.repositories.*; import net.gepafin.tendermanagement.service.AmazonS3Service; import net.gepafin.tendermanagement.service.CallService; import net.gepafin.tendermanagement.service.CompanyService; import net.gepafin.tendermanagement.service.DocumentService; import net.gepafin.tendermanagement.service.FormService; import net.gepafin.tendermanagement.service.SystemEmailTemplatesService; import net.gepafin.tendermanagement.service.UserService; import net.gepafin.tendermanagement.util.DateTimeUtil; import net.gepafin.tendermanagement.util.FieldValidator; import net.gepafin.tendermanagement.util.MailUtil; import net.gepafin.tendermanagement.util.Utils; 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.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.data.jpa.domain.Specification; import org.springframework.stereotype.Component; import org.springframework.web.multipart.MultipartFile; import jakarta.persistence.criteria.Predicate; import jakarta.servlet.http.HttpServletRequest; import java.text.MessageFormat; import java.time.LocalDateTime; import java.time.LocalTime; import java.util.*; import java.util.stream.Collectors; @Component public class ApplicationDao { private final Logger log = LoggerFactory.getLogger(ApplicationDao.class); @Autowired private CallService callService; @Autowired private ApplicationRepository applicationRepository; @Autowired private ApplicationFormRepository applicationFormRepository; @Autowired private ApplicationFormFieldRepository applicationFormFieldRepository; @Autowired private FormService formService; @Autowired private DocumentService documentService; @Autowired private CallDao callDao; @Autowired private FlowFormDao flowFormDao; @Autowired private FlowEdgesRepository flowEdgesRepository; @Autowired private FlowDataRepository flowDataRepository; @Autowired private UserCompanyDelegationRepository userCompanyDelegationRepository; @Autowired private Validator validator; @Autowired private CompanyService companyService; @Autowired private ProtocolRepository protocolRepository; @Autowired private SystemEmailTemplatesService systemEmailTemplatesService; @Autowired private MailUtil mailUtil; @Value("${default_System_Receiver_Email}") private String defaultSystemReceiverEmail; @Value("${gepafin_email}") private String gepafinEmail; @Value("${rinaldo_email}") private String rinaldoEmail; @Value("${carlo_email}") private String carloEmail; @Autowired private AmazonS3Service amazonS3Service; @Autowired private ApplicationSignedDocumentRepository applicationSignedDocumentRepository; @Value("${aws.s3.url.folder.signed.document}") private String signedDocumentS3Folder; @Value("${default.hub.uuid}") private String defaultHubUuid; @Autowired private UserService userService; public ApplicationResponseBean createApplication(HttpServletRequest request, ApplicationRequestBean applicationRequestBean, Long formId, Long applicationId) { FormEntity formEntity = formService.validateForm(formId); // callService.validatePublishedCall(formEntity.getCall().getId()); validateFormFields(applicationRequestBean,formEntity); ApplicationEntity applicationEntity = validateApplication(applicationId); validator.validateUserWithCompany(request, applicationEntity.getCompany().getId()); if(Boolean.FALSE.equals(applicationEntity.getStatus().equals(ApplicationStatusTypeEnum.DRAFT.getValue()))) { throw new CustomValidationException(Status.BAD_REQUEST,Translator.toLocale(GepafinConstant.APPLICATION_NOT_IN_DRAFT_STATUS)); } formService.validateFormField(applicationRequestBean.getFormFields(),applicationEntity,formEntity); ApplicationFormEntity applicationFormEntity = getApplicationFormOrCreate(formEntity, applicationEntity); createOrUpdateMultipleFormFields(applicationRequestBean.getFormFields(), applicationFormEntity, formEntity); return getApplicationById(applicationEntity.getId(),formEntity.getId()); } public void validateDelegation(UserEntity user, CompanyEntity company) { UserWithCompanyEntity userWithCompany = companyService.getUserWithCompanyEntity(user.getId(), company.getId()); UserCompanyDelegationEntity userCompanyDelegationEntity = userCompanyDelegationRepository .findByUserIdAndCompanyIdAndStatus(user.getId(), company.getId(), UserCompanyDelegationStatusEnum.ACTIVE.getValue()); if (!userWithCompany.getIsLegalRepresentant() && userCompanyDelegationEntity == null) { throw new CustomValidationException(Status.BAD_REQUEST, Translator.toLocale(GepafinConstant.USER_NOT_AUTHORIZED_TO_CREATE_APPLICATION)); } } public ApplicationFormEntity saveApplicationFormEntity(ApplicationFormEntity applicationFormEntity) { ApplicationFormEntity applicationFormEntity1 = applicationFormRepository.save(applicationFormEntity); return applicationFormEntity1; } public ApplicationFormEntity createApplicationFormEntity(ApplicationEntity application, FormEntity formEntity) { ApplicationFormEntity applicationFormEntity = new ApplicationFormEntity(); applicationFormEntity.setApplication(application); applicationFormEntity.setForm(formEntity); applicationFormEntity = saveApplicationFormEntity(applicationFormEntity); return applicationFormEntity; } public ApplicationEntity createApplicationEntity(UserEntity user, CallEntity call, CompanyEntity companyEntity) { validateDelegation(user,companyEntity); ApplicationEntity entity = new ApplicationEntity(); entity.setUserId(user.getId()); entity.setCompany(companyEntity); entity.setCall(call); entity.setHubId(call.getHub().getId()); entity.setIsDeleted(false); entity.setStatus(ApplicationStatusTypeEnum.DRAFT.getValue()); return entity; } public ApplicationResponseBean getApplicationById(Long id,Long formId) { log.info("Fetching application with ID: {}", id); ApplicationEntity applicationEntity = validateApplication(id); ApplicationFormEntity applicationFormEntity = applicationFormRepository.findByApplicationIdAndFormId(applicationEntity.getId(),formId); List applicationFormFieldResponseBeans=new ArrayList<>(); List applicationFormFieldEntities = applicationFormFieldRepository.findByApplicationFormId(applicationFormEntity.getId()); applicationFormFieldResponseBeans=createApplicationFormFieldResponse(applicationFormFieldEntities, applicationFormEntity, applicationFormFieldResponseBeans); ApplicationResponseBean applicationResponseBean= convertApplicationEntityToApplicationResponseBean(applicationEntity); applicationResponseBean.setFormFields(applicationFormFieldResponseBeans); return applicationResponseBean; } private List createApplicationFormFieldResponse( List applicationFormFieldEntities, ApplicationFormEntity applicationFormEntity, List applicationFormFieldResponseBeans) { List contentResponseBeans = Utils.convertJsonStringToList( applicationFormEntity.getForm().getContent(), ContentResponseBean.class); for (ApplicationFormFieldEntity applicationFormFieldEntity : applicationFormFieldEntities) { Optional fileUploadContent = contentResponseBeans.stream() .filter(contentResponseBean -> "fileupload".equals(contentResponseBean.getName()) && contentResponseBean.getId().equals(applicationFormFieldEntity.getFieldId())) .findFirst(); List documentResponseBeans = new ArrayList<>(); if (fileUploadContent.isPresent()) { String documentId = applicationFormFieldEntity.getFieldValue(); if (documentId != null && !documentId.isEmpty()) { documentResponseBeans = Arrays.stream(documentId.split(",")) .map(String::trim) .map(Long::parseLong) .map(docId -> { DocumentEntity documentEntity = documentService.validateDocument(docId); if (Boolean.FALSE.equals(DocumentSourceTypeEnum.APPLICATION.getValue().equals(documentEntity.getSource()))) { throw new CustomValidationException(Status.NOT_FOUND,Translator.toLocale(GepafinConstant.DOCUMENT_NOT_FOUND)); } return documentEntity; }) .map(callDao::convertToDocumentResponseBean) .collect(Collectors.toList()); } } ApplicationFormFieldResponseBean responseBean = convertApplicationFormFieldEntityToApplicationFormFieldResponseBean( applicationFormFieldEntity, applicationFormEntity.getId()); if (!documentResponseBeans.isEmpty()) { responseBean.setFieldValue(documentResponseBeans); } applicationFormFieldResponseBeans.add(responseBean); } return applicationFormFieldResponseBeans; } public void deleteById(HttpServletRequest request, Long id) { log.info("Deleting application with ID: {}", id); ApplicationEntity applicationEntity= validateApplication(id); validator.validateUserWithCompany(request, applicationEntity.getCompany().getId()); applicationEntity.setIsDeleted(true); applicationEntity=saveApplicationEntity(applicationEntity); log.info("Application deleted with ID: {}", id); } // public List getAllApplications(UserEntity userEntity, Long callId, CompanyEntity companyEntity) { // boolean isBeneficiary = validator.checkIsBeneficiary(); // // log.info("Fetching applications for RoleType: {}", userEntity.getRoleEntity().getRoleType()); // List applicationResponses = new ArrayList<>(); // // if (callId != null) { // // Fetch based on callId and user if role is BENEFICIARY, otherwise fetch all for the call // log.info("Fetching applications for callId: {}", callId); // CallEntity call = callService.validateCall(callId); // // // Use a single method to handle both conditions for consistency // List applicationEntities = isBeneficiary // ? applicationRepository.findByUserIdAndCallIdAndIsDeletedFalse(userEntity.getId(), call.getId()) // .map(List::of) // Convert Optional to a List of one element // .orElse(List.of()) // If not present, return an empty list // : applicationRepository.findByCallIdAndIsDeletedFalse(call.getId()); // // applicationResponses = applicationEntities.stream() // .map(this::getApplicationResponse) // .collect(Collectors.toList()); // // } else { // // Fetch all applications for the user if BENEFICIARY, or fetch all applications in general // List applicationEntities = isBeneficiary // ? applicationRepository.findByUserIdAndIsDeletedFalse(companyEntity.getId()) // : applicationRepository.findByIsDeletedFalse(); // // applicationResponses = applicationEntities.stream() // .map(this::getApplicationResponse) // .collect(Collectors.toList()); // } // // return applicationResponses; // } public List getAllApplications(UserEntity userEntity, Long callId, Long companyId,String status) { log.info("Fetching applications for RoleType: {}", userEntity.getRoleEntity().getRoleType()); Specification spec = search(userEntity, callId, companyId,status); List applicationEntities = applicationRepository.findAll(spec); return applicationEntities.stream() .map(this::getApplicationResponse) .collect(Collectors.toList()); } private Specification search(UserEntity userEntity, Long callId, Long companyId,String status) { return (root, query, builder) -> { Boolean isBeneficiary = validator.checkIsBeneficiary(); Predicate predicate = builder.isFalse(root.get("isDeleted")); if (isBeneficiary) { predicate = builder.and(predicate, builder.equal(root.get("userId"), userEntity.getId())); } if (callId != null) { predicate = builder.and(predicate, builder.equal(root.get("call").get("id"), callId)); } if (companyId != null) { predicate = builder.and(predicate, builder.equal(root.get("company").get("id"), companyId)); } if (status != null) { predicate = builder.and(predicate, builder.equal(root.get("status"), status)); } predicate = builder.and(predicate, builder.equal(root.get("hubId"), userEntity.getHub().getId())); return predicate; }; } private ApplicationResponse getApplicationResponse(ApplicationEntity applicationEntity) { ApplicationResponse responseBean = new ApplicationResponse(); List flowEdgesList = flowEdgesRepository.findByCallId(applicationEntity.getCall().getId()); Long totalFormSteps = flowFormDao.calculateTotalSteps(flowEdgesList); Long completedSteps= Long.valueOf(flowFormDao.getCompletedSteps(applicationEntity)); Integer progress=calculateProgress(totalFormSteps,completedSteps); responseBean.setId(applicationEntity.getId()); responseBean.setProgress(progress); responseBean.setCallTitle(applicationEntity.getCall().getName()); responseBean.setCallEndDate(applicationEntity.getCall().getEndDate()); responseBean.setModifiedDate(applicationEntity.getCall().getUpdatedDate()); responseBean.setCallId(applicationEntity.getCall().getId()); responseBean.setSubmissionDate(applicationEntity.getSubmissionDate()); responseBean.setStatus(applicationEntity.getStatus()); responseBean.setComments(applicationEntity.getComments()); responseBean.setCompanyId(applicationEntity.getCompany().getId()); responseBean.setCompanyName(applicationEntity.getCompany().getCompanyName()); if(applicationEntity.getProtocol() != null) { responseBean.setProtocolNumber(applicationEntity.getProtocol().getProtocolNumber()); } return responseBean; } public ApplicationEntity validateApplication(Long id) { ApplicationEntity applicationEntity = applicationRepository.findById(id) .orElseThrow(() -> new ResourceNotFoundException(Status.NOT_FOUND, Translator.toLocale(GepafinConstant.APPLICATION_NOT_FOUND_MSG))); return applicationEntity; } private ApplicationResponseBean convertApplicationEntityToApplicationResponseBean(ApplicationEntity entity) { ApplicationResponseBean response = new ApplicationResponseBean(); response.setId(entity.getId()); response.setSubmissionDate(entity.getSubmissionDate()); response.setStatus(entity.getStatus()); response.setComments(entity.getComments()); response.setCallId(entity.getCall().getId()); response.setCreatedDate(entity.getCreatedDate()); response.setUpdatedDate(entity.getUpdatedDate()); if(entity.getProtocol() != null) { response.setProtocolNumber(entity.getProtocol().getProtocolNumber()); } return response; } private ApplicationFormEntity getApplicationFormOrCreate(FormEntity formEntity, ApplicationEntity applicationEntity) { ApplicationFormEntity applicationFormEntity = applicationFormRepository.findByApplicationIdAndFormId(applicationEntity.getId(), formEntity.getId()); if(applicationFormEntity == null){ applicationFormEntity = createApplicationFormEntity(applicationEntity, formEntity); } return applicationFormEntity; } public List createOrUpdateMultipleFormFields(List formFieldResponseBeans, ApplicationFormEntity applicationFormEntity,FormEntity formEntity) { List existingFields = applicationFormFieldRepository.findByApplicationFormId(applicationFormEntity.getId()); List applicationFormFieldEntity = formFieldResponseBeans.stream() .map(requestBean -> createOrUpdateApplicationFormField(requestBean, applicationFormEntity,existingFields,formEntity)) .collect(Collectors.toList()); return applicationFormFieldEntity; } public ApplicationFormFieldEntity createOrUpdateApplicationFormField(ApplicationFormFieldRequestBean applicationFormFieldRequestBean, ApplicationFormEntity applicationFormEntity,List applicationFormFieldEntities ,FormEntity formEntity) { ApplicationFormFieldEntity applicationFormFieldEntity=null; validateFileUploadDocuments(applicationFormFieldRequestBean, formEntity); if(applicationFormFieldEntities==null || applicationFormFieldEntities.isEmpty()){ applicationFormFieldEntity = new ApplicationFormFieldEntity(); applicationFormFieldEntity.setApplicationForm(applicationFormEntity); }else { for (ApplicationFormFieldEntity applicationFormFieldEntity1 : applicationFormFieldEntities) { if (applicationFormFieldEntity1.getFieldId().equals(applicationFormFieldRequestBean.getFieldId())) { applicationFormFieldEntity = applicationFormFieldEntity1; if(applicationFormEntity.getForm().getId().equals(applicationFormEntity.getApplication().getCall().getInitialForm())){ validateRequiredFields(applicationFormEntity.getForm(),applicationFormEntity.getApplication(), applicationFormFieldRequestBean.getFieldId()); } break; } else { applicationFormFieldEntity = new ApplicationFormFieldEntity(); applicationFormFieldEntity.setApplicationForm(applicationFormEntity); } } } Utils.setIfUpdated(applicationFormFieldEntity::getFieldId, applicationFormFieldEntity::setFieldId, applicationFormFieldRequestBean.getFieldId()); if(applicationFormFieldRequestBean.getFieldValue() !=null ) { applicationFormFieldEntity.setFieldValue(Utils.convertObjectToJsonString(applicationFormFieldRequestBean.getFieldValue())); } if(applicationFormFieldRequestBean.getFieldValue() ==null ) { applicationFormFieldEntity.setFieldValue(null); } return applicationFormFieldRepository.save(applicationFormFieldEntity); } private List validateFileUploadDocuments(ApplicationFormFieldRequestBean applicationFormFieldRequestBean, FormEntity formEntity) { List documentIds=null; List contentResponseBeans=Utils.convertJsonStringToList(formEntity.getContent(),ContentResponseBean.class); for (ContentResponseBean contentResponseBean:contentResponseBeans){ if(Boolean.TRUE.equals(contentResponseBean.getName().equals("fileupload"))) { if (contentResponseBean.getId().equals(applicationFormFieldRequestBean.getFieldId())) { Object fieldValueObject = applicationFormFieldRequestBean.getFieldValue(); if (fieldValueObject instanceof String) { // Safely cast the object to a string String documentId = (String) fieldValueObject; // Now you can use documentId as needed documentIds = validateDocumentIds(documentId); } } } } return documentIds; } private List validateDocumentIds(String documentId) { if (documentId != null && !documentId.isEmpty()) { return Arrays.stream(documentId.split(",")) .map(Long::parseLong) .peek(docId -> documentService.validateDocument(docId)) .collect(Collectors.toList()); } return Collections.emptyList(); } public ApplicationFormFieldEntity validateApplicationFormField(Long applicationFormFieldId) { Optional applicationFormFieldEntity = applicationFormFieldRepository.findById(applicationFormFieldId); if (applicationFormFieldEntity.isEmpty()) { throw new ResourceNotFoundException(Status.NOT_FOUND, Translator.toLocale(GepafinConstant.APPLICATION_FORM_FIELD_NOT_FOUND)); } return applicationFormFieldEntity.get(); } public List saveApplicationFormFieldEntities(List applicationFormFieldEntities) { List applicationFormFieldEntities1 = applicationFormFieldRepository.saveAll(applicationFormFieldEntities); return applicationFormFieldEntities1; } public List convertApplicationFormFieldEntitiesToApplicationFormFieldResponseBeans(List applicationFormFieldEntities, Long applicationFormId) { return applicationFormFieldEntities.stream() .map(requestBean -> convertApplicationFormFieldEntityToApplicationFormFieldResponseBean(requestBean, applicationFormId)) .collect(Collectors.toList()); } public ApplicationFormFieldResponseBean convertApplicationFormFieldEntityToApplicationFormFieldResponseBean(ApplicationFormFieldEntity applicationFormFieldEntity, Long applicationFormId) { ApplicationFormFieldResponseBean applicationFormFieldResponseBean = new ApplicationFormFieldResponseBean(); applicationFormFieldResponseBean.setApplicationFormId(applicationFormId); applicationFormFieldResponseBean.setFieldId(applicationFormFieldEntity.getFieldId()); if(applicationFormFieldEntity.getFieldValue() != null) { applicationFormFieldResponseBean.setFieldValue(Utils.getFieldValueAsObject(applicationFormFieldEntity.getFieldValue())); } applicationFormFieldResponseBean.setId(applicationFormFieldEntity.getId()); applicationFormFieldResponseBean.setCreatedDate(applicationFormFieldEntity.getCreatedDate()); applicationFormFieldResponseBean.setUpdatedDate(applicationFormFieldEntity.getUpdatedDate()); return applicationFormFieldResponseBean; } public ApplicationEntity saveApplicationEntity(ApplicationEntity application){ ApplicationEntity applicationEntity=applicationRepository.save(application); return applicationEntity; } public ApplicationGetResponseBean getApplicationByFormId(HttpServletRequest request, Long applicationId, Long formId) { List formApplicationResponses = new ArrayList<>(); List formEntities = new ArrayList<>(); UserEntity userEntity = validator.validateUser(request); boolean isBeneficiary = isBeneficiary(userEntity); ApplicationEntity applicationEntity = isBeneficiary ? applicationRepository.findByIdAndUserIdAndIsDeletedFalse(applicationId, userEntity.getId()) .orElseThrow(() -> new CustomValidationException(Status.BAD_REQUEST, Translator.toLocale(GepafinConstant.APPLICATION_NOT_FOUND_MSG))) : applicationRepository.findById(applicationId) .stream().findFirst() .orElseThrow(() -> new CustomValidationException(Status.BAD_REQUEST, Translator.toLocale(GepafinConstant.APPLICATION_NOT_FOUND_MSG))); if (formId != null) { FormEntity formEntity = formService.validateForm(formId); Optional application = applicationRepository.findByIdAndUserIdAndCallIdAndIsDeletedFalse(applicationId, userEntity.getId(), formEntity.getCall().getId()); applicationEntity=application.get(); formEntities.add(formEntity); addFormApplication(formEntity, applicationEntity, formApplicationResponses); } else { List applicationFormEntities = applicationFormRepository.findByApplicationId(applicationEntity.getId()); for (ApplicationFormEntity applicationFormEntity : applicationFormEntities) { FormEntity form = formService.validateForm(applicationFormEntity.getForm().getId()); formEntities.add(form); addFormApplication(form, applicationEntity, formApplicationResponses); } } return createApplicationGetResponseBean(applicationEntity, formEntities, formApplicationResponses); } private boolean isBeneficiary(UserEntity userEntity) { RoleStatusEnum roleStatus = RoleStatusEnum.valueOf(userEntity.getRoleEntity().getRoleType()); boolean isBeneficiary = RoleStatusEnum.ROLE_BENEFICIARY.equals(roleStatus); return isBeneficiary; } private void addFormApplication(FormEntity formEntity, ApplicationEntity applicationEntity, List formApplicationResponses) { FormApplicationResponse formApplicationResponse = processForm(formEntity, applicationEntity); if(formApplicationResponse.getContent() != null && formApplicationResponse.getFormFields() != null) { formApplicationResponses.add(formApplicationResponse); } } public FormApplicationResponse processForm(FormEntity formEntity, ApplicationEntity applicationEntity) { FormApplicationResponse formApplicationResponse = createFormApplicationResponse(formEntity); List applicationFormFieldResponseBeans =new ArrayList<>(); ApplicationFormEntity applicationFormEntity = applicationFormRepository.findByApplicationIdAndFormId(applicationEntity.getId(), formEntity.getId()); if(applicationFormEntity!=null) { List applicationFormFieldEntities = applicationFormFieldRepository.findByApplicationFormId(applicationFormEntity.getId()); // formApplicationResponse = createFormApplicationResponse(formEntity); applicationFormFieldResponseBeans = createApplicationFormFieldResponse(applicationFormFieldEntities, applicationFormEntity,applicationFormFieldResponseBeans); formApplicationResponse.setFormFields(applicationFormFieldResponseBeans); } return formApplicationResponse; } private ApplicationGetResponseBean createApplicationGetResponseBean(ApplicationEntity applicationEntity, List formEntities, List formApplicationResponses) { ApplicationGetResponseBean applicationGetResponseBean = createApplicationGetResponseBean(applicationEntity); applicationGetResponseBean.setForm(formApplicationResponses); return applicationGetResponseBean; } private ApplicationGetResponseBean createApplicationGetResponseBean(ApplicationEntity applicationEntity) { ApplicationGetResponseBean applicationGetResponseBean = new ApplicationGetResponseBean(); applicationGetResponseBean.setId(applicationEntity.getId()); applicationGetResponseBean.setStatus(applicationEntity.getStatus()); applicationGetResponseBean.setComments(applicationEntity.getComments()); applicationGetResponseBean.setSubmissionDate(applicationEntity.getSubmissionDate()); applicationGetResponseBean.setCallId(applicationEntity.getCall().getId()); applicationGetResponseBean.setCallTitle(applicationEntity.getCall().getName()); applicationGetResponseBean.setCompanyId(applicationEntity.getCompany().getId()); if(applicationEntity.getProtocol() != null) { applicationGetResponseBean.setProtocolNumber(applicationEntity.getProtocol().getProtocolNumber()); } applicationGetResponseBean.setCompanyName(applicationEntity.getCompany().getCompanyName()); return applicationGetResponseBean; } private FormApplicationResponse createFormApplicationResponse(FormEntity formEntity) { FormApplicationResponse formApplicationResponse=new FormApplicationResponse(); formApplicationResponse.setId(formEntity.getId()); formApplicationResponse.setLabel(formEntity.getLabel()); formApplicationResponse.setCallId(formEntity.getCall().getId()); formApplicationResponse.setContent(Utils.convertJsonStringToList(formEntity.getContent(), ContentResponseBean.class)); return formApplicationResponse; } public ApplicationResponse createApplicationByCallId(CompanyEntity companyEntity, ApplicationRequest applicationRequest, Long callId, UserEntity userEntity) { CallEntity call = callService.validateCall(callId); // call = callService.validatePublishedCall(call.getId()); checkIfApplicationExists(call, companyEntity, userEntity); ApplicationEntity applicationEntity = createApplicationEntity(userEntity, call, companyEntity); applicationEntity.setComments(applicationRequest.getComments()); applicationEntity = saveApplicationEntity(applicationEntity); ApplicationResponse applicationResponse = getApplicationResponse(applicationEntity); return applicationResponse; } public void checkIfApplicationExists(CallEntity call, CompanyEntity companyEntity, UserEntity userEntity){ Optional applicationEntity=applicationRepository.findByUserIdAndCompanyIdAndCallIdAndIsDeletedFalse(userEntity.getId(), companyEntity.getId(),call.getId()); if(applicationEntity.isPresent()){ throw new CustomValidationException(Status.BAD_REQUEST,Translator.toLocale(GepafinConstant.APPLICATION_ALREADY_EXISTS)); } } public ApplicationResponse updateApplicationStatus(HttpServletRequest request, Long applicationId, ApplicationStatusTypeEnum status) { ApplicationEntity applicationEntity = validateApplication(applicationId); UserEntity userEntity = userService.validateUser(applicationEntity.getUserId()); validator.validateUserWithCompany(request, applicationEntity.getCompany().getId()); if (ApplicationStatusTypeEnum.SUBMIT.getValue().equals(applicationEntity.getStatus())) { throw new CustomValidationException(Status.BAD_REQUEST, Translator.toLocale(GepafinConstant.APPLICATION_SUBMITTED_CANNOT_CHANGE)); } if(Boolean.TRUE.equals(applicationEntity.getStatus().equals(status.getValue()))){ throw new CustomValidationException(Status.BAD_REQUEST,Translator.toLocale(GepafinConstant.APPLICATION_ALREADY_IN_PREVIOUS_STATUS)); } if (status.equals(ApplicationStatusTypeEnum.SUBMIT) && Boolean.TRUE.equals(applicationEntity.getStatus().equals(ApplicationStatusTypeEnum.READY.getValue()))) { callService.validatePublishedCall(applicationEntity.getCall().getId(), userEntity.getHub().getId()); Long protocolNumber = getProtocolNumber(userEntity.getHub()); ProtocolEntity protocolEntity = createProtocolEntity(applicationEntity,protocolNumber, userEntity.getHub().getId()); applicationEntity.setProtocol(protocolEntity); applicationEntity.setStatus(ApplicationStatusTypeEnum.SUBMIT.getValue()); applicationEntity.setSubmissionDate(DateTimeUtil.DateServerToUTC(LocalDateTime.now())); applicationEntity = saveApplicationEntity(applicationEntity); sendMailToUserAndCompany(userEntity, applicationEntity); sendMailTodefaultSystemAndGepafin(userEntity, applicationEntity); applicationEntity.setStatus(status.getValue()); applicationEntity = saveApplicationEntity(applicationEntity); } return getApplicationResponse(applicationEntity); } private Long getProtocolNumber(HubEntity hubEntity) { Long maxProtocolNumber = protocolRepository.findMaxProtocolNumberAndHubId(hubEntity.getId()); Long startNumber = 10000001L; if(Boolean.FALSE.equals(defaultHubUuid.equals(hubEntity.getUniqueUuid()))) { startNumber = 20000001L; } return (maxProtocolNumber != null) ? maxProtocolNumber + 1 : startNumber; } public Integer calculateProgress(Long totalSteps, Long completedSteps) { if (FieldValidator.isNullOrZero(totalSteps)) { throw new CustomValidationException(Status.BAD_REQUEST,Translator.toLocale(GepafinConstant.TOTAL_STEPS_NOT_BE_ZERO)); } if (completedSteps < 0 || completedSteps > totalSteps) { throw new CustomValidationException(Status.BAD_REQUEST,Translator.toLocale(GepafinConstant.COMPLETED_STEPS_NOT_VALID)); } double progress = ((double) completedSteps / totalSteps) * 100; return (int) Math.round(progress); } public void validateFormFields(ApplicationRequestBean request, FormEntity formEntity) { List contentResponseBeans=Utils.convertJsonStringToList(formEntity.getContent(),ContentResponseBean.class); List requestFields = request.getFormFields(); Map contentMap = contentResponseBeans.stream() .collect(Collectors.toMap(ContentResponseBean::getId, ContentResponseBean::getLabel)); // Change getLabel() if needed FieldValidator validator = FieldValidator.create(); for (ApplicationFormFieldRequestBean requestField : requestFields) { String fieldId = requestField.getFieldId(); if (!contentMap.containsKey(fieldId)) { validator.addError(MessageFormat.format(Translator.toLocale(GepafinConstant.FIELD_ID_NOT_FOUND), fieldId)); } } validator.validate(); } public void validateRequiredFields(FormEntity formEntity, ApplicationEntity applicationEntity, String fieldId) { FlowDataEntity flowDataEntity = flowDataRepository.findByFormIdAndCallId( formEntity.getId(), applicationEntity.getCall().getId()); if (flowDataEntity == null) { return; } ApplicationFormFieldEntity applicationFormFieldEntity = applicationFormFieldRepository .findByFieldIdAndApplicationFormFormIdAndApplicationFormApplicationId( flowDataEntity.getChoosenField(), formEntity.getId(), applicationEntity.getId()) .orElse(null); if (applicationFormFieldEntity == null || !fieldId.equals(applicationFormFieldEntity.getFieldId())) { return; } List nextFormIds = flowEdgesRepository.findBySourceIdAndCallId( formEntity.getId(), applicationEntity.getCall().getId()) .stream() .map(FlowEdgesEntity::getTargetId) .collect(Collectors.toList()); Optional nextFormIdOptional = flowDataRepository.findByChoosenValueAndFormIdIn( applicationFormFieldEntity.getFieldValue(), nextFormIds) .map(FlowDataEntity::getFormId); if (nextFormIdOptional.isPresent()) { Long nextFormId = nextFormIdOptional.get(); FormEntity nextForm = formService.validateForm(nextFormId); ApplicationFormEntity nextApplicationFormEntity = applicationFormRepository.findByApplicationIdAndFormId( applicationEntity.getId(), nextForm.getId()); if (nextApplicationFormEntity != null) { List nextApplicationFormFieldEntities = applicationFormFieldRepository.findByApplicationFormId(nextApplicationFormEntity.getId()); applicationFormFieldRepository.deleteAll(nextApplicationFormFieldEntities); applicationFormRepository.delete(nextApplicationFormEntity); } } } public ProtocolEntity createProtocolEntity(ApplicationEntity applicationEntity,Long protocolNumber, Long hubId){ ProtocolEntity protocolEntity=new ProtocolEntity(); protocolEntity.setCall(applicationEntity.getCall().getId()); LocalDateTime utcDateTime = DateTimeUtil.DateServerToUTC(LocalDateTime.now()); protocolEntity.setYear(utcDateTime.getYear()); protocolEntity.setProtocolNumber(protocolNumber); protocolEntity.setTime(LocalTime.now()); protocolEntity.setApplicationId(applicationEntity.getId()); protocolEntity.setHubId(hubId); protocolRepository.save(protocolEntity); return protocolEntity; } private void sendMailToUserAndCompany(UserEntity userEntity, ApplicationEntity applicationEntity) { CallEntity call =applicationEntity.getCall(); CompanyEntity company = applicationEntity.getCompany(); ProtocolEntity protocol = applicationEntity.getProtocol(); SystemEmailTemplateResponse systemEmailTemplateResponse = systemEmailTemplatesService .retrieveTemplateByTypeAndCall(SystemEmailTemplatesEntityTypeEnum.APPLICATION_SUBMISSION_TO_USER_AND_COMPANY, call, null); // Create the map for subject placeholders Map subjectPlaceholders = new HashMap<>(); subjectPlaceholders.put("{{call_name}}", call.getName()); subjectPlaceholders.put("{{company_name}}", company.getCompanyName()); // Create the map for body placeholders Map bodyPlaceholders = new HashMap<>(); bodyPlaceholders.put("{{call_name}}", call.getName()); bodyPlaceholders.put("{{protocol_number}}", protocol.getProtocolNumber().toString()); bodyPlaceholders.put("{{date}}", DateTimeUtil.formatLocalDateTime(protocol.getCreatedDate(), GepafinConstant.DD_MM_YYYY)); bodyPlaceholders.put("{{time}}", DateTimeUtil.parseLocalTimeToString(protocol.getTime(), GepafinConstant.HH_MM_SS)); // Replace placeholders in the subject and body String subject = Utils.replacePlaceholders(systemEmailTemplateResponse.getSubject(), subjectPlaceholders); String body = Utils.replacePlaceholders(systemEmailTemplateResponse.getHtmlContent(), bodyPlaceholders); String email = userEntity.getEmail(); if (userEntity.getBeneficiary() != null) { email = userEntity.getBeneficiary().getEmail(); } mailUtil.sendByMailGun(subject, body, List.of(email), null); mailUtil.sendByMailGun(subject, body, List.of(applicationEntity.getCompany().getEmail()), null); } private void sendMailTodefaultSystemAndGepafin(UserEntity userEntity, ApplicationEntity applicationEntity) { CallEntity call = applicationEntity.getCall(); CompanyEntity company = applicationEntity.getCompany(); ProtocolEntity protocol = applicationEntity.getProtocol(); SystemEmailTemplateResponse systemEmailTemplateResponse = systemEmailTemplatesService .retrieveTemplateByTypeAndCall(SystemEmailTemplatesEntityTypeEnum.APPLICATION_SUBMISSION_TO_GEPAFIN, call, null); // Create the map for subject placeholders Map subjectPlaceholders = new HashMap<>(); subjectPlaceholders.put("{{call_name}}", call.getName()); subjectPlaceholders.put("{{company_name}}", company.getCompanyName()); // Create the map for body placeholders Map bodyPlaceholders = new HashMap<>(); bodyPlaceholders.put("{{call_name}}", call.getName()); bodyPlaceholders.put("{{protocol_number}}", protocol.getProtocolNumber().toString()); bodyPlaceholders.put("{{date}}", DateTimeUtil.formatLocalDateTime(protocol.getCreatedDate(), GepafinConstant.DD_MM_YYYY)); bodyPlaceholders.put("{{time}}", DateTimeUtil.parseLocalTimeToString(protocol.getTime(), GepafinConstant.HH_MM_SS)); // Replace placeholders in the subject and body String subject = Utils.replacePlaceholders(systemEmailTemplateResponse.getSubject(), subjectPlaceholders); String body = Utils.replacePlaceholders(systemEmailTemplateResponse.getHtmlContent(), bodyPlaceholders); mailUtil.sendByMailGun(subject, body, List.of(defaultSystemReceiverEmail), null); mailUtil.sendByMailGun(subject, body, List.of(gepafinEmail), null); mailUtil.sendByMailGun(subject, body, List.of(rinaldoEmail), null); if(validator.isProductionProfileActivated()) { mailUtil.sendByMailGun(subject, body, List.of(carloEmail), null); } } public ApplicationSignedDocumentResponse uploadSignedDocument(HttpServletRequest request, Long applicationId, MultipartFile file) { ApplicationEntity applicationEntity = validateApplication(applicationId); validator.validateUserWithCompany(request, applicationEntity.getCompany().getId()); validateFileType(file); ApplicationSignedDocumentEntity applicationSignedDocument = applicationSignedDocumentRepository .findByApplicationIdAndStatus(applicationId, ApplicationSignedDocumentStatusEnum.ACTIVE.getValue()); if (applicationSignedDocument != null) { throw new CustomValidationException(Status.BAD_REQUEST,Translator.toLocale(GepafinConstant.APPLICATION_ALREADY_ASSIGNED)); // applicationSignedDocument.setStatus(ApplicationSignedDocumentStatusEnum.INACTIVE.getValue()); // applicationSignedDocumentRepository.save(applicationSignedDocument); } UploadFileOnAmazonS3Response uploadFileOnAmazonS3 = amazonS3Service.uploadFileOnAmazonS3(signedDocumentS3Folder, file); applicationSignedDocument = new ApplicationSignedDocumentEntity(); applicationSignedDocument.setApplication(applicationEntity); applicationSignedDocument.setFileName(uploadFileOnAmazonS3.getFileName()); applicationSignedDocument.setFilePath(uploadFileOnAmazonS3.getFilePath()); applicationSignedDocument.setStatus(ApplicationSignedDocumentStatusEnum.ACTIVE.getValue()); applicationSignedDocumentRepository.save(applicationSignedDocument); applicationEntity.setStatus(ApplicationStatusTypeEnum.READY.getValue()); applicationRepository.save(applicationEntity); return convertApplicationSignedDocumentToApplicationSignedDocumentResponse(applicationSignedDocument); } private ApplicationSignedDocumentResponse convertApplicationSignedDocumentToApplicationSignedDocumentResponse( ApplicationSignedDocumentEntity applicationSignedDocument) { ApplicationSignedDocumentResponse applicationSignedDocumentResponse = new ApplicationSignedDocumentResponse(); applicationSignedDocumentResponse.setId(applicationSignedDocument.getId()); applicationSignedDocumentResponse.setApplicationId(applicationSignedDocument.getApplication().getId()); applicationSignedDocumentResponse.setFileName(applicationSignedDocument.getFileName()); applicationSignedDocumentResponse.setFilePath(applicationSignedDocument.getFilePath()); applicationSignedDocumentResponse .setStatus(ApplicationSignedDocumentStatusEnum.valueOf(applicationSignedDocument.getStatus())); applicationSignedDocumentResponse.setCreatedDate(applicationSignedDocument.getCreatedDate()); applicationSignedDocumentResponse.setUpdatedDate(applicationSignedDocument.getUpdatedDate()); return applicationSignedDocumentResponse; } private void validateFileType(MultipartFile file) { if (file.isEmpty()) { throw new CustomValidationException(Status.VALIDATION_ERROR, Translator.toLocale(GepafinConstant.VALIDATION_ERROR_FILE_EMPTY)); } String filename = file.getOriginalFilename(); if (filename == null || !filename.endsWith(".p7m")) { throw new CustomValidationException(Status.VALIDATION_ERROR, Translator.toLocale(GepafinConstant.VALIDATION_ERROR_FILE_INVALIDTYPE)); } } public ApplicationSignedDocumentResponse getSignedDocument(HttpServletRequest request, Long applicationId) { ApplicationEntity applicationEntity = validateApplication(applicationId); validator.validateUserWithCompany(request, applicationEntity.getCompany().getId()); ApplicationSignedDocumentEntity applicationSignedDocument = applicationSignedDocumentRepository .findByApplicationIdAndStatus(applicationId, ApplicationSignedDocumentStatusEnum.ACTIVE.getValue()); if(applicationSignedDocument == null) { throw new ResourceNotFoundException(Status.NOT_FOUND, Translator.toLocale(GepafinConstant.APPLICATION_SIGNED_DOCUMENT_NOT_FOUND)); } return convertApplicationSignedDocumentToApplicationSignedDocumentResponse(applicationSignedDocument); } public void deleteSignedDocument(HttpServletRequest request, Long applicationId) { ApplicationEntity applicationEntity = validateApplication(applicationId); validator.validateUserWithCompany(request, applicationEntity.getCompany().getId()); ApplicationSignedDocumentEntity applicationSignedDocument = applicationSignedDocumentRepository .findByApplicationIdAndStatus(applicationId, ApplicationSignedDocumentStatusEnum.ACTIVE.getValue()); if(applicationSignedDocument == null) { throw new ResourceNotFoundException(Status.NOT_FOUND, Translator.toLocale(GepafinConstant.APPLICATION_SIGNED_DOCUMENT_NOT_FOUND)); } applicationSignedDocument.setStatus(ApplicationSignedDocumentStatusEnum.INACTIVE.getValue()); applicationSignedDocumentRepository.save(applicationSignedDocument); } public ApplicationResponse validateApplication(HttpServletRequest request, Long applicationId) { ApplicationEntity applicationEntity = validateApplication(applicationId); UserEntity userEntity = userService.validateUser(applicationEntity.getUserId()); validator.validateUserWithCompany(request, applicationEntity.getCompany().getId()); if (Boolean.FALSE.equals(ApplicationStatusTypeEnum.DRAFT.getValue().equals(applicationEntity.getStatus()))) { throw new CustomValidationException(Status.BAD_REQUEST, Translator.toLocale(GepafinConstant.APPLICATION_NOT_IN_DRAFT_STATUS)); } List flowEdgesList = flowEdgesRepository.findByCallId(applicationEntity.getCall().getId()); Long totalSteps=flowFormDao.calculateTotalSteps(flowEdgesList); Integer completedSteps=flowFormDao.getCompletedSteps(applicationEntity); if (totalSteps.intValue() != completedSteps) { throw new CustomValidationException(Status.BAD_REQUEST, Translator.toLocale(GepafinConstant.APPLICATION_IS_INCOMPLETE_MSG)); } applicationEntity.setStatus(ApplicationStatusTypeEnum.AWAIT.getValue()); applicationEntity = saveApplicationEntity(applicationEntity); return getApplicationResponse(applicationEntity); } }