package net.gepafin.tendermanagement.dao; import java.util.EnumSet; import java.util.List; import java.util.Map; import jakarta.servlet.http.HttpServletRequest; import net.gepafin.tendermanagement.entities.*; import net.gepafin.tendermanagement.enums.ApplicationStatusTypeEnum; import net.gepafin.tendermanagement.enums.UserCompanyDelegationStatusEnum; 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.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.stereotype.Component; import net.gepafin.tendermanagement.config.Translator; import net.gepafin.tendermanagement.constants.GepafinConstant; import net.gepafin.tendermanagement.model.request.CompanyRequest; 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.setIfUpdated; @Component public class CompanyDao { @Autowired private CompanyRepository companyRepository; @Autowired private UserService userService; @Autowired private UserWithCompanyRepository userWithCompanyRepository; @Autowired private ApplicationRepository applicationRepository; @Autowired private FaqRepository faqRepository; @Autowired private BeneficiaryPreferredCallRepository beneficiaryPreferredCallRepository; @Autowired private UserCompanyDelegationRepository userCompanyDelegationRepository; @Autowired private CompanyService companyService; @Autowired private LoggingUtil loggingUtil; @Autowired private HttpServletRequest request; public CompanyResponse createCompany(UserEntity userEntity, CompanyRequest companyRequest) { CompanyEntity existingCompany = companyRepository.findByVatNumberAndHubId(companyRequest.getVatNumber(), userEntity.getHub().getId()); UserWithCompanyEntity userWithCompanyEntity = null; if (existingCompany != null) { UserWithCompanyEntity existingRelation = userWithCompanyRepository.findByUserIdAndCompanyIdAndIsDeletedFalse(userEntity.getId(), existingCompany.getId()).orElse(null); if (existingRelation == null) { userWithCompanyEntity = createUserWithCompanyRelation(userEntity, existingCompany, companyRequest.getIsLegalRepresentant(),companyRequest); /** This code is responsible for adding a version history log for "adding user with company" operation. **/ loggingUtil.addVersionHistory( VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.INSERT).oldData(null).newData(userWithCompanyEntity).build()); } else { throw new CustomValidationException(Status.VALIDATION_ERROR, Translator.toLocale(GepafinConstant.USER_ALREADY_CONNECTED_TO_COMPANY)); } return convertCompanyEntityToCompanyResponse(existingCompany, userWithCompanyEntity); } else { validateCompany(userEntity, companyRequest); CompanyEntity companyEntity = convertCompanyRequestToCompanyEntity(userEntity, companyRequest); CompanyEntity companyData = companyRepository.save(companyEntity); /** This code is responsible for adding a version history log for "creating company" operation. **/ loggingUtil.addVersionHistory(VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.INSERT).oldData(null).newData(companyData).build()); userWithCompanyEntity = createUserWithCompanyRelation(userEntity, companyEntity, companyRequest.getIsLegalRepresentant(),companyRequest); return convertCompanyEntityToCompanyResponse(companyEntity, userWithCompanyEntity); } } private void validateCompany(UserEntity userEntity, CompanyRequest companyRequest) { if (Boolean.FALSE.equals(StringUtils.isEmpty(companyRequest.getEmail())) && Boolean.FALSE.equals(Utils.isValidEmail(companyRequest.getEmail()))) { throw new CustomValidationException(Status.VALIDATION_ERROR, Translator.toLocale(GepafinConstant.INVALID_EMAIL)); } if (StringUtils.isEmpty(companyRequest.getVatNumber())) { throw new CustomValidationException(Status.VALIDATION_ERROR, Translator.toLocale(GepafinConstant.VATNUMBER_MANDATORY)); } if (companyRepository.existsByVatNumberAndHubId(companyRequest.getVatNumber(), userEntity.getHub().getId())) { throw new CustomValidationException(Status.VALIDATION_ERROR, Translator.toLocale(GepafinConstant.VATNUMBER_ALREADY_EXISTS)); } } private UserWithCompanyEntity createUserWithCompanyRelation(UserEntity userEntity, CompanyEntity companyEntity, Boolean isLegalRepresentant,CompanyRequest companyRequest) { UserWithCompanyEntity userWithCompanyEntity = new UserWithCompanyEntity(); if (userEntity.getBeneficiary() != null) { userWithCompanyEntity.setBeneficiaryId(userEntity.getBeneficiary().getId()); } userWithCompanyEntity.setIsDeleted(Boolean.FALSE); userWithCompanyEntity.setCompanyId(companyEntity.getId()); userWithCompanyEntity.setUserId(userEntity.getId()); userWithCompanyEntity.setIsLegalRepresentant(isLegalRepresentant); userWithCompanyEntity.setEmail(companyRequest.getEmail()); userWithCompanyEntity.setPec(companyRequest.getPec()); userWithCompanyEntity.setContactName(companyRequest.getContactName()); userWithCompanyEntity.setContactEmail(companyRequest.getContactEmail()); UserWithCompanyEntity userWithCompany = userWithCompanyRepository.save(userWithCompanyEntity); /** This code is responsible for adding a version history log for the "adding user with company" operation. **/ loggingUtil.addVersionHistory(VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.INSERT).oldData(null).newData(userWithCompany).build()); if (StringUtils.isEmpty(companyEntity.getJson())) { companyEntity.setJson(Utils.convertMapIntoJsonString(companyRequest.getVatCheckResponse())); Map vatCheckResponse = companyRequest.getVatCheckResponse(); Map data = (Map) vatCheckResponse.get("data"); if (data != null) { if (data.containsKey("dettaglio")) { Map dettaglio = (Map) data.get("dettaglio"); if (dettaglio != null) { if (dettaglio.containsKey("codice_ateco")) { Object codiceAtecoObj = dettaglio.get("codice_ateco"); String codiceAteco = (codiceAtecoObj != null) ? codiceAtecoObj.toString() : null; if (codiceAteco != null) { companyEntity.setCodiceAteco(codiceAteco); } } } } } companyEntity = companyRepository.save(companyEntity); /** This code is responsible for adding a version history log for "updating company json field" operation. **/ loggingUtil.addVersionHistory(VersionHistoryRequest.builder() .request(request) .actionType(VersionActionTypeEnum.INSERT) .oldData(null) .newData(companyEntity) .build()); } return userWithCompany; } private CompanyEntity convertCompanyRequestToCompanyEntity(UserEntity userEntity, CompanyRequest request) { CompanyEntity entity = new CompanyEntity(); entity.setCompanyName(request.getCompanyName()); entity.setVatNumber(request.getVatNumber()); entity.setCodiceFiscale(request.getCodiceFiscale()); entity.setAddress(request.getAddress()); entity.setPhoneNumber(request.getPhoneNumber()); entity.setCity(request.getCity()); entity.setProvince(request.getProvince()); entity.setCap(request.getCap()); entity.setCountry(request.getCountry()); entity.setNumberOfEmployees(request.getNumberOfEmployees()); entity.setAnnualRevenue(request.getAnnualRevenue()); entity.setHub(userEntity.getHub()); entity.setJson(Utils.convertMapIntoJsonString(request.getVatCheckResponse())); if (request.getVatCheckResponse() != null) { Map vatCheckResponse = request.getVatCheckResponse(); Map data = (Map) vatCheckResponse.get("data"); if (data != null) { if (data.containsKey("dettaglio")) { Map dettaglio = (Map) data.get("dettaglio"); if (dettaglio != null) { if (dettaglio.containsKey("codice_ateco")) { Object codiceAtecoObj = dettaglio.get("codice_ateco"); String codiceAteco = (codiceAtecoObj != null) ? codiceAtecoObj.toString() : null; if (codiceAteco != null) { entity.setCodiceAteco(codiceAteco); } } } } } } return entity; } private CompanyResponse convertCompanyEntityToCompanyResponse(CompanyEntity entity, UserWithCompanyEntity userWithCompanyEntity) { CompanyResponse response = new CompanyResponse(); response.setId(entity.getId()); response.setCompanyName(entity.getCompanyName()); response.setVatNumber(entity.getVatNumber()); response.setCodiceFiscale(entity.getCodiceFiscale()); response.setAddress(entity.getAddress()); response.setPhoneNumber(entity.getPhoneNumber()); response.setCity(entity.getCity()); response.setProvince(entity.getProvince()); response.setCap(entity.getCap()); response.setCountry(entity.getCountry()); response.setPec(userWithCompanyEntity.getPec()); response.setEmail(userWithCompanyEntity.getEmail()); response.setNumberOfEmployees(entity.getNumberOfEmployees()); response.setAnnualRevenue(entity.getAnnualRevenue()); if(userWithCompanyEntity!=null) { response.setIsLegalRepresentant(userWithCompanyEntity.getIsLegalRepresentant()); response.setCodiceAteco(entity.getCodiceAteco()); } response.setCreatedDate(entity.getCreatedDate()); response.setUpdatedDate(entity.getUpdatedDate()); response.setContactName(userWithCompanyEntity.getContactName()); response.setContactEmail(userWithCompanyEntity.getContactEmail()); return response; } public CompanyResponse updateCompany(UserEntity userEntity, Long companyId, CompanyRequest companyRequest) { CompanyEntity companyEntity = validateCompany(companyId); //cloned entity for old data CompanyEntity oldCompanyData = Utils.getClonedEntityForData(companyEntity); setIfUpdated(companyEntity::getCompanyName, companyEntity::setCompanyName, companyRequest.getCompanyName()); setIfUpdated(companyEntity::getCodiceFiscale, companyEntity::setCodiceFiscale, companyRequest.getCodiceFiscale()); setIfUpdated(companyEntity::getAddress, companyEntity::setAddress, companyRequest.getAddress()); setIfUpdated(companyEntity::getPhoneNumber, companyEntity::setPhoneNumber, companyRequest.getPhoneNumber()); 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::getNumberOfEmployees, companyEntity::setNumberOfEmployees, companyRequest.getNumberOfEmployees()); setIfUpdated(companyEntity::getAnnualRevenue, companyEntity::setAnnualRevenue, companyRequest.getAnnualRevenue()); // // if(StringUtils.isNotBlank(companyRequest.getVatNumber())) { // CompanyEntity existingCompany = companyRepository.findByVatNumberAndHubId(companyRequest.getVatNumber(), userEntity.getHub().getId()); // if(existingCompany!=null){ // throw new CustomValidationException(Status.BAD_REQUEST, Translator.toLocale(GepafinConstant.VATNUMBER_ALREADY_EXISTS)); // } // companyEntity.setVatNumber(companyRequest.getVatNumber()); // // } companyRepository.save(companyEntity); /** This code is responsible for adding a version history log for the "Update company" operation. **/ loggingUtil.addVersionHistory( VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.UPDATE).oldData(oldCompanyData).newData(companyEntity).build()); UserWithCompanyEntity userWithCompanyEntity = getUserWithCompany(userEntity.getId(), companyId); //cloned entity for old data UserWithCompanyEntity oldUserWithCompanyData = Utils.getClonedEntityForData(userWithCompanyEntity); // if(StringUtils.isNotBlank(companyRequest.getVatNumber())) { // String responseJson = companyRequest.getVatCheckResponse() != null ? Utils.convertMapIntoJsonString(companyRequest.getVatCheckResponse()) : null; // setIfUpdated(companyEntity::getJson, companyEntity::setJson, responseJson); // } setIfUpdated(userWithCompanyEntity::getPec, userWithCompanyEntity::setPec, companyRequest.getPec()); setIfUpdated(userWithCompanyEntity::getEmail, userWithCompanyEntity::setEmail, companyRequest.getEmail()); setIfUpdated(userWithCompanyEntity::getContactName, userWithCompanyEntity::setContactName, companyRequest.getContactName()); setIfUpdated(userWithCompanyEntity::getContactEmail, userWithCompanyEntity::setContactEmail, companyRequest.getContactEmail()); setIfUpdated(userWithCompanyEntity::getIsLegalRepresentant, userWithCompanyEntity::setIsLegalRepresentant, companyRequest.getIsLegalRepresentant()); userWithCompanyEntity = userWithCompanyRepository.save(userWithCompanyEntity); /** This code is responsible for adding a version history log for the "Update company" operation. **/ loggingUtil.addVersionHistory( VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.UPDATE).oldData(oldUserWithCompanyData).newData(userWithCompanyEntity).build()); return convertCompanyEntityToCompanyResponse(companyEntity, userWithCompanyEntity); } public CompanyEntity validateCompany(Long companyId) { return companyRepository.findById(companyId).orElseThrow(() -> new ResourceNotFoundException(Status.NOT_FOUND, Translator.toLocale(GepafinConstant.COMPANY_NOT_FOUND_MSG))); } public CompanyResponse getCompany(UserEntity userEntity, Long companyId) { UserWithCompanyEntity userWithCompanyEntity = getUserWithCompany(userEntity.getId(), companyId); return convertCompanyEntityToCompanyResponse(validateCompany(companyId), userWithCompanyEntity); } public void deleteCompany(UserEntity userEntity, Long companyId) { CompanyEntity companyEntity = validateCompany(companyId); /** This code is responsible for adding a version history log for the "delete company" operation. **/ loggingUtil.addVersionHistory(VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.DELETE).oldData(companyEntity).newData(null).build()); companyRepository.delete(companyEntity); UserWithCompanyEntity userWithCompanyEntity = getUserWithCompany(userEntity.getId(), companyId); /** This code is responsible for adding a version history log for the "delete user with company" operation. **/ loggingUtil.addVersionHistory( VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.DELETE).oldData(userWithCompanyEntity).newData(null).build()); userWithCompanyRepository.deleteByCompanyIdAndIsDeletedFalse(companyId); } public List getCompanyByUserId(Long userId) { UserEntity userEntity = userService.validateUser(userId); List activeCompanyIds = userWithCompanyRepository.findActiveCompanyIdsByUserId(userEntity.getId()); List companies = companyRepository.findByIdInAndHubId(activeCompanyIds, userEntity.getHub().getId()); return companies.stream().map(companyEntity -> { UserWithCompanyEntity userWithCompanyEntity = getUserWithCompany(userEntity.getId(), companyEntity.getId()); return convertCompanyEntityToCompanyResponse(companyEntity, userWithCompanyEntity); }).toList(); } public UserWithCompanyEntity validateUserWithCompny(Long userId, Long companyId) { return userWithCompanyRepository.findByUserIdAndCompanyIdAndIsDeletedFalse(userId, companyId).orElseThrow(() -> new ForbiddenAccessException(Status.FORBIDDEN, Translator.toLocale(GepafinConstant.PERMISSION_DENIED))); } public UserWithCompanyEntity getUserWithCompany(Long userId, Long compnayId) { return userWithCompanyRepository.findByUserIdAndCompanyIdAndIsDeletedFalse(userId, compnayId).orElseThrow( () -> new ResourceNotFoundException(Status.NOT_FOUND, Translator.toLocale(GepafinConstant.USER_COMPANY_RELATION_NOT_FOUND))); } public void removeCompanyFromList(UserEntity userEntity, Long companyId) { CompanyEntity companyEntity = validateCompany(companyId); UserWithCompanyEntity existingRelation=companyService.getUserWithCompany(userEntity.getId(),companyEntity.getId()); List userApplications = applicationRepository.findByUserWithCompanyIdAndUserIdAndIsDeletedFalse(existingRelation.getId(), userEntity.getId()); List faqs = faqRepository.findByUserWithCompanyIdAndIsDeletedFalse(existingRelation.getId()); List preferredCallEntities= beneficiaryPreferredCallRepository.findByUserIdAndUserWithCompanyIdAndIsDeletedFalse(userEntity.getId(),existingRelation.getId()); UserCompanyDelegationEntity userCompanyDelegationEntity = userCompanyDelegationRepository.findByUserIdAndUserWithCompanyIdAndStatus(userEntity.getId(),existingRelation.getId(), UserCompanyDelegationStatusEnum.ACTIVE.getValue()); List applicationStatusAllowed = List.of( ApplicationStatusTypeEnum.DRAFT.getValue(), ApplicationStatusTypeEnum.AWAITING.getValue(), ApplicationStatusTypeEnum.READY.getValue() ); boolean notAllowedStatus = userApplications.stream() .anyMatch(application -> !applicationStatusAllowed.contains(application.getStatus())); if (notAllowedStatus) { throw new CustomValidationException(Status.BAD_REQUEST, Translator.toLocale(GepafinConstant.CANNOT_DELETE_COMPANY_WITH_APPLICATION_SUBMITT)); } userApplications = userApplications.stream() .peek(application -> { ApplicationEntity oldApplication = Utils.getClonedEntityForData(application); application.setIsDeleted(Boolean.TRUE); /** This code is responsible for adding a version history log for the "Soft delete Faq" operation. **/ loggingUtil.addVersionHistory( VersionHistoryRequest.builder() .request(request) .actionType(VersionActionTypeEnum.SOFT_DELETE) .oldData(oldApplication) .newData(application) .build() ); }) .toList(); applicationRepository.saveAll(userApplications); faqs = faqs.stream() .peek(faq -> { FaqEntity oldFaq = Utils.getClonedEntityForData(faq); faq.setIsDeleted(Boolean.TRUE); /** This code is responsible for adding a version history log for the "Soft delete Faq" operation. **/ loggingUtil.addVersionHistory( VersionHistoryRequest.builder() .request(request) .actionType(VersionActionTypeEnum.SOFT_DELETE) .oldData(oldFaq) .newData(faq) .build() ); }) .toList(); faqRepository.saveAll(faqs); preferredCallEntities = preferredCallEntities.stream() .peek(beneficiaryPreferredCall -> { BeneficiaryPreferredCallEntity oldPreferredCall = Utils.getClonedEntityForData(beneficiaryPreferredCall); beneficiaryPreferredCall.setIsDeleted(Boolean.TRUE); /** This code is responsible for adding a version history log for the "Soft Delete BeneficiaryPreferredCall" operation. **/ loggingUtil.addVersionHistory( VersionHistoryRequest.builder() .request(request) .actionType(VersionActionTypeEnum.SOFT_DELETE) .oldData(oldPreferredCall) .newData(beneficiaryPreferredCall) .build() ); }) .toList(); beneficiaryPreferredCallRepository.saveAll(preferredCallEntities); if(userCompanyDelegationEntity!=null){ UserCompanyDelegationEntity oldUserWithCompanyDelegation = Utils.getClonedEntityForData(userCompanyDelegationEntity); userCompanyDelegationEntity.setStatus( UserCompanyDelegationStatusEnum.INACTIVE.getValue()); userCompanyDelegationRepository.save(userCompanyDelegationEntity); /** This code is responsible for adding a version history log for the "Update UserWithCompanyDelegation" operation. **/ loggingUtil.addVersionHistory( VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.UPDATE).oldData(oldUserWithCompanyDelegation).newData(userCompanyDelegationEntity).build()); } UserWithCompanyEntity oldUserWithCompanyData = Utils.getClonedEntityForData(existingRelation); existingRelation.setIsDeleted(Boolean.TRUE); userWithCompanyRepository.save(existingRelation); /** This code is responsible for adding a version history log for the "soft deleting existing user relation" operation. **/ loggingUtil.addVersionHistory( VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.SOFT_DELETE).oldData(oldUserWithCompanyData).newData(existingRelation).build()); } }