Merge pull request #86 from Kitzanos/develop

Sync master with develop branch(11/11/2024)
MassivePEC, Review PDF ....
This commit is contained in:
rbonazzo-KZ
2024-11-12 09:40:21 +01:00
committed by GitHub
92 changed files with 4976 additions and 165 deletions

View File

@@ -233,7 +233,16 @@ public class GepafinConstant {
public static final String CANNOT_DELETE_COMPANY_WITH_APPLICATION_SUBMITT = "application.in.submit.status.cannot.delete.company";
public static final String GET_USERS_SUCCESS_MSG = "get.users.success.msg";
public static final String CANNOT_CREATE_BENEFICIARY_USER="cannot.create.beneficiary.user";
public static final String EVALUATION_CREATED_SUCCESSFULLY = "evaluation.created.successfully";
public static final String EVALUATION_UPDATED_SUCCESSFULLY = "evaluation.updated.successfully";
public static final String EVALUATION_FETCHED_SUCCESSFULLY = "evaluation.fetched.successfully";
public static final String EVALUATION_DELETED_SUCCESSFULLY = "evaluation.deleted.successfully";
public static final String EVALUATIONS_FETCHED_SUCCESSFULLY = "evaluations.fetched.successfully";
public static final String APPLICATION_EVALUATION_NOT_FOUND = "application.evaluation.not.found";
public static final String APPLICATION_EVALUATION_STATUS_UPDATED_SUCCESSFULLY = "application.evaluation.status.updated.successfully";
public static final String ASSIGNED_APPLICATION_NOT_FOUND_WITH_ID_MSG = "assigned.application.not.found.with.id";
public static final String EITHER_APPLICATION_OR_ASSIGNED_APPLICATION_ID_REQUIRED_MSG = "either.application.or.assigned.application.id.required";
public static final String EVALUATION_ALREADY_EXISTS_MSG = "evaluation.already.exists";
public static final String APPLICATION_ASSIGNED= "application.assigned.success.msg";
public static final String APPLICATION_ALREADY_ASSIGNED = "application.already.assigned.msg";
public static final String ASSIGNED_APPLICATION_NOT_FOUND_MSG="aasigned.application.not.found";
@@ -250,8 +259,7 @@ public class GepafinConstant {
public static final String EVALUATIONCRITERIA_INVALID = "evaluationCriteria.invalid";
public static final String APPLICATION_NOT_IN_DRAFT_STATUS="application.not.in.draft.status";
public static final String GET_ERROR_S3 = "get.error.s3";
public static final String INVALID_APPLICATION_STATUS = "invalid.application.status";
public static final String BENEFICIARY_EMAIL_NOT_FOUND_MSG = "beneficiary.email.not.found.msg";
public static final String ADDED_S3_PATH_STRUCTURE ="added.s3.path.structure";
public static final String S3_PATH_STRUCTURE_BY_TYPE ="fetched.s3.path.structure.by.type.successfully";
public static final String S3_PATH_STRUCTURE_NOT_FOUND_BY_TYPE_MSG ="s3.path.not.found.by.type";
@@ -260,5 +268,27 @@ public class GepafinConstant {
public static final String S3_PATH_CONFIG_UPDATE_MSG ="s3.path.config.updated.successfully";
public static final String S3_PATH_CONFIG_DUPLICATE_TYPE_ALREADY_EXIST ="s3.path.config.already.exist.";
public static final String S3_PATH_GENERATION_ERROR_MSG ="s3.path.config.already.exist.";
public static final String INVALID_APPLICATION_STATUS = "invalid.application.status";
public static final String APPLICATION_DATA_FOR_AMENDMENT_SUCCESS_MSG = "application.data.amendment.success";
public static final String DELETE_APPLICATION_AMENDMENT_SUCCESS_MSG = "delete.application.amendment.success";
public static final String CREATE_APPLICATION_DATA_FOR_AMENDMENT_MSG = "create.application.data.amendment.msg";
public static final String APPLICATION_AMENDMENT_NOT_FOUND_MSG = "application.amendment.not.found";
public static final String GET_APPLICATION_AMENDMENT_SUCCESS_MSG = "application.amendment.get.success";
public static final String APPLICATION_AMENDMENT_UPDATE_SUCCESSFULLY_MSG = "application.amendment.update.successfully";
public static final String APPLICATION_AMENDMENT_CLOSED_SUCCESFULLY = "application.amendment.closed.successfully";
public static final String RESPONSE_DAYS_EXTENDED_SUCCESS_MSG = "response.days.extended.success";
public static final String COMMUNICATION_ADDED_TO_AMENDMENT_REQUEST_SUCCESS = "added.comment.to.amendment.request.success";
public static final String COMMENT_NOT_FOUND = "comment.not.found";
public static final String COMMENT_UPDATED_SUCCESS_MSG = "comment.updated.successfully";
public static final String COMMENT_DELETED_SUCCESS_MSG = "comment.deleted.successfully";
public static final String COMMENT_NOT_ASSOCIATE_WITH_AMENDMENT_ID_ERROR_MSG = "comment.not.associate.with.amendment";
public static final String AMENDMENT_FOUND_SUCCESS = "amendment.found.success";
public static final String INVALID_AMENDMENT_FOR_COMMENT = "invalid.amendment.for.comment";
public static final String DD_MM_YYYY_HH_MM = "DD_MM_YYYY_HH_MM";
public static final String REMINDER_EMAIL_SENT_SUCCESS_MSG = "reminder.email.sent.success.msg";
public static final String ENCRYPT_INIT_VECTOR = "IG8*(*@&)*#biVVD";
public static final String ENCRYPT_KEY = "U2VjdXJlRW5jcnlwdEtleQ==";
}

View File

@@ -0,0 +1,634 @@
package net.gepafin.tendermanagement.dao;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.persistence.criteria.Join;
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.*;
import net.gepafin.tendermanagement.enums.*;
import net.gepafin.tendermanagement.model.request.ApplicationAmendmentRequest;
import net.gepafin.tendermanagement.model.request.ApplicationAmendmentRequestBean;
import net.gepafin.tendermanagement.model.request.ApplicationFormFieldRequestBean;
import net.gepafin.tendermanagement.model.request.CloseAmendmentRequest;
import net.gepafin.tendermanagement.model.response.*;
import net.gepafin.tendermanagement.repositories.*;
import net.gepafin.tendermanagement.service.*;
import net.gepafin.tendermanagement.util.DateTimeUtil;
import net.gepafin.tendermanagement.util.Validator;
import net.gepafin.tendermanagement.entities.SystemEmailTemplatesEntity.SystemEmailTemplatesEntityTypeEnum;
import net.gepafin.tendermanagement.util.Utils;
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.beans.factory.annotation.Value;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Component;
import java.time.temporal.ChronoUnit;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;
import static net.gepafin.tendermanagement.util.Utils.log;
import static net.gepafin.tendermanagement.util.Utils.setIfUpdated;
@Component
public class ApplicationAmendmentRequestDao {
@Value("${application.amendment.expiration.days}")
private long expirationDays;
@Autowired
private ApplicationService applicationService;
@Autowired
private UserService userService;
@Autowired
private DocumentService documentService;
@Autowired
private ApplicationFormRepository applicationFormRepository;
@Autowired
private ApplicationAmendmentRequestRepository applicationAmendmentRequestRepository;
@Autowired
private ApplicationFormFieldRepository applicationFormFieldRepository;
@Autowired
private EmailNotificationDao emailNotificationDao;
@Autowired
private ApplicationEvaluationService applicationEvaluationService;
@Autowired
private ProtocolDao protocolDao;
@Autowired
private AssignedApplicationsService assignedApplicationsService;
@Autowired
private ApplicationEvaluationRepository applicationEvaluationRepository;
@Autowired
private ApplicationRepository applicationRepository;
@Autowired
private AssignedApplicationsRepository assignedApplicationsRepository;
@Autowired
private SystemEmailTemplatesService systemEmailTemplatesService;
@Autowired
private CallDao callDao;
@Autowired
private DocumentRepository documentRepository;
@Autowired
private HubService hubService;
// @Autowired
// private MailUtil mailUtil;
@Autowired
private Validator validator;
public ApplicationAmendmentRequestResponse getApplicationDataForAmendment(Long applicationEvaluationId) {
log.info("Fetching the application data for the Amendment process {}", applicationEvaluationId);
ApplicationEvaluationEntity applicationEvaluationEntity = applicationEvaluationService.validateApplicationEvaluation(applicationEvaluationId);
Long applicationId = applicationEvaluationEntity.getApplicationId();
ApplicationEntity application = applicationService.validateApplication(applicationId);
// Set common application-level details
String callName = application.getCall().getName();
Long protocolNumber = (application.getProtocol() != null && application.getProtocol().getProtocolNumber() != null)
? application.getProtocol().getProtocolNumber()
: null;
UserEntity userEntity = userService.validateUser(application.getUserId());
String firstName = userEntity.getBeneficiary() != null ? userEntity.getBeneficiary().getFirstName() : "";
String lastName = userEntity.getBeneficiary() != null ? userEntity.getBeneficiary().getLastName() : "";
String beneficiaryName = (!firstName.isBlank() ? firstName : "") +
(!lastName.isBlank() ? " " + lastName : "");
beneficiaryName = beneficiaryName.isBlank() ? "" : beneficiaryName;
ApplicationAmendmentRequestResponse response = new ApplicationAmendmentRequestResponse();
response.setId(applicationEvaluationId);
response.setProtocolNumber(protocolNumber);
response.setCallName(callName);
response.setBeneficiaryName(beneficiaryName);
response.setApplicationId(applicationId);
response.setApplicationEvaluationId(applicationEvaluationId);
List<ApplicationFormEntity> forms = applicationFormRepository.findByApplicationId(applicationId);
List<AmendmentFormFieldResponse> allFormFields = new ArrayList<>();
for (ApplicationFormEntity form : forms) {
String content = form.getForm().getContent();
List<Map<String, Object>> result = filterByName(content, "fileupload");
allFormFields.addAll(getIdAndLabelFromResult(result));
}
response.setFormFields(allFormFields);
return response;
}
public List<AmendmentFormFieldResponse> getIdAndLabelFromResult(List<Map<String, Object>> result) {
List<AmendmentFormFieldResponse> formFieldResponses = new ArrayList<>();
for (Map<String, Object> item : result) {
AmendmentFormFieldResponse formFieldResponse = new AmendmentFormFieldResponse();
formFieldResponse.setFieldId((String) item.get("id"));
// Extract "label" value from the "settings" array
List<Map<String, Object>> settings = (List<Map<String, Object>>) item.get("settings");
String label = settings.stream()
.filter(setting -> "label".equals(setting.get("name")))
.map(setting -> (String) setting.get("value"))
.findFirst()
.orElse(""); // Default to empty string if not found
if (label == null || label.trim().isEmpty()) {
continue;
}
formFieldResponse.setLabel(label); // Set the label as fieldValue
formFieldResponses.add(formFieldResponse);
}
return formFieldResponses;
}
public static List<Map<String, Object>> filterByName(String content, String target) {
ObjectMapper objectMapper = new ObjectMapper();
List<Map<String, Object>> filteredList = new ArrayList<>();
try {
List<Map<String, Object>> dataList = objectMapper.readValue(
content, new TypeReference<List<Map<String, Object>>>() {});
for (Map<String, Object> data : dataList) {
if (target.equals(data.get("name"))) {
filteredList.add(data);
}
}
} catch (Exception e) {
e.printStackTrace();
}
return filteredList;
}
public ApplicationAmendmentRequestResponse createApplicationAmendmentRequest(Long applicationEvaluationId, ApplicationAmendmentRequest applicationAmendmentRequest){
log.info("Submiting application data for amendment Process with details: {}", applicationEvaluationId);
ApplicationAmendmentRequestEntity applicationAmendmentRequestEntity = createApplicationAmendmentRequestEntity(applicationAmendmentRequest, applicationEvaluationId);
ApplicationAmendmentRequestResponse applicationAmendmentRequestResponse = convertEntityToResponse(applicationAmendmentRequestEntity);
log.info("Application submitted successfully for amendment", applicationAmendmentRequestResponse);
if(Boolean.TRUE.equals(applicationAmendmentRequestResponse.isSendEmail())){
emailNotificationDao.sendMailToNotifyBeneficiaryRegardingNewAmendment(applicationAmendmentRequestEntity);
}
return applicationAmendmentRequestResponse;
}
public ApplicationAmendmentRequestEntity createApplicationAmendmentRequestEntity(ApplicationAmendmentRequest applicationAmendmentRequest,Long applicationEvaluationId){
ApplicationAmendmentRequestEntity applicationAmendmentRequestEntity = new ApplicationAmendmentRequestEntity();
applicationAmendmentRequestEntity.setNote(applicationAmendmentRequest.getNote());
applicationAmendmentRequestEntity.setResponseDays(applicationAmendmentRequest.getResponseDays());
applicationAmendmentRequestEntity.setIsEmail(applicationAmendmentRequest.getIsSendEmail());
applicationAmendmentRequestEntity.setIsNotification(applicationAmendmentRequest.getIsSendNotification());
applicationAmendmentRequestEntity.setStartDate(DateTimeUtil.DateServerToUTC(LocalDateTime.now()));
applicationAmendmentRequestEntity.setStatus(ApplicationAmendmentRequestEnum.AWAITING.getValue());
ApplicationEvaluationEntity applicationEvaluationEntity = applicationEvaluationService.validateApplicationEvaluation(applicationEvaluationId);
applicationAmendmentRequestEntity.setApplicationEvaluationEntity(applicationEvaluationEntity);
Long applicationId = applicationEvaluationEntity.getApplicationId();
Long assignedApplicationId = applicationEvaluationEntity.getAssignedApplicationsEntity().getId();
applicationAmendmentRequestEntity.setApplicationId(applicationId);
if (applicationAmendmentRequest.getFormFields() != null) {
String fieldIdsString = applicationAmendmentRequest.getFormFields().stream()
.filter(AmendmentFormFieldResponse::isSelected)
.map(AmendmentFormFieldResponse::getFieldId)
.collect(Collectors.joining(","));
applicationAmendmentRequestEntity.setFormFields(fieldIdsString);
}
UserEntity userEntity = userService.validateUser(applicationEvaluationEntity.getUserId());
Long protocolNumber = protocolDao.getProtocolNumber(userEntity.getHub());
ProtocolEntity protocolEntity = protocolDao.createProtocolEntity(
applicationEvaluationEntity.getAssignedApplicationsEntity().getApplication(), protocolNumber,
userEntity.getHub().getId());
applicationAmendmentRequestEntity.setProtocol(protocolEntity);
ApplicationAmendmentRequestEntity applicationAmendment = saveApplicationAmendmentRequestEntity(applicationAmendmentRequestEntity);
//Set Status
applicationEvaluationEntity.setStatus(ApplicationEvaluationStatusTypeEnum.SOCCORSO.getValue());
applicationEvaluationRepository.save(applicationEvaluationEntity);
ApplicationEntity applicationEntity = applicationService.validateApplication(applicationId);
applicationEntity.setStatus(ApplicationStatusTypeEnum.SOCCORSO.getValue());
applicationRepository.save(applicationEntity);
AssignedApplicationsEntity assignedApplicationsEntity = assignedApplicationsService.validateAssignedApplication(assignedApplicationId);
assignedApplicationsEntity.setStatus(AssignedApplicationEnum.SOCCORSO.getValue());
assignedApplicationsRepository.save(assignedApplicationsEntity);
return applicationAmendment;
}
public ApplicationAmendmentRequestEntity saveApplicationAmendmentRequestEntity(ApplicationAmendmentRequestEntity applicationAmendmentRequestEntity){
ApplicationAmendmentRequestEntity applicationAmendmentRequest= applicationAmendmentRequestRepository.save(applicationAmendmentRequestEntity);
return applicationAmendmentRequest;
}
public ApplicationAmendmentRequestResponse convertEntityToResponse(ApplicationAmendmentRequestEntity applicationAmendmentRequestEntity){
ApplicationAmendmentRequestResponse applicationAmendmentRequestResponse = new ApplicationAmendmentRequestResponse();
applicationAmendmentRequestResponse.setId(applicationAmendmentRequestEntity.getId());
Long applicationId= applicationAmendmentRequestEntity.getApplicationId();
ApplicationEntity application = applicationService.validateApplication(applicationId);
applicationAmendmentRequestResponse.setApplicationId(applicationId);
applicationAmendmentRequestResponse.setCallEmail(application.getCall().getEmail());
applicationAmendmentRequestResponse.setApplicationEvaluationId(applicationAmendmentRequestEntity.getApplicationEvaluationEntity().getId());
applicationAmendmentRequestResponse.setNote(applicationAmendmentRequestEntity.getNote());
applicationAmendmentRequestResponse.setStatus(ApplicationAmendmentRequestEnum.valueOf(applicationAmendmentRequestEntity.getStatus()));
applicationAmendmentRequestResponse.setResponseDays(applicationAmendmentRequestEntity.getResponseDays());
applicationAmendmentRequestResponse.setInternalNote(applicationAmendmentRequestEntity.getInternalNote());
LocalDateTime startDate = applicationAmendmentRequestEntity.getStartDate();
applicationAmendmentRequestResponse.setStartDate(startDate);
LocalDateTime expirationDate = startDate.plus(expirationDays, ChronoUnit.DAYS);
applicationAmendmentRequestResponse.setExpirationDate(expirationDate);
applicationAmendmentRequestResponse.setSendEmail(applicationAmendmentRequestEntity.getIsEmail());
applicationAmendmentRequestResponse.setSendNotification(applicationAmendmentRequestEntity.getIsNotification());
String callName = application.getCall().getName();
Long protocolNumber = (applicationAmendmentRequestEntity.getProtocol() != null && applicationAmendmentRequestEntity.getProtocol().getProtocolNumber() != null)
? applicationAmendmentRequestEntity.getProtocol().getProtocolNumber()
: null;
UserEntity userEntity = userService.validateUser(application.getUserId());
String firstName = userEntity.getBeneficiary() != null ? userEntity.getBeneficiary().getFirstName() : "";
String lastName = userEntity.getBeneficiary() != null ? userEntity.getBeneficiary().getLastName() : "";
String beneficiaryName = (!firstName.isBlank() ? firstName : "") +
(!lastName.isBlank() ? " " + lastName : "");
beneficiaryName = beneficiaryName.isBlank() ? "" : beneficiaryName;
applicationAmendmentRequestResponse.setCallName(callName);
applicationAmendmentRequestResponse.setProtocolNumber(protocolNumber);
applicationAmendmentRequestResponse.setBeneficiaryName(beneficiaryName);
String formFieldsString = applicationAmendmentRequestEntity.getFormFields();
List<String> storedFieldIds = (formFieldsString != null) ? Arrays.asList(formFieldsString.split(",")) : Collections.emptyList();
List<ApplicationFormEntity> applicationForms = applicationFormRepository.findByApplicationId(application.getId());
List<AmendmentFormFieldResponse> formFields = new ArrayList<>();
for (ApplicationFormEntity formEntity : applicationForms) {
String content = formEntity.getForm().getContent();
List<Map<String, Object>> result = filterByName(content, "fileupload");
List<AmendmentFormFieldResponse> matchingFields = getIdAndLabelFromResult(result).stream()
.filter(field -> storedFieldIds.contains(field.getFieldId()))
.collect(Collectors.toList());
formFields.addAll(matchingFields);
}
applicationAmendmentRequestResponse.setFormFields(formFields);
List<AmendmentFormFieldResponse> formField = formFields.stream()
.map(field -> {
AmendmentFormFieldResponse responseField = new AmendmentFormFieldResponse();
responseField.setFieldId(field.getFieldId());
responseField.setLabel(field.getLabel());
responseField.setSelected(true);
return responseField;
})
.collect(Collectors.toList());
applicationAmendmentRequestResponse.setFormFields(formField);
List<ApplicationFormFieldEntity> formFieldEntities = applicationFormFieldRepository.findByApplicationFormIdIn(
applicationForms.stream().map(ApplicationFormEntity::getId).collect(Collectors.toList())
);
List<ApplicationFormFieldResponseBean> fileDetailResponses = new ArrayList<>();
for (AmendmentFormFieldResponse field : formFields) {
for (ApplicationFormFieldEntity formFieldEntity : formFieldEntities) {
if (formFieldEntity.getFieldId().equals(field.getFieldId()) && formFieldEntity.getFieldValue() != null) {
ApplicationFormFieldResponseBean responseBean = new ApplicationFormFieldResponseBean();
responseBean.setFieldId(formFieldEntity.getFieldId());
String[] documentIds = formFieldEntity.getFieldValue().split(",");
List<DocumentResponseBean> documentResponseBeans = new ArrayList<>();
for (String docId : documentIds) {
Long documentId = Long.valueOf(docId.trim());
documentRepository.findByIdAndNotDeleted(documentId).ifPresent(documentEntity -> {
DocumentResponseBean docBean = new DocumentResponseBean();
docBean.setId(documentEntity.getId());
docBean.setName(documentEntity.getFileName());
docBean.setType(DocumentTypeEnum.valueOf(documentEntity.getType()));
docBean.setSource(DocumentSourceTypeEnum.valueOf(documentEntity.getSource()));
docBean.setSourceId(documentEntity.getSourceId());
docBean.setFilePath(documentEntity.getFilePath());
docBean.setCreatedDate(documentEntity.getCreatedDate());
docBean.setUpdatedDate(documentEntity.getUpdatedDate());
documentResponseBeans.add(docBean);
});
}
responseBean.setFieldValue(documentResponseBeans);
fileDetailResponses.add(responseBean);
}
}
}
applicationAmendmentRequestResponse.setApplicationFormFields(fileDetailResponses);
return applicationAmendmentRequestResponse;
}
public ApplicationAmendmentRequestEntity validateApplicationAmendmentRequest(Long id) {
return applicationAmendmentRequestRepository.findByIdAndIsDeletedFalse(id)
.orElseThrow(() -> new ResourceNotFoundException(Status.NOT_FOUND,
Translator.toLocale(GepafinConstant.APPLICATION_AMENDMENT_NOT_FOUND_MSG)));
}
public void deleteById(Long id) {
log.info("Deleting assigned application with ID: {}", id);
ApplicationAmendmentRequestEntity applicationAmendmentRequestEntity= validateApplicationAmendmentRequest(id);
applicationAmendmentRequestEntity.setIsDeleted(true);
saveApplicationAmendmentRequestEntity(applicationAmendmentRequestEntity);
log.info(" Application amendment deleted with ID: {}", id);
}
public ApplicationAmendmentRequestResponse getApplicationAmendmentRequestById(Long id) {
log.info("Fetching application amendment with ID: {}", id);
ApplicationAmendmentRequestEntity applicationAmendmentRequestEntity = validateApplicationAmendmentRequest(id);
ApplicationAmendmentRequestResponse response = convertEntityToResponse(applicationAmendmentRequestEntity);
log.info("Application Amendment fetched successfully by ID: {}", response);
return response;
}
public List<ApplicationAmendmentRequestResponse> getAllApplicationAmendmentRequest(HttpServletRequest request,Long userId) {
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<ApplicationAmendmentRequestEntity> spec = search(userId);
List<ApplicationAmendmentRequestEntity> applicationAmendmentRequestEntities =
applicationAmendmentRequestRepository.findAll(spec);
return applicationAmendmentRequestEntities.stream()
.map(this::convertEntityToResponse)
.collect(Collectors.toList());
}
private Specification<ApplicationAmendmentRequestEntity> search(Long userId) {
return (root, query, builder) -> {
Predicate predicate = builder.isFalse(root.get("isDeleted")); // Only non-deleted records
if (userId != null) {
Join<Object, Object> evaluationJoin = root.join("applicationEvaluationEntity");
predicate = builder.and(predicate, builder.equal(evaluationJoin.get("userId"), userId));
}
return predicate; // Return final predicate
};
}
public ApplicationAmendmentRequestResponse updateApplicationAmendment(
Long id, ApplicationAmendmentRequestBean updateRequest) {
log.info("Updating application amendement with ID: {}", id);
ApplicationAmendmentRequestEntity existingApplicationAmendment = validateApplicationAmendmentRequest(id);
setIfUpdated(existingApplicationAmendment::getNote, existingApplicationAmendment::setNote, updateRequest.getNote());
if (updateRequest.getApplicationFormFields() != null) {
updateApplicationFormFields(existingApplicationAmendment, updateRequest.getApplicationFormFields());
}
existingApplicationAmendment.setUpdatedDate(DateTimeUtil.DateServerToUTC(LocalDateTime.now()));
ApplicationAmendmentRequestEntity updatedApplicationAmendment = saveApplicationAmendmentRequestEntity(existingApplicationAmendment);
ApplicationAmendmentRequestResponse response = convertEntityToResponse(updatedApplicationAmendment);
log.info("Application Amendment updated successfully: {}", response);
return response;
}
private void updateApplicationFormFields(ApplicationAmendmentRequestEntity applicationAmendment, ApplicationFormFieldRequestBean updatedFormField) {
if (updatedFormField.getFieldValue() == null || "".equals(updatedFormField.getFieldValue().toString().trim())) {
List<ApplicationFormEntity> applicationForms = applicationFormRepository.findByApplicationId(applicationAmendment.getApplicationId());
boolean fieldUpdated = false;
for (ApplicationFormEntity applicationForm : applicationForms) {
Optional<ApplicationFormFieldEntity> formFieldEntityOptional = applicationFormFieldRepository
.findByApplicationFormIdAndFieldId(applicationForm.getId(), updatedFormField.getFieldId());
if (formFieldEntityOptional.isPresent()) {
ApplicationFormFieldEntity formEntity = formFieldEntityOptional.get();
formEntity.setFieldValue(null); // Set field value to null
applicationFormFieldRepository.save(formEntity);
log.info("Set field value to null for application ID {} and field ID {}", applicationAmendment.getApplicationId(), updatedFormField.getFieldId());
fieldUpdated = true;
break;
}
}
if (!fieldUpdated) {
throw new CustomValidationException(Status.NOT_FOUND, "No ApplicationFormField found for application ID " + applicationAmendment.getApplicationId() + " and field ID " + updatedFormField.getFieldId());
}
return;
}
List<String> documentIds;
if (updatedFormField.getFieldValue() instanceof String && updatedFormField.getFieldValue() != null) {
documentIds = Arrays.asList(((String) updatedFormField.getFieldValue()).split(","));
} else {
log.warn("Expected fieldValue as a comma-separated String but got: {}", updatedFormField.getFieldValue());
return;
}
List<String> validDocumentIds = new ArrayList<>();
for (String documentId : documentIds) {
try {
DocumentEntity documentEntity = documentService.validateDocument(Long.parseLong(documentId.trim()));
if (documentEntity != null) {
validDocumentIds.add(documentId.trim());
} else {
log.warn("Document with ID {} does not exist. Skipping this ID.", documentId);
}
} catch (NumberFormatException e) {
log.error("Invalid document ID format: {}. Error: {}", documentId, e.getMessage());
}
}
if (!validDocumentIds.isEmpty()) {
List<ApplicationFormEntity> applicationForms = applicationFormRepository.findByApplicationId(applicationAmendment.getApplicationId());
boolean fieldUpdated = false;
for (ApplicationFormEntity applicationForm : applicationForms) {
Optional<ApplicationFormFieldEntity> formFieldEntityOptional = applicationFormFieldRepository
.findByApplicationFormIdAndFieldId(applicationForm.getId(), updatedFormField.getFieldId());
if (formFieldEntityOptional.isPresent()) {
ApplicationFormFieldEntity formEntity = formFieldEntityOptional.get();
formEntity.setFieldValue(String.join(",", validDocumentIds));
applicationFormFieldRepository.save(formEntity);
log.info("Updated field value for application ID {} and field ID {} with document IDs {}",
applicationAmendment.getApplicationId(), updatedFormField.getFieldId(), String.join(",", validDocumentIds));
fieldUpdated = true;
break;
}
}
if (!fieldUpdated) {
throw new CustomValidationException(Status.NOT_FOUND,"No ApplicationFormField found for application ID {} and field ID {}. Skipping update.");
}
} else {
log.warn("No valid document IDs found for update. Skipping field ID {}", updatedFormField.getFieldId());
}
}
public List<ApplicationAmendmentRequestResponse> getAllAmendmentRequestByBeneficiaryId(Long beneficiaryId) {
UserEntity userEntity = userService.validateUser(beneficiaryId);
List<ApplicationAmendmentRequestEntity> entities =
applicationAmendmentRequestRepository.findByUserId(beneficiaryId);
return entities.stream()
.map(this::convertEntityToResponse)
.collect(Collectors.toList());
}
public ApplicationAmendmentRequestResponse closeAmendmentRequest(Long id, CloseAmendmentRequest closeAmendmentRequest){
log.info("Closing application amendement with ID: {}", id);
ApplicationAmendmentRequestEntity existingApplicationAmendment = validateApplicationAmendmentRequest(id);
setIfUpdated(existingApplicationAmendment::getInternalNote, existingApplicationAmendment::setInternalNote, closeAmendmentRequest.getInternalNote());
setIfUpdated(existingApplicationAmendment::getStatus, existingApplicationAmendment::setStatus, ApplicationAmendmentRequestEnum.CLOSE.getValue());
ApplicationAmendmentRequestEntity updatedApplicationAmendment = saveApplicationAmendmentRequestEntity(existingApplicationAmendment);
ApplicationAmendmentRequestResponse response = convertEntityToResponse(updatedApplicationAmendment);
log.info("Application Amendment closed successfully: {}", response);
return response;
}
public ApplicationAmendmentRequestResponse extendResponseDays(Long id, Long newResponseDays) {
ApplicationAmendmentRequestEntity request = applicationAmendmentRequestRepository.findByIdAndIsDeletedFalse(id)
.orElseThrow(() -> new ResourceNotFoundException(Status.NOT_FOUND,
Translator.toLocale(GepafinConstant.APPLICATION_AMENDMENT_NOT_FOUND_MSG)));
if (newResponseDays != null && newResponseDays > 0) {
Long currentResponseDays = request.getResponseDays() != null ? request.getResponseDays() : 0L;
request.setResponseDays(currentResponseDays + newResponseDays);
applicationAmendmentRequestRepository.save(request);
}
return convertEntityToResponse(request);
}
public List<ApplicationAmendmentRequestResponse> getAmendmentByApplicationId(HttpServletRequest request, Long applicationId,List<ApplicationAmendmentRequestEnum> statuses) {
log.info("Fetching the Amendment data from application id {}", applicationId);
ApplicationEntity application = applicationService.validateApplication(applicationId);
List<ApplicationAmendmentRequestEntity> applicationAmendmentRequestEntity=applicationAmendmentRequestRepository.findByApplicationIdAndIsDeletedFalse(applicationId);
if(statuses!=null && !statuses.isEmpty()) {
List<String> statusStrings = statuses.stream().map(Enum::name).collect(Collectors.toList());
applicationAmendmentRequestEntity = applicationAmendmentRequestRepository.findByApplicationIdAndStatusInAndIsDeletedFalse(application.getId(), statusStrings);
} if(!applicationAmendmentRequestEntity.isEmpty()) {
ApplicationAmendmentRequestEntity applicationAmendmentRequest=applicationAmendmentRequestEntity.get(0);
Optional<ApplicationEvaluationEntity> entityOptional = applicationEvaluationRepository.findByIdAndIsDeletedFalse(applicationAmendmentRequest.getApplicationEvaluationEntity().getId());
if (entityOptional.isPresent()) {
if (Boolean.FALSE.equals(validator.checkIsBeneficiary())) {
validator.validatePreInstructor(request, entityOptional.get().getUserId());
} else {
validator.validateUserId(request, entityOptional.get().getAssignedApplicationsEntity().getApplication().getUserId());
}
}}
List <ApplicationAmendmentRequestResponse> response=new ArrayList<>();
if(applicationAmendmentRequestEntity!=null) {
response= applicationAmendmentRequestEntity.stream()
.map(this::convertEntityToResponse)
.collect(Collectors.toList());
}
return response;
}
public ApplicationAmendmentRequestResponse updateApplicationAmendmentStatus(
Long id,ApplicationAmendmentRequestEnum statusTypeEnum) {
log.info("Updating application amendement with status: {}", id);
ApplicationAmendmentRequestEntity existingApplicationAmendment = validateApplicationAmendmentRequest(id);
if(Boolean.TRUE.equals(existingApplicationAmendment.getStatus().equals(ApplicationAmendmentRequestEnum.AWAITING.getValue())) && Boolean.TRUE.equals(statusTypeEnum.equals(ApplicationAmendmentRequestEnum.RESPONSE_RECEIVED))){
existingApplicationAmendment.setStatus(ApplicationAmendmentRequestEnum.RESPONSE_RECEIVED.getValue());
existingApplicationAmendment.setUpdatedDate(DateTimeUtil.DateServerToUTC(LocalDateTime.now()));
applicationAmendmentRequestRepository.save(existingApplicationAmendment);
}
ApplicationAmendmentRequestResponse response = convertEntityToResponse(existingApplicationAmendment);
log.info("Amendment status updated successfully: {}", response);
return response;
}
public void sendReminderEmail(Long amendmentId) {
ApplicationAmendmentRequestEntity amendment = applicationAmendmentRequestRepository.findByIdAndIsDeletedFalse(amendmentId)
.orElseThrow(() -> new ResourceNotFoundException(Status.NOT_FOUND,
Translator.toLocale(GepafinConstant.APPLICATION_AMENDMENT_NOT_FOUND_MSG)));
Optional<ApplicationEvaluationEntity> entityOptional = applicationEvaluationRepository.findByIdAndIsDeletedFalse(amendment.getApplicationEvaluationEntity().getId());
if (entityOptional.isPresent()) {
ApplicationEntity applicationEntity = applicationService.validateApplication(entityOptional.get().getApplicationId());
UserEntity beneficiaryUser = userService.validateUser(applicationEntity.getUserId());
HubEntity hub = hubService.valdateHub(applicationEntity.getHubId());
SystemEmailTemplateResponse emailTemplate = systemEmailTemplatesService
.retrieveTemplateByTypeAndCall(SystemEmailTemplatesEntityTypeEnum.AMENDMENT_REMINDER, hub, null);
String subject = prepareSubject(emailTemplate, amendment, beneficiaryUser);
String body = prepareBody(emailTemplate, amendment, beneficiaryUser);
String email = beneficiaryUser.getEmail();
if (Boolean.TRUE.equals(amendment.getIsEmail())&&email != null && !email.isEmpty()) {
emailNotificationDao.sendMail(hub.getId(), subject, body, List.of(email));
} else {
throw new CustomValidationException(Status.BAD_REQUEST, Translator.toLocale(GepafinConstant.BENEFICIARY_EMAIL_NOT_FOUND_MSG));
}
}
}
private String prepareSubject(SystemEmailTemplateResponse template, ApplicationAmendmentRequestEntity amendment, UserEntity beneficiary) {
Map<String, String> subjectPlaceholders = new HashMap<>();
String firstName = beneficiary.getFirstName() != null ? beneficiary.getFirstName() : "";
String lastName = beneficiary.getLastName() != null ? beneficiary.getLastName() : "";
String beneficiaryName = String.join(" ", firstName, lastName).trim();
subjectPlaceholders.put("{{amendment_id}}", amendment.getId().toString());
subjectPlaceholders.put("{{beneficiary_name}}", beneficiaryName);
return Utils.replacePlaceholders(template.getSubject(), subjectPlaceholders);
}
private String prepareBody(SystemEmailTemplateResponse template, ApplicationAmendmentRequestEntity amendment, UserEntity beneficiary) {
Map<String, String> bodyPlaceholders = new HashMap<>();
bodyPlaceholders.put("{{amendment_id}}", amendment.getId().toString());
if (amendment.getStartDate() != null && amendment.getResponseDays() != null) {
LocalDateTime dueDate = amendment.getStartDate().plusDays(amendment.getResponseDays());
bodyPlaceholders.put("{{amendment_due_date}}", DateTimeUtil.formatLocalDateTime(dueDate, GepafinConstant.DD_MM_YYYY));
} else {
bodyPlaceholders.put("{{amendment_due_date}}", "Not available");
}
return Utils.replacePlaceholders(template.getHtmlContent(), bodyPlaceholders);
}
}

View File

@@ -25,14 +25,12 @@ 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.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
@@ -46,7 +44,6 @@ 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;
@@ -93,16 +90,10 @@ public class ApplicationDao {
@Autowired
private CompanyService companyService;
@Autowired
private ProtocolRepository protocolRepository;
@Autowired
private SystemEmailTemplatesService systemEmailTemplatesService;
@Autowired
private MailUtil mailUtil;
@Value("${default_System_Receiver_Email}")
private String defaultSystemReceiverEmail;
@@ -136,9 +127,18 @@ public class ApplicationDao {
@Autowired
private S3PathConfig s3ConfigBean;
@Autowired
private ProtocolDao protocolDao;
@Autowired
private HubService hubService;
@Autowired
private EmailNotificationDao emailNotificationDao;
@Autowired
private FormDao formDao;
public ApplicationResponseBean createApplication(HttpServletRequest request, ApplicationRequestBean applicationRequestBean, Long formId, Long applicationId) {
FormEntity formEntity = formService.validateForm(formId);
@@ -211,8 +211,10 @@ public class ApplicationDao {
ApplicationFormEntity applicationFormEntity,
List<ApplicationFormFieldResponseBean> applicationFormFieldResponseBeans) {
List<ContentResponseBean> contentResponseBeans = Utils.convertJsonStringToList(
applicationFormEntity.getForm().getContent(), ContentResponseBean.class);
// List<ContentResponseBean> contentResponseBeans = Utils.convertJsonStringToList(
// applicationFormEntity.getForm().getContent(), ContentResponseBean.class);
List<ContentResponseBean> contentResponseBeans = formDao.convertFormEntityToFormResponseBean(applicationFormEntity.getForm()).getContent();
for (ApplicationFormFieldEntity applicationFormFieldEntity : applicationFormFieldEntities) {
@@ -296,11 +298,11 @@ public class ApplicationDao {
// return applicationResponses;
// }
public List<ApplicationResponse> getAllApplications(UserEntity userEntity, Long callId, Long companyId,String status) {
public List<ApplicationResponse> getAllApplications(UserEntity userEntity, Long callId, Long companyId,List<ApplicationStatusTypeEnum> statusList) {
log.info("Fetching applications for RoleType: {}", userEntity.getRoleEntity().getRoleType());
Specification<ApplicationEntity> spec = search(userEntity, callId, companyId,status);
Specification<ApplicationEntity> spec = search(userEntity, callId, companyId,statusList);
List<ApplicationEntity> applicationEntities = applicationRepository.findAll(spec);
@@ -310,7 +312,7 @@ public class ApplicationDao {
}
private Specification<ApplicationEntity> search(UserEntity userEntity, Long callId, Long companyId,String status) {
private Specification<ApplicationEntity> search(UserEntity userEntity, Long callId, Long companyId,List<ApplicationStatusTypeEnum> statusList) {
return (root, query, builder) -> {
Boolean isBeneficiary = validator.checkIsBeneficiary();
Predicate predicate = builder.isFalse(root.get("isDeleted"));
@@ -323,8 +325,11 @@ public class ApplicationDao {
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));
if (statusList != null && !statusList.isEmpty()) {
List<String> statusNames = statusList.stream()
.map(Enum::name)
.collect(Collectors.toList());
predicate = builder.and(predicate, root.get("status").in(statusNames));
}
predicate = builder.and(predicate, builder.equal(root.get("hubId"), userEntity.getHub().getId()));
return predicate;
@@ -429,7 +434,8 @@ public class ApplicationDao {
private List<Long> validateFileUploadDocuments(ApplicationFormFieldRequestBean applicationFormFieldRequestBean, FormEntity formEntity) {
List<Long> documentIds=null;
List<ContentResponseBean> contentResponseBeans=Utils.convertJsonStringToList(formEntity.getContent(),ContentResponseBean.class);
// List<ContentResponseBean> contentResponseBeans=Utils.convertJsonStringToList(formEntity.getContent(),ContentResponseBean.class);
List<ContentResponseBean> contentResponseBeans=formDao.convertFormEntityToFormResponseBean(formEntity).getContent();
for (ContentResponseBean contentResponseBean:contentResponseBeans){
if(Boolean.TRUE.equals(contentResponseBean.getName().equals("fileupload"))) {
if (contentResponseBean.getId().equals(applicationFormFieldRequestBean.getFieldId())) {
@@ -514,10 +520,63 @@ public class ApplicationDao {
}
else {
List<ApplicationFormEntity> applicationFormEntities = applicationFormRepository.findByApplicationId(applicationEntity.getId());
for (ApplicationFormEntity applicationFormEntity : applicationFormEntities) {
FormEntity form = formService.validateForm(applicationFormEntity.getForm().getId());
formEntities.add(form);
addFormApplication(form, applicationEntity, formApplicationResponses);
List<ApplicationFormEntity> sequencedApplicationFormEntity = new ArrayList<>();
Long formIdMiddle = null;
List<FlowEdgesEntity> flowEdgesList = flowEdgesRepository.findBySourceIdAndCallId(
applicationEntity.getCall().getInitialForm(), applicationEntity.getCall().getId());
if (!flowEdgesList.isEmpty()) {
if (flowEdgesList.size() == 1) {
formIdMiddle = flowEdgesList.get(0).getTargetId();
} else {
List<Long> nextFormIds = flowEdgesList.stream()
.map(FlowEdgesEntity::getTargetId)
.toList();
FlowDataEntity flowDataEntity = flowDataRepository.findByFormIdAndCallId(
applicationEntity.getCall().getInitialForm(), applicationEntity.getCall().getId());
ApplicationFormFieldEntity applicationFormFieldEntity = applicationFormFieldRepository
.findByFieldIdAndApplicationFormFormIdAndApplicationFormApplicationId(
flowDataEntity.getChoosenField(), applicationEntity.getCall().getInitialForm(), applicationEntity.getId())
.orElse(null);
if (applicationFormFieldEntity != null) {
formIdMiddle = flowDataRepository.findByChoosenValueAndFormIdIn(
applicationFormFieldEntity.getFieldValue(), nextFormIds)
.map(FlowDataEntity::getFormId)
.orElse(null);
}
}
}
List<Long> applicationFormIds = new ArrayList<>();
applicationFormIds.add(applicationEntity.getCall().getInitialForm());
if (formIdMiddle != null && formIdMiddle > 0) {
applicationFormIds.add(formIdMiddle);
}
applicationFormIds.add(applicationEntity.getCall().getFinalForm());
if (applicationFormEntities.size() == 3) {
for (Long applicationFormId : applicationFormIds) {
for (ApplicationFormEntity applicationFormEntity : applicationFormEntities) {
if (applicationFormEntity.getForm().getId().equals(applicationFormId)) {
sequencedApplicationFormEntity.add(applicationFormEntity);
FormEntity form = formService.validateForm(applicationFormId);
formEntities.add(form);
addFormApplication(form, applicationEntity, formApplicationResponses);
}
}
}
}else {
ApplicationFormEntity applicationFormEntity1=applicationFormRepository.findByApplicationIdAndFormId(applicationEntity.getId(),applicationEntity.getCall().getInitialForm());
sequencedApplicationFormEntity.add(applicationFormEntity1);
FormEntity form1 = formService.validateForm(applicationFormEntity1.getForm().getId());
formEntities.add(form1);
addFormApplication(form1, applicationEntity, formApplicationResponses);
ApplicationFormEntity applicationFormEntity2=applicationFormRepository.findByApplicationIdAndFormId(applicationEntity.getId(),applicationEntity.getCall().getFinalForm());
sequencedApplicationFormEntity.add(applicationFormEntity2);
FormEntity form2= formService.validateForm(applicationFormEntity2.getForm().getId());
formEntities.add(form2);
addFormApplication(form2, applicationEntity, formApplicationResponses);
}
}
@@ -579,7 +638,8 @@ public class ApplicationDao {
formApplicationResponse.setId(formEntity.getId());
formApplicationResponse.setLabel(formEntity.getLabel());
formApplicationResponse.setCallId(formEntity.getCall().getId());
formApplicationResponse.setContent(Utils.convertJsonStringToList(formEntity.getContent(), ContentResponseBean.class));
// formApplicationResponse.setContent(Utils.convertJsonStringToList(formEntity.getContent(), ContentResponseBean.class)
formApplicationResponse.setContent(formDao.convertFormEntityToFormResponseBean(formEntity).getContent());
return formApplicationResponse;
}
@@ -614,13 +674,13 @@ public class ApplicationDao {
}
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());
Long protocolNumber = protocolDao.getProtocolNumber(userEntity.getHub());
ProtocolEntity protocolEntity = protocolDao.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);
sendMailToUserAndCompany(userEntity, applicationEntity);
sendMailTodefaultSystemAndGepafin(userEntity, applicationEntity);
applicationEntity.setStatus(status.getValue());
}
@@ -633,14 +693,7 @@ public class ApplicationDao {
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));
@@ -655,7 +708,8 @@ public class ApplicationDao {
}
public void validateFormFields(ApplicationRequestBean request, FormEntity formEntity) {
List<ContentResponseBean> contentResponseBeans=Utils.convertJsonStringToList(formEntity.getContent(),ContentResponseBean.class);
// List<ContentResponseBean> contentResponseBeans=Utils.convertJsonStringToList(formEntity.getContent(),ContentResponseBean.class);
List<ContentResponseBean> contentResponseBeans=formDao.convertFormEntityToFormResponseBean(formEntity).getContent();
List<ApplicationFormFieldRequestBean> requestFields = request.getFormFields();
@@ -714,18 +768,6 @@ public class ApplicationDao {
}
}
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();
@@ -750,17 +792,26 @@ public class ApplicationDao {
// 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);
**/
}
emailNotificationDao.sendMail(hub.getId(), subject, body, List.of(email));
List<String> recipientEmails = new ArrayList<>();
// recipientEmails.add(email);
String companyEmail = company.getEmail();
String contactEmail = company.getContactEmail();
if (companyEmail != null && !companyEmail.isEmpty()) {
recipientEmails.add(companyEmail);
}
if (contactEmail != null && !contactEmail.isEmpty() && !contactEmail.equals(companyEmail)) {
recipientEmails.add(contactEmail);
}
emailNotificationDao.sendMail(hub.getId(), subject, body, recipientEmails);
}
private void sendMailTodefaultSystemAndGepafin(UserEntity userEntity, ApplicationEntity applicationEntity) {
CallEntity call = applicationEntity.getCall();
CompanyEntity company = applicationEntity.getCompany();
@@ -787,12 +838,16 @@ public class ApplicationDao {
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);
// 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);
// mailUtil.sendByMailGun(subject, body, List.of(carloEmail), null);
emailNotificationDao.sendMail(hub.getId(), subject, body, List.of(carloEmail));
}
emailNotificationDao.sendMail(hub.getId(), subject, body, List.of(gepafinEmail));
emailNotificationDao.sendMail(hub.getId(), subject, body, List.of(defaultSystemReceiverEmail));
emailNotificationDao.sendMail(hub.getId(), subject, body, List.of(rinaldoEmail));
}
public ApplicationSignedDocumentResponse uploadSignedDocument(HttpServletRequest request, Long applicationId,

File diff suppressed because it is too large Load Diff

View File

@@ -79,7 +79,7 @@ public class AssignedApplicationsDao {
assignApplication.setApplication(application);
assignApplication.setAssignedBy(assignedByUser.getId());
assignApplication.setUserId(userId);
assignApplication.setStatus(AssignedApplicationEnum.ASSIGNED.getValue());
assignApplication.setStatus(AssignedApplicationEnum.OPEN.getValue());
if(assignedApplicationsRequest.getStatus() != null) {
assignApplication.setStatus(assignedApplicationsRequest.getStatus().getValue());
}

View File

@@ -0,0 +1,102 @@
package net.gepafin.tendermanagement.dao;
import net.gepafin.tendermanagement.config.Translator;
import net.gepafin.tendermanagement.constants.GepafinConstant;
import net.gepafin.tendermanagement.entities.ApplicationAmendmentRequestEntity;
import net.gepafin.tendermanagement.entities.CommunicationEntity;
import net.gepafin.tendermanagement.model.request.CommunicationRequestBean;
import net.gepafin.tendermanagement.model.response.ApplicationAmendmentResponse;
import net.gepafin.tendermanagement.model.response.CommunicationResponseBean;
import net.gepafin.tendermanagement.repositories.CommunicationRepository;
import net.gepafin.tendermanagement.service.ApplicationAmendmentRequestService;
import net.gepafin.tendermanagement.web.rest.api.errors.CustomValidationException;
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.stereotype.Component;
import java.time.LocalDateTime;
import java.util.List;
@Component
public class CommunicationDao {
private static final Logger log = LoggerFactory.getLogger(CommunicationDao.class);
@Autowired
private CommunicationRepository communicationRepository;
@Autowired
ApplicationAmendmentRequestService applicationAmendmentRequestService;
public CommunicationResponseBean addCommentToAmendmentRequest(CommunicationRequestBean communicationReq, Long amendmentId) {
log.info("Adding communication request...");
CommunicationEntity communicationEntity = convertToCommunicationCommentEntity(communicationReq, amendmentId);
communicationEntity = communicationRepository.save(communicationEntity);
log.info("Added comment: {}", communicationEntity);
return convertToCommunicationResponseBean(communicationEntity);
}
public String deleteComment(Long amendmentId, Long commentId) {
CommunicationEntity data = communicationRepository.findById(commentId)
.orElseThrow(() -> new CustomValidationException(Status.NOT_FOUND, Translator.toLocale(GepafinConstant.COMMENT_NOT_FOUND)));
if (!data.getApplicationAmendmentRequest().getId().equals(amendmentId)) {
throw new CustomValidationException(Status.BAD_REQUEST, Translator.toLocale(GepafinConstant.INVALID_AMENDMENT_FOR_COMMENT));
}
data.setIsDeleted(true);
communicationRepository.save(data);
return "Deleted Comment Successfully.";
}
public ApplicationAmendmentResponse getAmendmentComments(Long amendmentId) {
ApplicationAmendmentRequestEntity amendmentData = applicationAmendmentRequestService.validateApplicationAmendmentRequest(amendmentId);
List<CommunicationResponseBean> commentsList = communicationRepository.findCommentDetailsByAmendmentId(amendmentId);
if (commentsList == null) {
throw new CustomValidationException(Status.NOT_FOUND, Translator.toLocale(GepafinConstant.COMMENT_NOT_FOUND));
}
return new ApplicationAmendmentResponse(amendmentData, commentsList);
}
public CommunicationResponseBean updateAmendmentComment(CommunicationRequestBean communicationRequestBean, Long amendmentId, Long commentId) {
log.info("Updating communication comment...");
CommunicationEntity existingComment = communicationRepository.findById(commentId)
.orElseThrow(() -> new CustomValidationException(Status.NOT_FOUND, Translator.toLocale(GepafinConstant.COMMENT_NOT_FOUND)));
if (!existingComment.getApplicationAmendmentRequest().getId().equals(amendmentId)) {
throw new CustomValidationException(Status.BAD_REQUEST, Translator.toLocale(GepafinConstant.COMMENT_NOT_ASSOCIATE_WITH_AMENDMENT_ID_ERROR_MSG));
}
existingComment.setCommunicationTitle(communicationRequestBean.getTitle());
existingComment.setCommunicationComment(communicationRequestBean.getComment());
existingComment.setCommentedDate(LocalDateTime.now());
existingComment = communicationRepository.save(existingComment);
log.info("Updated Comment: {}", existingComment);
return convertToCommunicationResponseBean(existingComment);
}
private CommunicationResponseBean convertToCommunicationResponseBean(CommunicationEntity entity) {
CommunicationResponseBean response = new CommunicationResponseBean();
response.setComment(entity.getCommunicationComment());
response.setCommentedDate(entity.getCommentedDate());
response.setAmendmentId(entity.getApplicationAmendmentRequest().getId());
response.setCreatedDate(entity.getCreatedDate());
response.setUpdatedDate(entity.getUpdatedDate());
response.setTitle(entity.getCommunicationTitle());
return response;
}
private CommunicationEntity convertToCommunicationCommentEntity(CommunicationRequestBean communicationReq, Long amendmentId) {
ApplicationAmendmentRequestEntity amendmentRequest = applicationAmendmentRequestService.validateApplicationAmendmentRequest(amendmentId);
CommunicationEntity communicationEntity = new CommunicationEntity();
communicationEntity.setApplicationAmendmentRequest(amendmentRequest);
communicationEntity.setCommunicationTitle(communicationReq.getTitle());
communicationEntity.setCommunicationComment(communicationReq.getComment());
communicationEntity.setIsDeleted(false);
communicationEntity.setCommentedDate(LocalDateTime.now());
return communicationEntity;
}
}

View File

@@ -97,6 +97,7 @@ public class DocumentDao {
private Long resolveSourceId(Long sourceId, DocumentSourceTypeEnum sourceType) {
if (sourceType == DocumentSourceTypeEnum.CALL) {
CallEntity callEntity = callService.validateCall(sourceId);
callDao.validateUpdate(callEntity);
return callEntity.getId();
}
// else if (sourceType == SourceTypeEnum.APPLICATION) {

View File

@@ -0,0 +1,199 @@
package net.gepafin.tendermanagement.dao;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import net.gepafin.tendermanagement.constants.GepafinConstant;
import net.gepafin.tendermanagement.entities.ApplicationAmendmentRequestEntity;
import net.gepafin.tendermanagement.entities.ApplicationEntity;
import net.gepafin.tendermanagement.entities.HubEntity;
import net.gepafin.tendermanagement.entities.SystemEmailTemplatesEntity;
import net.gepafin.tendermanagement.entities.UserEntity;
import net.gepafin.tendermanagement.model.request.EmailConfig;
import net.gepafin.tendermanagement.model.response.SystemEmailTemplateResponse;
import net.gepafin.tendermanagement.repositories.HubRepository;
import net.gepafin.tendermanagement.service.ApplicationService;
import net.gepafin.tendermanagement.service.HubService;
import net.gepafin.tendermanagement.service.SystemEmailTemplatesService;
import net.gepafin.tendermanagement.service.UserService;
import net.gepafin.tendermanagement.service.impl.EmailService;
import net.gepafin.tendermanagement.service.impl.EmailServiceFactory;
import net.gepafin.tendermanagement.util.DateTimeUtil;
import net.gepafin.tendermanagement.util.Utils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Component
public class EmailNotificationDao {
private static final Logger log = LoggerFactory.getLogger(EmailNotificationDao.class);
@Autowired
private SystemEmailTemplatesService systemEmailTemplatesService;
@Autowired
private ApplicationService applicationService;
@Autowired
private UserService userService;
@Autowired
private HubService hubService;
@Autowired
EmailServiceFactory emailServiceFactory;
@Autowired
HubRepository hubRepository;
private void sendEmail(ApplicationAmendmentRequestEntity amendmentRequest, SystemEmailTemplatesEntity.SystemEmailTemplatesEntityTypeEnum templateType,
Map<String, String> bodyPlaceholders, List<String> additionalRecipients) {
ApplicationEntity applicationEntity = applicationService.validateApplication(amendmentRequest.getApplicationId());
HubEntity hubEntity = hubService.valdateHub(applicationEntity.getHubId());
String service = determineService(applicationEntity.getHubId());
String legalMail = service.equals("Gepafin S.p.a.") ? "bandi.gepafin@legalmail.it" : "bandi.sviluppumbria@legalmail.it";
SystemEmailTemplateResponse systemEmailTemplateResponse = systemEmailTemplatesService.retrieveTemplateByTypeAndCall(templateType, hubEntity, null);
Map<String, String> subjectPlaceholders = new HashMap<>();
subjectPlaceholders.put("{{call_name}}", applicationEntity.getCall().getName());
subjectPlaceholders.put("{{company_name}}", applicationEntity.getCompany().getCompanyName());
bodyPlaceholders.put("{{legal_mail}}", legalMail);
String subject = Utils.replacePlaceholders(systemEmailTemplateResponse.getSubject(), subjectPlaceholders);
String body = Utils.replacePlaceholders(systemEmailTemplateResponse.getHtmlContent(), bodyPlaceholders);
UserEntity userEntity = userService.validateUser(applicationEntity.getUserId());
List<String> recipientEmails = getRecipientEmails(applicationEntity, userEntity, additionalRecipients);
sendMail(applicationEntity.getHubId(), subject, body, recipientEmails);
}
private List<String> getRecipientEmails(ApplicationEntity applicationEntity, UserEntity userEntity, List<String> additionalRecipients) {
List<String> recipientEmails = new ArrayList<>();
String companyEmail = applicationEntity.getCompany().getEmail();
String contactEmail = applicationEntity.getCompany().getContactEmail();
if (companyEmail != null && !companyEmail.isEmpty()) {
recipientEmails.add(companyEmail);
}
if (contactEmail != null && !contactEmail.isEmpty() && !contactEmail.equals(companyEmail)) {
recipientEmails.add(contactEmail);
}
if (userEntity.getBeneficiary().getEmail() != null) {
recipientEmails.add(userEntity.getBeneficiary().getEmail());
}
if (additionalRecipients != null) {
recipientEmails.addAll(additionalRecipients);
}
return recipientEmails;
}
private String determineService(Long hubId) {
HubEntity hub = hubRepository.findById(hubId).orElseThrow(() -> new IllegalArgumentException("Invalid Hub ID: " + hubId));
return hub.getEmailServiceType().equalsIgnoreCase("MAILGUN_SERVICE") ? "Gepafin S.p.a." : "Sviluppumbria";
}
public void sendMailToNotifyBeneficiaryRegardingNewAmendment(ApplicationAmendmentRequestEntity applicationAmendmentRequest) {
ApplicationEntity applicationEntity = applicationService.validateApplication(applicationAmendmentRequest.getApplicationId());
Map<String, String> bodyPlaceholders = new HashMap<>();
bodyPlaceholders.put("{{call_name}}", applicationEntity.getCall().getName());
bodyPlaceholders.put("{{protocol_number}}", applicationAmendmentRequest.getProtocol().getProtocolNumber().toString());
bodyPlaceholders.put("{{protocol_date}}", DateTimeUtil.formatLocalDateTime(applicationAmendmentRequest.getProtocol().getCreatedDate(), GepafinConstant.DD_MM_YYYY));
bodyPlaceholders.put("{{protocol_time}}", DateTimeUtil.parseLocalTimeToString(applicationAmendmentRequest.getProtocol().getTime(), GepafinConstant.HH_MM_SS));
String formFieldsJson = applicationAmendmentRequest.getFormFields();
ObjectMapper objectMapper = new ObjectMapper();
try {
List<Map<String, Object>> formFields = objectMapper.readValue(formFieldsJson, new TypeReference<List<Map<String, Object>>>() {
});
//•
StringBuilder bulletPoints = new StringBuilder();
for (Map<String, Object> field : formFields) {
String label = (String) field.get("label");
boolean selected = (boolean) field.get("selected");
if (!selected) {
bulletPoints.append("").append(label).append("\n");
}
}
bodyPlaceholders.put("{{form_dataInput}}", bulletPoints.toString());
} catch (Exception e) {
log.error("Failed to parse form fields JSON: ", e);
}
bodyPlaceholders.put("{{note}}", applicationAmendmentRequest.getNote());
sendEmail(applicationAmendmentRequest, SystemEmailTemplatesEntity.SystemEmailTemplatesEntityTypeEnum.DOCUMENTATION_INTEGRATION_REQUEST, bodyPlaceholders, null);
}
public void sendApplicationFailureNotificationEmail(ApplicationAmendmentRequestEntity amendmentRequest) {
ApplicationEntity applicationEntity = applicationService.validateApplication(amendmentRequest.getApplicationId());
Map<String, String> bodyPlaceholders = new HashMap<>();
bodyPlaceholders.put("{{call_name}}", applicationEntity.getCall().getName());
bodyPlaceholders.put("{{date_time_emailSend}}", DateTimeUtil.formatLocalDateTime(amendmentRequest.getCreatedDate(), GepafinConstant.DD_MM_YYYY_HH_MM));
sendEmail(amendmentRequest, SystemEmailTemplatesEntity.SystemEmailTemplatesEntityTypeEnum.INADMISSIBILITY_NOTIFICATION_DUE_TO_FAILURE, bodyPlaceholders, null);
}
public void sendAdmissibilityNotificationEmailForApprovedApplication(ApplicationAmendmentRequestEntity amendmentRequest) {
ApplicationEntity applicationEntity = applicationService.validateApplication(amendmentRequest.getApplicationId());
Map<String, String> bodyPlaceholders = new HashMap<>();
bodyPlaceholders.put("{{call_name}}", applicationEntity.getCall().getName());
bodyPlaceholders.put("{{protocol_number}}", amendmentRequest.getProtocol().getProtocolNumber().toString());
bodyPlaceholders.put("{{protocol_date}}", DateTimeUtil.formatCreatedDate(amendmentRequest.getProtocol().getCreatedDate()));
bodyPlaceholders.put("{{protocol_time}}", DateTimeUtil.parseLocalTimeToString(amendmentRequest.getProtocol().getTime(), GepafinConstant.HH_MM_SS));
sendEmail(amendmentRequest, SystemEmailTemplatesEntity.SystemEmailTemplatesEntityTypeEnum.ADMISSIBILITY_NOTIFICATION, bodyPlaceholders, null);
}
public void sendInadmissibilityEmailForRejectedApplication(ApplicationAmendmentRequestEntity amendmentRequest) {
ApplicationEntity applicationEntity = applicationService.validateApplication(amendmentRequest.getApplicationId());
Map<String, String> bodyPlaceholders = new HashMap<>();
bodyPlaceholders.put("{{call_name}}", applicationEntity.getCall().getName());
bodyPlaceholders.put("{{protocol_number}}", amendmentRequest.getProtocol().getProtocolNumber().toString());
bodyPlaceholders.put("{{protocol_date}}", DateTimeUtil.formatCreatedDate(amendmentRequest.getProtocol().getCreatedDate()));
bodyPlaceholders.put("{{protocol_time}}", DateTimeUtil.parseLocalTimeToString(amendmentRequest.getProtocol().getTime(), GepafinConstant.HH_MM_SS));
bodyPlaceholders.put("{{form_text}}", amendmentRequest.getNote());
sendEmail(amendmentRequest, SystemEmailTemplatesEntity.SystemEmailTemplatesEntityTypeEnum.INADMISSIBILITY_TEMPLATE, bodyPlaceholders, null);
}
public void sendMail(Long hubId, String subject, String body, List<String> recipientEmails) {
EmailConfig emailConfig = retrieveEmailConfig(hubId);
EmailService emailService = emailServiceFactory.getEmailService(emailConfig.getEmailServiceType());
emailService.sendEmail(subject, body, recipientEmails, emailConfig);
}
public EmailConfig retrieveEmailConfig(Long hubId) {
HubEntity hubEntity = hubRepository.findById(hubId).orElseThrow(() -> new IllegalArgumentException("Invalid Hub ID: " + hubId));
String emailServiceType = hubEntity.getEmailServiceType();
String encryptedConfigJson = hubEntity.getEmailServiceConfig();
String decryptedConfigJson = Utils.decryptCredential(encryptedConfigJson);
EmailConfig emailConfig = parseEmailConfig(decryptedConfigJson);
emailConfig.setEmailServiceType(emailServiceType);
return emailConfig;
}
private EmailConfig parseEmailConfig(String configJson) {
ObjectMapper objectMapper = new ObjectMapper();
try {
return objectMapper.readValue(configJson, EmailConfig.class);
} catch (JsonProcessingException e) {
throw new IllegalArgumentException("Failed to parse email configuration JSON", e);
}
}
}

View File

@@ -230,10 +230,10 @@ public class PdfDao {
// PdfPCell valueCell = new PdfPCell(new Phrase(item, valueFont));
PdfPCell valueCell = PdfUtils.htmlToPdfPCell(item, valueFont);
valueCell.setFixedHeight(30f); // Set a fixed height for the cell
valueCell.setPaddingLeft(10f); // Adjust left padding as needed
valueCell.setPaddingTop(0f); // Remove padding from top to allow vertical centering
valueCell.setPaddingBottom(6f);
valueCell.setMinimumHeight(30f); // Set a fixed height for the cell
valueCell.setPaddingLeft(leftMargin); // Increase left margin for value
valueCell.setBorder(Rectangle.NO_BORDER); // Remove border for value cell
valueCell.setVerticalAlignment(Element.ALIGN_MIDDLE);
@@ -306,7 +306,7 @@ public class PdfDao {
}
// PdfPCell valueCell = new PdfPCell(new Phrase(fieldValue1, valueFont));
PdfPCell valueCell = PdfUtils.htmlToPdfPCell(fieldValue1, valueFont);
valueCell.setFixedHeight(30f); // Set a fixed height for the cell
valueCell.setMinimumHeight(30f); // Set a fixed height for the cell
valueCell.setPaddingLeft(10f); // Adjust left padding as needed
valueCell.setPaddingTop(0f); // Remove padding from top to allow vertical centering
valueCell.setPaddingBottom(6f);
@@ -393,7 +393,7 @@ public class PdfDao {
headerCell.setHorizontalAlignment(Element.ALIGN_CENTER); // Center align
headerCell.setVerticalAlignment(Element.ALIGN_MIDDLE);
headerCell.setBackgroundColor(new BaseColor(178, 190, 181)); // Light gray background for header
headerCell.setFixedHeight(30f); // Set a fixed height for the cell
headerCell.setMinimumHeight(30f); // Set a fixed height for the cell
headerCell.setPaddingLeft(10f); // Adjust left padding as needed
headerCell.setPaddingTop(0f); // Remove padding from top to allow vertical centering
headerCell.setPaddingBottom(6f);
@@ -415,6 +415,7 @@ public class PdfDao {
// PdfPCell dataCell = new PdfPCell(new Phrase(fieldValue != null ?fieldValue: "", textFont));
PdfPCell dataCell = PdfUtils.htmlToPdfPCell(fieldValue != null ? fieldValue : "", textFont);
dataCell.setBackgroundColor(new BaseColor(239, 243, 248)); // Light blue for the cell
dataCell.setMinimumHeight(30f);
dataCell.setPaddingLeft(10f); // Adjust left padding as needed
dataCell.setPaddingTop(0f); // Remove padding from top to allow vertical centering
dataCell.setPaddingBottom(6f);

View File

@@ -0,0 +1,48 @@
package net.gepafin.tendermanagement.dao;
import java.time.LocalDateTime;
import java.time.LocalTime;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import net.gepafin.tendermanagement.entities.ApplicationEntity;
import net.gepafin.tendermanagement.entities.HubEntity;
import net.gepafin.tendermanagement.entities.ProtocolEntity;
import net.gepafin.tendermanagement.repositories.ProtocolRepository;
import net.gepafin.tendermanagement.util.DateTimeUtil;
@Component
public class ProtocolDao {
@Autowired
private ProtocolRepository protocolRepository;
@Value("${default.hub.uuid}")
private String defaultHubUuid;
public 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 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;
}
}

View File

@@ -5,10 +5,7 @@ import jakarta.servlet.http.HttpServletResponse;
import net.gepafin.tendermanagement.config.SamlSuccessHandler;
import net.gepafin.tendermanagement.config.Translator;
import net.gepafin.tendermanagement.constants.GepafinConstant;
import net.gepafin.tendermanagement.entities.BeneficiaryEntity;
import net.gepafin.tendermanagement.entities.HubEntity;
import net.gepafin.tendermanagement.entities.RoleEntity;
import net.gepafin.tendermanagement.entities.UserEntity;
import net.gepafin.tendermanagement.entities.*;
import net.gepafin.tendermanagement.enums.RoleStatusEnum;
import net.gepafin.tendermanagement.enums.UserStatusEnum;
import net.gepafin.tendermanagement.model.request.*;
@@ -80,6 +77,9 @@ public class UserDao {
@Autowired
private HubService hubService;
@Autowired
private AuthenticationService authenticationService;
public JWTToken createUser(HttpServletRequest request, String tempToken, UserReq userReq) {
if(StringUtils.isEmpty(userReq.getHubUuid())) {
@@ -92,6 +92,14 @@ public class UserDao {
BeneficiaryEntity beneficiary = createBeneficiary(roleEntity, userReq, hub);
UserEntity userEntity = convertUserRequestToUserEntity(beneficiary, roleEntity, userReq, hub);
log.info("User created with ID: {}", userEntity.getId());
LoginReq loginReq=new LoginReq();
loginReq.setEmail(userEntity.getEmail());
if(userEntity!=null){
LoginAttemptEntity loginAttemptEntity =authenticationService.prepareLoginAttemptEntity(loginReq, request);
log.info("Authentication failed for email: {}", loginReq.getEmail());
loginAttemptEntity.setUserId(userEntity.getId());
authenticationService.createSuccessLoginAttempt(loginAttemptEntity);
}
return authService.getJWTTokenBean(userEntity, Boolean.TRUE);
}
@@ -403,8 +411,8 @@ public class UserDao {
return userResponseBeans;
}
public JWTToken validateExistingUserToken(String token) {
return authService.validateExistingUserToken(token);
public JWTToken validateExistingUserToken(HttpServletRequest request,String token) {
return authService.validateExistingUserToken(request,token);
}
public UserSamlResponse validateNewUserToken(String token) {

View File

@@ -0,0 +1,50 @@
package net.gepafin.tendermanagement.entities;
import jakarta.persistence.*;
import lombok.Data;
import java.time.LocalDateTime;
@Entity
@Table(name="application_amendment_request")
@Data
public class ApplicationAmendmentRequestEntity extends BaseEntity {
@Column(name = "NOTE")
private String note;
@Column(name ="RESPONSE_DAYS")
private Long responseDays;
@Column(name = "IS_NOTIFICATION")
private Boolean isNotification = false;
@Column(name = "IS_EMAIL")
private Boolean isEmail=false;
@Column(name = "APPLICATION_ID")
private Long applicationId;
@Column(name = "START_DATE")
private LocalDateTime startDate;
@Column(name = "FORM_FIELDS")
private String formFields;
@Column(name="IS_DELETED")
private Boolean isDeleted=false;
@Column(name = "STATUS")
private String status;
@Column(name = "INTERNAL_NOTE")
private String internalNote;
@ManyToOne
@JoinColumn(name = "APPLICATION_EVALUATION_ID", nullable = false)
private ApplicationEvaluationEntity applicationEvaluationEntity;
@OneToOne
@JoinColumn(name = "PROTOCOL_Id")
private ProtocolEntity protocol;
}

View File

@@ -8,9 +8,6 @@ import java.time.LocalDateTime;
@Entity
@Table(name = "APPLICATION")
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class ApplicationEntity extends BaseEntity {
@Column(name = "USER_ID")

View File

@@ -0,0 +1,39 @@
package net.gepafin.tendermanagement.entities;
import jakarta.persistence.*;
import lombok.Data;
@Data
@Entity
@Table(name = "application_evaluation")
public class ApplicationEvaluationEntity extends BaseEntity{
@Column(name = "application_Id")
private Long applicationId;
@Column(name = "user_id")
private Long userId;
@Column(name = "criteria")
private String criteria;
@Column(name = "checklist")
private String checklist;
@Column(name = "file")
private String file;
@Column(name = "note")
private String note;
@Column(name = "status")
private String status;
@Column(name="IS_DELETED")
private Boolean isDeleted;
@ManyToOne
@JoinColumn(name = "assigned_applications_id", nullable = true)
private AssignedApplicationsEntity assignedApplicationsEntity;
}

View File

@@ -0,0 +1,33 @@
package net.gepafin.tendermanagement.entities;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.Table;
import lombok.Data;
import java.time.LocalDateTime;
@Entity
@Table(name = "communication")
@Data
public class CommunicationEntity extends BaseEntity {
@Column(name = "COMMUNICATION_TITLE")
private String communicationTitle;
@Column(name = "COMMUNICATION_COMMENT")
private String communicationComment;
@Column(name = "IS_DELETED")
private Boolean isDeleted = false;
@Column(name = "COMMENTED_DATE")
private LocalDateTime commentedDate;
@ManyToOne
@JoinColumn(name = "AMENDMENT_ID", referencedColumnName = "id", nullable = false)
private ApplicationAmendmentRequestEntity applicationAmendmentRequest;
}

View File

@@ -42,10 +42,16 @@ public class HubEntity extends BaseEntity{
@Column(name = "UNIQUE_UUID")
private String uniqueUuid;
@Column(name = "EMAIL_SIGNATURE")
private String emailSignature;
@Column(name="PDF_BANNER")
private String pdfBanner;
@Column(name = "EMAIL_SIGNATURE")
private String emailSignature;
@Column(name = "EMAIL_SERVICE_TYPE")
private String emailServiceType;
@Column(name = "EMAIL_SERVICE_CONFIG")
private String emailServiceConfig;
}

View File

@@ -39,7 +39,12 @@ public class SystemEmailTemplatesEntity extends BaseEntity {
public enum SystemEmailTemplatesEntityTypeEnum {
APPLICATION_SUBMISSION_TO_USER_AND_COMPANY("APPLICATION_SUBMISSION_TO_USER_AND_COMPANY"),
APPLICATION_SUBMISSION_TO_GEPAFIN("APPLICATION_SUBMISSION_TO_GEPAFIN");
APPLICATION_SUBMISSION_TO_GEPAFIN("APPLICATION_SUBMISSION_TO_GEPAFIN"),
DOCUMENTATION_INTEGRATION_REQUEST("DOCUMENTATION_INTEGRATION_REQUEST"),
INADMISSIBILITY_NOTIFICATION_DUE_TO_FAILURE("INADMISSIBILITY_NOTIFICATION_DUE_TO_FAILURE"),
ADMISSIBILITY_NOTIFICATION("ADMISSIBILITY_NOTIFICATION"),
AMENDMENT_REMINDER("AMENDMENT_REMINDER"),
INADMISSIBILITY_TEMPLATE("INADMISSIBILITY_NOTIFICATION");
private String value;

View File

@@ -0,0 +1,21 @@
package net.gepafin.tendermanagement.enums;
import com.fasterxml.jackson.annotation.JsonValue;
public enum ApplicationAmendmentRequestEnum {
AWAITING("AWAITING"),
RESPONSE_RECEIVED("RESPONSE_RECEIVED"),
CLOSE("CLOSE"),
EXPIRED("EXPIRED");
private String value;
ApplicationAmendmentRequestEnum(String value) {
this.value = value;
}
@JsonValue
public String getValue() {
return value;
}
}

View File

@@ -0,0 +1,20 @@
package net.gepafin.tendermanagement.enums;
import com.fasterxml.jackson.annotation.JsonValue;
public enum ApplicationEvaluationStatusTypeEnum {
OPEN ("OPEN"),
SOCCORSO("SOCCORSO"),
CLOSE("CLOSE");
private String value;
ApplicationEvaluationStatusTypeEnum(String value) {
this.value = value;
}
@JsonValue
public String getValue() {
return value;
}
}

View File

@@ -0,0 +1,19 @@
package net.gepafin.tendermanagement.enums;
import com.fasterxml.jackson.annotation.JsonValue;
public enum ApplicationStatusForEvaluation {
APPROVED("APPROVED"),
REJECTED("REJECTED");
private String value;
ApplicationStatusForEvaluation(String value) {
this.value = value;
}
@JsonValue
public String getValue() {
return value;
}
}

View File

@@ -9,6 +9,9 @@ public enum ApplicationStatusTypeEnum {
AWAITING("AWAITING"),
READY("READY"),
DISCARD("DISCARD"),
SOCCORSO("SOCCORSO"),
APPROVED("APPROVED"),
REJECTED("REJECTED"),
EVALUATION("EVALUATION");
private String value;

View File

@@ -3,9 +3,9 @@ package net.gepafin.tendermanagement.enums;
import com.fasterxml.jackson.annotation.JsonValue;
public enum AssignedApplicationEnum {
ASSIGNED("ASSIGNED"),
APPROVED("APPROVED"),
REJECTED("REJECTED");
OPEN ("OPEN"),
SOCCORSO("SOCCORSO"),
CLOSE("CLOSE");
private final String value;

View File

@@ -0,0 +1,14 @@
package net.gepafin.tendermanagement.model.request;
import lombok.Data;
import net.gepafin.tendermanagement.model.response.AmendmentFormFieldResponse;
import java.util.List;
@Data
public class ApplicationAmendmentRequest {
private String note;
private List<AmendmentFormFieldResponse> formFields;
private Long responseDays;
private Boolean isSendNotification;
private Boolean isSendEmail;
}

View File

@@ -0,0 +1,9 @@
package net.gepafin.tendermanagement.model.request;
import lombok.Data;
@Data
public class ApplicationAmendmentRequestBean {
private String note;
private ApplicationFormFieldRequestBean applicationFormFields;
}

View File

@@ -0,0 +1,15 @@
package net.gepafin.tendermanagement.model.request;
import lombok.Data;
import net.gepafin.tendermanagement.enums.ApplicationStatusForEvaluation;
import java.util.List;
@Data
public class ApplicationEvaluationRequest {
private List<CriteriaRequest> criteria;
private List<ChecklistRequest> checklist;
private List<FieldRequest> files;
private String note;
private ApplicationStatusForEvaluation applicationStatus;
}

View File

@@ -0,0 +1,9 @@
package net.gepafin.tendermanagement.model.request;
import lombok.Data;
@Data
public class ChecklistRequest {
private Long id;
private Boolean valid;
}

View File

@@ -0,0 +1,8 @@
package net.gepafin.tendermanagement.model.request;
import lombok.Data;
@Data
public class CloseAmendmentRequest {
private String InternalNote;
}

View File

@@ -0,0 +1,10 @@
package net.gepafin.tendermanagement.model.request;
import lombok.Data;
@Data
public class CommunicationRequestBean {
private String title;
private String comment;
}

View File

@@ -0,0 +1,10 @@
package net.gepafin.tendermanagement.model.request;
import lombok.Data;
@Data
public class CriteriaRequest {
private Long id;
private Long score;
private Boolean valid;
}

View File

@@ -0,0 +1,18 @@
package net.gepafin.tendermanagement.model.request;
import lombok.Data;
@Data
public class EmailConfig {
private String emailServiceType;
private String authToken;
private String apiKey;
private String username;
private String password;
private String sender;
private String domain;
private String mailgunApiUrl;
private String pecApiUrl;
}

View File

@@ -0,0 +1,9 @@
package net.gepafin.tendermanagement.model.request;
import lombok.Data;
@Data
public class FieldRequest {
private String id;
private Boolean valid;
}

View File

@@ -0,0 +1,15 @@
package net.gepafin.tendermanagement.model.request;
import lombok.Data;
import java.util.List;
@Data
public class PecEmailRequest {
private String sender;
private List<String> recipient;
private String subject;
private String body;
private String username;
private String password;
}

View File

@@ -0,0 +1,2 @@
package net.gepafin.tendermanagement.model.request;public class UpdateApplicationEvaluationRequest {
}

View File

@@ -0,0 +1,10 @@
package net.gepafin.tendermanagement.model.response;
import lombok.Data;
@Data
public class AmendmentFormFieldResponse {
private String fieldId;
private String label;
private boolean isSelected = false;
}

View File

@@ -0,0 +1,30 @@
package net.gepafin.tendermanagement.model.response;
import lombok.Data;
import net.gepafin.tendermanagement.entities.ApplicationEvaluationEntity;
import net.gepafin.tendermanagement.enums.ApplicationAmendmentRequestEnum;
import java.time.LocalDateTime;
import java.util.List;
@Data
public class ApplicationAmendmentRequestResponse {
private Long id;
private String callEmail;
private String note;
private Long responseDays;
private LocalDateTime startDate;
private boolean isSendNotification;
private boolean isSendEmail;
private Long protocolNumber;
private String callName;
private String beneficiaryName;
private List<AmendmentFormFieldResponse> formFields;
private List<ApplicationFormFieldResponseBean> applicationFormFields;
private Long applicationId;
private Long applicationEvaluationId;
private LocalDateTime expirationDate;
private List<CommunicationResponseBean> commentsList;
private String internalNote;
private ApplicationAmendmentRequestEnum status;
}

View File

@@ -0,0 +1,16 @@
package net.gepafin.tendermanagement.model.response;
import lombok.Data;
import net.gepafin.tendermanagement.entities.ApplicationAmendmentRequestEntity;
import java.util.List;
@Data
public class ApplicationAmendmentResponse {
private ApplicationAmendmentRequestEntity amendment;
private List<CommunicationResponseBean> commentsList;
public ApplicationAmendmentResponse(ApplicationAmendmentRequestEntity amendment, List<CommunicationResponseBean> comments) {
this.amendment = amendment;
this.commentsList = comments;
}
}

View File

@@ -0,0 +1,32 @@
package net.gepafin.tendermanagement.model.response;
import lombok.Data;
import net.gepafin.tendermanagement.enums.ApplicationEvaluationStatusTypeEnum;
import net.gepafin.tendermanagement.enums.ApplicationStatusTypeEnum;
import java.time.LocalDateTime;
import java.util.List;
@Data
public class ApplicationEvaluationResponse {
private Long id;
private Long applicationId;
private ApplicationStatusTypeEnum applicationStatus;
private Long assignedApplicationId;
private String note;
private ApplicationEvaluationStatusTypeEnum status;
private Long minScore;
private List<CriteriaResponse> criteria;
private List<ChecklistResponse> checklist;
private List<FieldResponse> files;
private LocalDateTime createdDate;
private LocalDateTime updatedDate;
private String beneficiary;
private Long protocolNumber;
private String callName;
private LocalDateTime submissionDate;
private LocalDateTime evaluationDate;
private LocalDateTime callEndDate;
}

View File

@@ -0,0 +1,11 @@
package net.gepafin.tendermanagement.model.response;
import lombok.AllArgsConstructor;
import lombok.Data;
@Data
public class ChecklistResponse {
private Long id;
private String label;
private Boolean valid;
}

View File

@@ -0,0 +1,33 @@
package net.gepafin.tendermanagement.model.response;
import lombok.Data;
import java.time.LocalDateTime;
@Data
public class CommunicationResponseBean {
private LocalDateTime commentedDate;
private String comment;
private String title;
private LocalDateTime createdDate;
private LocalDateTime updatedDate;
private Long amendmentId;
public CommunicationResponseBean(LocalDateTime commentedDate, String comment, String title, LocalDateTime createdDate, LocalDateTime updatedDate, Long amendmentId) {
this.commentedDate = commentedDate;
this.comment = comment;
this.title = title;
this.createdDate = createdDate;
this.updatedDate = updatedDate;
this.amendmentId = amendmentId;
}
public CommunicationResponseBean() {
}
}

View File

@@ -0,0 +1,12 @@
package net.gepafin.tendermanagement.model.response;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import lombok.Data;
@Data
public class CriteriaMappedField {
private String id;
private String fieldName;
private String fieldLabel;
private Object fieldValue;
}

View File

@@ -0,0 +1,15 @@
package net.gepafin.tendermanagement.model.response;
import lombok.Data;
import java.util.List;
@Data
public class CriteriaResponse {
private Long id;
private String label;
private Long score;
private Long maxScore;
private List<CriteriaMappedField> criteriaMappedFields;
private Boolean valid;
}

View File

@@ -0,0 +1,15 @@
package net.gepafin.tendermanagement.model.response;
import lombok.AllArgsConstructor;
import lombok.Data;
import java.util.List;
@Data
public class FieldResponse {
private String id;
private String label;
private Boolean valid;
private List<DocumentResponseBean> fileDetail ;
}

View File

@@ -0,0 +1,32 @@
package net.gepafin.tendermanagement.repositories;
import net.gepafin.tendermanagement.entities.ApplicationAmendmentRequestEntity;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import java.util.List;
import java.util.Optional;
public interface ApplicationAmendmentRequestRepository extends JpaRepository<ApplicationAmendmentRequestEntity,Long>, JpaSpecificationExecutor<ApplicationAmendmentRequestEntity> {
Optional<ApplicationAmendmentRequestEntity> findByIdAndIsDeletedFalse(Long id);
@Query(value = "SELECT ar.* FROM application_amendment_request ar " +
"JOIN application app ON ar.application_id = app.id " +
"WHERE app.user_id = :userId AND ar.is_deleted = false",
nativeQuery = true)
List<ApplicationAmendmentRequestEntity> findByUserId(@Param("userId") Long userId);
List<ApplicationAmendmentRequestEntity> findByIsDeletedFalse();
@Query(value = "SELECT amr FROM ApplicationAmendmentRequestEntity amr " + "WHERE amr.applicationEvaluationEntity.id = :id " + "AND amr.applicationEvaluationEntity.isDeleted = false")
ApplicationAmendmentRequestEntity findByApplicationEvaluationIdAndIsDeletedFalse(Long id);
// ApplicationAmendmentRequestEntity findByApplicationIdAndIsDeletedFalse(Long applicationId);
List<ApplicationAmendmentRequestEntity> findByApplicationIdAndIsDeletedFalse(Long applicationId);
List<ApplicationAmendmentRequestEntity> findByApplicationIdAndStatusInAndIsDeletedFalse(Long applicationId, List<String> statuses);
}

View File

@@ -0,0 +1,25 @@
package net.gepafin.tendermanagement.repositories;
import net.gepafin.tendermanagement.entities.ApplicationEvaluationEntity;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;
import java.util.List;
import java.util.Optional;
@Repository
public interface ApplicationEvaluationRepository extends JpaRepository<ApplicationEvaluationEntity, Long> {
Optional<ApplicationEvaluationEntity> findByApplicationIdAndIsDeletedFalse(Long applicationId);
Optional<ApplicationEvaluationEntity> findByIdAndIsDeletedFalse(Long id);
Optional<ApplicationEvaluationEntity> findByAssignedApplicationsEntity_IdAndIsDeletedFalse(Long assignedApplicationId);
Optional<ApplicationEvaluationEntity> findByApplicationIdAndAssignedApplicationsEntity_IdAndIsDeletedFalse(Long applicationId, Long assignedApplicationId);
Optional<ApplicationEvaluationEntity> findFirstByIsDeletedFalseOrderByCreatedDateDesc();
boolean existsByApplicationIdAndIsDeletedFalse(Long applicationId);
}

View File

@@ -23,5 +23,19 @@ public interface ApplicationFormFieldRepository extends JpaRepository<Applicatio
public List<ApplicationFormFieldEntity> findByFieldValueInAndApplicationFormApplicationId(
List<String> fieldValue, Long applicationId);
/**
* Find ApplicationFormField entity by Field ID, Form ID, and Application ID.
*
* @param fieldId The Field ID to search.
* @param formId The Form ID to search.
* @param applicationId The Application ID to search.
* @return Optional of ApplicationFormFieldEntity
*/
Optional<ApplicationFormFieldEntity> findByFieldIdAndApplicationFormIdAndApplicationFormApplicationId(
String fieldId, Long formId, Long applicationId);
public ApplicationFormFieldEntity findByFieldId(String FieldId);
Optional<ApplicationFormFieldEntity> findByApplicationFormIdAndFieldId(Long id, String fieldId);
}

View File

@@ -29,15 +29,15 @@ public interface ApplicationRepository extends JpaRepository<ApplicationEntity,
public Optional<ApplicationEntity> findByIdAndUserIdAndCallIdAndIsDeletedFalse(Long applicationId, Long userId,
Long callId);
@Query("SELECT COUNT(a) FROM ApplicationEntity a WHERE a.userId = :userId AND a.company.id = :companyId AND a.status = 'SUBMIT' ")
@Query("SELECT COUNT(a) FROM ApplicationEntity a WHERE a.userId = :userId AND a.company.id = :companyId AND a.status = 'SUBMIT' AND a.isDeleted = false")
Long countSubmittedApplicationsByUserId(@Param("userId") Long userId, @Param("companyId") Long companyId);
List<ApplicationEntity> findByCompanyIdAndUserIdAndIsDeletedFalse(Long companyId,Long userId);
@Query("SELECT COUNT(a) FROM ApplicationEntity a WHERE a.status = 'SUBMIT' And a.hubId = :hubId")
@Query("SELECT COUNT(a) FROM ApplicationEntity a WHERE a.status = 'SUBMIT' And a.hubId = :hubId AND a.isDeleted = false")
public Long countSubmittedApplicationsByHubId(@Param("hubId") Long hubId);
@Query("SELECT COUNT(a) FROM ApplicationEntity a WHERE a.status = 'DRAFT' And a.hubId = :hubId")
@Query("SELECT COUNT(a) FROM ApplicationEntity a WHERE a.status = 'DRAFT' And a.hubId = :hubId AND a.isDeleted = false")
public Long countDraftApplicationsByHubId(@Param("hubId") Long hubId);
@Query("SELECT a.call.id FROM ApplicationEntity a WHERE a.id = :id")

View File

@@ -2,12 +2,24 @@ package net.gepafin.tendermanagement.repositories;
import net.gepafin.tendermanagement.entities.AssignedApplicationsEntity;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;
import java.util.List;
import java.util.Optional;
@Repository
public interface AssignedApplicationsRepository extends JpaRepository<AssignedApplicationsEntity,Long>, JpaSpecificationExecutor<AssignedApplicationsEntity>{
Optional<AssignedApplicationsEntity> findByApplicationIdAndIsDeletedFalse(Long applicationId);
Optional<AssignedApplicationsEntity> findByIdAndIsDeletedFalse(Long id);
@Query("SELECT aa FROM AssignedApplicationsEntity aa WHERE aa.isDeleted = false " +
"AND (:applicationId IS NULL OR aa.application.id = :applicationId) " +
"AND (:id IS NULL OR aa.id = :id) ")
Optional<AssignedApplicationsEntity> findByApplicationIdOrIdAndIsDeletedFalse(
@Param("applicationId") Long applicationId,
@Param("id") Long id);
}

View File

@@ -22,6 +22,14 @@ public interface CallRepository extends JpaRepository<CallEntity, Long> {
// @Query("SELECT COALESCE(SUM(c.amount), 0) FROM CallEntity c WHERE c.status = 'PUBLISH'")
// BigDecimal findTotalAmountOfPublishedCalls();
@Query("SELECT c.name, COUNT(a.id) " +
"FROM CallEntity c LEFT JOIN ApplicationEntity a ON c.id = a.call.id " +
"GROUP BY c.name")
List<Object[]> findApplicationsPerCall();
@Query("SELECT c FROM CallEntity c JOIN ApplicationEntity a ON c.id = a.call.id WHERE a.id = :applicationId")
CallEntity findCallEntityByApplicationId(Long applicationId);
// @Query("SELECT c.name, COUNT(a.id) " +
// "FROM CallEntity c LEFT JOIN ApplicationEntity a ON c.id = a.call.id " +
// "GROUP BY c.name")

View File

@@ -17,4 +17,5 @@ public interface CallTargetAudienceChecklistRepository extends JpaRepository<Cal
Optional<CallTargetAudienceChecklistEntity> findById(@Param("id") Long id);
List<CallTargetAudienceChecklistEntity> findByCallIdAndLookupDataTypeAndIsDeletedFalse(Long id, String type);
List<CallTargetAudienceChecklistEntity> findByCallId(Long callId);
}

View File

@@ -0,0 +1,21 @@
package net.gepafin.tendermanagement.repositories;
import net.gepafin.tendermanagement.entities.CommunicationEntity;
import net.gepafin.tendermanagement.model.response.CommunicationResponseBean;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import java.util.List;
public interface CommunicationRepository extends JpaRepository<CommunicationEntity, Long> {
@Query("Select new net.gepafin.tendermanagement.model.response.CommunicationResponseBean(c.commentedDate, c.communicationComment, c.communicationTitle, c.createdDate, c.updatedDate, c.applicationAmendmentRequest.id) " +
"from CommunicationEntity c Where c.applicationAmendmentRequest.id = :applicationAmendmentRequestId")
List<CommunicationResponseBean> findCommentsByApplicationAmendmentRequestId(@Param("applicationAmendmentRequestId") Long amendmentRequestId);
@Query("SELECT new net.gepafin.tendermanagement.model.response.CommunicationResponseBean( " + "c.commentedDate, c.communicationComment, c.communicationTitle, c.createdDate, c" +
".updatedDate, c.applicationAmendmentRequest.id) " + "FROM CommunicationEntity c " + "WHERE c.applicationAmendmentRequest.id = :amendmentId AND c.isDeleted = false")
List<CommunicationResponseBean> findCommentDetailsByAmendmentId(@Param("amendmentId") Long amendmentId);
}

View File

@@ -13,14 +13,14 @@ import org.springframework.stereotype.Repository;
public interface DocumentRepository extends JpaRepository<DocumentEntity, Long> {
@Query("SELECT d FROM DocumentEntity d WHERE d.id = :id AND d.isDeleted = false")
Optional<DocumentEntity> findById(@Param("id") Long id);
Optional<DocumentEntity> findByIdAndNotDeleted(@Param("id") Long id);
// List<DocumentEntity> findBySourceIdAndTypeAndIsDeletedFalse(Long sourceId, String type);
// Optional<DocumentEntity> findByIdAndSourceIdAndIsDeletedFalse(Long id, Long sourceId);
List<DocumentEntity> findBySource(String source);
List<DocumentEntity> findBySourceIdAndSourceAndTypeAndIsDeletedFalse(Long sourceId, String source, String type);
Optional<DocumentEntity> findByIdAndSourceIdAndSourceAndIsDeletedFalse(Long id, Long sourceId, String source);

View File

@@ -16,4 +16,6 @@ public interface EvaluationCriteriaRepository extends JpaRepository<EvaluationCr
Optional<EvaluationCriteriaEntity> findById(@Param("id") Long id);
List<EvaluationCriteriaEntity> findByCallIdAndLookupDataTypeAndIsDeletedFalse(Long callId, String type);
List<EvaluationCriteriaEntity> findByCallId(Long callId);
}

View File

@@ -0,0 +1,61 @@
package net.gepafin.tendermanagement.scheduler;
import net.gepafin.tendermanagement.dao.EmailNotificationDao;
import net.gepafin.tendermanagement.entities.ApplicationAmendmentRequestEntity;
import net.gepafin.tendermanagement.entities.ApplicationEntity;
import net.gepafin.tendermanagement.entities.UserEntity;
import net.gepafin.tendermanagement.repositories.ApplicationAmendmentRequestRepository;
import net.gepafin.tendermanagement.repositories.ApplicationRepository;
import net.gepafin.tendermanagement.repositories.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import java.time.LocalDateTime;
import java.util.List;
@Component
public class NotificationScheduler {
@Autowired
UserRepository userRepository;
@Autowired
ApplicationRepository applicationRepository;
@Autowired
ApplicationAmendmentRequestRepository applicationAmendmentRepository;
@Autowired
EmailNotificationDao emailNotificationDao;
@Scheduled(cron = "0 0 1 * * ?")
void sendNotificationForRejectedApplicationToBeneficiary() {
List<ApplicationEntity> applicationsList = applicationRepository.findByIsDeletedFalse();
List<ApplicationAmendmentRequestEntity> amendmentRequestList = applicationAmendmentRepository.findByIsDeletedFalse();
LocalDateTime today = LocalDateTime.now();
for (ApplicationEntity application : applicationsList) {
ApplicationAmendmentRequestEntity amendmentRequest = getAmendmentRequestForApplication(application, amendmentRequestList);
if (amendmentRequest != null) {
LocalDateTime requestDate = amendmentRequest.getCreatedDate();
if (requestDate.plusDays(amendmentRequest.getResponseDays()).isAfter(today)) {
// Update the application status to REJECTED
application.setStatus("REJECTED");
applicationRepository.save(application);
amendmentRequest.setStatus("CLOSE");
applicationAmendmentRepository.save(amendmentRequest);
emailNotificationDao.sendApplicationFailureNotificationEmail(amendmentRequest);
}
}
}
}
private ApplicationAmendmentRequestEntity getAmendmentRequestForApplication(ApplicationEntity application, List<ApplicationAmendmentRequestEntity> amendmentRequestList) {
return amendmentRequestList.stream().filter(request -> request.getId().equals(application.getId())).findFirst().orElse(null);
}
}

View File

@@ -0,0 +1,29 @@
package net.gepafin.tendermanagement.service;
import jakarta.servlet.http.HttpServletRequest;
import net.gepafin.tendermanagement.entities.ApplicationAmendmentRequestEntity;
import net.gepafin.tendermanagement.enums.ApplicationAmendmentRequestEnum;
import net.gepafin.tendermanagement.enums.ApplicationStatusTypeEnum;
import net.gepafin.tendermanagement.model.request.ApplicationAmendmentRequest;
import net.gepafin.tendermanagement.model.request.ApplicationAmendmentRequestBean;
import net.gepafin.tendermanagement.model.request.CloseAmendmentRequest;
import net.gepafin.tendermanagement.model.response.ApplicationAmendmentRequestResponse;
import java.util.List;
public interface ApplicationAmendmentRequestService {
public ApplicationAmendmentRequestResponse getApplicationDataForAmendment(HttpServletRequest request,Long applicationEvaluationId);
public ApplicationAmendmentRequestResponse createApplicationAmendmentRequest(HttpServletRequest request, Long applicationEvaluationId , ApplicationAmendmentRequest applicationAmendmentRequest);
void deleteApplicationAmendmentRequest(HttpServletRequest request, Long id);
ApplicationAmendmentRequestResponse getApplicationAmendmentRequestById(HttpServletRequest request,Long id);
List<ApplicationAmendmentRequestResponse> getAllApplicationAmendmentRequest(HttpServletRequest request,Long userId);
ApplicationAmendmentRequestResponse updateApplicationAmendment(HttpServletRequest request, Long id, ApplicationAmendmentRequestBean applicationAmendmentRequestBean);
ApplicationAmendmentRequestEntity validateApplicationAmendmentRequest(Long applicationAmendmentId);
List<ApplicationAmendmentRequestResponse> getAllAmendmentRequestByBeneficiaryId(HttpServletRequest request,Long beneficiaryId);
ApplicationAmendmentRequestResponse closeAmendmentRequest(HttpServletRequest request, Long id, CloseAmendmentRequest closeAmendmentRequest);
ApplicationAmendmentRequestResponse extendResponseDays(HttpServletRequest request, Long id, Long addedDays);
public List<ApplicationAmendmentRequestResponse> getAmendmentByApplicationId(HttpServletRequest request,Long applicationId,List<ApplicationAmendmentRequestEnum> statuses);
public ApplicationAmendmentRequestResponse updateApplicationAmendmentStatus(HttpServletRequest request, Long applicationAmendmentId, ApplicationAmendmentRequestEnum status);
void sendReminderEmail(HttpServletRequest request,Long amendmentId);
}

View File

@@ -0,0 +1,19 @@
package net.gepafin.tendermanagement.service;
import jakarta.servlet.http.HttpServletRequest;
import net.gepafin.tendermanagement.entities.ApplicationEvaluationEntity;
import net.gepafin.tendermanagement.enums.ApplicationStatusForEvaluation;
import net.gepafin.tendermanagement.model.request.ApplicationEvaluationRequest;
import net.gepafin.tendermanagement.model.response.ApplicationEvaluationResponse;
public interface ApplicationEvaluationService {
ApplicationEvaluationResponse createOrUpdateApplicationEvaluation(
HttpServletRequest request,
ApplicationEvaluationRequest applicationEvaluationRequest,
Long assignedApplicationsId);
void deleteApplicationEvaluation(HttpServletRequest request,Long id);
ApplicationEvaluationResponse getApplicationEvaluationByApplicationId(HttpServletRequest request,Long applicationId,Long assignedApplicationId);
ApplicationEvaluationEntity validateApplicationEvaluation(Long applicationEvaluationId);
}

View File

@@ -22,11 +22,11 @@ public interface ApplicationService {
ApplicationGetResponseBean getApplicationByFormId(HttpServletRequest request, Long applicationId,Long formId);
List<ApplicationResponse> getAllApplications(HttpServletRequest request,Long callId, Long companyId,String status);
List<ApplicationResponse> getAllApplications(HttpServletRequest request,Long callId, Long companyId,List<ApplicationStatusTypeEnum> statusList);
void deleteApplication(HttpServletRequest request, Long applicationId);
public ApplicationEntity validateApplication(Long userId);
public ApplicationEntity validateApplication(Long applicationId);
public ApplicationResponse createApplication(HttpServletRequest request, Long companyId, ApplicationRequest applicationRequest, Long callId);

View File

@@ -1,6 +1,7 @@
package net.gepafin.tendermanagement.service;
import jakarta.servlet.http.HttpServletRequest;
import net.gepafin.tendermanagement.entities.AssignedApplicationsEntity;
import net.gepafin.tendermanagement.model.request.AssignedApplicationsRequest;
import net.gepafin.tendermanagement.model.response.AssignedApplicationsResponse;
@@ -16,4 +17,5 @@ public interface AssignedApplicationsService {
List<AssignedApplicationsResponse> getAllAssignedApplications(HttpServletRequest request, Long userId);
AssignedApplicationsResponse updateAssignedApplication(HttpServletRequest request, Long id, AssignedApplicationsRequest assignedApplicationsRequest);
AssignedApplicationsResponse getAssignedApplicationById(HttpServletRequest request, Long id);
AssignedApplicationsEntity validateAssignedApplication(Long assignedApplicationId);
}

View File

@@ -0,0 +1,15 @@
package net.gepafin.tendermanagement.service;
import net.gepafin.tendermanagement.model.request.CommunicationRequestBean;
import net.gepafin.tendermanagement.model.response.ApplicationAmendmentResponse;
import net.gepafin.tendermanagement.model.response.CommunicationResponseBean;
public interface CommunicationService {
CommunicationResponseBean addCommentToAmendmentRequest(CommunicationRequestBean communicationRequestBean, Long amendmentId);
String deleteComment(Long amendmentId, Long commentId);
CommunicationResponseBean updateAmendmentComment(CommunicationRequestBean communicationRequestBean, Long amendmentId, Long commentId);
ApplicationAmendmentResponse getAmendmentComments(Long id);
}

View File

@@ -0,0 +1,24 @@
package net.gepafin.tendermanagement.service.feignClient;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestParam;
import java.util.List;
@FeignClient(name = "mailgunClient", url = "${mailGun_base_url}")
public interface MailgunFeignClient {
@PostMapping("/v3/{domain}/messages")
ResponseEntity<Void> sendEmail(
@PathVariable("domain") String domain,
@RequestParam("from") String from,
@RequestParam("to") List<String> to,
@RequestParam("subject") String subject,
@RequestParam("html") String htmlBody,
@RequestHeader("Authorization") String authorizationHeader);
}

View File

@@ -0,0 +1,17 @@
package net.gepafin.tendermanagement.service.feignClient;
import feign.Headers;
import net.gepafin.tendermanagement.model.request.PecEmailRequest;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestHeader;
@FeignClient(name = "pecClient", url = "${api.pecUrl}")
public interface PecFeignClient {
@PostMapping("/send")
ResponseEntity<Void> sendEmail(@RequestHeader("Authorization") String token,
@RequestBody PecEmailRequest emailRequest);
}

View File

@@ -0,0 +1,153 @@
package net.gepafin.tendermanagement.service.impl;
import jakarta.servlet.http.HttpServletRequest;
import net.gepafin.tendermanagement.config.Translator;
import net.gepafin.tendermanagement.constants.GepafinConstant;
import net.gepafin.tendermanagement.dao.ApplicationAmendmentRequestDao;
import net.gepafin.tendermanagement.entities.ApplicationAmendmentRequestEntity;
import net.gepafin.tendermanagement.entities.ApplicationEvaluationEntity;
import net.gepafin.tendermanagement.entities.UserEntity;
import net.gepafin.tendermanagement.enums.ApplicationAmendmentRequestEnum;
import net.gepafin.tendermanagement.model.request.ApplicationAmendmentRequest;
import net.gepafin.tendermanagement.model.request.ApplicationAmendmentRequestBean;
import net.gepafin.tendermanagement.model.request.CloseAmendmentRequest;
import net.gepafin.tendermanagement.model.response.ApplicationAmendmentRequestResponse;
import net.gepafin.tendermanagement.repositories.ApplicationAmendmentRequestRepository;
import net.gepafin.tendermanagement.repositories.ApplicationEvaluationRepository;
import net.gepafin.tendermanagement.service.ApplicationAmendmentRequestService;
import net.gepafin.tendermanagement.util.Validator;
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.stereotype.Service;
import java.util.List;
import java.util.Optional;
@Service
public class ApplicationAmendmentRequestServiceImpl implements ApplicationAmendmentRequestService {
@Autowired
private Validator validator;
@Autowired
private ApplicationAmendmentRequestDao applicationAmendmentRequestDao;
@Autowired
private ApplicationAmendmentRequestRepository applicationAmendmentRequestRepository;
@Autowired
private ApplicationEvaluationRepository applicationEvaluationRepository;
@Override
public ApplicationAmendmentRequestResponse getApplicationDataForAmendment(HttpServletRequest request, Long applicationEvaluationId) {
Optional<ApplicationEvaluationEntity> entityOptional = applicationEvaluationRepository.findByIdAndIsDeletedFalse(applicationEvaluationId);
entityOptional.ifPresent(applicationEvaluationEntity -> validator.validatePreInstructor(request, applicationEvaluationEntity.getUserId()));
return applicationAmendmentRequestDao.getApplicationDataForAmendment(applicationEvaluationId);
}
@Override
public ApplicationAmendmentRequestResponse createApplicationAmendmentRequest(HttpServletRequest request, Long applicationEvaluationId , ApplicationAmendmentRequest applicationAmendmentRequest) {
Optional<ApplicationEvaluationEntity> entityOptional = applicationEvaluationRepository.findByIdAndIsDeletedFalse(applicationEvaluationId);
entityOptional.ifPresent(applicationEvaluationEntity -> validator.validatePreInstructor(request, applicationEvaluationEntity.getUserId()));
return applicationAmendmentRequestDao.createApplicationAmendmentRequest(applicationEvaluationId,applicationAmendmentRequest);
}
@Override
public void deleteApplicationAmendmentRequest(HttpServletRequest request, Long id) {
ApplicationAmendmentRequestEntity amendment = applicationAmendmentRequestRepository.findByIdAndIsDeletedFalse(id)
.orElseThrow(() -> new ResourceNotFoundException(Status.NOT_FOUND,
Translator.toLocale(GepafinConstant.APPLICATION_AMENDMENT_NOT_FOUND_MSG)));
Optional<ApplicationEvaluationEntity> entityOptional = applicationEvaluationRepository.findByIdAndIsDeletedFalse(amendment.getApplicationEvaluationEntity().getId());
if (entityOptional.isPresent()) {
UserEntity user = validator.validatePreInstructor(request, entityOptional.get().getUserId());
applicationAmendmentRequestDao.deleteById(id);
}
}
@Override
public ApplicationAmendmentRequestResponse getApplicationAmendmentRequestById(HttpServletRequest request,Long id) {
ApplicationAmendmentRequestEntity amendment = applicationAmendmentRequestRepository.findByIdAndIsDeletedFalse(id)
.orElseThrow(() -> new ResourceNotFoundException(Status.NOT_FOUND,
Translator.toLocale(GepafinConstant.APPLICATION_AMENDMENT_NOT_FOUND_MSG)));
Optional<ApplicationEvaluationEntity> entityOptional = applicationEvaluationRepository.findByIdAndIsDeletedFalse(amendment.getApplicationEvaluationEntity().getId());
if (entityOptional.isPresent()) {
UserEntity user = validator.validatePreInstructor(request, entityOptional.get().getUserId());
}
return applicationAmendmentRequestDao.getApplicationAmendmentRequestById(id);
}
@Override
public List<ApplicationAmendmentRequestResponse> getAllApplicationAmendmentRequest(HttpServletRequest request,Long userId) {
UserEntity user = validator.validatePreInstructor(request, userId);
return applicationAmendmentRequestDao.getAllApplicationAmendmentRequest(request,userId);
}
@Override
public ApplicationAmendmentRequestResponse updateApplicationAmendment(HttpServletRequest request, Long id, ApplicationAmendmentRequestBean applicationAmendmentRequestBean) {
ApplicationAmendmentRequestEntity amendment = applicationAmendmentRequestRepository.findByIdAndIsDeletedFalse(id)
.orElseThrow(() -> new ResourceNotFoundException(Status.NOT_FOUND,
Translator.toLocale(GepafinConstant.APPLICATION_AMENDMENT_NOT_FOUND_MSG)));
Optional<ApplicationEvaluationEntity> entityOptional = applicationEvaluationRepository.findByIdAndIsDeletedFalse(amendment.getApplicationEvaluationEntity().getId());
if (entityOptional.isPresent()) {
UserEntity user = validator.validatePreInstructor(request, entityOptional.get().getUserId());
}
return applicationAmendmentRequestDao.updateApplicationAmendment(id,applicationAmendmentRequestBean);
}
@Override
public ApplicationAmendmentRequestEntity validateApplicationAmendmentRequest(Long applicationAmendmentId) {
return applicationAmendmentRequestDao.validateApplicationAmendmentRequest(applicationAmendmentId);
}
@Override
public List<ApplicationAmendmentRequestResponse> getAllAmendmentRequestByBeneficiaryId(HttpServletRequest request, Long beneficiaryId) {
UserEntity user= validator.validateUser(request);
return applicationAmendmentRequestDao.getAllAmendmentRequestByBeneficiaryId(beneficiaryId);
}
@Override
public ApplicationAmendmentRequestResponse closeAmendmentRequest(HttpServletRequest request, Long id, CloseAmendmentRequest closeAmendmentRequest) {
ApplicationAmendmentRequestEntity amendment = applicationAmendmentRequestRepository.findByIdAndIsDeletedFalse(id)
.orElseThrow(() -> new ResourceNotFoundException(Status.NOT_FOUND,
Translator.toLocale(GepafinConstant.APPLICATION_AMENDMENT_NOT_FOUND_MSG)));
Optional<ApplicationEvaluationEntity> entityOptional = applicationEvaluationRepository.findByIdAndIsDeletedFalse(amendment.getApplicationEvaluationEntity().getId());
if (entityOptional.isPresent()) {
UserEntity user = validator.validatePreInstructor(request, entityOptional.get().getUserId());
}
return applicationAmendmentRequestDao.closeAmendmentRequest(id,closeAmendmentRequest);
}
@Override
public ApplicationAmendmentRequestResponse extendResponseDays(HttpServletRequest request, Long id, Long addedDays) {
UserEntity user= validator.validateUser(request);
return applicationAmendmentRequestDao.extendResponseDays(id, addedDays);
}
public List<ApplicationAmendmentRequestResponse> getAmendmentByApplicationId(HttpServletRequest request, Long applicationId,List<ApplicationAmendmentRequestEnum> statuses) {
return applicationAmendmentRequestDao.getAmendmentByApplicationId(request,applicationId,statuses);
}
@Override
public ApplicationAmendmentRequestResponse updateApplicationAmendmentStatus(HttpServletRequest request, Long applicationAmendmentId, ApplicationAmendmentRequestEnum status) {
return applicationAmendmentRequestDao.updateApplicationAmendmentStatus(applicationAmendmentId, status);
}
@Override
public void sendReminderEmail(HttpServletRequest request,Long amendmentId) {
ApplicationAmendmentRequestEntity amendment = applicationAmendmentRequestRepository.findByIdAndIsDeletedFalse(amendmentId)
.orElseThrow(() -> new ResourceNotFoundException(Status.NOT_FOUND,
Translator.toLocale(GepafinConstant.APPLICATION_AMENDMENT_NOT_FOUND_MSG)));
Optional<ApplicationEvaluationEntity> entityOptional = applicationEvaluationRepository.findByIdAndIsDeletedFalse(amendment.getApplicationEvaluationEntity().getId());
if (entityOptional.isPresent()) {
UserEntity user = validator.validatePreInstructor(request, entityOptional.get().getUserId());
applicationAmendmentRequestDao.sendReminderEmail(amendmentId);
}
}
}

View File

@@ -0,0 +1,98 @@
package net.gepafin.tendermanagement.service.impl;
import jakarta.servlet.http.HttpServletRequest;
import net.gepafin.tendermanagement.config.Translator;
import net.gepafin.tendermanagement.constants.GepafinConstant;
import net.gepafin.tendermanagement.dao.ApplicationEvaluationDao;
import net.gepafin.tendermanagement.entities.ApplicationEvaluationEntity;
import net.gepafin.tendermanagement.entities.AssignedApplicationsEntity;
import net.gepafin.tendermanagement.entities.UserEntity;
import net.gepafin.tendermanagement.enums.ApplicationStatusForEvaluation;
import net.gepafin.tendermanagement.model.request.ApplicationEvaluationRequest;
import net.gepafin.tendermanagement.model.response.ApplicationEvaluationResponse;
import net.gepafin.tendermanagement.repositories.AssignedApplicationsRepository;
import net.gepafin.tendermanagement.service.ApplicationEvaluationService;
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.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.Optional;
@Service
public class ApplicationEvaluationServiceImpl implements ApplicationEvaluationService {
@Autowired
private ApplicationEvaluationDao applicationEvaluationDao;
@Autowired
private Validator validator;
@Autowired
private AssignedApplicationsRepository assignedApplicationsRepository;
@Override
@Transactional(rollbackFor = Exception.class)
public ApplicationEvaluationResponse createOrUpdateApplicationEvaluation(
HttpServletRequest request,
ApplicationEvaluationRequest req,
Long assignedApplicationsId) {
AssignedApplicationsEntity assignedApplication = assignedApplicationsRepository
.findByIdAndIsDeletedFalse(assignedApplicationsId)
.orElseThrow(() -> new ResourceNotFoundException(
Status.NOT_FOUND,
Translator.toLocale(GepafinConstant.ASSIGNED_APPLICATION_NOT_FOUND_MSG)));
UserEntity user = validator.validatePreInstructor(request, assignedApplication.getUserId());
return applicationEvaluationDao.createOrUpdateApplicationEvaluation(user, req, assignedApplication.getId());
}
@Override
@Transactional(readOnly = true)
public ApplicationEvaluationResponse getApplicationEvaluationByApplicationId(
HttpServletRequest request, Long applicationId, Long assignedApplicationId) {
if (applicationId == null && assignedApplicationId == null) {
throw new CustomValidationException(
Status.BAD_REQUEST,
Translator.toLocale(GepafinConstant.EITHER_APPLICATION_OR_ASSIGNED_APPLICATION_ID_REQUIRED_MSG)
);
}
UserEntity preInstructor = validator.validateUser(request);
Optional<AssignedApplicationsEntity> assignedApplicationsOptional =
assignedApplicationsRepository.findByApplicationIdOrIdAndIsDeletedFalse(applicationId,assignedApplicationId);
if (assignedApplicationId != null) {
assignedApplicationsOptional = assignedApplicationsOptional.filter(a -> a.getId().equals(assignedApplicationId));
}
AssignedApplicationsEntity assignedApplications = assignedApplicationsOptional
.orElseThrow(() -> new CustomValidationException(
Status.BAD_REQUEST,
Translator.toLocale(GepafinConstant.ASSIGNED_APPLICATION_NOT_FOUND_WITH_ID_MSG)
));
validator.validatePreInstructor(request, assignedApplications.getUserId());
return applicationEvaluationDao.getApplicationEvaluationByApplicationId(
preInstructor,
assignedApplications.getApplication().getId(),
assignedApplications.getId()
);
}
@Override
@Transactional(rollbackFor = Exception.class)
public void deleteApplicationEvaluation(HttpServletRequest request,Long id) {
validator.getUserIdFromToken(request);
applicationEvaluationDao.deleteById(id);
}
@Override
public ApplicationEvaluationEntity validateApplicationEvaluation(Long applicationEvaluationId) {
return applicationEvaluationDao.validateApplicationEvaluation(applicationEvaluationId);
}
}

View File

@@ -56,8 +56,8 @@ public class ApplicationServiceImpl implements ApplicationService {
}
@Override
public ApplicationEntity validateApplication(Long id) {
return applicationDao.validateApplication(id);
public ApplicationEntity validateApplication(Long applicationId) {
return applicationDao.validateApplication(applicationId);
}
@Override
@@ -86,12 +86,12 @@ public class ApplicationServiceImpl implements ApplicationService {
@Override
@Transactional(readOnly = true)
public List<ApplicationResponse> getAllApplications(HttpServletRequest request, Long callId, Long companyId , String status) {
public List<ApplicationResponse> getAllApplications(HttpServletRequest request, Long callId, Long companyId ,List<ApplicationStatusTypeEnum> statusList) {
UserEntity userEntity = validator.validateUser(request);
if (companyId != null) {
validator.validateUserWithCompany(request, companyId);
}
return applicationDao.getAllApplications(userEntity, callId, companyId , status);
return applicationDao.getAllApplications(userEntity, callId, companyId , statusList);
}
@Override
@Transactional(rollbackFor = Exception.class)

View File

@@ -2,6 +2,7 @@ package net.gepafin.tendermanagement.service.impl;
import jakarta.servlet.http.HttpServletRequest;
import net.gepafin.tendermanagement.dao.AssignedApplicationsDao;
import net.gepafin.tendermanagement.entities.AssignedApplicationsEntity;
import net.gepafin.tendermanagement.entities.UserEntity;
import net.gepafin.tendermanagement.model.request.AssignedApplicationsRequest;
import net.gepafin.tendermanagement.model.response.AssignedApplicationsResponse;
@@ -54,4 +55,9 @@ public class AssignedApplicationsServiceImpl implements AssignedApplicationsServ
return assignedApplicationsDao.getAssignedApplicationById(request, id);
}
@Override
public AssignedApplicationsEntity validateAssignedApplication(Long assignedApplicationId) {
return assignedApplicationsDao.validateAssignedApplication(assignedApplicationId);
}
}

View File

@@ -79,6 +79,7 @@ public class AuthenticationService {
UserEntity user=null;
LoginAttemptEntity loginAttemptEntity = prepareLoginAttemptEntity(loginReq, request);
try {
log.info("Attempting login for email: {}", loginReq.getEmail());
String emailWithHubId = loginReq.getEmail()+":"+loginReq.getHubUuid();
UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(
@@ -94,11 +95,18 @@ public class AuthenticationService {
throw new ResourceNotFoundException(Status.NOT_FOUND,
Translator.toLocale(GepafinConstant.USER_NOT_FOUND_MSG));
}
loginAttemptEntity.setUserId(user.getId());
createSuccessLoginAttempt(loginAttemptEntity);
} catch (Exception e) {
log.info("Authentication failed for email: {}", loginReq.getEmail());
loginAttemptEntity.setUserId(user.getId());
createFailedLoginAttempt(loginAttemptEntity, e.getMessage());
throw e;
}
return getJWTTokenBean(user, loginReq.getRememberMe());
}
private LoginAttemptEntity prepareLoginAttemptEntity(LoginReq loginUserReq, HttpServletRequest request) {
public LoginAttemptEntity prepareLoginAttemptEntity(LoginReq loginUserReq, HttpServletRequest request) {
String ipAddress = Utils.getClientIpAddress(request);
String userAgent = request.getHeader("user-agent");
LoginAttemptEntity loginAttemptEntity = new LoginAttemptEntity();
@@ -109,11 +117,11 @@ public class AuthenticationService {
return loginAttemptEntity;
}
private void createSuccessLoginAttempt(LoginAttemptEntity loginAttemptEntity) {
public void createSuccessLoginAttempt(LoginAttemptEntity loginAttemptEntity) {
loginAttemptEntity.setResult(LoginAttemptResultEnum.SUCCESS.getValue());
loginAttemptDao.createLoginAttempt(loginAttemptEntity);
}
private void createFailedLoginAttempt(LoginAttemptEntity loginAttemptEntity, String errorMsg) {
public void createFailedLoginAttempt(LoginAttemptEntity loginAttemptEntity, String errorMsg) {
loginAttemptEntity.setResult(LoginAttemptResultEnum.FAILED.getValue());
loginAttemptEntity.setErrorMsg(errorMsg);
loginAttemptDao.createLoginAttempt(loginAttemptEntity);
@@ -184,13 +192,17 @@ public class AuthenticationService {
SecurityContextHolder.clearContext();
}
public JWTToken validateExistingUserToken(String token) {
public JWTToken validateExistingUserToken(HttpServletRequest request,String token) {
SamlResponseEntity samlResponseLogEntity = samlResponseLogRepository.findByToken(token);
if (samlResponseLogEntity == null) {
log.info("Invalid spid login token : {}", token);
throw new CustomValidationException(Status.VALIDATION_ERROR,
Translator.toLocale(GepafinConstant.INVALID_TOKEN_MSG));
}
LoginReq loginReq=new LoginReq();
Long userId=null;
LoginAttemptEntity loginAttemptEntity =new LoginAttemptEntity();
try {
HubEntity hub = hubService.getHubByUuid(samlResponseLogEntity.getHubUuid());
Map<String, List<Object>> userAttributes = Utils
.convertStringIntoMap(samlResponseLogEntity.getAuthenticationObject());
@@ -198,9 +210,18 @@ public class AuthenticationService {
UserEntity userEntity = userRepository.findByBeneficiaryCodiceFiscaleAndHubId(cf, hub.getId())
.orElseThrow(() -> new ResourceNotFoundException(Status.NOT_FOUND,
Translator.toLocale(GepafinConstant.USER_NOT_FOUND_MSG)));
userId=userEntity.getId();
//samlResponseLogRepository.delete(samlResponseLogEntity);
return getJWTTokenBean(userEntity, Boolean.TRUE);
loginReq.setEmail(userEntity.getEmail());
loginAttemptEntity = prepareLoginAttemptEntity(loginReq, request);
loginAttemptEntity.setUserId(userEntity.getId());
return getJWTTokenBean(userEntity, Boolean.TRUE);
} catch (Exception e) {
log.info("Authentication login failed for email: {}",e.getMessage());
loginAttemptEntity.setUserId(userId);
createFailedLoginAttempt(loginAttemptEntity, e.getMessage());
throw e;
}
}

View File

@@ -0,0 +1,43 @@
package net.gepafin.tendermanagement.service.impl;
import net.gepafin.tendermanagement.dao.CommunicationDao;
import net.gepafin.tendermanagement.model.request.CommunicationRequestBean;
import net.gepafin.tendermanagement.model.response.ApplicationAmendmentResponse;
import net.gepafin.tendermanagement.model.response.CommunicationResponseBean;
import net.gepafin.tendermanagement.service.CommunicationService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service
public class CommunicationServiceImpl implements CommunicationService {
@Autowired
CommunicationDao communicationDao;
@Override
@Transactional(rollbackFor = Exception.class)
public CommunicationResponseBean addCommentToAmendmentRequest(CommunicationRequestBean communicationRequestBean, Long amendmentId) {
return communicationDao.addCommentToAmendmentRequest(communicationRequestBean, amendmentId);
}
@Override
@Transactional(rollbackFor = Exception.class)
public String deleteComment(Long amendmentId, Long commentId) {
return communicationDao.deleteComment(amendmentId, commentId);
}
@Override
@Transactional(rollbackFor = Exception.class)
public CommunicationResponseBean updateAmendmentComment(CommunicationRequestBean communicationRequestBean, Long amendmentId, Long commentId) {
return communicationDao.updateAmendmentComment(communicationRequestBean, amendmentId, commentId);
}
@Override
@Transactional(readOnly = true)
public ApplicationAmendmentResponse getAmendmentComments(Long id) {
return communicationDao.getAmendmentComments(id);
}
}

View File

@@ -0,0 +1,11 @@
package net.gepafin.tendermanagement.service.impl;
import net.gepafin.tendermanagement.model.request.EmailConfig;
import java.util.List;
public interface EmailService {
void sendEmail(String subject, String body, List<String> recipientEmails, EmailConfig emailConfig);
}

View File

@@ -0,0 +1,24 @@
package net.gepafin.tendermanagement.service.impl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class EmailServiceFactory {
@Autowired
private PecEmailService pecEmailService;
@Autowired
private MailgunEmailService mailgunEmailService;
public EmailService getEmailService(String serviceType) {
if ("MAILGUN_SERVICE".equals(serviceType)) {
return mailgunEmailService;
} else if ("PEC_SERVICE".equals(serviceType)) {
return pecEmailService;
} else {
throw new IllegalArgumentException("Invalid email service type: " + serviceType);
}
}
}

View File

@@ -0,0 +1,49 @@
package net.gepafin.tendermanagement.service.impl;
import net.gepafin.tendermanagement.model.request.EmailConfig;
import net.gepafin.tendermanagement.service.feignClient.MailgunFeignClient;
import net.gepafin.tendermanagement.util.Validator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import java.util.Base64;
import java.util.List;
@Service
public class MailgunEmailService implements EmailService {
@Autowired
private MailgunFeignClient mailgunFeignClient;
@Value("${isMailSendingEnabled}")
private String isEmailSendingEnabled;
@Autowired
private Validator validator;
@Override
public void sendEmail(String subject, String body, List<String> recipientEmails, EmailConfig emailConfig) {
if (Boolean.FALSE.equals(Boolean.parseBoolean(isEmailSendingEnabled))) {
return;
}
String domain = emailConfig.getDomain();
String from = emailConfig.getSender();
String apiKey = emailConfig.getApiKey();
String authHeader = "Basic " + Base64.getEncoder().encodeToString(("api:" + apiKey).getBytes());
// Send email via Mailgun API
if (Boolean.FALSE.equals(validator.isTestProfileActivated())) {
ResponseEntity<Void> response = mailgunFeignClient.sendEmail(domain, from, List.of("rajeshkhoreupwork@gmail.com"), subject, body, authHeader);
if (!response.getStatusCode().is2xxSuccessful()) {
throw new RuntimeException("Failed to send email via Mailgun: " + response.getStatusCode());
}
}
}
}

View File

@@ -0,0 +1,58 @@
package net.gepafin.tendermanagement.service.impl;
import lombok.extern.slf4j.Slf4j;
import net.gepafin.tendermanagement.model.request.EmailConfig;
import net.gepafin.tendermanagement.model.request.PecEmailRequest;
import net.gepafin.tendermanagement.service.feignClient.PecFeignClient;
import net.gepafin.tendermanagement.util.Validator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import java.util.List;
@Slf4j
@Service
public class PecEmailService implements EmailService {
private final PecFeignClient pecFeignClient;
public PecEmailService(PecFeignClient pecFeignClient) {
this.pecFeignClient = pecFeignClient;
}
@Value("${isMailSendingEnabled}")
private String isEmailSendingEnabled;
@Autowired
private Validator validator;
@Override
public void sendEmail(String subject, String body, List<String> recipientEmails, EmailConfig emailConfig) {
if (Boolean.FALSE.equals(Boolean.parseBoolean(isEmailSendingEnabled))) {
return;
}
PecEmailRequest emailRequest = new PecEmailRequest();
emailRequest.setSender(emailConfig.getSender());
emailRequest.setRecipient(List.of("rajeshkhoreupwork@gmail.com"));
emailRequest.setSubject(subject);
emailRequest.setBody(body);
emailRequest.setUsername(emailConfig.getUsername());
emailRequest.setPassword(emailConfig.getPassword());
String authToken = emailConfig.getAuthToken();
if (Boolean.FALSE.equals(validator.isTestProfileActivated())) {
ResponseEntity<Void> response = pecFeignClient.sendEmail("Bearer " + authToken, emailRequest);
log.info("Mail response status: {}, headers: {}, body: {}", response.getStatusCode(), response.getHeaders(), response.getBody());
if (!response.getStatusCode().is2xxSuccessful()) {
throw new RuntimeException("Failed to send email via PEC: " + response.getStatusCode());
}
}
}
}

View File

@@ -103,7 +103,7 @@ public class UserServiceImpl implements UserService {
@Override
@Transactional(rollbackFor = Exception.class)
public JWTToken validateExistingUserToken(HttpServletRequest request, String token) {
return userDao.validateExistingUserToken(token);
return userDao.validateExistingUserToken(request,token);
}
@Override
public UserSamlResponse validateNewUserToken(HttpServletRequest request, String token) {

View File

@@ -108,4 +108,12 @@ public class DateTimeUtil {
return null;
}
}
public static String formatCreatedDate(LocalDateTime createdDate) {
if (createdDate == null) {
return "";
}
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd/MM/yyyy");
return createdDate.format(formatter);
}
}

View File

@@ -1,5 +1,6 @@
package net.gepafin.tendermanagement.util;
import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.Type;
import java.nio.charset.StandardCharsets;
@@ -19,6 +20,7 @@ import java.util.stream.Collectors;
import com.itextpdf.styledxmlparser.jsoup.Jsoup;
import jakarta.servlet.http.HttpServletRequest;
import net.gepafin.tendermanagement.constants.GepafinConstant;
import org.apache.commons.collections4.MapUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -39,6 +41,10 @@ import net.gepafin.tendermanagement.web.rest.api.errors.FeignClientNotFoundExcep
import net.gepafin.tendermanagement.web.rest.api.errors.FeignClientUnauthorizedException;
import net.gepafin.tendermanagement.web.rest.api.errors.FeignClientValidationException;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import static org.apache.commons.lang3.StringUtils.isEmpty;
@@ -318,6 +324,23 @@ public class Utils {
return new StringTokenizer(header, ",").nextToken().trim();
}
public static <T> List<T> convertJsonToList(String json, TypeReference<List<T>> typeRef) {
ObjectMapper objectMapper = new ObjectMapper();
try {
return objectMapper.readValue(json, typeRef);
} catch (IOException e) {
e.printStackTrace();
return Collections.emptyList();
}
}
public static String convertObjectToJson(Object obj) {
try {
if(obj == null){return null;}
return new ObjectMapper().writeValueAsString(obj);
} catch (JsonProcessingException e) {
log.error("Failed to convert object to JSON: {}", e.getMessage(), e);
throw new RuntimeException("Failed to convert object to JSON", e);}}
public static String replaceSpacesWithUnderscores(String content) {
if (content == null) {
@@ -449,4 +472,47 @@ public class Utils {
return sanitizedInput.matches(wholeNumberPattern);
}
public static String encryptCredential(String value) {
try {
if(Boolean.FALSE.equals(isEmpty(value))) {
IvParameterSpec iv = new IvParameterSpec(GepafinConstant.ENCRYPT_INIT_VECTOR.getBytes("UTF-8"));
SecretKeySpec skeySpec = new SecretKeySpec(Base64.getDecoder().decode(GepafinConstant.ENCRYPT_KEY), "AES");
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");
cipher.init(Cipher.ENCRYPT_MODE, skeySpec, iv);
byte[] encrypted = cipher.doFinal(value.getBytes());
return Base64.getEncoder().encodeToString(encrypted);
}
} catch (Exception ex) {
log.error("Exception occured while encrypt credential :- {0}", ex);
}
return null;
}
public static String decryptCredential(String encrypted) {
try {
if(Boolean.FALSE.equals(isEmpty(encrypted))) {
IvParameterSpec iv = new IvParameterSpec(GepafinConstant.ENCRYPT_INIT_VECTOR.getBytes("UTF-8"));
SecretKeySpec skeySpec = new SecretKeySpec(Base64.getDecoder().decode(GepafinConstant.ENCRYPT_KEY), "AES");
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");
cipher.init(Cipher.DECRYPT_MODE, skeySpec, iv);
byte[] original = cipher.doFinal(Base64.getDecoder().decode(encrypted));
return new String(original);
}
} catch (Exception ex) {
// log.error("Exception occured while decrypt credential :- {0}", ex);
return encrypted;
}
return null;
}
}

View File

@@ -135,11 +135,10 @@ public class Validator {
return requestedUser;
}
private Long getUserIdFromToken(HttpServletRequest request) {
public Long getUserIdFromToken(HttpServletRequest request) {
Map<String, Object> userInfo= tokenProvider.getUserInfoAndUserIdFromToken(request);
return Long.parseLong(userInfo.get("userId").toString());
}
public CallEntity validateUserWithCall(UserEntity user, Long callId) {
CallEntity callEntity = callService.validateCall(callId);
if(Boolean.FALSE.equals(user.getHub().getId().equals(callEntity.getHub().getId()))) {
@@ -152,6 +151,11 @@ public class Validator {
String[] activeProfiles = environment.getActiveProfiles();
return Arrays.stream(activeProfiles).anyMatch("production"::equals);
}
public Boolean isTestProfileActivated() {
String[] activeProfiles = environment.getActiveProfiles();
return Arrays.stream(activeProfiles).anyMatch("test"::equals);
}
public UserEntity validatePreInstructor(HttpServletRequest request, Long preInstructorUserId) {
UserEntity preInstructorUser = userService.validateUser(preInstructorUserId);

View File

@@ -0,0 +1,191 @@
package net.gepafin.tendermanagement.web.rest.api;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.ExampleObject;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.validation.Valid;
import net.gepafin.tendermanagement.enums.ApplicationAmendmentRequestEnum;
import net.gepafin.tendermanagement.enums.ApplicationStatusTypeEnum;
import net.gepafin.tendermanagement.model.request.ApplicationAmendmentRequest;
import net.gepafin.tendermanagement.model.request.ApplicationAmendmentRequestBean;
import net.gepafin.tendermanagement.model.request.CloseAmendmentRequest;
import net.gepafin.tendermanagement.model.response.ApplicationAmendmentRequestResponse;
import net.gepafin.tendermanagement.model.response.ApplicationResponse;
import net.gepafin.tendermanagement.model.util.Response;
import net.gepafin.tendermanagement.web.rest.api.errors.ErrorConstants;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@Validated
public interface ApplicationAmendmentRequestApi {
@Operation(summary = "Api to get application data for the Amendment process",
responses = {
@ApiResponse(responseCode = "200", description = "OK"),
@ApiResponse(responseCode = "404", description = "Not Found", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = {
@ExampleObject(value = ErrorConstants.NOTFOUND_ERROR_EXAMPLE) })),
@ApiResponse(responseCode = "401", description = "Unauthorized", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = {
@ExampleObject(value = ErrorConstants.UNAUTHORIZED_ERROR_EXAMPLE) })),
@ApiResponse(responseCode = "400", description = "Bad Request", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = {
@ExampleObject(value = ErrorConstants.BADREQUEST_ERROR_EXAMPLE) })) })
@GetMapping(value = "applicationEvaluation/{id}", produces = "application/json")
ResponseEntity<Response<ApplicationAmendmentRequestResponse>> getApplicationDataForAmendment(HttpServletRequest request, @Parameter(description = "The Application Evaluation id", required = true) @PathVariable(value = "id", required = true) Long applicationEvaluationId);
@Operation(summary = "Api to submit the application data for the Amendment",
responses = {
@ApiResponse(responseCode = "200", description = "OK"),
@ApiResponse(responseCode = "404", description = "Not Found", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = {
@ExampleObject(value = ErrorConstants.NOTFOUND_ERROR_EXAMPLE) })),
@ApiResponse(responseCode = "401", description = "Unauthorized", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = {
@ExampleObject(value = ErrorConstants.UNAUTHORIZED_ERROR_EXAMPLE) })),
@ApiResponse(responseCode = "400", description = "Bad Request", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = {
@ExampleObject(value = ErrorConstants.BADREQUEST_ERROR_EXAMPLE) })) })
@PostMapping(value = "", produces = "application/json")
ResponseEntity<Response<ApplicationAmendmentRequestResponse>> createApplicationAmendmentRequest(HttpServletRequest request,
@Parameter(description = "Application Evaluation Id", required = true) @RequestParam Long applicationEvaluationId,
@Valid @RequestBody ApplicationAmendmentRequest applicationAmendmentRequest);
@Operation(summary = "Api to delete application amendment request",
responses = {
@ApiResponse(responseCode = "200", description = "OK"),
@ApiResponse(responseCode = "404", description = "Not Found", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = {
@ExampleObject(value = ErrorConstants.NOTFOUND_ERROR_EXAMPLE) })),
@ApiResponse(responseCode = "401", description = "Unauthorized", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = {
@ExampleObject(value = ErrorConstants.UNAUTHORIZED_ERROR_EXAMPLE) })),
@ApiResponse(responseCode = "400", description = "Bad Request", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = {
@ExampleObject(value = ErrorConstants.BADREQUEST_ERROR_EXAMPLE) })) })
@DeleteMapping(value = "/{id}")
ResponseEntity<Response<Void>> deleteApplicationAmendmentRequest(HttpServletRequest request,
@Parameter(description = "The application Amendment id", required = true) @PathVariable("id") Long id);
@Operation(summary = "Api to get an application amendment by id",
responses = {
@ApiResponse(responseCode = "200", description = "OK"),
@ApiResponse(responseCode = "404", description = "Not Found", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = {
@ExampleObject(value = ErrorConstants.NOTFOUND_ERROR_EXAMPLE) })),
@ApiResponse(responseCode = "401", description = "Unauthorized", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = {
@ExampleObject(value = ErrorConstants.UNAUTHORIZED_ERROR_EXAMPLE) })),
@ApiResponse(responseCode = "400", description = "Bad Request", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = {
@ExampleObject(value = ErrorConstants.BADREQUEST_ERROR_EXAMPLE) })) })
@GetMapping(value = "", produces = "application/json")
ResponseEntity<Response<ApplicationAmendmentRequestResponse>> getApplicationAmendmentRequestById(HttpServletRequest request,@Parameter(description = "The application amendment id", required = true) @RequestParam(value = "id", required = true) Long id);
@Operation(summary = "Api to get all applications amendment request by preInstructor user Id",
responses = {
@ApiResponse(responseCode = "200", description = "OK"),
@ApiResponse(responseCode = "404", description = "Not Found", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = {
@ExampleObject(value = ErrorConstants.NOTFOUND_ERROR_EXAMPLE) })),
@ApiResponse(responseCode = "401", description = "Unauthorized", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = {
@ExampleObject(value = ErrorConstants.UNAUTHORIZED_ERROR_EXAMPLE) })),
@ApiResponse(responseCode = "400", description = "Bad Request", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = {
@ExampleObject(value = ErrorConstants.BADREQUEST_ERROR_EXAMPLE) })) })
@GetMapping(value = "/user/{id}", produces = "application/json")
ResponseEntity<Response<List<ApplicationAmendmentRequestResponse>>> getAllApplicationAmendmentRequest(HttpServletRequest request,
@Parameter(description = "The User ID", required = false) @PathVariable(value = "id",required = false) Long userId);
@Operation(summary = "Api to update application amendment",
responses = {
@ApiResponse(responseCode = "200", description = "OK"),
@ApiResponse(responseCode = "404", description = "Not Found", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = {
@ExampleObject(value = ErrorConstants.NOTFOUND_ERROR_EXAMPLE) })),
@ApiResponse(responseCode = "401", description = "Unauthorized", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = {
@ExampleObject(value = ErrorConstants.UNAUTHORIZED_ERROR_EXAMPLE) })),
@ApiResponse(responseCode = "400", description = "Bad Request", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = {
@ExampleObject(value = ErrorConstants.BADREQUEST_ERROR_EXAMPLE) }))
})
@PutMapping(value = "/{id}", produces = MediaType.APPLICATION_JSON_VALUE, consumes = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<Response<ApplicationAmendmentRequestResponse>> updateApplicationAmendment(HttpServletRequest request,
@Parameter(description = "The Application Amendment id", required = true) @PathVariable("id") Long id,
@Parameter(description = "Assigned Application request object", required = true) @Valid @RequestBody ApplicationAmendmentRequestBean applicationAmendmentRequestBean);
@Operation(summary = "Api to get all applications amendment request by beneficary user Id",
responses = {
@ApiResponse(responseCode = "200", description = "OK"),
@ApiResponse(responseCode = "404", description = "Not Found", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = {
@ExampleObject(value = ErrorConstants.NOTFOUND_ERROR_EXAMPLE) })),
@ApiResponse(responseCode = "401", description = "Unauthorized", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = {
@ExampleObject(value = ErrorConstants.UNAUTHORIZED_ERROR_EXAMPLE) })),
@ApiResponse(responseCode = "400", description = "Bad Request", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = {
@ExampleObject(value = ErrorConstants.BADREQUEST_ERROR_EXAMPLE) })) })
@GetMapping(value = "/beneficiary/user/{id}", produces = "application/json")
ResponseEntity<Response<List<ApplicationAmendmentRequestResponse>>> getAllAmendmentRequestByBeneficiaryId(HttpServletRequest request,
@Parameter(description = "Id", required = false) @PathVariable(value = "id",required = false) Long beneficiaryId);
@Operation(summary = "Api to extend response days for an amendment request",
responses = {
@ApiResponse(responseCode = "200", description = "OK"),
@ApiResponse(responseCode = "404", description = "Not Found", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = {
@ExampleObject(value = ErrorConstants.NOTFOUND_ERROR_EXAMPLE) })),
@ApiResponse(responseCode = "401", description = "Unauthorized", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = {
@ExampleObject(value = ErrorConstants.UNAUTHORIZED_ERROR_EXAMPLE) })),
@ApiResponse(responseCode = "400", description = "Bad Request", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = {
@ExampleObject(value = ErrorConstants.BADREQUEST_ERROR_EXAMPLE) }))
})
@PutMapping(value = "/{id}/extendExpiration", produces = MediaType.APPLICATION_JSON_VALUE)
ResponseEntity<Response<ApplicationAmendmentRequestResponse>> extendResponseDays(
HttpServletRequest request,
@Parameter( required = true) @PathVariable("id") Long id,
@Parameter( required = true) @RequestParam("extendedDays") Long extendedDays);
@Operation(summary = "Api to close the application amendment request",
responses = {
@ApiResponse(responseCode = "200", description = "OK"),
@ApiResponse(responseCode = "404", description = "Not Found", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = {
@ExampleObject(value = ErrorConstants.NOTFOUND_ERROR_EXAMPLE) })),
@ApiResponse(responseCode = "401", description = "Unauthorized", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = {
@ExampleObject(value = ErrorConstants.UNAUTHORIZED_ERROR_EXAMPLE) })),
@ApiResponse(responseCode = "400", description = "Bad Request", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = {
@ExampleObject(value = ErrorConstants.BADREQUEST_ERROR_EXAMPLE) })) })
@PutMapping(value = "", produces = "application/json")
ResponseEntity<Response<ApplicationAmendmentRequestResponse>> closeApplicationAmendmentRequest(HttpServletRequest request,
@Parameter(description = "The Application Amendment id", required = true) @RequestParam("id") Long id,
@Valid @RequestBody CloseAmendmentRequest closeAmendmentRequest);
@Operation(summary = "Api to get amendment process list by application id",
responses = {
@ApiResponse(responseCode = "200", description = "OK"),
@ApiResponse(responseCode = "404", description = "Not Found", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = {
@ExampleObject(value = ErrorConstants.NOTFOUND_ERROR_EXAMPLE) })),
@ApiResponse(responseCode = "401", description = "Unauthorized", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = {
@ExampleObject(value = ErrorConstants.UNAUTHORIZED_ERROR_EXAMPLE) })),
@ApiResponse(responseCode = "400", description = "Bad Request", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = {
@ExampleObject(value = ErrorConstants.BADREQUEST_ERROR_EXAMPLE) })) })
@GetMapping(value = "application/{applicationId}", produces = "application/json")
ResponseEntity<Response<List<ApplicationAmendmentRequestResponse>>> getAmendmentByApplicationId(HttpServletRequest request, @Parameter(description = "The Application id", required = true) @PathVariable(value = "applicationId", required = true) Long applicationId,
@Parameter(description = "List of amendment statuses") @RequestParam(value = "statuses", required = false) List<ApplicationAmendmentRequestEnum> statuses
);
@Operation(summary = "Api to update application amendment status",
responses = {
@ApiResponse(responseCode = "200", description = "OK"),
@ApiResponse(responseCode = "404", description = "Not Found", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = {
@ExampleObject(value = ErrorConstants.NOTFOUND_ERROR_EXAMPLE) })),
@ApiResponse(responseCode = "401", description = "Unauthorized", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = {
@ExampleObject(value = ErrorConstants.UNAUTHORIZED_ERROR_EXAMPLE) })),
@ApiResponse(responseCode = "400", description = "Bad Request", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = {
@ExampleObject(value = ErrorConstants.BADREQUEST_ERROR_EXAMPLE) })) })
@PutMapping(value = "/{applicationAmendmentId}/status", produces = { "application/json" })
ResponseEntity<Response<ApplicationAmendmentRequestResponse>> updateApplicationAmendmentStatus(HttpServletRequest request,
@Parameter(description = "The application amendment id", required = true) @PathVariable("applicationAmendmentId") Long applicationAmendmentId,
@Parameter(description = "status", required = true)@RequestParam(value = "status", required = true) ApplicationAmendmentRequestEnum status);
@Operation(summary = "Send reminder email for the specified amendment",
responses = {
@ApiResponse(responseCode = "200", description = "Email sent successfully"),
@ApiResponse(responseCode = "404", description = "Amendment not found", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = {
@ExampleObject(value = ErrorConstants.NOTFOUND_ERROR_EXAMPLE) })),
@ApiResponse(responseCode = "400", description = "Bad Request", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = {
@ExampleObject(value = ErrorConstants.BADREQUEST_ERROR_EXAMPLE) })),
@ApiResponse(responseCode = "401", description = "Unauthorized", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = {
@ExampleObject(value = ErrorConstants.UNAUTHORIZED_ERROR_EXAMPLE) }))
})
@PostMapping(value = "/{amendmentId}/reminder", produces = MediaType.APPLICATION_JSON_VALUE)
ResponseEntity<Response<Void>> sendReminderEmail(HttpServletRequest request,
@Parameter( required = true)
@PathVariable(value = "amendmentId") Long amendmentId);
}

View File

@@ -72,7 +72,7 @@ public interface ApplicationApi {
ResponseEntity<Response<List<ApplicationResponse>>> getAllApplications(HttpServletRequest request,
@Parameter(description = "The call id", required = false) @RequestParam(value = "callId", required = false) Long callId,
@Parameter(description = "The company id", required = false) @RequestParam(value = "companyId", required = false) Long companyId,
@Parameter(description = "Application status" ,required = false) @RequestParam(value = "status",required = false)String status);
@Parameter(description = "Application statuses" ,required = false) @RequestParam(value = "statuses",required = false) List<ApplicationStatusTypeEnum> statusList);
@Operation(summary = "Api to delete application",
responses = {

View File

@@ -0,0 +1,57 @@
package net.gepafin.tendermanagement.web.rest.api;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.ExampleObject;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.validation.Valid;
import net.gepafin.tendermanagement.enums.ApplicationStatusForEvaluation;
import net.gepafin.tendermanagement.model.request.ApplicationEvaluationRequest;
import net.gepafin.tendermanagement.model.response.ApplicationEvaluationResponse;
import net.gepafin.tendermanagement.model.util.Response;
import net.gepafin.tendermanagement.web.rest.api.errors.ErrorConstants;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
public interface ApplicationEvaluationApi {
@Operation(summary = "API to create or update ApplicationEvaluation",
responses = {
@ApiResponse(responseCode = "200", description = "OK"),
@ApiResponse(responseCode = "404", description = "Not Found", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = {
@ExampleObject(value = ErrorConstants.NOTFOUND_ERROR_EXAMPLE) })),
@ApiResponse(responseCode = "400", description = "Bad Request", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = {
@ExampleObject(value = ErrorConstants.BADREQUEST_ERROR_EXAMPLE) }))
})
@PutMapping(value = "/{assignedApplicationsId}", produces = MediaType.APPLICATION_JSON_VALUE, consumes = MediaType.APPLICATION_JSON_VALUE)
ResponseEntity<Response<ApplicationEvaluationResponse>> createOrUpdateApplicationEvaluation(
HttpServletRequest request,
@Parameter(description = "Assigned Application ID", required = true) @PathVariable("assignedApplicationsId") Long assignedApplicationsId,
@Parameter(description = "Application Evaluation Request Body", required = true) @Valid @RequestBody ApplicationEvaluationRequest evaluationRequest);
@Operation(summary = "API to get ApplicationEvaluation data for evaluation process",
responses = {
@ApiResponse(responseCode = "200", description = "OK"),
@ApiResponse(responseCode = "404", description = "Not Found", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = {
@ExampleObject(value = ErrorConstants.NOTFOUND_ERROR_EXAMPLE) }))
})
@GetMapping(value = "/application", produces = MediaType.APPLICATION_JSON_VALUE)
ResponseEntity<Response<ApplicationEvaluationResponse>> getApplicationEvaluationByApplicationId(
HttpServletRequest request,
@Parameter(required = false) @RequestParam(value = "applicationId", required = false) Long applicationId,
@Parameter( required = false) @RequestParam(value = "assignedApplicationId", required = false) Long assignedApplicationId);
@Operation(summary = "API to delete ApplicationEvaluation",
responses = {
@ApiResponse(responseCode = "200", description = "OK"),
@ApiResponse(responseCode = "404", description = "Not Found", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = {
@ExampleObject(value = ErrorConstants.NOTFOUND_ERROR_EXAMPLE) }))
})
@DeleteMapping(value = "/{id}")
ResponseEntity<Response<Void>> deleteApplicationEvaluation(HttpServletRequest request,
@Parameter( required = true) @PathVariable("id") Long id);
}

View File

@@ -0,0 +1,69 @@
package net.gepafin.tendermanagement.web.rest.api;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.ExampleObject;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import jakarta.servlet.http.HttpServletRequest;
import net.gepafin.tendermanagement.model.request.CommunicationRequestBean;
import net.gepafin.tendermanagement.model.response.ApplicationAmendmentResponse;
import net.gepafin.tendermanagement.model.response.CommunicationResponseBean;
import net.gepafin.tendermanagement.model.util.Response;
import net.gepafin.tendermanagement.web.rest.api.errors.ErrorConstants;
import org.springframework.data.repository.query.Param;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
@Validated
public interface CommunicationApi {
@Operation(summary = "Api to create communication amendment comment", responses = { @ApiResponse(responseCode = "200", description = "OK"),
@ApiResponse(responseCode = "404", description = "Not Found", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = {
@ExampleObject(value = ErrorConstants.NOTFOUND_ERROR_EXAMPLE) })),
@ApiResponse(responseCode = "401", description = "Unauthorized", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = {
@ExampleObject(value = ErrorConstants.UNAUTHORIZED_ERROR_EXAMPLE) })),
@ApiResponse(responseCode = "400", description = "Bad Request", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = {
@ExampleObject(value = ErrorConstants.BADREQUEST_ERROR_EXAMPLE) })) })
@PostMapping(value = "/{amendmentId}", produces = { "application/json" })
ResponseEntity<Response<CommunicationResponseBean>> addCommentToAmendmentRequest(HttpServletRequest request,
@RequestBody @Parameter CommunicationRequestBean communicationResponseBean, @PathVariable(value = "amendmentId") Long amendmentId);
@Operation(summary = "API to Get Amendment Request Comment", responses = { @ApiResponse(responseCode = "200", description = "OK"),
@ApiResponse(responseCode = "404", description = "Not Found", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = @ExampleObject(value =
ErrorConstants.NOTFOUND_ERROR_EXAMPLE))),
@ApiResponse(responseCode = "401", description = "Unauthorized", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = @ExampleObject(value =
ErrorConstants.UNAUTHORIZED_ERROR_EXAMPLE))),
@ApiResponse(responseCode = "400", description = "Bad Request", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = @ExampleObject(value =
ErrorConstants.BADREQUEST_ERROR_EXAMPLE))) })
@GetMapping(value = "/{amendmentId}", produces = "application/json")
public ResponseEntity<Response<ApplicationAmendmentResponse>> getAmendmentComments(@PathVariable(value = "amendmentId") Long amendmentId);
@Operation(summary = "Api to update communication comments", responses = { @ApiResponse(responseCode = "200", description = "OK"),
@ApiResponse(responseCode = "404", description = "Not Found", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = {
@ExampleObject(value = ErrorConstants.NOTFOUND_ERROR_EXAMPLE) })),
@ApiResponse(responseCode = "401", description = "Unauthorized", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = {
@ExampleObject(value = ErrorConstants.UNAUTHORIZED_ERROR_EXAMPLE) })),
@ApiResponse(responseCode = "400", description = "Bad Request", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = {
@ExampleObject(value = ErrorConstants.BADREQUEST_ERROR_EXAMPLE) })) })
@PutMapping(value = "/{amendmentId}/{commentId}", produces = { "application/json" })
ResponseEntity<Response<CommunicationResponseBean>> updateCommunicationAmendment(HttpServletRequest request,
@RequestBody @Parameter CommunicationRequestBean communicationResponseBean, @PathVariable(value = "amendmentId") Long amendmentId, @PathVariable(value = "commentId") Long commentId);
@Operation(summary = "Api to delete communication comments", responses = { @ApiResponse(responseCode = "200", description = "OK"),
@ApiResponse(responseCode = "404", description = "Not Found", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = {
@ExampleObject(value = ErrorConstants.NOTFOUND_ERROR_EXAMPLE) })),
@ApiResponse(responseCode = "401", description = "Unauthorized", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = {
@ExampleObject(value = ErrorConstants.UNAUTHORIZED_ERROR_EXAMPLE) })),
@ApiResponse(responseCode = "400", description = "Bad Request", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = {
@ExampleObject(value = ErrorConstants.BADREQUEST_ERROR_EXAMPLE) })) })
@DeleteMapping(value = "/{amendmentId}/{commentId}", produces = { "application/json" })
ResponseEntity<Response<String>> deleteApplicationAmendmentComment(HttpServletRequest request, @PathVariable(value = "amendmentId") Long amendmentId,
@Param(value = "commentId") Long commentId);
}

