diff --git a/src/main/java/net/gepafin/tendermanagement/config/SamlFailureHandler.java b/src/main/java/net/gepafin/tendermanagement/config/SamlFailureHandler.java index 81df79e3..171b7e12 100644 --- a/src/main/java/net/gepafin/tendermanagement/config/SamlFailureHandler.java +++ b/src/main/java/net/gepafin/tendermanagement/config/SamlFailureHandler.java @@ -15,7 +15,7 @@ import jakarta.servlet.http.HttpServletResponse; @Component public class SamlFailureHandler implements AuthenticationFailureHandler { - private final Logger logger = LoggerFactory.getLogger(SamlSuccessHandler.class); + private final Logger logger = LoggerFactory.getLogger(SamlFailureHandler.class); @Value("${fe.base.url}") private String feBaseUrl; diff --git a/src/main/java/net/gepafin/tendermanagement/config/SecurityConfig.java b/src/main/java/net/gepafin/tendermanagement/config/SecurityConfig.java index 91424195..ec38b268 100644 --- a/src/main/java/net/gepafin/tendermanagement/config/SecurityConfig.java +++ b/src/main/java/net/gepafin/tendermanagement/config/SecurityConfig.java @@ -107,7 +107,7 @@ public class SecurityConfig { .requestMatchers("/swagger-ui/**").permitAll() // Swagger docs .requestMatchers("/v1/api-docs/**").permitAll() // API docs .anyRequest().authenticated()) - .sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS)) + .sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED)) .addFilterBefore(corsFilter(), UsernamePasswordAuthenticationFilter.class) .addFilterBefore(new JWTFilter(tokenProvider), UsernamePasswordAuthenticationFilter.class) // Add SAML2 login configuration (for BENEFICIARI) diff --git a/src/main/java/net/gepafin/tendermanagement/constants/GepafinConstant.java b/src/main/java/net/gepafin/tendermanagement/constants/GepafinConstant.java index 5caf97bc..3375765a 100644 --- a/src/main/java/net/gepafin/tendermanagement/constants/GepafinConstant.java +++ b/src/main/java/net/gepafin/tendermanagement/constants/GepafinConstant.java @@ -191,4 +191,9 @@ public class GepafinConstant { public static final String VALIDATION_ERROR_FILE_EMPTY = "validation.error.file.empty"; public static final String VALIDATION_ERROR_FILE_INVALIDTYPE = "validation.error.file.invalidType"; public static final String UPLOAD_ERROR_S3 = "upload.error.s3"; + + public static final String CALL_NOT_STARTED_YET = "call.not.started.yet"; + public static final String CALL_ALREADY_ENDED = "call.already.ended"; + public static final String APPLICATION_STATUS_UPDATED_SUCCESSFULLY = "application.status.updated.successfully"; + } diff --git a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java index a76b9de3..ae8db433 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java @@ -75,7 +75,7 @@ public class ApplicationDao { public ApplicationResponseBean createApplication(ApplicationRequestBean applicationRequestBean, UserEntity userEntity, Long formId, Long applicationId) { FormEntity formEntity = formService.validateForm(formId); - callService.validatePublishedCall(formEntity.getCall().getId()); +// callService.validatePublishedCall(formEntity.getCall().getId()); validateFormFields(applicationRequestBean,formEntity); ApplicationEntity applicationEntity = validateApplication(applicationId); if(Boolean.TRUE.equals(applicationEntity.getStatus().equals(ApplicationStatusTypeEnum.SUBMIT.getValue()))) { @@ -323,9 +323,13 @@ public class ApplicationDao { } } Utils.setIfUpdated(applicationFormFieldEntity::getFieldId, applicationFormFieldEntity::setFieldId, applicationFormFieldRequestBean.getFieldId()); - if(applicationFormFieldRequestBean.getFieldValue() ==null || Boolean.FALSE.equals(applicationFormFieldRequestBean.getFieldValue().isEmpty())) { - applicationFormFieldEntity.setFieldValue(applicationFormFieldRequestBean.getFieldValue()); + + if(applicationFormFieldRequestBean.getFieldValue() !=null ) { + applicationFormFieldEntity.setFieldValue(Utils.convertObjectToJsonString(applicationFormFieldRequestBean.getFieldValue())); } + if(applicationFormFieldRequestBean.getFieldValue() ==null ) { + applicationFormFieldEntity.setFieldValue(null); + } return applicationFormFieldRepository.save(applicationFormFieldEntity); } @@ -333,10 +337,15 @@ public class ApplicationDao { List documentIds=null; List contentResponseBeans=Utils.convertJsonStringToList(formEntity.getContent(),ContentResponseBean.class); for (ContentResponseBean contentResponseBean:contentResponseBeans){ - if(Boolean.TRUE.equals(contentResponseBean.getName().equals("fileupload"))){ - if(contentResponseBean.getId().equals(applicationFormFieldRequestBean.getFieldId())) { - String documentId = applicationFormFieldRequestBean.getFieldValue(); - documentIds = validateDocumentIds(documentId); + if(Boolean.TRUE.equals(contentResponseBean.getName().equals("fileupload"))) { + if (contentResponseBean.getId().equals(applicationFormFieldRequestBean.getFieldId())) { + Object fieldValueObject = applicationFormFieldRequestBean.getFieldValue(); + if (fieldValueObject instanceof String) { + // Safely cast the object to a string + String documentId = (String) fieldValueObject; + // Now you can use documentId as needed + documentIds = validateDocumentIds(documentId); + } } } } @@ -377,7 +386,9 @@ public class ApplicationDao { ApplicationFormFieldResponseBean applicationFormFieldResponseBean = new ApplicationFormFieldResponseBean(); applicationFormFieldResponseBean.setApplicationFormId(applicationFormId); applicationFormFieldResponseBean.setFieldId(applicationFormFieldEntity.getFieldId()); - applicationFormFieldResponseBean.setFieldValue(applicationFormFieldEntity.getFieldValue()); + if(applicationFormFieldEntity.getFieldValue() != null) { + applicationFormFieldResponseBean.setFieldValue(Utils.getFieldValueAsObject(applicationFormFieldEntity.getFieldValue())); + } applicationFormFieldResponseBean.setId(applicationFormFieldEntity.getId()); applicationFormFieldResponseBean.setCreatedDate(applicationFormFieldEntity.getCreatedDate()); applicationFormFieldResponseBean.setUpdatedDate(applicationFormFieldEntity.getUpdatedDate()); @@ -447,7 +458,7 @@ public class ApplicationDao { } private ApplicationGetResponseBean createApplicationGetResponseBean(ApplicationEntity applicationEntity, List formEntities, List formApplicationResponses) { - ApplicationGetResponseBean applicationGetResponseBean =createApplicationGetResponseBean(applicationEntity); + ApplicationGetResponseBean applicationGetResponseBean = createApplicationGetResponseBean(applicationEntity); applicationGetResponseBean.setForm(formApplicationResponses); return applicationGetResponseBean; } @@ -477,7 +488,7 @@ public class ApplicationDao { public ApplicationResponse createApplicationByCallId(CompanyEntity companyEntity, ApplicationRequest applicationRequest, Long callId, UserEntity userEntity) { CallEntity call = callService.validateCall(callId); - call = callService.validatePublishedCall(call.getId()); +// call = callService.validatePublishedCall(call.getId()); checkIfApplicationExists(call, companyEntity); ApplicationEntity applicationEntity = createApplicationEntity(userEntity, call, companyEntity); applicationEntity.setComments(applicationRequest.getComments()); @@ -492,10 +503,11 @@ public class ApplicationDao { } } - public void updateApplicationStatus(Long applicationId, ApplicationStatusTypeEnum status) { + public ApplicationResponse updateApplicationStatus(Long applicationId, ApplicationStatusTypeEnum status) { ApplicationEntity applicationEntity = validateApplication(applicationId); if (status.equals(ApplicationStatusTypeEnum.SUBMIT)) { + callService.validatePublishedCall(applicationEntity.getCall().getId()); // CallEntity callEntity = applicationEntity.getCall(); // Long initialFormId = callEntity.getInitialForm(); // Long finalFormId = callEntity.getFinalForm(); @@ -518,7 +530,9 @@ public class ApplicationDao { } else { applicationEntity.setStatus(status.getValue()); } - saveApplicationEntity(applicationEntity); + applicationEntity = saveApplicationEntity(applicationEntity); + + return getApplicationResponse(applicationEntity); } public Integer calculateProgress(Long totalSteps, Long completedSteps) { diff --git a/src/main/java/net/gepafin/tendermanagement/dao/CallDao.java b/src/main/java/net/gepafin/tendermanagement/dao/CallDao.java index e214e562..c6345d59 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/CallDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/CallDao.java @@ -3,6 +3,7 @@ package net.gepafin.tendermanagement.dao; import java.math.BigDecimal; import java.time.LocalDate; import java.time.LocalDateTime; +import java.time.LocalTime; import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -673,6 +674,25 @@ public class CallDao { Status.NOT_FOUND, Translator.toLocale(GepafinConstant.CALL_NOT_PUBLISHED)); } + LocalDate currentDate = LocalDate.now(); + LocalTime currentTime = LocalTime.now(); + + if (currentDate.isBefore(callEntity.getStartDate().toLocalDate()) || + (currentDate.isEqual(callEntity.getStartDate().toLocalDate()) && currentTime.isBefore(callEntity.getStartTime()))) { + throw new CustomValidationException( + Status.BAD_REQUEST, + Translator.toLocale(GepafinConstant.CALL_NOT_STARTED_YET) + ); + } + + if (currentDate.isAfter(callEntity.getEndDate().toLocalDate()) || + (currentDate.isEqual(callEntity.getEndDate().toLocalDate()) && currentTime.isAfter(callEntity.getEndTime()))) { + throw new CustomValidationException( + Status.BAD_REQUEST, + Translator.toLocale(GepafinConstant.CALL_ALREADY_ENDED) + ); + } + return callEntity; } diff --git a/src/main/java/net/gepafin/tendermanagement/dao/CompanyDao.java b/src/main/java/net/gepafin/tendermanagement/dao/CompanyDao.java index 089c210b..2e148665 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/CompanyDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/CompanyDao.java @@ -21,6 +21,8 @@ import net.gepafin.tendermanagement.web.rest.api.errors.CustomValidationExceptio import net.gepafin.tendermanagement.web.rest.api.errors.ResourceNotFoundException; import net.gepafin.tendermanagement.web.rest.api.errors.Status; +import static net.gepafin.tendermanagement.util.Utils.setIfUpdated; + @Component public class CompanyDao { @@ -100,6 +102,8 @@ public class CompanyDao { entity.setEmail(request.getEmail()); entity.setNumberOfEmployees(request.getNumberOfEmployees()); entity.setAnnualRevenue(request.getAnnualRevenue()); + entity.setContactName(request.getContactName()); + entity.setContactEmail(request.getContactEmail()); return entity; } @@ -124,29 +128,33 @@ public class CompanyDao { } response.setCreatedDate(entity.getCreatedDate()); response.setUpdatedDate(entity.getUpdatedDate()); + response.setContactName(entity.getContactName()); + response.setContactEmail(entity.getContactEmail()); return response; } public CompanyResponse updateCompany(UserEntity userEntity, Long companyId, CompanyRequest companyRequest) { CompanyEntity companyEntity = validateCompany(companyId); - Utils.setIfUpdated(companyEntity::getCompanyName, companyEntity::setCompanyName, + setIfUpdated(companyEntity::getCompanyName, companyEntity::setCompanyName, companyRequest.getCompanyName()); - Utils.setIfUpdated(companyEntity::getVatNumber, companyEntity::setVatNumber, companyRequest.getVatNumber()); - Utils.setIfUpdated(companyEntity::getCodiceFiscale, companyEntity::setCodiceFiscale, + setIfUpdated(companyEntity::getVatNumber, companyEntity::setVatNumber, companyRequest.getVatNumber()); + setIfUpdated(companyEntity::getCodiceFiscale, companyEntity::setCodiceFiscale, companyRequest.getCodiceFiscale()); - Utils.setIfUpdated(companyEntity::getAddress, companyEntity::setAddress, companyRequest.getAddress()); - Utils.setIfUpdated(companyEntity::getPhoneNumber, companyEntity::setPhoneNumber, + setIfUpdated(companyEntity::getAddress, companyEntity::setAddress, companyRequest.getAddress()); + setIfUpdated(companyEntity::getPhoneNumber, companyEntity::setPhoneNumber, companyRequest.getPhoneNumber()); - Utils.setIfUpdated(companyEntity::getCity, companyEntity::setCity, companyRequest.getCity()); - Utils.setIfUpdated(companyEntity::getProvince, companyEntity::setProvince, companyRequest.getProvince()); - Utils.setIfUpdated(companyEntity::getCap, companyEntity::setCap, companyRequest.getCap()); - Utils.setIfUpdated(companyEntity::getCountry, companyEntity::setCountry, companyRequest.getCountry()); - Utils.setIfUpdated(companyEntity::getPec, companyEntity::setPec, companyRequest.getPec()); - Utils.setIfUpdated(companyEntity::getEmail, companyEntity::setEmail, companyRequest.getEmail()); - Utils.setIfUpdated(companyEntity::getNumberOfEmployees, companyEntity::setNumberOfEmployees, + setIfUpdated(companyEntity::getCity, companyEntity::setCity, companyRequest.getCity()); + setIfUpdated(companyEntity::getProvince, companyEntity::setProvince, companyRequest.getProvince()); + setIfUpdated(companyEntity::getCap, companyEntity::setCap, companyRequest.getCap()); + setIfUpdated(companyEntity::getCountry, companyEntity::setCountry, companyRequest.getCountry()); + setIfUpdated(companyEntity::getPec, companyEntity::setPec, companyRequest.getPec()); + setIfUpdated(companyEntity::getEmail, companyEntity::setEmail, companyRequest.getEmail()); + setIfUpdated(companyEntity::getNumberOfEmployees, companyEntity::setNumberOfEmployees, companyRequest.getNumberOfEmployees()); - Utils.setIfUpdated(companyEntity::getAnnualRevenue, companyEntity::setAnnualRevenue, + setIfUpdated(companyEntity::getAnnualRevenue, companyEntity::setAnnualRevenue, companyRequest.getAnnualRevenue()); + setIfUpdated(companyEntity::getContactName,companyEntity::setContactName,companyRequest.getContactName()); + setIfUpdated(companyEntity::getContactEmail,companyEntity::setContactEmail,companyRequest.getContactEmail()); companyRepository.save(companyEntity); UserWithCompanyEntity userWithCompanyEntity = userWithCompanyRepository.findByUserIdAndCompanyId(userEntity.getId(), companyId).orElse(null); Utils.setIfUpdated(userWithCompanyEntity::getIsLegalRepresentant, userWithCompanyEntity::setIsLegalRepresentant, diff --git a/src/main/java/net/gepafin/tendermanagement/dao/FlowFormDao.java b/src/main/java/net/gepafin/tendermanagement/dao/FlowFormDao.java index b99ba6c2..1ffb9059 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/FlowFormDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/FlowFormDao.java @@ -1,6 +1,7 @@ package net.gepafin.tendermanagement.dao; import java.util.*; +import java.util.stream.Collectors; import net.gepafin.tendermanagement.enums.ApplicationStatusTypeEnum; import net.gepafin.tendermanagement.repositories.*; @@ -174,81 +175,83 @@ public class FlowFormDao { .orElse(null); } -// public Long getPreviousForm(FormEntity currentFormEntity, ApplicationEntity applicationEntity) { -// // Retrieve the flow edges for the previous forms -// List flowEdgesList = flowEdgesRepository.findByTargetIdAndCallId( -// currentFormEntity.getId(), applicationEntity.getCall().getId()); -// -// if (flowEdgesList.isEmpty()) { -// return null; -//// throw new ResourceNotFoundException(Status.NOT_FOUND, -//// Translator.toLocale(GepafinConstant.PREVIOUS_FORM_NOT_FOUND)); -// } -// -// // If only one edge exists, return the source form ID -// if (flowEdgesList.size() == 1) { -// return flowEdgesList.get(0).getSourceId(); -// } -// -// // For multiple edges, find the previous form based on the chosen value -// List previousFormIds = flowEdgesList.stream() -// .map(FlowEdgesEntity::getSourceId) -// .toList(); -// -// // Fetch the flow data based on previous form IDs -// List flowDataList = flowDataRepository.findByFormIdInAndCallId( -// previousFormIds, applicationEntity.getCall().getId()); -// -// List chosenValues = flowDataList.stream() -// .map(FlowDataEntity::getChoosenValue) -// .toList(); -// -// // Fetch the previous forms based on the chosen field values -// Set formList = applicationFormFieldRepository -// .findByFieldValueInAndApplicationFormApplicationId(chosenValues, applicationEntity.getId()).stream() -// .map(fieldEntity -> fieldEntity.getApplicationForm().getForm()) -// .collect(Collectors.toSet()); -// -// // Find next form IDs recursively for all forms in the formList -// List fieldIds = formList.stream() -// .map(formEntity -> getNextForm(formEntity, applicationEntity)) -// .toList(); -// -// // Return the first matching previous form ID that corresponds to a next form -// return previousFormIds.stream() -// .filter(fieldIds::contains) -// .findFirst().orElse(null); -// } - public Long getPreviousForm(FormEntity currentFormEntity, ApplicationEntity applicationEntity) { + // Retrieve the flow edges for the previous forms + List flowEdgesList = flowEdgesRepository.findByTargetIdAndCallId( + currentFormEntity.getId(), applicationEntity.getCall().getId()); - List flowEdgesList = flowEdgesRepository.findByTargetIdAndCallId( - currentFormEntity.getId(), applicationEntity.getCall().getId()); - - if (flowEdgesList.isEmpty()) { - return null; + if (flowEdgesList.isEmpty()) { + return null; // throw new ResourceNotFoundException(Status.NOT_FOUND, // Translator.toLocale(GepafinConstant.PREVIOUS_FORM_NOT_FOUND)); } - // // If only one edge exists, return the source form ID - // if (flowEdgesList.size() == 1) { - // return flowEdgesList.get(0).getSourceId(); - // } + // If only one edge exists, return the source form ID + if (flowEdgesList.size() == 1) { + return flowEdgesList.get(0).getSourceId(); + } // For multiple edges, find the previous form based on the chosen value - List previousFormIds = flowEdgesList.stream() - .map(FlowEdgesEntity::getSourceId) - .toList(); + List previousFormIds = flowEdgesList.stream() + .map(FlowEdgesEntity::getSourceId) + .toList(); - List applicationFormEntities=applicationFormRepository.findByFormIdInAndApplicationId(previousFormIds,applicationEntity.getId()); + // Fetch the flow data based on previous form IDs + List flowDataList = flowDataRepository.findByFormIdInAndCallId( + previousFormIds, applicationEntity.getCall().getId()); - applicationFormEntities.sort(Comparator.comparing(ApplicationFormEntity::getCreatedDate).reversed()); + List chosenValues = flowDataList.stream() + .map(FlowDataEntity::getChoosenValue) + .toList(); - return applicationFormEntities.isEmpty() ? null : applicationFormEntities.get(0).getForm().getId(); + // Fetch the previous forms based on the chosen field values + Set formList = applicationFormFieldRepository + .findByFieldValueInAndApplicationFormApplicationId(chosenValues, applicationEntity.getId()).stream() + .map(fieldEntity -> fieldEntity.getApplicationForm().getForm()) + .collect(Collectors.toSet()); + + // Find next form IDs recursively for all forms in the formList + List fieldIds = formList.stream() + .map(formEntity -> getNextForm(formEntity, applicationEntity)) + .toList(); + + // Return the first matching previous form ID that corresponds to a next form + return previousFormIds.stream() + .filter(fieldIds::contains) + .findFirst().orElse(null); } - public NextOrPreviousFormResponse getnextOrPreviousForm(ApplicationEntity applicationEntity, Long formId, - FormActionEnum action) { + +// public Long getPreviousForm(FormEntity currentFormEntity, ApplicationEntity applicationEntity) { +// +// List flowEdgesList = flowEdgesRepository.findByTargetIdAndCallId( +// currentFormEntity.getId(), applicationEntity.getCall().getId()); +// +// if (flowEdgesList.isEmpty()) { +// return null; +//// throw new ResourceNotFoundException(Status.NOT_FOUND, +//// Translator.toLocale(GepafinConstant.PREVIOUS_FORM_NOT_FOUND)); +// } +// +// // // If only one edge exists, return the source form ID +// // if (flowEdgesList.size() == 1) { +// // return flowEdgesList.get(0).getSourceId(); +// // } +// +// // For multiple edges, find the previous form based on the chosen value +// List previousFormIds = flowEdgesList.stream() +// .map(FlowEdgesEntity::getSourceId) +// .toList(); +// if (previousFormIds.size() == 1) { +// return previousFormIds.get(0); +// } +// +// List applicationFormEntities=applicationFormRepository.findByFormIdInAndApplicationId(previousFormIds,applicationEntity.getId()); +// applicationFormEntities.sort(Comparator.comparing(ApplicationFormEntity::getCreatedDate).reversed()); +// +// return applicationFormEntities.isEmpty() ? null : applicationFormEntities.get(0).getForm().getId(); +// } + public NextOrPreviousFormResponse getNextOrPreviousForm(ApplicationEntity applicationEntity, Long formId, + FormActionEnum action) { Long calculatedFormId = null; FormEntity formEntity = null; if (formId == null) { @@ -299,7 +302,7 @@ public class FlowFormDao { List flowEdgesList = flowEdgesRepository.findByCallId(applicationEntity.getCall().getId()); Long totalFormSteps = calculateTotalSteps(flowEdgesList); - Long currentStep = calculateCurrentStep(formEntity); + Long currentStep = calculateCurrentStep(flowEdgesList, formEntity); nextOrPreviousFormResponse.setTotalFormSteps(totalFormSteps); completedSteps = getCompletedSteps(applicationEntity); nextOrPreviousFormResponse.setCompletedSteps(Long.valueOf(completedSteps)); @@ -321,11 +324,11 @@ public class FlowFormDao { return completedSteps; } - public Long calculateCurrentStep(FormEntity formEntity) { + public Long calculateCurrentStep(List flowEdgesList, FormEntity formEntity) { Long currentStep = 2l; if (formEntity.getId().equals(formEntity.getCall().getInitialForm())) { currentStep = 1l; - } else if (formEntity.getId().equals(formEntity.getCall().getFinalForm())) { + } else if (flowEdgesList.size()>1 && formEntity.getId().equals(formEntity.getCall().getFinalForm())) { currentStep = 3l; } return currentStep; @@ -341,13 +344,21 @@ public class FlowFormDao { private Long getDefaultForm(ApplicationEntity applicationEntity) { List applicationFormList = applicationFormRepository.findByApplicationIdOrderByCreatedDateAsc(applicationEntity.getId()); - if(applicationFormList.isEmpty()) { + if (applicationFormList.isEmpty()) { return applicationEntity.getCall().getInitialForm(); } - if(applicationFormList.get(applicationFormList.size()-1).getForm().getId().equals(applicationEntity.getCall().getFinalForm())) { - return applicationEntity.getCall().getInitialForm(); + if (applicationFormList.get(applicationFormList.size() - 1).getForm().getId().equals(applicationEntity.getCall().getFinalForm())) { + return applicationEntity.getCall().getInitialForm(); } - return getNextForm(applicationFormList.get(applicationFormList.size()-1).getForm(), applicationEntity); + FormEntity currentFormEntity = applicationFormList.get(applicationFormList.size() - 1).getForm(); + + for (ApplicationFormEntity applicationFormEntity : applicationFormList) { + Boolean isCompleted = formDao.validateCompletedSteps(applicationFormFieldRepository.findByApplicationFormId(applicationFormEntity.getId()), applicationEntity, applicationFormEntity.getForm()); + if (Boolean.FALSE.equals(isCompleted)) { + return applicationFormEntity.getForm().getId(); + } + } + return getNextForm(currentFormEntity, applicationEntity); } diff --git a/src/main/java/net/gepafin/tendermanagement/dao/FormDao.java b/src/main/java/net/gepafin/tendermanagement/dao/FormDao.java index 9cdf3fed..84c9d9b1 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/FormDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/FormDao.java @@ -15,6 +15,7 @@ import net.gepafin.tendermanagement.util.Utils; import net.gepafin.tendermanagement.web.rest.api.errors.CustomValidationException; import net.gepafin.tendermanagement.web.rest.api.errors.ResourceNotFoundException; import net.gepafin.tendermanagement.web.rest.api.errors.Status; +import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import org.springframework.util.CollectionUtils; @@ -205,12 +206,14 @@ public class FormDao { public void validateFormField(List applicationFormFieldRequestList, ApplicationEntity applicationEntity, FormEntity formEntity) { Map formFieldMap = new LinkedHashMap(); for(ApplicationFormFieldRequestBean applicationFormFieldRequestBean:applicationFormFieldRequestList) { - if(applicationFormFieldRequestBean.getFieldValue()==null || applicationFormFieldRequestBean.getFieldValue().isEmpty()) + if(applicationFormFieldRequestBean.getFieldValue()==null ) continue; - formFieldMap.put(applicationFormFieldRequestBean.getFieldId(),applicationFormFieldRequestBean.getFieldValue()); - } + if (applicationFormFieldRequestBean.getFieldValue() != null ) { + Object fieldValue = applicationFormFieldRequestBean.getFieldValue(); + checkObjectData(applicationFormFieldRequestBean.getFieldId(), fieldValue, formFieldMap); + }} - FormResponseBean formResponseBean = convertFormEntityToFormResponseBean(formEntity); + FormResponseBean formResponseBean = convertFormEntityToFormResponseBean(formEntity); ApplicationFormEntity applicationFormEntity=applicationFormRepository.findByApplicationIdAndFormId(applicationEntity.getId(),formEntity.getId()); Boolean isApplicationFormExist= getApplicationFormExist(applicationFormEntity); FieldValidator validator = FieldValidator.create(); @@ -238,6 +241,28 @@ public class FormDao { validator.validate(); } + private void checkObjectData(String fieldId, Object fieldValue, Map formFieldMap) { + if (fieldValue instanceof List) { + List list = (List) fieldValue; + + // Only map if the list is not empty and contains Strings + if (!list.isEmpty() && list.get(0) instanceof String) { + for (Object value : list) { + setFormFieldMap(fieldId, formFieldMap, value); + } + } + } + else setFormFieldMap(fieldId, formFieldMap, fieldValue); + } + + private void setFormFieldMap(String fieldId, Map formFieldMap, Object value) { + if (value instanceof String) { + if(value !=null && Boolean.FALSE.equals(StringUtils.isEmpty((String)value))) { + formFieldMap.put(fieldId, value); + } + } + } + private Boolean getApplicationFormExist(ApplicationFormEntity applicationFormEntity) { if(applicationFormEntity !=null) { return true; @@ -249,8 +274,8 @@ public class FormDao { Map formFieldMap = new LinkedHashMap(); for(ApplicationFormFieldEntity applicationFormFieldEntity:applicationFormFieldEntityList) { formFieldMap.put(applicationFormFieldEntity.getFieldId(),applicationFormFieldEntity.getFieldValue()); - } - + } + FormResponseBean formResponseBean = convertFormEntityToFormResponseBean(formEntity); FieldValidator validator = FieldValidator.create(); formResponseBean.getContent().forEach(contentResponseBean -> { diff --git a/src/main/java/net/gepafin/tendermanagement/dao/UserDao.java b/src/main/java/net/gepafin/tendermanagement/dao/UserDao.java index 53825d01..04608206 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/UserDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/UserDao.java @@ -83,6 +83,12 @@ public class UserDao { beneficiaryEntity.setLastName(userReq.getLastName()); beneficiaryEntity.setOrganization(userReq.getOrganization()); beneficiaryEntity.setPhoneNumber(userReq.getPhoneNumber()); + beneficiaryEntity.setPrivacy(userReq.getPrivacy()); + beneficiaryEntity.setTerms(userReq.getTerms()); + beneficiaryEntity.setOffers(userReq.getOffers()); + beneficiaryEntity.setMarketing(userReq.getMarketing()); + beneficiaryEntity.setThirdParty(userReq.getThirdParty()); + beneficiaryEntity.setEmailPec(userReq.getEmailPec()); beneficiaryEntity =beneficiaryRepository.save(beneficiaryEntity); } return beneficiaryEntity; @@ -148,10 +154,16 @@ public class UserDao { setIfUpdated(userEntity::getOrganization, userEntity::setOrganization, userReq.getOrganization()); setIfUpdated(userEntity::getAddress, userEntity::setAddress, userReq.getAddress()); setIfUpdated(userEntity::getPhoneNumber, userEntity::setPhoneNumber, userReq.getPhoneNumber()); + setIfUpdated(userEntity::getDateOfBirth, userEntity::setDateOfBirth, userReq.getDateOfBirth()); + setIfUpdated(userEntity.getBeneficiary()::getCodiceFiscale, userEntity.getBeneficiary()::setCodiceFiscale, userReq.getCodiceFiscale()); + setIfUpdated(userEntity.getBeneficiary()::getMarketing, userEntity.getBeneficiary()::setMarketing, userReq.getMarketing()); + setIfUpdated(userEntity.getBeneficiary()::getOffers, userEntity.getBeneficiary()::setOffers, userReq.getOffers()); + setIfUpdated(userEntity.getBeneficiary()::getThirdParty, userEntity.getBeneficiary()::setThirdParty, userReq.getThirdParty()); if (userReq.getRoleId() != null) { RoleEntity roleEntity = roleDao.validateRole(userReq.getRoleId()); setIfUpdated(userEntity::getRoleEntity, userEntity::setRoleEntity, roleEntity); } + setIfUpdated(userEntity.getBeneficiary()::getEmailPec, userEntity.getBeneficiary()::setEmailPec, userReq.getEmailPec()); userEntity = userRepository.save(userEntity); log.info("User updated with ID: {}", userEntity.getId()); return convertUserEntityToUserResponse(userEntity); @@ -167,6 +179,7 @@ public class UserDao { userEntity.setStatus(UserStatusEnum.ACTIVE.getValue()); userEntity.setBeneficiary(beneficiary); if (Boolean.FALSE.equals(RoleStatusEnum.ROLE_BENEFICIARY.getValue().equals(roleEntity.getRoleType()))) { + userEntity.setFirstName(userReq.getFirstName()); userEntity.setLastName(userReq.getLastName()); userEntity.setOrganization(userReq.getOrganization()); @@ -216,6 +229,12 @@ public class UserDao { userResponseBean.setCountry(userEntity.getBeneficiary().getCountry()); userResponseBean.setCodiceFiscale(userEntity.getBeneficiary().getCodiceFiscale()); userResponseBean.setDateOfBirth(userEntity.getBeneficiary().getDateOfBirth()); + userResponseBean.setPrivacy(userEntity.getBeneficiary().getPrivacy()); + userResponseBean.setTerms(userEntity.getBeneficiary().getTerms()); + userResponseBean.setOffers(userEntity.getBeneficiary().getOffers()); + userResponseBean.setMarketing(userEntity.getBeneficiary().getMarketing()); + userResponseBean.setThirdParty(userEntity.getBeneficiary().getThirdParty()); + userResponseBean.setEmailPec(userEntity.getBeneficiary().getEmailPec()); } return userResponseBean; } diff --git a/src/main/java/net/gepafin/tendermanagement/entities/BeneficiaryEntity.java b/src/main/java/net/gepafin/tendermanagement/entities/BeneficiaryEntity.java index 302f2af5..bae88c90 100644 --- a/src/main/java/net/gepafin/tendermanagement/entities/BeneficiaryEntity.java +++ b/src/main/java/net/gepafin/tendermanagement/entities/BeneficiaryEntity.java @@ -37,11 +37,28 @@ public class BeneficiaryEntity extends BaseEntity { @Column(name = "COUNTRY") private String country; - + @Column(name = "CODICE_FISCALE") private String codiceFiscale; - + @Column(name = "DATE_OF_BIRTH") private LocalDateTime dateOfBirth; - + + @Column(name = "PRIVACY") + private Boolean privacy; + + @Column(name = "TERMS") + private Boolean terms; + + @Column(name = "MARKETING") + private Boolean marketing; + + @Column(name = "OFFERS") + private Boolean offers; + + @Column(name = "THIRD_PARTY") + private Boolean thirdParty; + + @Column(name = "EMAIL_PEC") + private String emailPec; } diff --git a/src/main/java/net/gepafin/tendermanagement/entities/CompanyEntity.java b/src/main/java/net/gepafin/tendermanagement/entities/CompanyEntity.java index 347e4db1..c35a8cf0 100644 --- a/src/main/java/net/gepafin/tendermanagement/entities/CompanyEntity.java +++ b/src/main/java/net/gepafin/tendermanagement/entities/CompanyEntity.java @@ -50,4 +50,10 @@ public class CompanyEntity extends BaseEntity{ @Column(name = "ANNUAL_REVENUE") private BigDecimal annualRevenue; + + @Column(name = "CONTACT_NAME") + private String contactName; + + @Column(name = "CONTACT_EMAIL") + private String contactEmail; } diff --git a/src/main/java/net/gepafin/tendermanagement/model/request/ApplicationFormFieldRequestBean.java b/src/main/java/net/gepafin/tendermanagement/model/request/ApplicationFormFieldRequestBean.java index 029eb470..993fc7e4 100644 --- a/src/main/java/net/gepafin/tendermanagement/model/request/ApplicationFormFieldRequestBean.java +++ b/src/main/java/net/gepafin/tendermanagement/model/request/ApplicationFormFieldRequestBean.java @@ -9,6 +9,6 @@ public class ApplicationFormFieldRequestBean { private String fieldId; - private String fieldValue; + private Object fieldValue; } diff --git a/src/main/java/net/gepafin/tendermanagement/model/request/CompanyRequest.java b/src/main/java/net/gepafin/tendermanagement/model/request/CompanyRequest.java index 0d8a3185..b9f43932 100644 --- a/src/main/java/net/gepafin/tendermanagement/model/request/CompanyRequest.java +++ b/src/main/java/net/gepafin/tendermanagement/model/request/CompanyRequest.java @@ -21,5 +21,6 @@ public class CompanyRequest { private String numberOfEmployees; private BigDecimal annualRevenue; private Boolean isLegalRepresentant; - + private String contactName; + private String contactEmail; } diff --git a/src/main/java/net/gepafin/tendermanagement/model/request/UpdateUserReq.java b/src/main/java/net/gepafin/tendermanagement/model/request/UpdateUserReq.java index 65eba841..ff267f33 100644 --- a/src/main/java/net/gepafin/tendermanagement/model/request/UpdateUserReq.java +++ b/src/main/java/net/gepafin/tendermanagement/model/request/UpdateUserReq.java @@ -4,6 +4,8 @@ import lombok.Getter; import lombok.Setter; import net.gepafin.tendermanagement.enums.UserStatusEnum; +import java.time.LocalDateTime; + @Getter @Setter public class UpdateUserReq { @@ -17,4 +19,11 @@ public class UpdateUserReq { private String city; private UserStatusEnum status; private String country; + private String codiceFiscale; + private LocalDateTime dateOfBirth; + private Boolean marketing; + private Boolean offers; + private Boolean thirdParty; + + private String emailPec; } diff --git a/src/main/java/net/gepafin/tendermanagement/model/request/UserReq.java b/src/main/java/net/gepafin/tendermanagement/model/request/UserReq.java index c53d65aa..14111818 100644 --- a/src/main/java/net/gepafin/tendermanagement/model/request/UserReq.java +++ b/src/main/java/net/gepafin/tendermanagement/model/request/UserReq.java @@ -31,5 +31,12 @@ public class UserReq { private String codiceFiscale; private LocalDateTime dateOfBirth; + private Boolean privacy; + private Boolean terms; + private Boolean marketing; + private Boolean offers; + private Boolean thirdParty; + + private String emailPec; } diff --git a/src/main/java/net/gepafin/tendermanagement/model/response/CompanyResponse.java b/src/main/java/net/gepafin/tendermanagement/model/response/CompanyResponse.java index 92e79384..e54b040f 100644 --- a/src/main/java/net/gepafin/tendermanagement/model/response/CompanyResponse.java +++ b/src/main/java/net/gepafin/tendermanagement/model/response/CompanyResponse.java @@ -22,5 +22,6 @@ public class CompanyResponse extends BaseBean{ private String numberOfEmployees; private BigDecimal annualRevenue; private Boolean isLegalRepresentant; - + private String contactName; + private String contactEmail; } diff --git a/src/main/java/net/gepafin/tendermanagement/model/response/LoginResponse.java b/src/main/java/net/gepafin/tendermanagement/model/response/LoginResponse.java index d9cf63e9..39fdfb63 100644 --- a/src/main/java/net/gepafin/tendermanagement/model/response/LoginResponse.java +++ b/src/main/java/net/gepafin/tendermanagement/model/response/LoginResponse.java @@ -41,6 +41,18 @@ public class LoginResponse { private LocalDateTime dateOfBirth; + private Boolean privacy; + + private Boolean terms; + + private Boolean marketing; + + private Boolean offers; + + private Boolean thirdParty; + + private String emailPec; + private LocalDateTime createdDate; private LocalDateTime updatedDate; diff --git a/src/main/java/net/gepafin/tendermanagement/model/response/UserResponseBean.java b/src/main/java/net/gepafin/tendermanagement/model/response/UserResponseBean.java index c0457120..b0a5ef38 100644 --- a/src/main/java/net/gepafin/tendermanagement/model/response/UserResponseBean.java +++ b/src/main/java/net/gepafin/tendermanagement/model/response/UserResponseBean.java @@ -39,4 +39,12 @@ public class UserResponseBean extends BaseBean { private LocalDateTime dateOfBirth; private List companies; + private Boolean privacy; + private Boolean terms; + + private Boolean marketing; + private Boolean offers; + private Boolean thirdParty; + + private String emailPec; } diff --git a/src/main/java/net/gepafin/tendermanagement/model/response/UserSamlResponse.java b/src/main/java/net/gepafin/tendermanagement/model/response/UserSamlResponse.java index da732bd4..8fdcbdea 100644 --- a/src/main/java/net/gepafin/tendermanagement/model/response/UserSamlResponse.java +++ b/src/main/java/net/gepafin/tendermanagement/model/response/UserSamlResponse.java @@ -2,6 +2,8 @@ package net.gepafin.tendermanagement.model.response; import lombok.Data; +import java.time.LocalDateTime; + @Data public class UserSamlResponse { @@ -10,4 +12,6 @@ public class UserSamlResponse { private String firstName; private String lastName; + + private LocalDateTime dateOfBirth; } diff --git a/src/main/java/net/gepafin/tendermanagement/service/ApplicationService.java b/src/main/java/net/gepafin/tendermanagement/service/ApplicationService.java index a8f6ad53..edb62c93 100644 --- a/src/main/java/net/gepafin/tendermanagement/service/ApplicationService.java +++ b/src/main/java/net/gepafin/tendermanagement/service/ApplicationService.java @@ -29,6 +29,6 @@ public interface ApplicationService { public NextOrPreviousFormResponse getNextOrPreviousForm(HttpServletRequest request, Long applicationId, Long formId, FormActionEnum action); - public void updateApplicationStatus(HttpServletRequest request, Long applicationId, ApplicationStatusTypeEnum status); + public ApplicationResponse updateApplicationStatus(HttpServletRequest request, Long applicationId, ApplicationStatusTypeEnum status); } diff --git a/src/main/java/net/gepafin/tendermanagement/service/impl/ApplicationServiceImpl.java b/src/main/java/net/gepafin/tendermanagement/service/impl/ApplicationServiceImpl.java index a64afadf..a082a092 100644 --- a/src/main/java/net/gepafin/tendermanagement/service/impl/ApplicationServiceImpl.java +++ b/src/main/java/net/gepafin/tendermanagement/service/impl/ApplicationServiceImpl.java @@ -72,12 +72,13 @@ public class ApplicationServiceImpl implements ApplicationService { public NextOrPreviousFormResponse getNextOrPreviousForm(HttpServletRequest request, Long applicationId, Long formId, FormActionEnum action) { ApplicationEntity applicationEntity = validateApplication(applicationId); - return flowFormDao.getnextOrPreviousForm(applicationEntity, formId, action); + return flowFormDao.getNextOrPreviousForm(applicationEntity, formId, action); } @Override - public void updateApplicationStatus(HttpServletRequest request, Long applicationId, ApplicationStatusTypeEnum status) { - applicationDao.updateApplicationStatus(applicationId, status); + @Transactional(rollbackFor = Exception.class) + public ApplicationResponse updateApplicationStatus(HttpServletRequest request, Long applicationId, ApplicationStatusTypeEnum status) { + return applicationDao.updateApplicationStatus(applicationId, status); } diff --git a/src/main/java/net/gepafin/tendermanagement/service/impl/AuthenticationService.java b/src/main/java/net/gepafin/tendermanagement/service/impl/AuthenticationService.java index a84b325c..4153c2f2 100644 --- a/src/main/java/net/gepafin/tendermanagement/service/impl/AuthenticationService.java +++ b/src/main/java/net/gepafin/tendermanagement/service/impl/AuthenticationService.java @@ -33,6 +33,7 @@ import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler; import org.springframework.stereotype.Service; +import java.time.LocalDate; import java.time.LocalDateTime; import java.util.List; import java.util.Map; @@ -124,6 +125,12 @@ public class AuthenticationService { loginResponse.setCity(user.getBeneficiary().getCity()); loginResponse.setCodiceFiscale(user.getBeneficiary().getCodiceFiscale()); loginResponse.setDateOfBirth(user.getBeneficiary().getDateOfBirth()); + loginResponse.setPrivacy(user.getBeneficiary().getPrivacy()); + loginResponse.setMarketing(user.getBeneficiary().getMarketing()); + loginResponse.setOffers(user.getBeneficiary().getOffers()); + loginResponse.setTerms(user.getBeneficiary().getTerms()); + loginResponse.setThirdParty(user.getBeneficiary().getThirdParty()); + loginResponse.setEmailPec(user.getBeneficiary().getEmailPec()); } return loginResponse; @@ -152,7 +159,7 @@ public class AuthenticationService { UserEntity userEntity = userRepository.findByBeneficiaryCodiceFiscale(cf) .orElseThrow(() -> new ResourceNotFoundException(Status.NOT_FOUND, Translator.toLocale(GepafinConstant.USER_NOT_FOUND_MSG))); - samlResponseLogRepository.delete(samlResponseLogEntity); + //samlResponseLogRepository.delete(samlResponseLogEntity); return getJWTTokenBean(userEntity, Boolean.TRUE); } @@ -182,6 +189,13 @@ public class AuthenticationService { && !userAttributes.get("cognome").isEmpty()) { userSamlResponse.setLastName(userAttributes.get("cognome").get(0).toString()); } + if (userAttributes.containsKey("dataNascita") && userAttributes.get("dataNascita") != null + && !userAttributes.get("dataNascita").isEmpty()) { + String dateString =userAttributes.get("dataNascita").get(0).toString(); + LocalDate dateOfBirth = LocalDate.parse(dateString); + LocalDateTime dateOfBirthWithTime = dateOfBirth.atStartOfDay(); + userSamlResponse.setDateOfBirth(dateOfBirthWithTime); + } userSamlResponse.setCodiceFiscale(cf); return userSamlResponse; } diff --git a/src/main/java/net/gepafin/tendermanagement/util/Utils.java b/src/main/java/net/gepafin/tendermanagement/util/Utils.java index 2238cc1b..746c8e8d 100644 --- a/src/main/java/net/gepafin/tendermanagement/util/Utils.java +++ b/src/main/java/net/gepafin/tendermanagement/util/Utils.java @@ -233,4 +233,47 @@ public class Utils { return data.substring(data.length() - range); } + public static String convertObjectToJsonString(Object object) { + try { + // Check if the object is a string + if (object instanceof String) { + String str = (String) object; + // Return null if the string is null or empty + if (str != null && !str.trim().isEmpty()) { + return str; // Return the non-empty string + } else { + return null; // Return null for null or empty string + } + } else if (object != null) { + // Convert non-string objects (arrays, objects) to JSON strings + return mapper.writeValueAsString(object); + } + return null; // Return null if the object is null + } catch (JsonProcessingException e) { + log.error("Error while converting object to string: {}", e.getMessage(), e); + return null; // Return null in case of exception + } + } + + + public static Object getFieldValueAsObject(String fieldValue) { + ObjectMapper mapper = new ObjectMapper(); + try { + // Check if the string is a valid JSON object, array, or simple string + if (fieldValue.startsWith("{")) { + // Convert to a Map (representing an object) + return mapper.readValue(fieldValue, Map.class); + } else if (fieldValue.startsWith("[")) { + // Convert to a List (representing an array) + return mapper.readValue(fieldValue, List.class); + } else { + // Return the raw string (it's a simple value) + return fieldValue; + } + } catch (JsonProcessingException e) { + log.error("Error while converting string to object: {}", e.getMessage(), e); + return fieldValue; // If there's an error, return the raw string + } + } + } diff --git a/src/main/java/net/gepafin/tendermanagement/web/rest/api/ApplicationApi.java b/src/main/java/net/gepafin/tendermanagement/web/rest/api/ApplicationApi.java index c56680ef..1869655c 100644 --- a/src/main/java/net/gepafin/tendermanagement/web/rest/api/ApplicationApi.java +++ b/src/main/java/net/gepafin/tendermanagement/web/rest/api/ApplicationApi.java @@ -127,7 +127,7 @@ public interface ApplicationApi { @ApiResponse(responseCode = "400", description = "Bad Request", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = { @ExampleObject(value = ErrorConstants.BADREQUEST_ERROR_EXAMPLE) })) }) @PutMapping(value = "/{applicationId}/status", produces = { "application/json" }) - ResponseEntity> updateApplicationStatus(HttpServletRequest request, + ResponseEntity> updateApplicationStatus(HttpServletRequest request, @Parameter(description = "The application id", required = true) @PathVariable("applicationId") Long applicationId, @Parameter(description = "status", required = true)@RequestParam(value = "status", required = true) ApplicationStatusTypeEnum status); diff --git a/src/main/java/net/gepafin/tendermanagement/web/rest/api/CompanyApi.java b/src/main/java/net/gepafin/tendermanagement/web/rest/api/CompanyApi.java index 7b908ee1..b4029444 100644 --- a/src/main/java/net/gepafin/tendermanagement/web/rest/api/CompanyApi.java +++ b/src/main/java/net/gepafin/tendermanagement/web/rest/api/CompanyApi.java @@ -109,7 +109,7 @@ public interface CompanyApi { @Parameter(description = "The company id", required = true) @PathVariable("companyId") Long companyId, @Parameter(description = "Company delegation request object", required = true) @RequestBody CompanyDelegationRequest companyDelegationRequest); - @Operation(summary = "Api to upload company delegation", responses = { @ApiResponse(responseCode = "200", description = "OK"), + @Operation(summary = "Api to upload company delegation (only p7m file format is supported)", 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 = { diff --git a/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/ApplicationApiController.java b/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/ApplicationApiController.java index 69f28492..bcbf8e80 100644 --- a/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/ApplicationApiController.java +++ b/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/ApplicationApiController.java @@ -83,10 +83,10 @@ public class ApplicationApiController implements ApplicationApi { } @Override - public ResponseEntity> updateApplicationStatus(HttpServletRequest request, Long applicationId, + public ResponseEntity> updateApplicationStatus(HttpServletRequest request, Long applicationId, ApplicationStatusTypeEnum status) { - applicationService.updateApplicationStatus(request, applicationId, status); + ApplicationResponse applicationResponse = applicationService.updateApplicationStatus(request, applicationId, status); return ResponseEntity.status(HttpStatus.OK) - .body(new Response<>(null, Status.SUCCESS, Translator.toLocale(GepafinConstant.GET_APPLICATION_SUCCESS_MSG))); + .body(new Response<>(applicationResponse, Status.SUCCESS, Translator.toLocale(GepafinConstant.APPLICATION_STATUS_UPDATED_SUCCESSFULLY))); } } diff --git a/src/main/resources/application-production.properties b/src/main/resources/application-production.properties index f4ea18fa..968d5ac5 100644 --- a/src/main/resources/application-production.properties +++ b/src/main/resources/application-production.properties @@ -9,8 +9,8 @@ spring.h2.console.enabled=true base-url=http://bandi-api.gepafin.it isVatCheckGloballyDisabled = false -fe.base.url=http://gepafin-production-fe.s3-website.eu-central-1.amazonaws.com - +#fe.base.url=http://gepafin-production-fe.s3-website.eu-central-1.amazonaws.com +fe.base.url=http://bandi.gepafin.it #SPID configuration spid.ipd.base.url=https://login.regione.umbria.it active.profile.folder=production \ No newline at end of file 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 56c4b841..13e2bedf 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 @@ -539,7 +539,7 @@ - + TRUNCATE TABLE FORM_FIELD RESTART IDENTITY; @@ -696,7 +696,7 @@ path="classpath:db/dump/inserted_form_field_data_13_09_2024.sql" /> - + @@ -710,6 +710,35 @@ + + + + CREATE OR REPLACE FUNCTION gepafin_schema.clock_timestamp_updated_date_column() + RETURNS TRIGGER + LANGUAGE plpgsql + AS $$ + BEGIN + NEW.updated_date = clock_timestamp(); + RETURN NEW; + END; + $$; + + + + CREATE OR REPLACE FUNCTION gepafin_schema.clock_timestamp_created_date_column() + RETURNS TRIGGER + LANGUAGE plpgsql + AS $$ + BEGIN + IF NEW.created_date IS NULL THEN + NEW.created_date = clock_timestamp(); + END IF; + NEW.updated_date = NEW.created_date; + RETURN NEW; + END; + $$; + + @@ -882,4 +911,35 @@ + + + TRUNCATE TABLE FORM_FIELD RESTART IDENTITY; + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/db/changelog/db.changelog-master.xml b/src/main/resources/db/changelog/db.changelog-master.xml index f44695c7..bf4c4536 100644 --- a/src/main/resources/db/changelog/db.changelog-master.xml +++ b/src/main/resources/db/changelog/db.changelog-master.xml @@ -5,4 +5,5 @@ xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.23.xsd"> + diff --git a/src/main/resources/db/changelog/dynamic-triggers.xml b/src/main/resources/db/changelog/dynamic-triggers.xml new file mode 100644 index 00000000..23f1101e --- /dev/null +++ b/src/main/resources/db/changelog/dynamic-triggers.xml @@ -0,0 +1,51 @@ + + + + + DO $$ + DECLARE + r RECORD; + BEGIN + -- Loop through all tables in the schema that have the 'updated_date' column + FOR r IN ( + SELECT table_name + FROM information_schema.columns + WHERE column_name = 'updated_date' + AND table_schema = 'gepafin_schema' + ) + LOOP + EXECUTE format( + 'CREATE OR REPLACE TRIGGER tg_gepafin_schema_updated_at_%I + BEFORE UPDATE ON gepafin_schema.%I + FOR EACH ROW + EXECUTE FUNCTION gepafin_schema.clock_timestamp_updated_date_column()', + r.table_name, r.table_name + ); + END LOOP; + + -- Loop through all tables in the schema that have the 'created_date' column + FOR r IN ( + SELECT table_name + FROM information_schema.columns + WHERE column_name = 'created_date' + AND table_schema = 'gepafin_schema' + ) + LOOP + EXECUTE format( + 'CREATE OR REPLACE TRIGGER tg_gepafin_schema_created_at_%I + BEFORE INSERT ON gepafin_schema.%I + FOR EACH ROW + EXECUTE FUNCTION gepafin_schema.clock_timestamp_created_date_column()', + r.table_name, r.table_name + ); + END LOOP; + END; + $$ LANGUAGE plpgsql; + + + diff --git a/src/main/resources/db/dump/updated_form_field_data_03-10-2024_1.sql b/src/main/resources/db/dump/updated_form_field_data_03-10-2024_1.sql new file mode 100644 index 00000000..697903cc --- /dev/null +++ b/src/main/resources/db/dump/updated_form_field_data_03-10-2024_1.sql @@ -0,0 +1,101 @@ +INSERT INTO FORM_FIELD (SORT_ORDER, NAME, LABEL, DESCRIPTION, SETTINGS, VALIDATORS, CREATED_DATE, UPDATED_DATE) +VALUES +(1, 'textinput', 'Testo Breve', 'Per risposte concise (nomi, titoli, brevi descrizioni)', + '[{"name": "label", "value": "Testo Breve"}, {"name": "placeholder", "value": ""}]', + '{"isRequired": false, "minLength": null, "maxLength": null, "pattern": null, "custom": null}', + CURRENT_TIMESTAMP, CURRENT_TIMESTAMP), + +(2, 'textarea', 'Testo Lungo', 'Campo di testo esteso per paragrafi, descrizioni, proposte', + '[{"name": "label", "value": "Testo Lungo"}, {"name": "placeholder", "value": ""}]', + '{"isRequired": false, "minLength": null, "maxLength": null, "pattern": null, "custom": null}', + CURRENT_TIMESTAMP, CURRENT_TIMESTAMP), + +(3, 'wysiwyg', 'Campo di Testo Formattato', 'Editor avanzato per testo con formattazione', + '[{"name": "label", "value": "Testo Formattato"}, {"name": "placeholder", "value": ""}]', + '{"isRequired": false, "minLength": null, "maxLength": null, "pattern": null, "custom": null}', + CURRENT_TIMESTAMP, CURRENT_TIMESTAMP), + +(4, 'numberinput', 'Campo Numerico', 'Per l''inserimento di valori numerici (quantità, importi, percentuali)', + '[{"name": "label", "value": "Numero"}, {"name": "placeholder", "value": "0"}, {"name": "step", "value": "0"}]', + '{"isRequired": false, "min": null, "max": null, "pattern": null, "custom": null}', + CURRENT_TIMESTAMP, CURRENT_TIMESTAMP), + +(5, 'radio', 'Scelta Singola', 'Gruppo di opzioni per selezione singola', + '[{"name": "label", "value": "Scelta Singola"}, {"name": "options", "value": []}]', + '{"isRequired": false, "custom": null}', + CURRENT_TIMESTAMP, CURRENT_TIMESTAMP), + +(6, 'select', 'Menu a Tendina', 'Selezione da opzioni predefinite', + '[{"name": "label", "value": "Menu a Tendina"}, {"name": "options", "value": []}]', + '{"isRequired": false, "custom": null}', + CURRENT_TIMESTAMP, CURRENT_TIMESTAMP), + +(7, 'checkboxes', 'Scelta Multipla', 'Gruppo di opzioni per selezione singola o multipla', + '[{"name": "label", "value": "Scelta Multipla"}, {"name": "options", "value": []}]', + '{"isRequired": false, "min": null, "max": null, "custom": null}', + CURRENT_TIMESTAMP, CURRENT_TIMESTAMP), + +(8, 'switch', 'Casella di Spunta', 'Per selezioni binarie, accettazioni, conferme', + '[{"name": "label", "value": "Casella di Spunta"}]', + '{"isRequired": false}', + CURRENT_TIMESTAMP, CURRENT_TIMESTAMP), + +(9, 'datepicker', 'Data', 'Selezione di data', + '[{"name": "label", "value": "Data"}]', + '{"isRequired": false}', + CURRENT_TIMESTAMP, CURRENT_TIMESTAMP), + +(10, 'fileupload', 'Caricamento File', 'Per l''upload di documenti o immagini', + '[{"name": "label", "value": "Caricamento File"}, {"name": "mime", "value": []}]', + '{"isRequired": false, "maxSize": 100000}', + CURRENT_TIMESTAMP, CURRENT_TIMESTAMP), + +(11, 'textinput', 'Campo Partita IVA', 'Specifico per l''inserimento del numero di Partita IVA', + '[{"name": "label", "value": "Partita IVA"}, {"name": "placeholder", "value": ""}]', + '{"isRequired": true, "custom": "isPIVA"}', + CURRENT_TIMESTAMP, CURRENT_TIMESTAMP), + +(12, 'textinput', 'Campo Codice Fiscale','Specifico per l''inserimento del Codice Fiscale italiano per persone fisiche e giuridiche', + '[{"name": "label", "value": "Codice Fiscale"}, {"name": "placeholder", "value": ""}]', + '{"isRequired": true, "custom": "isCodiceFiscale"}', + CURRENT_TIMESTAMP, CURRENT_TIMESTAMP), + +(13, 'textinput', 'Campo CAP','Per l''inserimento del Codice di Avviamento Postale', + '[{"name": "label", "value": "CAP"}, {"name": "placeholder", "value": ""}]', + '{"isRequired": true, "custom": "isCAP"}', + CURRENT_TIMESTAMP, CURRENT_TIMESTAMP), + +(14, 'textinput', 'Campo IBAN', 'Per l''inserimento del codice IBAN', + '[{"name": "label", "value": "IBAN"}, {"name": "placeholder", "value": ""}]', + '{"isRequired": true, "custom": "isIBAN"}', + CURRENT_TIMESTAMP, CURRENT_TIMESTAMP), + +(15, 'textinput', 'Campo Email', 'Per l''inserimento di indirizzi email standard (non PEC)', + '[{"name": "label", "value": "Campo Email"}, {"name": "placeholder", "value": "nome@esempio.it"}]', + '{"isRequired": false, "custom": "isEmail"}', + CURRENT_TIMESTAMP, CURRENT_TIMESTAMP), + +(16, 'textinput', 'Campo PEC', 'Specifico per l''inserimento di un indirizzo di Posta Elettronica Certificata', + '[{"name": "label", "value": "Campo PEC"}, {"name": "placeholder", "value": "nome@pec.it"}]', + '{"isRequired": false, "custom": "isEmailPEC"}', + CURRENT_TIMESTAMP, CURRENT_TIMESTAMP), + +(17, 'textinput', 'Campo URL', 'Per l''inserimento di indirizzi web', + '[{"name": "label", "value": "Indirizzo URL"}, {"name": "placeholder", "value": ""}]', + '{"isRequired": false, "custom": "isUrl"}', + CURRENT_TIMESTAMP, CURRENT_TIMESTAMP), + +(18, 'textinput', 'Marca da bollo', 'Per inserire codice di marca da bollo', + '[{"name": "label", "value": "Marca da bollo"}, {"name": "placeholder", "value": "Numero identificativo"}]', + '{"isRequired": false, "custom": "isMarcaDaBollo"}', + CURRENT_TIMESTAMP, CURRENT_TIMESTAMP), + +(19, 'paragraph', 'Paragrafo', 'Semplice testo formattato', + '[{"name": "text", "value": ""}]', + '{}', + CURRENT_TIMESTAMP, CURRENT_TIMESTAMP), + +(20, 'table', 'Tabella', 'Tabella', + '[{"name": "label", "value": "Tabella"}, {"name": "table_columns", "value": []}]', + '{}', + CURRENT_TIMESTAMP, CURRENT_TIMESTAMP); diff --git a/src/main/resources/message_en.properties b/src/main/resources/message_en.properties index 324d5b79..3be65f9f 100644 --- a/src/main/resources/message_en.properties +++ b/src/main/resources/message_en.properties @@ -216,4 +216,7 @@ validation.error.file.empty=The uploaded file is empty. validation.error.file.invalidType=Only .p7m files are accepted. upload.error.s3=Failed to upload the file to S3. - +call.not.started.yet = The call has not started yet. Please wait until the specified start date and time. +call.already.ended = The call has already ended. You cannot submit the application after the deadline. +status.updated.successfully=Status updated successfully. +application.status.updated.successfully = Application status updated successfully. diff --git a/src/main/resources/message_it.properties b/src/main/resources/message_it.properties index e22bc3b4..bd6a09f7 100644 --- a/src/main/resources/message_it.properties +++ b/src/main/resources/message_it.properties @@ -9,7 +9,7 @@ get_user_success_msg=Utente recuperato con successo. get_user_error_msg=Si � verificato un errore durante il recupero dell'utente. user.not.active=Utente non attivo. Si prega di contattare il supporto. user.already.exist.msg=L'utente esiste gi� per questo codice fiscale. -validate.email=L'email è obbligatoria e deve essere nel formato corretto. Si prega di verificare e riprovare. +validate.email=L'email � obbligatoria e deve essere nel formato corretto. Si prega di verificare e riprovare. validate.password=La password e confPassword sono obbligatorie. Verifica e riprova. # Role-related messages role.created.success=Ruolo creato con successo. @@ -20,7 +20,7 @@ create.role.error=Errore durante la creazione del ruolo. update.role.error=Errore durante l'aggiornamento del ruolo. role.fetch.success=Ruolo recuperato con successo. delete.role.error=Errore durante l'eliminazione del ruolo. -role.id.mandatory=L'ID del ruolo è obbligatorio. +role.id.mandatory=L'ID del ruolo � obbligatorio. # Region-related messages region.created.success=Regione creata con successo. @@ -194,19 +194,24 @@ company.get.success=Azienda recuperata con successo. company.not.found=Azienda non trovata. check.vatnumber.success=Numero di partita IVA verificato con successo. invalid.vatnumber=Numero di partita IVA non valido. -vatnumber.mandatory=Il numero di partita IVA è obbligatorio. -vatnumber.already.exists=Il numero di partita IVA esiste già. +vatnumber.mandatory=Il numero di partita IVA � obbligatorio. +vatnumber.already.exists=Il numero di partita IVA esiste gi�. invalid.email=Email non valida. -company.id.mandatory=L'ID dell'azienda è obbligatorio. -user.already.connected.to.company=L'utente è già collegato a questa azienda. -validation.error.missing.firstName=Il nome è obbligatorio. -validation.error.missing.lastName=Il cognome è obbligatorio. -validation.error.missing.codiceFiscale=Il Codice Fiscale è obbligatorio. +company.id.mandatory=L'ID dell'azienda � obbligatorio. +user.already.connected.to.company=L'utente � gi� collegato a questa azienda. +validation.error.missing.firstName=Il nome � obbligatorio. +validation.error.missing.lastName=Il cognome � obbligatorio. +validation.error.missing.codiceFiscale=Il Codice Fiscale � obbligatorio. delegation.file.upload.success=File di delega caricato con successo. delegation.fetch.success=Delega recuperata con successo. -delegation.template.generation.error=Si è verificato un errore durante la generazione del modello di delega. -validation.error.file.empty=Il file caricato è vuoto. +delegation.template.generation.error=Si � verificato un errore durante la generazione del modello di delega. +validation.error.file.empty=Il file caricato � vuoto. validation.error.file.invalidType=Sono accettati solo file .p7m. upload.error.s3=Impossibile caricare il file su S3. - +company.id.mandatory=L'ID dell'azienda � obbligatorio. +user.already.connected.to.company=L'utente � gi� collegato a questa azienda. +call.not.started.yet = La chiamata non � ancora iniziata. Attendere fino alla data e all'ora di inizio specificate. +call.already.ended = La chiamata � gi� terminata. Non � possibile inviare l'applicazione dopo la scadenza. +status.updated.successfully=Stato aggiornato con successo. +application.status.updated.successfully = Stato dell'applicazione aggiornato con successo.