package net.gepafin.tendermanagement.dao; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.util.HashMap; import java.util.Map; import java.util.function.Function; import net.gepafin.tendermanagement.entities.*; import net.gepafin.tendermanagement.enums.DocOtherSourceTypeEnum; import net.gepafin.tendermanagement.repositories.ApplicationEvaluationRepository; import net.gepafin.tendermanagement.repositories.UserWithCompanyRepository; import net.gepafin.tendermanagement.service.ApplicationService; import net.gepafin.tendermanagement.service.CompanyService; import net.gepafin.tendermanagement.enums.VersionActionTypeEnum; import net.gepafin.tendermanagement.model.request.VersionHistoryRequest; import net.gepafin.tendermanagement.util.LoggingUtil; import org.apache.commons.lang3.StringUtils; import org.apache.poi.xwpf.usermodel.XWPFDocument; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import org.springframework.web.multipart.MultipartFile; import jakarta.servlet.http.HttpServletRequest; import net.gepafin.tendermanagement.config.Translator; import net.gepafin.tendermanagement.constants.GepafinConstant; import net.gepafin.tendermanagement.enums.UserCompanyDelegationStatusEnum; import net.gepafin.tendermanagement.model.request.CompanyDelegationRequest; import net.gepafin.tendermanagement.model.response.CompanyDelegationResponse; import net.gepafin.tendermanagement.model.response.UploadFileOnAmazonS3Response; import net.gepafin.tendermanagement.model.response.UserResponseBean; import net.gepafin.tendermanagement.repositories.DocumentRepository; import net.gepafin.tendermanagement.repositories.UserCompanyDelegationRepository; import net.gepafin.tendermanagement.service.AmazonS3Service; import net.gepafin.tendermanagement.service.UserService; import net.gepafin.tendermanagement.util.DateTimeUtil; import net.gepafin.tendermanagement.util.Utils; import net.gepafin.tendermanagement.util.Validator; import net.gepafin.tendermanagement.web.rest.api.errors.CustomValidationException; import net.gepafin.tendermanagement.web.rest.api.errors.ResourceNotFoundException; import net.gepafin.tendermanagement.web.rest.api.errors.Status; @Component public class DelegationDao { // private static final String DEFAULT_PLACEHOLDER = "____________________"; @Autowired private UserService userService; @Autowired private CompanyDao companyDao; @Autowired private AmazonS3Service amazonS3Service; @Autowired private DocumentRepository documentRepository; @Autowired private S3PathConfig s3ConfigBean; // @Value("${aws.s3.url.folder.delegation}") // private String s3Folder; @Autowired private UserCompanyDelegationRepository userCompanyDelegationRepository; @Autowired private Validator validator; @Autowired private UserWithCompanyRepository userWithCompanyRepository; @Autowired private CompanyService companyService; @Autowired private LoggingUtil loggingUtil; @Autowired private HttpServletRequest request; @Autowired private ApplicationService applicationService; @Autowired private ApplicationEvaluationRepository applicationEvaluationRepository; public ByteArrayOutputStream generateDocument(Map placeholders, String templateName) { try { String s3Folder = s3ConfigBean.generateDocumentPathForOther(DocOtherSourceTypeEnum.TEMPLATE, 0L, 0L,0L); InputStream templateStream = amazonS3Service.getFile(s3Folder ,templateName); XWPFDocument doc = loadTemplate(templateStream); replacePlaceholders(doc, placeholders); ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); doc.write(byteArrayOutputStream); return byteArrayOutputStream; } catch (Exception e) { throw new CustomValidationException(Status.VALIDATION_ERROR, Translator.toLocale(GepafinConstant.DELEGATION_TEMPLATE_GENERATION_ERROR)); } } public void replacePlaceholders(XWPFDocument doc, Map placeholders) { doc.getParagraphs().forEach(paragraph -> { placeholders.forEach((placeholder, value) -> { if (paragraph.getText().contains(placeholder)) { String updatedText = paragraph.getText().replace(placeholder, value); paragraph.getRuns().forEach(run -> run.setText("", 0)); // Clear the existing text paragraph.createRun().setText(updatedText); // Insert updated text } }); }); } public XWPFDocument loadTemplate(InputStream templateStream) throws IOException { return new XWPFDocument(templateStream); } public ByteArrayOutputStream downloadCompanyDelegation(HttpServletRequest request, Long companyId, CompanyDelegationRequest companyDelegationRequest) { Map placeholders = getDefaultPlaceholders(); UserEntity userEntity = validator.validateUser(request); UserResponseBean user = userService.getUserById(request, userEntity.getId()); CompanyEntity companyEntity = companyDao.validateCompany(companyId); companyDao.getUserWithCompany(userEntity.getId(), companyId); updatePlaceholdersForDelegation(user, companyEntity, placeholders, companyDelegationRequest); DocumentEntity documentEntity = documentRepository.findBySource(GepafinConstant.DELEGATION_TEMPLATE).get(0); return generateDocument(placeholders, documentEntity.getFilePath()); } private Map updatePlaceholdersForDelegation(UserResponseBean user, CompanyEntity companyEntity, Map placeholders, CompanyDelegationRequest companyDelegationRequest) { validateMandatoryFields(companyDelegationRequest); addIfNotEmpty(placeholders, "{{company_first_name}}", companyDelegationRequest.getFirstName()); addIfNotEmpty(placeholders, "{{company_last_name}}", companyDelegationRequest.getLastName()); addIfNotEmpty(placeholders, "{{company_codice_fiscale}}", companyDelegationRequest.getCodiceFiscale()); addIfNotEmpty(placeholders, "{{company_name}}", companyEntity.getCompanyName()); addIfNotEmpty(placeholders, "{{company_city}}", companyEntity.getCity()); addIfNotEmpty(placeholders, "{{company_address}}", companyEntity.getAddress()); addIfNotEmpty(placeholders, "{{company_province}}", companyEntity.getProvince()); addIfNotEmpty(placeholders, "{{company_cap}}", companyEntity.getCap()); addIfNotEmpty(placeholders, "{{company_vat_number}}", companyEntity.getVatNumber()); addIfNotEmpty(placeholders, "{{user_first_name}}", user.getFirstName()); addIfNotEmpty(placeholders, "{{user_last_name}}", user.getLastName()); addIfNotNull(placeholders, "{{user_date_of_birth}}", user.getDateOfBirth(), date -> DateTimeUtil.formatLocalDateTime(date, GepafinConstant.YYYY_MM_DD_SLASH)); addIfNotEmpty(placeholders, "{{user_codice_fiscale}}", user.getCodiceFiscale()); return placeholders; } private Map getDefaultPlaceholders() { Map placeholders = new HashMap<>(); placeholders.put("{{company_first_name}}", ""); placeholders.put("{{company_last_name}}", ""); placeholders.put("{{company_codice_fiscale}}", ""); placeholders.put("{{company_name}}", ""); placeholders.put("{{company_city}}", ""); placeholders.put("{{company_address}}", ""); placeholders.put("{{company_province}}", ""); placeholders.put("{{company_cap}}", ""); placeholders.put("{{company_vat_number}}", ""); placeholders.put("{{user_first_name}}", ""); placeholders.put("{{user_last_name}}", ""); placeholders.put("{{user_date_of_birth}}", ""); placeholders.put("{{user_codice_fiscale}}", ""); return placeholders; } private void validateMandatoryFields(CompanyDelegationRequest companyDelegationRequest) { if (StringUtils.isAllEmpty(companyDelegationRequest.getFirstName())) { throw new CustomValidationException(Status.VALIDATION_ERROR, Translator.toLocale(GepafinConstant.VALIDATION_ERROR_MISSING_FIRSTNAME)); } if (StringUtils.isAllEmpty(companyDelegationRequest.getLastName())) { throw new CustomValidationException(Status.VALIDATION_ERROR, Translator.toLocale(GepafinConstant.VALIDATION_ERROR_MISSING_LASTNAME)); } if (StringUtils.isAllEmpty(companyDelegationRequest.getCodiceFiscale())) { throw new CustomValidationException(Status.VALIDATION_ERROR, Translator.toLocale(GepafinConstant.VALIDATION_ERROR_MISSING_CODICEFISCALE)); } } private void addIfNotEmpty(Map placeholders, String key, String value) { if (Boolean.FALSE.equals(StringUtils.isAllEmpty(value))) { placeholders.put(key, value); } } private void addIfNotNull(Map placeholders, String key, T value, Function formatter) { if (value != null) { placeholders.put(key, formatter.apply(value)); } } public CompanyDelegationResponse uploadCompanyDelegation(UserEntity userEntity, Long companyId, MultipartFile file) { companyDao.validateCompany(companyId); companyDao.getUserWithCompany(userEntity.getId(), companyId); validateFileType(file); UserWithCompanyEntity userWithCompanyEntity=companyService.getUserWithCompany(userEntity.getId(),companyId); UserCompanyDelegationEntity userCompanyDelegationEntity = userCompanyDelegationRepository .findByUserIdAndUserWithCompanyIdAndStatus(userEntity.getId(), userWithCompanyEntity.getId(), UserCompanyDelegationStatusEnum.ACTIVE.getValue()); if (userCompanyDelegationEntity != null) { deleteDelegationFromS3(userCompanyDelegationEntity); } UploadFileOnAmazonS3Response uploadFileOnAmazonS3Response = uploadFileOnAmazonS3ForCompanyDelegation(file); userCompanyDelegationEntity = new UserCompanyDelegationEntity(); userCompanyDelegationEntity.setUserWithCompany(userWithCompanyEntity); userCompanyDelegationEntity.setCompanyId(userWithCompanyEntity.getCompanyId()); userCompanyDelegationEntity.setUserId(userEntity.getId()); if (userEntity.getBeneficiary() != null) { userCompanyDelegationEntity.setBeneficiaryId(userEntity.getBeneficiary().getId()); } userCompanyDelegationEntity.setStatus(UserCompanyDelegationStatusEnum.ACTIVE.getValue()); userCompanyDelegationEntity.setFileName(uploadFileOnAmazonS3Response.getFileName()); userCompanyDelegationEntity.setFilePath(uploadFileOnAmazonS3Response.getFilePath()); userCompanyDelegationRepository.save(userCompanyDelegationEntity); /** This code is responsible for adding a version history log for the "Insert or upload user company delegation" operation. **/ loggingUtil.addVersionHistory(VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.INSERT).oldData(null) .newData(userCompanyDelegationEntity).build()); return convertUserCompanyDelegationToCompanyDelegationResponse(userCompanyDelegationEntity); } private UploadFileOnAmazonS3Response uploadFileOnAmazonS3ForCompanyDelegation(MultipartFile file) { try { String s3Path = generateS3PathForDelegation(); return amazonS3Service.uploadFileOnAmazonS3(s3Path, file); } catch (Exception e) { throw new CustomValidationException(Status.VALIDATION_ERROR, Translator.toLocale(GepafinConstant.UPLOAD_ERROR_S3)); } } private String generateS3PathForDelegation() { try { return s3ConfigBean.generateDocumentPathForDelegationAndSignedDocument(DocOtherSourceTypeEnum.USER_DELEGATION); } catch (IllegalArgumentException e) { throw new CustomValidationException(Status.VALIDATION_ERROR, Translator.toLocale(GepafinConstant.S3_PATH_GENERATION_ERROR_MSG)); } } private CompanyDelegationResponse convertUserCompanyDelegationToCompanyDelegationResponse( UserCompanyDelegationEntity userCompanyDelegationEntity) { return Utils.convertSourceObjectToDestinationObject(userCompanyDelegationEntity, CompanyDelegationResponse.class); } private void validateFileType(MultipartFile file) { if (file.isEmpty()) { throw new CustomValidationException(Status.VALIDATION_ERROR, Translator.toLocale(GepafinConstant.VALIDATION_ERROR_FILE_EMPTY)); } String filename = file.getOriginalFilename(); if (filename == null || !filename.endsWith(".p7m")) { throw new CustomValidationException(Status.VALIDATION_ERROR, Translator.toLocale(GepafinConstant.VALIDATION_ERROR_FILE_INVALIDTYPE)); } } public CompanyDelegationResponse getCompanyDelegation(HttpServletRequest request, Long companyId, Long applicationId) { if(companyId==null && applicationId==null){ throw new CustomValidationException(Status.BAD_REQUEST,Translator.toLocale(GepafinConstant.ATLEAST_ONE_ID_REQUIRED)); } if(validator.checkIsPreInstructor()) { ApplicationEvaluationEntity applicationEvaluationEntity = applicationEvaluationRepository.findByApplicationIdAndIsDeletedFalse(applicationId).orElseThrow(()-> throw new ResourceNotFoundException(Status.NOT_FOUND, Translator.toLocale(GepafinConstant.APPLICATION_EVALUATION_NOT_FOUND, companyId)); validator.validateUserWithCompany(); } else { validator.validateUserWithCompany(); } Long userId=userEntity.getId(); if(applicationId != null) { ApplicationEntity application = applicationService.validateApplication(applicationId); userId=application.getUserId(); companyId=application.getCompanyId(); } UserWithCompanyEntity userWithCompanyEntity=companyService.getUserWithCompany(userId,companyId); UserCompanyDelegationEntity userCompanyDelegationEntity = userCompanyDelegationRepository .findByUserIdAndUserWithCompanyIdAndStatus(userId, userWithCompanyEntity.getId(), UserCompanyDelegationStatusEnum.ACTIVE.getValue()); companyDao.getUserWithCompany(userEntity.getId(), companyId); if(userCompanyDelegationEntity == null) { throw new ResourceNotFoundException(Status.NOT_FOUND, Translator.toLocale(GepafinConstant.DELEGATION_NOT_FOUND)); } return convertUserCompanyDelegationToCompanyDelegationResponse(userCompanyDelegationEntity); } public void deleteCompanyDelegation(UserEntity userEntity, Long companyId) { UserWithCompanyEntity userWithCompanyEntity=companyService.getUserWithCompany(userEntity.getId(),companyId); UserCompanyDelegationEntity userCompanyDelegationEntity = userCompanyDelegationRepository .findByUserIdAndUserWithCompanyIdAndStatus(userEntity.getId(), userWithCompanyEntity.getId(), UserCompanyDelegationStatusEnum.ACTIVE.getValue()); companyDao.getUserWithCompany(userEntity.getId(), companyId); if (userCompanyDelegationEntity == null) { throw new ResourceNotFoundException(Status.NOT_FOUND, Translator.toLocale(GepafinConstant.DELEGATION_NOT_FOUND)); } deleteDelegationFromS3(userCompanyDelegationEntity); } public void deleteDelegationFromS3(UserCompanyDelegationEntity userCompanyDelegationEntity) { UserCompanyDelegationEntity oldUserCompanyDelegation = Utils.getClonedEntityForData(userCompanyDelegationEntity); String oldS3Path = userCompanyDelegationEntity.getFilePath(); String newS3Path = s3ConfigBean.generateDocumentPathForDelegationAndSignedDocument(DocOtherSourceTypeEnum.DELETED_USER_DELEGATION); UploadFileOnAmazonS3Response response = amazonS3Service.moveFile(userCompanyDelegationEntity.getFileName(), oldS3Path, newS3Path); userCompanyDelegationEntity.setFileName(response.getFileName()); userCompanyDelegationEntity.setFilePath(response.getFilePath()); userCompanyDelegationEntity.setStatus(UserCompanyDelegationStatusEnum.INACTIVE.getValue()); userCompanyDelegationRepository.save(userCompanyDelegationEntity); /** This code is responsible for adding a version history log for the "Soft Deleting company delegation " operation. **/ loggingUtil.addVersionHistory( VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.SOFT_DELETE).oldData(oldUserCompanyDelegation).newData(userCompanyDelegationEntity) .build()); } }