View File

@@ -51,6 +51,8 @@ public class GlobalExceptionHandler {
@ExceptionHandler(ResourceNotFoundException.class)
public ResponseEntity<Response<Void>> handleResourceNotFoundException(ResourceNotFoundException ex) {
log.error(ex.getMessage());
log.error(ex.getLocalizedMessage(), ex);
return ResponseEntity.status(HttpStatus.NOT_FOUND)
.body(new Response<>(null, ex.getStatus(), ex.getMessage()));
}

View File

@@ -0,0 +1,132 @@
package net.gepafin.tendermanagement.web.rest.api.impl;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.log4j.Log4j2;
import net.gepafin.tendermanagement.config.Translator;
import net.gepafin.tendermanagement.constants.GepafinConstant;
import net.gepafin.tendermanagement.enums.ApplicationAmendmentRequestEnum;
import net.gepafin.tendermanagement.enums.ApplicationStatusTypeEnum;
import net.gepafin.tendermanagement.model.request.ApplicationAmendmentRequest;
import net.gepafin.tendermanagement.model.request.ApplicationAmendmentRequestBean;
import net.gepafin.tendermanagement.model.request.CloseAmendmentRequest;
import net.gepafin.tendermanagement.model.response.ApplicationAmendmentRequestResponse;
import net.gepafin.tendermanagement.model.util.Response;
import net.gepafin.tendermanagement.service.ApplicationAmendmentRequestService;
import net.gepafin.tendermanagement.web.rest.api.ApplicationAmendmentRequestApi;
import net.gepafin.tendermanagement.web.rest.api.errors.Status;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
@RestController
@RequestMapping("${openapi.gepafin.base-path:/v1/amendments}")
@Log4j2
public class ApplicationAmendmentRequestController implements ApplicationAmendmentRequestApi {
@Autowired
ApplicationAmendmentRequestService applicationAmendmentRequestService;
@Override
public ResponseEntity<Response<ApplicationAmendmentRequestResponse>> getApplicationDataForAmendment(HttpServletRequest request, Long applicationEvaluationId) {
ApplicationAmendmentRequestResponse applicationAmendmentBean = applicationAmendmentRequestService.getApplicationDataForAmendment(request,applicationEvaluationId);
return ResponseEntity.status(HttpStatus.OK)
.body(new Response<>(applicationAmendmentBean, Status.SUCCESS, Translator.toLocale(GepafinConstant.APPLICATION_DATA_FOR_AMENDMENT_SUCCESS_MSG)));
}
@Override
public ResponseEntity<Response<ApplicationAmendmentRequestResponse>> createApplicationAmendmentRequest(HttpServletRequest request, Long applicationEvaluationId, ApplicationAmendmentRequest applicationAmendmentRequest) {
ApplicationAmendmentRequestResponse applicationAmendmentRequestResponse = applicationAmendmentRequestService.createApplicationAmendmentRequest(request,applicationEvaluationId,applicationAmendmentRequest);
return ResponseEntity.status(HttpStatus.OK)
.body(new Response<>(applicationAmendmentRequestResponse, Status.SUCCESS, Translator.toLocale(GepafinConstant.CREATE_APPLICATION_DATA_FOR_AMENDMENT_MSG)));
}
@Override
public ResponseEntity<Response<Void>> deleteApplicationAmendmentRequest(HttpServletRequest request, Long id) {
log.info("Delete Application Amendment Request- Application Amendment ID: {}", id);
applicationAmendmentRequestService.deleteApplicationAmendmentRequest(request,id);
return ResponseEntity.status(HttpStatus.OK)
.body(new Response<>(null, Status.SUCCESS, Translator.toLocale(GepafinConstant.DELETE_APPLICATION_AMENDMENT_SUCCESS_MSG)));
}
@Override
public ResponseEntity<Response<ApplicationAmendmentRequestResponse>> getApplicationAmendmentRequestById(HttpServletRequest request,Long id) {
log.info("Get Application Amendment Request By Id");
ApplicationAmendmentRequestResponse applicationAmendmentRequestResponse = applicationAmendmentRequestService.getApplicationAmendmentRequestById(request,id);
return ResponseEntity.status(HttpStatus.OK)
.body(new Response<>(applicationAmendmentRequestResponse, Status.SUCCESS, Translator.toLocale(GepafinConstant.GET_APPLICATION_AMENDMENT_SUCCESS_MSG)));
}
@Override
public ResponseEntity<Response<List<ApplicationAmendmentRequestResponse>>> getAllApplicationAmendmentRequest(HttpServletRequest request,Long userId) {
log.info("Get All Applications Amendment Request");
List<ApplicationAmendmentRequestResponse> applicationAmendmentRequestResponses = applicationAmendmentRequestService.getAllApplicationAmendmentRequest(request,userId);
return ResponseEntity.status(HttpStatus.OK)
.body(new Response<>(applicationAmendmentRequestResponses, Status.SUCCESS, Translator.toLocale(GepafinConstant.GET_APPLICATION_AMENDMENT_SUCCESS_MSG)));
}
@Override
public ResponseEntity<Response<ApplicationAmendmentRequestResponse>> updateApplicationAmendment(HttpServletRequest request, Long id, ApplicationAmendmentRequestBean applicationAmendmentRequestBean) {
log.info("Update Application Amendment");
ApplicationAmendmentRequestResponse updateApplicationAmendment = applicationAmendmentRequestService.updateApplicationAmendment(request, id, applicationAmendmentRequestBean);
return ResponseEntity.status(HttpStatus.CREATED)
.body(new Response<>(updateApplicationAmendment, Status.SUCCESS, Translator.toLocale(GepafinConstant.APPLICATION_AMENDMENT_UPDATE_SUCCESSFULLY_MSG)));
}
@Override
public ResponseEntity<Response<List<ApplicationAmendmentRequestResponse>>> getAllAmendmentRequestByBeneficiaryId(HttpServletRequest request, Long beneficiaryId) {
log.info("Get All Application Amendment Request By Beneficiary ID");
List<ApplicationAmendmentRequestResponse> applicationAmendmentRequestResponseList = applicationAmendmentRequestService.getAllAmendmentRequestByBeneficiaryId(request, beneficiaryId);
return ResponseEntity.status(HttpStatus.CREATED)
.body(new Response<>(applicationAmendmentRequestResponseList, Status.SUCCESS, Translator.toLocale(GepafinConstant.GET_APPLICATION_AMENDMENT_SUCCESS_MSG)));
}
@Override
public ResponseEntity<Response<ApplicationAmendmentRequestResponse>> closeApplicationAmendmentRequest(HttpServletRequest request, Long id, CloseAmendmentRequest closeAmendmentRequest) {
log.info("Closing Amendment Request");
ApplicationAmendmentRequestResponse amendmentRequestResponse = applicationAmendmentRequestService.closeAmendmentRequest(request, id,closeAmendmentRequest);
return ResponseEntity.status(HttpStatus.CREATED)
.body(new Response<>(amendmentRequestResponse, Status.SUCCESS, Translator.toLocale(GepafinConstant.APPLICATION_AMENDMENT_CLOSED_SUCCESFULLY)));
}
@Override
public ResponseEntity<Response<ApplicationAmendmentRequestResponse>> extendResponseDays(
HttpServletRequest request,
Long id,
Long addedDays) {
log.info("Extending response days for Amendment Request ID: {}", id);
ApplicationAmendmentRequestResponse response = applicationAmendmentRequestService.extendResponseDays(request, id, addedDays);
return ResponseEntity.status(HttpStatus.OK)
.body(new Response<>(response, Status.SUCCESS, Translator.toLocale(GepafinConstant.RESPONSE_DAYS_EXTENDED_SUCCESS_MSG)));
}
@Override
public ResponseEntity<Response<List<ApplicationAmendmentRequestResponse>>> getAmendmentByApplicationId(HttpServletRequest request, Long applicationId,List<ApplicationAmendmentRequestEnum> statuses) {
List<ApplicationAmendmentRequestResponse> applicationAmendmentBean = applicationAmendmentRequestService.getAmendmentByApplicationId(request,applicationId,statuses);
return ResponseEntity.status(HttpStatus.OK)
.body(new Response<>(applicationAmendmentBean, Status.SUCCESS, Translator.toLocale(GepafinConstant.APPLICATION_DATA_FOR_AMENDMENT_SUCCESS_MSG)));
}
@Override
public ResponseEntity<Response<ApplicationAmendmentRequestResponse>> updateApplicationAmendmentStatus(HttpServletRequest request, Long applicationAmendmentId,
ApplicationAmendmentRequestEnum status) {
ApplicationAmendmentRequestResponse applicationResponse = applicationAmendmentRequestService.updateApplicationAmendmentStatus(request, applicationAmendmentId, status);
return ResponseEntity.status(HttpStatus.OK)
.body(new Response<>(applicationResponse, Status.SUCCESS, Translator.toLocale(GepafinConstant.APPLICATION_AMENDMENT_UPDATE_SUCCESSFULLY_MSG)));
}
@Override
public ResponseEntity<Response<Void>> sendReminderEmail(
HttpServletRequest request,
Long amendmentId) {
log.info("Sending reminder email for Amendment ID: {}", amendmentId);
applicationAmendmentRequestService.sendReminderEmail(request,amendmentId);
return ResponseEntity.status(HttpStatus.OK)
.body(new Response<>(null, Status.SUCCESS, Translator.toLocale(GepafinConstant.REMINDER_EMAIL_SENT_SUCCESS_MSG)));
}
}

View File

@@ -76,8 +76,8 @@ public class ApplicationApiController implements ApplicationApi {
}
@Override
public ResponseEntity<Response<List<ApplicationResponse>>> getAllApplications(HttpServletRequest request, Long callId, Long companyId, String status) {
List<ApplicationResponse> applications = applicationService.getAllApplications(request, callId, companyId,status);
public ResponseEntity<Response<List<ApplicationResponse>>> getAllApplications(HttpServletRequest request, Long callId, Long companyId, List<ApplicationStatusTypeEnum> statusList) {
List<ApplicationResponse> applications = applicationService.getAllApplications(request, callId, companyId,statusList);
log.info("Get All Applications");
return ResponseEntity.status(HttpStatus.OK)
.body(new Response<>(applications, Status.SUCCESS, Translator.toLocale(GepafinConstant.GET_APPLICATION_SUCCESS_MSG)));

View File

@@ -0,0 +1,59 @@
package net.gepafin.tendermanagement.web.rest.api.impl;
import jakarta.servlet.http.HttpServletRequest;
import net.gepafin.tendermanagement.config.Translator;
import net.gepafin.tendermanagement.constants.GepafinConstant;
import net.gepafin.tendermanagement.enums.ApplicationStatusForEvaluation;
import net.gepafin.tendermanagement.model.request.ApplicationEvaluationRequest;
import net.gepafin.tendermanagement.model.response.ApplicationEvaluationResponse;
import net.gepafin.tendermanagement.model.util.Response;
import net.gepafin.tendermanagement.service.ApplicationEvaluationService;
import net.gepafin.tendermanagement.web.rest.api.ApplicationEvaluationApi;
import net.gepafin.tendermanagement.web.rest.api.errors.Status;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("${openapi.gepafin.base-path:/v1/applicationEvaluation}")
public class ApplicationEvaluationApiController implements ApplicationEvaluationApi {
@Autowired
private ApplicationEvaluationService applicationEvaluationService;
@Override
public ResponseEntity<Response<ApplicationEvaluationResponse>> createOrUpdateApplicationEvaluation(
HttpServletRequest request,
Long assignedApplicationsId,
ApplicationEvaluationRequest evaluationRequest) {
ApplicationEvaluationResponse response = applicationEvaluationService.createOrUpdateApplicationEvaluation(
request, evaluationRequest, assignedApplicationsId);
return ResponseEntity.status(HttpStatus.CREATED)
.body(new Response<>(response, Status.SUCCESS, Translator.toLocale(GepafinConstant.EVALUATION_CREATED_SUCCESSFULLY)));
}
@Override
public ResponseEntity<Response<ApplicationEvaluationResponse>> getApplicationEvaluationByApplicationId(
HttpServletRequest request, Long applicationId, Long assignedApplicationId) {
ApplicationEvaluationResponse response = null;
response = applicationEvaluationService.getApplicationEvaluationByApplicationId(request, applicationId,assignedApplicationId);
return ResponseEntity.status(HttpStatus.OK)
.body(new Response<>(response, Status.SUCCESS, Translator.toLocale(GepafinConstant.EVALUATION_FETCHED_SUCCESSFULLY)));
}
@Override
public ResponseEntity<Response<Void>> deleteApplicationEvaluation(HttpServletRequest request,
Long id) {
applicationEvaluationService.deleteApplicationEvaluation(request,id);
return ResponseEntity.status(HttpStatus.OK)
.body(new Response<>(null, Status.SUCCESS, Translator.toLocale(GepafinConstant.EVALUATION_DELETED_SUCCESSFULLY)));
}
}

View File

@@ -0,0 +1,56 @@
package net.gepafin.tendermanagement.web.rest.api.impl;
import jakarta.servlet.http.HttpServletRequest;
import net.gepafin.tendermanagement.config.Translator;
import net.gepafin.tendermanagement.constants.GepafinConstant;
import net.gepafin.tendermanagement.model.request.CommunicationRequestBean;
import net.gepafin.tendermanagement.model.response.ApplicationAmendmentResponse;
import net.gepafin.tendermanagement.model.response.CommunicationResponseBean;
import net.gepafin.tendermanagement.model.util.Response;
import net.gepafin.tendermanagement.service.CommunicationService;
import net.gepafin.tendermanagement.web.rest.api.CommunicationApi;
import net.gepafin.tendermanagement.web.rest.api.errors.Status;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("${openapi.gepafin.base-path:/v1/communication}")
public class CommunicationController implements CommunicationApi {
@Autowired
CommunicationService communicationService;
@Override
public ResponseEntity<Response<CommunicationResponseBean>> addCommentToAmendmentRequest(HttpServletRequest request, CommunicationRequestBean communicationRequestBean,
Long amendmentId) {
CommunicationResponseBean communicationResponseBean = communicationService.addCommentToAmendmentRequest(communicationRequestBean, amendmentId);
return ResponseEntity.status(HttpStatus.CREATED)
.body(new Response<>(communicationResponseBean, Status.SUCCESS, Translator.toLocale(GepafinConstant.COMMUNICATION_ADDED_TO_AMENDMENT_REQUEST_SUCCESS)));
}
@Override
public ResponseEntity<Response<ApplicationAmendmentResponse>> getAmendmentComments(Long amendmentId) {
ApplicationAmendmentResponse response = communicationService.getAmendmentComments(amendmentId);
return ResponseEntity.ok(new Response<>(response, Status.SUCCESS, Translator.toLocale(GepafinConstant.AMENDMENT_FOUND_SUCCESS)));
}
@Override
public ResponseEntity<Response<CommunicationResponseBean>> updateCommunicationAmendment(HttpServletRequest request, CommunicationRequestBean communicationRequestBean,
Long amendmentId, Long commentId) {
CommunicationResponseBean communicationResponseBean = communicationService.updateAmendmentComment(communicationRequestBean, amendmentId, commentId);
return ResponseEntity.status(HttpStatus.OK)
.body(new Response<>(communicationResponseBean, Status.SUCCESS, Translator.toLocale(GepafinConstant.COMMENT_UPDATED_SUCCESS_MSG)));
}
@Override
public ResponseEntity<Response<String>> deleteApplicationAmendmentComment(HttpServletRequest request, Long applicationAmendId, Long commentId) {
String communicationResponseBean = communicationService.deleteComment(applicationAmendId, commentId);
return ResponseEntity.status(HttpStatus.OK)
.body(new Response<>(communicationResponseBean, Status.SUCCESS, Translator.toLocale(GepafinConstant.COMMENT_DELETED_SUCCESS_MSG)));
}
}

View File

@@ -4,7 +4,7 @@ spring.application.name=tendermanagement
spring.servlet.multipart.max-file-size=300MB
spring.servlet.multipart.max-request-size=300MB
spring.profiles.active=testing
spring.profiles.active=testing
# JPA Configuration
@@ -60,8 +60,10 @@ mailGun_domainName=paghiamoci.ai
mailGun_base_url=https://api.eu.mailgun.net/
# SendinBlue API key
apiKey=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
api.pecUrl=https://ws.pecmassiva.com
#senderEmail=mailer@bflows.net
application.amendment.expiration.days=30
default.email.signature=Gepafin S.p.a
default.hub.pdf.banner=https://mementoresources.s3.amazonaws.com/gepafin/staging/template/gepafin-logo.jpg

View File

@@ -1336,20 +1336,20 @@
</changeSet>
<changeSet id="19-10-2024_2" author="Harish Bagora">
<modifyDataType tableName="protocol" columnName="HUB_ID" newDataType="INTEGER"/>
<addForeignKeyConstraint baseTableName="protocol"
baseColumnNames="HUB_ID"
constraintName="fk_protocol_hub"
referencedTableName="hub"
referencedColumnNames="id"/>
</changeSet>
<modifyDataType tableName="protocol" columnName="HUB_ID" newDataType="INTEGER"/>
<addForeignKeyConstraint baseTableName="protocol"
baseColumnNames="HUB_ID"
constraintName="fk_protocol_hub"
referencedTableName="hub"
referencedColumnNames="id"/>
</changeSet>
<changeSet id="24-10-2024_1" author="Rajesh Khore">
<dropUniqueConstraint
constraintName="company_vat_number_key"
tableName="company"/>
<dropUniqueConstraint
constraintName="company_vat_number_key"
tableName="company"/>
<addColumn tableName="company">
<column name="hub_id" type="INTEGER" defaultValue="1">
@@ -1357,24 +1357,24 @@
</column>
</addColumn>
<addUniqueConstraint
columnNames="VAT_NUMBER, hub_id"
tableName="company"
constraintName="uk_vat_hub" />
<addForeignKeyConstraint
baseTableName="company"
baseColumnNames="hub_id"
referencedTableName="hub"
referencedColumnNames="id"
constraintName="fk_company_hub" />
<addUniqueConstraint
columnNames="VAT_NUMBER, hub_id"
tableName="company"
constraintName="uk_vat_hub"/>
<addForeignKeyConstraint
baseTableName="company"
baseColumnNames="hub_id"
referencedTableName="hub"
referencedColumnNames="id"
constraintName="fk_company_hub"/>
</changeSet>
<changeSet id="24-10-2024_2" author="Rajesh Khore">
<dropUniqueConstraint
constraintName="beneficiary_codice_fiscale_key"
tableName="beneficiary"/>
<dropUniqueConstraint
constraintName="beneficiary_codice_fiscale_key"
tableName="beneficiary"/>
<addColumn tableName="beneficiary">
<column name="hub_id" type="INTEGER" defaultValue="1">
@@ -1382,17 +1382,17 @@
</column>
</addColumn>
<addUniqueConstraint
columnNames="CODICE_FISCALE, hub_id"
tableName="beneficiary"
constraintName="uk_codice_hub" />
<addForeignKeyConstraint
baseTableName="beneficiary"
baseColumnNames="hub_id"
referencedTableName="hub"
referencedColumnNames="id"
constraintName="fk_beneficiary_hub" />
<addUniqueConstraint
columnNames="CODICE_FISCALE, hub_id"
tableName="beneficiary"
constraintName="uk_codice_hub"/>
<addForeignKeyConstraint
baseTableName="beneficiary"
baseColumnNames="hub_id"
referencedTableName="hub"
referencedColumnNames="id"
constraintName="fk_beneficiary_hub"/>
</changeSet>
<changeSet id="24-10-2024_3" author="Rajesh Khore">
@@ -1402,12 +1402,12 @@
</column>
</addColumn>
<addForeignKeyConstraint
baseTableName="application"
baseColumnNames="hub_id"
referencedTableName="hub"
referencedColumnNames="id"
constraintName="fk_application_hub" />
<addForeignKeyConstraint
baseTableName="application"
baseColumnNames="hub_id"
referencedTableName="hub"
referencedColumnNames="id"
constraintName="fk_application_hub"/>
</changeSet>
<changeSet id="25-10-2024_1" author="Piyush">
@@ -1482,18 +1482,216 @@
<column name="parent_folder" value="gepafin/local"/>
</insert>
</changeSet>
<changeSet id="26-10-2024_1" author="Harish Bagora">
<createTable tableName="application_evaluation">
<column autoIncrement="true" name="id" type="INTEGER">
<constraints nullable="false" primaryKey="true" primaryKeyName="application_evaluation_pkey"/>
</column>
<column name="assigned_applications_id" type="INTEGER">
<constraints nullable="false"/>
</column>
<column name="application_id" type="INTEGER">
<constraints nullable="false"/>
</column>
<column name="user_id" type="INTEGER">
<constraints nullable="false"/>
</column>
<column name="criteria" type="TEXT">
<constraints nullable="true"/>
</column>
<column name="checklist" type="TEXT">
<constraints nullable="true"/>
</column>
<column name="file" type="TEXT">
<constraints nullable="true"/>
</column>
<column name="note" type="TEXT">
<constraints nullable="true"/>
</column>
<column name="status" type="VARCHAR(255)">
<constraints nullable="false"/>
</column>
<column name="created_date" type="TIMESTAMP WITHOUT TIME ZONE">
<constraints nullable="true"/>
</column>
<column name="updated_date" type="TIMESTAMP WITHOUT TIME ZONE">
<constraints nullable="true"/>
</column>
<column name="is_deleted" type="BOOLEAN" defaultValueBoolean="false">
<constraints nullable="false"/>
</column>
</createTable>
<addForeignKeyConstraint
baseTableName="application_evaluation"
baseColumnNames="user_id"
referencedTableName="gepafin_user"
referencedColumnNames="id"
constraintName="fk_application_evaluation_gepafin_user"
onDelete="CASCADE"/>
<addForeignKeyConstraint
baseTableName="application_evaluation"
baseColumnNames="assigned_applications_id"
referencedTableName="assigned_applications"
referencedColumnNames="id"
constraintName="fk_application_evaluation_assigned_applications"
onDelete="CASCADE"/>
</changeSet>
<changeSet id="27-10-2024_1" author="Rajesh Khore">
<createTable tableName="application_amendment_request">
<column autoIncrement="true" name="id" type="INTEGER">
<constraints nullable="false" primaryKey="true"
primaryKeyName="pk_application_amendment_request"/>
</column>
<column name="note" type="TEXT">
<constraints nullable="true"/>
</column>
<column name="response_days" type="INTEGER">
<constraints nullable="true"/>
</column>
<column name="is_notification" type="BOOLEAN">
<constraints nullable="false"/>
</column>
<column name="is_email" type="BOOLEAN">
<constraints nullable="false"/>
</column>
<column name="form_fields" type="TEXT">
<constraints nullable="true"/>
</column>
<column name="is_deleted" type="BOOLEAN" defaultValueBoolean="false">
<constraints nullable="false"/>
</column>
<column name="application_id" type="INTEGER">
<constraints nullable="true"/>
</column>
<column name="application_evaluation_id" type="INTEGER">
<constraints nullable="false"
foreignKeyName="fk_application_evaluation_application_amendment_request"
references="application_evaluation(id)"/>
</column>
<column name="created_date" type="TIMESTAMP WITHOUT TIME ZONE">
<constraints nullable="true"/>
</column>
<column name="updated_date" type="TIMESTAMP WITHOUT TIME ZONE">
<constraints nullable="true"/>
</column>
</createTable>
</changeSet>
<changeSet id="28-10-2024_1" author="Piyush">
<createTable tableName="communication">
<column autoIncrement="true" name="id" type="INTEGER">
<constraints nullable="false" primaryKey="true"
primaryKeyName="pk_communication"/>
</column>
<column name="communication_title" type="TEXT">
<constraints nullable="true"/>
</column>
<column name="communication_comment" type="TEXT">
<constraints nullable="true"/>
</column>
<column name="is_deleted" type="BOOLEAN" defaultValueBoolean="false">
<constraints nullable="true"/>
</column>
<column name="commented_date" type="TIMESTAMP WITHOUT TIME ZONE">
<constraints nullable="true"/>
</column>
<column name="created_date" type="TIMESTAMP WITHOUT TIME ZONE"/>
<column name="updated_date" type="TIMESTAMP WITHOUT TIME ZONE"/>
<column name="amendment_id" type="INTEGER">
<constraints nullable="false"/>
</column>
</createTable>
<!-- Add foreign key constraint between communication and application_amendment_request -->
<addForeignKeyConstraint baseTableName="communication"
baseColumnNames="amendment_id"
referencedTableName="application_amendment_request"
referencedColumnNames="id"
constraintName="fk_communication_application_amendment_request"/>
</changeSet>
<changeSet id="28-10-2024_3" author="Rajesh Khore">
<addColumn tableName="application_amendment_request">
<column name="protocol_id" type="INTEGER"/>
</addColumn>
<addForeignKeyConstraint
baseTableName="application_amendment_request"
baseColumnNames="protocol_id"
referencedTableName="protocol"
referencedColumnNames="id"
constraintName="fk_application_amendment_request_protocol"/>
</changeSet>
<changeSet id="29-10-2024_1" author="Rajesh Khore">
<addColumn tableName="application_amendment_request">
<column name="start_date" type="TIMESTAMP WITHOUT TIME ZONE"/>
<column name="status" type="VARCHAR(50)"/>
<column name="internal_note" type="TEXT"></column>
</addColumn>
</changeSet>
<changeSet id="29-10-2024_2" author="Piyush">
<addColumn tableName="hub">
<column name="EMAIL_SERVICE_TYPE" type="TEXT"/>
<column name="EMAIL_SERVICE_CONFIG" type="TEXT"/>
</addColumn>
</changeSet>
<changeSet id="29-10-2024_3" author="Piyush">
<sqlFile dbms="postgresql"
path="db/dump/insert_system_email_template_for_notification_mail_31_10_2024.sql"/>
</changeSet>
<changeSet id="30-10-2024_1" author="Nisha Kashyap">
<addColumn tableName="hub">
<column name="pdf_banner" type="TEXT"></column>
</addColumn>
<update tableName="hub">
<column name="pdf_banner"
value='https://mementoresources.s3.amazonaws.com/gepafin/staging/template/gepafin-logo.jpg'/>
<where>UNIQUE_UUID = 'p4lk3bcx1RStqTaIVVbXs'</where>
</update>
<update tableName="hub">
<column name="pdf_banner"
value='https://mementoresources.s3.amazonaws.com/gepafin/staging/template/sviluppumbria_logo.jpg'/>
<where>UNIQUE_UUID = 't7jh5wfg9QXylNaTZkPoE'</where>
</update>
</changeSet>
<changeSet id="30-10-2024_2" author="Piyush">
<sqlFile dbms="postgresql"
path="db/dump/update_hub_data_for_email_service_config_31_10_2024_1.sql"/>
</changeSet>
<changeSet id="31-10-2024_1" author="Rajesh Khore">
<addColumn tableName="hub">
<column name="EMAIL_SIGNATURE" type="TEXT"/>
</addColumn>
</changeSet>
<changeSet id="31-10-2024_2" author="Rajesh Khore">
<sqlFile dbms="postgresql"
path="db/dump/updated_system_email_template_for_application_submition_30-10-2024.sql"/>
</changeSet>
<changeSet id="31-10-2024_3" author="Rajesh Khore">
<update tableName="hub">
<column name="EMAIL_SIGNATURE" value="Gepafin S.p.a"/>
@@ -1504,20 +1702,22 @@
<where>UNIQUE_UUID = 't7jh5wfg9QXylNaTZkPoE'</where>
</update>
</changeSet>
<changeSet id="30-10-2024_1" author="Nisha Kashyap">
<addColumn tableName="hub">
<column name="pdf_banner" type="TEXT"></column>
</addColumn>
<update tableName="hub">
<column name="pdf_banner" value='https://mementoresources.s3.amazonaws.com/gepafin/staging/template/gepafin-logo.jpg'/>
<where>UNIQUE_UUID = 'p4lk3bcx1RStqTaIVVbXs'</where>
</update>
<update tableName="hub">
<column name="pdf_banner" value='https://mementoresources.s3.amazonaws.com/gepafin/staging/template/sviluppumbria_logo.jpg'/>
<where>UNIQUE_UUID = 't7jh5wfg9QXylNaTZkPoE'</where>
</update>
<changeSet id="30-10-2024_4" author="Harish Bagora">
<sql dbms="postgresql">select
setval('gepafin_schema.system_email_template_id_seq', (select
max(id)+1
from gepafin_schema.system_email_template), false)
</sql>
<sqlFile dbms="postgresql"
path="db/dump/insert_system_email_template_for_sollecito_30_10_2024.sql"/>
</changeSet>
<changeSet id="04-11-2024_1" author="Piyush">
<sqlFile dbms="postgresql"
path="db/dump/update_system_email_template_for_notification_mail_04_11_2024_1.sql"/>
</changeSet>
<changeSet id="05-11-2024_4" author="Harish Bagora">
<sqlFile dbms="postgresql"
path="db/dump/update_system_email_template_for_notification_mail_05_11_2024_4.sql"/>
</changeSet>
</databaseChangeLog>

View File

@@ -0,0 +1,141 @@
INSERT INTO gepafin_schema.system_email_template
(
id, template_name, "type", html_content, subject, "json", "system",
is_deleted, created_date, updated_date
)
VALUES
(
3,
'Instructional Aid/Request for Documentation Integration Template',
'DOCUMENTATION_INTEGRATION_REQUEST',
'<html>
<body style="font-family: Arial, sans-serif; color: #000; line-height: 1.6;">
<div style="padding: 20px; border: 1px solid #ddd; border-radius: 8px; max-width: 600px; margin: auto;">
<p><strong>RICHIESTA INTEGRAZIONE DOCUMENTALE</strong></p>
<p>Buongiorno,</p>
<p>In riferimento alla domanda di concessione di Finanziamento agevolato a valere sul Fondo prestiti
<strong>{{call_name}}</strong> di cui al <strong>Protocollo n. {{protocol_number}} del
{{protocol_date}} e {{protocol_time}}</strong>, alla luce dellattività istruttoria svolta,
segnaliamo quanto segue:</p>
<ul>
<li>{{form_dataInput}}</li>
</ul>
<p>{{note}}</p>
<p>Vi invitiamo a fornire quanto sopra richiesto integrando la documentazione sia caricandola allinterno dello sportello
online <a href="{{platform_link}}">{{platform_link}}</a> che inviandola a mezzo PEC allindirizzo
{{legal_mail}} entro e <strong>non oltre 10 giorni</strong> dal ricevimento della presente comunicazione,
precisando che, in caso di mancata ricezione nei termini indicati, saremo costretti a non prendere in considerazione la Vostra richiesta di finanziamento.</p>
<p>Vi informiamo che per la ricezione della PEC farà fede la ricevuta di avvenuta consegna che attesterà il buon esito
dellinvio. La documentazione trasmessa e le informazioni fornite saranno processate dall''istruttore assegnatario della pratica.</p>
<p>Distinti Saluti,</p>
<p><strong>{{email_signature}}</strong></p>
</div>
</body>
</html>',
'RICHIESTA INTEGRAZIONE DOCUMENTALE - {{call_name}}',
NULL,
true,
false,
'2024-10-26 20:00:00',
'2024-10-26 20:00:00'
);
-- Insert for INADMISSIBILITY_NOTIFICATION_DUE_TO_FAILURE
INSERT INTO gepafin_schema.system_email_template
(
id, template_name, "type", html_content, subject, "json", "system",
is_deleted, created_date, updated_date
)
VALUES
(
4,
'Notification of Inadmissibility Due to Failure to Respond Template',
'INADMISSIBILITY_NOTIFICATION_DUE_TO_FAILURE',
'<html>
<body style="font-family: Arial, sans-serif; color: #000; line-height: 1.6;">
<div style="padding: 20px; border: 1px solid #ddd; border-radius: 8px; max-width: 600px; margin: auto;">
<p><strong>Comunicazione di non ammissibilità per mancata risposta a richiesta integrazione documentale</strong></p>
<p>Buongiorno,</p>
<p>Con posta elettronica certificata del <strong>{{date_time_emailSend}}</strong>, vi abbiamo comunicato che i documenti richiesti
dal Gestore sarebbero dovuti pervenire entro <strong>10 giorni</strong> dal ricevimento di detta comunicazione.
Trascorso il termine senza la ricezione dei documenti richiesti, il Gestore non ha potuto prendere in considerazione la richiesta di finanziamento.</p>
<p>È possibile presentare ricorso tramite modello disponibile nello sportello online
<a href="{{platform_link}}">{{platform_link}}</a> entro <strong>10 giorni</strong> dalla ricezione di questa comunicazione.</p>
<p>Distinti Saluti,</p>
<p><strong>{{email_signature}}</strong></p>
</div>
</body>
</html>',
'BANDO {{call_name}} - Domanda di finanziamento non ammessa {{company_name}}',
NULL,
true,
false,
'2024-10-26 20:00:00',
'2024-10-26 20:00:00'
);
-- Insert for ADMISSIBILITY_NOTIFICATION
INSERT INTO gepafin_schema.system_email_template
(
id, template_name, "type", html_content, subject, "json", "system",
is_deleted, created_date, updated_date
)
VALUES
(
5,
'Notification of Admissibility Template',
'ADMISSIBILITY_NOTIFICATION',
'<html>
<body style="font-family: Arial, sans-serif; color: #000; line-height: 1.6;">
<div style="padding: 20px; border: 1px solid #ddd; border-radius: 8px; max-width: 600px; margin: auto;">
<p>Buongiorno,</p>
<p>In riferimento alla domanda di concessione di Finanziamento agevolato “<strong>{{call_name}}</strong>” di cui al
<strong>Protocollo n. {{protocol_number}} del {{protocol_date}} alle {{protocol_time}}</strong>, listruttoria di ammissibilità
è stata completata con esito positivo.</p>
<p>Seguirà una comunicazione relativa alla valutazione tecnica ed economico-finanziaria ai fini della valutazione finale.</p>
<p>Distinti Saluti,</p>
<p><strong>{{email_signature}}</strong></p>
</div>
</body>
</html>',
'BANDO {{call_name}} Esito positivo istruttoria di ammissibilità {{company_name}}',
NULL,
true,
false,
'2024-10-26 20:00:00',
'2024-10-26 20:00:00'
);
-- Insert for INADMISSIBILITY_NOTIFICATION
INSERT INTO gepafin_schema.system_email_template
(
id, template_name, "type", html_content, subject, "json", "system",
is_deleted, created_date, updated_date
)
VALUES
(
6,
'Notification of Inadmissibility Template',
'INADMISSIBILITY_NOTIFICATION',
'<html>
<body style="font-family: Arial, sans-serif; color: #000; line-height: 1.6;">
<div style="padding: 20px; border: 1px solid #ddd; border-radius: 8px; max-width: 600px; margin: auto;">
<p>Buongiorno,</p>
<p>In riferimento alla domanda di concessione di Finanziamento agevolato “<strong>{{call_name}}</strong>” di cui al
<strong>Protocollo n. {{protocol_number}} del {{protocol_date}} alle {{protocol_time}}</strong>,
l''istruttoria di ammissibilità è stata completata con esito negativo.</p>
<p>Motivazioni: <strong>{{form_text}}</strong></p>
<p>È possibile presentare ricorso tramite modello disponibile nello sportello online
<a href="{{platform_link}}">{{platform_link}}</a> entro <strong>10 giorni</strong> dalla ricezione di questa comunicazione.</p>
<p>Distinti Saluti,</p>
<p><strong>{{email_signature}}</strong></p>
</div>
</body>
</html>',
'BANDO {{call_name}} Esito negativo istruttoria di ammissibilità {{company_name}}',
NULL,
true,
false,
'2024-10-26 20:00:00',
'2024-10-26 20:00:00'
);

View File

@@ -0,0 +1,29 @@
-- SQL Dump to insert system email template for amendment reminder email with calculated due date
INSERT INTO gepafin_schema.system_email_template
(template_name, "type", html_content, subject, "json", "system", is_deleted, created_date, updated_date)
VALUES
(
'Amendment Reminder Email',
'AMENDMENT_REMINDER',
'<html>
<body style="font-family: Arial, sans-serif; color: #000; line-height: 1.6;">
<div style="padding: 20px; border: 1px solid #ddd; border-radius: 8px; max-width: 600px; margin: auto;">
<p><strong>PROMEMORIA PER LA PRESENTAZIONE DELL''EMENDAMENTO</strong></p>
<p>Buongiorno,</p>
<p>Questo è un promemoria per completare la presentazione dell''emendamento entro il termine specificato. Di seguito i dettagli:</p>
<ul>
<li><strong>Amendment ID:</strong> {{amendment_id}}</li>
<li><strong>Data di Scadenza:</strong> {{amendment_due_date}}</li>
</ul>
<p>Si prega di assicurarsi che l''emendamento venga presentato entro la data di scadenza per evitare ritardi. Inviare l''emendamento tramite la piattaforma online <a href="{{platform_link}}">{{platform_link}}</a> </p>
<p>Distinti saluti,</p>
<p><strong>{{email_signature}}</strong></p>
</div>
</body>
</html>',
'Reminder: Pending Amendment Submission - ID {{amendment_id}}',
NULL,
true,
false,
CURRENT_TIMESTAMP,
CURRENT_TIMESTAMP);

View File

@@ -0,0 +1,9 @@
UPDATE hub
SET email_service_type = 'PEC_SERVICE',
email_service_config = 'JkFbBfuVvq7VWwp5LcWIi+hAa1RJ1ekI0jq3w7gLTXETZiTaN8zC4OBWD53x8FtbfFTh3L/5805CIYTH1BQGa3X9q16q9SDzMy7DKHdmJzOnLKhn74C5akoXKaeXUCGnzp0cSk2c01FV6lwefC29IshijFSumCHtVlgWNeZigBx51GL2Coh8nF1Mu7/KIcny'
WHERE UNIQUE_UUID = 'p4lk3bcx1RStqTaIVVbXs';
UPDATE hub
SET email_service_type = 'MAILGUN_SERVICE',
email_service_config = 'mhyP0kKQCrsbhGv3PGx4yob4dPSNBOd2xFnAPkikJE7VHkydklfUSVWAdYjhXwOz8rglH2YYEC/xGZdrEgSnkS9Ed56/qzmaU1667GGf+kc5mciOiECW5/sVmhtbVClEnu1FGZMzlsJSqYKlTmqfCYD0lTAlak1Lu2n030tj6nhMDvUxP9CbeTwkzALMtmgt'
WHERE UNIQUE_UUID = 't7jh5wfg9QXylNaTZkPoE';

View File

@@ -0,0 +1,78 @@
UPDATE gepafin_schema.system_email_template
SET html_content = '<html>
<body style="font-family: Arial, sans-serif; color: #000; line-height: 1.6;">
<div style="padding: 20px; border: 1px solid #ddd; border-radius: 8px; max-width: 600px; margin: auto;">
<p><strong>RICHIESTA INTEGRAZIONE DOCUMENTALE</strong></p>
<p>Buongiorno,</p>
<p>In riferimento alla domanda di concessione di Finanziamento agevolato a valere sul Fondo prestiti
<strong>{{call_name}}</strong> di cui al <strong>Protocollo n. {{protocol_number}} del
{{protocol_date}} e {{protocol_time}}</strong>, alla luce dellattività istruttoria svolta,
segnaliamo quanto segue:</p>
<ul>
<li>{{form_dataInput}}</li>
</ul>
<p>{{note}}</p>
<p>Vi invitiamo a fornire quanto sopra richiesto integrando la documentazione sia caricandola allinterno dello sportello
online <a href="{{platform_link}}">{{platform_link}}</a> che inviandola a mezzo PEC allindirizzo
{{legal_mail}} entro e <strong>non oltre 10 giorni</strong> dal ricevimento della presente comunicazione,
precisando che, in caso di mancata ricezione nei termini indicati, saremo costretti a non prendere in considerazione la Vostra richiesta di finanziamento.</p>
<p>Vi informiamo che per la ricezione della PEC farà fede la ricevuta di avvenuta consegna che attesterà il buon esito
dellinvio. La documentazione trasmessa e le informazioni fornite saranno processate dall''istruttore assegnatario della pratica.</p>
<p>Distinti Saluti,</p>
<p><strong>{{email_signature}}</strong></p>
</div>
</body>
</html>'
WHERE "type" = 'DOCUMENTATION_INTEGRATION_REQUEST' AND "system" = true;
UPDATE gepafin_schema.system_email_template
SET html_content = '<html>
<body style="font-family: Arial, sans-serif; color: #000; line-height: 1.6;">
<div style="padding: 20px; border: 1px solid #ddd; border-radius: 8px; max-width: 600px; margin: auto;">
<p><strong>Comunicazione di non ammissibilità per mancata risposta a richiesta integrazione documentale</strong></p>
<p>Buongiorno,</p>
<p>Con posta elettronica certificata del <strong>{{date_time_emailSend}}</strong>, vi abbiamo comunicato che i documenti richiesti
dal Gestore sarebbero dovuti pervenire entro <strong>10 giorni</strong> dal ricevimento di detta comunicazione.
Trascorso il termine senza la ricezione dei documenti richiesti, il Gestore non ha potuto prendere in considerazione la richiesta di finanziamento.</p>
<p>È possibile presentare ricorso tramite modello disponibile nello sportello online
<a href="{{platform_link}}">{{platform_link}}</a> entro <strong>10 giorni</strong> dalla ricezione di questa comunicazione.</p>
<p>Distinti Saluti,</p>
<p><strong>{{email_signature}}</strong></p>
</div>
</body>
</html>'
WHERE "type" = 'INADMISSIBILITY_NOTIFICATION_DUE_TO_FAILURE' AND "system" = true;
UPDATE gepafin_schema.system_email_template
SET html_content = '<html>
<body style="font-family: Arial, sans-serif; color: #000; line-height: 1.6;">
<div style="padding: 20px; border: 1px solid #ddd; border-radius: 8px; max-width: 600px; margin: auto;">
<p>Buongiorno,</p>
<p>In riferimento alla domanda di concessione di Finanziamento agevolato “<strong>{{call_name}}</strong>” di cui al
<strong>Protocollo n. {{protocol_number}} del {{protocol_date}} alle {{protocol_time}}</strong>, listruttoria di ammissibilità
è stata completata con esito positivo.</p>
<p>Seguirà una comunicazione relativa alla valutazione tecnica ed economico-finanziaria ai fini della valutazione finale.</p>
<p>Distinti Saluti,</p>
<p><strong>{{email_signature}}</strong></p>
</div>
</body>
</html>'
WHERE "type" = 'ADMISSIBILITY_NOTIFICATION' AND "system" = true;
UPDATE gepafin_schema.system_email_template
SET html_content = '<html>
<body style="font-family: Arial, sans-serif; color: #000; line-height: 1.6;">
<div style="padding: 20px; border: 1px solid #ddd; border-radius: 8px; max-width: 600px; margin: auto;">
<p>Buongiorno,</p>
<p>In riferimento alla domanda di concessione di Finanziamento agevolato “<strong>{{call_name}}</strong>” di cui al
<strong>Protocollo n. {{protocol_number}} del {{protocol_date}} alle {{protocol_time}}</strong>,
l''istruttoria di ammissibilità è stata completata con esito negativo.</p>
<p>Motivazioni: <strong>{{form_text}}</strong></p>
<p>È possibile presentare ricorso tramite modello disponibile nello sportello online
<a href="{{platform_link}}">{{platform_link}}</a> entro <strong>10 giorni</strong> dalla ricezione di questa comunicazione.</p>
<p>Distinti Saluti,</p>
<p><strong>{{email_signature}}</strong></p>
</div>
</body>
</html>'
WHERE "type" = 'INADMISSIBILITY_NOTIFICATION' AND "system" = true;

View File

@@ -0,0 +1,16 @@
UPDATE gepafin_schema.system_email_template
SET
subject = 'BANDO {{call_name}}- Domanda di concessione di finanziamento agevolato {{company_name}}',
html_content = '<html>
<body style="font-family: Arial, sans-serif; color: #000; line-height: 1.6;">
<div style="padding: 20px; border: 1px solid #ddd; border-radius: 8px; max-width: 600px; margin: auto;">
<p>In riferimento alla domanda di concessione di Finanziamento agevolato a valere sul Fondo prestiti
<strong>{{call_name}}</strong> di cui alloggetto, la stessa è stata regolarmente acquisita ed è stata
registrata con Protocollo n. <strong>{{protocol_number}}</strong> del <strong>{{protocol_date}}</strong>
alle <strong>{{protocol_time}}</strong>.</p>
<p>Distinti Saluti,</p>
<p><strong>{{email_signature}}</strong></p>
</div>
</body>
</html>'
WHERE "type" = 'DOCUMENTATION_INTEGRATION_REQUEST' AND "system" = true;

View File

@@ -101,6 +101,7 @@ success.password.changed=Password changed successfully.
logout.successful.msg=Logout successful. You have been logged out successfully.
#Update user Active or Deactive status
update.user.status.success=User status has been successfully updated.
beneficiary.email.not.found.msg=The email address for the beneficiary could not be found. Please ensure that the beneficiary has a valid email address.
#Form-field-related messages
@@ -253,8 +254,18 @@ get_login_attempt_se_msg=Login attempts fetched successfully.
application.in.submit.status.cannot.delete.company=The company cannot be deleted because there are active applications in the SUBMITTED status.
get.users.success.msg = Successfully fetched users.
cannot.create.beneficiary.user = Creation of a Beneficiary user is not allowed. Please assign the appropriate role.
evaluationCriteria.invalid=This evaluation criterion does not belong to the current call.
application.evaluation.not.found=Application Evaluation not found with ID: {0}
evaluation.created.successfully = Application evaluation created successfully.
evaluation.updated.successfully = Application evaluation updated successfully.
evaluation.fetched.successfully = Application evaluation fetched successfully.
evaluation.deleted.successfully = Application evaluation deleted successfully.
evaluations.fetched.successfully = All application evaluations fetched successfully.
application.evaluation.status.updated.successfully=Application evaluation status updated successfully.
evaluationCriteria.invalid=This evaluation criterion does not belong to the current call.
assigned.application.not.found.with.id=Assigned application with this application ID not found
either.application.or.assigned.application.id.required=Either applicationId or assignedApplicationId is required.
evaluation.already.exists=An application evaluation already exists for this application ID.
# Hub Messages
hub_create_success=Hub created successfully
@@ -276,3 +287,22 @@ assigned.application.get.success=Assigned Application details fetched successful
assigned.application.update.successfully=Assigned Application updated successfully.
get.error.s3=Failed to fetch the file from S3.
invalid.application.status = Invalid Application status.
application.data.amendment.success = Successfully retrieved the application data for the amendment process.
delete.application.amendment.success = Application Amendment successfully deleted.
create.application.data.amendment.msg = Application amendment submited succesfully.
application.amendment.not.found = Application Amendment Request not found with the given ID.
application.amendment.get.success = Application Amendment details fetched successfully with given ID.
application.amendment.update.successfully = Application Amendment Updated Successfully.
application.amendment.closed.successfully = Application Amendment Closed Successfully.
response.days.extended.success=Response days extended successfully.
reminder.email.sent.success.msg=Reminder email sent successfully!
added.comment.to.amendment.request.success = Application Amendment Comment Added Successfully.
comment.not.found = Comment Not Found.
comment.updated.successfully = Comment Updated Successfully.
comment.deleted.successfully = Comment Deleted Successfully.
comment.not.associate.with.amendment = Comment Not Associated with Amendment Request.
amendment.found.success = Amendment Request Found Successfully.
invalid.amendment.for.comment = Invalid Amendment Request for the Given Comment.
DD_MM_YYYY_HH_MM = dd_MM_yyyy HH:mm

View File

@@ -252,6 +252,16 @@ get.users.success.msg = Utenti recuperati con successo
cannot.create.beneficiary.user = La creazione di un utente beneficiario non � consentita. Si prega di assegnare il ruolo appropriato.
evaluationCriteria.invalid=Questo criterio di valutazione non appartiene alla chiamata corrente.
application.evaluation.not.found=Valutazione dell'applicazione non trovata con ID: {0}
evaluation.created.successfully = Valutazione dell'applicazione creata con successo.
evaluation.updated.successfully = Valutazione dell'applicazione aggiornata con successo.
evaluation.fetched.successfully = Valutazione dell'applicazione recuperata con successo.
evaluation.deleted.successfully = Valutazione dell'applicazione eliminata con successo.
evaluations.fetched.successfully = Tutte le valutazioni delle applicazioni recuperate con successo.
application.evaluation.status.updated.successfully=Stato della valutazione dell'applicazione aggiornato con successo.
assigned.application.not.found.with.id=Applicazione assegnata con questo ID dell'applicazione non trovata
either.application.or.assigned.application.id.required=� richiesto almeno uno tra applicationId o assignedApplicationId.
evaluation.already.exists=Una valutazione dell'applicazione esiste gi� per questo ID applicazione.
application.assigned.success.msg =Domanda assegnata con successo
application.already.assigned.msg =La domanda � gi� assegnata
@@ -271,3 +281,23 @@ hub_not_found=Hub non trovato
application.not.in.draft.status=La domanda non � in stato DRAFT.
get.error.s3=Impossibile recuperare il file da S3.
application.data.amendment.success = Recupero riuscito dei dati dell'applicazione per il processo di modifica
delete.application.amendment.success =Emendamento all'applicazione eliminato con successo.
application.amendment.not.found = Richiesta di modifica dell'applicazione non trovata con l'ID indicato.
application.amendment.get.success = Dettagli della modifica dell'applicazione recuperati correttamente con l'ID fornito.
application.amendment.update.successfully = Emendamento all'applicazione aggiornato con successo.
application.amendment.closed.successfully = Emendamento alla domanda chiuso con successo.
response.days.extended.success=Giorni di risposta estesi con successo.
added.comment.to.amendment.request.success = Commento aggiunto con successo alla richiesta di emendamento.
comment.not.found = Commento non trovato.
comment.updated.successfully = Commento aggiornato con successo.
comment.deleted.successfully = Commento eliminato con successo.
comment.not.associate.with.amendment = Il commento non � associato alla richiesta di emendamento.
amendment.found.success = Richiesta di emendamento trovata con successo.
invalid.amendment.for.comment = Richiesta di emendamento non valida per il commento fornito.
DD_MM_YYYY_HH_MM = dd_MM_yyyy HH:mm
create.application.data.amendment.msg =Emendamento alla domanda inviato con successo
beneficiary.email.not.found.msg=L'indirizzo email per il beneficiario non è stato trovato. Si prega di assicurarsi che il beneficiario abbia un indirizzo email valido.
reminder.email.sent.success.msg=Email di promemoria inviata con successo!