diff --git a/pom.xml b/pom.xml index a2a1e712..b0a632d8 100644 --- a/pom.xml +++ b/pom.xml @@ -94,7 +94,7 @@ commons-io commons-io - 2.11.0 + 2.17.0 @@ -173,6 +173,12 @@ 4.1.3 + + org.apache.poi + poi-ooxml + 5.3.0 + + org.apache.santuario xmlsec diff --git a/src/main/java/net/gepafin/tendermanagement/constants/GepafinConstant.java b/src/main/java/net/gepafin/tendermanagement/constants/GepafinConstant.java index 1a2bd78c..3375765a 100644 --- a/src/main/java/net/gepafin/tendermanagement/constants/GepafinConstant.java +++ b/src/main/java/net/gepafin/tendermanagement/constants/GepafinConstant.java @@ -179,6 +179,18 @@ public class GepafinConstant { public static final String UNAUTHORIZED = "UNAUTHORIZED"; public static final String COMPANY_ID_MANDATORY = "company.id.mandatory"; public static final String USER_ALREADY_CONNECTED_TO_COMPANY = "user.already.connected.to.company"; + public static final String YYYY_MM_DD_DASH = "yyyy-MM-dd"; + public static final String YYYY_MM_DD_SLASH = "yyyy/MM/dd"; + public static final String DELEGATION_TEMPLATE = "DELEGATION_TEMPLATE"; + public static final String VALIDATION_ERROR_MISSING_FIRSTNAME = "validation.error.missing.firstName"; + public static final String VALIDATION_ERROR_MISSING_LASTNAME = "validation.error.missing.lastName"; + public static final String VALIDATION_ERROR_MISSING_CODICEFISCALE = "validation.error.missing.codiceFiscale"; + public static final String DELEGATION_FILE_UPLOAD_SUCCESS = "delegation.file.upload.success"; + public static final String DELEGATION_FETCH_SUCCESS = "delegation.fetch.success"; + public static final String DELEGATION_TEMPLATE_GENERATION_ERROR = "delegation.template.generation.error"; + 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"; diff --git a/src/main/java/net/gepafin/tendermanagement/dao/CompanyDao.java b/src/main/java/net/gepafin/tendermanagement/dao/CompanyDao.java index ceec5a8c..2e148665 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/CompanyDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/CompanyDao.java @@ -35,24 +35,26 @@ public class CompanyDao { @Autowired private UserWithCompanyRepository userWithCompanyRepository; + public CompanyResponse createCompany(UserEntity userEntity, CompanyRequest companyRequest) { CompanyEntity existingCompany = companyRepository.findByVatNumber(companyRequest.getVatNumber()); + UserWithCompanyEntity userWithCompanyEntity = null; if (existingCompany != null) { UserWithCompanyEntity existingRelation = userWithCompanyRepository.findByUserIdAndCompanyId(userEntity.getId(), existingCompany.getId()) .orElse(null); if (existingRelation == null) { - createUserWithCompanyRelation(userEntity, existingCompany); + userWithCompanyEntity = createUserWithCompanyRelation(userEntity, existingCompany, companyRequest.getIsLegalRepresentant()); } else { throw new CustomValidationException(Status.VALIDATION_ERROR, Translator.toLocale(GepafinConstant.USER_ALREADY_CONNECTED_TO_COMPANY)); } - return convertCompanyEntityToCompanyResponse(existingCompany); + return convertCompanyEntityToCompanyResponse(existingCompany, userWithCompanyEntity); } else { validateCompany(companyRequest); CompanyEntity companyEntity = convertCompanyRequestToCompanyEntity(companyRequest); companyRepository.save(companyEntity); - createUserWithCompanyRelation(userEntity, companyEntity); - return convertCompanyEntityToCompanyResponse(companyEntity); + userWithCompanyEntity = createUserWithCompanyRelation(userEntity, companyEntity, companyRequest.getIsLegalRepresentant()); + return convertCompanyEntityToCompanyResponse(companyEntity, userWithCompanyEntity); } } @@ -74,13 +76,14 @@ public class CompanyDao { } } - private UserWithCompanyEntity createUserWithCompanyRelation(UserEntity userEntity, CompanyEntity companyEntity) { + private UserWithCompanyEntity createUserWithCompanyRelation(UserEntity userEntity, CompanyEntity companyEntity, Boolean isLegalRepresentant) { UserWithCompanyEntity userWithCompanyEntity = new UserWithCompanyEntity(); if (userEntity.getBeneficiary() != null) { userWithCompanyEntity.setBeneficiaryId(userEntity.getBeneficiary().getId()); } userWithCompanyEntity.setCompanyId(companyEntity.getId()); userWithCompanyEntity.setUserId(userEntity.getId()); + userWithCompanyEntity.setIsLegalRepresentant(isLegalRepresentant); return userWithCompanyRepository.save(userWithCompanyEntity); } @@ -104,7 +107,7 @@ public class CompanyDao { return entity; } - private CompanyResponse convertCompanyEntityToCompanyResponse(CompanyEntity entity) { + private CompanyResponse convertCompanyEntityToCompanyResponse(CompanyEntity entity, UserWithCompanyEntity userWithCompanyEntity) { CompanyResponse response = new CompanyResponse(); response.setId(entity.getId()); response.setCompanyName(entity.getCompanyName()); @@ -120,6 +123,9 @@ public class CompanyDao { response.setEmail(entity.getEmail()); response.setNumberOfEmployees(entity.getNumberOfEmployees()); response.setAnnualRevenue(entity.getAnnualRevenue()); + if(userWithCompanyEntity!=null) { + response.setIsLegalRepresentant(userWithCompanyEntity.getIsLegalRepresentant()); + } response.setCreatedDate(entity.getCreatedDate()); response.setUpdatedDate(entity.getUpdatedDate()); response.setContactName(entity.getContactName()); @@ -150,7 +156,11 @@ public class CompanyDao { setIfUpdated(companyEntity::getContactName,companyEntity::setContactName,companyRequest.getContactName()); setIfUpdated(companyEntity::getContactEmail,companyEntity::setContactEmail,companyRequest.getContactEmail()); companyRepository.save(companyEntity); - return convertCompanyEntityToCompanyResponse(companyEntity); + UserWithCompanyEntity userWithCompanyEntity = userWithCompanyRepository.findByUserIdAndCompanyId(userEntity.getId(), companyId).orElse(null); + Utils.setIfUpdated(userWithCompanyEntity::getIsLegalRepresentant, userWithCompanyEntity::setIsLegalRepresentant, + companyRequest.getIsLegalRepresentant()); + userWithCompanyRepository.save(userWithCompanyEntity); + return convertCompanyEntityToCompanyResponse(companyEntity, userWithCompanyEntity); } public CompanyEntity validateCompany(Long companyId) { @@ -159,7 +169,8 @@ public class CompanyDao { } public CompanyResponse getCompany(UserEntity userEntity, Long companyId) { - return convertCompanyEntityToCompanyResponse(validateCompany(companyId)); + UserWithCompanyEntity userWithCompanyEntity = userWithCompanyRepository.findByUserIdAndCompanyId(userEntity.getId(), companyId).orElse(null); + return convertCompanyEntityToCompanyResponse(validateCompany(companyId), userWithCompanyEntity); } public void deleteCompany(UserEntity userEntity, Long companyId) { @@ -172,7 +183,10 @@ public class CompanyDao { UserEntity userEntity = userService.validateUser(userId); List companyIds = userWithCompanyRepository.findCompanyIdByUserId(userEntity.getId()); List list = companyRepository.findByIdIn(companyIds); - return list.stream().map(this::convertCompanyEntityToCompanyResponse).toList(); + return list.stream().map(companyEntity->{ + UserWithCompanyEntity userWithCompanyEntity = userWithCompanyRepository.findByUserIdAndCompanyId(userEntity.getId(), companyEntity.getId()).orElse(null); + return convertCompanyEntityToCompanyResponse(companyEntity, userWithCompanyEntity); + }).toList(); } public UserWithCompanyEntity validateUserWithCompny(Long userId, Long companyId) { diff --git a/src/main/java/net/gepafin/tendermanagement/dao/DelegationDao.java b/src/main/java/net/gepafin/tendermanagement/dao/DelegationDao.java new file mode 100644 index 00000000..4d4f2c03 --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/dao/DelegationDao.java @@ -0,0 +1,240 @@ +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); + 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); + 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()); + if(userCompanyDelegationEntity == null) { + throw new ResourceNotFoundException(Status.NOT_FOUND, + Translator.toLocale("validation.error.file.invalidType")); + } + return convertUserCompanyDelegationToCompanyDelegationResponse(userCompanyDelegationEntity); + } +} diff --git a/src/main/java/net/gepafin/tendermanagement/dao/DocumentDao.java b/src/main/java/net/gepafin/tendermanagement/dao/DocumentDao.java index 374c741b..224a21ec 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/DocumentDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/DocumentDao.java @@ -6,6 +6,7 @@ import java.util.stream.Collectors; import net.gepafin.tendermanagement.enums.DocumentSourceTypeEnum; import org.apache.commons.io.FilenameUtils; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; import org.springframework.util.StringUtils; import org.springframework.web.multipart.MultipartFile; @@ -40,6 +41,9 @@ public class DocumentDao { @Autowired private CallService callService; + + @Value("${aws.s3.url.folder}") + private String s3Folder; public List uploadFiles(List files, Long sourceId, DocumentSourceTypeEnum sourceType, DocumentTypeEnum fileType) { List documentEntities = new ArrayList<>(); @@ -81,7 +85,7 @@ public class DocumentDao { String fileName = StringUtils.cleanPath(file.getOriginalFilename()); String firstNameContain = fileName.substring(0, fileName.lastIndexOf('.')); fileName = (firstNameContain + "." + extension); - String filepath = amazonS3Service.upload(fileName, file); + String filepath = amazonS3Service.upload(fileName, s3Folder, file); uploadFileOnAmazonS3 result = new uploadFileOnAmazonS3(fileName, filepath); return result; } @@ -99,7 +103,7 @@ public class DocumentDao { private DocumentEntity deleteFileOnAmazonS3(String fileName) { try { - amazonS3Service.delete(fileName); + amazonS3Service.delete(s3Folder, fileName); } catch (Exception e) { } return null; diff --git a/src/main/java/net/gepafin/tendermanagement/entities/UserCompanyDelegationEntity.java b/src/main/java/net/gepafin/tendermanagement/entities/UserCompanyDelegationEntity.java new file mode 100644 index 00000000..d682747d --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/entities/UserCompanyDelegationEntity.java @@ -0,0 +1,31 @@ +package net.gepafin.tendermanagement.entities; + +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.Table; +import lombok.Data; + +@Data +@Entity +@Table(name = "user_company_delegation") +public class UserCompanyDelegationEntity extends BaseEntity{ + + @Column(name="USER_ID") + private Long userId; + + @Column(name="COMPANY_ID") + private Long companyId; + + @Column(name = "BENEFICIARY_ID") + private Long beneficiaryId; + + @Column(name = "FILE_NAME") + private String fileName; + + @Column(name = "FILE_PATH") + private String filePath; + + @Column(name="STATUS") + private String status; + +} diff --git a/src/main/java/net/gepafin/tendermanagement/entities/UserWithCompanyEntity.java b/src/main/java/net/gepafin/tendermanagement/entities/UserWithCompanyEntity.java index fce47e66..f2d175e2 100644 --- a/src/main/java/net/gepafin/tendermanagement/entities/UserWithCompanyEntity.java +++ b/src/main/java/net/gepafin/tendermanagement/entities/UserWithCompanyEntity.java @@ -18,5 +18,8 @@ public class UserWithCompanyEntity extends BaseEntity{ @Column(name = "COMPANY_ID") Long companyId; + + @Column(name = "IS_LEGAL_REPRESENTANT") + private Boolean isLegalRepresentant; } diff --git a/src/main/java/net/gepafin/tendermanagement/enums/UserCompanyDelegationStatusEnum.java b/src/main/java/net/gepafin/tendermanagement/enums/UserCompanyDelegationStatusEnum.java new file mode 100644 index 00000000..1f8f9725 --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/enums/UserCompanyDelegationStatusEnum.java @@ -0,0 +1,18 @@ +package net.gepafin.tendermanagement.enums; + +import com.fasterxml.jackson.annotation.JsonValue; + +public enum UserCompanyDelegationStatusEnum { + ACTIVE("ACTIVE"), INACTIVE("INACTIVE"); + + private String value; + + UserCompanyDelegationStatusEnum(String value) { + this.value = value; + } + + @JsonValue + public String getValue() { + return value; + } +} diff --git a/src/main/java/net/gepafin/tendermanagement/model/request/CompanyDelegationRequest.java b/src/main/java/net/gepafin/tendermanagement/model/request/CompanyDelegationRequest.java new file mode 100644 index 00000000..b47ed579 --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/model/request/CompanyDelegationRequest.java @@ -0,0 +1,13 @@ +package net.gepafin.tendermanagement.model.request; + +import lombok.Data; + +@Data +public class CompanyDelegationRequest { + + private String firstName; + + private String lastName; + + private String codiceFiscale; +} 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 cc90380b..b9f43932 100644 --- a/src/main/java/net/gepafin/tendermanagement/model/request/CompanyRequest.java +++ b/src/main/java/net/gepafin/tendermanagement/model/request/CompanyRequest.java @@ -20,6 +20,7 @@ public class CompanyRequest { private String email; 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/CompanyDelegationResponse.java b/src/main/java/net/gepafin/tendermanagement/model/response/CompanyDelegationResponse.java new file mode 100644 index 00000000..7c23b3b8 --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/model/response/CompanyDelegationResponse.java @@ -0,0 +1,15 @@ +package net.gepafin.tendermanagement.model.response; + +import lombok.Data; +import net.gepafin.tendermanagement.entities.BaseEntity; +import net.gepafin.tendermanagement.enums.UserCompanyDelegationStatusEnum; + +@Data +public class CompanyDelegationResponse extends BaseEntity{ + private Long userId; + private Long companyId; + private Long beneficiaryId; + private String fileName; + private String filePath; + private UserCompanyDelegationStatusEnum status; +} 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 3d414414..e54b040f 100644 --- a/src/main/java/net/gepafin/tendermanagement/model/response/CompanyResponse.java +++ b/src/main/java/net/gepafin/tendermanagement/model/response/CompanyResponse.java @@ -21,6 +21,7 @@ public class CompanyResponse extends BaseBean{ private String email; private String numberOfEmployees; private BigDecimal annualRevenue; + private Boolean isLegalRepresentant; private String contactName; private String contactEmail; } diff --git a/src/main/java/net/gepafin/tendermanagement/repositories/DocumentRepository.java b/src/main/java/net/gepafin/tendermanagement/repositories/DocumentRepository.java index 40361cd9..339efd13 100644 --- a/src/main/java/net/gepafin/tendermanagement/repositories/DocumentRepository.java +++ b/src/main/java/net/gepafin/tendermanagement/repositories/DocumentRepository.java @@ -19,5 +19,7 @@ public interface DocumentRepository extends JpaRepository Optional findByIdAndSourceIdAndIsDeletedFalse(Long id, Long sourceId); + List findBySource(String source); + } diff --git a/src/main/java/net/gepafin/tendermanagement/repositories/UserCompanyDelegationRepository.java b/src/main/java/net/gepafin/tendermanagement/repositories/UserCompanyDelegationRepository.java new file mode 100644 index 00000000..1224dd70 --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/repositories/UserCompanyDelegationRepository.java @@ -0,0 +1,10 @@ +package net.gepafin.tendermanagement.repositories; + +import org.springframework.data.jpa.repository.JpaRepository; +import net.gepafin.tendermanagement.entities.UserCompanyDelegationEntity; + +public interface UserCompanyDelegationRepository extends JpaRepository { + + UserCompanyDelegationEntity findByUserIdAndCompanyIdAndStatus(Long userId, Long companyId, String status); + +} diff --git a/src/main/java/net/gepafin/tendermanagement/service/AmazonS3Service.java b/src/main/java/net/gepafin/tendermanagement/service/AmazonS3Service.java index 1ff3a7fd..ce34cd7d 100644 --- a/src/main/java/net/gepafin/tendermanagement/service/AmazonS3Service.java +++ b/src/main/java/net/gepafin/tendermanagement/service/AmazonS3Service.java @@ -9,9 +9,9 @@ import java.io.InputStream; @Component public interface AmazonS3Service { - public String upload(String fileName, MultipartFile file) throws IOException; + public String upload(String fileName, String s3Folder, MultipartFile file) throws IOException; - public Boolean delete(String fileName); + public Boolean delete(String s3Folder, String fileName); - InputStream getFile(String filePath) throws IOException; + InputStream getFile(String s3Folder, String filePath) throws IOException; } \ No newline at end of file diff --git a/src/main/java/net/gepafin/tendermanagement/service/CompanyService.java b/src/main/java/net/gepafin/tendermanagement/service/CompanyService.java index d0d7ce20..8382d37f 100644 --- a/src/main/java/net/gepafin/tendermanagement/service/CompanyService.java +++ b/src/main/java/net/gepafin/tendermanagement/service/CompanyService.java @@ -1,12 +1,17 @@ package net.gepafin.tendermanagement.service; +import java.io.ByteArrayOutputStream; import java.util.List; import java.util.Map; +import org.springframework.web.multipart.MultipartFile; + import jakarta.servlet.http.HttpServletRequest; import net.gepafin.tendermanagement.entities.CompanyEntity; import net.gepafin.tendermanagement.entities.UserWithCompanyEntity; +import net.gepafin.tendermanagement.model.request.CompanyDelegationRequest; import net.gepafin.tendermanagement.model.request.CompanyRequest; +import net.gepafin.tendermanagement.model.response.CompanyDelegationResponse; import net.gepafin.tendermanagement.model.response.CompanyResponse; public interface CompanyService { @@ -27,4 +32,10 @@ public interface CompanyService { UserWithCompanyEntity validateUserWithCompny(Long userId, Long companyId); + ByteArrayOutputStream downloadCompanyDelegation(HttpServletRequest request, Long companyId, CompanyDelegationRequest companyDelegationRequest); + + CompanyDelegationResponse uploadCompanyDelegation(HttpServletRequest request, Long companyId, MultipartFile file); + + CompanyDelegationResponse getCompanyDelegation(HttpServletRequest request, Long companyId); + } diff --git a/src/main/java/net/gepafin/tendermanagement/service/impl/AmazonS3ServiceImpl.java b/src/main/java/net/gepafin/tendermanagement/service/impl/AmazonS3ServiceImpl.java index 3657d115..756e4360 100644 --- a/src/main/java/net/gepafin/tendermanagement/service/impl/AmazonS3ServiceImpl.java +++ b/src/main/java/net/gepafin/tendermanagement/service/impl/AmazonS3ServiceImpl.java @@ -29,18 +29,16 @@ public class AmazonS3ServiceImpl implements AmazonS3Service { @Value("${aws.s3.bucket.name}") private String bucketName; - @Value("${aws.s3.url.folder}") - private String s3Folder; - @Value("${aws.s3.url}") private String s3Url; @Override - public String upload(String fileName, + public String upload(String fileName, String s3Folder, MultipartFile file) throws IOException { - String path = bucketName+"/"+s3Folder; +// String path = bucketName+"/"+s3Folder; + String path = s3Folder +"/"+fileName; InputStream inputStream = file.getInputStream(); @@ -57,15 +55,15 @@ public class AmazonS3ServiceImpl implements AmazonS3Service { }); if(Boolean.FALSE.equals(isTestProfileActivated())) { - amazonS3.putObject(path, fileName, inputStream, objectMetadata); + amazonS3.putObject(bucketName, path, inputStream, objectMetadata); } return s3Url + s3Folder +"/"+ fileName; } @Override - public Boolean delete(String fileName) { - - final DeleteObjectRequest deleteObjectRequest = new DeleteObjectRequest(bucketName, fileName); + public Boolean delete(String s3Folder, String fileName) { + String path = s3Folder +"/"+fileName; + final DeleteObjectRequest deleteObjectRequest = new DeleteObjectRequest(bucketName, path); if(Boolean.FALSE.equals(isTestProfileActivated())) { amazonS3.deleteObject(deleteObjectRequest); } @@ -78,10 +76,10 @@ public class AmazonS3ServiceImpl implements AmazonS3Service { } @Override - public InputStream getFile(String filePath) throws IOException { + public InputStream getFile(String s3Folder, String filePath) throws IOException { try { - String path = bucketName+ s3Folder +"/"; - GetObjectRequest getObjectRequest = new GetObjectRequest(path, filePath); + String path = s3Folder +"/"+filePath; + GetObjectRequest getObjectRequest = new GetObjectRequest(bucketName, path); S3Object s3Object = amazonS3.getObject(getObjectRequest); return s3Object.getObjectContent(); } catch (AmazonS3Exception e) { 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 6dfec87a..d8c4f429 100644 --- a/src/main/java/net/gepafin/tendermanagement/service/impl/CompanyServiceImpl.java +++ b/src/main/java/net/gepafin/tendermanagement/service/impl/CompanyServiceImpl.java @@ -1,19 +1,24 @@ package net.gepafin.tendermanagement.service.impl; +import java.io.ByteArrayOutputStream; import java.util.List; import java.util.Map; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import org.springframework.web.multipart.MultipartFile; import jakarta.servlet.http.HttpServletRequest; import net.gepafin.tendermanagement.dao.CompanyDao; +import net.gepafin.tendermanagement.dao.DelegationDao; import net.gepafin.tendermanagement.dao.VatCheckDao; import net.gepafin.tendermanagement.entities.CompanyEntity; import net.gepafin.tendermanagement.entities.UserEntity; import net.gepafin.tendermanagement.entities.UserWithCompanyEntity; +import net.gepafin.tendermanagement.model.request.CompanyDelegationRequest; import net.gepafin.tendermanagement.model.request.CompanyRequest; +import net.gepafin.tendermanagement.model.response.CompanyDelegationResponse; import net.gepafin.tendermanagement.model.response.CompanyResponse; import net.gepafin.tendermanagement.service.CompanyService; import net.gepafin.tendermanagement.util.Validator; @@ -30,6 +35,9 @@ public class CompanyServiceImpl implements CompanyService { @Autowired private VatCheckDao vatCheckDao; + @Autowired + private DelegationDao delegationDao; + @Override @Transactional(rollbackFor = Exception.class) public CompanyResponse createCompany(HttpServletRequest request, CompanyRequest companyRequest) { @@ -61,7 +69,7 @@ public class CompanyServiceImpl implements CompanyService { @Override @Transactional(readOnly = true) public List getCompanyByUserId(HttpServletRequest request, Long userId) { - UserEntity userEntity = validator.validateUser(request); + validator.validateUser(request); return companyDao.getCompanyByUserId(userId); } @@ -80,4 +88,24 @@ public class CompanyServiceImpl implements CompanyService { return companyDao.validateUserWithCompny(userId, companyId); } + @Override + @Transactional(readOnly = true) + public ByteArrayOutputStream downloadCompanyDelegation(HttpServletRequest request, Long companyId, CompanyDelegationRequest companyDelegationRequest) { + UserEntity userEntity =validator.validateUser(request); + return delegationDao.downloadCompanyDelegation(userEntity, companyId, companyDelegationRequest); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public CompanyDelegationResponse uploadCompanyDelegation(HttpServletRequest request, Long companyId, MultipartFile file) { + UserEntity userEntity =validator.validateUser(request); + return delegationDao.uploadCompanyDelegation(userEntity, companyId, file); + } + + @Override + @Transactional(readOnly = true) + public CompanyDelegationResponse getCompanyDelegation(HttpServletRequest request, Long companyId) { + UserEntity userEntity =validator.validateUser(request); + return delegationDao.getCompanyDelegation(userEntity, companyId); + } } diff --git a/src/main/java/net/gepafin/tendermanagement/util/DateTimeUtil.java b/src/main/java/net/gepafin/tendermanagement/util/DateTimeUtil.java index 63ed91a5..342ca2b2 100644 --- a/src/main/java/net/gepafin/tendermanagement/util/DateTimeUtil.java +++ b/src/main/java/net/gepafin/tendermanagement/util/DateTimeUtil.java @@ -1,13 +1,9 @@ package net.gepafin.tendermanagement.util; -import com.fasterxml.jackson.core.JsonParser; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.DeserializationContext; import net.gepafin.tendermanagement.web.rest.api.errors.CustomValidationException; import net.gepafin.tendermanagement.web.rest.api.errors.Status; import org.springframework.stereotype.Component; -import java.io.IOException; import java.time.LocalDateTime; import java.time.LocalTime; import java.time.ZoneId; @@ -86,4 +82,14 @@ public class DateTimeUtil { // If all parsing attempts fail, throw an exception throw new CustomValidationException(Status.BAD_REQUEST,"Failed to parse time: " + timeString); } + + public static String formatLocalDateTime(LocalDateTime dateTime, String pattern) { + DateTimeFormatter formatter = DateTimeFormatter.ofPattern(pattern); + return dateTime.format(formatter); + } + + public static LocalDateTime parseStringToLocalDateTime(String dateTimeStr, String pattern) { + DateTimeFormatter formatter = DateTimeFormatter.ofPattern(pattern); + return LocalDateTime.parse(dateTimeStr, formatter); + } } diff --git a/src/main/java/net/gepafin/tendermanagement/util/Utils.java b/src/main/java/net/gepafin/tendermanagement/util/Utils.java index 0c76c78c..746c8e8d 100644 --- a/src/main/java/net/gepafin/tendermanagement/util/Utils.java +++ b/src/main/java/net/gepafin/tendermanagement/util/Utils.java @@ -227,6 +227,12 @@ public class Utils { Pattern pattern = Pattern.compile(EMAIL_REGEX); return pattern.matcher(email).matches(); } + + public static String randomKey(Integer range) { + String data = String.valueOf(System.currentTimeMillis()); + return data.substring(data.length() - range); + } + public static String convertObjectToJsonString(Object object) { try { // Check if the object is a string diff --git a/src/main/java/net/gepafin/tendermanagement/util/Validator.java b/src/main/java/net/gepafin/tendermanagement/util/Validator.java index 44ba62af..e123988a 100644 --- a/src/main/java/net/gepafin/tendermanagement/util/Validator.java +++ b/src/main/java/net/gepafin/tendermanagement/util/Validator.java @@ -37,8 +37,7 @@ public class Validator { } public UserEntity validateUser(HttpServletRequest request) { - Map userInfo= tokenProvider.getUserInfoAndUserIdFromToken(request); - return userService.validateUser(Long.parseLong(userInfo.get("userId").toString())); + return userService.validateUser(getUserIdFromToken(request)); } public Boolean checkIsSuperAdmin() { @@ -86,5 +85,18 @@ public class Validator { } return false; } + + public UserEntity validateUserId(HttpServletRequest request, Long userId) { + UserEntity user = validateUser(request); + if(user.getRoleEntity().getRoleType().equals(RoleStatusEnum.ROLE_BENEFICIARY.getValue()) && Boolean.FALSE.equals(user.getId().equals(userId))) { + throw new UnauthorizedAccessException(Status.UNAUTHORIZED, Translator.toLocale(GepafinConstant.INVALID_REQUEST)); + } + return userService.validateUser(userId); + } + + private Long getUserIdFromToken(HttpServletRequest request) { + Map userInfo= tokenProvider.getUserInfoAndUserIdFromToken(request); + return Long.parseLong(userInfo.get("userId").toString()); + } } 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 53ff4102..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 @@ -12,6 +12,7 @@ import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PutMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.multipart.MultipartFile; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; @@ -19,7 +20,9 @@ import io.swagger.v3.oas.annotations.media.Content; import io.swagger.v3.oas.annotations.media.ExampleObject; import io.swagger.v3.oas.annotations.responses.ApiResponse; import jakarta.servlet.http.HttpServletRequest; +import net.gepafin.tendermanagement.model.request.CompanyDelegationRequest; import net.gepafin.tendermanagement.model.request.CompanyRequest; +import net.gepafin.tendermanagement.model.response.CompanyDelegationResponse; import net.gepafin.tendermanagement.model.response.CompanyResponse; import net.gepafin.tendermanagement.model.util.Response; import net.gepafin.tendermanagement.web.rest.api.errors.ErrorConstants; @@ -81,7 +84,7 @@ public interface CompanyApi { @ExampleObject(value = ErrorConstants.BADREQUEST_ERROR_EXAMPLE) })) }) @GetMapping(value = "/user/{userId}", produces = { "application/json" }) ResponseEntity>> getCompanyByUserId(HttpServletRequest request, - @Parameter(description = "The company id", required = true) @PathVariable("userId") Long userId); + @Parameter(description = "The user id", required = true) @PathVariable("userId") Long userId); @Operation(summary = "Api to check vatNumber", responses = { @ApiResponse(responseCode = "200", description = "OK"), @ApiResponse(responseCode = "404", description = "Not Found", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = { @@ -93,5 +96,40 @@ public interface CompanyApi { @GetMapping(value = "/vatNumber", produces = { "application/json" }) ResponseEntity>> checkVatNumber(HttpServletRequest request, @Parameter(description = "The vatNumber of company", required = true) @RequestParam("vatNumber") String vatNumber); + + @Operation(summary = "Api to download company delegation template", 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 = "{companyId}/delegation/download", produces = { "application/json" }) + ResponseEntity downloadCompanyDelegation(HttpServletRequest request, + @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 (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 = { + @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 = "{companyId}/delegation/upload", consumes = MediaType.MULTIPART_FORM_DATA_VALUE) + ResponseEntity> uploadCompanyDelegation(HttpServletRequest request, + @Parameter(description = "The company id", required = true) @PathVariable("companyId") Long companyId, + @Parameter(description = "The company delegation", required = true) @RequestParam("file") MultipartFile file); + + @Operation(summary = "Api to get company delegation", 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) })) }) + @GetMapping(value = "{companyId}/delegation", produces = { "application/json" }) + ResponseEntity> getCompanyDelegation(HttpServletRequest request, + @Parameter(description = "The company id", required = true) @PathVariable("companyId") Long companyId); } 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 c4428f04..a3ab214c 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 @@ -1,20 +1,26 @@ package net.gepafin.tendermanagement.web.rest.api.impl; +import java.io.ByteArrayOutputStream; import java.util.List; import java.util.Map; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; +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.model.request.CompanyDelegationRequest; import net.gepafin.tendermanagement.model.request.CompanyRequest; +import net.gepafin.tendermanagement.model.response.CompanyDelegationResponse; import net.gepafin.tendermanagement.model.response.CompanyResponse; import net.gepafin.tendermanagement.model.util.Response; import net.gepafin.tendermanagement.service.CompanyService; @@ -86,4 +92,33 @@ public class CompanyApiController implements CompanyApi{ .body(new Response<>(data, Status.SUCCESS, Translator.toLocale(GepafinConstant.CHECK_VATNUMBER_SUCCESS_MSG))); } + @Override + public ResponseEntity downloadCompanyDelegation(HttpServletRequest request, Long companyId, CompanyDelegationRequest companyDelegationRequest) { + log.info("download company delegation with companyId: {}", companyId); + ByteArrayOutputStream data = companyService.downloadCompanyDelegation(request, companyId, companyDelegationRequest); + HttpHeaders headers = new HttpHeaders(); + headers.setContentType(MediaType.APPLICATION_OCTET_STREAM); + headers.setContentDispositionFormData("attachment", "delegation-template.docx"); + + return new ResponseEntity<>(data.toByteArray(), headers, HttpStatus.OK); + } + + @Override + public ResponseEntity> uploadCompanyDelegation(HttpServletRequest request, Long companyId, + MultipartFile file) { + log.info("upload company delegation with companyId: {}", companyId); + CompanyDelegationResponse companyDelegationResponse = companyService.uploadCompanyDelegation(request, companyId, file); + return ResponseEntity.status(HttpStatus.OK) + .body(new Response<>(companyDelegationResponse, Status.SUCCESS, Translator.toLocale(GepafinConstant.DELEGATION_FILE_UPLOAD_SUCCESS))); + } + + @Override + public ResponseEntity> getCompanyDelegation(HttpServletRequest request, + Long companyId) { + + log.info("get company delegation with companyId: {}", companyId); + CompanyDelegationResponse companyDelegationResponse = companyService.getCompanyDelegation(request, companyId); + return ResponseEntity.status(HttpStatus.OK) + .body(new Response<>(companyDelegationResponse, Status.SUCCESS, Translator.toLocale(GepafinConstant.DELEGATION_FETCH_SUCCESS))); + } } diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 3ce9ed17..eb6606ff 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -1,8 +1,8 @@ spring.application.name=tendermanagement # Multipart Configuration -spring.servlet.multipart.max-file-size=50MB -spring.servlet.multipart.max-request-size=50MB +spring.servlet.multipart.max-file-size=15MB +spring.servlet.multipart.max-request-size=15MB spring.profiles.active=testing @@ -31,6 +31,7 @@ aws.s3.region=eu-west-1 aws.s3.bucket.name=mementoresources aws.s3.url = https://mementoresources.s3.eu-west-1.amazonaws.com/ aws.s3.url.folder=gepafin +aws.s3.url.folder.delegation=gepafin/delegation # JWT configuration # Ensure these values match your expectations security.authentication.jwt.secret=my-secret-token-to-change-in-prod-environment-your-super-secure-randomly-generated-key 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 b0842eff..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 @@ -870,6 +870,46 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/message_en.properties b/src/main/resources/message_en.properties index 83d51d11..3be65f9f 100644 --- a/src/main/resources/message_en.properties +++ b/src/main/resources/message_en.properties @@ -206,6 +206,15 @@ vatnumber.already.exists=VatNumber already exists. invalid.email=Invalid email. company.id.mandatory=Company id is mandatory. user.already.connected.to.company=The user is already connected to this company. +validation.error.missing.firstName=First name is required. +validation.error.missing.lastName=Last name is required. +validation.error.missing.codiceFiscale=Codice Fiscale is required. +delegation.file.upload.success=Delegation file uploaded successfully. +delegation.fetch.success=Delegation fetched successfully. +delegation.template.generation.error=Something went wrong while generating the delegation template. +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. diff --git a/src/main/resources/message_it.properties b/src/main/resources/message_it.properties index 42453b8a..bd6a09f7 100644 --- a/src/main/resources/message_it.properties +++ b/src/main/resources/message_it.properties @@ -197,6 +197,18 @@ 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�. 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. +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. +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.