diff --git a/pom.xml b/pom.xml index c463be91..a42534bf 100644 --- a/pom.xml +++ b/pom.xml @@ -245,6 +245,12 @@ reactor-netty + + net.objecthunter + exp4j + 0.4.8 + + diff --git a/src/main/java/net/gepafin/tendermanagement/constants/GepafinConstant.java b/src/main/java/net/gepafin/tendermanagement/constants/GepafinConstant.java index ce019638..da225c54 100644 --- a/src/main/java/net/gepafin/tendermanagement/constants/GepafinConstant.java +++ b/src/main/java/net/gepafin/tendermanagement/constants/GepafinConstant.java @@ -112,6 +112,7 @@ public class GepafinConstant { public static final String APPLICATION_UPDATED_SUCCESS_MSG = "application.updated.success"; public static final String DELETE_APPLICATION_SUCCESS_MSG = "application.deleted.success"; public static final String GET_APPLICATION_SUCCESS_MSG = "application.get.success"; + public static final String GET_APPLICATION_EVALUATION_VERSION_SUCCESS_MSG = "application.evaluation.version.get.success"; public static final String APPLICATION_NOT_FOUND_MSG = "application.not.found"; public static final String APPLICATION_FORM_FIELD_NOT_FOUND = "application.form.field.not.found"; public static final String FORM_ID_DOES_NOT_MACTHES = "Form.not.matches.to.call.initial.form"; @@ -237,6 +238,7 @@ public class GepafinConstant { 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 GET_APPLICATION_EVALUATION_FORM_SUCCESS_MSG = "application.evaluation.form.get.success"; 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"; @@ -402,6 +404,7 @@ public class GepafinConstant { public static final String EVALUATION_V2_STEP_2 = "EVALUATION_V2_STEP_2"; + public static final String EITHER_APPLICATION_ID_OR_ASSIGNED_APPLICATION_ID_MUST_BE_PROVIDED = "either.applicationId.or.assignedApplicationId.must.be.provided"; public static final String ASSIGNED_APPLICATION_STATUS_UPDATED_SUCCESSFULLY = "assigned.application.status.updated.successfully"; public static final String REQUIRED_REQUESTED_AMOUNT_MSG = "validation.required.requested.amount"; @@ -418,5 +421,46 @@ public class GepafinConstant { public static final String COMPANY_ID_NOT_NULL_MSG = "company.id.not.null"; public static final String USER_WITH_COMPANY="userWithCompany"; + public static final String FORMULA_AMOUNT_NOT_MATCHED="formula.amount.not.matches.requested.amount"; + public static final String CRITERIA_TABLE_COLUMNS="criteria_table_columns"; + + public static final String DOCUMENTATION_INTEGRATION_REQUEST_SVILUPPUMBRIA= "\n" + + " \n" + + "
\n" + + "

RICHIESTA INTEGRAZIONE DOCUMENTALE

\n" + + "

Buongiorno,

\n" + + "

In riferimento alla domanda di concessione di Finanziamento agevolato a valere sul Bando \n" + + " “{{call_name}}“ di cui al Protocollo n. {{protocol_number}} del\n" + + " {{protocol_date}} e {{protocol_time}}, alla luce dell'attività istruttoria svolta,\n" + + " segnaliamo quanto segue:\n" + + "

\n" + + " {{note}}\n" + + "

Vi invitiamo a fornire quanto sopra richiesto integrando la documentazione caricandola all'interno dello sportello\n" + + " online {{platform_link}} entro e non oltre {{response_days}} giorni dal ricevimento della presente comunicazione,\n" + + " precisando che, in caso di mancata ricezione nei termini indicati, saremo costretti a non prendere in considerazione la Vostra richiesta di finanziamento.\n" + + "

\n" + + "

La documentazione trasmessa e le informazioni fornite saranno processate dall'istruttore assegnatario della pratica.\n" + + "

\n" + + "

Distinti Saluti,

\n" + + "

{{email_signature}}

\n" + + "
\n" + + " \n" + + ""; + + + public static final String APPLICATION_REJECTED_SVILUPPUMBRIA = "\n" + + " \n" + + "
\n" + + "

Buongiorno,

\n" + + "

Si comunica che, in riferimento alla domanda a valere sul bando “{{call_name}}” di cui al\n" + + " Protocollo n. {{protocol_number}} del {{protocol_date}} alle {{protocol_time}},\n" + + " la stessa è stata sottoposta ad istruttoria di ammissibilità con esito negativo.

\n" + + "

Le motivazioni sono le seguenti: {{form_text}}

\n" + + "

Vi ricordiamo che i Beneficiari che hanno presentato richieste valutate non ammissibili entro 10 giorni dalla data di ricevimento della presente potranno finoltrare richiesta di chiarimenti e/o osservazioni alla scrivente Società ai sensi e per gli effetti dell’art.10 bis della L.241/1990 e s.m.i.

\n" + + "

Distinti Saluti,

\n" + + "

{{email_signature}}

\n" + + "
\n" + + " \n" + + ""; } diff --git a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java index 7d15e8b1..35ecc113 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java @@ -31,6 +31,7 @@ import net.gepafin.tendermanagement.web.rest.api.errors.ResourceNotFoundExceptio import net.gepafin.tendermanagement.web.rest.api.errors.Status; import org.h2.util.IOUtils; +import org.json.JSONObject; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -49,11 +50,16 @@ import java.io.IOException; import java.io.InputStream; import java.math.BigDecimal; import java.text.MessageFormat; +import java.text.NumberFormat; +import java.text.ParseException; import java.time.LocalDate; import java.time.LocalDateTime; import java.time.LocalTime; import java.util.*; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import java.util.stream.Collectors; +import java.util.stream.Stream; import java.util.zip.ZipEntry; import java.util.zip.ZipOutputStream; @@ -94,29 +100,29 @@ public class ApplicationDao { @Autowired private FlowDataRepository flowDataRepository; - + @Autowired private UserCompanyDelegationRepository userCompanyDelegationRepository; - + @Autowired private Validator validator; - + @Autowired private CompanyService companyService; @Autowired private S3PathConfig s3PathConfig; - + @Autowired private SystemEmailTemplatesService systemEmailTemplatesService; @Autowired private AssignedApplicationsRepository assignedApplicationsRepository; - + @Value("${default_System_Receiver_Email}") private String defaultSystemReceiverEmail; - + @Value("${rinaldo_email}") private String rinaldoEmail; - + @Value("${carlo_email}") private String carloEmail; @@ -125,37 +131,37 @@ public class ApplicationDao { @Autowired private AmazonS3Service amazonS3Service; - + @Autowired private ApplicationSignedDocumentRepository applicationSignedDocumentRepository; - + // @Value("${aws.s3.url.folder.signed.document}") // private String signedDocumentS3Folder; - + @Value("${default.hub.uuid}") private String defaultHubUuid; - + @Autowired private UserService userService; @Autowired private S3PathConfig s3ConfigBean; - + @Autowired private ProtocolDao protocolDao; - + @Autowired private HubService hubService; @Autowired private EmailNotificationDao emailNotificationDao; - + @Autowired private FormDao formDao; @Autowired private EmailLogDao emailLogDao; - + @Autowired private UserWithCompanyRepository userWithCompanyRepository; @@ -183,6 +189,7 @@ public class ApplicationDao { @Autowired private ApplicationEvaluationRepository applicationEvaluationRepository; + public ApplicationResponseBean createApplication(HttpServletRequest request, ApplicationRequestBean applicationRequestBean, Long formId, Long applicationId) { FormEntity formEntity = formService.validateForm(formId); // callService.validatePublishedCall(formEntity.getCall().getId()); @@ -258,7 +265,7 @@ public class ApplicationDao { // List contentResponseBeans = Utils.convertJsonStringToList( // applicationFormEntity.getForm().getContent(), ContentResponseBean.class); - + List contentResponseBeans = formDao.convertFormEntityToFormResponseBean(applicationFormEntity.getForm()).getContent(); for (ApplicationFormFieldEntity applicationFormFieldEntity : applicationFormFieldEntities) { @@ -309,7 +316,7 @@ public class ApplicationDao { ); } ApplicationEntity oldApplicationDataEntity = Utils.getClonedEntityForData(applicationEntity); - + validator.validateUserWithCompany(request, applicationEntity.getCompanyId()); applicationEntity.setIsDeleted(true); applicationEntity = applicationRepository.save(applicationEntity); @@ -356,9 +363,9 @@ public class ApplicationDao { // // return applicationResponses; // } - + public List getAllApplications(UserEntity userEntity, Long callId, Long companyId,List statusList) { - + log.info("Fetching applications for RoleType: {}", userEntity.getRoleEntity().getRoleType()); Specification spec = search(userEntity, callId, companyId,statusList); @@ -482,15 +489,18 @@ public class ApplicationDao { public List createOrUpdateMultipleFormFields(List formFieldResponseBeans, ApplicationFormEntity applicationFormEntity, FormEntity formEntity) { + FieldValidator fieldValidator = FieldValidator.create(); List existingFields = applicationFormFieldRepository.findByApplicationFormId(applicationFormEntity.getId()); - return formFieldResponseBeans.stream().map(requestBean -> createOrUpdateApplicationFormField(requestBean, applicationFormEntity, existingFields, formEntity)) + List applicationFormFieldEntities=formFieldResponseBeans.stream().map(requestBean -> createOrUpdateApplicationFormField(requestBean, applicationFormEntity, existingFields, formEntity,fieldValidator)) .collect(Collectors.toList()); + fieldValidator.validate(); + return applicationFormFieldEntities; } public ApplicationFormFieldEntity createOrUpdateApplicationFormField(ApplicationFormFieldRequestBean applicationFormFieldRequestBean, - ApplicationFormEntity applicationFormEntity, List applicationFormFieldEntities, FormEntity formEntity) { + ApplicationFormEntity applicationFormEntity, List applicationFormFieldEntities, FormEntity formEntity,FieldValidator fieldValidator) { ApplicationFormFieldEntity applicationFormFieldEntity = new ApplicationFormFieldEntity(); @@ -506,7 +516,7 @@ public class ApplicationDao { .filter(setting -> "isRequestedAmount".equals(setting.getName()) && Boolean.TRUE.equals(setting.getValue())) .findFirst() .ifPresent(setting -> { - + Object fieldValue = applicationFormFieldRequestBean.getFieldValue(); if(fieldValue!=null) { try { @@ -538,6 +548,7 @@ public class ApplicationDao { } } } + calculationProcessForFormula(applicationFormEntity,contentResponseBeans,applicationFormFieldRequestBean,fieldValidator); Utils.setIfUpdated(applicationFormFieldEntity::getFieldId, applicationFormFieldEntity::setFieldId, applicationFormFieldRequestBean.getFieldId()); if (applicationFormFieldRequestBean.getFieldValue() != null) { @@ -560,7 +571,6 @@ public class ApplicationDao { VersionHistoryRequest.builder().request(request).actionType(actionType).oldData(oldApplicationFormFieldData).newData(applicationFormField).build()); log.info("Version history logged for action: {}, Field ID: {}", actionType, applicationFormFieldEntity.getFieldId()); - return applicationFormField; } @@ -669,7 +679,7 @@ public class ApplicationDao { return documentIds; } - private List validateDocumentIds(String documentId) { + public List validateDocumentIds(String documentId) { if (documentId != null && !documentId.isEmpty()) { return Arrays.stream(documentId.split(",")) .map(Long::parseLong) @@ -818,7 +828,7 @@ public class ApplicationDao { if(formApplicationResponse.getContent() != null && formApplicationResponse.getFormFields() != null) { formApplicationResponses.add(formApplicationResponse); } - + } public FormApplicationResponse processForm(FormEntity formEntity, ApplicationEntity applicationEntity) { @@ -954,7 +964,7 @@ public class ApplicationDao { return (int) Math.round(progress); } public void validateFormFields(ApplicationRequestBean request, FormEntity formEntity) { - + // List contentResponseBeans=Utils.convertJsonStringToList(formEntity.getContent(),ContentResponseBean.class); List contentResponseBeans=formDao.convertFormEntityToFormResponseBean(formEntity).getContent(); @@ -1034,7 +1044,7 @@ public class ApplicationDao { SystemEmailTemplateResponse systemEmailTemplateResponse = systemEmailTemplatesService .retrieveTemplateByTypeAndCall(SystemEmailTemplatesEntityTypeEnum.APPLICATION_SUBMISSION_TO_USER_AND_COMPANY, hub, null); - + // Create the map for subject placeholders Map subjectPlaceholders = new HashMap<>(); subjectPlaceholders.put("{{call_name}}", call.getName()); @@ -1114,8 +1124,13 @@ public class ApplicationDao { } emailLogRequest.setRecipientEmails(hub.getEmail()); emailNotificationDao.sendMail(hub.getId(), subject, body, List.of(hub.getEmail()),emailLogRequest); + List listDefaultSystemReceiverEmail = Arrays.stream(defaultSystemReceiverEmail.split(",")) + .map(String::trim) + .filter(email -> !email.isEmpty()) + .toList(); + emailLogRequest.setRecipientEmails(defaultSystemReceiverEmail); - emailNotificationDao.sendMail(hub.getId(), subject, body, List.of(defaultSystemReceiverEmail),emailLogRequest); + emailNotificationDao.sendMail(hub.getId(), subject, body, listDefaultSystemReceiverEmail,emailLogRequest); emailLogRequest.setRecipientEmails(rinaldoEmail); emailNotificationDao.sendMail(hub.getId(), subject, body, List.of(rinaldoEmail),emailLogRequest); } @@ -1211,17 +1226,17 @@ public class ApplicationDao { } public ApplicationSignedDocumentResponse getSignedDocument(HttpServletRequest request, Long applicationId) { - + ApplicationEntity applicationEntity = validateApplication(applicationId); // validator.validateUserWithCompany(request, applicationEntity.getCompanyId()); - + if (validator.checkIsPreInstructor()) { ApplicationEvaluationEntity applicationEvaluationEntity = applicationEvaluationService.validateApplicationEvaluationByApplicationId(applicationId); validator.validatePreInstructor(request, applicationEvaluationEntity.getUserId()); } else { validator.validateUserId(request, applicationEntity.getUserId()); } - + ApplicationSignedDocumentEntity applicationSignedDocument = applicationSignedDocumentRepository .findByApplicationIdAndStatus(applicationId, ApplicationSignedDocumentStatusEnum.ACTIVE.getValue()); if(applicationSignedDocument == null) { @@ -1230,11 +1245,11 @@ public class ApplicationDao { } return convertApplicationSignedDocumentToApplicationSignedDocumentResponse(applicationSignedDocument); } - + public void deleteSignedDocument(HttpServletRequest request, Long applicationId) { ApplicationEntity applicationEntity = validateApplication(applicationId); validator.validateUserWithCompany(request, applicationEntity.getCompanyId()); - + ApplicationSignedDocumentEntity applicationSignedDocument = applicationSignedDocumentRepository .findByApplicationIdAndStatus(applicationId, ApplicationSignedDocumentStatusEnum.ACTIVE.getValue()); //cloned entity for old data @@ -1552,5 +1567,135 @@ public class ApplicationDao { } } + public void calculationProcessForFormula(ApplicationFormEntity applicationFormEntity, List contentResponseBeans, ApplicationFormFieldRequestBean applicationFormFieldRequestBean,FieldValidator fieldValidator) { + List formulaValue = new ArrayList<>(); + String formulaValueOpt=null; + String label=null; + for (ContentResponseBean contentResponseBean:contentResponseBeans){ + if(contentResponseBean.getId().equals(applicationFormFieldRequestBean.getFieldId())){ + for (SettingResponseBean settingResponseBean:contentResponseBean.getSettings()){ + if (settingResponseBean.getName().equals("label")){ + label= String.valueOf(settingResponseBean.getValue()); + } + if(settingResponseBean.getName().equals("formula")){ + String value= (String) settingResponseBean.getValue(); + formulaValueOpt=value; + formulaValue=Utils.extractValues(value); + } + } + } + } + Map mappedFormulaValue = new HashMap<>(); + Object fieldValue = applicationFormFieldRequestBean.getFieldValue(); + if (formulaValueOpt != null && fieldValue==null) { + fieldValue=0; + } + + for (ContentResponseBean contentResponseBean : contentResponseBeans) { + String contentId = contentResponseBean.getId(); + + // Extract variable values once per contentResponseBean to avoid repeated stream operations + Set variableValues = contentResponseBean.getSettings().stream() + .filter(setting -> "variable".equals(setting.getName())) + .flatMap(setting -> { + Object value = setting.getValue(); // Get the raw value + if (value instanceof String) { + return Stream.of((String) value); // Handle single String case + } else if (value instanceof List) { + return ((List) value).stream() + .filter(item -> item instanceof String) // Ensure it's a String + .map(item -> (String) item); // Convert to String + } else { + return Stream.empty(); // Ignore unexpected types + } + }) + .collect(Collectors.toSet()); // Collect into a Set for uniqueness + + for (String formula : formulaValue) { + if (variableValues.contains(formula)) { // O(1) lookup instead of O(n) + mappedFormulaValue.put(formula, contentId); + } + } + } + Map updatedMappedFormulaValue = new HashMap<>(); + + for (Map.Entry entry : mappedFormulaValue.entrySet()) { + String variable = entry.getKey(); + String contentId = entry.getValue(); + + // Repository call using contentId + Optional optionalEntity = applicationFormFieldRepository.findByApplicationFormIdAndFieldId(applicationFormEntity.getId(),contentId); + // If entity is found, extract fieldValue and fieldId + optionalEntity.ifPresent(entity -> { + String entityFieldValue = entity.getFieldValue(); // Assuming getter method exists + String fieldId = entity.getFieldId(); // Assuming getter method exists + String tableType = contentResponseBeans.stream() + .filter(content -> content.getId().equals(fieldId)) // Match Content ID with fieldId + .flatMap(content -> content.getSettings().stream()) // Extract settings + .filter(setting -> "criteria_table_columns".equals(setting.getName())) // Match name + .map(setting -> setting.getName()) // Return the name of the setting + .findFirst() // Get the first match + .orElse(null); // Default to null if no match + + if(tableType!=null){ + JSONObject jsonObject = new JSONObject(entityFieldValue); + + // Extract the value of total + entityFieldValue = jsonObject.getString("total"); + + } + + updatedMappedFormulaValue.put(fieldId, entityFieldValue); + }); + } + if(formulaValueOpt==null || formulaValueOpt.isEmpty()){ + return; + } + double finalValue = evaluateFormula(formulaValueOpt, mappedFormulaValue, updatedMappedFormulaValue); + + fieldValidator.formulaValidation(fieldValue, finalValue, label); + } + + + public static double evaluateFormula(String formula, Map mappedFormulaValue, Map updatedMappedFormulaValue) { + // Step 1: Extract all placeholders (variables) like {rest}, {another_var}, etc. + Pattern pattern = Pattern.compile("\\{(.*?)\\}"); + Matcher matcher = pattern.matcher(formula); + List variables = new ArrayList<>(); + + while (matcher.find()) { + variables.add(matcher.group(1)); // Extract variable names inside the curly braces + } + + // Step 2: Replace placeholders with corresponding fieldValue + Map variableValues = new HashMap<>(); + + for (String variable : variables) { + String fieldId = mappedFormulaValue.get(variable); + if (fieldId != null && updatedMappedFormulaValue.containsKey(fieldId)) { + String fieldValueStr = updatedMappedFormulaValue.get(fieldId); + try { + double fieldValue = Double.parseDouble(fieldValueStr); // Assuming fieldValue is numeric + variableValues.put(variable, fieldValue); + } catch (NumberFormatException e) { + // Handle invalid number format gracefully (e.g., log an error or default to 0) + variableValues.put(variable, 0.0); + } + } + } + + // Step 3: Replace variables in the formula with their corresponding values + String expression = formula; + for (String variable : variables) { + Double value = variableValues.get(variable); + if (value != null) { + // Replace {variable} with its corresponding value in the formula + expression = expression.replace("{" + variable + "}", String.valueOf(value)); + } + } + + // Step 4: Evaluate the mathematical expression + return Utils.evaluateExpression(expression); + } } diff --git a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationEvaluationDao.java b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationEvaluationDao.java index 74a14114..2c36b86c 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationEvaluationDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationEvaluationDao.java @@ -12,10 +12,7 @@ import net.gepafin.tendermanagement.model.request.*; 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.LoggingUtil; -import net.gepafin.tendermanagement.util.Utils; -import net.gepafin.tendermanagement.util.Validator; +import net.gepafin.tendermanagement.util.*; 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; @@ -25,6 +22,7 @@ import org.springframework.stereotype.Component; import org.springframework.util.CollectionUtils; import java.math.BigDecimal; +import java.text.MessageFormat; import java.time.Duration; import java.time.LocalDateTime; import java.time.temporal.ChronoUnit; @@ -32,6 +30,7 @@ import java.util.*; import java.util.function.Function; import java.util.stream.Collectors; +import static net.gepafin.tendermanagement.util.Utils.log; import static net.gepafin.tendermanagement.util.Utils.setIfUpdated; @Component @@ -116,6 +115,34 @@ public class ApplicationEvaluationDao { @Autowired private HubService hubService; + @Autowired + private EvaluationFormService evaluationFormService; + + @Autowired + private EvaluationFormDao evaluationFormDao; + + @Autowired + private ApplicationEvaluationFormRepository applicationEvaluationFormRepository; + + @Autowired + private ApplicationEvaluationFormFieldRepository applicationEvaluationFormFieldRepository; + + @Autowired + private ApplicationDao applicationDao; + + @Autowired + private ApplicationEvaluationService applicationEvaluationService; + + @Autowired + private CallDao callDao; + + @Autowired + private EvaluationFormRepository evaluationFormRepository; + + @Autowired + private ObjectMapper objectMapper; + + private ApplicationEvaluationEntity convertToEntity(UserEntity user, ApplicationEvaluationRequest req, Long assignedApplciationId) { ApplicationEvaluationEntity entity = new ApplicationEvaluationEntity(); @@ -142,6 +169,7 @@ public class ApplicationEvaluationDao { entity.setSuspendedDays(0L); entity.setStartDate(DateTimeUtil.DateServerToUTC(LocalDateTime.now())); entity.setEndDate(DateTimeUtil.DateServerToUTC(application.getSubmissionDate().plusDays(30))); + entity.setEvaluationVersion(application.getEvaluationVersion()); entity.setStatus(ApplicationEvaluationStatusTypeEnum.OPEN.getValue()); return entity; } @@ -263,9 +291,13 @@ public class ApplicationEvaluationDao { response.setNote(entity.getNote()); response.setMotivation(entity.getMotivation()); response.setStatus(ApplicationEvaluationStatusTypeEnum.valueOf(entity.getStatus())); + response.setEvaluationVersion(EvaluationVersionEnum.valueOf(entity.getEvaluationVersion())); response.setEvaluationEndDate(entity.getEndDate()); response.setCreatedDate(entity.getCreatedDate()); response.setUpdatedDate(entity.getUpdatedDate()); + response.setNumberOfCheck(entity.getAssignedApplicationsEntity().getApplication().getCall().getNumberOfCheck()); + response.setProductId(entity.getAssignedApplicationsEntity().getApplication().getCall().getProductId()); + } @@ -612,6 +644,7 @@ public class ApplicationEvaluationDao { ApplicationEvaluationEntity oldApplicationEvaluation = null; ApplicationEntity application = applicationService.validateApplication(assignedApplications.get().getApplication().getId()); VersionActionTypeEnum actionType = VersionActionTypeEnum.INSERT; + validateApplicationEvaluationRequest(req, application); if (existingEntityOptional.isPresent()) { entity = existingEntityOptional.get(); oldApplicationEvaluation = Utils.getClonedEntityForData(entity); @@ -683,7 +716,14 @@ public class ApplicationEvaluationDao { } } - private void updateAmendmentDocumentsAndFormFields(List applicationAmendmentRequestEntities, List amendmentFormFields) { + private void validateApplicationEvaluationRequest(ApplicationEvaluationRequest req, ApplicationEntity application) { + if(EvaluationVersionEnum.V2.getValue().equals(application.getEvaluationVersion())) { + req.setChecklist(null); + req.setCriteria(null); + } + } + + private void updateAmendmentDocumentsAndFormFields(List applicationAmendmentRequestEntities, List amendmentFormFields) { // Iterate through amendment request entities // @@ -1107,6 +1147,7 @@ public class ApplicationEvaluationDao { List applicationFormEntities = applicationFormRepository.findByApplicationId(applicationId); response.setApplicationId(application.getId()); response.setAssignedApplicationId(assignedApplications.getId()); + response.setEvaluationVersion(EvaluationVersionEnum.valueOf(application.getEvaluationVersion())); response.setNote(null); response.setMotivation(null); response.setApplicationStatus(ApplicationStatusTypeEnum.valueOf(application.getStatus())); @@ -1115,6 +1156,8 @@ public class ApplicationEvaluationDao { response.setEvaluationEndDate(entity.getEndDate()); LocalDateTime callEndDate = application.getCall().getEndDate(); response.setCallEndDate(callEndDate); + response.setNumberOfCheck(call.getNumberOfCheck()); + response.setProductId(call.getProductId()); setCriteriaResponses(entity, application.getId(), response, evaluationCriterias); setChecklistResponses(entity, application.getId(), response, checklistEntities); setFileResponses(entity, application.getId(), response, applicationFormEntities); @@ -1907,5 +1950,321 @@ public class ApplicationEvaluationDao { loggingUtil.addVersionHistory(VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.UPDATE).oldData(oldApplicationEvaluation).newData(savedEntity).build()); return convertToResponse(savedEntity); } + + public ApplicationEvaluationFormResponse createApplicationEvaluation(HttpServletRequest request, ApplicationEvaluationFormRequestBean applicationEvaluationFormRequestBean, Long evaluationFormId, Long assignedApplicationId){ + + UserEntity user = validator.validateUser(request); + AssignedApplicationsEntity assignedApplicationsEntity = assignedApplicationsService.validateAssignedApplication(assignedApplicationId); + ApplicationEntity application = applicationService.validateApplication(assignedApplicationsEntity.getApplication().getId()); + + // Convert FormRequestBean to ApplicationEvaluationRequest + ApplicationEvaluationRequest req = convertToApplicationEvaluationRequest(applicationEvaluationFormRequestBean); + + // Call the existing method to create or update evaluation + ApplicationEvaluationResponse evaluationResponse = createOrUpdateApplicationEvaluation(user, req, assignedApplicationId); + + ApplicationEvaluationEntity entity = applicationEvaluationService.validateApplicationEvaluation(evaluationResponse.getId()); + + //Handling Application Evaluation form + EvaluationFormEntity evaluationFormEntity = evaluationFormService.validateEvaluationForm(evaluationFormId); + validateFormFields(applicationEvaluationFormRequestBean,evaluationFormEntity); +// ApplicationEvaluationEntity applicationEvaluationEntity = applicationEvaluationRepository.findByAssignedApplicationsId(assignedApplicationId); + ApplicationEvaluationFormEntity applicationEvaluationFormEntity = getApplicationEvaluationFormOrCreate(evaluationFormEntity,entity); + createOrUpdateMultipleFormFields(applicationEvaluationFormRequestBean.getFormFields(), applicationEvaluationFormEntity, evaluationFormEntity); + return processEvaluationForm(entity); + } + + private ApplicationEvaluationFormEntity getApplicationEvaluationFormOrCreate(EvaluationFormEntity evaluationFormEntity, ApplicationEvaluationEntity applicationEvaluationEntity) { + + ApplicationEvaluationFormEntity applicationEvaluationFormEntity = applicationEvaluationFormRepository.findByEvaluationIdAndEvaluationFormId(applicationEvaluationEntity.getId(), evaluationFormEntity.getId()); + ApplicationEvaluationFormEntity oldApplicationEvaluationFormEntity = Utils.getClonedEntityForData(applicationEvaluationFormEntity); + if (applicationEvaluationFormEntity == null) { + applicationEvaluationFormEntity = createApplicationEvaluationFormEntity(applicationEvaluationEntity, evaluationFormEntity); + + /** This code is responsible for adding a version history log for the "Create application evalaution form" operation. **/ + loggingUtil.addVersionHistory( + VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.INSERT).oldData(oldApplicationEvaluationFormEntity).newData(applicationEvaluationFormEntity) + .build()); + } + return applicationEvaluationFormEntity; + } + + public ApplicationEvaluationFormEntity createApplicationEvaluationFormEntity(ApplicationEvaluationEntity applicationEvaluationEntity, EvaluationFormEntity evaluationFormEntity) { + ApplicationEvaluationFormEntity applicationEvaluationFormEntity = new ApplicationEvaluationFormEntity(); + applicationEvaluationFormEntity.setApplicationId(applicationEvaluationEntity.getApplicationId()); + applicationEvaluationFormEntity.setEvaluationForm(evaluationFormEntity); + applicationEvaluationFormEntity.setApplicationEvaluation(applicationEvaluationEntity); + applicationEvaluationFormEntity.setIsDeleted(false); + return saveApplicationEvaluationFormEntity(applicationEvaluationFormEntity); + } + + public void validateFormFields(ApplicationEvaluationFormRequestBean request, EvaluationFormEntity evaluationFormEntity) { + + List contentResponseBeans=evaluationFormDao.convertEvaluationFormEntityToEvaluationFormResponseBean(evaluationFormEntity).getContent(); + + List requestFields = request.getFormFields(); + + Map contentMap = contentResponseBeans.stream() + .collect(Collectors.toMap(ContentResponseBean::getId, ContentResponseBean::getLabel)); // Change getLabel() if needed + FieldValidator validator = FieldValidator.create(); + for (ApplicationFormFieldRequestBean requestField : requestFields) { + String fieldId = requestField.getFieldId(); + + if (!contentMap.containsKey(fieldId)) { + validator.addError(MessageFormat.format(Translator.toLocale(GepafinConstant.FIELD_ID_NOT_FOUND), fieldId)); + } + + } + validator.validate(); + } + + public ApplicationEvaluationFormEntity saveApplicationEvaluationFormEntity(ApplicationEvaluationFormEntity applicationEvaluationFormEntity) { + return applicationEvaluationFormRepository.save(applicationEvaluationFormEntity); + } + + public List createOrUpdateMultipleFormFields(List formFieldRequestBeans, + ApplicationEvaluationFormEntity applicationEvaluationFormEntity, EvaluationFormEntity evaluationFormEntity) { + + List existingFields = applicationEvaluationFormFieldRepository.findByApplicationEvaluationFormId(applicationEvaluationFormEntity.getId()); + + return formFieldRequestBeans.stream().map(requestBean -> createOrUpdateApplicationEvaluationFormField(requestBean, applicationEvaluationFormEntity, existingFields, evaluationFormEntity)) + .collect(Collectors.toList()); + } + + public ApplicationEvaluationFormFieldEntity createOrUpdateApplicationEvaluationFormField(ApplicationFormFieldRequestBean applicationFormFieldRequestBean, + ApplicationEvaluationFormEntity applicationEvaluationFormEntity, + List applicationEvaluationFormFieldEntities, + EvaluationFormEntity evaluationFormEntity){ + ApplicationEvaluationFormFieldEntity applicationEvaluationFormFieldEntity = new ApplicationEvaluationFormFieldEntity(); + validateFileUploadDocuments(applicationFormFieldRequestBean, evaluationFormEntity); + VersionActionTypeEnum actionType = VersionActionTypeEnum.INSERT; + ApplicationEvaluationFormFieldEntity oldApplicationEvaluationFormFieldData = null; + if (applicationEvaluationFormFieldEntities == null || applicationEvaluationFormFieldEntities.isEmpty()) { + applicationEvaluationFormFieldEntity = new ApplicationEvaluationFormFieldEntity(); + applicationEvaluationFormFieldEntity.setApplicationEvaluationForm(applicationEvaluationFormEntity); + applicationEvaluationFormFieldEntity.setIsDeleted(false); + }else{ + for (ApplicationEvaluationFormFieldEntity existingFieldEntity : applicationEvaluationFormFieldEntities) { + if (existingFieldEntity.getFieldId().equals(applicationFormFieldRequestBean.getFieldId())) { + applicationEvaluationFormFieldEntity = existingFieldEntity; + oldApplicationEvaluationFormFieldData = Utils.getClonedEntityForData(existingFieldEntity); + actionType = VersionActionTypeEnum.UPDATE; + break; + } else { + applicationEvaluationFormFieldEntity.setApplicationEvaluationForm(applicationEvaluationFormEntity); + applicationEvaluationFormFieldEntity.setIsDeleted(Boolean.FALSE); + } + } + } + Utils.setIfUpdated(applicationEvaluationFormFieldEntity::getFieldId, applicationEvaluationFormFieldEntity::setFieldId, applicationFormFieldRequestBean.getFieldId()); + + if (applicationFormFieldRequestBean.getFieldValue() != null) { + applicationEvaluationFormFieldEntity.setFieldValue(Utils.convertObjectToJsonString(applicationFormFieldRequestBean.getFieldValue())); + } else { + applicationEvaluationFormFieldEntity.setFieldValue(null); + } + + ApplicationEvaluationFormFieldEntity savedEvaluationFormFieldEntity = applicationEvaluationFormFieldRepository.save(applicationEvaluationFormFieldEntity); + + loggingUtil.addVersionHistory(VersionHistoryRequest.builder().request(request).actionType(actionType).oldData(oldApplicationEvaluationFormFieldData).newData(savedEvaluationFormFieldEntity).build()); + + log.info("Version history logged for action: {}, Field ID: {}", actionType, applicationEvaluationFormFieldEntity.getFieldId()); + + return savedEvaluationFormFieldEntity; + } + + private List validateFileUploadDocuments(ApplicationFormFieldRequestBean applicationFormFieldRequestBean, EvaluationFormEntity evaluationFormEntity) { + List documentIds=null; + + List contentResponseBeans=evaluationFormDao.convertEvaluationFormEntityToEvaluationFormResponseBean(evaluationFormEntity).getContent(); + for (ContentResponseBean contentResponseBean:contentResponseBeans){ + if(Boolean.TRUE.equals(contentResponseBean.getName().equals("fileupload"))) { + if (contentResponseBean.getId().equals(applicationFormFieldRequestBean.getFieldId())) { + Object fieldValueObject = applicationFormFieldRequestBean.getFieldValue(); + if (fieldValueObject instanceof String) { + // Safely cast the object to a string + String documentId = (String) fieldValueObject; + // Now you can use documentId as needed + documentIds = applicationDao.validateDocumentIds(documentId); + } + } + } + } + return documentIds; + } + + + private List createEvaluationFormFieldResponse( + List evaluationFormFieldEntities, + ApplicationEvaluationFormEntity applicationEvaluationFormEntity){ + List evaluationFormFieldResponseBeans = new ArrayList<>(); + List contentResponseBeans =evaluationFormDao.convertEvaluationFormEntityToEvaluationFormResponseBean(applicationEvaluationFormEntity.getEvaluationForm()).getContent(); + + for (ApplicationEvaluationFormFieldEntity applicationEvaluationFormFieldEntity : evaluationFormFieldEntities) { + + Optional fileUploadContent = contentResponseBeans.stream() + .filter(contentResponseBean -> "fileupload".equals(contentResponseBean.getName()) && + contentResponseBean.getId().equals(applicationEvaluationFormFieldEntity.getFieldId())) + .findFirst(); + + List documentResponseBeans = new ArrayList<>(); + if (fileUploadContent.isPresent()) { + String documentId = applicationEvaluationFormFieldEntity.getFieldValue(); + if (documentId != null && !documentId.isEmpty()) { + documentResponseBeans = Arrays.stream(documentId.split(",")) + .map(String::trim) + .map(Long::parseLong) + .map(docId -> { + DocumentEntity documentEntity = documentService.validateDocument(docId); +// if (Boolean.FALSE.equals(DocumentSourceTypeEnum.APPLICATION.getValue().equals(documentEntity.getSource()))) { +// throw new CustomValidationException(Status.NOT_FOUND,Translator.toLocale(GepafinConstant.DOCUMENT_NOT_FOUND)); +// } + return documentEntity; + }) + .map(callDao::convertToDocumentResponseBean) + .collect(Collectors.toList()); + } + } + ApplicationEvaluationFormFieldReponseBean responseBean = convertToEvaluationFormFieldResponseBean( + applicationEvaluationFormFieldEntity, applicationEvaluationFormEntity.getId()); + if (!documentResponseBeans.isEmpty()) { + responseBean.setFieldValue(documentResponseBeans); + } + evaluationFormFieldResponseBeans.add(responseBean); + } + return evaluationFormFieldResponseBeans; + + } + + private ApplicationEvaluationFormFieldReponseBean convertToEvaluationFormFieldResponseBean(ApplicationEvaluationFormFieldEntity entity,Long applicationEvaluationFormId){ + ApplicationEvaluationFormFieldReponseBean applicationEvaluationFormFieldReponseBean = new ApplicationEvaluationFormFieldReponseBean(); + applicationEvaluationFormFieldReponseBean.setApplicationEvaluationFormId(applicationEvaluationFormId); + applicationEvaluationFormFieldReponseBean.setFieldId(entity.getFieldId()); + if(entity.getFieldValue() != null) { + applicationEvaluationFormFieldReponseBean.setFieldValue(Utils.getFieldValueAsObject(entity.getFieldValue())); + } + applicationEvaluationFormFieldReponseBean.setId(entity.getId()); + applicationEvaluationFormFieldReponseBean.setCreatedDate(entity.getCreatedDate()); + applicationEvaluationFormFieldReponseBean.setUpdatedDate(entity.getUpdatedDate()); + return applicationEvaluationFormFieldReponseBean; + } + + private ApplicationEvaluationFormResponse convertToApplicationEvaluationResponseBean(ApplicationEvaluationResponse applicationEvaluationResponse){ + ApplicationEvaluationFormResponse response = new ApplicationEvaluationFormResponse(); + response.setId(applicationEvaluationResponse.getId()); + response.setApplicationId(applicationEvaluationResponse.getApplicationId()); + response.setNote(applicationEvaluationResponse.getNote()); + response.setEvaluationVersion(applicationEvaluationResponse.getEvaluationVersion()); + response.setCreatedDate(applicationEvaluationResponse.getCreatedDate()); + response.setUpdatedDate(applicationEvaluationResponse.getUpdatedDate()); + response.setApplicationStatus(applicationEvaluationResponse.getApplicationStatus()); + response.setAssignedApplicationId(applicationEvaluationResponse.getAssignedApplicationId()); + response.setMinScore(applicationEvaluationResponse.getMinScore()); + response.setStatus(applicationEvaluationResponse.getStatus()); + response.setFiles(applicationEvaluationResponse.getFiles()); + response.setEvaluationDocument(applicationEvaluationResponse.getEvaluationDocument()); + response.setAmendmentDetails(applicationEvaluationResponse.getAmendmentDetails()); + response.setBeneficiary(applicationEvaluationResponse.getBeneficiary()); + response.setAssignedUserId(applicationEvaluationResponse.getAssignedUserId()); + response.setAssignedUserName(applicationEvaluationResponse.getAssignedUserName()); + response.setProtocolNumber(applicationEvaluationResponse.getProtocolNumber()); + response.setCallName(applicationEvaluationResponse.getCallName()); + response.setMotivation(applicationEvaluationResponse.getMotivation()); + response.setSubmissionDate(applicationEvaluationResponse.getSubmissionDate()); + response.setEvaluationEndDate(applicationEvaluationResponse.getEvaluationEndDate()); + response.setCallEndDate(applicationEvaluationResponse.getCallEndDate()); + response.setCompanyName(applicationEvaluationResponse.getCompanyName()); + response.setAssignedAt(applicationEvaluationResponse.getAssignedAt()); + response.setNdg(applicationEvaluationResponse.getNdg()); + response.setAppointmentId(applicationEvaluationResponse.getAppointmentId()); + response.setAmountRequested(applicationEvaluationResponse.getAmountRequested()); + response.setAmountAccepted(applicationEvaluationResponse.getAmountAccepted()); + response.setDateAccepted(applicationEvaluationResponse.getDateAccepted()); + response.setDateRejected(applicationEvaluationResponse.getDateRejected()); + + return response; + } + + public ApplicationEvaluationFormResponse getApplicationEvaluationForm(HttpServletRequest request, Long applicationId, Long assignedApplicationId ){ + + if (applicationId == null && assignedApplicationId == null) { + throw new CustomValidationException(Status.BAD_REQUEST,Translator.toLocale(GepafinConstant.EITHER_APPLICATION_ID_OR_ASSIGNED_APPLICATION_ID_MUST_BE_PROVIDED)); + } + + ApplicationEvaluationEntity evaluationEntity = applicationEvaluationRepository.findByApplicationIdAndAssignedApplicationId(applicationId, assignedApplicationId); + + return (evaluationEntity != null) ? processEvaluationForm(evaluationEntity) : null; + } + + private ApplicationEvaluationFormResponse processEvaluationForm(ApplicationEvaluationEntity evaluationEntity){ + + Object convertedResponse = convertToResponse(evaluationEntity); + + ApplicationEvaluationFormResponse response = objectMapper.convertValue(convertedResponse, ApplicationEvaluationFormResponse.class); + EvaluationFormEntity evaluationFormEntity = evaluationFormRepository.findByCallIdAndIsDeletedFalse(evaluationEntity.getAssignedApplicationsEntity().getApplication().getCall().getId()); + + if (evaluationFormEntity != null) { + response.setApplicationEvaluationFormResponse(convertEvaluationFormToResponse(evaluationFormEntity, evaluationEntity)); + } + + return response; + } + + private ApplicationEvaluationFormResponseBean convertEvaluationFormToResponse(EvaluationFormEntity evaluationForm, ApplicationEvaluationEntity applicationEvaluationEntity) { + ApplicationEvaluationFormResponseBean applicationEvaluationFormResponseBean = createEvaluationFormResponse(evaluationForm); + + ApplicationEvaluationFormEntity applicationEvaluationFormEntity = applicationEvaluationFormRepository.findByEvaluationIdAndEvaluationFormId(applicationEvaluationEntity.getId(), evaluationForm.getId()); + + if(applicationEvaluationFormEntity!=null) { + List applicationEvaluationFormFieldEntities = applicationEvaluationFormFieldRepository.findByApplicationEvaluationFormId(applicationEvaluationFormEntity.getId()); + List evaluationFormFieldResponseBeans = createEvaluationFormFieldResponse(applicationEvaluationFormFieldEntities, applicationEvaluationFormEntity); + applicationEvaluationFormResponseBean.setFormFields(evaluationFormFieldResponseBeans); + } + + return applicationEvaluationFormResponseBean; + } + + private ApplicationEvaluationFormResponseBean createEvaluationFormResponse(EvaluationFormEntity evaluationFormEntity) { + ApplicationEvaluationFormResponseBean evaluationFormResponseBean = new ApplicationEvaluationFormResponseBean(); + evaluationFormResponseBean.setId(evaluationFormEntity.getId()); + evaluationFormResponseBean.setLabel(evaluationFormEntity.getLabel()); + evaluationFormResponseBean.setCallId(evaluationFormEntity.getCall().getId()); + evaluationFormResponseBean.setContent(evaluationFormDao.convertEvaluationFormEntityToEvaluationFormResponseBean(evaluationFormEntity).getContent()); + return evaluationFormResponseBean; + } + + public ApplicationEvaluationVersionResponse getApplicationEvaluationVersion(HttpServletRequest request, Long applicationId){ + + log.info("Fetching application evaluation version with ID: {}", applicationId); + + ApplicationEntity applicationEntity = applicationService.validateApplication(applicationId); + return buildApplicationEvaluationVersionResponse(applicationEntity); + + } + private ApplicationEvaluationVersionResponse buildApplicationEvaluationVersionResponse(ApplicationEntity applicationEntity) { + ApplicationEvaluationVersionResponse response = new ApplicationEvaluationVersionResponse(); + response.setApplicationId(applicationEntity.getId()); + response.setCallId(applicationEntity.getCall().getId()); + response.setCompanyId(applicationEntity.getCompanyId()); + response.setEvaluationVersion(EvaluationVersionEnum.valueOf(applicationEntity.getEvaluationVersion())); + response.setEvaluationId(applicationEntity.getApplicationEvaluationId()); + return response; + } + + public static ApplicationEvaluationRequest convertToApplicationEvaluationRequest(ApplicationEvaluationFormRequestBean formRequestBean) { + ApplicationEvaluationRequest request = new ApplicationEvaluationRequest(); + request.setFiles(formRequestBean.getFiles()); + request.setEvaluationDocument(formRequestBean.getEvaluationDocument()); + request.setAmendmentDetails(formRequestBean.getAmendmentDetails()); + request.setNote(formRequestBean.getNote()); + request.setApplicationStatus(formRequestBean.getApplicationStatus()); + request.setMotivation(formRequestBean.getMotivation()); + request.setAmountAccepted(formRequestBean.getAmountAccepted()); + + request.setCriteria(null); + request.setChecklist(null); + + return request; + } } diff --git a/src/main/java/net/gepafin/tendermanagement/dao/AssignedApplicationsDao.java b/src/main/java/net/gepafin/tendermanagement/dao/AssignedApplicationsDao.java index 9729fd85..05c65292 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/AssignedApplicationsDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/AssignedApplicationsDao.java @@ -200,6 +200,8 @@ public class AssignedApplicationsDao { if(applicationEvaluationEntity.isPresent()){ assignedApplicationsResponse.setEvaluationEndDate(applicationEvaluationEntity.get().getEndDate()); } + assignedApplicationsResponse.setNumberOfCheck(application.getCall().getNumberOfCheck()); + assignedApplicationsResponse.setProductId(application.getCall().getProductId()); return assignedApplicationsResponse; } diff --git a/src/main/java/net/gepafin/tendermanagement/dao/CallDao.java b/src/main/java/net/gepafin/tendermanagement/dao/CallDao.java index ce9fefd9..277fb68c 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/CallDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/CallDao.java @@ -201,6 +201,8 @@ public class CallDao { callEntity.setStartTime(DateTimeUtil.parseTime(createCallRequest.getStartTime())); callEntity.setEndTime(DateTimeUtil.parseTime(createCallRequest.getEndTime())); callEntity.setHub(userEntity.getHub()); + callEntity.setNumberOfCheck(createCallRequest.getNumberOfCheck()); + callEntity.setProductId(createCallRequest.getProductId()); callEntity = callRepository.save(callEntity); /** This code is responsible for adding a version history log for the "Create Call" operation. **/ @@ -607,6 +609,8 @@ public class CallDao { setIfUpdated(callEntity::getEndTime, callEntity::setEndTime, DateTimeUtil.parseTime(updateCallRequest.getEndTime())); setIfUpdated(callEntity::getConfidi, callEntity::setConfidi, updateCallRequest.getConfidi()); setIfUpdated(callEntity::getEvaluationVersion, callEntity::setEvaluationVersion, updateCallRequest.getEvaluationVersion().getValue()); + setIfUpdated(callEntity::getNumberOfCheck, callEntity::setNumberOfCheck, updateCallRequest.getNumberOfCheck()); + setIfUpdated(callEntity::getProductId, callEntity::setProductId, updateCallRequest.getProductId()); callEntity = callRepository.save(callEntity); /** This code is responsible for adding a version history log for the "update call step 1" operation **/ @@ -713,7 +717,8 @@ public class CallDao { callDetailsResponseBean.setPhoneNumber(callEntity.getPhoneNumber()); callDetailsResponseBean.setCreatedDate(callEntity.getCreatedDate()); callDetailsResponseBean.setUpdatedDate(callEntity.getUpdatedDate()); - + callDetailsResponseBean.setNumberOfCheck(callEntity.getNumberOfCheck()); + callDetailsResponseBean.setProductId(callEntity.getProductId()); return callDetailsResponseBean; } @@ -737,6 +742,8 @@ public class CallDao { createCallResponseBean.setFaq(faqService.getFaqByCallId(callEntity.getId())); createCallResponseBean.setAimedTo(amiedTo); createCallResponseBean.setCheckList(checkList); + createCallResponseBean.setNumberOfCheck(callEntity.getNumberOfCheck()); + createCallResponseBean.setProductId(callEntity.getProductId()); return createCallResponseBean; } diff --git a/src/main/java/net/gepafin/tendermanagement/dao/CompanyDao.java b/src/main/java/net/gepafin/tendermanagement/dao/CompanyDao.java index b014b779..3a527d9f 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/CompanyDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/CompanyDao.java @@ -230,8 +230,8 @@ public class CompanyDao { String responseJson = companyRequest.getVatCheckResponse() != null ? Utils.convertMapIntoJsonString(companyRequest.getVatCheckResponse()) : null; setIfUpdated(userWithCompanyEntity::getJson, userWithCompanyEntity::setJson, responseJson); } - setIfUpdated(userWithCompanyEntity::getPec, userWithCompanyEntity::setPec, userWithCompanyEntity.getPec()); - setIfUpdated(userWithCompanyEntity::getEmail, userWithCompanyEntity::setEmail, userWithCompanyEntity.getEmail()); + setIfUpdated(userWithCompanyEntity::getPec, userWithCompanyEntity::setPec, companyRequest.getPec()); + setIfUpdated(userWithCompanyEntity::getEmail, userWithCompanyEntity::setEmail, companyRequest.getEmail()); setIfUpdated(userWithCompanyEntity::getContactName, userWithCompanyEntity::setContactName, companyRequest.getContactName()); setIfUpdated(userWithCompanyEntity::getContactEmail, userWithCompanyEntity::setContactEmail, companyRequest.getContactEmail()); setIfUpdated(userWithCompanyEntity::getIsLegalRepresentant, userWithCompanyEntity::setIsLegalRepresentant, companyRequest.getIsLegalRepresentant()); diff --git a/src/main/java/net/gepafin/tendermanagement/dao/DashboardDao.java b/src/main/java/net/gepafin/tendermanagement/dao/DashboardDao.java index 31468d57..0e7f7802 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/DashboardDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/DashboardDao.java @@ -1,8 +1,9 @@ package net.gepafin.tendermanagement.dao; +import jakarta.servlet.http.HttpServletRequest; +import net.gepafin.tendermanagement.config.Translator; import net.gepafin.tendermanagement.constants.GepafinConstant; import net.gepafin.tendermanagement.entities.CompanyEntity; -import net.gepafin.tendermanagement.entities.UserActionEntity; import net.gepafin.tendermanagement.entities.UserEntity; import net.gepafin.tendermanagement.entities.UserWithCompanyEntity; import net.gepafin.tendermanagement.entities.*; @@ -11,17 +12,21 @@ import net.gepafin.tendermanagement.model.response.*; import net.gepafin.tendermanagement.repositories.*; import net.gepafin.tendermanagement.service.CompanyService; import net.gepafin.tendermanagement.util.Validator; +import net.gepafin.tendermanagement.web.rest.api.errors.CustomValidationException; +import net.gepafin.tendermanagement.web.rest.api.errors.ForbiddenAccessException; +import net.gepafin.tendermanagement.web.rest.api.errors.Status; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import java.math.BigDecimal; import java.math.RoundingMode; -import java.util.HashMap; -import java.util.List; -import java.util.Map; import java.util.*; import java.time.LocalDate; import java.time.LocalDateTime; +import java.util.List; +import java.util.HashMap; +import java.util.List; +import java.util.Map; import java.util.stream.Collectors; @@ -60,7 +65,7 @@ public class DashboardDao { public SuperAdminWidgetResponseBean getDashboardWidget(UserEntity requestedUserEntity) { SuperAdminWidgetResponseBean widgetResponseBean = new SuperAdminWidgetResponseBean(); widgetResponseBean.setWidget1(createWidget1(requestedUserEntity)); - Map widgetBars =getStatistics(requestedUserEntity); + Map widgetBars = getStatistics(requestedUserEntity); widgetResponseBean.setWidgetBars(widgetBars); return widgetResponseBean; } @@ -74,8 +79,8 @@ public class DashboardDao { setSubmittedApplications(widget1, requestedUserEntity); setDraftApplications(widget1, requestedUserEntity); setNumberOfCompanies(widget1, requestedUserEntity); - setAmountRequested(widget1,requestedUserEntity); - setAmountAccepted(widget1,requestedUserEntity); + setAmountRequested(widget1, requestedUserEntity); + setAmountAccepted(widget1, requestedUserEntity); return widget1; } @@ -193,6 +198,7 @@ public class DashboardDao { return stats; } + // public Page getUserAction(UserEntity requestedUserEntity){ // Pageable pageable = PageRequest.of(0, 20); // Get the first 20 records // List roles=List.of(RoleStatusEnum.ROLE_PRE_INSTRUCTOR.getValue(),RoleStatusEnum.ROLE_GEPAFIN_OPERATOR.getValue(),RoleStatusEnum.ROLE_INSTRUCTOR_MANAGER.getValue()); @@ -251,7 +257,7 @@ public class DashboardDao { responseBean.setEvaluationAverageTime(averageTime != null ? averageTime.setScale(2, RoundingMode.HALF_UP) : BigDecimal.ZERO); } LocalDate twoDaysLater = LocalDate.now().plusDays(2); - List statusList =Arrays.asList( ApplicationEvaluationStatusTypeEnum.OPEN.getValue(), ApplicationEvaluationStatusTypeEnum.SOCCORSO.getValue()); + List statusList = Arrays.asList(ApplicationEvaluationStatusTypeEnum.OPEN.getValue(), ApplicationEvaluationStatusTypeEnum.SOCCORSO.getValue()); Long dueApplications = applicationEvaluationRepository.countDueApplicationsBetween( applicationIds, LocalDate.now(), @@ -263,6 +269,7 @@ public class DashboardDao { responseBean.setNumberOfDueApplication(dueApplications); } } + private AmendmentWidgetResponseBean initializeAmendmentResponseBean() { return AmendmentWidgetResponseBean.builder() .totalAmendments(0L) @@ -278,21 +285,24 @@ public class DashboardDao { AmendmentWidgetResponseBean amendmentWidgetResponseBean = initializeAmendmentResponseBean(); Long hubId = userEntity.getHub().getId(); - List applicationIds = getApplicationIdsForUserOrHub(userEntity,hubId); - setAmendmentCounts(applicationIds,amendmentWidgetResponseBean, hubId); - calculateExpiringRequestsIn48Hours(applicationIds,amendmentWidgetResponseBean, hubId); - calculateAverageResponseDays(applicationIds,amendmentWidgetResponseBean,hubId); + List applicationIds = getApplicationIdsForUserOrHub(userEntity, hubId, null); + setAmendmentCounts(applicationIds, amendmentWidgetResponseBean, hubId); + calculateExpiringRequestsIn48Hours(applicationIds, amendmentWidgetResponseBean, hubId); + calculateAverageResponseDays(applicationIds, amendmentWidgetResponseBean, hubId); return amendmentWidgetResponseBean; } - public List getApplicationIdsForUserOrHub(UserEntity userEntity, Long hubId) { - if (validator.checkIsPreInstructor()) { + + public List getApplicationIdsForUserOrHub(UserEntity userEntity, Long hubId, Long userId) { + if (userId != null) { + return assignedApplicationsRepository.findApplicationIdsByUserIdAndIsDeletedFalse(userId); + } else if (validator.checkIsPreInstructor()) { return assignedApplicationsRepository.findApplicationIdsByUserIdAndIsDeletedFalse(userEntity.getId()); } else { return applicationRepository.findApplicationIdsByHubId(hubId); } } - private void setAmendmentCounts(List applicationIds,AmendmentWidgetResponseBean responseBean, Long hubId) { + private void setAmendmentCounts(List applicationIds, AmendmentWidgetResponseBean responseBean, Long hubId) { Long totalAmendment = applicationAmendmentRequestRepository.countAmendmentsByApplicationIds(applicationIds); if (totalAmendment != null) { @@ -316,7 +326,7 @@ public class DashboardDao { } } - private void calculateExpiringRequestsIn48Hours(List applicationIds ,AmendmentWidgetResponseBean responseBean, Long hubId) { + private void calculateExpiringRequestsIn48Hours(List applicationIds, AmendmentWidgetResponseBean responseBean, Long hubId) { // Define the statuses to filter List statuses = List.of( @@ -338,7 +348,7 @@ public class DashboardDao { } } - private void calculateAverageResponseDays(List applicationIds ,AmendmentWidgetResponseBean responseBean, Long hubId) { + private void calculateAverageResponseDays(List applicationIds, AmendmentWidgetResponseBean responseBean, Long hubId) { if (!applicationIds.isEmpty()) { BigDecimal averageResponseDays = applicationAmendmentRequestRepository @@ -361,7 +371,7 @@ public class DashboardDao { List applicationIds; if (validator.checkIsPreInstructor()) { results = assignedApplicationsRepository.countAssignedApplicationsWithStatus(userId, hubId); - applicationIds = assignedApplicationsRepository.findApplicationIdsByUserIdAndHubIdAndIsDeletedFalse(userId,hubId); + applicationIds = assignedApplicationsRepository.findApplicationIdsByUserIdAndHubIdAndIsDeletedFalse(userId, hubId); } else { results = assignedApplicationsRepository.countAssignedApplicationsForHub(hubId); applicationIds = assignedApplicationsRepository.findApplicationIdsByHubId(hubId); @@ -383,9 +393,9 @@ public class DashboardDao { LocalDate today = LocalDate.now(); LocalDate twoDaysLater = today.plusDays(2); - List statusList =Arrays.asList( ApplicationEvaluationStatusTypeEnum.OPEN.getValue(), ApplicationEvaluationStatusTypeEnum.SOCCORSO.getValue()); + List statusList = Arrays.asList(ApplicationEvaluationStatusTypeEnum.OPEN.getValue(), ApplicationEvaluationStatusTypeEnum.SOCCORSO.getValue()); Long dueApplications = applicationEvaluationRepository.countDueApplicationsBetween( - applicationIds, today, twoDaysLater,statusList + applicationIds, today, twoDaysLater, statusList ); response.setNumberOfApplicationExpiringIn48Hours(dueApplications != null ? dueApplications : 0L); } @@ -415,22 +425,24 @@ public class DashboardDao { ApplicationStatusTypeEnum.ADMISSIBLE.getValue() ); } + public BeneficiaryStatisticsResponseBean getStatisticsPageForBeneficiary(UserEntity userEntity, CompanyEntity company) { BeneficiaryStatisticsResponseBean widgetResponseBean = initializeBeneficiaryStatisticsBean(); UserWithCompanyEntity userWithCompanyEntity = companyService.getUserWithCompany(userEntity.getId(), company.getId()); Long hubId = userEntity.getHub().getId(); List statusList = getStatusList(); - Long submittedApplication = applicationRepository.countSubmittedApplicationsByHubIdAndUserId(hubId, userEntity.getId(), userWithCompanyEntity.getId(),statusList); + Long submittedApplication = applicationRepository.countSubmittedApplicationsByHubIdAndUserId(hubId, userEntity.getId(), userWithCompanyEntity.getId(), statusList); Long approvedApplication = getApplicationCountByStatus(hubId, userEntity.getId(), userWithCompanyEntity.getId(), ApplicationStatusTypeEnum.APPROVED); BigDecimal successRate = getSuccessRate(hubId, userEntity.getId(), userWithCompanyEntity.getId()); BigDecimal totalAmountRequested = applicationRepository.sumAmountRequestedByHubIdAndUserId(hubId, userEntity.getId(), userWithCompanyEntity.getId()); - updateApplicationWidget(widgetResponseBean.getApplicationWidget(), submittedApplication, approvedApplication, successRate,totalAmountRequested); + updateApplicationWidget(widgetResponseBean.getApplicationWidget(), submittedApplication, approvedApplication, successRate, totalAmountRequested); - Map widgetBars = getApplicationStatistics(userEntity,userWithCompanyEntity.getId()); + Map widgetBars = getApplicationStatistics(userEntity, userWithCompanyEntity.getId()); widgetResponseBean.setApplicationWidgetBars(widgetBars); return widgetResponseBean; } + private BeneficiaryStatisticsResponseBean initializeBeneficiaryStatisticsBean() { return BeneficiaryStatisticsResponseBean.builder() .applicationWidget(ApplicationWidget.builder() @@ -441,12 +453,15 @@ public class DashboardDao { .build()) .build(); } + private Long getApplicationCountByStatus(Long hubId, Long userId, Long userWithCompanyId, ApplicationStatusTypeEnum status) { return applicationRepository.countSubmittedApplicationsByHubIdAndUserIdAndStatus(hubId, userId, userWithCompanyId, status.getValue()); } + private BigDecimal getSuccessRate(Long hubId, Long userId, Long userWithCompanyId) { return applicationRepository.findSuccessRateByHubIdAndUserIdAndUserWithCompanyId(hubId, userId, userWithCompanyId); } + private void updateApplicationWidget(ApplicationWidget applicationWidget, Long submittedApplication, Long approvedApplication, BigDecimal successRate, BigDecimal totalAmountRequested) { applicationWidget.setSubmittedApplication(submittedApplication != null ? submittedApplication : 0L); applicationWidget.setApprovedApplication(approvedApplication != null ? approvedApplication : 0L); @@ -454,7 +469,7 @@ public class DashboardDao { applicationWidget.setTotalAmountFinanced(totalAmountRequested != null ? totalAmountRequested : BigDecimal.ZERO); } - public Map getApplicationStatistics(UserEntity requestedUser,Long userWithCompanyId) { + public Map getApplicationStatistics(UserEntity requestedUser, Long userWithCompanyId) { Map stats = new HashMap<>(); Map statusData = new HashMap<>(); @@ -499,11 +514,107 @@ public class DashboardDao { data.put(GepafinConstant.TOTAL_APPROVED, result[2]); return data; }).toList()); - - - - return stats; } + private PreInstructorWidgetResponseBean initializeDashboardPreInstructorResponseBean() { + return PreInstructorWidgetResponseBean.builder() + .assignedApplication(ApplicationToConsider.builder() + .totalAssignedApplication(0L) + .additionalApplicationPercentage(BigDecimal.ZERO) + .build()) + .evaluatedApplication(EvaluatedApplication.builder() + .evaluatedApplication(0L) + .dailyAverage(BigDecimal.ZERO) + .build()) + .averageEvaluationDays(AverageEvaluationTime.builder() + .averageEvlauationDaysRating(BigDecimal.ZERO) + .timeDifferenceFromAverage(BigDecimal.ZERO) + .build()) + .amendmentInProgress(RescueInstructorInProgress.builder() + .totalAmendmentInProgress(0L) + .expiringToday(0L) + .build()) + .build(); + } + public PreInstructorWidgetResponseBean getDashboardWidgetForPreInstructor(HttpServletRequest request, Long userId) { + UserEntity userEntity = validator.validateUser(request); + if (validator.checkIsPreInstructor() && userId == null) { + throw new CustomValidationException(Status.BAD_REQUEST, Translator.toLocale(GepafinConstant.USER_ID_NOT_NULL_MSG)); + } + if (userId != null) { + validator.validatePreInstructor(request, userId); + if (validator.checkIsInstructorManager() && !userEntity.getId().equals(userId)) { + throw new ForbiddenAccessException(Status.FORBIDDEN, + Translator.toLocale(GepafinConstant.PERMISSION_DENIED)); + } + } + PreInstructorWidgetResponseBean preInstructorWidgetResponseBean = initializeDashboardPreInstructorResponseBean(); + Long hubId = userEntity.getHub().getId(); + List applicationIds = getApplicationIdsForUserOrHub(userEntity, hubId,userId); + setPreInstructorWidgets(applicationIds, preInstructorWidgetResponseBean,hubId); + calculateAverageEvaluationTime(applicationIds, preInstructorWidgetResponseBean, hubId); + return preInstructorWidgetResponseBean; + } + private void setPreInstructorWidgets(List applicationIds, PreInstructorWidgetResponseBean responseBean,Long hubId) { + List assignedApplicationStatus = Arrays.asList(AssignedApplicationEnum.AWAITING.getValue(), AssignedApplicationEnum.OPEN.getValue()); + Long totalAssignedApplications = assignedApplicationsRepository.countAssignedApplicationsByApplicationIds(applicationIds,assignedApplicationStatus); + if (totalAssignedApplications != null) { + responseBean.getAssignedApplication().setTotalAssignedApplication(totalAssignedApplications); + } + LocalDateTime yesterday = LocalDateTime.now().minusDays(1); -} \ No newline at end of file + Long newApplicationsAddedYesterday = assignedApplicationsRepository.countApplicationsAddedYesterdayForHub(applicationIds, hubId, yesterday,assignedApplicationStatus); + if (newApplicationsAddedYesterday != null && totalAssignedApplications != null && totalAssignedApplications > 0) { + BigDecimal percentageAdded = BigDecimal.valueOf(newApplicationsAddedYesterday) + .divide(BigDecimal.valueOf(totalAssignedApplications), 4, RoundingMode.HALF_UP) + .multiply(BigDecimal.valueOf(100)); + responseBean.getAssignedApplication().setAdditionalApplicationPercentage(percentageAdded.setScale(2, RoundingMode.HALF_UP)); + } + + List statuses = Arrays.asList(ApplicationStatusTypeEnum.APPROVED.getValue(), ApplicationStatusTypeEnum.REJECTED.getValue()); + LocalDateTime sevenDaysAgo = LocalDateTime.now().minusDays(7); + Long evaluatedApplication = assignedApplicationsRepository.countEvaluatedApplicationsInLast7Days(applicationIds, statuses, sevenDaysAgo); + if (evaluatedApplication != null) { + responseBean.getEvaluatedApplication().setEvaluatedApplication(evaluatedApplication); + + BigDecimal dailyAverage = assignedApplicationsRepository.countDailyAverageEvaluatedApplicationsInLast7Days(applicationIds, statuses, sevenDaysAgo); + if (dailyAverage != null) { + responseBean.getEvaluatedApplication().setDailyAverage(dailyAverage.setScale(2, RoundingMode.HALF_UP)); // Rounded to 2 decimal places + } + } + List amendmentStatus =Arrays.asList( ApplicationAmendmentRequestEnum.AWAITING.getValue(), ApplicationAmendmentRequestEnum.RESPONSE_RECEIVED.getValue()); + Long rescueInstructorsInProgress = applicationAmendmentRequestRepository.countAmendmentsByApplicationIds(applicationIds,amendmentStatus); + if (rescueInstructorsInProgress != null) { + responseBean.getAmendmentInProgress().setTotalAmendmentInProgress(rescueInstructorsInProgress); + } + calculateExpiringRescueInstructorsToday(applicationIds,responseBean); + + } + private void calculateExpiringRescueInstructorsToday(List applicationIds, PreInstructorWidgetResponseBean responseBean) { + List statuses =Arrays.asList( ApplicationAmendmentRequestEnum.AWAITING.getValue(), ApplicationAmendmentRequestEnum.RESPONSE_RECEIVED.getValue()); + + LocalDateTime startOfDay = LocalDateTime.now().toLocalDate().atStartOfDay(); + + LocalDateTime endOfDay = startOfDay.plusDays(1).minusNanos(1); + + Long expiringToday = applicationAmendmentRequestRepository.countAmendmentsExpiringToday(applicationIds, statuses, startOfDay, endOfDay); + + if (expiringToday != null) { + responseBean.getAmendmentInProgress().setExpiringToday(expiringToday); + } + } + + private void calculateAverageEvaluationTime(List applicationIds, PreInstructorWidgetResponseBean responseBean, Long hubId) { + + if (Boolean.FALSE.equals(applicationIds.isEmpty())) { + BigDecimal averageTime = applicationEvaluationRepository.findAverageEvaluationTimeByApplicationIds(applicationIds); + responseBean.getAverageEvaluationDays().setAverageEvlauationDaysRating( + averageTime != null ? averageTime.setScale(2, RoundingMode.HALF_UP) : BigDecimal.ZERO.setScale(2, RoundingMode.HALF_UP) + ); + +// +// BigDecimal timeDifference = applicationEvaluationRepository.findTimeDifferenceFromAverage(applicationIds); +// responseBean.getAverageEvaluationTime().setTimeDifferenceFromAverage(timeDifference != null ? timeDifference : BigDecimal.ZERO); + } + } +} diff --git a/src/main/java/net/gepafin/tendermanagement/dao/EmailNotificationDao.java b/src/main/java/net/gepafin/tendermanagement/dao/EmailNotificationDao.java index 3988b35a..8133e5f7 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/EmailNotificationDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/EmailNotificationDao.java @@ -94,7 +94,19 @@ public class EmailNotificationDao { subjectPlaceholders.put("{{company_name}}", company.getCompanyName()); // bodyPlaceholders.put("{{legal_mail}}", legalMail); String subject = Utils.replacePlaceholders(systemEmailTemplateResponse.getSubject(), subjectPlaceholders); - String body = Utils.replacePlaceholders(systemEmailTemplateResponse.getHtmlContent(), bodyPlaceholders); + String body; + if ("t7jh5wfg9QXylNaTZkPoE".equals(hubEntity.getUniqueUuid()) && templateType.equals(SystemEmailTemplatesEntity.SystemEmailTemplatesEntityTypeEnum.DOCUMENTATION_INTEGRATION_REQUEST)) { + bodyPlaceholders.put("{{email_signature}}", hubEntity.getEmailSignature()); + bodyPlaceholders.put("{{platform_link}}",hubEntity.getDomainName()); + body = Utils.replacePlaceholders(GepafinConstant.DOCUMENTATION_INTEGRATION_REQUEST_SVILUPPUMBRIA, bodyPlaceholders); + } + else if ("t7jh5wfg9QXylNaTZkPoE".equals(hubEntity.getUniqueUuid()) && templateType.equals(SystemEmailTemplatesEntity.SystemEmailTemplatesEntityTypeEnum.INADMISSIBILITY_TEMPLATE)) { + bodyPlaceholders.put("{{email_signature}}", hubEntity.getEmailSignature()); + body = Utils.replacePlaceholders(GepafinConstant.APPLICATION_REJECTED_SVILUPPUMBRIA, bodyPlaceholders); + } + else { + body = Utils.replacePlaceholders(systemEmailTemplateResponse.getHtmlContent(), bodyPlaceholders); + } return new EmailContentResponse(subject, body, systemEmailTemplateResponse); } diff --git a/src/main/java/net/gepafin/tendermanagement/dao/EvaluationFormDao.java b/src/main/java/net/gepafin/tendermanagement/dao/EvaluationFormDao.java index 594aa24d..e5361e83 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/EvaluationFormDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/EvaluationFormDao.java @@ -21,17 +21,13 @@ package net.gepafin.tendermanagement.dao; import org.springframework.stereotype.Component; import java.time.LocalDateTime; - import java.util.Collections; import java.util.List; - import java.util.Optional; - import java.util.Set; - import java.util.stream.Collectors; @Component public class EvaluationFormDao { @Autowired - private EvalualtionFormRepository evaluationFormRepository; + private EvaluationFormRepository evaluationFormRepository; @Autowired private CallDao callDao; diff --git a/src/main/java/net/gepafin/tendermanagement/dao/FormDao.java b/src/main/java/net/gepafin/tendermanagement/dao/FormDao.java index 1c7ed019..4311076f 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/FormDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/FormDao.java @@ -1,9 +1,12 @@ package net.gepafin.tendermanagement.dao; import jakarta.servlet.http.HttpServletRequest; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import net.gepafin.tendermanagement.config.Translator; import net.gepafin.tendermanagement.constants.GepafinConstant; import net.gepafin.tendermanagement.entities.*; +import net.gepafin.tendermanagement.enums.CallStatusEnum; import net.gepafin.tendermanagement.enums.VersionActionTypeEnum; import net.gepafin.tendermanagement.model.request.*; import net.gepafin.tendermanagement.model.response.ContentResponseBean; @@ -35,6 +38,8 @@ import java.util.stream.Collectors; @Component public class FormDao { + private final Logger log = LoggerFactory.getLogger(FormDao.class); + @Autowired private FormRepository formRepository; @@ -118,6 +123,10 @@ public class FormDao { //cloned entity for old call data. CallEntity oldCallData = Utils.getClonedEntityForData(callEntity); + if(callEntity.getStatus().equals(CallStatusEnum.PUBLISH.getValue())) { + throw new CustomValidationException(Status.VALIDATION_ERROR, + Translator.toLocale(GepafinConstant.PUBLISHED_CALL_NOT_UPDATE)); + } List flowDataEntities = flowDataRepository.findByCallId(callEntity.getId()); List flowEdgesEntities = flowEdgesRepository.findByCallId(callEntity.getId()); if (Boolean.FALSE.equals(flowDataEntities.isEmpty() || flowDataEntities == null) || Boolean.FALSE.equals(flowEdgesEntities.isEmpty() || flowEdgesEntities == null)) { @@ -198,8 +207,9 @@ public class FormDao { String formFieldId,Long evaluationCriteriaId) { EvaluationCriteriaEntity evaluationCriteria = evaluationCriteriaService.validateEvaluationCriteria(evaluationCriteriaId); if (Boolean.FALSE.equals(evaluationCriteria.getCall().getId().equals(callEntity.getId()))) { - throw new CustomValidationException(Status.VALIDATION_ERROR, - Translator.toLocale(GepafinConstant.EVALUATIONCRITERIA_INVALID)); + log.info("This evaluation criterion does not belong to the current call. Expected Call ID = {}, Found Call ID = {}", + callEntity.getId(), evaluationCriteria.getCall().getId()); + return; } CriteriaFormFieldEntity criteriaFormField = new CriteriaFormFieldEntity(); criteriaFormField.setCallId(callEntity.getId()); @@ -466,7 +476,9 @@ public class FormDao { FieldValidatorBean fieldValidatorBean = Utils.convertSourceObjectToDestinationObject(contentResponseBean.getValidators(), FieldValidatorBean.class); String fieldValue = getFieldValue(contentResponseBean); - validator.isRequired(value, fieldValidatorBean.getIsRequired(), fieldValue); + + validator.isRequired(value, fieldValidatorBean.getIsRequired(), fieldValue) + .validateCustomTableValidation(value,fieldValidatorBean.getCustom(),fieldValue,contentResponseBean); }); if (Boolean.TRUE.equals(isSendValidationError)) { validator.validate(); diff --git a/src/main/java/net/gepafin/tendermanagement/dao/PdfDao.java b/src/main/java/net/gepafin/tendermanagement/dao/PdfDao.java index 8be69097..8247c321 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/PdfDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/PdfDao.java @@ -152,6 +152,31 @@ public class PdfDao { // Create value cell with rounded corners PdfPTable valueTable = new PdfPTable(1); valueTable.setWidthPercentage(100); + + + Object finalValue = value; + List criteriaObject = (List) contentResponseBean.getSettings().stream() + .filter(setting -> GepafinConstant.CRITERIA_TABLE_COLUMNS.equals(setting.getName())) + .findFirst() + .map(setting -> { + try { + // Assuming setting.getValue() contains the JSON string or object + return PdfUtils.extractRows(finalValue); + } catch (Exception e) { + throw new RuntimeException("Error extracting rows from setting value", e); + } + }) + .orElse(null); + + +// Update value if criteriaObject is not null + if (criteriaObject != null) { + value = criteriaObject; + } + + +// Update value if criteriaObject is not null + if (value instanceof List) { // Further check if the list contains Strings List list = (List) value; @@ -181,11 +206,10 @@ public class PdfDao { document.add(valueTable); } else if (!list.isEmpty() && list.get(0) instanceof Map) { - Object object = value; - String stringvalue = Utils.convertToString(object); - List> fieldValueList = Utils.convertJsonStringIntoJsonList(stringvalue); - - document = createPdfTable(fieldValueList, document, contentResponseBean); + Object object = value; + String stringvalue = Utils.convertToString(object); + List> fieldValueList = Utils.convertJsonStringIntoJsonList(stringvalue); + document = createPdfTable(fieldValueList, document, contentResponseBean); } } else { @@ -231,27 +255,29 @@ public class PdfDao { document.add(valueTable); } else { - String fieldValue1= (String) value; - if(Utils.isValidDateString(fieldValue1)){ - fieldValue1=Utils.formatDateString(String.valueOf(value)); - } - if(Boolean.TRUE.equals(Utils.isItalianFormattedAmount(fieldValue)) ){ - fieldValue= String.valueOf(Utils.convertToItalianFormat(fieldValue)); - } + if (value instanceof String) { + String fieldValue1 = (String) value; + if (Utils.isValidDateString(fieldValue1)) { + fieldValue1 = Utils.formatDateString(String.valueOf(value)); + } + if(contentResponseBean.getName().equals("numberinput") && Boolean.TRUE.equals(Utils.isNumeric(fieldValue))){ + fieldValue1=Utils.convertToItalianFormat(fieldValue); + } // PdfPCell valueCell = new PdfPCell(new Phrase(fieldValue1, valueFont)); - PdfPCell valueCell = PdfUtils.htmlToPdfPCell(fieldValue1, valueFont); - 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); - valueCell.setPaddingLeft(leftMargin); // Increase left margin for value - valueCell.setBorder(Rectangle.NO_BORDER); // Remove border for value cell - valueCell.setVerticalAlignment(Element.ALIGN_MIDDLE); - valueCell.setHorizontalAlignment(Element.ALIGN_LEFT); - valueCell.setCellEvent(new RoundedCorners()); // Apply rounded corners - valueTable.addCell(valueCell); - document.add(valueTable); - } + PdfPCell valueCell = PdfUtils.htmlToPdfPCell(fieldValue1, valueFont); + 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); + valueCell.setPaddingLeft(leftMargin); // Increase left margin for value + valueCell.setBorder(Rectangle.NO_BORDER); // Remove border for value cell + valueCell.setVerticalAlignment(Element.ALIGN_MIDDLE); + valueCell.setHorizontalAlignment(Element.ALIGN_LEFT); + valueCell.setCellEvent(new RoundedCorners()); // Apply rounded corners + valueTable.addCell(valueCell); + document.add(valueTable); + } + } } document.add(new Paragraph("\n")); // Add line break after each value @@ -264,11 +290,12 @@ public class PdfDao { Map formulaEnabledMap = new HashMap<>(); Map formulaTypeMap = new HashMap<>(); Map fieldTypeMap = new HashMap<>(); + Map totalMap = new HashMap<>(); Font lightGrayFont = FontFactory.getFont(FontFactory.HELVETICA, 12, Font.NORMAL, new BaseColor(110, 110, 110)); // Light gray contentResponseBean.getSettings().stream() - .filter(setting -> "table_columns".equals(setting.getName())) // Check for "table_columns" + .filter(setting -> "table_columns".equals(setting.getName()) || "criteria_table_columns".equals(setting.getName())) // Check for "table_columns" .map(SettingResponseBean::getValue) .filter(Objects::nonNull) // Ensure value is not null .filter(settingValue -> settingValue instanceof Map) // Ensure value is a Map @@ -283,7 +310,7 @@ public class PdfDao { Boolean isFormulaEnabled = (Boolean) fieldData.get("enableFormula"); String formulaType = (String) fieldData.get("lastRowFormula"); String fieldType = (String) fieldData.get("fieldtype"); // Get the field type (e.g., numeric) - + String total= (String) fieldData.get("lastRowText"); if (fieldName != null && fieldDataValue != null) { stateFieldMap.put(fieldName, fieldDataValue); } @@ -297,6 +324,9 @@ public class PdfDao { if (fieldType != null) { fieldTypeMap.put(fieldName, fieldType); // Store the fieldType in the map } + if(total!=null){ + totalMap.put(fieldName,total); + } }); PdfPTable table = new PdfPTable(stateFieldMap.size()); // Number of columns equals the number of map entries @@ -342,12 +372,15 @@ public class PdfDao { Object value = row.getOrDefault(key, ""); // Fetch value or use empty string if key not present // String fieldValue= (String) value; String fieldValue = value != null ? value.toString() : ""; - if(Boolean.TRUE.equals(Utils.isItalianFormattedAmount(fieldValue)) ){ - fieldValue= String.valueOf(Utils.convertToItalianFormat(fieldValue)); - } +// if(Boolean.TRUE.equals(Utils.isItalianFormattedAmount(fieldValue)) ){ +//// fieldValue= String.valueOf(Utils.convertToItalianFormat(fieldValue)); +// } if (Boolean.TRUE.equals(formulaEnabledMap.get(key)) && Boolean.TRUE.equals(GepafinConstant.NUMERIC.equalsIgnoreCase(fieldTypeMap.get(key)))) { calculateValue(key, fieldValue, formulaTypeMap, columnSums); } + if(Boolean.TRUE.equals(Utils.isNumeric(fieldValue))){ + fieldValue=Utils.convertToItalianFormat(fieldValue); + } PdfPCell dataCell = PdfUtils.htmlToPdfPCell(fieldValue != null ? fieldValue : "", textFont); dataCell.setBackgroundColor(new BaseColor(239, 243, 248)); // Light blue for the cell @@ -397,14 +430,19 @@ public class PdfDao { table.addCell(emptyCell); } } else { - PdfPCell emptyCell = new PdfPCell(new Phrase("")); + String total=null; + if (totalMap.containsKey(key)) { + total=totalMap.getOrDefault(key, ""); + } + PdfPCell emptyCell = new PdfPCell(new Phrase(total,lightGrayFont)); + emptyCell.setPaddingTop(8f); + emptyCell.setPaddingLeft(8f); emptyCell.setBackgroundColor(new BaseColor(239, 243, 248)); table.addCell(emptyCell); } } - // Add the last table to the document document.add(table); @@ -415,7 +453,7 @@ public class PdfDao { try { if (Boolean.FALSE.equals(StringUtils.isEmpty(fieldValue))) { // Use Locale.ITALY to parse the number with the Italian format (comma as decimal separator) - NumberFormat format = NumberFormat.getInstance(Locale.ITALY); + NumberFormat format = NumberFormat.getInstance(Locale.ENGLISH); Number number = format.parse(fieldValue); // Parse the fieldValue as a number double numericValue = number.doubleValue(); // Convert the parsed number to double diff --git a/src/main/java/net/gepafin/tendermanagement/dao/UserDao.java b/src/main/java/net/gepafin/tendermanagement/dao/UserDao.java index 0ffa0b42..acb098ef 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/UserDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/UserDao.java @@ -20,6 +20,7 @@ import net.gepafin.tendermanagement.util.LoggingUtil; 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.ForbiddenAccessException; import net.gepafin.tendermanagement.web.rest.api.errors.ResourceNotFoundException; import net.gepafin.tendermanagement.web.rest.api.errors.Status; @@ -597,5 +598,58 @@ public class UserDao { return userResponseBeans; } + public UserResponseBean updateUserDetails(HttpServletRequest request , Long userId, UpdateUserReqForBeneficiary userReq){ + log.info("Updating user by beneficiary with ID: {}", userId); + UserEntity userEntity = validator.validateUserId(request, userId); + + UserEntity oldUserEntity = Utils.getClonedEntityForData(userEntity); + log.info("Current user details: {}", userEntity); + log.info("New user details: {}", userReq); + + HubEntity hubEntity = hubService.valdateHub(userEntity.getHub().getId()); + String beneficiaryRoleType = RoleStatusEnum.ROLE_BENEFICIARY.getValue(); + + if (validator.checkIsBeneficiary()) { + // Validate if the new email already exists for another beneficiary in the same hub + boolean emailExistsForBeneficiary = userRepository.existsByEmailIgnoreCaseForBeneficiaries( + userReq.getEmail(), hubEntity.getUniqueUuid(), beneficiaryRoleType); + + if (emailExistsForBeneficiary) { + throw new CustomValidationException(Status.VALIDATION_ERROR, + Translator.toLocale(GepafinConstant.EMAIL_ALREADY_EXISTS)); + } + + setIfUpdated(userEntity::getEmail,userEntity::setEmail,userReq.getEmail()); // Only update email if role is beneficiary + } + + BeneficiaryEntity oldBeneficiaryEntity = null; + + if(userEntity.getBeneficiary()!=null) { + oldBeneficiaryEntity = Utils.getClonedEntityForData(userEntity.getBeneficiary()); + setIfUpdated(userEntity.getBeneficiary()::getFirstName, userEntity.getBeneficiary()::setFirstName, userReq.getFirstName()); + setIfUpdated(userEntity.getBeneficiary()::getLastName, userEntity.getBeneficiary()::setLastName, userReq.getLastName()); + setIfUpdated(userEntity.getBeneficiary()::getOrganization, userEntity.getBeneficiary()::setOrganization, userReq.getOrganization()); + setIfUpdated(userEntity.getBeneficiary()::getAddress, userEntity.getBeneficiary()::setAddress, userReq.getAddress()); + setIfUpdated(userEntity.getBeneficiary()::getPhoneNumber, userEntity.getBeneficiary()::setPhoneNumber, userReq.getPhoneNumber()); + setIfUpdated(userEntity.getBeneficiary()::getDateOfBirth, userEntity.getBeneficiary()::setDateOfBirth, userReq.getDateOfBirth()); + setIfUpdated(userEntity.getBeneficiary()::getCity, userEntity.getBeneficiary()::setCity, userReq.getCity()); + setIfUpdated(userEntity.getBeneficiary()::getCountry, userEntity.getBeneficiary()::setCountry, userReq.getCountry()); + + /** This code is responsible for adding a version history log for the "Update beneficiary details " operation **/ + loggingUtil.addVersionHistory(VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.INSERT).oldData(oldBeneficiaryEntity).newData(userEntity.getBeneficiary()).build()); + } + + userEntity = userRepository.save(userEntity); + + /** This code is responsible for adding a version history log for the "Update user details by beneficiary" operation **/ + loggingUtil.addVersionHistory(VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.INSERT).oldData(oldUserEntity).newData(userEntity).build()); + + return convertUserEntityToUserResponse(userEntity); + } + + + + + } diff --git a/src/main/java/net/gepafin/tendermanagement/entities/ApplicationEvaluationEntity.java b/src/main/java/net/gepafin/tendermanagement/entities/ApplicationEvaluationEntity.java index 6ab7b72c..045a1bdb 100644 --- a/src/main/java/net/gepafin/tendermanagement/entities/ApplicationEvaluationEntity.java +++ b/src/main/java/net/gepafin/tendermanagement/entities/ApplicationEvaluationEntity.java @@ -67,5 +67,8 @@ public class ApplicationEvaluationEntity extends BaseEntity{ @Column(name = "ACTIVE_DAYS") private Long activeDays; + + @Column(name = "evaluationVersion") + private String evaluationVersion; } diff --git a/src/main/java/net/gepafin/tendermanagement/entities/ApplicationEvaluationFormEntity.java b/src/main/java/net/gepafin/tendermanagement/entities/ApplicationEvaluationFormEntity.java new file mode 100644 index 00000000..251fb262 --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/entities/ApplicationEvaluationFormEntity.java @@ -0,0 +1,22 @@ +package net.gepafin.tendermanagement.entities; + +import jakarta.persistence.*; +import lombok.Data; + +@Entity +@Data +@Table(name = "APPLICATION_EVALUATION_FORM") +public class ApplicationEvaluationFormEntity extends BaseEntity{ + private Long applicationId; + + @Column(name="IS_DELETED") + private Boolean isDeleted; + + @ManyToOne + @JoinColumn(name = "EVALUATION_ID") + private ApplicationEvaluationEntity applicationEvaluation; + + @ManyToOne + @JoinColumn(name = "EVALUATION_FORM_ID") + private EvaluationFormEntity evaluationForm; +} diff --git a/src/main/java/net/gepafin/tendermanagement/entities/ApplicationEvaluationFormFieldEntity.java b/src/main/java/net/gepafin/tendermanagement/entities/ApplicationEvaluationFormFieldEntity.java new file mode 100644 index 00000000..913d8831 --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/entities/ApplicationEvaluationFormFieldEntity.java @@ -0,0 +1,24 @@ +package net.gepafin.tendermanagement.entities; + +import jakarta.persistence.*; +import lombok.Data; + +@Entity +@Data +@Table(name = "APPLICATION_EVALUATION_FORM_FIELD") +public class ApplicationEvaluationFormFieldEntity extends BaseEntity { + + @ManyToOne + @JoinColumn(name = "APPLICATION_EVALUATION_FORM_ID") + private ApplicationEvaluationFormEntity applicationEvaluationForm; + + @Column(name = "FIELD_ID") + private String fieldId; + + @Column(name = "FIELD_VALUE") + private String fieldValue; + + @Column(name="IS_DELETED") + private Boolean isDeleted; + +} diff --git a/src/main/java/net/gepafin/tendermanagement/entities/CallEntity.java b/src/main/java/net/gepafin/tendermanagement/entities/CallEntity.java index 990d27a1..a9098234 100644 --- a/src/main/java/net/gepafin/tendermanagement/entities/CallEntity.java +++ b/src/main/java/net/gepafin/tendermanagement/entities/CallEntity.java @@ -91,5 +91,11 @@ public class CallEntity extends BaseEntity { @Column(name = "evaluationVersion") private String evaluationVersion; + + @Column(name = "NUMBER_OF_CHECK") + private BigDecimal numberOfCheck; + + @Column(name = "PRODUCT_ID") + private BigDecimal productId; } diff --git a/src/main/java/net/gepafin/tendermanagement/enums/UserActionContextEnum.java b/src/main/java/net/gepafin/tendermanagement/enums/UserActionContextEnum.java index bdae22ca..25a056ae 100644 --- a/src/main/java/net/gepafin/tendermanagement/enums/UserActionContextEnum.java +++ b/src/main/java/net/gepafin/tendermanagement/enums/UserActionContextEnum.java @@ -35,6 +35,7 @@ public enum UserActionContextEnum { /** application action context **/ GET_APPLICATION("GET_APPLICATION"), CREATE_UPDATE_APPLICATION_FORM("CREATE_UPDATE_APPLICATION_FORM"), + GET_APPLICATION_EVALUATION_VERSION("GET_APPLICATION_EVALUATION_VERSION"), CREATE_APPLICATION("CREATE_APPLICATION"), DELETE_APPLICATION("DELETE_APPLICATION"), GET_ALL_APPLICATION("GET_ALL_APPLICATION"), @@ -97,6 +98,8 @@ public enum UserActionContextEnum { CREATE_UPDATE_APPLICATION_EVALUATION("CREATE_UPDATE_APPLICATION_EVALUATION"), GET_APPLICATION_EVALUATION("GET_APPLICATION_EVALUATION"), DELETE_APPLICATION_EVALUATION("DELETE_APPLICATION_EVALUATION"), + CREATE_UPDATE_APPLICATION_EVALUATION_FORM("CREATE_UPDATE_APPLICATION_EVALUATION_FORM"), + GET_APPLICATION_EVALUATION_FORM("GET_APPLICATION_EVALUATION_FORM"), /** Beneficiary Preferred Call action context **/ CREATE_BENEFICIARY_PREFERRED_CALL("CREATE_BENEFICIARY_PREFERRED_CALL"), @@ -144,6 +147,7 @@ public enum UserActionContextEnum { GET_DASHBOARD_WIDGET_FOR_BENEFICIARY("GET_DASHBOARD_WIDGET_FOR_BENEFICIARY"), GET_APPLICATION_DETAILS("GET_APPLICATION_DETAILS"), GET_AMENDMENT_DETAILS("GET_AMENDMENT_DETAILS"), + GET_DASHBOARD_WIDGET_FOR_PRE_INSTRUCTOR("GET_DASHBOARD_WIDGET_FOR_PRE_INSTRUCTOR"), GET_APPLICATION_DETAILS_FOR_EVALUATION("GET_APPLICATION_DETAILS_FOR_EVALUATION"), GET_STATISTICS_PAGE_FOR_BENEFICIARY("GET_STATISTICS_PAGE_FOR_BENEFICIARY"), diff --git a/src/main/java/net/gepafin/tendermanagement/model/request/ApplicationEvaluationFormRequestBean.java b/src/main/java/net/gepafin/tendermanagement/model/request/ApplicationEvaluationFormRequestBean.java new file mode 100644 index 00000000..d2c0e2dc --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/model/request/ApplicationEvaluationFormRequestBean.java @@ -0,0 +1,19 @@ +package net.gepafin.tendermanagement.model.request; + +import lombok.Data; +import net.gepafin.tendermanagement.enums.ApplicationStatusForEvaluation; + +import java.math.BigDecimal; +import java.util.List; + +@Data +public class ApplicationEvaluationFormRequestBean { + private List files; + private List evaluationDocument; + private List amendmentDetails; + private String note; + private ApplicationStatusForEvaluation applicationStatus; + private List formFields; + private String motivation; + private BigDecimal amountAccepted; +} diff --git a/src/main/java/net/gepafin/tendermanagement/model/request/CreateCallRequestStep1.java b/src/main/java/net/gepafin/tendermanagement/model/request/CreateCallRequestStep1.java index 75c2a3d0..ca8abd99 100644 --- a/src/main/java/net/gepafin/tendermanagement/model/request/CreateCallRequestStep1.java +++ b/src/main/java/net/gepafin/tendermanagement/model/request/CreateCallRequestStep1.java @@ -24,6 +24,10 @@ public class CreateCallRequestStep1 { private BigDecimal amountMax; + private BigDecimal numberOfCheck; + + private BigDecimal productId; + private List aimedTo; private String documentationRequested; diff --git a/src/main/java/net/gepafin/tendermanagement/model/request/UpdateCallRequestStep1.java b/src/main/java/net/gepafin/tendermanagement/model/request/UpdateCallRequestStep1.java index d63e5754..2ebda4b5 100644 --- a/src/main/java/net/gepafin/tendermanagement/model/request/UpdateCallRequestStep1.java +++ b/src/main/java/net/gepafin/tendermanagement/model/request/UpdateCallRequestStep1.java @@ -41,6 +41,10 @@ public class UpdateCallRequestStep1 { private List faq; + private BigDecimal numberOfCheck; + + private BigDecimal productId; + private EvaluationVersionEnum evaluationVersion; } diff --git a/src/main/java/net/gepafin/tendermanagement/model/request/UpdateUserReqForBeneficiary.java b/src/main/java/net/gepafin/tendermanagement/model/request/UpdateUserReqForBeneficiary.java new file mode 100644 index 00000000..3516db8f --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/model/request/UpdateUserReqForBeneficiary.java @@ -0,0 +1,18 @@ +package net.gepafin.tendermanagement.model.request; + +import lombok.Data; + +import java.time.LocalDateTime; + +@Data +public class UpdateUserReqForBeneficiary { + private String firstName; + private String lastName; + private String email; + private String phoneNumber; + private String organization; + private String address; + private String city; + private String country; + private LocalDateTime dateOfBirth; +} diff --git a/src/main/java/net/gepafin/tendermanagement/model/response/ApplicationEvaluationFormFieldReponseBean.java b/src/main/java/net/gepafin/tendermanagement/model/response/ApplicationEvaluationFormFieldReponseBean.java new file mode 100644 index 00000000..62a0aa82 --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/model/response/ApplicationEvaluationFormFieldReponseBean.java @@ -0,0 +1,15 @@ +package net.gepafin.tendermanagement.model.response; + +import lombok.Data; +import net.gepafin.tendermanagement.model.BaseBean; + +@Data +public class ApplicationEvaluationFormFieldReponseBean extends BaseBean { + private Long id; + + private Long applicationEvaluationFormId; + + private String fieldId; + + private Object fieldValue; +} diff --git a/src/main/java/net/gepafin/tendermanagement/model/response/ApplicationEvaluationFormResponse.java b/src/main/java/net/gepafin/tendermanagement/model/response/ApplicationEvaluationFormResponse.java new file mode 100644 index 00000000..f71cf808 --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/model/response/ApplicationEvaluationFormResponse.java @@ -0,0 +1,50 @@ +package net.gepafin.tendermanagement.model.response; + +import lombok.Data; +import net.gepafin.tendermanagement.enums.ApplicationEvaluationStatusTypeEnum; +import net.gepafin.tendermanagement.enums.ApplicationStatusTypeEnum; +import net.gepafin.tendermanagement.enums.EvaluationVersionEnum; + +import java.math.BigDecimal; +import java.time.LocalDateTime; +import java.util.List; + +@Data +public class ApplicationEvaluationFormResponse { + + + private Long id; + private Long applicationId; + private ApplicationStatusTypeEnum applicationStatus; + private Long assignedApplicationId; + private String note; + private ApplicationEvaluationStatusTypeEnum status; + private Long minScore; + private ApplicationEvaluationFormResponseBean applicationEvaluationFormResponse; + private List files; + private List evaluationDocument; + private List amendmentDetails; + private LocalDateTime createdDate; + private LocalDateTime updatedDate; + private String beneficiary; + private Long assignedUserId; + private String assignedUserName; + private Long protocolNumber; + private String callName; + private String motivation; + private LocalDateTime submissionDate; + private LocalDateTime evaluationEndDate; + private LocalDateTime callEndDate; + private String companyName; + private LocalDateTime assignedAt; + private String ndg; + private String appointmentId; + private BigDecimal amountRequested; + private BigDecimal amountAccepted; + private LocalDateTime dateAccepted; + private LocalDateTime dateRejected; + private EvaluationVersionEnum evaluationVersion; + private BigDecimal numberOfCheck; + private BigDecimal productId; + +} diff --git a/src/main/java/net/gepafin/tendermanagement/model/response/ApplicationEvaluationFormResponseBean.java b/src/main/java/net/gepafin/tendermanagement/model/response/ApplicationEvaluationFormResponseBean.java new file mode 100644 index 00000000..804d5845 --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/model/response/ApplicationEvaluationFormResponseBean.java @@ -0,0 +1,19 @@ +package net.gepafin.tendermanagement.model.response; + +import lombok.Data; + +import java.util.List; + +@Data +public class ApplicationEvaluationFormResponseBean { + + private Long id; + + private String label; + + private Long callId; + + private List content; + + private List formFields; +} diff --git a/src/main/java/net/gepafin/tendermanagement/model/response/ApplicationEvaluationResponse.java b/src/main/java/net/gepafin/tendermanagement/model/response/ApplicationEvaluationResponse.java index c2fcd6cb..312e6f35 100644 --- a/src/main/java/net/gepafin/tendermanagement/model/response/ApplicationEvaluationResponse.java +++ b/src/main/java/net/gepafin/tendermanagement/model/response/ApplicationEvaluationResponse.java @@ -3,6 +3,7 @@ package net.gepafin.tendermanagement.model.response; import lombok.Data; import net.gepafin.tendermanagement.enums.ApplicationEvaluationStatusTypeEnum; import net.gepafin.tendermanagement.enums.ApplicationStatusTypeEnum; +import net.gepafin.tendermanagement.enums.EvaluationVersionEnum; import java.math.BigDecimal; import java.time.LocalDateTime; @@ -43,4 +44,8 @@ public class ApplicationEvaluationResponse { private BigDecimal amountAccepted; private LocalDateTime dateAccepted; private LocalDateTime dateRejected; + private BigDecimal numberOfCheck; + private BigDecimal productId; + private EvaluationVersionEnum evaluationVersion; + } diff --git a/src/main/java/net/gepafin/tendermanagement/model/response/ApplicationEvaluationVersionResponse.java b/src/main/java/net/gepafin/tendermanagement/model/response/ApplicationEvaluationVersionResponse.java new file mode 100644 index 00000000..99f1ae75 --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/model/response/ApplicationEvaluationVersionResponse.java @@ -0,0 +1,13 @@ +package net.gepafin.tendermanagement.model.response; + +import lombok.Data; +import net.gepafin.tendermanagement.enums.EvaluationVersionEnum; + +@Data +public class ApplicationEvaluationVersionResponse { + private Long callId; + private Long companyId; + private Long applicationId; + private Long evaluationId; + private EvaluationVersionEnum evaluationVersion; +} diff --git a/src/main/java/net/gepafin/tendermanagement/model/response/ApplicationToConsider.java b/src/main/java/net/gepafin/tendermanagement/model/response/ApplicationToConsider.java new file mode 100644 index 00000000..b7f9715b --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/model/response/ApplicationToConsider.java @@ -0,0 +1,15 @@ +package net.gepafin.tendermanagement.model.response; + +import lombok.Builder; +import lombok.Data; + +import java.math.BigDecimal; + +@Builder +@Data +public class ApplicationToConsider { + + public Long totalAssignedApplication; + + private BigDecimal additionalApplicationPercentage; +} diff --git a/src/main/java/net/gepafin/tendermanagement/model/response/AssignedApplicationsResponse.java b/src/main/java/net/gepafin/tendermanagement/model/response/AssignedApplicationsResponse.java index 83c1ab0a..8597cafa 100644 --- a/src/main/java/net/gepafin/tendermanagement/model/response/AssignedApplicationsResponse.java +++ b/src/main/java/net/gepafin/tendermanagement/model/response/AssignedApplicationsResponse.java @@ -5,6 +5,7 @@ import net.gepafin.tendermanagement.enums.AssignedApplicationEnum; import net.gepafin.tendermanagement.enums.EvaluationVersionEnum; import net.gepafin.tendermanagement.model.BaseBean; +import java.math.BigDecimal; import java.time.LocalDateTime; @Data @@ -23,6 +24,8 @@ public class AssignedApplicationsResponse extends BaseBean { private LocalDateTime callEndDate; private String companyName; private LocalDateTime evaluationEndDate; + private BigDecimal numberOfCheck; + private BigDecimal productId; private EvaluationVersionEnum evaluationVersion; } diff --git a/src/main/java/net/gepafin/tendermanagement/model/response/AverageEvaluationTime.java b/src/main/java/net/gepafin/tendermanagement/model/response/AverageEvaluationTime.java new file mode 100644 index 00000000..0715d7e8 --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/model/response/AverageEvaluationTime.java @@ -0,0 +1,15 @@ +package net.gepafin.tendermanagement.model.response; + +import lombok.Builder; +import lombok.Data; + +import java.math.BigDecimal; + +@Builder +@Data +public class AverageEvaluationTime { + + private BigDecimal averageEvlauationDaysRating; + + private BigDecimal timeDifferenceFromAverage; +} diff --git a/src/main/java/net/gepafin/tendermanagement/model/response/CallDetailsResponseBean.java b/src/main/java/net/gepafin/tendermanagement/model/response/CallDetailsResponseBean.java index ebe82d1e..256a564b 100644 --- a/src/main/java/net/gepafin/tendermanagement/model/response/CallDetailsResponseBean.java +++ b/src/main/java/net/gepafin/tendermanagement/model/response/CallDetailsResponseBean.java @@ -57,5 +57,9 @@ public class CallDetailsResponseBean { private Long preferredCallId; + private BigDecimal numberOfCheck; + + private BigDecimal productId; + private EvaluationVersionEnum evaluationVersion; } diff --git a/src/main/java/net/gepafin/tendermanagement/model/response/CallResponse.java b/src/main/java/net/gepafin/tendermanagement/model/response/CallResponse.java index 01c36068..6390e91c 100644 --- a/src/main/java/net/gepafin/tendermanagement/model/response/CallResponse.java +++ b/src/main/java/net/gepafin/tendermanagement/model/response/CallResponse.java @@ -50,6 +50,10 @@ public class CallResponse { private String phoneNumber; + private BigDecimal numberOfCheck; + + private BigDecimal productId; + @JsonSerialize(using = DynamicLocalTimeSerializer.class) private LocalTime startTime; diff --git a/src/main/java/net/gepafin/tendermanagement/model/response/EvaluatedApplication.java b/src/main/java/net/gepafin/tendermanagement/model/response/EvaluatedApplication.java new file mode 100644 index 00000000..50df2089 --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/model/response/EvaluatedApplication.java @@ -0,0 +1,15 @@ +package net.gepafin.tendermanagement.model.response; + +import lombok.Builder; +import lombok.Data; + +import java.math.BigDecimal; + +@Builder +@Data +public class EvaluatedApplication { + + public Long evaluatedApplication; + + private BigDecimal dailyAverage; +} diff --git a/src/main/java/net/gepafin/tendermanagement/model/response/PreInstructorWidgetResponseBean.java b/src/main/java/net/gepafin/tendermanagement/model/response/PreInstructorWidgetResponseBean.java new file mode 100644 index 00000000..579d4df5 --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/model/response/PreInstructorWidgetResponseBean.java @@ -0,0 +1,20 @@ +package net.gepafin.tendermanagement.model.response; + +import lombok.Builder; +import lombok.Data; + +import java.math.BigDecimal; + +@Builder +@Data +public class PreInstructorWidgetResponseBean { + + private ApplicationToConsider assignedApplication; + + private EvaluatedApplication evaluatedApplication; + + private AverageEvaluationTime averageEvaluationDays; + + private RescueInstructorInProgress amendmentInProgress; + +} diff --git a/src/main/java/net/gepafin/tendermanagement/model/response/RescueInstructorInProgress.java b/src/main/java/net/gepafin/tendermanagement/model/response/RescueInstructorInProgress.java new file mode 100644 index 00000000..ec8502e1 --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/model/response/RescueInstructorInProgress.java @@ -0,0 +1,13 @@ +package net.gepafin.tendermanagement.model.response; + +import lombok.Builder; +import lombok.Data; + +@Builder +@Data +public class RescueInstructorInProgress { + + private Long totalAmendmentInProgress; + + private Long expiringToday; +} diff --git a/src/main/java/net/gepafin/tendermanagement/repositories/ApplicationAmendmentRequestRepository.java b/src/main/java/net/gepafin/tendermanagement/repositories/ApplicationAmendmentRequestRepository.java index 0ec7d668..fc492019 100644 --- a/src/main/java/net/gepafin/tendermanagement/repositories/ApplicationAmendmentRequestRepository.java +++ b/src/main/java/net/gepafin/tendermanagement/repositories/ApplicationAmendmentRequestRepository.java @@ -132,4 +132,22 @@ public interface ApplicationAmendmentRequestRepository extends JpaRepository= :startOfDay + AND e.start_date + INTERVAL '1 DAY' * e.response_days < :endOfDay + AND e.is_deleted = false +""", nativeQuery = true) + Long countAmendmentsExpiringToday( + @Param("applicationIds") List applicationIds, + @Param("statuses") List statuses, + @Param("startOfDay") LocalDateTime startOfDay, + @Param("endOfDay") LocalDateTime endOfDay + ); + + @Query("SELECT COUNT(a) FROM ApplicationAmendmentRequestEntity a WHERE a.applicationId IN :applicationIds AND a.status IN :statuses AND a.isDeleted = false") + Long countAmendmentsByApplicationIds(@Param("applicationIds") List applicationIds, @Param("statuses") List statuses); } diff --git a/src/main/java/net/gepafin/tendermanagement/repositories/ApplicationEvaluationFormFieldRepository.java b/src/main/java/net/gepafin/tendermanagement/repositories/ApplicationEvaluationFormFieldRepository.java new file mode 100644 index 00000000..07a0d318 --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/repositories/ApplicationEvaluationFormFieldRepository.java @@ -0,0 +1,18 @@ +package net.gepafin.tendermanagement.repositories; + +import net.gepafin.tendermanagement.entities.ApplicationEvaluationFormFieldEntity; +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; + +@Repository +public interface ApplicationEvaluationFormFieldRepository extends JpaRepository { + @Query("SELECT f FROM ApplicationEvaluationFormFieldEntity f " + + "WHERE f.applicationEvaluationForm.id = :applicationEvaluationFormId " + + "AND f.isDeleted = false") + List findByApplicationEvaluationFormId( + @Param("applicationEvaluationFormId") Long applicationEvaluationFormId); +} diff --git a/src/main/java/net/gepafin/tendermanagement/repositories/ApplicationEvaluationFormRepository.java b/src/main/java/net/gepafin/tendermanagement/repositories/ApplicationEvaluationFormRepository.java new file mode 100644 index 00000000..8e2fba81 --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/repositories/ApplicationEvaluationFormRepository.java @@ -0,0 +1,21 @@ +package net.gepafin.tendermanagement.repositories; + +import net.gepafin.tendermanagement.entities.ApplicationEvaluationFormEntity; +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; + +@Repository +public interface ApplicationEvaluationFormRepository extends JpaRepository { + + @Query("SELECT a FROM ApplicationEvaluationFormEntity a " + + "WHERE a.applicationEvaluation.id = :evaluationId " + + "AND a.evaluationForm.id = :evaluationFormId " + + "AND a.isDeleted = false") + ApplicationEvaluationFormEntity findByEvaluationIdAndEvaluationFormId( + @Param("evaluationId") Long evaluationId, + @Param("evaluationFormId") Long evaluationFormId); + + ApplicationEvaluationFormEntity findByApplicationEvaluation_IdAndIsDeletedFalse(Long evaluationId); +} diff --git a/src/main/java/net/gepafin/tendermanagement/repositories/ApplicationEvaluationRepository.java b/src/main/java/net/gepafin/tendermanagement/repositories/ApplicationEvaluationRepository.java index c1329470..9019aad4 100644 --- a/src/main/java/net/gepafin/tendermanagement/repositories/ApplicationEvaluationRepository.java +++ b/src/main/java/net/gepafin/tendermanagement/repositories/ApplicationEvaluationRepository.java @@ -21,6 +21,9 @@ public interface ApplicationEvaluationRepository extends JpaRepository findByIdAndIsDeletedFalse(Long id); Optional findByAssignedApplicationsEntity_IdAndIsDeletedFalse(Long assignedApplicationId); + @Query("SELECT ae FROM ApplicationEvaluationEntity ae WHERE ae.assignedApplicationsEntity.id = :assignedApplicationId AND ae.isDeleted = false") + ApplicationEvaluationEntity findByAssignedApplicationsId(Long assignedApplicationId); + Optional findByApplicationIdAndAssignedApplicationsEntity_IdAndIsDeletedFalse(Long applicationId, Long assignedApplicationId); Optional findFirstByIsDeletedFalseOrderByCreatedDateDesc(); @@ -64,5 +67,14 @@ public interface ApplicationEvaluationRepository extends JpaRepository statusList ); + @Query("SELECT ae FROM ApplicationEvaluationEntity ae " + + "WHERE ae.isDeleted = false " + + "AND (:applicationId IS NULL OR ae.applicationId = :applicationId) " + + "AND (:assignedApplicationId IS NULL OR ae.assignedApplicationsEntity.id = :assignedApplicationId)") + ApplicationEvaluationEntity findByApplicationIdAndAssignedApplicationId( + @Param("applicationId") Long applicationId, + @Param("assignedApplicationId") Long assignedApplicationId + ); + } diff --git a/src/main/java/net/gepafin/tendermanagement/repositories/ApplicationRepository.java b/src/main/java/net/gepafin/tendermanagement/repositories/ApplicationRepository.java index 67ff18cd..2434fac9 100644 --- a/src/main/java/net/gepafin/tendermanagement/repositories/ApplicationRepository.java +++ b/src/main/java/net/gepafin/tendermanagement/repositories/ApplicationRepository.java @@ -8,6 +8,8 @@ import org.springframework.data.repository.query.Param; import org.springframework.stereotype.Repository; import java.math.BigDecimal; +import java.time.LocalDate; +import java.time.LocalDateTime; import java.util.List; import java.util.Optional; diff --git a/src/main/java/net/gepafin/tendermanagement/repositories/AssignedApplicationsRepository.java b/src/main/java/net/gepafin/tendermanagement/repositories/AssignedApplicationsRepository.java index f48833aa..43a40f04 100644 --- a/src/main/java/net/gepafin/tendermanagement/repositories/AssignedApplicationsRepository.java +++ b/src/main/java/net/gepafin/tendermanagement/repositories/AssignedApplicationsRepository.java @@ -6,6 +6,8 @@ import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; import org.springframework.stereotype.Repository; +import java.math.BigDecimal; +import java.time.LocalDateTime; import java.util.List; import java.util.Optional; @@ -25,6 +27,25 @@ public interface AssignedApplicationsRepository extends JpaRepository findApplicationIdsByUserIdAndIsDeletedFalse(@Param("userId") Long userId); + + @Query("SELECT COUNT(a) FROM AssignedApplicationsEntity a WHERE a.application.id IN :applicationIds AND a.status IN :statuses AND a.isDeleted = false") + Long countAssignedApplicationsByApplicationIds(@Param("applicationIds") List applicationIds, @Param("statuses") List statuses); + + @Query(""" + SELECT COUNT(aa) + FROM AssignedApplicationsEntity aa + JOIN aa.application a + WHERE a.hubId = :hubId + AND a.isDeleted = false + AND aa.status IN :statuses + AND aa.createdDate >= :yesterday + AND aa.isDeleted = false + AND (:applicationIds IS NULL OR aa.application.id IN :applicationIds) + """) + Long countApplicationsAddedYesterdayForHub(@Param("applicationIds") List applicationIds, @Param("hubId") Long hubId, @Param("yesterday") LocalDateTime yesterday, @Param("statuses") List statuses); + + @Query("SELECT COUNT(a) FROM AssignedApplicationsEntity a WHERE a.application.id IN :applicationIds AND a.status = :status AND a.isDeleted = false") + Long countApplicationsByIdsAndStatus(@Param("applicationIds") List applicationIds, @Param("status") String status); @Query(""" SELECT @@ -65,6 +86,28 @@ public interface AssignedApplicationsRepository extends JpaRepository findApplicationIdsByHubId(@Param("hubId") Long hubId); + @Query(" SELECT COUNT(aa) FROM AssignedApplicationsEntity aa " + + "JOIN aa.application a " + + "WHERE a.status IN :statuses " + + "AND a.isDeleted = false " + + "AND a.updatedDate >= :sevenDaysAgo " + + "AND aa.status = 'CLOSE'" + + "AND aa.isDeleted = false " + + " AND (:applicationIds IS NULL OR aa.application.id IN :applicationIds) ") + Long countEvaluatedApplicationsInLast7Days(@Param("applicationIds") List applicationIds, + @Param("statuses") List statuses, + @Param("sevenDaysAgo") LocalDateTime sevenDaysAgo); + @Query("SELECT (COUNT(a) / 7.0) FROM AssignedApplicationsEntity aa " + + "JOIN aa.application a " + + "WHERE a.status IN :statuses " + + "AND a.isDeleted = false " + + "AND a.updatedDate >= :sevenDaysAgo " + + "AND aa.status = 'CLOSE'" + + "AND aa.isDeleted = false " + + "AND (:applicationIds IS NULL OR aa.application.id IN :applicationIds)") + BigDecimal countDailyAverageEvaluatedApplicationsInLast7Days(@Param("applicationIds") List applicationIds, + @Param("statuses") List statuses, + @Param("sevenDaysAgo") LocalDateTime sevenDaysAgo); } diff --git a/src/main/java/net/gepafin/tendermanagement/repositories/EvalualtionFormRepository.java b/src/main/java/net/gepafin/tendermanagement/repositories/EvaluationFormRepository.java similarity index 76% rename from src/main/java/net/gepafin/tendermanagement/repositories/EvalualtionFormRepository.java rename to src/main/java/net/gepafin/tendermanagement/repositories/EvaluationFormRepository.java index fb658f54..11db32e2 100644 --- a/src/main/java/net/gepafin/tendermanagement/repositories/EvalualtionFormRepository.java +++ b/src/main/java/net/gepafin/tendermanagement/repositories/EvaluationFormRepository.java @@ -1,13 +1,12 @@ package net.gepafin.tendermanagement.repositories; import net.gepafin.tendermanagement.entities.EvaluationFormEntity; -import net.gepafin.tendermanagement.entities.FormEntity; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; import java.util.List; @Repository -public interface EvalualtionFormRepository extends JpaRepository { +public interface EvaluationFormRepository extends JpaRepository { EvaluationFormEntity findByCallIdAndIsDeletedFalse(Long callId); EvaluationFormEntity findByIdAndIsDeletedFalse(Long formId); diff --git a/src/main/java/net/gepafin/tendermanagement/service/ApplicationEvaluationService.java b/src/main/java/net/gepafin/tendermanagement/service/ApplicationEvaluationService.java index 454030af..86140ac6 100644 --- a/src/main/java/net/gepafin/tendermanagement/service/ApplicationEvaluationService.java +++ b/src/main/java/net/gepafin/tendermanagement/service/ApplicationEvaluationService.java @@ -2,9 +2,12 @@ package net.gepafin.tendermanagement.service; import jakarta.servlet.http.HttpServletRequest; import net.gepafin.tendermanagement.entities.ApplicationEvaluationEntity; +import net.gepafin.tendermanagement.enums.FormActionEnum; +import net.gepafin.tendermanagement.model.request.ApplicationEvaluationFormRequestBean; import net.gepafin.tendermanagement.model.request.ApplicationEvaluationRequest; +import net.gepafin.tendermanagement.model.request.ApplicationRequestBean; import net.gepafin.tendermanagement.model.request.EvaluationDocumentRequest; -import net.gepafin.tendermanagement.model.response.ApplicationEvaluationResponse; +import net.gepafin.tendermanagement.model.response.*; import java.util.List; @@ -21,4 +24,10 @@ public interface ApplicationEvaluationService { ApplicationEvaluationEntity validateApplicationEvaluationByApplicationId(Long applicationId); + ApplicationEvaluationFormResponse createApplicationEvaluation(HttpServletRequest request, ApplicationEvaluationFormRequestBean applicationEvaluationFormRequestBean, Long evaluationId, Long evaluationFormId); + + ApplicationEvaluationFormResponse getApplicationEvaluationForm(HttpServletRequest request, Long applicationId, Long assignedApplicationId); + + ApplicationEvaluationVersionResponse getApplicationEvaluationVersion(HttpServletRequest request, Long applicationId); + } diff --git a/src/main/java/net/gepafin/tendermanagement/service/DashboardService.java b/src/main/java/net/gepafin/tendermanagement/service/DashboardService.java index 713a83c9..ac1bd636 100644 --- a/src/main/java/net/gepafin/tendermanagement/service/DashboardService.java +++ b/src/main/java/net/gepafin/tendermanagement/service/DashboardService.java @@ -2,6 +2,11 @@ package net.gepafin.tendermanagement.service; import jakarta.servlet.http.HttpServletRequest; import net.gepafin.tendermanagement.model.response.*; +import net.gepafin.tendermanagement.model.response.AmendmentWidgetResponseBean; +import net.gepafin.tendermanagement.model.response.ApplicationWidgetResponseBean; +import net.gepafin.tendermanagement.model.response.AssignedApplicationWidgetResponseBean; +import net.gepafin.tendermanagement.model.response.BeneficiaryWidgetResponseBean; +import net.gepafin.tendermanagement.model.response.SuperAdminWidgetResponseBean; public interface DashboardService { @@ -10,6 +15,7 @@ public interface DashboardService { public BeneficiaryWidgetResponseBean getDashboardWidgetForBeneficiary(HttpServletRequest request, Long companyId); public ApplicationWidgetResponseBean getApplicationDetails(HttpServletRequest request); public AmendmentWidgetResponseBean getAmendmentDetails(HttpServletRequest request); + public PreInstructorWidgetResponseBean getDashboardWidgetForPreInstructor(HttpServletRequest request,Long userId); public AssignedApplicationWidgetResponseBean getApplicationDetailsForEvaluation(HttpServletRequest request); public BeneficiaryStatisticsResponseBean getStatisticsPageForBeneficiary(HttpServletRequest request,Long companyId); diff --git a/src/main/java/net/gepafin/tendermanagement/service/UserService.java b/src/main/java/net/gepafin/tendermanagement/service/UserService.java index 6a92a667..d13d8dff 100644 --- a/src/main/java/net/gepafin/tendermanagement/service/UserService.java +++ b/src/main/java/net/gepafin/tendermanagement/service/UserService.java @@ -47,4 +47,6 @@ public interface UserService { public UserEntity getUserEntityById(Long userId); List getAllUsers(HttpServletRequest request, List roleIds); + UserResponseBean updateUserDetails(HttpServletRequest request, Long userId, UpdateUserReqForBeneficiary userReq); + } diff --git a/src/main/java/net/gepafin/tendermanagement/service/impl/ApplicationEvaluationServiceImpl.java b/src/main/java/net/gepafin/tendermanagement/service/impl/ApplicationEvaluationServiceImpl.java index 3dd9035f..044c0902 100644 --- a/src/main/java/net/gepafin/tendermanagement/service/impl/ApplicationEvaluationServiceImpl.java +++ b/src/main/java/net/gepafin/tendermanagement/service/impl/ApplicationEvaluationServiceImpl.java @@ -3,15 +3,18 @@ package net.gepafin.tendermanagement.service.impl; import jakarta.servlet.http.HttpServletRequest; import net.gepafin.tendermanagement.dao.ApplicationEvaluationDao; +import net.gepafin.tendermanagement.entities.ApplicationEntity; import net.gepafin.tendermanagement.entities.ApplicationEvaluationEntity; import net.gepafin.tendermanagement.entities.AssignedApplicationsEntity; import net.gepafin.tendermanagement.entities.UserEntity; +import net.gepafin.tendermanagement.model.request.ApplicationEvaluationFormRequestBean; import net.gepafin.tendermanagement.model.request.ApplicationEvaluationRequest; -import net.gepafin.tendermanagement.model.request.EvaluationDocumentRequest; +import net.gepafin.tendermanagement.model.response.ApplicationEvaluationFormResponse; import net.gepafin.tendermanagement.model.response.ApplicationEvaluationResponse; - +import net.gepafin.tendermanagement.model.response.ApplicationEvaluationVersionResponse; import net.gepafin.tendermanagement.repositories.AssignedApplicationsRepository; import net.gepafin.tendermanagement.service.ApplicationEvaluationService; +import net.gepafin.tendermanagement.service.ApplicationService; import net.gepafin.tendermanagement.service.AssignedApplicationsService; import net.gepafin.tendermanagement.util.Validator; import org.springframework.beans.factory.annotation.Autowired; @@ -34,6 +37,9 @@ public class ApplicationEvaluationServiceImpl implements ApplicationEvaluationSe @Autowired private ApplicationEvaluationService applicationEvaluationService; + @Autowired + private ApplicationService applicationService; + @Override @Transactional(rollbackFor = Exception.class) public ApplicationEvaluationResponse createOrUpdateApplicationEvaluation( @@ -78,4 +84,27 @@ public class ApplicationEvaluationServiceImpl implements ApplicationEvaluationSe return applicationEvaluationDao.validateApplicationEvaluationByApplicationId(applicationId); } + @Override + @Transactional(rollbackFor = Exception.class) + public ApplicationEvaluationFormResponse createApplicationEvaluation(HttpServletRequest request, ApplicationEvaluationFormRequestBean applicationEvaluationFormRequestBean, Long assignedApplicationId, Long evaluationFormId) { + AssignedApplicationsEntity assignedApplicationsEntity = assignedApplicationsService.validateAssignedApplication(assignedApplicationId); + validator.validatePreInstructor(request, assignedApplicationsEntity.getUserId()); + return applicationEvaluationDao.createApplicationEvaluation(request,applicationEvaluationFormRequestBean,evaluationFormId,assignedApplicationId); + } + + @Override + @Transactional(readOnly = true) + public ApplicationEvaluationFormResponse getApplicationEvaluationForm(HttpServletRequest request, Long applicationId, Long assignedApplicationId) { + validator.validateUser(request); + return applicationEvaluationDao.getApplicationEvaluationForm(request,applicationId,assignedApplicationId); + } + + @Override + public ApplicationEvaluationVersionResponse getApplicationEvaluationVersion(HttpServletRequest request, Long applicationId) { + validator.validateUser(request); + return applicationEvaluationDao.getApplicationEvaluationVersion(request,applicationId); + } + + + } diff --git a/src/main/java/net/gepafin/tendermanagement/service/impl/DashboardServiceImpl.java b/src/main/java/net/gepafin/tendermanagement/service/impl/DashboardServiceImpl.java index 5dca39fd..cb52f321 100644 --- a/src/main/java/net/gepafin/tendermanagement/service/impl/DashboardServiceImpl.java +++ b/src/main/java/net/gepafin/tendermanagement/service/impl/DashboardServiceImpl.java @@ -5,6 +5,11 @@ import net.gepafin.tendermanagement.dao.DashboardDao; import net.gepafin.tendermanagement.entities.CompanyEntity; import net.gepafin.tendermanagement.entities.UserEntity; import net.gepafin.tendermanagement.model.response.*; +import net.gepafin.tendermanagement.model.response.AmendmentWidgetResponseBean; +import net.gepafin.tendermanagement.model.response.ApplicationWidgetResponseBean; +import net.gepafin.tendermanagement.model.response.AssignedApplicationWidgetResponseBean; +import net.gepafin.tendermanagement.model.response.BeneficiaryWidgetResponseBean; +import net.gepafin.tendermanagement.model.response.SuperAdminWidgetResponseBean; import net.gepafin.tendermanagement.service.DashboardService; import net.gepafin.tendermanagement.util.Validator; import org.springframework.beans.factory.annotation.Autowired; @@ -42,7 +47,11 @@ public class DashboardServiceImpl implements DashboardService { UserEntity userEntity=validator.validateUser(request); return dashboardDao.getAmendmentDetails(userEntity); } - + @Override + public PreInstructorWidgetResponseBean getDashboardWidgetForPreInstructor(HttpServletRequest request,Long userId) { + validator.validateUser(request); + return dashboardDao.getDashboardWidgetForPreInstructor(request,userId); + } @Override public AssignedApplicationWidgetResponseBean getApplicationDetailsForEvaluation(HttpServletRequest request) { UserEntity userEntity = validator.validateUser(request); diff --git a/src/main/java/net/gepafin/tendermanagement/service/impl/FormServiceImpl.java b/src/main/java/net/gepafin/tendermanagement/service/impl/FormServiceImpl.java index 51199767..fe62af2f 100644 --- a/src/main/java/net/gepafin/tendermanagement/service/impl/FormServiceImpl.java +++ b/src/main/java/net/gepafin/tendermanagement/service/impl/FormServiceImpl.java @@ -14,6 +14,7 @@ import net.gepafin.tendermanagement.util.Validator; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; import java.util.List; @@ -27,6 +28,7 @@ public class FormServiceImpl implements FormService { private Validator validator; @Override + @Transactional(rollbackFor = Exception.class) public FormResponseBean createForm(HttpServletRequest request,Long callId, FormRequest formRequest) { UserEntity user = validator.validateUser(request); CallEntity call = validator.validateUserWithCall(user, callId); @@ -34,18 +36,21 @@ public class FormServiceImpl implements FormService { } @Override + @Transactional(rollbackFor = Exception.class) public FormResponseBean updateForm(HttpServletRequest request, Long formId, FormRequest formRequest,Boolean forceDeleteFlow) { UserEntity user = validator.validateUser(request); return formDao.updateForm(user, formId,formRequest,forceDeleteFlow); } @Override + @Transactional(readOnly = true) public FormResponseBean getFormById(HttpServletRequest request, Long formId) { UserEntity user = validator.validateUser(request); return formDao.getFormEntityById(user, formId); } @Override + @Transactional(rollbackFor = Exception.class) public void deleteForm(HttpServletRequest request, Long formId) { UserEntity user = validator.validateUser(request); formDao.deleteFormById(user, formId); @@ -57,6 +62,7 @@ public class FormServiceImpl implements FormService { } @Override + @Transactional(readOnly = true) public List getFormsByCallId(HttpServletRequest request, Long callId) { UserEntity user = validator.validateUser(request); CallEntity call = validator.validateUserWithCall(user, callId); diff --git a/src/main/java/net/gepafin/tendermanagement/service/impl/UserServiceImpl.java b/src/main/java/net/gepafin/tendermanagement/service/impl/UserServiceImpl.java index b959ba61..320cb616 100644 --- a/src/main/java/net/gepafin/tendermanagement/service/impl/UserServiceImpl.java +++ b/src/main/java/net/gepafin/tendermanagement/service/impl/UserServiceImpl.java @@ -130,4 +130,10 @@ public class UserServiceImpl implements UserService { UserEntity user=validator.validateUser(request); return userDao.getAllUsers(user, roleIds); } + + @Override + @Transactional(rollbackFor = Exception.class) + public UserResponseBean updateUserDetails(HttpServletRequest request, Long userId, UpdateUserReqForBeneficiary userReq) { + return userDao.updateUserDetails(request , userId, userReq); + } } \ No newline at end of file diff --git a/src/main/java/net/gepafin/tendermanagement/util/FieldValidator.java b/src/main/java/net/gepafin/tendermanagement/util/FieldValidator.java index 9fb108ae..d311547a 100644 --- a/src/main/java/net/gepafin/tendermanagement/util/FieldValidator.java +++ b/src/main/java/net/gepafin/tendermanagement/util/FieldValidator.java @@ -2,6 +2,10 @@ package net.gepafin.tendermanagement.util; import java.text.MessageFormat; import java.util.*; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import java.util.stream.Collectors; +import java.util.stream.Stream; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; @@ -9,12 +13,18 @@ import net.gepafin.tendermanagement.config.Translator; import net.gepafin.tendermanagement.constants.GepafinConstant; import net.gepafin.tendermanagement.dao.FormDao; import net.gepafin.tendermanagement.dao.VatCheckDao; +import net.gepafin.tendermanagement.entities.ApplicationFormEntity; +import net.gepafin.tendermanagement.entities.ApplicationFormFieldEntity; +import net.gepafin.tendermanagement.model.request.ApplicationFormFieldRequestBean; import net.gepafin.tendermanagement.model.request.ContentRequestBean; import net.gepafin.tendermanagement.model.response.ContentResponseBean; import net.gepafin.tendermanagement.model.response.SettingResponseBean; +import net.gepafin.tendermanagement.repositories.ApplicationFormFieldRepository; +import net.gepafin.tendermanagement.web.rest.api.errors.CustomValidationException; import net.gepafin.tendermanagement.web.rest.api.errors.Status; import net.gepafin.tendermanagement.web.rest.api.errors.ValidationException; import org.apache.commons.lang3.StringUtils; +import org.json.JSONObject; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.util.CollectionUtils; @@ -135,7 +145,7 @@ public class FieldValidator { break; case GepafinConstant.NON_EMPTY_TABLES: - checkTableValidation(value, fieldId, contentResponseBean, errors); +// checkTableValidation(value, fieldId, contentResponseBean, errors); break; default: @@ -147,11 +157,46 @@ public class FieldValidator { return this; } - private static void checkTableValidation(String value, String fieldId, ContentResponseBean contentResponseBean, List errors) { + + + public FieldValidator validateCustomTableValidation(String value, String customRule, String fieldId, ContentResponseBean contentResponseBean) { + if (customRule == null || value == null) { + return this; // No custom rule to validate + } + + switch (customRule) { + + case GepafinConstant.NON_EMPTY_TABLES: + try { + checkTableValidation(value, fieldId, contentResponseBean, errors); + } catch (Exception e) { + throw new RuntimeException(e); + } + break; + } + + return this; + } + + private static void checkTableValidation(String value, String fieldId, ContentResponseBean contentResponseBean, List errors) throws Exception { Map stateFieldMap= new HashMap<>(); + String tableType = contentResponseBean.getSettings().stream() + .filter(setting ->GepafinConstant.CRITERIA_TABLE_COLUMNS.equals(setting.getName())) // Check for "table_columns" + .map(SettingResponseBean::getName) // Extract the name + .findFirst() // Get the first matching result + .orElse(null); // Default to null if no match + + if (tableType!=null){ + try { + Object object = PdfUtils.extractRows(value);; + value= Utils.convertToString(object); + } catch (Exception e) { + throw new RuntimeException(e); + } + } contentResponseBean.getSettings().stream() - .filter(setting -> "table_columns".equals(setting.getName())) // Check for "table_columns" + .filter(setting -> "table_columns".equals(setting.getName()) || GepafinConstant.CRITERIA_TABLE_COLUMNS.equals(setting.getName())) // Check for "table_columns" .map(SettingResponseBean::getValue) .filter(Objects::nonNull) // Ensure value is not null .filter(settingValue -> settingValue instanceof Map) // Ensure value is a Map @@ -232,5 +277,17 @@ public class FieldValidator { // Now contentRequestBean is populated with the data from the JSON return contentRequestBean; } - + public FieldValidator formulaValidation(Object fieldValue, double finalValue, String label) { + if (fieldValue != null) { + try { + double fieldValueAsDouble = Double.parseDouble(fieldValue.toString()); // Convert fieldValue to double + if (Double.compare(finalValue, fieldValueAsDouble) != 0) { // Compare doubles safely + errors.add(MessageFormat.format(Translator.toLocale(GepafinConstant.FORMULA_AMOUNT_NOT_MATCHED), label)); + } + } catch (NumberFormatException e) { + throw new CustomValidationException(Status.BAD_REQUEST, "Invalid field value: " + fieldValue); + } + } + return this; + } } diff --git a/src/main/java/net/gepafin/tendermanagement/util/PdfUtils.java b/src/main/java/net/gepafin/tendermanagement/util/PdfUtils.java index cfa32b03..1878f5ce 100644 --- a/src/main/java/net/gepafin/tendermanagement/util/PdfUtils.java +++ b/src/main/java/net/gepafin/tendermanagement/util/PdfUtils.java @@ -1,4 +1,6 @@ package net.gepafin.tendermanagement.util; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; import com.itextpdf.text.DocumentException; import com.itextpdf.text.Element; import com.itextpdf.text.Font; @@ -60,6 +62,24 @@ public class PdfUtils { return cell; } + public static Object extractRows(Object content) throws Exception { + ObjectMapper objectMapper = new ObjectMapper(); + JsonNode rootNode; + + // Check if input is already a JSON tree (Object) or a String + if (content instanceof String) { + rootNode = objectMapper.readTree((String) content); + } else { + rootNode = objectMapper.valueToTree(content); + } + + // Extract "rows" dynamically + JsonNode rowsArray = rootNode.get("rows"); + + // Convert to a generic List + return objectMapper.convertValue(rowsArray, List.class); + } + } diff --git a/src/main/java/net/gepafin/tendermanagement/util/Utils.java b/src/main/java/net/gepafin/tendermanagement/util/Utils.java index 2f063173..f444d69d 100644 --- a/src/main/java/net/gepafin/tendermanagement/util/Utils.java +++ b/src/main/java/net/gepafin/tendermanagement/util/Utils.java @@ -11,6 +11,7 @@ import java.text.SimpleDateFormat; import java.util.*; import java.util.function.Consumer; import java.util.function.Supplier; +import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.stream.Collectors; @@ -27,6 +28,8 @@ import jakarta.servlet.http.HttpServletRequest; import net.gepafin.tendermanagement.config.Translator; import net.gepafin.tendermanagement.constants.GepafinConstant; import net.gepafin.tendermanagement.model.request.GlobalFilters; +import net.objecthunter.exp4j.Expression; +import net.objecthunter.exp4j.ExpressionBuilder; import org.apache.commons.collections4.MapUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -54,6 +57,9 @@ import javax.crypto.Cipher; import javax.crypto.Mac; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; +import javax.script.ScriptEngine; +import javax.script.ScriptEngineManager; +import javax.script.ScriptException; import static org.apache.commons.lang3.StringUtils.isEmpty; @@ -753,6 +759,31 @@ public class Utils { private static Map defaultErrorResponse() { return Collections.singletonMap("message", Translator.toLocale(GepafinConstant.INVALID_VATNUMBER)); } + public static List extractValues(String input) { + List extractedValues = new ArrayList<>(); + Pattern pattern = Pattern.compile("\\{(.*?)\\}"); // Regex to match {value} + Matcher matcher = pattern.matcher(input); + while (matcher.find()) { + extractedValues.add(matcher.group(1)); // Extract value inside {} + } + return extractedValues; + } + public static double evaluateExpression(String expression) { + try { + Expression exp = new ExpressionBuilder(expression).build(); + return exp.evaluate(); + } catch (Exception e) { + e.printStackTrace(); + return Double.NaN; // Return NaN if the expression is invalid + } + } + public static boolean isNumeric(String input) { + if (input == null || input.trim().isEmpty()) { + return false; + } + + return input.matches("-?\\d+(\\.\\d+)?"); + } } \ No newline at end of file diff --git a/src/main/java/net/gepafin/tendermanagement/web/rest/api/ApplicationEvaluationApi.java b/src/main/java/net/gepafin/tendermanagement/web/rest/api/ApplicationEvaluationApi.java index 9d168955..4798e078 100644 --- a/src/main/java/net/gepafin/tendermanagement/web/rest/api/ApplicationEvaluationApi.java +++ b/src/main/java/net/gepafin/tendermanagement/web/rest/api/ApplicationEvaluationApi.java @@ -7,9 +7,12 @@ 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.FormActionEnum; +import net.gepafin.tendermanagement.model.request.ApplicationEvaluationFormRequestBean; import net.gepafin.tendermanagement.model.request.ApplicationEvaluationRequest; +import net.gepafin.tendermanagement.model.request.ApplicationRequestBean; import net.gepafin.tendermanagement.model.request.EvaluationDocumentRequest; -import net.gepafin.tendermanagement.model.response.ApplicationEvaluationResponse; +import net.gepafin.tendermanagement.model.response.*; import net.gepafin.tendermanagement.model.util.Response; import net.gepafin.tendermanagement.web.rest.api.errors.ErrorConstants; import org.springframework.http.MediaType; @@ -45,6 +48,7 @@ public interface ApplicationEvaluationApi { 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"), @@ -56,4 +60,49 @@ public interface ApplicationEvaluationApi { @Parameter( required = true) @PathVariable("id") Long id); + @Operation(summary = "Api to create or update application evaluation form ( Evaluation V2 )", + 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 = "/v2/assignedApplication/{id}", + produces = { "application/json" }) + ResponseEntity> createApplicationEvaluation(HttpServletRequest request, + @Valid @RequestBody ApplicationEvaluationFormRequestBean applicationEvaluationFormRequestBean, + @Parameter(description = "Assigned Application ID", required = true) @PathVariable(value = "id", required = true) Long assignedApplicationId, + @Parameter(description = "The evaluation form ID", required = true) @RequestParam("evaluationFormId") Long evaluationFormId); + + @Operation(summary = "Api to get an application evaluation form (Evaluation V2)", + 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 = "/v2", produces = "application/json") + ResponseEntity> getApplicationEvaluationForm(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 get application evaluation version", + 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/{id}/version", produces = { "application/json" }) + ResponseEntity> getApplicationEvaluationVersion(HttpServletRequest request, + @Parameter(description = "The application id", required = true) @PathVariable("id") Long id); + + + } diff --git a/src/main/java/net/gepafin/tendermanagement/web/rest/api/DashboardApi.java b/src/main/java/net/gepafin/tendermanagement/web/rest/api/DashboardApi.java index 16a81c1d..a6aebf4e 100644 --- a/src/main/java/net/gepafin/tendermanagement/web/rest/api/DashboardApi.java +++ b/src/main/java/net/gepafin/tendermanagement/web/rest/api/DashboardApi.java @@ -7,6 +7,11 @@ 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.response.*; +import net.gepafin.tendermanagement.model.response.AmendmentWidgetResponseBean; +import net.gepafin.tendermanagement.model.response.ApplicationWidgetResponseBean; +import net.gepafin.tendermanagement.model.response.AssignedApplicationWidgetResponseBean; +import net.gepafin.tendermanagement.model.response.BeneficiaryWidgetResponseBean; +import net.gepafin.tendermanagement.model.response.SuperAdminWidgetResponseBean; import net.gepafin.tendermanagement.model.util.Response; import net.gepafin.tendermanagement.web.rest.api.errors.ErrorConstants; import org.springframework.http.MediaType; @@ -15,6 +20,7 @@ import org.springframework.security.access.prepost.PreAuthorize; 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.RequestParam; public interface DashboardApi { @@ -73,30 +79,51 @@ public interface DashboardApi { @PreAuthorize("hasRole('ROLE_SUPER_ADMIN') || hasRole('ROLE_INSTRUCTOR_MANAGER')|| hasRole('ROLE_PRE_INSTRUCTOR')") ResponseEntity> getAmendmentDetails(HttpServletRequest request); + @Operation(summary = "Api to get Application details for Evaluation", responses = { - @ApiResponse(responseCode = "200", description = "OK"), + @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 = "/evaluation", + + @GetMapping(value = "/evaluation", produces = { "application/json" }) @PreAuthorize("hasRole('ROLE_SUPER_ADMIN') || hasRole('ROLE_INSTRUCTOR_MANAGER')|| hasRole('ROLE_PRE_INSTRUCTOR')") ResponseEntity> getApplicationDetailsForEvaluation(HttpServletRequest request); - @Operation(summary = "Api to get Statistics page for beneficiary", + + @Operation(summary = "Api to get Statistics page for beneficiary", 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/statistic/company/{companyId}", + produces = { "application/json" }) + ResponseEntity> getStatisticsPageForBeneficiary(HttpServletRequest request, + @Parameter(description = "The company id", required = true) @PathVariable(value = "companyId", required = true) Long companyId); + + + + + @Operation(summary = "Api to get dashboard widget for pre instructor", + 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/statistic/company/{companyId}", + @GetMapping(value = "/instructor/amendment", produces = { "application/json" }) - ResponseEntity> getStatisticsPageForBeneficiary(HttpServletRequest request, - @Parameter(description = "The company id", required = true) @PathVariable(value = "companyId", required = true) Long companyId); + @PreAuthorize("hasRole('ROLE_SUPER_ADMIN') || hasRole('ROLE_INSTRUCTOR_MANAGER')|| hasRole('ROLE_PRE_INSTRUCTOR')") + ResponseEntity> getDashboardWidgetForPreInstructor(HttpServletRequest request, @Parameter(description = "The User ID", required = false) @RequestParam(value = "userId",required = false) Long userId); } diff --git a/src/main/java/net/gepafin/tendermanagement/web/rest/api/UserApi.java b/src/main/java/net/gepafin/tendermanagement/web/rest/api/UserApi.java index 6dc45bec..b5517cd6 100644 --- a/src/main/java/net/gepafin/tendermanagement/web/rest/api/UserApi.java +++ b/src/main/java/net/gepafin/tendermanagement/web/rest/api/UserApi.java @@ -47,7 +47,7 @@ public interface UserApi { return new ResponseEntity>(HttpStatus.NOT_IMPLEMENTED); } - @Operation(summary = "Api to update user", + @Operation(summary = "Api to update user (Only for super admin)", responses = { @ApiResponse(responseCode = "200", description = "OK"), @ApiResponse(responseCode = "404", description = "Not Found", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = { @@ -243,6 +243,24 @@ public interface UserApi { @RequestMapping("favicon.ico") @ResponseBody void returnNoFavicon(); + + @Operation(summary = "Api to update user", + 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)}))}) + @RequestMapping(value = "/{userId}/update-details", + produces = {"application/json"}, + method = RequestMethod.PUT) + default ResponseEntity> updateUserDetails(HttpServletRequest request, + @Parameter(description = "The user id", required = true) @PathVariable("userId") Long userId, + @Parameter(description = "User request object", required = true) @Valid @RequestBody UpdateUserReqForBeneficiary userReq) { + return new ResponseEntity<>(HttpStatus.NOT_IMPLEMENTED); + } diff --git a/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/ApplicationEvaluationApiController.java b/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/ApplicationEvaluationApiController.java index b299ecc2..50eadb36 100644 --- a/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/ApplicationEvaluationApiController.java +++ b/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/ApplicationEvaluationApiController.java @@ -3,13 +3,11 @@ 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.FormActionEnum; import net.gepafin.tendermanagement.enums.UserActionContextEnum; import net.gepafin.tendermanagement.enums.UserActionLogsEnum; -import net.gepafin.tendermanagement.model.request.ApplicationEvaluationRequest; -import net.gepafin.tendermanagement.model.request.EvaluationDocumentRequest; -import net.gepafin.tendermanagement.model.request.UserActionRequest; -import net.gepafin.tendermanagement.model.response.ApplicationEvaluationResponse; -import net.gepafin.tendermanagement.model.response.EvaluationDocumentResponse; +import net.gepafin.tendermanagement.model.request.*; +import net.gepafin.tendermanagement.model.response.*; import net.gepafin.tendermanagement.model.util.Response; import net.gepafin.tendermanagement.service.ApplicationEvaluationService; import net.gepafin.tendermanagement.util.LoggingUtil; @@ -83,4 +81,41 @@ public class ApplicationEvaluationApiController implements ApplicationEvaluation .body(new Response<>(null, Status.SUCCESS, Translator.toLocale(GepafinConstant.EVALUATION_DELETED_SUCCESSFULLY))); } + @Override + public ResponseEntity> createApplicationEvaluation(HttpServletRequest request, ApplicationEvaluationFormRequestBean applicationEvaluationFormRequestBean, Long assignedApplicationId, Long evaluationFormId) { + + /** This code is responsible for creating user action logs for the "Create or update application evaluation form" operation. **/ + loggingUtil.logUserAction( + UserActionRequest.builder().request(request).actionType(UserActionLogsEnum.UPDATE).actionContext(UserActionContextEnum.CREATE_UPDATE_APPLICATION_EVALUATION_FORM).build()); + + ApplicationEvaluationFormResponse applicationEvaluationResponseBean = applicationEvaluationService.createApplicationEvaluation(request, applicationEvaluationFormRequestBean, assignedApplicationId, evaluationFormId); + + return ResponseEntity.status(HttpStatus.CREATED) + .body(new Response<>(applicationEvaluationResponseBean, Status.SUCCESS, Translator.toLocale(GepafinConstant.EVALUATION_CREATED_SUCCESSFULLY))); + } + + @Override + public ResponseEntity> getApplicationEvaluationForm(HttpServletRequest request, Long applicationId, Long assignedApplicationId) { + + /** This code is responsible for creating user action logs for the "get application evaluation form" operation. **/ + loggingUtil.logUserAction(UserActionRequest.builder().request(request).actionType(UserActionLogsEnum.VIEW).actionContext(UserActionContextEnum.GET_APPLICATION_EVALUATION_FORM).build()); + + ApplicationEvaluationFormResponse applicationEvaluationFormResponse = applicationEvaluationService.getApplicationEvaluationForm(request,applicationId,assignedApplicationId); + return ResponseEntity.status(HttpStatus.OK) + .body(new Response<>(applicationEvaluationFormResponse, Status.SUCCESS, Translator.toLocale(GepafinConstant.GET_APPLICATION_EVALUATION_FORM_SUCCESS_MSG))); + + } + + @Override + public ResponseEntity> getApplicationEvaluationVersion(HttpServletRequest request, Long applicationId) { + + /** This code is responsible for creating user action logs for the "get application evaluation version" operation. **/ + loggingUtil.logUserAction(UserActionRequest.builder().request(request).actionType(UserActionLogsEnum.VIEW).actionContext(UserActionContextEnum.GET_APPLICATION_EVALUATION_VERSION).build()); + + ApplicationEvaluationVersionResponse applicationEvaluationVersionResponse = applicationEvaluationService.getApplicationEvaluationVersion(request,applicationId); + + return ResponseEntity.status(HttpStatus.OK) + .body(new Response<>(applicationEvaluationVersionResponse, Status.SUCCESS, Translator.toLocale(GepafinConstant.GET_APPLICATION_EVALUATION_VERSION_SUCCESS_MSG))); + } + } diff --git a/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/DashboardApiController.java b/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/DashboardApiController.java index 0f299122..21264355 100644 --- a/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/DashboardApiController.java +++ b/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/DashboardApiController.java @@ -7,6 +7,11 @@ import net.gepafin.tendermanagement.enums.UserActionContextEnum; import net.gepafin.tendermanagement.enums.UserActionLogsEnum; import net.gepafin.tendermanagement.model.request.UserActionRequest; import net.gepafin.tendermanagement.model.response.*; +import net.gepafin.tendermanagement.model.response.AmendmentWidgetResponseBean; +import net.gepafin.tendermanagement.model.response.ApplicationWidgetResponseBean; +import net.gepafin.tendermanagement.model.response.AssignedApplicationWidgetResponseBean; +import net.gepafin.tendermanagement.model.response.BeneficiaryWidgetResponseBean; +import net.gepafin.tendermanagement.model.response.SuperAdminWidgetResponseBean; import net.gepafin.tendermanagement.model.util.Response; import net.gepafin.tendermanagement.service.DashboardService; import net.gepafin.tendermanagement.util.LoggingUtil; @@ -70,6 +75,15 @@ public class DashboardApiController implements DashboardApi { } @Override + public ResponseEntity> getDashboardWidgetForPreInstructor(HttpServletRequest request,Long userId) { + + /** This code is responsible for creating user action logs for the "Get dashboard stats widget for amendment page" operation. **/ + loggingUtil.logUserAction(UserActionRequest.builder().request(request).actionType(UserActionLogsEnum.VIEW).actionContext(UserActionContextEnum.GET_DASHBOARD_WIDGET_FOR_PRE_INSTRUCTOR).build()); + + PreInstructorWidgetResponseBean widgetResponseBean= dashboardService.getDashboardWidgetForPreInstructor(request,userId); + return ResponseEntity.status(HttpStatus.CREATED) + .body(new Response<>(widgetResponseBean, Status.SUCCESS, Translator.toLocale(GepafinConstant.DASHBOARD_WIDGET_FETCHED_SUCCESSFULLY))); + } public ResponseEntity> getApplicationDetailsForEvaluation(HttpServletRequest request) { /** This code is responsible for creating user action logs for the "Get Application Details for Evaluation" operation. **/ diff --git a/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/UserApiController.java b/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/UserApiController.java index 0d649943..35088a3b 100644 --- a/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/UserApiController.java +++ b/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/UserApiController.java @@ -247,5 +247,21 @@ public class UserApiController implements UserApi { public void returnNoFavicon() { // Do nothing } - + + @Override + public ResponseEntity> updateUserDetails(HttpServletRequest request, + @PathVariable("userId") Long userId, + @Valid @RequestBody UpdateUserReqForBeneficiary userReq) { + log.info("Update User for Beneficiary- User ID: {}, Request Body: {}", userId, userReq); + + /** This code is responsible for "Updating user details by beneficiary" operation. **/ + loggingUtil.logUserAction(UserActionRequest.builder().request(request).actionType(UserActionLogsEnum.UPDATE) + .actionContext(UserActionContextEnum.UPDATE_USER_DETAILS).build()); + + UserResponseBean updatedUser = userService.updateUserDetails(request, userId, userReq); + + return ResponseEntity.status(HttpStatus.OK) + .body(new Response<>(updatedUser, Status.SUCCESS, Translator.toLocale(GepafinConstant.USER_UPDATED_SUCCESS_MSG))); + } + } \ No newline at end of file diff --git a/src/main/resources/application-production.properties b/src/main/resources/application-production.properties index c6a9cce8..cbf5dd3d 100644 --- a/src/main/resources/application-production.properties +++ b/src/main/resources/application-production.properties @@ -16,7 +16,7 @@ spid.ipd.base.url=https://login.regione.umbria.it active.profile.folder=production isMailSendingEnabled = true -default_System_Receiver_Email=c.moretti@gepafin.it +default_System_Receiver_Email=m.gaudino@gepafin.it,f.marinelli@gepafin.it gepafin_email=bandi@pec.gepafin.it rinaldo_email=rinaldo.bonazzo@bflows.net carlo_email=carlo.mancosu@bflows.net diff --git a/src/main/resources/db/changelog/db.changelog-1.0.0.xml b/src/main/resources/db/changelog/db.changelog-1.0.0.xml index b987fd7c..8b6833b4 100644 --- a/src/main/resources/db/changelog/db.changelog-1.0.0.xml +++ b/src/main/resources/db/changelog/db.changelog-1.0.0.xml @@ -2303,7 +2303,94 @@ EXISTS (SELECT 1 FROM application_evaluation ae WHERE ae.application_id = application.id) - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/db/dump/update_form_field_data_06-02-2025.sql b/src/main/resources/db/dump/update_form_field_data_06-02-2025.sql new file mode 100644 index 00000000..970f442b --- /dev/null +++ b/src/main/resources/db/dump/update_form_field_data_06-02-2025.sql @@ -0,0 +1,14 @@ + +INSERT INTO FORM_FIELD (ID, SORT_ORDER, NAME, LABEL, DESCRIPTION, SETTINGS, VALIDATORS, CREATED_DATE, UPDATED_DATE) +VALUES +( + 22, + 22, + 'switch', + 'Casella di spunta "Checklist"', + 'Per selezioni binarie, accettazioni, conferme', + '[{"name":"label","value":"Casella di Spunta"},{"name":"isChecklistItem","value":true}]', + '{"isRequired":false}', + CURRENT_TIMESTAMP, + CURRENT_TIMESTAMP +); \ No newline at end of file diff --git a/src/main/resources/db/dump/update_system_email_template_application_rejected_04_02_2025.sql b/src/main/resources/db/dump/update_system_email_template_application_rejected_04_02_2025.sql new file mode 100644 index 00000000..67815ab0 --- /dev/null +++ b/src/main/resources/db/dump/update_system_email_template_application_rejected_04_02_2025.sql @@ -0,0 +1,17 @@ +UPDATE gepafin_schema.system_email_template +SET html_content = ' + +
+

Buongiorno,

+

Si comunica che, in riferimento alla domanda a valere sul bando “{{call_name}}” di cui al + Protocollo n. {{protocol_number}} del {{protocol_date}} alle {{protocol_time}}, + la stessa è stata sottoposta ad istruttoria di ammissibilità con esito negativo.

+

Le motivazioni sono le seguenti: {{form_text}}

+

Vi ricordiamo che i Beneficiari che hanno presentato richieste valutate non ammissibili entro 10 giorni dalla data di ricevimento della presente potranno formulare ricorso al Gestore tramite modello disponibile nello sportello online + {{platform_link}}.

+

Distinti Saluti,

+

{{email_signature}}

+
+ + ' +WHERE "type" = 'INADMISSIBILITY_NOTIFICATION'; \ No newline at end of file diff --git a/src/main/resources/message_en.properties b/src/main/resources/message_en.properties index b3c5f259..7aab6f08 100644 --- a/src/main/resources/message_en.properties +++ b/src/main/resources/message_en.properties @@ -152,6 +152,7 @@ application.created.success=Application successfully created. application.updated.success=Application successfully updated. application.deleted.success=Application successfully deleted. application.get.success=Application details fetched successfully. +application.evaluation.version.get.success = Application evaluation version fetched successfully. application.not.found=Application not found with the given ID. application.form.field.not.found=Application form field not found. Form.not.matches.to.call.initial.form=Form id does not matches to initial form id of call. @@ -267,6 +268,7 @@ evaluationCriteria.invalid=This evaluation criterion does not belong to the curr 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. +application.evaluation.form.get.success = Application Evaluation Form Fetched Successfully. # Hub Messages hub_create_success=Hub created successfully @@ -362,8 +364,11 @@ evaluation.form.deleted.successfully=Evaluation form deleted successfully. evaluation.form.fetched.successfully=Evaluation form fetched successfully. evaluation.form.not.found=Evaluation form not found. +either.applicationId.or.assignedApplicationId.must.be.provided=Either applicationId or assignedApplicationId must be provided. assigned.application.status.updated.successfully=Assigned application status updated successfully. validation.required.requested.amount=The Requested Amount configuration should be mandatory. company.id.not.null=Company ID cannot be null. +formula.amount.not.matches.requested.amount= The {0} does not matches to calculated amount. + diff --git a/src/main/resources/message_it.properties b/src/main/resources/message_it.properties index 3ba36fcf..c1794a8d 100644 --- a/src/main/resources/message_it.properties +++ b/src/main/resources/message_it.properties @@ -146,6 +146,7 @@ application.created.success=Applicazione creata con successo. application.updated.success=Applicazione aggiornata con successo. application.deleted.success=Applicazione eliminata con successo. application.get.success=Dettagli dell'applicazione recuperati con successo. +application.evaluation.version.get.success = Versione di valutazione dell'applicazione recuperata correttamente. application.not.found=Applicazione non trovata con l'ID fornito. application.form.field.not.found=Campo del modulo di domanda non trovato. Form.not.matches.to.call.initial.form=L'ID del modulo non corrisponde all'ID del modulo iniziale della chiamata. @@ -260,6 +261,7 @@ application.evaluation.status.updated.successfully=Stato della valutazione dell' 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.evaluation.form.get.success =Modulo di valutazione della domanda recuperato correttamente.code application.assigned.success.msg =Domanda assegnata con successo application.already.assigned.msg =La domanda ? gi? assegnata @@ -352,10 +354,12 @@ evaluation.form.deleted.successfully=Modulo di valutazione eliminato con success evaluation.form.fetched.successfully=Modulo di valutazione recuperato con successo. evaluation.form.not.found=Modulo di valutazione non trovato. +either.applicationId.or.assignedApplicationId.must.be.provided = "� necessario fornire applicationId o assegnatoApplicationId." assigned.application.status.updated.successfully=Stato dell'applicazione assegnata aggiornato con successo. -validation.required.requested.amount=La configurazione dell'importo richiesto obbligatoria. +validation.required.requested.amount=La configurazione dell'importo richiesto � obbligatoria. company.id.not.null=L'ID dell'azienda non pu? essere nullo. +formula.amount.not.matches.requested.amount=Il {0} non corrisponde all'importo calcolato.