diff --git a/src/main/java/net/gepafin/tendermanagement/constants/GepafinConstant.java b/src/main/java/net/gepafin/tendermanagement/constants/GepafinConstant.java index 31d409d6..deee5738 100644 --- a/src/main/java/net/gepafin/tendermanagement/constants/GepafinConstant.java +++ b/src/main/java/net/gepafin/tendermanagement/constants/GepafinConstant.java @@ -485,6 +485,8 @@ public class GepafinConstant { public static final String USAGE="usage"; public static final String LIMIT="limit"; public static final String DATA="data"; + public static final String FILE_SELECT = "fileselect"; + public static final String INVALID_LIMIT = "error.invalid.limit"; public static final String PREFERRED_CALL_ID="preferredCallId"; public static final String REGION_ID="regionId"; public static final String DELEGATION_TEMPLATE_CONFIDI="DELEGATION_TEMPLATE_CONFIDI"; diff --git a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationAmendmentRequestDao.java b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationAmendmentRequestDao.java index bcb9efa0..a766d1a5 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationAmendmentRequestDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationAmendmentRequestDao.java @@ -181,6 +181,7 @@ public class ApplicationAmendmentRequestDao { for (ApplicationFormEntity form : forms) { String content = form.getForm().getContent(); List> result = filterByName(content, "fileupload"); + result.addAll(filterByName(content, GepafinConstant.FILE_SELECT)); List amendmentFormFieldResponses= getIdAndLabelFromResult(result); amendmentFormFieldResponses.removeIf(amendmentFormFieldResponse -> { FieldRequest matchingRequest = fieldRequestMap.get(amendmentFormFieldResponse.getFieldId()); @@ -533,12 +534,15 @@ public class ApplicationAmendmentRequestDao { } return response; } - + private Map extractFieldIdToLabelMap(List forms) { return forms.stream() .flatMap(form -> { String content = form.getForm().getContent(); - return getIdAndLabelFromResult(filterByName(content, "fileupload")).stream(); + List> filteredResults = new ArrayList<>(); + filteredResults.addAll(filterByName(content, "fileupload")); + filteredResults.addAll(filterByName(content, GepafinConstant.FILE_SELECT)); + return getIdAndLabelFromResult(filteredResults).stream(); }) .collect(Collectors.toMap(AmendmentFormFieldResponse::getFieldId, AmendmentFormFieldResponse::getLabel)); } diff --git a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationEvaluationDao.java b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationEvaluationDao.java index 336db880..7a5807a2 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationEvaluationDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationEvaluationDao.java @@ -378,6 +378,9 @@ public class ApplicationEvaluationDao { case "fileupload": mapFileFieldDetails(mappedField, formFieldId, applicationForm.getId(), applicationId); break; + case "fileselect": + mapFileFieldDetails(mappedField, formFieldId, applicationForm.getId(), applicationId); + break; case "checkboxes": populateOptionFieldsAsFieldValue(mappedField, formFieldId, applicationForm, applicationId, contentBean); break; @@ -516,7 +519,7 @@ public class ApplicationEvaluationDao { List contentResponseBeans = formDao.convertFormEntityToFormResponseBean(formEntity).getContent(); contentResponseBeans.forEach(contentResponseBean -> { // Check if this is a file upload field that matches the current field response - if ("fileupload".equals(contentResponseBean.getName()) && contentResponseBean.getId().equals(fieldResponse.getId())) { + if (("fileupload".equals(contentResponseBean.getName()) || GepafinConstant.FILE_SELECT.equals(contentResponseBean.getName())) && contentResponseBean.getId().equals(fieldResponse.getId())) { String label = null; // Set the label if available if (contentResponseBean.getSettings() != null) { @@ -1252,7 +1255,9 @@ public class ApplicationEvaluationDao { case "fileupload": populateFileDetailsAsFieldValue(mappedField, formFieldId, applicationForm, applicationId); break; - + case "fileselect": + populateFileDetailsAsFieldValue(mappedField, formFieldId, applicationForm, applicationId); + break; case "checkboxes": populateOptionFieldsAsFieldValue(mappedField, formFieldId, applicationForm, applicationId, contentResponseBean); break; @@ -1402,7 +1407,7 @@ public class ApplicationEvaluationDao { // List contentResponseBeans = Utils.convertJsonStringToList(formEntity.getContent(), ContentResponseBean.class); List contentResponseBeans = formDao.convertFormEntityToFormResponseBean(formEntity).getContent(); contentResponseBeans.forEach(contentResponseBean -> { - if ("fileupload".equals(contentResponseBean.getName()) && contentResponseBean.getId().equals(fieldResponse.getId())) { + if (("fileupload".equals(contentResponseBean.getName()) || GepafinConstant.FILE_SELECT.equals(contentResponseBean.getName())) && contentResponseBean.getId().equals(fieldResponse.getId())) { String label = null; if (contentResponseBean.getSettings() != null) { for (SettingResponseBean setting : contentResponseBean.getSettings()) { @@ -1564,9 +1569,10 @@ public class ApplicationEvaluationDao { mappedField.setFieldName(contentResponseBean.getName()); boolean isCheckbox = "checkboxes".equals(contentResponseBean.getName()); boolean isFileUpload = "fileupload".equals(contentResponseBean.getName()); + boolean isFileSelect = GepafinConstant.FILE_SELECT.equals(contentResponseBean.getName()); boolean isParagraph = "paragraph".equals(contentResponseBean.getName()); boolean isTable = "table".equals(contentResponseBean.getName()); - if (isFileUpload) { + if (isFileUpload || isFileSelect ) { handleFileUpload(applicationId, criteriaFormField, mappedField); } else if (isCheckbox) { handleCheckbox(applicationId, criteriaFormField, contentResponseBean, mappedField); @@ -1773,7 +1779,7 @@ public class ApplicationEvaluationDao { List contentResponseBeans = formDao.convertFormEntityToFormResponseBean(formEntity).getContent(); for (ContentResponseBean contentResponseBean : contentResponseBeans) { - if ("fileupload".equals(contentResponseBean.getName())) { + if ("fileupload".equals(contentResponseBean.getName()) || GepafinConstant.FILE_SELECT.equals(contentResponseBean.getName())) { String fieldId = contentResponseBean.getId(); Long applicationFormId = applicationForm.getId(); @@ -2103,7 +2109,8 @@ public class ApplicationEvaluationDao { List contentResponseBeans=evaluationFormDao.convertEvaluationFormEntityToEvaluationFormResponseBean(evaluationFormEntity).getContent(); for (ContentResponseBean contentResponseBean:contentResponseBeans){ - if(Boolean.TRUE.equals(contentResponseBean.getName().equals("fileupload"))) { + if(Boolean.TRUE.equals(contentResponseBean.getName().equals("fileupload")) || + Boolean.TRUE.equals(contentResponseBean.getName().equals(GepafinConstant.FILE_SELECT))){ if (contentResponseBean.getId().equals(applicationFormFieldRequestBean.getFieldId())) { Object fieldValueObject = applicationFormFieldRequestBean.getFieldValue(); if (fieldValueObject instanceof String) { @@ -2128,7 +2135,8 @@ public class ApplicationEvaluationDao { for (ApplicationEvaluationFormFieldEntity applicationEvaluationFormFieldEntity : evaluationFormFieldEntities) { Optional fileUploadContent = contentResponseBeans.stream() - .filter(contentResponseBean -> "fileupload".equals(contentResponseBean.getName()) && + .filter(contentResponseBean -> ("fileupload".equals(contentResponseBean.getName()) || + GepafinConstant.FILE_SELECT.equals(contentResponseBean.getName())) && contentResponseBean.getId().equals(applicationEvaluationFormFieldEntity.getFieldId())) .findFirst(); diff --git a/src/main/java/net/gepafin/tendermanagement/dao/CallDao.java b/src/main/java/net/gepafin/tendermanagement/dao/CallDao.java index 94fefebc..c57307b4 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/CallDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/CallDao.java @@ -15,6 +15,10 @@ import java.util.stream.Collectors; import java.util.zip.ZipEntry; import java.util.zip.ZipOutputStream; +import jakarta.persistence.criteria.CriteriaBuilder; +import jakarta.persistence.criteria.Expression; +import jakarta.persistence.criteria.Predicate; +import jakarta.persistence.criteria.Root; import jakarta.persistence.criteria.*; import jakarta.servlet.http.HttpServletRequest; import net.gepafin.tendermanagement.entities.*; @@ -796,6 +800,42 @@ public class CallDao { List calls = callRepository.findAll(spec); + if (Boolean.TRUE.equals(onlyPreferredCall)) { + validator.validateUserWithCompany(request, companyId); + UserWithCompanyEntity userWithCompanyEntity=companyService.getUserWithCompany(user.getId(),companyId); + List preferredCalls = beneficiaryPreferredCallRepository + .findByUserIdAndUserWithCompanyIdAndIsDeletedFalse(user.getId(), userWithCompanyEntity.getId()); + List preferredCallIds = preferredCalls.stream() + .map(BeneficiaryPreferredCallEntity::getCallId) + .collect(Collectors.toList()); + calls = callRepository.findByIdInAndStatusIn(preferredCallIds, callStatusList); + } else { + calls = callRepository.findByStatusInAndHubId(callStatusList, user.getHub().getId()); + } + LocalDateTime now = LocalDateTime.now(); + for (CallEntity call : calls) { + CallEntity oldCallEntity = Utils.getClonedEntityForData(call); + if (CallStatusEnum.PUBLISH.getValue().equals(call.getStatus()) && + call.getEndDate() != null && call.getEndTime() != null) { + LocalDateTime callEndDateTime = LocalDateTime.of(LocalDate.from(call.getEndDate()), call.getEndTime()); + if (callEndDateTime.isBefore(now)) { + call.setStatus(CallStatusEnum.EXPIRED.getValue()); + callRepository.save(call); + } + if (Boolean.FALSE.equals(oldCallEntity.getStatus().equals(call.getStatus()))) { + + loggingUtil.logUserAction(UserActionRequest.builder() + .request(request) + .actionType(UserActionLogsEnum.UPDATE) + .actionContext(UserActionContextEnum.UPDATE_EXPIRED_CALL) + .build()); + + /** This code is responsible for adding a version history log for the "update call status to EXPIRED" operation **/ + loggingUtil.addVersionHistory(VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.UPDATE).oldData(oldCallEntity).newData(call).build()); + } + } + } + List callIds = calls.stream().map(CallEntity::getId).collect(Collectors.toList()); Map preferredCallsMap = getBeneficiaryPreferredCallsForUser(request,user, callIds, companyId); @@ -972,7 +1012,7 @@ public class CallDao { Translator.toLocale(GepafinConstant.COMPANY_ID_REQUIRED_FOR_PREFERRED_CALL) ); } - Specification spec = search(user, callPageableRequestBean); + Specification spec = search(request,user, callPageableRequestBean); Page entityPage; if (Boolean.TRUE.equals(onlyPreferredCall)) { validator.validateUserWithCompany(request, companyId); @@ -1022,10 +1062,10 @@ public class CallDao { return pageableResponseBean; } - public Specification search(UserEntity userEntity, CallPageableRequestBean callPageableRequestBean) { + public Specification search(HttpServletRequest request,UserEntity userEntity, CallPageableRequestBean callPageableRequestBean) { return (root, query, criteriaBuilder) -> { - List predicates = getPredicates(callPageableRequestBean, criteriaBuilder, root, userEntity); + List predicates = getPredicates(request,callPageableRequestBean, criteriaBuilder, root, userEntity); SortBy sortBy = new SortBy(GepafinConstant.CREATED_DATE, true); if (callPageableRequestBean.getGlobalFilters() != null @@ -1048,9 +1088,9 @@ public class CallDao { } - private List getPredicates(CallPageableRequestBean callPageableRequestBean, + private List getPredicates(HttpServletRequest request,CallPageableRequestBean callPageableRequestBean, CriteriaBuilder criteriaBuilder, Root root, UserEntity userEntity) { - + expirePublishedCalls(request); Integer year = null; String search = null; Map filters = new HashMap<>(); @@ -1128,11 +1168,59 @@ public class CallDao { predicates.add(criteriaBuilder.equal(root.get(GepafinConstant.HUB).get(GepafinConstant.ID), userEntity.getHub().getId())); - return predicates; } + public void expirePublishedCalls(HttpServletRequest request) { + List expiredCalls = callRepository.findAll((root, query, criteriaBuilder) -> { + Predicate isPublished = criteriaBuilder.equal(root.get(GepafinConstant.STATUS), CallStatusEnum.PUBLISH.name()); + + // Concatenate date and time as a single string + Expression dateTimeString = criteriaBuilder.concat( + root.get(GepafinConstant.END_DATE), + criteriaBuilder.literal(" ") // Space between date and time + ); + Expression fullDateTimeString = criteriaBuilder.concat(dateTimeString, root.get(GepafinConstant.END_TIME)); + + // Convert the concatenated string into TIMESTAMP + Expression endDateTime = criteriaBuilder.function( + "to_timestamp", + LocalDateTime.class, + fullDateTimeString, + criteriaBuilder.literal("YYYY-MM-DD HH24:MI:SS") + ); + + Predicate isExpired = criteriaBuilder.lessThan(endDateTime, LocalDateTime.now()); + + return criteriaBuilder.and(isPublished, isExpired); + }); + + if (!expiredCalls.isEmpty()) { + for (CallEntity call : expiredCalls) { + CallEntity oldCallEntity = Utils.getClonedEntityForData(call); // Clone before modification + call.setStatus(CallStatusEnum.EXPIRED.getValue()); + + if (!oldCallEntity.getStatus().equals(call.getStatus())) { + // Log user action + loggingUtil.logUserAction(UserActionRequest.builder() + .request(request) + .actionType(UserActionLogsEnum.UPDATE) + .actionContext(UserActionContextEnum.UPDATE_EXPIRED_CALL) + .build()); + + // Add version history log + loggingUtil.addVersionHistory(VersionHistoryRequest.builder() + .request(request) + .actionType(VersionActionTypeEnum.UPDATE) + .oldData(oldCallEntity) + .newData(call) + .build()); + } + } + callRepository.saveAll(expiredCalls); // Save all modified calls at once + } + } private void applyFilters(Root root, CriteriaBuilder criteriaBuilder, List predicates, Map filters) { if (Boolean.FALSE.equals(filters.isEmpty())) { for (Map.Entry entry : filters.entrySet()) { diff --git a/src/main/java/net/gepafin/tendermanagement/dao/CompanyDao.java b/src/main/java/net/gepafin/tendermanagement/dao/CompanyDao.java index 1f0446a0..ca9c2621 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/CompanyDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/CompanyDao.java @@ -1,23 +1,33 @@ package net.gepafin.tendermanagement.dao; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.springframework.data.domain.Pageable; // Correct package + import java.util.EnumSet; import java.util.List; import java.util.Map; import jakarta.servlet.http.HttpServletRequest; +import lombok.extern.log4j.Log4j2; import net.gepafin.tendermanagement.entities.*; import net.gepafin.tendermanagement.enums.ApplicationStatusTypeEnum; import net.gepafin.tendermanagement.enums.UserCompanyDelegationStatusEnum; +import net.gepafin.tendermanagement.model.request.LimitRequest; +import net.gepafin.tendermanagement.model.response.VatCheckResponseBean; import net.gepafin.tendermanagement.repositories.*; import net.gepafin.tendermanagement.service.CompanyService; import net.gepafin.tendermanagement.enums.VersionActionTypeEnum; import net.gepafin.tendermanagement.model.request.VersionHistoryRequest; import net.gepafin.tendermanagement.repositories.ApplicationRepository; import net.gepafin.tendermanagement.repositories.FaqRepository; +import net.gepafin.tendermanagement.service.feignClient.VatCheckService; import net.gepafin.tendermanagement.util.LoggingUtil; import net.gepafin.tendermanagement.web.rest.api.errors.*; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Sort; import org.springframework.stereotype.Component; import net.gepafin.tendermanagement.config.Translator; @@ -27,9 +37,11 @@ import net.gepafin.tendermanagement.model.response.CompanyResponse; import net.gepafin.tendermanagement.service.UserService; import net.gepafin.tendermanagement.util.Utils; +import static net.gepafin.tendermanagement.util.Utils.convertObjectToJsonString; import static net.gepafin.tendermanagement.util.Utils.setIfUpdated; @Component +@Log4j2 public class CompanyDao { @Autowired @@ -60,6 +72,13 @@ public class CompanyDao { @Autowired private HttpServletRequest request; + + @Autowired + private VatCheckService vatCheckService; // Service to call VAT API + + + private static final String NOT_FOUND_JSON = "{\"data\": \"not found\"}"; + public CompanyResponse createCompany(UserEntity userEntity, CompanyRequest companyRequest) { CompanyEntity existingCompany = companyRepository.findByVatNumberAndHubId(companyRequest.getVatNumber(), userEntity.getHub().getId()); @@ -410,4 +429,123 @@ public class CompanyDao { VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.SOFT_DELETE).oldData(oldUserWithCompanyData).newData(existingRelation).build()); } + + + public void updateMissingVatCheckResponses(HttpServletRequest request, LimitRequest limitRequest) { + long limit = limitRequest.getLimit(); + + if (limit <= 0 || limit > 3000) { + log.error("Invalid limit: {}. Limit should be between 1 and 3000.", limit); + throw new CustomValidationException(Status.VALIDATION_ERROR, + Translator.toLocale(GepafinConstant.INVALID_LIMIT)); + } + + int successfulUpdates = 0; + int failedUpdates = 0; + int invalidVatNumbers = 0; + + Pageable pageable = PageRequest.of(0, (int) limit, Sort.by("id").ascending()); + Page companyPage = companyRepository.findCompaniesWithMissingVatCheck(pageable); + List companies = companyPage.getContent(); + + if (companies.isEmpty()) { + log.info("No companies found with missing VAT check responses."); + return; + } + + log.info("Processing {} companies with missing VAT check responses...", companies.size()); + + for (CompanyEntity company : companies) { + try { + log.info("Processing company ID: {} with VAT number: {}", company.getId(), company.getVatNumber()); + + VatCheckResponseBean vatResponse = companyService.checkVatNumber(request, company.getVatNumber()); + CompanyEntity oldCompanyData = Utils.getClonedEntityForData(company); + + if (vatResponse != null && vatResponse.getVatCheckResponse() != null) { + // Convert response to JSON and update the JSON field + String jsonResponse = Utils.convertMapIntoJsonString(vatResponse.getVatCheckResponse()); + company.setJson(jsonResponse); + log.info("Company ID {}: JSON field updated successfully.", company.getId()); + + // Extract and set codiceAteco field + updateCodiceAtecoField(company); + + successfulUpdates++; + } else { + company.setJson(NOT_FOUND_JSON); + invalidVatNumbers++; + log.warn("Company ID {}: Invalid or null VAT check response. JSON set to '{}'", company.getId(), NOT_FOUND_JSON); + } + + // Adding version history log + /** This code is responsible for adding a version history log for the "Update MissingVatCheckResponses" operation. **/ + loggingUtil.addVersionHistory( + VersionHistoryRequest.builder() + .request(request) + .actionType(VersionActionTypeEnum.UPDATE) + .oldData(oldCompanyData) + .newData(company) + .build()); + + } catch (Exception e) { + failedUpdates++; + log.error("Error updating VAT check response for company ID {}: {}", company.getId(), e.getMessage(), e); + } + } + + companyRepository.saveAll(companies); + + log.info("VAT check update completed. Limit: {} | Successful: {} | Invalid VAT numbers: {} | Failed: {}", + limit, successfulUpdates, invalidVatNumbers, failedUpdates); + } + + private void updateCodiceAtecoField(CompanyEntity company) { + Map vatCheckResponse = Utils.convertJsonStringToMap(company.getJson()); + + if (vatCheckResponse != null && vatCheckResponse.containsKey("data")) { + Object dataObj = vatCheckResponse.get("data"); + + if (dataObj instanceof Map) { + Map dataMap = (Map) dataObj; + log.info("Company ID {}: Available keys inside 'data' -> {}", company.getId(), dataMap.keySet()); + + if (dataMap.containsKey("dettaglio")) { + Object dettaglioObj = dataMap.get("dettaglio"); + + if (dettaglioObj instanceof Map) { + Map dettaglio = (Map) dettaglioObj; + + if (dettaglio.containsKey("codice_ateco")) { + Object codiceAtecoObj = dettaglio.get("codice_ateco"); + + if (codiceAtecoObj instanceof String) { + String codiceAteco = (String) codiceAtecoObj; + + if (codiceAteco != null && !codiceAteco.isEmpty()) { + company.setCodiceAteco(codiceAteco); + log.info("Company ID {}: codiceAteco updated to {}", company.getId(), codiceAteco); + } else { + log.warn("Company ID {}: codiceAteco is null or empty in the response.", company.getId()); + } + } else { + log.warn("Company ID {}: 'codice_ateco' is not a string, actual type: {}", company.getId(), codiceAtecoObj.getClass()); + } + } else { + log.warn("Company ID {}: 'dettaglio' does not contain 'codice_ateco' key.", company.getId()); + } + } else { + log.warn("Company ID {}: 'dettaglio' is not a Map, actual type: {}", company.getId(), dettaglioObj.getClass()); + } + } else { + log.warn("Company ID {}: 'dettaglio' section is missing inside 'data'!", company.getId()); + } + } else { + log.warn("Company ID {}: 'data' is not a Map, actual type: {}", company.getId(), dataObj.getClass()); + } + } else { + log.warn("Company ID {}: 'data' section missing in the JSON response.", company.getId()); + } + } + } diff --git a/src/main/java/net/gepafin/tendermanagement/dao/EmailNotificationDao.java b/src/main/java/net/gepafin/tendermanagement/dao/EmailNotificationDao.java index 25b54319..185d1c62 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/EmailNotificationDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/EmailNotificationDao.java @@ -184,8 +184,11 @@ public class EmailNotificationDao { // Extract data from forms for (ApplicationFormEntity form : forms) { String content = form.getForm().getContent(); - List> result = filterByName(content, "fileupload"); - allFormFields.addAll(getIdAndLabelFromResult(result)); + List> fileUploadResult = filterByName(content, "fileupload"); + allFormFields.addAll(getIdAndLabelFromResult(fileUploadResult)); + + List> fileSelectResult = filterByName(content,GepafinConstant.FILE_SELECT); + allFormFields.addAll(getIdAndLabelFromResult(fileSelectResult)); } // Process allFormFields and generate bullet points diff --git a/src/main/java/net/gepafin/tendermanagement/enums/UserActionContextEnum.java b/src/main/java/net/gepafin/tendermanagement/enums/UserActionContextEnum.java index c1d0d83e..a1f7ee5c 100644 --- a/src/main/java/net/gepafin/tendermanagement/enums/UserActionContextEnum.java +++ b/src/main/java/net/gepafin/tendermanagement/enums/UserActionContextEnum.java @@ -65,6 +65,7 @@ public enum UserActionContextEnum { CHECK_COMPANY_VAT_NUMBER("CHECK_COMPANY_VAT_NUMBER"), GET_COMPANY_BY_USER("GET_COMPANY_BY_USER"), REMOVE_COMPANY_FROM_USER("REMOVE_COMPANY_FROM_USER"), + UPDATE_COMPANY_JSON("UPDATE_COMPANY_JSON"), /** LookUpData action context **/ CREATE_LOOKUP_DATA("CREATE_LOOKUP_DATA"), @@ -213,7 +214,8 @@ public enum UserActionContextEnum { GET_ALL_APPLICATION_AMENDMENT_BY_PAGINATION("GET_ALL_APPLICATION_AMENDMENT_BY_PAGINATION"), GET_ALL_USER_ACTION_BY_PAGINATION("GET_ALL_USER_ACTION_BY_PAGINATION"), GET_ALL_USER_BY_PAGINATION("GET_ALL_USER_BY_PAGINATION"), - UPDATE_CALL_END_DATE_AND_TIME("UPDATE_CALL_END_DATE_AND_TIME"); + UPDATE_CALL_END_DATE_AND_TIME("UPDATE_CALL_END_DATE_AND_TIME"), + UPDATE_EXPIRED_CALL("UPDATE_EXPIRED_CALL") ; private final String value; diff --git a/src/main/java/net/gepafin/tendermanagement/model/request/LimitRequest.java b/src/main/java/net/gepafin/tendermanagement/model/request/LimitRequest.java new file mode 100644 index 00000000..6d360714 --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/model/request/LimitRequest.java @@ -0,0 +1,8 @@ +package net.gepafin.tendermanagement.model.request; + +import lombok.Data; + +@Data +public class LimitRequest { + private Long limit; +} diff --git a/src/main/java/net/gepafin/tendermanagement/repositories/CompanyRepository.java b/src/main/java/net/gepafin/tendermanagement/repositories/CompanyRepository.java index b9395883..350b9b49 100644 --- a/src/main/java/net/gepafin/tendermanagement/repositories/CompanyRepository.java +++ b/src/main/java/net/gepafin/tendermanagement/repositories/CompanyRepository.java @@ -1,7 +1,10 @@ package net.gepafin.tendermanagement.repositories; +import org.springframework.data.domain.Pageable; + import java.util.List; +import org.springframework.data.domain.Page; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; @@ -21,5 +24,12 @@ public interface CompanyRepository extends JpaRepository { CompanyEntity findByVatNumberAndHubId(String vatNumber, Long hubId); + @Query(""" + SELECT c FROM CompanyEntity c + WHERE c.vatNumber IS NOT NULL + AND (c.json IS NULL OR c.json = '') +""") + Page findCompaniesWithMissingVatCheck(Pageable pageable); + } diff --git a/src/main/java/net/gepafin/tendermanagement/service/CompanyService.java b/src/main/java/net/gepafin/tendermanagement/service/CompanyService.java index da36cc15..ae752c04 100644 --- a/src/main/java/net/gepafin/tendermanagement/service/CompanyService.java +++ b/src/main/java/net/gepafin/tendermanagement/service/CompanyService.java @@ -4,6 +4,7 @@ import java.io.ByteArrayOutputStream; import java.util.List; import java.util.Map; +import net.gepafin.tendermanagement.model.request.LimitRequest; import net.gepafin.tendermanagement.model.response.VatCheckResponseBean; import org.springframework.web.multipart.MultipartFile; @@ -45,4 +46,6 @@ public interface CompanyService { UserWithCompanyEntity getUserWithCompanyEntity(Long userId,Long companyId); void removeCompanyFromList(HttpServletRequest request, Long companyId); + void updateMissingVatCheckResponses(HttpServletRequest request, LimitRequest limitRequest); + } diff --git a/src/main/java/net/gepafin/tendermanagement/service/impl/CallServiceImpl.java b/src/main/java/net/gepafin/tendermanagement/service/impl/CallServiceImpl.java index 8dfbd861..d58a7644 100644 --- a/src/main/java/net/gepafin/tendermanagement/service/impl/CallServiceImpl.java +++ b/src/main/java/net/gepafin/tendermanagement/service/impl/CallServiceImpl.java @@ -61,7 +61,7 @@ public class CallServiceImpl implements CallService { } @Override - @Transactional(readOnly = true) + @Transactional(rollbackFor = Exception.class) public List getAllCalls(HttpServletRequest request,Long companyId,Boolean onlyPreferredCall,Boolean onlyConfidiCall) { UserEntity user = validator.validateUser(request); return callDao.getAllCalls(request,user,companyId,onlyPreferredCall,onlyConfidiCall); @@ -104,6 +104,7 @@ public class CallServiceImpl implements CallService { } @Override + @Transactional(rollbackFor = Exception.class) public PageableResponseBean> getAllCallsByPagination(HttpServletRequest request,Long companyId , Boolean onlyPreferredCall, CallPageableRequestBean callPageableRequestBean) { UserEntity user = validator.validateUser(request); return callDao.getAllCallsByPagination(request,user,companyId,onlyPreferredCall,callPageableRequestBean); diff --git a/src/main/java/net/gepafin/tendermanagement/service/impl/CompanyServiceImpl.java b/src/main/java/net/gepafin/tendermanagement/service/impl/CompanyServiceImpl.java index 092c5102..1e77eddb 100644 --- a/src/main/java/net/gepafin/tendermanagement/service/impl/CompanyServiceImpl.java +++ b/src/main/java/net/gepafin/tendermanagement/service/impl/CompanyServiceImpl.java @@ -4,6 +4,7 @@ import java.io.ByteArrayOutputStream; import java.util.List; import java.util.Map; +import net.gepafin.tendermanagement.model.request.LimitRequest; import net.gepafin.tendermanagement.model.response.VatCheckResponseBean; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @@ -130,4 +131,10 @@ public class CompanyServiceImpl implements CompanyService { UserEntity userEntity =validator.validateUser(request); companyDao.removeCompanyFromList(userEntity, companyId); } + + @Override + public void updateMissingVatCheckResponses(HttpServletRequest request, LimitRequest limitRequest) { + UserEntity userEntity =validator.validateUser(request); + companyDao.updateMissingVatCheckResponses(request, limitRequest); + } } diff --git a/src/main/java/net/gepafin/tendermanagement/util/FieldValidator.java b/src/main/java/net/gepafin/tendermanagement/util/FieldValidator.java index caccec60..6b286642 100644 --- a/src/main/java/net/gepafin/tendermanagement/util/FieldValidator.java +++ b/src/main/java/net/gepafin/tendermanagement/util/FieldValidator.java @@ -63,8 +63,8 @@ public class FieldValidator { if (value != null) { if(min!=null) { if(contentResponseBean.getName().equals(GepafinConstant.NUMBER_INPUT)) { - long numericValue = Long.parseLong(value); // Convert String to Long - if (numericValue < min) { + double numericValue = Double.parseDouble(value); // Use double instead of long + if (numericValue < min.doubleValue()) { errors.add(MessageFormat.format( Translator.toLocale(GepafinConstant.VALIDATION_FIELD_MIN), fieldLabel, min)); } @@ -90,8 +90,8 @@ public class FieldValidator { if (value != null) { if (max != null) { if(contentResponseBean.getName().equals(GepafinConstant.NUMBER_INPUT)) { - long numericValue = Long.parseLong(value); // Convert String to Long - if (numericValue > max) { + double numericValue = Double.parseDouble(value); // Convert String to Long + if (numericValue > max.doubleValue()) { errors.add(MessageFormat.format( Translator.toLocale(GepafinConstant.VALIDATION_FIELD_MAX), fieldLabel, max)); } diff --git a/src/main/java/net/gepafin/tendermanagement/util/Utils.java b/src/main/java/net/gepafin/tendermanagement/util/Utils.java index 06abaaab..1838bd57 100644 --- a/src/main/java/net/gepafin/tendermanagement/util/Utils.java +++ b/src/main/java/net/gepafin/tendermanagement/util/Utils.java @@ -788,4 +788,12 @@ public class Utils { public static boolean isValidBoolean(String value) { return "true".equalsIgnoreCase(value) || "false".equalsIgnoreCase(value); } + public static Map convertJsonStringToMap(String jsonString) { + try { + return mapper.readValue(jsonString, Map.class); + } catch (Exception e) { + e.printStackTrace(); // Handle the exception + return null; + } + } } \ No newline at end of file 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 6384f4d7..fea29d0d 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 @@ -3,9 +3,11 @@ package net.gepafin.tendermanagement.web.rest.api; import java.util.List; import java.util.Map; +import net.gepafin.tendermanagement.model.request.LimitRequest; import net.gepafin.tendermanagement.model.response.VatCheckResponseBean; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; +import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; @@ -155,4 +157,16 @@ public interface CompanyApi { ResponseEntity> removeCompanyFromList(HttpServletRequest request, @Parameter(description = "The company id", required = true) @PathVariable("companyId") Long companyId); + + @Operation(summary = "Api to update company with no data through script", responses = { @ApiResponse(responseCode = "200", description = "OK"), + @ApiResponse(responseCode = "404", description = "Not Found", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = { + @ExampleObject(value = ErrorConstants.NOTFOUND_ERROR_EXAMPLE) })), + @ApiResponse(responseCode = "401", description = "Unauthorized", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = { + @ExampleObject(value = ErrorConstants.UNAUTHORIZED_ERROR_EXAMPLE) })), + @ApiResponse(responseCode = "400", description = "Bad Request", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = { + @ExampleObject(value = ErrorConstants.BADREQUEST_ERROR_EXAMPLE) })) }) + @PostMapping(value = "/updateCompanyJson", produces = { "application/json" }) + @PreAuthorize("hasRole('ROLE_SUPER_ADMIN') ") + ResponseEntity> updateMissingVatCheckResponses(HttpServletRequest request, + @Parameter(description = "Limit request object ", required = true) @RequestBody LimitRequest limitRequest); } diff --git a/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/CompanyApiController.java b/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/CompanyApiController.java index 0bfb0e7a..64dee16b 100644 --- a/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/CompanyApiController.java +++ b/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/CompanyApiController.java @@ -6,6 +6,7 @@ import java.util.Map; import net.gepafin.tendermanagement.enums.UserActionContextEnum; import net.gepafin.tendermanagement.enums.UserActionLogsEnum; +import net.gepafin.tendermanagement.model.request.LimitRequest; import net.gepafin.tendermanagement.model.request.UserActionRequest; import net.gepafin.tendermanagement.model.response.VatCheckResponseBean; import net.gepafin.tendermanagement.util.LoggingUtil; @@ -188,4 +189,16 @@ public class CompanyApiController implements CompanyApi{ return ResponseEntity.status(HttpStatus.OK) .body(new Response<>(null, Status.SUCCESS, Translator.toLocale(GepafinConstant.COMPANY_DELETE_SUCCESS_MSG))); } + @Override + public ResponseEntity> updateMissingVatCheckResponses(HttpServletRequest request, LimitRequest limitRequest) { + log.info("Api to update company json field"); + + /** This code is responsible for creating user action logs for the "Update company json field" operation. **/ + loggingUtil.logUserAction(UserActionRequest.builder().request(request).actionType(UserActionLogsEnum.UPDATE).actionContext(UserActionContextEnum.UPDATE_COMPANY_JSON).build()); + + companyService.updateMissingVatCheckResponses(request, limitRequest); + + return ResponseEntity.status(HttpStatus.OK) + .body(new Response<>(null, Status.SUCCESS, Translator.toLocale(GepafinConstant.COMPANY_UPDATED_SUCCESS_MSG))); + } } diff --git a/src/main/resources/message_en.properties b/src/main/resources/message_en.properties index d312160e..c7b9a3f3 100644 --- a/src/main/resources/message_en.properties +++ b/src/main/resources/message_en.properties @@ -394,4 +394,5 @@ appointment.cannot.be.created = Appointment cannot be created because call doesn appointment.not.created = Appointment not created please try again. validation.failed.checklist=Validation failed for checklist. +error.invalid.limit=Limit should be between 1 and 3000. insufficient.score.msg = Insufficient score to pass to the technical and economic-financial evaluation diff --git a/src/main/resources/message_it.properties b/src/main/resources/message_it.properties index 67a3921c..88d38ab1 100644 --- a/src/main/resources/message_it.properties +++ b/src/main/resources/message_it.properties @@ -385,4 +385,5 @@ appointment.cannot.be.created = Impossibile creare l'appuntamento perch� la ch appointment.not.created = Appuntamento non creato, riprova validation.failed.checklist=Convalida fallita per la checklist. +error.invalid.limit=Il limite dovrebbe essere compreso tra 1 e 3000. insufficient.score.msg = Punteggio non sufficiente per passaggio alla valutazione tecnica ed economico finanziaria