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 org.apache.commons.io.FilenameUtils; import org.apache.commons.lang3.StringUtils; import org.apache.poi.xwpf.usermodel.XWPFDocument; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; import org.springframework.web.multipart.MultipartFile; import net.gepafin.tendermanagement.config.Translator; import net.gepafin.tendermanagement.constants.GepafinConstant; import net.gepafin.tendermanagement.entities.CompanyEntity; import net.gepafin.tendermanagement.entities.DocumentEntity; import net.gepafin.tendermanagement.entities.UserCompanyDelegationEntity; import net.gepafin.tendermanagement.entities.UserEntity; 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.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.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; @Value("${aws.s3.url.folder.delegation}") private String s3Folder; @Autowired private UserCompanyDelegationRepository userCompanyDelegationRepository; public ByteArrayOutputStream generateDocument(Map placeholders, String templateName) { try { 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(UserEntity userEntity, Long companyId, CompanyDelegationRequest companyDelegationRequest) { Map placeholders = getDefaultPlaceholders(); UserResponseBean user = userService.getUserById(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.getFileName()); } 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}}", DEFAULT_PLACEHOLDER); placeholders.put("{{company_address}}", DEFAULT_PLACEHOLDER); placeholders.put("{{company_province}}", DEFAULT_PLACEHOLDER); placeholders.put("{{company_cap}}", DEFAULT_PLACEHOLDER); placeholders.put("{{company_vat_number}}", ""); placeholders.put("{{user_first_name}}", ""); placeholders.put("{{user_last_name}}", ""); placeholders.put("{{user_date_of_birth}}", DEFAULT_PLACEHOLDER); 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); UserCompanyDelegationEntity userCompanyDelegationEntity = userCompanyDelegationRepository .findByUserIdAndCompanyIdAndStatus(userEntity.getId(), companyId, UserCompanyDelegationStatusEnum.ACTIVE.getValue()); if (userCompanyDelegationEntity != null) { userCompanyDelegationEntity.setStatus(UserCompanyDelegationStatusEnum.INACTIVE.getValue()); userCompanyDelegationRepository.save(userCompanyDelegationEntity); } UploadFileOnAmazonS3 uploadFileOnAmazonS3 = uploadFileOnAmazonS3(file); userCompanyDelegationEntity = new UserCompanyDelegationEntity(); userCompanyDelegationEntity.setCompanyId(companyId); userCompanyDelegationEntity.setUserId(userEntity.getId()); if (userEntity.getBeneficiary() != null) { userCompanyDelegationEntity.setBeneficiaryId(userEntity.getBeneficiary().getId()); } userCompanyDelegationEntity.setStatus(UserCompanyDelegationStatusEnum.ACTIVE.getValue()); userCompanyDelegationEntity.setFileName(uploadFileOnAmazonS3.fileName()); userCompanyDelegationEntity.setFilePath(uploadFileOnAmazonS3.filepath()); userCompanyDelegationRepository.save(userCompanyDelegationEntity); return convertUserCompanyDelegationToCompanyDelegationResponse(userCompanyDelegationEntity); } private CompanyDelegationResponse convertUserCompanyDelegationToCompanyDelegationResponse( UserCompanyDelegationEntity userCompanyDelegationEntity) { return Utils.convertSourceObjectToDestinationObject(userCompanyDelegationEntity, CompanyDelegationResponse.class); } private UploadFileOnAmazonS3 uploadFileOnAmazonS3(MultipartFile file){ String extension = FilenameUtils.getExtension(file.getOriginalFilename()); String fileName = org.springframework.util.StringUtils.cleanPath(file.getOriginalFilename()); String firstNameContain = fileName.substring(0, fileName.lastIndexOf('.')); firstNameContain+=Utils.randomKey(5); fileName = (firstNameContain + "." + extension); try { String filepath = amazonS3Service.upload(fileName, s3Folder, file); return new UploadFileOnAmazonS3(fileName, filepath); } catch (Exception e) { throw new CustomValidationException(Status.VALIDATION_ERROR, Translator.toLocale(GepafinConstant.UPLOAD_ERROR_S3)); } } private record UploadFileOnAmazonS3(String fileName, String filepath) { } 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(UserEntity userEntity, Long companyId) { UserCompanyDelegationEntity userCompanyDelegationEntity = userCompanyDelegationRepository .findByUserIdAndCompanyIdAndStatus(userEntity.getId(), companyId, 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) { UserCompanyDelegationEntity userCompanyDelegationEntity = userCompanyDelegationRepository .findByUserIdAndCompanyIdAndStatus(userEntity.getId(), companyId, UserCompanyDelegationStatusEnum.ACTIVE.getValue()); companyDao.getUserWithCompany(userEntity.getId(), companyId); if(userCompanyDelegationEntity == null) { throw new ResourceNotFoundException(Status.NOT_FOUND, Translator.toLocale(GepafinConstant.DELEGATION_NOT_FOUND)); } userCompanyDelegationEntity.setStatus(UserCompanyDelegationStatusEnum.INACTIVE.getValue()); userCompanyDelegationRepository.save(userCompanyDelegationEntity); } }