From f4932c2d1db9fc7b90c2eb0439aeee5ae4238ebd Mon Sep 17 00:00:00 2001 From: rajesh Date: Fri, 25 Oct 2024 13:33:01 +0530 Subject: [PATCH 01/23] Changed the URL of login api to identify the deployment bug --- .../tendermanagement/config/SamlFailureHandler.java | 13 ++++++++++++- .../tendermanagement/web/rest/api/UserApi.java | 2 +- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/src/main/java/net/gepafin/tendermanagement/config/SamlFailureHandler.java b/src/main/java/net/gepafin/tendermanagement/config/SamlFailureHandler.java index d2337ee9..52b30dbd 100644 --- a/src/main/java/net/gepafin/tendermanagement/config/SamlFailureHandler.java +++ b/src/main/java/net/gepafin/tendermanagement/config/SamlFailureHandler.java @@ -4,6 +4,7 @@ import java.io.IOException; import java.util.regex.Matcher; import java.util.regex.Pattern; + import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -16,9 +17,11 @@ import org.springframework.stereotype.Component; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import net.gepafin.tendermanagement.constants.GepafinConstant; +import net.gepafin.tendermanagement.entities.HubEntity; import net.gepafin.tendermanagement.entities.SamlResponseEntity; import net.gepafin.tendermanagement.enums.SamlResponseStatusEnum; import net.gepafin.tendermanagement.repositories.SamlResponseRepository; +import net.gepafin.tendermanagement.service.HubService; import net.gepafin.tendermanagement.web.rest.api.errors.CustomValidationException; import net.gepafin.tendermanagement.web.rest.api.errors.Status; @@ -33,12 +36,16 @@ public class SamlFailureHandler implements AuthenticationFailureHandler { @Autowired private SamlResponseRepository samlResponseRepository; + @Autowired + private HubService hubService; + @Override public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException { try { logger.error("SAML login failed: " + exception.getMessage()); - String inResponseTo = extractInResponseTo(feBaseUrl); + String inResponseTo = extractInResponseTo(exception.getMessage()); + if (Boolean.FALSE.equals(StringUtils.isEmpty(inResponseTo))) { SamlResponseEntity samlResponseLogEntity = samlResponseRepository .findByInResponseToAndStatus(inResponseTo, SamlResponseStatusEnum.INITIATED.getValue()) @@ -46,6 +53,10 @@ public class SamlFailureHandler implements AuthenticationFailureHandler { Translator.toLocale(GepafinConstant.INVALID_REQUEST))); samlResponseLogEntity.setStatus(SamlResponseStatusEnum.FAILED.getValue()); samlResponseRepository.save(samlResponseLogEntity); + HubEntity hub = hubService.getHubByUuid(samlResponseLogEntity.getHubUuid()); + if (Boolean.FALSE.equals(StringUtils.isEmpty(hub.getDomainName()))) { + feBaseUrl = hub.getDomainName(); + } } response.sendRedirect(feBaseUrl + "/login"); } catch (Exception e) { diff --git a/src/main/java/net/gepafin/tendermanagement/web/rest/api/UserApi.java b/src/main/java/net/gepafin/tendermanagement/web/rest/api/UserApi.java index c7b8e530..057d5d37 100644 --- a/src/main/java/net/gepafin/tendermanagement/web/rest/api/UserApi.java +++ b/src/main/java/net/gepafin/tendermanagement/web/rest/api/UserApi.java @@ -98,7 +98,7 @@ public interface UserApi { return new ResponseEntity<>(HttpStatus.NOT_IMPLEMENTED); } - @Operation(summary = "Api to login user", + @Operation(summary = "Api to login user Changed the URL to identify the deployment issue", responses = { @ApiResponse(responseCode = "200", description = "OK"), @ApiResponse(responseCode = "400", description = "Bad Request"), From 29f3b68850f2a2cc073714f3ea2fe59560adcdc5 Mon Sep 17 00:00:00 2001 From: rbonazzo-KZ <66477605+rbonazzo-KZ@users.noreply.github.com> Date: Fri, 25 Oct 2024 10:16:43 +0200 Subject: [PATCH 02/23] Update application-production.properties TEST DEPLOY --- src/main/resources/application-production.properties | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/resources/application-production.properties b/src/main/resources/application-production.properties index be007786..8c19671b 100644 --- a/src/main/resources/application-production.properties +++ b/src/main/resources/application-production.properties @@ -21,3 +21,4 @@ gepafin_email=bandi@pec.gepafin.it rinaldo_email=rinaldo.bonazzo@bflows.net carlo_email=carlo.mancosu@bflows.net default.hub.uuid=p4lk3bcx1RStqTaIVVbXs +# TEST DEPLOY Configuration From e9704e50cd7c4a032c838cd1b9c9c0f9795beaa5 Mon Sep 17 00:00:00 2001 From: nisha Date: Sat, 26 Oct 2024 09:05:22 +0530 Subject: [PATCH 03/23] Updated code for pdf correction --- .../gepafin/tendermanagement/dao/PdfDao.java | 125 ++++++++++++++---- 1 file changed, 97 insertions(+), 28 deletions(-) diff --git a/src/main/java/net/gepafin/tendermanagement/dao/PdfDao.java b/src/main/java/net/gepafin/tendermanagement/dao/PdfDao.java index efdc3798..bf585e19 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/PdfDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/PdfDao.java @@ -17,6 +17,7 @@ import net.gepafin.tendermanagement.model.response.*; import net.gepafin.tendermanagement.service.CallService; import net.gepafin.tendermanagement.util.Utils; import net.gepafin.tendermanagement.util.Validator; +import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -25,6 +26,7 @@ import org.springframework.stereotype.Component; import java.io.ByteArrayOutputStream; +import java.io.IOException; import java.util.*; import java.util.List; import java.util.stream.Collectors; @@ -60,7 +62,7 @@ public class PdfDao { // writer.setPageEvent(pageEvent); document.open(); // pageEvent.setTotalPages(writer.getPageNumber()); - addLogo(document, "https://mementoresources.s3.eu-west-1.amazonaws.com/gepafin/logo.jpg"); // Add your image path here + addLogo(document, "logo.jpg"); // Add your image path here BaseColor customColor = new BaseColor(0, 128, 0); // Adjust RGB values as needed @@ -82,8 +84,6 @@ public class PdfDao { ApplicationGetResponseBean applicationGetResponseBean=applicationDao.getApplicationByFormId(request, applicationId, null); for(FormApplicationResponse formApplicationResponse: applicationGetResponseBean.getForm()) { - document.add(new Paragraph(formApplicationResponse.getLabel(),sectionFont)); - document.add(new Paragraph(" ")); // Add line break List fieldLabelValuePairRequests = getFormFieldsToLabels(formApplicationResponse,writer,document); addColoredLines(writer,document,greenColor); document.add(new Paragraph(" ")); // Add line break @@ -231,24 +231,70 @@ public class PdfDao { } } else { - PdfPCell valueCell = new PdfPCell(new Phrase(String.valueOf(value), valueFont)); - valueCell.setPadding(5f); // Increase padding for better spacing - valueCell.setPaddingLeft(leftMargin); // Increase left margin for value - valueCell.setBorder(Rectangle.NO_BORDER); // Remove border for value cell - valueCell.setMinimumHeight(30f); - valueCell.setVerticalAlignment(Element.ALIGN_MIDDLE); - valueCell.setCellEvent(new RoundedCorners()); // Apply rounded corners - valueTable.addCell(valueCell); - document.add(valueTable); + String fieldValue=Utils.convertToString(value); + Image img = null; // This may throw MalformedURLException + if (fieldValue.equalsIgnoreCase("true")) { + // Use images for tick and cross + try { + img = Image.getInstance("true.jpg"); + } catch (IOException e) { + log.error("Error while uploading image for pdf for true"); + } + img.scaleAbsolute(15, 15); // Resize the image if needed + + PdfPCell cell = new PdfPCell(img); + cell.setPadding(5f); // Increase padding for better spacing + cell.setPaddingLeft(leftMargin); // Increase left margin for value + cell.setBorder(Rectangle.NO_BORDER); // Remove border for value cell + cell.setMinimumHeight(30f); + cell.setVerticalAlignment(Element.ALIGN_LEFT); + cell.setCellEvent(new RoundedCorners()); // Apply rounded corners + cell.setHorizontalAlignment(Element.ALIGN_LEFT); + valueTable.addCell(cell); + document.add(valueTable); + } + else if (fieldValue.equalsIgnoreCase("false")) { + // Use images for tick and cross + try { + img = Image.getInstance("false.jpg"); + } catch (IOException e) { + log.error("Error while uploading image for pdf for true"); + } + img.scaleAbsolute(15, 15); // Resize the image if needed + + PdfPCell cell = new PdfPCell(img); + cell.setPadding(5f); // Increase padding for better spacing + cell.setPaddingLeft(leftMargin); // Increase left margin for value + cell.setBorder(Rectangle.NO_BORDER); // Remove border for value cell + cell.setMinimumHeight(30f); + cell.setVerticalAlignment(Element.ALIGN_LEFT); + cell.setCellEvent(new RoundedCorners()); // Apply rounded corners + cell.setHorizontalAlignment(Element.ALIGN_LEFT); + valueTable.addCell(cell); + document.add(valueTable); + } + else { + PdfPCell valueCell = new PdfPCell(new Phrase(String.valueOf(value), valueFont)); + valueCell.setPadding(5f); // Increase padding for better spacing + valueCell.setPaddingLeft(leftMargin); // Increase left margin for value + valueCell.setBorder(Rectangle.NO_BORDER); // Remove border for value cell + valueCell.setMinimumHeight(30f); + valueCell.setVerticalAlignment(Element.ALIGN_MIDDLE); + valueCell.setCellEvent(new RoundedCorners()); // Apply rounded corners + + valueTable.addCell(valueCell); + document.add(valueTable); + } + } - document.add(new Paragraph("\n")); // Add line break after each value } private Document createPdfTable(List> extractedData, Document document, ContentResponseBean contentResponseBean) throws DocumentException { // Create a PdfPTable with dynamic column count based on stateFieldMap size Map stateFieldMap = new HashMap<>(); + Map stateFieldBoolean = new HashMap<>(); // Populate stateFieldMap from contentResponseBean settings contentResponseBean.getSettings().stream() @@ -268,8 +314,23 @@ public class PdfDao { stateFieldMap.put(fieldName, fieldDataValue); } }); - - PdfPTable table = new PdfPTable(stateFieldMap.size()); // Number of columns equals the number of map entries + contentResponseBean.getSettings().stream() + .filter(setting -> "table_columns".equals(setting.getName())) // Check for "table_columns" + .map(SettingResponseBean::getValue) + .filter(Objects::nonNull) // Ensure value is not null + .filter(settingValue -> settingValue instanceof Map) // Ensure value is a Map + .map(settingValue -> (Map) settingValue) // Cast to Map + .map(valueMap -> (List>) valueMap.get("stateFieldData")) // Extract stateFieldData list + .filter(Objects::nonNull) // Ensure stateFieldData is not null + .flatMap(List::stream) // Flatten the list of field data maps + .forEach(fieldData -> { + String fieldName = (String) fieldData.get("name"); // Get the name field + Boolean predefined = (Boolean) fieldData.get("predefined"); // Get the predefined field + if (fieldName != null && fieldName != null) { + stateFieldBoolean.put(fieldName, predefined); + } + }); + PdfPTable table = new PdfPTable(stateFieldMap.size()); // Number of columns equals the number of map entries table.setWidthPercentage(100); // Set table width to 100% table.setTableEvent(new RoundedBorderEvent()); @@ -278,29 +339,37 @@ public class PdfDao { float maxTableHeight = 700f; // Maximum height of the table before a page break boolean headersAdded = false; // Flag to check if headers have been added + List trueKeys = new ArrayList<>(); + List falseKeys = new ArrayList<>(); + for (Map.Entry entry : stateFieldBoolean.entrySet()) { + if (Boolean.TRUE.equals(entry.getValue())) { + trueKeys.add(entry.getKey()); // Store true keys + } else { + falseKeys.add(entry.getKey()); // Store false keys + } + } + List orderedKeys = new ArrayList<>(trueKeys); + orderedKeys.addAll(falseKeys); // Iterate through extracted data to populate the table for (Map row : extractedData) { // Add headers once if (!headersAdded) { - for (Map.Entry stateField : stateFieldMap.entrySet()) { - String headerValue = stateField.getValue(); // Header text + for (String key : orderedKeys) { + String headerValue = stateFieldMap.get(key); // Header text + PdfPCell headerCell = new PdfPCell(new Phrase(headerValue)); // Create a new PdfPCell for the header + headerCell.setHorizontalAlignment(Element.ALIGN_CENTER); // Center align + headerCell.setVerticalAlignment(Element.ALIGN_MIDDLE); + headerCell.setBackgroundColor(new BaseColor(178, 190, 181)); // Light gray background for header - PdfPCell headerCell = new PdfPCell(new Phrase(headerValue)); // Create a new PdfPCell for the header - headerCell.setHorizontalAlignment(Element.ALIGN_CENTER); // Center align - headerCell.setVerticalAlignment(Element.ALIGN_MIDDLE); - headerCell.setBackgroundColor(new BaseColor(178, 190, 181)); // Light gray background for header - - table.addCell(headerCell); // Add the header cell to the table - } + table.addCell(headerCell); // Add the header cell to the table + } headersAdded = true; // Prevent headers from being added again } // Add data rows matching stateFieldMap keys for (Map.Entry stateField : stateFieldMap.entrySet()) { - String stateKey = stateField.getKey(); // Get the key from stateFieldMap - if (row.containsKey(stateKey)) { // If row contains the stateKey - Object value = row.get(stateKey); // Get the value from the row map - + for (String key : orderedKeys) { // Iterate over the ordered keys + Object value = row.getOrDefault(key, ""); // Fetch value or use empty string if key not present PdfPCell dynamicCell = new PdfPCell(new Phrase(value != null ? value.toString() : "", textFont)); dynamicCell.setBackgroundColor(new BaseColor(239, 243, 248)); // Light blue for the cell dynamicCell.setMinimumHeight(rowHeight); From afa506f00f1917773e059e8b6b55988b435a289e Mon Sep 17 00:00:00 2001 From: harish Date: Sat, 26 Oct 2024 14:19:10 +0530 Subject: [PATCH 04/23] updated checkbox code --- .../gepafin/tendermanagement/dao/PdfDao.java | 47 +++++++++---------- 1 file changed, 22 insertions(+), 25 deletions(-) diff --git a/src/main/java/net/gepafin/tendermanagement/dao/PdfDao.java b/src/main/java/net/gepafin/tendermanagement/dao/PdfDao.java index bf585e19..a2c03a5b 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/PdfDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/PdfDao.java @@ -10,14 +10,12 @@ import com.itextpdf.text.Rectangle; import com.itextpdf.text.pdf.*; import jakarta.servlet.http.HttpServletRequest; -import lombok.extern.slf4j.Slf4j; import net.gepafin.tendermanagement.entities.*; import net.gepafin.tendermanagement.model.request.FieldLabelValuePairRequest; import net.gepafin.tendermanagement.model.response.*; import net.gepafin.tendermanagement.service.CallService; import net.gepafin.tendermanagement.util.Utils; import net.gepafin.tendermanagement.util.Validator; -import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -62,7 +60,8 @@ public class PdfDao { // writer.setPageEvent(pageEvent); document.open(); // pageEvent.setTotalPages(writer.getPageNumber()); - addLogo(document, "logo.jpg"); // Add your image path here +// addLogo(document, "logo.jpg"); // Add your image path here the migration code after cherry-pick + addLogo(document, "https://mementoresources.s3.eu-west-1.amazonaws.com/gepafin/logo.jpg"); BaseColor customColor = new BaseColor(0, 128, 0); // Adjust RGB values as needed @@ -234,44 +233,42 @@ public class PdfDao { String fieldValue=Utils.convertToString(value); Image img = null; // This may throw MalformedURLException - if (fieldValue.equalsIgnoreCase("true")) { + if (fieldValue.trim().equalsIgnoreCase("true")) { // Use images for tick and cross try { - img = Image.getInstance("true.jpg"); +// img = Image.getInstance("true.jpg"); update code after cherry-pick + img = Image.getInstance("https://mementoresources.s3.eu-west-1.amazonaws.com/gepafin/true.png"); } catch (IOException e) { log.error("Error while uploading image for pdf for true"); } img.scaleAbsolute(15, 15); // Resize the image if needed PdfPCell cell = new PdfPCell(img); - cell.setPadding(5f); // Increase padding for better spacing - cell.setPaddingLeft(leftMargin); // Increase left margin for value - cell.setBorder(Rectangle.NO_BORDER); // Remove border for value cell - cell.setMinimumHeight(30f); - cell.setVerticalAlignment(Element.ALIGN_LEFT); - cell.setCellEvent(new RoundedCorners()); // Apply rounded corners - cell.setHorizontalAlignment(Element.ALIGN_LEFT); - valueTable.addCell(cell); + cell.setPadding(0); // Remove padding + cell.setBorder(Rectangle.NO_BORDER); // Remove border + cell.setMinimumHeight(15f); // Set height to fit checkbox image + cell.setVerticalAlignment(Element.ALIGN_MIDDLE); + cell.setHorizontalAlignment(Element.ALIGN_LEFT); // Align the checkbox image to the left + + valueTable.addCell(cell); // Add cell with checkbox to the table document.add(valueTable); - } - else if (fieldValue.equalsIgnoreCase("false")) { + } else if (fieldValue.trim().equalsIgnoreCase("false")) { // Use images for tick and cross try { - img = Image.getInstance("false.jpg"); + img = Image.getInstance("https://mementoresources.s3.eu-west-1.amazonaws.com/gepafin/false.png"); } catch (IOException e) { - log.error("Error while uploading image for pdf for true"); + log.error("Error while uploading image for pdf for false"); } img.scaleAbsolute(15, 15); // Resize the image if needed PdfPCell cell = new PdfPCell(img); - cell.setPadding(5f); // Increase padding for better spacing - cell.setPaddingLeft(leftMargin); // Increase left margin for value - cell.setBorder(Rectangle.NO_BORDER); // Remove border for value cell - cell.setMinimumHeight(30f); - cell.setVerticalAlignment(Element.ALIGN_LEFT); - cell.setCellEvent(new RoundedCorners()); // Apply rounded corners - cell.setHorizontalAlignment(Element.ALIGN_LEFT); - valueTable.addCell(cell); + cell.setPadding(0); // Remove padding + cell.setBorder(Rectangle.NO_BORDER); // Remove border + cell.setMinimumHeight(15f); // Set height to fit checkbox image + cell.setVerticalAlignment(Element.ALIGN_MIDDLE); + cell.setHorizontalAlignment(Element.ALIGN_LEFT); // Align the checkbox image to the left + + valueTable.addCell(cell); // Add cell with checkbox to the table document.add(valueTable); } else { From 69e70ec9fa58472ceaca354c7332435cd5b915b2 Mon Sep 17 00:00:00 2001 From: harish Date: Sat, 26 Oct 2024 14:50:52 +0530 Subject: [PATCH 05/23] updated login api description --- .../java/net/gepafin/tendermanagement/web/rest/api/UserApi.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/net/gepafin/tendermanagement/web/rest/api/UserApi.java b/src/main/java/net/gepafin/tendermanagement/web/rest/api/UserApi.java index 057d5d37..c7b8e530 100644 --- a/src/main/java/net/gepafin/tendermanagement/web/rest/api/UserApi.java +++ b/src/main/java/net/gepafin/tendermanagement/web/rest/api/UserApi.java @@ -98,7 +98,7 @@ public interface UserApi { return new ResponseEntity<>(HttpStatus.NOT_IMPLEMENTED); } - @Operation(summary = "Api to login user Changed the URL to identify the deployment issue", + @Operation(summary = "Api to login user", responses = { @ApiResponse(responseCode = "200", description = "OK"), @ApiResponse(responseCode = "400", description = "Bad Request"), From 951575054070f43ff19133f49d971ef3212d7e77 Mon Sep 17 00:00:00 2001 From: piyuskag Date: Fri, 25 Oct 2024 15:29:28 +0530 Subject: [PATCH 06/23] Resolved Conflicts --- .../constants/GepafinConstant.java | 9 + .../tendermanagement/dao/ApplicationDao.java | 27 +- .../tendermanagement/dao/DelegationDao.java | 22 +- .../tendermanagement/dao/DocumentDao.java | 60 +- .../tendermanagement/dao/S3ConfigDao.java | 104 +++ .../tendermanagement/dao/S3PathConfig.java | 49 + .../entities/S3ConfigEntity.java | 25 + .../enums/DocOtherSourceTypeEnum.java | 17 + .../model/request/S3ConfigReq.java | 20 + .../model/response/S3ConfigBean.java | 11 + .../repositories/ApplicationRepository.java | 3 +- .../ApplicationSignedDocumentRepository.java | 11 + .../repositories/DocumentRepository.java | 2 + .../repositories/S3ConfigRepository.java | 24 + .../UserCompanyDelegationRepository.java | 6 + .../service/S3ConfigService.java | 19 + .../service/impl/DocumentServiceImpl.java | 2 +- .../service/impl/S3ConfigServiceImpl.java | 41 + .../impl/S3ReUploadMigrationService.java | 197 ++++ .../UserSignedAndDelegationServiceImpl.java | 261 ++++++ .../web/rest/api/S3ConfigApi.java | 67 ++ .../web/rest/api/S3MigrationApi.java | 28 + .../rest/api/UserSignedAndDelegationApi.java | 38 + .../rest/api/impl/DocumentApiController.java | 2 +- .../web/rest/api/impl/S3ConfigController.java | 59 ++ .../api/impl/S3MigrationApiController.java | 19 + ...ignedAndDelegationMigrationController.java | 24 + .../db/changelog/db.changelog-1.0.0.xml | 864 ++++++++++-------- 28 files changed, 1611 insertions(+), 400 deletions(-) create mode 100644 src/main/java/net/gepafin/tendermanagement/dao/S3ConfigDao.java create mode 100644 src/main/java/net/gepafin/tendermanagement/dao/S3PathConfig.java create mode 100644 src/main/java/net/gepafin/tendermanagement/entities/S3ConfigEntity.java create mode 100644 src/main/java/net/gepafin/tendermanagement/enums/DocOtherSourceTypeEnum.java create mode 100644 src/main/java/net/gepafin/tendermanagement/model/request/S3ConfigReq.java create mode 100644 src/main/java/net/gepafin/tendermanagement/model/response/S3ConfigBean.java create mode 100644 src/main/java/net/gepafin/tendermanagement/repositories/S3ConfigRepository.java create mode 100644 src/main/java/net/gepafin/tendermanagement/service/S3ConfigService.java create mode 100644 src/main/java/net/gepafin/tendermanagement/service/impl/S3ConfigServiceImpl.java create mode 100644 src/main/java/net/gepafin/tendermanagement/service/impl/S3ReUploadMigrationService.java create mode 100644 src/main/java/net/gepafin/tendermanagement/service/impl/UserSignedAndDelegationServiceImpl.java create mode 100644 src/main/java/net/gepafin/tendermanagement/web/rest/api/S3ConfigApi.java create mode 100644 src/main/java/net/gepafin/tendermanagement/web/rest/api/S3MigrationApi.java create mode 100644 src/main/java/net/gepafin/tendermanagement/web/rest/api/UserSignedAndDelegationApi.java create mode 100644 src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/S3ConfigController.java create mode 100644 src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/S3MigrationApiController.java create mode 100644 src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/S3UserSignedAndDelegationMigrationController.java diff --git a/src/main/java/net/gepafin/tendermanagement/constants/GepafinConstant.java b/src/main/java/net/gepafin/tendermanagement/constants/GepafinConstant.java index c5b18460..45418554 100644 --- a/src/main/java/net/gepafin/tendermanagement/constants/GepafinConstant.java +++ b/src/main/java/net/gepafin/tendermanagement/constants/GepafinConstant.java @@ -251,5 +251,14 @@ public class GepafinConstant { public static final String APPLICATION_NOT_IN_DRAFT_STATUS="application.not.in.draft.status"; public static final String GET_ERROR_S3 = "get.error.s3"; public static final String INVALID_APPLICATION_STATUS = "invalid.application.status"; + + public static final String ADDED_S3_PATH_STRUCTURE ="added.s3.path.structure"; + public static final String S3_PATH_STRUCTURE_BY_TYPE ="fetched.s3.path.structure.by.type.successfully"; + public static final String S3_PATH_STRUCTURE_NOT_FOUND_BY_TYPE_MSG ="s3.path.not.found.by.type"; + public static final String S3_PATH_STRUCTURE_NOT_FOUND_BY_ID_MSG ="s3.path.not.found.by.id"; + public static final String S3_PATH_DELETE_MSG ="s3.path.config.delete.successfully"; + public static final String S3_PATH_CONFIG_UPDATE_MSG ="s3.path.config.updated.successfully"; + public static final String S3_PATH_CONFIG_DUPLICATE_TYPE_ALREADY_EXIST ="s3.path.config.already.exist."; + public static final String S3_PATH_GENERATION_ERROR_MSG ="s3.path.config.already.exist."; } diff --git a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java index c68d3f2e..2332a194 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java @@ -6,6 +6,7 @@ import net.gepafin.tendermanagement.entities.*; import net.gepafin.tendermanagement.entities.SystemEmailTemplatesEntity.SystemEmailTemplatesEntityTypeEnum; import net.gepafin.tendermanagement.enums.ApplicationSignedDocumentStatusEnum; import net.gepafin.tendermanagement.enums.ApplicationStatusTypeEnum; +import net.gepafin.tendermanagement.enums.DocOtherSourceTypeEnum; import net.gepafin.tendermanagement.enums.DocumentSourceTypeEnum; import net.gepafin.tendermanagement.enums.RoleStatusEnum; import net.gepafin.tendermanagement.enums.UserCompanyDelegationStatusEnum; @@ -127,6 +128,9 @@ public class ApplicationDao { @Autowired private UserService userService; + @Autowired + S3PathConfig s3ConfigBean; + public ApplicationResponseBean createApplication(HttpServletRequest request, ApplicationRequestBean applicationRequestBean, Long formId, Long applicationId) { FormEntity formEntity = formService.validateForm(formId); @@ -789,9 +793,9 @@ public class ApplicationDao { // applicationSignedDocument.setStatus(ApplicationSignedDocumentStatusEnum.INACTIVE.getValue()); // applicationSignedDocumentRepository.save(applicationSignedDocument); } - UploadFileOnAmazonS3Response uploadFileOnAmazonS3 = amazonS3Service.uploadFileOnAmazonS3(signedDocumentS3Folder, - file); - applicationSignedDocument = new ApplicationSignedDocumentEntity(); + UploadFileOnAmazonS3Response uploadFileOnAmazonS3 = uploadFileOnAmazonS3ForUserSignedDocument(file, + applicationEntity.getCall().getId(), applicationId); + applicationSignedDocument = new ApplicationSignedDocumentEntity(); applicationSignedDocument.setApplication(applicationEntity); applicationSignedDocument.setFileName(uploadFileOnAmazonS3.getFileName()); applicationSignedDocument.setFilePath(uploadFileOnAmazonS3.getFilePath()); @@ -801,7 +805,22 @@ public class ApplicationDao { applicationRepository.save(applicationEntity); return convertApplicationSignedDocumentToApplicationSignedDocumentResponse(applicationSignedDocument); } - + private UploadFileOnAmazonS3Response uploadFileOnAmazonS3ForUserSignedDocument(MultipartFile file, Long callId, Long applicationId) { + try { + String s3Path = generateS3PathForDelegation(callId, applicationId); + log.info("S3 Path {}", s3Path); + return amazonS3Service.uploadFileOnAmazonS3(s3Path, file); + } catch (Exception e) { + throw new CustomValidationException(Status.VALIDATION_ERROR, Translator.toLocale(GepafinConstant.UPLOAD_ERROR_S3)); + } + } + private String generateS3PathForDelegation(Long callId, Long applicationId) { + try { + return s3ConfigBean.generateDocumentPathForOther(DocOtherSourceTypeEnum.USER_SIGNED_DOCUMENT, callId, applicationId); + } catch (IllegalArgumentException e) { + throw new CustomValidationException(Status.VALIDATION_ERROR, Translator.toLocale(GepafinConstant.S3_PATH_GENERATION_ERROR_MSG)); + } + } private ApplicationSignedDocumentResponse convertApplicationSignedDocumentToApplicationSignedDocumentResponse( ApplicationSignedDocumentEntity applicationSignedDocument) { ApplicationSignedDocumentResponse applicationSignedDocumentResponse = new ApplicationSignedDocumentResponse(); diff --git a/src/main/java/net/gepafin/tendermanagement/dao/DelegationDao.java b/src/main/java/net/gepafin/tendermanagement/dao/DelegationDao.java index 1d9e904a..20ae2cca 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/DelegationDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/DelegationDao.java @@ -7,6 +7,7 @@ import java.util.HashMap; import java.util.Map; import java.util.function.Function; +import net.gepafin.tendermanagement.enums.DocOtherSourceTypeEnum; import org.apache.commons.lang3.StringUtils; import org.apache.poi.xwpf.usermodel.XWPFDocument; import org.springframework.beans.factory.annotation.Autowired; @@ -53,6 +54,9 @@ public class DelegationDao { @Autowired private DocumentRepository documentRepository; + + @Autowired + private S3PathConfig s3ConfigBean; @Value("${aws.s3.url.folder.delegation}") private String s3Folder; @@ -185,7 +189,7 @@ public class DelegationDao { userCompanyDelegationEntity.setStatus(UserCompanyDelegationStatusEnum.INACTIVE.getValue()); userCompanyDelegationRepository.save(userCompanyDelegationEntity); } - UploadFileOnAmazonS3Response uploadFileOnAmazonS3Response = amazonS3Service.uploadFileOnAmazonS3(s3Folder, file); + UploadFileOnAmazonS3Response uploadFileOnAmazonS3Response = uploadFileOnAmazonS3ForCompanyDelegation(file); userCompanyDelegationEntity = new UserCompanyDelegationEntity(); userCompanyDelegationEntity.setCompanyId(companyId); userCompanyDelegationEntity.setUserId(userEntity.getId()); @@ -198,7 +202,21 @@ public class DelegationDao { userCompanyDelegationRepository.save(userCompanyDelegationEntity); 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); diff --git a/src/main/java/net/gepafin/tendermanagement/dao/DocumentDao.java b/src/main/java/net/gepafin/tendermanagement/dao/DocumentDao.java index 90725964..226848f7 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/DocumentDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/DocumentDao.java @@ -2,7 +2,10 @@ package net.gepafin.tendermanagement.dao; import java.util.stream.Collectors; +import lombok.extern.slf4j.Slf4j; import net.gepafin.tendermanagement.enums.DocumentSourceTypeEnum; +import net.gepafin.tendermanagement.repositories.ApplicationRepository; +import net.gepafin.tendermanagement.web.rest.api.errors.CustomValidationException; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; @@ -24,6 +27,7 @@ import net.gepafin.tendermanagement.web.rest.api.errors.Status; import java.util.ArrayList; import java.util.List; +@Slf4j @Component public class DocumentDao { @@ -38,6 +42,12 @@ public class DocumentDao { @Autowired private CallService callService; + + @Autowired + private S3PathConfig s3ConfigBean; + + @Autowired + private ApplicationRepository applicationFormRepository; @Value("${aws.s3.url.folder}") private String s3Folder; @@ -46,8 +56,7 @@ public class DocumentDao { List documentEntities = new ArrayList<>(); Long source = resolveSourceId(sourceId, sourceType); for (MultipartFile file : files) { - UploadFileOnAmazonS3Response uploadFileOnAmazonS3Response = amazonS3Service.uploadFileOnAmazonS3(s3Folder, - file); + UploadFileOnAmazonS3Response uploadFileOnAmazonS3Response = uploadFileOnAmazonS3(file, sourceType, sourceId); if (uploadFileOnAmazonS3Response != null) { DocumentEntity documentEntity = new DocumentEntity(); documentEntity.setFileName(uploadFileOnAmazonS3Response.getFileName()); @@ -62,6 +71,30 @@ public class DocumentDao { documentRepository.saveAll(documentEntities); return documentEntities.stream().map(callDao::convertToDocumentResponseBean).collect(Collectors.toList()); } + private UploadFileOnAmazonS3Response uploadFileOnAmazonS3(MultipartFile file, DocumentSourceTypeEnum type, Long sourceId) { + + Long applicationId = 0L; + Long callId = sourceId; + if (type == DocumentSourceTypeEnum.APPLICATION) { + applicationId = sourceId; + callId = applicationFormRepository.findCallIdById(applicationId); + } + try { + String s3Path = generateS3Path(type, callId, applicationId); + log.info("Generated S3 path {}", s3Path); + return amazonS3Service.uploadFileOnAmazonS3(s3Path, file); + } catch (Exception e) { + throw new CustomValidationException(Status.VALIDATION_ERROR, Translator.toLocale(GepafinConstant.UPLOAD_ERROR_S3)); + } + } + public String generateS3Path(DocumentSourceTypeEnum typeOfDocument, Long callId, Long applicationId) { + + try { + return s3ConfigBean.generateDocumentPath(typeOfDocument, callId, applicationId); + } catch (IllegalArgumentException e) { + throw new CustomValidationException(Status.VALIDATION_ERROR, Translator.toLocale(GepafinConstant.S3_PATH_GENERATION_ERROR_MSG)); + } + } private Long resolveSourceId(Long sourceId, DocumentSourceTypeEnum sourceType) { if (sourceType == DocumentSourceTypeEnum.CALL) { CallEntity callEntity = callService.validateCall(sourceId); @@ -91,8 +124,9 @@ public class DocumentDao { public DocumentResponseBean updateDocument(Long documentId, MultipartFile file, DocumentTypeEnum documentTypeEnum) { DocumentEntity documentEntity = validateDocument(documentId); - UploadFileOnAmazonS3Response uploadFileOnAmazonS3Response = amazonS3Service.uploadFileOnAmazonS3(s3Folder, file); - if (uploadFileOnAmazonS3Response != null) { + String type = documentEntity.getSource(); + UploadFileOnAmazonS3Response uploadFileOnAmazonS3Response = updateFileOnAmazonS3(file, DocumentSourceTypeEnum.valueOf(type), documentEntity.getSourceId()); + if (uploadFileOnAmazonS3Response != null) { documentEntity.setFileName(uploadFileOnAmazonS3Response.getFileName()); documentEntity.setFilePath(uploadFileOnAmazonS3Response.getFilePath()); documentEntity.setType(documentTypeEnum.getValue()); @@ -102,7 +136,25 @@ public class DocumentDao { } return callDao.convertToDocumentResponseBean(documentEntity); } + private UploadFileOnAmazonS3Response updateFileOnAmazonS3(MultipartFile file, DocumentSourceTypeEnum type, Long id) { + try { + Long callId; + Long applicationId; + if(type.equals("APPLICATION")){ + callId = applicationFormRepository.findCallIdById(id); + applicationId = id; + }else{ + callId = id; + applicationId = 0L; + } + String s3Path = generateS3Path(type, callId, applicationId); + log.info("Generated S3 path {}", s3Path); + return amazonS3Service.uploadFileOnAmazonS3(s3Path, file); + } catch (Exception e) { + throw new CustomValidationException(Status.VALIDATION_ERROR, Translator.toLocale(GepafinConstant.UPLOAD_ERROR_S3)); + } + } public DocumentResponseBean getDocument(Long documentId) { DocumentEntity documentEntity = validateDocument(documentId); return callDao.convertToDocumentResponseBean(documentEntity); diff --git a/src/main/java/net/gepafin/tendermanagement/dao/S3ConfigDao.java b/src/main/java/net/gepafin/tendermanagement/dao/S3ConfigDao.java new file mode 100644 index 00000000..3661ad02 --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/dao/S3ConfigDao.java @@ -0,0 +1,104 @@ +package net.gepafin.tendermanagement.dao; + +import net.gepafin.tendermanagement.config.Translator; +import net.gepafin.tendermanagement.constants.GepafinConstant; +import net.gepafin.tendermanagement.entities.S3ConfigEntity; +import net.gepafin.tendermanagement.model.request.S3ConfigReq; +import net.gepafin.tendermanagement.model.response.S3ConfigBean; +import net.gepafin.tendermanagement.repositories.S3ConfigRepository; +import net.gepafin.tendermanagement.web.rest.api.errors.CustomValidationException; +import net.gepafin.tendermanagement.web.rest.api.errors.Status; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.util.Optional; + +import static net.gepafin.tendermanagement.util.Utils.setIfUpdated; + +@Component +public class S3ConfigDao { + private static final Logger log = LoggerFactory.getLogger(S3ConfigDao.class); + + @Autowired + S3ConfigRepository s3ConfigRepository; + + public S3ConfigBean addS3Path(S3ConfigReq s3PathConfigurationReq) { + + log.info("Adding s3 s3PathConfigurationReq structure with it's type.."); + S3ConfigEntity s3PathConfigurationEntity = convertToS3pathEntity(s3PathConfigurationReq); + s3PathConfigurationEntity = s3ConfigRepository.save(s3PathConfigurationEntity); + log.info("Added s3 path config details {} to DB.", s3PathConfigurationEntity); + return convertToS3pathBean(s3PathConfigurationEntity); + } + private S3ConfigEntity convertToS3pathEntity(S3ConfigReq s3PathConfigReq) { + + S3ConfigEntity s3PathConfigEntity = new S3ConfigEntity(); + s3PathConfigEntity.setPath(s3PathConfigReq.getPath()); + s3PathConfigEntity.setType(s3PathConfigReq.getType()); + s3PathConfigEntity.setBucketName(s3PathConfigReq.getBucketName()); + return s3PathConfigEntity; + } + private S3ConfigBean convertToS3pathBean(S3ConfigEntity s3PathConfigReq) { + + S3ConfigBean s3PathConfigBean = new S3ConfigBean(); + s3PathConfigBean.setPath(s3PathConfigReq.getPath()); + s3PathConfigBean.setType(s3PathConfigReq.getType()); + s3PathConfigBean.setBucketName(s3PathConfigReq.getBucketName()); + return s3PathConfigBean; + } + + public Optional getS3PathByType(String type) { + + log.info("Fetching S3-Path structure by type: {}", type); + Optional s3PathData = s3ConfigRepository.getPathByType(type); + if (s3PathData == null) { + log.error("No S3-Path found for type: {}", type); + throw new CustomValidationException(Status.NOT_FOUND, Translator.toLocale(GepafinConstant.S3_PATH_STRUCTURE_NOT_FOUND_BY_TYPE_MSG)); + } + log.info("Fetched S3-Path: {} for type: {}", s3PathData, type); + return s3PathData; + } + + public S3ConfigEntity deleteS3PathConfigById(Long id) { + + log.info("Checking s3-path associated with this id {} to delete....", id); + S3ConfigEntity s3PathConfigData = s3ConfigRepository.findS3PathConfigurationById(id); + if (s3PathConfigData == null) { + log.error("No S3-Path found for id: {}", id); + throw new CustomValidationException(Status.NOT_FOUND, Translator.toLocale(GepafinConstant.S3_PATH_STRUCTURE_NOT_FOUND_BY_ID_MSG)); + } else { + log.info("Found s3-path associated with this id {} to delete.", id); + s3ConfigRepository.deleteById(id); + log.error("Deleted s3-path configuration successfully for id: {}", id); + return s3PathConfigData; + } + } + public S3ConfigBean updateS3PathConfiguration(S3ConfigReq s3PathConfigurationReq, Long id) { + + log.info("Updating S3-path Configuration."); + S3ConfigEntity s3PathConfigDataExists = s3ConfigRepository.findS3PathConfigurationById(id); + if (s3PathConfigDataExists == null) { + log.error("No S3-Path found for id: {}", id); + throw new CustomValidationException(Status.NOT_FOUND, Translator.toLocale(GepafinConstant.S3_PATH_STRUCTURE_NOT_FOUND_BY_ID_MSG)); + } else { + Optional s3PathData = s3ConfigRepository.getPathByType(s3PathConfigurationReq.getType()); + if(s3PathData != null){ + log.error("S3-Path type already exist. {}", s3PathData); + throw new CustomValidationException(Status.BAD_REQUEST, Translator.toLocale(GepafinConstant.S3_PATH_CONFIG_DUPLICATE_TYPE_ALREADY_EXIST)); + } + S3ConfigEntity s3PathConfigurationEntity = convertToS3pathEntity(s3PathConfigurationReq); + setIfUpdated(s3PathConfigurationEntity::getPath, s3PathConfigurationEntity::setPath, s3PathConfigurationReq.getPath()); + setIfUpdated(s3PathConfigurationEntity::getBucketName, s3PathConfigurationEntity::setBucketName, s3PathConfigurationReq.getBucketName()); + setIfUpdated(s3PathConfigurationEntity::getType, s3PathConfigurationEntity::setType, s3PathConfigurationReq.getType()); +// s3PathConfigurationEntity.setType(s3PathConfigurationReq.getType()); +// s3PathConfigurationEntity.setPath(s3PathConfigurationReq.getPath()); +// s3PathConfigurationEntity.setBucketName(s3PathConfigurationReq.getBucketName()); + s3ConfigRepository.save(s3PathConfigurationEntity); + log.info("Updated S3-path-configuration successfully."); + return convertToS3pathBean(s3PathConfigurationEntity); + } + + } +} diff --git a/src/main/java/net/gepafin/tendermanagement/dao/S3PathConfig.java b/src/main/java/net/gepafin/tendermanagement/dao/S3PathConfig.java new file mode 100644 index 00000000..b127b699 --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/dao/S3PathConfig.java @@ -0,0 +1,49 @@ +package net.gepafin.tendermanagement.dao; + +import net.gepafin.tendermanagement.entities.S3ConfigEntity; +import net.gepafin.tendermanagement.enums.DocOtherSourceTypeEnum; +import net.gepafin.tendermanagement.enums.DocumentSourceTypeEnum; +import net.gepafin.tendermanagement.repositories.S3ConfigRepository; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +@Component +public class S3PathConfig { + + @Autowired + S3ConfigRepository s3ConfigRepository; + + public String generateDocumentPath(DocumentSourceTypeEnum type, Long callId, Long applicationId) { + + S3ConfigEntity config = getDocumentPath(type); + return config.getParentFolder() + "/" + buildS3Path(config.getPath(), callId, applicationId); + } + public String generateDocumentPathForOther(DocOtherSourceTypeEnum type, Long callId, Long applicationId) { + + S3ConfigEntity config = getDocumentPathForOther(type); + return config.getParentFolder() + "/" + buildS3Path(config.getPath(), callId, applicationId); + } + private String buildS3Path(String pathTemplate, Long callId, Long applicationId) { + + return pathTemplate.replace("{call_id}", callId != null && callId != 0L ? "call_" + callId : "").replace("{application_id}", applicationId != null && applicationId != 0L ? "application_" + applicationId : ""); + } + public String generateDocumentPathForDelegationAndSignedDocument(DocOtherSourceTypeEnum type) { + + S3ConfigEntity config = getDocumentPathForOther(type); + return config.getParentFolder() + "/" + config.getPath(); + } + private S3ConfigEntity getDocumentPath(DocumentSourceTypeEnum type) { + + return s3ConfigRepository.getPathByType(type.name()).orElseThrow(() -> new IllegalArgumentException("No path configuration found for type: " + type)); + } + private S3ConfigEntity getDocumentPathForOther(DocOtherSourceTypeEnum type) { + + return s3ConfigRepository.getPathByType(type.name()).orElseThrow(() -> new IllegalArgumentException("No path configuration found for type: " + type)); + } + public String getBucketNameForOtherType(DocOtherSourceTypeEnum type){ + return s3ConfigRepository.getBucketNameByType(type); + } + public String getBucketNameForCallAppType(DocumentSourceTypeEnum type){ + return s3ConfigRepository.getBucketNameByType(type); + } +} diff --git a/src/main/java/net/gepafin/tendermanagement/entities/S3ConfigEntity.java b/src/main/java/net/gepafin/tendermanagement/entities/S3ConfigEntity.java new file mode 100644 index 00000000..66502bbc --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/entities/S3ConfigEntity.java @@ -0,0 +1,25 @@ +package net.gepafin.tendermanagement.entities; + +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.Table; +import lombok.Data; + +@Entity +@Table(name = "s3_path_configuration") +@Data +public class S3ConfigEntity extends BaseEntity { + + @Column(name = "TYPE") + private String type; + + @Column(name = "PATH") + private String path; + + @Column(name = "BUCKET_NAME") + private String bucketName; + + @Column(name = "PARENT_FOLDER") + private String parentFolder; +} + diff --git a/src/main/java/net/gepafin/tendermanagement/enums/DocOtherSourceTypeEnum.java b/src/main/java/net/gepafin/tendermanagement/enums/DocOtherSourceTypeEnum.java new file mode 100644 index 00000000..751dfa92 --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/enums/DocOtherSourceTypeEnum.java @@ -0,0 +1,17 @@ +package net.gepafin.tendermanagement.enums; + +public enum DocOtherSourceTypeEnum { + USER_SIGNED_DOCUMENT("USER_SIGNED_DOCUMENT"), + USER_DELEGATION("USER_DELEGATION"), + TEMPLATE("TEMPLATE"); + + private String value; + + DocOtherSourceTypeEnum(String value) { + this.value = value; + } + + public String getValue() { + return value; + } +} diff --git a/src/main/java/net/gepafin/tendermanagement/model/request/S3ConfigReq.java b/src/main/java/net/gepafin/tendermanagement/model/request/S3ConfigReq.java new file mode 100644 index 00000000..859878de --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/model/request/S3ConfigReq.java @@ -0,0 +1,20 @@ +package net.gepafin.tendermanagement.model.request; + +import lombok.Data; + +import javax.validation.constraints.NotNull; + +@Data +public class S3ConfigReq { + @NotNull + private String path; + + @NotNull + private String type; + + @NotNull + private String bucketName; + + @NotNull + private String parentFolder; +} diff --git a/src/main/java/net/gepafin/tendermanagement/model/response/S3ConfigBean.java b/src/main/java/net/gepafin/tendermanagement/model/response/S3ConfigBean.java new file mode 100644 index 00000000..798f8b2c --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/model/response/S3ConfigBean.java @@ -0,0 +1,11 @@ +package net.gepafin.tendermanagement.model.response; + +import lombok.Data; + +@Data +public class S3ConfigBean { + private String path; + private String type; + private String bucketName; + private String parentFolder; +} diff --git a/src/main/java/net/gepafin/tendermanagement/repositories/ApplicationRepository.java b/src/main/java/net/gepafin/tendermanagement/repositories/ApplicationRepository.java index 9d52b2aa..158c43fd 100644 --- a/src/main/java/net/gepafin/tendermanagement/repositories/ApplicationRepository.java +++ b/src/main/java/net/gepafin/tendermanagement/repositories/ApplicationRepository.java @@ -40,5 +40,6 @@ public interface ApplicationRepository extends JpaRepository { ApplicationSignedDocumentEntity findByApplicationIdAndStatus(Long applicationId, String status); + Long findApplicationIdById(Long id); + + @Query("SELECT a.id FROM ApplicationSignedDocumentEntity d JOIN d.application a WHERE d.id = :id") + List findApplicationIdIdsById(@Param("id") Long id); + + @Query("SELECT d FROM ApplicationSignedDocumentEntity d WHERE d.status = :status") + List findAllByIsStatus(@Param("status")String status); } diff --git a/src/main/java/net/gepafin/tendermanagement/repositories/DocumentRepository.java b/src/main/java/net/gepafin/tendermanagement/repositories/DocumentRepository.java index 4f621d38..b7fc2923 100644 --- a/src/main/java/net/gepafin/tendermanagement/repositories/DocumentRepository.java +++ b/src/main/java/net/gepafin/tendermanagement/repositories/DocumentRepository.java @@ -25,5 +25,7 @@ public interface DocumentRepository extends JpaRepository Optional findByIdAndSourceIdAndSourceAndIsDeletedFalse(Long id, Long sourceId, String source); + @Query("SELECT d FROM DocumentEntity d WHERE d.isDeleted = false") + List findAllByIsDeleteFalse(); } diff --git a/src/main/java/net/gepafin/tendermanagement/repositories/S3ConfigRepository.java b/src/main/java/net/gepafin/tendermanagement/repositories/S3ConfigRepository.java new file mode 100644 index 00000000..2349861c --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/repositories/S3ConfigRepository.java @@ -0,0 +1,24 @@ +package net.gepafin.tendermanagement.repositories; + +import net.gepafin.tendermanagement.entities.S3ConfigEntity; +import net.gepafin.tendermanagement.enums.DocOtherSourceTypeEnum; +import net.gepafin.tendermanagement.enums.DocumentSourceTypeEnum; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.stereotype.Repository; + +import java.util.Optional; + +@Repository +public interface S3ConfigRepository extends JpaRepository { + Optional getPathByType(String type); + + S3ConfigEntity findS3PathConfigurationById(Long id); + + String getBucketNameByType(DocumentSourceTypeEnum type); + + String getBucketNameByType(DocOtherSourceTypeEnum type); + + @Query("Select s3.parentFolder From S3ConfigEntity s3 Where s3.type = :s") + String getPathByTypeOther(String s); +} diff --git a/src/main/java/net/gepafin/tendermanagement/repositories/UserCompanyDelegationRepository.java b/src/main/java/net/gepafin/tendermanagement/repositories/UserCompanyDelegationRepository.java index 1224dd70..03067c80 100644 --- a/src/main/java/net/gepafin/tendermanagement/repositories/UserCompanyDelegationRepository.java +++ b/src/main/java/net/gepafin/tendermanagement/repositories/UserCompanyDelegationRepository.java @@ -2,9 +2,15 @@ package net.gepafin.tendermanagement.repositories; import org.springframework.data.jpa.repository.JpaRepository; import net.gepafin.tendermanagement.entities.UserCompanyDelegationEntity; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; + +import java.util.List; public interface UserCompanyDelegationRepository extends JpaRepository { UserCompanyDelegationEntity findByUserIdAndCompanyIdAndStatus(Long userId, Long companyId, String status); + @Query("SELECT d FROM UserCompanyDelegationEntity d where d.status = :status") + List findAllByStatus(@Param("status") String status); } diff --git a/src/main/java/net/gepafin/tendermanagement/service/S3ConfigService.java b/src/main/java/net/gepafin/tendermanagement/service/S3ConfigService.java new file mode 100644 index 00000000..d284e649 --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/service/S3ConfigService.java @@ -0,0 +1,19 @@ +package net.gepafin.tendermanagement.service; + +import net.gepafin.tendermanagement.entities.S3ConfigEntity; +import net.gepafin.tendermanagement.model.request.S3ConfigReq; +import net.gepafin.tendermanagement.model.response.S3ConfigBean; +import org.springframework.stereotype.Component; + +import java.util.Optional; + +@Component +public interface S3ConfigService { + S3ConfigBean addS3Path(S3ConfigReq s3Path); + + Optional getS3PathByType(String type); + + S3ConfigEntity deleteS3PathById(Long id); + + S3ConfigBean updateS3PathConfiguration(S3ConfigReq s3PathConfigurationReq, Long id); +} diff --git a/src/main/java/net/gepafin/tendermanagement/service/impl/DocumentServiceImpl.java b/src/main/java/net/gepafin/tendermanagement/service/impl/DocumentServiceImpl.java index 3b3fa310..235a1244 100644 --- a/src/main/java/net/gepafin/tendermanagement/service/impl/DocumentServiceImpl.java +++ b/src/main/java/net/gepafin/tendermanagement/service/impl/DocumentServiceImpl.java @@ -34,7 +34,7 @@ public class DocumentServiceImpl implements DocumentService { @Override public DocumentResponseBean updateDocument(HttpServletRequest httpServletRequest, Long documentId, MultipartFile file, DocumentTypeEnum documentTypeEnum) { - return documentDao.updateDocument(documentId,file,documentTypeEnum); + return documentDao.updateDocument(documentId, file,documentTypeEnum); } @Override diff --git a/src/main/java/net/gepafin/tendermanagement/service/impl/S3ConfigServiceImpl.java b/src/main/java/net/gepafin/tendermanagement/service/impl/S3ConfigServiceImpl.java new file mode 100644 index 00000000..5dfa22de --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/service/impl/S3ConfigServiceImpl.java @@ -0,0 +1,41 @@ +package net.gepafin.tendermanagement.service.impl; + +import jakarta.transaction.Transactional; +import net.gepafin.tendermanagement.dao.S3ConfigDao; +import net.gepafin.tendermanagement.entities.S3ConfigEntity; +import net.gepafin.tendermanagement.model.request.S3ConfigReq; +import net.gepafin.tendermanagement.model.response.S3ConfigBean; +import net.gepafin.tendermanagement.service.S3ConfigService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.Optional; + +@Service +public class S3ConfigServiceImpl implements S3ConfigService { + @Autowired + S3ConfigDao s3ConfigDao; + + @Override + public S3ConfigBean addS3Path(S3ConfigReq s3Path) { + + return s3ConfigDao.addS3Path(s3Path); + } + @Override + public Optional getS3PathByType(String type) { + + return s3ConfigDao.getS3PathByType(type); + } + @Override + @Transactional + public S3ConfigEntity deleteS3PathById(Long id) { + + return s3ConfigDao.deleteS3PathConfigById(id); + } + @Override + @Transactional + public S3ConfigBean updateS3PathConfiguration(S3ConfigReq s3PathConfigurationReq, Long id) { + + return s3ConfigDao.updateS3PathConfiguration(s3PathConfigurationReq, id); + } +} diff --git a/src/main/java/net/gepafin/tendermanagement/service/impl/S3ReUploadMigrationService.java b/src/main/java/net/gepafin/tendermanagement/service/impl/S3ReUploadMigrationService.java new file mode 100644 index 00000000..4db4ea12 --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/service/impl/S3ReUploadMigrationService.java @@ -0,0 +1,197 @@ +package net.gepafin.tendermanagement.service.impl; + +import com.amazonaws.AmazonServiceException; +import com.amazonaws.SdkClientException; +import com.amazonaws.services.s3.AmazonS3; +import com.amazonaws.services.s3.AmazonS3Client; +import com.amazonaws.services.s3.model.GetObjectRequest; +import com.amazonaws.services.s3.model.ObjectMetadata; +import lombok.extern.slf4j.Slf4j; +import net.gepafin.tendermanagement.dao.S3PathConfig; +import net.gepafin.tendermanagement.entities.DocumentEntity; +import net.gepafin.tendermanagement.enums.DocumentSourceTypeEnum; +import net.gepafin.tendermanagement.repositories.ApplicationRepository; +import net.gepafin.tendermanagement.repositories.ApplicationSignedDocumentRepository; +import net.gepafin.tendermanagement.repositories.DocumentRepository; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.List; + +@Slf4j +@Service +public class S3ReUploadMigrationService { + + private static final String OLD_BUCKET = "mementoresources"; + + private static final String SECURE_KEY = "267163962963"; + + @Autowired + private DocumentRepository documentRepository; + + @Autowired + private AmazonS3Client s3Client; + + @Autowired + private S3PathConfig s3ConfigBean; + + @Autowired + private ApplicationRepository applicationRepository; + + @Autowired + private ApplicationSignedDocumentRepository applicationSignedDocumentRepository; + + @Autowired + private AmazonS3 amazonS3; + + @Value("${aws.s3.url}") + private String s3Url; + + private boolean migrationCompleted = false; + + public String reUploadAndMigrateDocuments(String providedKey) { + + if (migrationCompleted) { + return "Migration already completed."; + } + + // Validate the provided key + if (!isValidKey(providedKey)) { + return "Invalid or missing migration key."; + } + + List documents = documentRepository.findAllByIsDeleteFalse(); + + if (documents.isEmpty()) { + return "No documents found to migrate."; + } + + for (DocumentEntity document : documents) { + String oldUrl = document.getFilePath(); // This should contain the full URL + log.info("Processing {}", oldUrl); + + try { + File localFile = downloadFileFromS3(oldUrl); + String newKey = generateNewS3Path(document); // Make sure this generates the correct new path + String uploadedPath = uploadFileToNewBucket(localFile, newKey); + updateDocumentPathAndDeleteOldEntry(document, uploadedPath); + } catch (Exception e) { + log.error("Error processing document {}: {}", document.getId(), e.getMessage()); + } + } + return "Migrated Successfully."; + } + + private boolean isValidKey(String providedKey) { + + return providedKey != null && providedKey.equals(SECURE_KEY); + } + + private File downloadFileFromS3(String fileUrl) throws Exception { + + String key = extractS3KeyFromUrl(fileUrl); // Get the S3 key from the URL + File localFile = new File("/tmp/" + extractFileName(key)); // Save file locally + + GetObjectRequest getObjectRequest = new GetObjectRequest(OLD_BUCKET, key); // Use the key + + try (InputStream s3Stream = s3Client.getObject(getObjectRequest).getObjectContent(); FileOutputStream outputStream = new FileOutputStream(localFile)) { + s3Stream.transferTo(outputStream); + } + + log.info("Downloaded file from old S3 bucket: {}", key); + return localFile; + } + + private String extractS3KeyFromUrl(String url) { + // Assuming the URL structure is consistent + return url.replace("https://mementoresources.s3.eu-west-1.amazonaws.com/", ""); + } + + private String uploadFileToNewBucket(File localFile, String s3Folder) { + + InputStream inputStream = null; // Declare the InputStream here for cleanup + try { + // Extract file name from the local file + String fileName = extractFileName(localFile.getAbsolutePath()); // Get the file name + String path = s3Folder + "/" + fileName; // Construct the S3 path + + // Create InputStream from the local file + inputStream = new FileInputStream(localFile); + + // Set up object metadata + ObjectMetadata objectMetadata = new ObjectMetadata(); + objectMetadata.setContentType("application/octet-stream"); + objectMetadata.setContentLength(localFile.length()); + + // Upload to S3 + s3Client.putObject(OLD_BUCKET, path, inputStream, objectMetadata); + + // Construct the full S3 URL + String fullUrl = String.format("https://%s.s3.%s.amazonaws.com/%s", OLD_BUCKET, "eu-west-1", path); + log.info("File '{}' uploaded successfully to Amazon S3 with URL: {}", fileName, fullUrl); + return fullUrl; + + } catch (IOException e) { + log.error("IOException occurred during file upload for '{}': {}", localFile.getName(), e.getMessage()); + throw new RuntimeException("Upload failed for: " + s3Folder + "/" + localFile.getName(), e); + } catch (AmazonServiceException e) { + log.error("Amazon service exception while uploading file '{}': {}", localFile.getName(), e.getMessage()); + throw new RuntimeException("Upload failed for: " + s3Folder + "/" + localFile.getName(), e); + } catch (SdkClientException e) { + log.error("SDK client exception while uploading file '{}': {}", localFile.getName(), e.getMessage()); + throw new RuntimeException("Upload failed for: " + s3Folder + "/" + localFile.getName(), e); + } finally { + // Close InputStream if it was opened + if (inputStream != null) { + try { + inputStream.close(); + } catch (IOException e) { + log.warn("Failed to close InputStream for file '{}': {}", localFile.getName(), e.getMessage()); + } + } + } + } + + private String generateNewS3Path(DocumentEntity document) { + + DocumentSourceTypeEnum sourceType = DocumentSourceTypeEnum.valueOf(document.getSource()); + Long callId; + + if (sourceType.equals(DocumentSourceTypeEnum.CALL)) { + return s3ConfigBean.generateDocumentPath(sourceType, document.getSourceId(), 0L); + } else { + callId = applicationRepository.findCallIdById(document.getSourceId()); + return s3ConfigBean.generateDocumentPath(sourceType, callId, document.getSourceId()); + } + } + + private String extractFileName(String filePath) { + + String[] parts = filePath.split("/"); + return parts[parts.length - 1]; + } + + + private void updateDocumentPathAndDeleteOldEntry(DocumentEntity document, String newPath) { + + String fileName = extractFileName(newPath); + DocumentEntity newDocument = new DocumentEntity(); + newDocument.setFilePath(newPath); + newDocument.setSource(document.getSource()); + newDocument.setType(document.getType()); + newDocument.setIsDeleted(false); + newDocument.setSourceId(document.getSourceId()); + newDocument.setFileName(fileName); + + documentRepository.save(newDocument); + documentRepository.delete(document); + + log.info("Migrated document ID: {} to new path: {}", document.getId(), newPath); + } +} diff --git a/src/main/java/net/gepafin/tendermanagement/service/impl/UserSignedAndDelegationServiceImpl.java b/src/main/java/net/gepafin/tendermanagement/service/impl/UserSignedAndDelegationServiceImpl.java new file mode 100644 index 00000000..c1228565 --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/service/impl/UserSignedAndDelegationServiceImpl.java @@ -0,0 +1,261 @@ +package net.gepafin.tendermanagement.service.impl; + +import com.amazonaws.AmazonServiceException; +import com.amazonaws.SdkClientException; +import com.amazonaws.services.s3.AmazonS3Client; +import com.amazonaws.services.s3.model.GetObjectRequest; +import com.amazonaws.services.s3.model.ObjectMetadata; +import lombok.extern.slf4j.Slf4j; +import net.gepafin.tendermanagement.dao.S3PathConfig; +import net.gepafin.tendermanagement.entities.ApplicationSignedDocumentEntity; +import net.gepafin.tendermanagement.entities.UserCompanyDelegationEntity; +import net.gepafin.tendermanagement.enums.DocOtherSourceTypeEnum; +import net.gepafin.tendermanagement.repositories.ApplicationRepository; +import net.gepafin.tendermanagement.repositories.ApplicationSignedDocumentRepository; +import net.gepafin.tendermanagement.repositories.S3ConfigRepository; +import net.gepafin.tendermanagement.repositories.UserCompanyDelegationRepository; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.List; + +@Slf4j +@Service +public class UserSignedAndDelegationServiceImpl { + private static final String OLD_BUCKET = "mementoresources"; + + private static final String NEW_BUCKET = "mementoresources"; + + private static final String SECURE_KEY = "267163962963"; + + @Autowired + private UserCompanyDelegationRepository userCompanyDelegationRepository; + + @Autowired + private AmazonS3Client s3Client; + + @Autowired + private S3PathConfig s3ConfigBean; + + @Autowired + private ApplicationSignedDocumentRepository applicationSignedDocumentRepository; + + @Autowired + ApplicationRepository applicationRepository; + + @Autowired + S3ConfigRepository s3ConfigRepository; + + @Value("${aws.s3.url}") + private String s3Url; + + private boolean migrationCompleted = false; + + + public String migrateUserDelegatedDocuments(String providedKey) { + + if (migrationCompleted) { + return "Migration already completed."; + } + + // Validate the provided key + if (isValidKey(providedKey)) { + return "Invalid or missing migration key."; + } + + List documents = userCompanyDelegationRepository.findAllByStatus("ACTIVE"); + + if (documents.isEmpty()) { + return "No documents found to migrate."; + } + + for (UserCompanyDelegationEntity document : documents) { + String oldUrl = document.getFilePath(); + log.info("Processing user designated document: {}", oldUrl); + + try { + File localFile = downloadFileFromS3(oldUrl); + String newKey = generateNewS3PathForDelegationDoc(); + String uploadedPath = uploadFileToNewBucket(localFile, newKey); + updateDelegatedDocumentPathAndDeleteOldEntry(document, uploadedPath); + } catch (Exception e) { + log.error("Error processing user designated document {}: {}", document.getId(), e.getMessage()); + } + } + return "Migrated"; + } + + + public String migrateUserSignedDocuments(String providedKey) { + + if (migrationCompleted) { + return "Migration already completed."; + } + + // Validate the provided key + if (isValidKey(providedKey)) { + return "Invalid or missing migration key."; + } + List documents = applicationSignedDocumentRepository.findAllByIsStatus("ACTIVE"); + + if (documents.isEmpty()) { + return "No documents found to migrate."; + } + + for (ApplicationSignedDocumentEntity document : documents) { + String oldUrl = document.getFilePath(); + log.info("Processing user signed document: {}", oldUrl); + + try { + File localFile = downloadFileFromS3(oldUrl); + String newKey = generateNewS3PathForUserSignedDoc(document); + String uploadedPath = uploadFileToNewBucket(localFile, newKey); + updateDocumentPathAndDeleteOldEntry(document, uploadedPath); + } catch (Exception e) { + log.error("Error processing user signed document {}: {}", document.getId(), e.getMessage()); + } + } + return "Migrated."; + } + + private boolean isValidKey(String providedKey) { + + return providedKey == null || !providedKey.equals(SECURE_KEY); + } + + private String generateNewS3PathForDelegationDoc() { + + return s3ConfigBean.generateDocumentPathForOther(DocOtherSourceTypeEnum.USER_DELEGATION, 0L, 0L); + } + + private String generateNewS3PathForUserSignedDoc(ApplicationSignedDocumentEntity document) { + // Fetch the list of application IDs associated with the document + List applicationIds = applicationSignedDocumentRepository.findApplicationIdIdsById(document.getId()); + List paths = new ArrayList<>(); + + // Loop through the application IDs and generate paths + for (Long applicationId : applicationIds) { + Long callId = applicationRepository.findCallIdById(applicationId); + + // Construct the path for the current application and call ID + String newPath = String.format("%s/call/call_%d/application/application_%d/user_signed_document", s3ConfigRepository.getPathByTypeOther( + String.valueOf(DocOtherSourceTypeEnum.USER_SIGNED_DOCUMENT)) , callId, applicationId); + + log.info("Generated new S3 path: {}", newPath); + paths.add(newPath); + } + + return String.join(",", paths); + } + + private File downloadFileFromS3(String fileUrl) throws Exception { + + String key = extractS3KeyFromUrl(fileUrl); + File localFile = new File("/tmp/" + extractFileName(key)); + + GetObjectRequest getObjectRequest = new GetObjectRequest(OLD_BUCKET, key); + + try (InputStream s3Stream = s3Client.getObject(getObjectRequest).getObjectContent(); FileOutputStream outputStream = new FileOutputStream(localFile)) { + s3Stream.transferTo(outputStream); + } + + log.info("Downloaded file from old S3 bucket: {}", key); + return localFile; + } + + private String extractS3KeyFromUrl(String url) { + + return url.replace("https://mementoresources.s3.eu-west-1.amazonaws.com/", ""); + } + + private String uploadFileToNewBucket(File localFile, String s3Path) { + + InputStream inputStream = null; + try { + String fileName = extractFileName(localFile.getAbsolutePath()); // Extract file name + String fullPath = String.format("%s/%s", s3Path, fileName); // Construct full path + + inputStream = new FileInputStream(localFile); // Create InputStream + + // Set metadata for the file + ObjectMetadata objectMetadata = new ObjectMetadata(); + objectMetadata.setContentLength(localFile.length()); + objectMetadata.setContentType("application/octet-stream"); + + // Upload the file to S3 with the constructed path + s3Client.putObject(NEW_BUCKET, fullPath, inputStream, objectMetadata); + + // Construct the full S3 URL for the uploaded file + String fullUrl = String.format("https://%s.s3.%s.amazonaws.com/%s", NEW_BUCKET, "eu-west-1", fullPath); + log.info("File '{}' uploaded successfully to Amazon S3 with URL: {}", fileName, fullUrl); + return fullUrl; + + } catch (IOException e) { + log.error("IOException occurred during file upload for '{}': {}", localFile.getName(), e.getMessage()); + throw new RuntimeException("Upload failed for: " + localFile, e); + } catch (AmazonServiceException e) { + log.error("Amazon service exception while uploading file '{}': {}", localFile.getName(), e.getMessage()); + throw new RuntimeException("Upload failed for: " + localFile, e); + } catch (SdkClientException e) { + log.error("SDK client exception while uploading file '{}': {}", localFile.getName(), e.getMessage()); + throw new RuntimeException("Upload failed for: " + localFile, e); + } finally { + if (inputStream != null) { + try { + inputStream.close(); + } catch (IOException e) { + log.warn("Failed to close InputStream for file '{}': {}", localFile.getName(), e.getMessage()); + } + } + } + } + + private String extractFileName(String filePath) { + + String[] parts = filePath.split("/"); + return parts[parts.length - 1]; + } + private String extractFileNameFromPath(String path) { + + return path.substring(path.lastIndexOf('/') + 1); + } + + private void updateDocumentPathAndDeleteOldEntry(ApplicationSignedDocumentEntity document, String newPath) { + + ApplicationSignedDocumentEntity newDocument = new ApplicationSignedDocumentEntity(); + String fileName = extractFileNameFromPath(newPath); + newDocument.setFilePath(newPath); + newDocument.setFileName(fileName); + newDocument.setApplication(document.getApplication()); + newDocument.setStatus("ACTIVE"); + + applicationSignedDocumentRepository.save(newDocument); + applicationSignedDocumentRepository.delete(document); + + log.info("Migrated document ID: {} to new path: {}", document.getId(), newPath); + } + + private void updateDelegatedDocumentPathAndDeleteOldEntry(UserCompanyDelegationEntity document, String newPath) { + + String fileName = extractFileNameFromPath(newPath); + UserCompanyDelegationEntity newDocument = new UserCompanyDelegationEntity(); + newDocument.setFilePath(newPath); + newDocument.setFileName(fileName); + newDocument.setBeneficiaryId(document.getBeneficiaryId()); + newDocument.setUserId(document.getUserId()); + newDocument.setCompanyId(document.getCompanyId()); + newDocument.setStatus("ACTIVE"); + + userCompanyDelegationRepository.save(newDocument); + userCompanyDelegationRepository.delete(document); + + log.info("Migrated document ID: {} to new path: {}", document.getId(), newPath); + } +} diff --git a/src/main/java/net/gepafin/tendermanagement/web/rest/api/S3ConfigApi.java b/src/main/java/net/gepafin/tendermanagement/web/rest/api/S3ConfigApi.java new file mode 100644 index 00000000..61b3bd6c --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/web/rest/api/S3ConfigApi.java @@ -0,0 +1,67 @@ +package net.gepafin.tendermanagement.web.rest.api; + +import io.swagger.v3.oas.annotations.Operation; +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.validation.Valid; +import net.gepafin.tendermanagement.entities.S3ConfigEntity; +import net.gepafin.tendermanagement.model.request.S3ConfigReq; +import net.gepafin.tendermanagement.model.response.S3ConfigBean; +import net.gepafin.tendermanagement.model.util.Response; +import net.gepafin.tendermanagement.web.rest.api.errors.ErrorConstants; +import org.springframework.data.repository.query.Param; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; + +import java.util.Optional; + +@Validated +public interface S3ConfigApi { + + @Operation(summary = "Api to create S3Path structure.", 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 = "", produces = { "application/json" }) + ResponseEntity> addS3Path(@Valid @RequestBody S3ConfigReq s3pathReq); + + @Operation(summary = "Api to get S3Path structure. by type", 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 = "", produces = { "application/json" }) + ResponseEntity>> getS3PathByType(@Valid @Param(value = "type") String type); + + @Operation(summary = "Api to delete S3Path structure. by id", 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) })) }) + @DeleteMapping(value = "", produces = { "application/json" }) + ResponseEntity> deleteS3PathConfigById(@Valid @Param(value = "id") Long id); + + @Operation(summary = "Api to update S3Path structure. by id", 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) })) }) + @PutMapping(value = "", produces = { "application/json" }) + ResponseEntity> updateS3PathConfigById(@Valid @RequestBody S3ConfigReq s3PathConfigurationReq, @Param(value = "id") Long id); +} diff --git a/src/main/java/net/gepafin/tendermanagement/web/rest/api/S3MigrationApi.java b/src/main/java/net/gepafin/tendermanagement/web/rest/api/S3MigrationApi.java new file mode 100644 index 00000000..4a4d3eb1 --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/web/rest/api/S3MigrationApi.java @@ -0,0 +1,28 @@ +package net.gepafin.tendermanagement.web.rest.api; + +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +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.validation.Valid; +import net.gepafin.tendermanagement.web.rest.api.errors.ErrorConstants; +import org.springframework.data.repository.query.Param; +import org.springframework.http.MediaType; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PutMapping; + +@Validated +public interface S3MigrationApi { + + @Operation(summary = "Api to migrate S3 doc to db and update s3 files as per specified folder.", 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) })) }) + @PutMapping(value = "/{key}", produces = { "application/json" }) + String reUploadAndMigrateDocuments(@Parameter(description = "The secret key", required = true) @PathVariable("key") String key); +} diff --git a/src/main/java/net/gepafin/tendermanagement/web/rest/api/UserSignedAndDelegationApi.java b/src/main/java/net/gepafin/tendermanagement/web/rest/api/UserSignedAndDelegationApi.java new file mode 100644 index 00000000..2a3978a1 --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/web/rest/api/UserSignedAndDelegationApi.java @@ -0,0 +1,38 @@ +package net.gepafin.tendermanagement.web.rest.api; + +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +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.validation.Valid; +import net.gepafin.tendermanagement.web.rest.api.errors.ErrorConstants; +import org.springframework.data.repository.query.Param; +import org.springframework.http.MediaType; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; + +@Validated +public interface UserSignedAndDelegationApi { + @Operation(summary = "Api to migrate S3 doc to db and user-delegated folder", 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 = "/{key}", produces = { "application/json" }) + String migrateUserDelegatedDocuments(@Parameter(description = "The secret key", required = true) @PathVariable("key") String key); + + @Operation(summary = "Api to migrate S3 doc to user-signed.", 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 = "/{key}", produces = { "application/json" }) + String migrateUserSignedDocuments(@Parameter(description = "The secret key", required = true) @PathVariable("key") String key); +} diff --git a/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/DocumentApiController.java b/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/DocumentApiController.java index 7141a256..34caa9fd 100644 --- a/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/DocumentApiController.java +++ b/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/DocumentApiController.java @@ -31,7 +31,7 @@ DocumentApiController implements DocumentApi { public ResponseEntity>> uploadFile(HttpServletRequest httpServletRequest, Long sourceId, DocumentSourceTypeEnum sourceType, List files, DocumentTypeEnum fileType) { try { - List responseBeans = documentService.uploadFile(files, sourceId,sourceType, fileType); + List responseBeans = documentService.uploadFile(files, sourceId, sourceType, fileType); return ResponseEntity.status(HttpStatus.CREATED) .body(new Response>(responseBeans, Status.SUCCESS, Translator.toLocale(GepafinConstant.FILES_UPLOADED_MSG))); } catch (CustomValidationException ex) { diff --git a/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/S3ConfigController.java b/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/S3ConfigController.java new file mode 100644 index 00000000..62f12414 --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/S3ConfigController.java @@ -0,0 +1,59 @@ +package net.gepafin.tendermanagement.web.rest.api.impl; + +import net.gepafin.tendermanagement.config.Translator; +import net.gepafin.tendermanagement.constants.GepafinConstant; +import net.gepafin.tendermanagement.entities.S3ConfigEntity; +import net.gepafin.tendermanagement.model.request.S3ConfigReq; +import net.gepafin.tendermanagement.model.response.S3ConfigBean; +import net.gepafin.tendermanagement.model.util.Response; +import net.gepafin.tendermanagement.service.S3ConfigService; +import net.gepafin.tendermanagement.web.rest.api.S3ConfigApi; +import net.gepafin.tendermanagement.web.rest.api.errors.Status; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.util.Optional; + +@RestController +@RequestMapping("${openapi.gepafin.base-path:/v1/s3-path-config}") +public class S3ConfigController implements S3ConfigApi { + + private static final Logger log = LoggerFactory.getLogger(S3ConfigController.class); + + @Autowired + S3ConfigService s3PathService; + + @Override + public ResponseEntity> addS3Path(S3ConfigReq s3pathReq) { + + log.info("Request Body : {}, {}, {}", s3pathReq.getPath(), s3pathReq.getType(), s3pathReq.getBucketName()); + S3ConfigBean s3Path = s3PathService.addS3Path(s3pathReq); + return ResponseEntity.status(HttpStatus.CREATED).body(new Response(s3Path, Status.SUCCESS, Translator.toLocale(GepafinConstant.ADDED_S3_PATH_STRUCTURE))); + } + @Override + public ResponseEntity>> getS3PathByType(String type) { + + log.info("Request to get S3Path by type {}", type); + Optional s3Path = s3PathService.getS3PathByType(type); + return ResponseEntity.status(HttpStatus.OK) + .body(new Response>(s3Path, Status.SUCCESS, Translator.toLocale(GepafinConstant.S3_PATH_STRUCTURE_BY_TYPE))); + } + @Override + public ResponseEntity> deleteS3PathConfigById(Long id) { + log.info("Request to delete S3Path by Id {}", id); + S3ConfigEntity deletedS3PathConfig = s3PathService.deleteS3PathById(id); + return ResponseEntity.status(HttpStatus.OK) + .body(new Response(deletedS3PathConfig, Status.SUCCESS, Translator.toLocale(GepafinConstant.S3_PATH_DELETE_MSG))); + } + @Override + public ResponseEntity> updateS3PathConfigById(S3ConfigReq s3PathConfigurationReq, Long id) { + S3ConfigBean updatedS3PathConfiguration = s3PathService.updateS3PathConfiguration(s3PathConfigurationReq, id); + return ResponseEntity.status(HttpStatus.OK) + .body(new Response(updatedS3PathConfiguration, Status.SUCCESS, Translator.toLocale(GepafinConstant.S3_PATH_CONFIG_UPDATE_MSG))); + } +} diff --git a/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/S3MigrationApiController.java b/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/S3MigrationApiController.java new file mode 100644 index 00000000..7e58800e --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/S3MigrationApiController.java @@ -0,0 +1,19 @@ +package net.gepafin.tendermanagement.web.rest.api.impl; + +import net.gepafin.tendermanagement.service.impl.S3ReUploadMigrationService; +import net.gepafin.tendermanagement.web.rest.api.S3MigrationApi; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("${openapi.gepafin.base-path:/v1/s3-migration}") +public class S3MigrationApiController implements S3MigrationApi { + + @Autowired + S3ReUploadMigrationService s3MigrationService; + @Override + public String reUploadAndMigrateDocuments(String providedKey) { + return s3MigrationService.reUploadAndMigrateDocuments(providedKey); + } +} diff --git a/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/S3UserSignedAndDelegationMigrationController.java b/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/S3UserSignedAndDelegationMigrationController.java new file mode 100644 index 00000000..061b731b --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/S3UserSignedAndDelegationMigrationController.java @@ -0,0 +1,24 @@ +package net.gepafin.tendermanagement.web.rest.api.impl; + +import net.gepafin.tendermanagement.service.impl.UserSignedAndDelegationServiceImpl; +import net.gepafin.tendermanagement.web.rest.api.UserSignedAndDelegationApi; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("${openapi.gepafin.base-path:/v1/s3-user-signed-and-delegation-migration}") +public class S3UserSignedAndDelegationMigrationController implements UserSignedAndDelegationApi { + + @Autowired + UserSignedAndDelegationServiceImpl userSignedAndDelegationService; + + @Override + public String migrateUserDelegatedDocuments(String providedKey) { + return userSignedAndDelegationService.migrateUserDelegatedDocuments(providedKey); + } + @Override + public String migrateUserSignedDocuments(String providedKey) { + return userSignedAndDelegationService.migrateUserSignedDocuments(providedKey); + } +} 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 41a10a1b..6dd0fdb1 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 @@ -67,7 +67,7 @@ - + @@ -83,7 +83,7 @@ - + @@ -101,18 +101,18 @@ - - + + - - + + - - + + @@ -122,19 +122,19 @@ - + - + - + - + - + @@ -250,7 +250,8 @@ - + + @@ -270,34 +271,39 @@ - + + - + - + - + + + - - - + + - + @@ -318,7 +324,8 @@ - + @@ -329,7 +336,8 @@ - + @@ -340,7 +348,8 @@ - + @@ -351,7 +360,8 @@ - + @@ -416,7 +426,8 @@ - + + @@ -432,7 +443,8 @@ - + + @@ -454,50 +466,50 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -507,62 +519,62 @@ + path="db/dump/inserted_form_field_data_30_08_2024.sql"/> select setval('gepafin_schema.form_field_id_seq', (select max(id)+1 from gepafin_schema.form_field), false) - - - - - - - - - - + + + + + + + + + + + references="lookup_data(id)"/> - - - - + + + + TRUNCATE TABLE FORM_FIELD RESTART IDENTITY; + path="db/dump/update_form_field_data_04_09_2024.sql"/> - - - - - - - - - - - - - - + + + + + + + + + + + + + + @@ -586,23 +598,26 @@ - + + - + - + - + - + + @@ -618,9 +633,10 @@ - + + - + @@ -634,12 +650,13 @@ - + + - + - + @@ -658,18 +675,20 @@ - + - + + - + @@ -693,7 +712,7 @@ TRUNCATE TABLE FORM_FIELD RESTART IDENTITY; + path="classpath:db/dump/inserted_form_field_data_13_09_2024.sql"/> @@ -708,7 +727,7 @@ + path="classpath:db/dump/updated_form_field_data_16-09-2024.sql"/> @@ -739,16 +758,16 @@ $$; - - - - - - - - - - + + + + + + + + + + @@ -783,99 +802,99 @@ - - - - - - - - - - - - - - + + + + + + + + + + + + + + - - - - - - - - - - - - - - + + + + + + + + + + + + + + - + - + id = 13 - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - + + + + + - - - - + + + + - - + + - + - + @@ -890,25 +909,25 @@ - + - - - + + + - - - - + + + + - + - + @@ -924,8 +943,8 @@ - - + + @@ -934,48 +953,48 @@ + path="classpath:db/dump/updated_form_field_data_03-10-2024.sql"/> - + - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -983,7 +1002,7 @@ + path="classpath:db/dump/updated_form_field_data_03-10-2024_1.sql"/> @@ -994,8 +1013,8 @@ - - + + @@ -1003,16 +1022,16 @@ - - + + + primaryKeyName="protocol_pkey"/> @@ -1058,132 +1077,132 @@ - - - - + + + + + primaryKeyName="system_email_template_pkey"/> - - - - - - - - - - + + + + + + + + + + - - - - - + + + + + - - - - - - - - - - - - - + + + + + + + + + + + + + - + - - - - - name='table' - - + + + + + name='table' + + + path="db/dump/update_system_email_template_of_application_submission.sql"/> - + + primaryKeyName="login_attempt_pkey"/> - - + + - - + + - + - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + - + - + + primaryKeyName="criteria_form_field_pkey"/> - - - - + + + + - - - - + + + + - + @@ -1226,9 +1245,10 @@ - + - + @@ -1244,47 +1264,44 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - @@ -1293,12 +1310,12 @@ - + - - + + @@ -1315,9 +1332,9 @@ - + - + @@ -1392,6 +1409,79 @@ referencedColumnNames="id" constraintName="fk_application_hub" /> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From 4e90401ad26fdd093e80392700193af2da9b1982 Mon Sep 17 00:00:00 2001 From: piyuskag Date: Mon, 28 Oct 2024 11:22:48 +0530 Subject: [PATCH 07/23] document code updation. --- .../impl/S3ReUploadMigrationService.java | 18 +++------ .../UserSignedAndDelegationServiceImpl.java | 40 ++++++------------- .../db/changelog/db.changelog-1.0.0.xml | 10 ++--- 3 files changed, 22 insertions(+), 46 deletions(-) diff --git a/src/main/java/net/gepafin/tendermanagement/service/impl/S3ReUploadMigrationService.java b/src/main/java/net/gepafin/tendermanagement/service/impl/S3ReUploadMigrationService.java index 4db4ea12..4bc59150 100644 --- a/src/main/java/net/gepafin/tendermanagement/service/impl/S3ReUploadMigrationService.java +++ b/src/main/java/net/gepafin/tendermanagement/service/impl/S3ReUploadMigrationService.java @@ -80,7 +80,7 @@ public class S3ReUploadMigrationService { File localFile = downloadFileFromS3(oldUrl); String newKey = generateNewS3Path(document); // Make sure this generates the correct new path String uploadedPath = uploadFileToNewBucket(localFile, newKey); - updateDocumentPathAndDeleteOldEntry(document, uploadedPath); + updateDocumentPathAndNameEntry(document, uploadedPath); } catch (Exception e) { log.error("Error processing document {}: {}", document.getId(), e.getMessage()); } @@ -178,20 +178,12 @@ public class S3ReUploadMigrationService { } - private void updateDocumentPathAndDeleteOldEntry(DocumentEntity document, String newPath) { + private void updateDocumentPathAndNameEntry(DocumentEntity document, String newPath) { String fileName = extractFileName(newPath); - DocumentEntity newDocument = new DocumentEntity(); - newDocument.setFilePath(newPath); - newDocument.setSource(document.getSource()); - newDocument.setType(document.getType()); - newDocument.setIsDeleted(false); - newDocument.setSourceId(document.getSourceId()); - newDocument.setFileName(fileName); - - documentRepository.save(newDocument); - documentRepository.delete(document); - + document.setFilePath(newPath); + document.setFileName(fileName); + documentRepository.save(document); log.info("Migrated document ID: {} to new path: {}", document.getId(), newPath); } } diff --git a/src/main/java/net/gepafin/tendermanagement/service/impl/UserSignedAndDelegationServiceImpl.java b/src/main/java/net/gepafin/tendermanagement/service/impl/UserSignedAndDelegationServiceImpl.java index c1228565..dbd54afd 100644 --- a/src/main/java/net/gepafin/tendermanagement/service/impl/UserSignedAndDelegationServiceImpl.java +++ b/src/main/java/net/gepafin/tendermanagement/service/impl/UserSignedAndDelegationServiceImpl.java @@ -32,7 +32,7 @@ public class UserSignedAndDelegationServiceImpl { private static final String OLD_BUCKET = "mementoresources"; private static final String NEW_BUCKET = "mementoresources"; - + private static final String SECURE_KEY = "267163962963"; @Autowired @@ -49,7 +49,7 @@ public class UserSignedAndDelegationServiceImpl { @Autowired ApplicationRepository applicationRepository; - + @Autowired S3ConfigRepository s3ConfigRepository; @@ -58,7 +58,6 @@ public class UserSignedAndDelegationServiceImpl { private boolean migrationCompleted = false; - public String migrateUserDelegatedDocuments(String providedKey) { if (migrationCompleted) { @@ -84,7 +83,7 @@ public class UserSignedAndDelegationServiceImpl { File localFile = downloadFileFromS3(oldUrl); String newKey = generateNewS3PathForDelegationDoc(); String uploadedPath = uploadFileToNewBucket(localFile, newKey); - updateDelegatedDocumentPathAndDeleteOldEntry(document, uploadedPath); + updateDelegatedDocumentPathAndNameEntry(document, uploadedPath); } catch (Exception e) { log.error("Error processing user designated document {}: {}", document.getId(), e.getMessage()); } @@ -92,7 +91,6 @@ public class UserSignedAndDelegationServiceImpl { return "Migrated"; } - public String migrateUserSignedDocuments(String providedKey) { if (migrationCompleted) { @@ -117,7 +115,7 @@ public class UserSignedAndDelegationServiceImpl { File localFile = downloadFileFromS3(oldUrl); String newKey = generateNewS3PathForUserSignedDoc(document); String uploadedPath = uploadFileToNewBucket(localFile, newKey); - updateDocumentPathAndDeleteOldEntry(document, uploadedPath); + updateDocumentPathAndNameEntry(document, uploadedPath); } catch (Exception e) { log.error("Error processing user signed document {}: {}", document.getId(), e.getMessage()); } @@ -227,35 +225,21 @@ public class UserSignedAndDelegationServiceImpl { return path.substring(path.lastIndexOf('/') + 1); } - private void updateDocumentPathAndDeleteOldEntry(ApplicationSignedDocumentEntity document, String newPath) { + private void updateDocumentPathAndNameEntry(ApplicationSignedDocumentEntity document, String newPath) { - ApplicationSignedDocumentEntity newDocument = new ApplicationSignedDocumentEntity(); String fileName = extractFileNameFromPath(newPath); - newDocument.setFilePath(newPath); - newDocument.setFileName(fileName); - newDocument.setApplication(document.getApplication()); - newDocument.setStatus("ACTIVE"); - - applicationSignedDocumentRepository.save(newDocument); - applicationSignedDocumentRepository.delete(document); - + document.setFilePath(newPath); + document.setFileName(fileName); + applicationSignedDocumentRepository.save(document); log.info("Migrated document ID: {} to new path: {}", document.getId(), newPath); } - private void updateDelegatedDocumentPathAndDeleteOldEntry(UserCompanyDelegationEntity document, String newPath) { + private void updateDelegatedDocumentPathAndNameEntry(UserCompanyDelegationEntity document, String newPath) { String fileName = extractFileNameFromPath(newPath); - UserCompanyDelegationEntity newDocument = new UserCompanyDelegationEntity(); - newDocument.setFilePath(newPath); - newDocument.setFileName(fileName); - newDocument.setBeneficiaryId(document.getBeneficiaryId()); - newDocument.setUserId(document.getUserId()); - newDocument.setCompanyId(document.getCompanyId()); - newDocument.setStatus("ACTIVE"); - - userCompanyDelegationRepository.save(newDocument); - userCompanyDelegationRepository.delete(document); - + document.setFilePath(newPath); + document.setFileName(fileName); + userCompanyDelegationRepository.save(document); log.info("Migrated document ID: {} to new path: {}", document.getId(), newPath); } } 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 6dd0fdb1..73ad16f7 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 @@ -1443,7 +1443,7 @@ - + @@ -1452,7 +1452,7 @@ - + @@ -1461,7 +1461,7 @@ - + @@ -1470,7 +1470,7 @@ - + @@ -1479,7 +1479,7 @@ - + From 6aea90c6eceaeb86dff9c7fde5d4284c8c6ceb37 Mon Sep 17 00:00:00 2001 From: nisha Date: Mon, 28 Oct 2024 18:11:41 +0530 Subject: [PATCH 08/23] Updated code for pdf tabel updation --- .../gepafin/tendermanagement/dao/PdfDao.java | 166 +++++++++--------- .../gepafin/tendermanagement/util/Utils.java | 26 +++ 2 files changed, 112 insertions(+), 80 deletions(-) diff --git a/src/main/java/net/gepafin/tendermanagement/dao/PdfDao.java b/src/main/java/net/gepafin/tendermanagement/dao/PdfDao.java index a2c03a5b..702c61d1 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/PdfDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/PdfDao.java @@ -16,6 +16,7 @@ import net.gepafin.tendermanagement.model.response.*; import net.gepafin.tendermanagement.service.CallService; import net.gepafin.tendermanagement.util.Utils; import net.gepafin.tendermanagement.util.Validator; +import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -91,73 +92,73 @@ public class PdfDao { Font boldSmallFont = new Font(Font.FontFamily.HELVETICA, 10, Font.BOLD,new BaseColor(105, 105, 105)); // Adding the "Documenti Allegati" section title - document.add(new Paragraph(" ")); - -// pageEvent.setTotalPages(writer.getPageNumber()); - document.newPage(); -// pageEvent.setTotalPages(writer.getPageNumber()); - document.add(new Paragraph("Documenti Allegati", sectionFont)); - document.add(new Paragraph(" ")); - - -// 1. Autocertificazione possesso Requisiti - Paragraph p1 = new Paragraph(); - p1.add(new Chunk("1. ", boldSmallFont)); - p1.add(new Chunk("Autocertificazione possesso Requisiti ", boldSmallFont)); - p1.add(new Chunk("ai sensi degli artt. 46 e 47 del DPR 445/2000", smallFont)); - document.add(p1); - document.add(new Paragraph(" ")); - - - -// 2. Informativa Privacy relativa al trattamento dei dati personali - Paragraph p2 = new Paragraph(); - p2.add(new Chunk("2. ", boldSmallFont)); - p2.add(new Chunk("Informativa Privacy relativa al trattamento dei dati personali", boldSmallFont)); - document.add(p2); - document.add(new Paragraph(" ")); - - -// 3. Dati richiesti per la valutazione dell’adeguatezza dei flussi finanziari - Paragraph p3 = new Paragraph(); - p3.add(new Chunk("3. ", boldSmallFont)); - p3.add(new Chunk("Dati richiesti per la valutazione dell’adeguatezza dei flussi finanziari prospettici come da tabella di cui all’Appendice 9", boldSmallFont)); - document.add(p3); - document.add(new Paragraph(" ")); - - -// 4. Rilevazione Centrale dei Rischi - Paragraph p4 = new Paragraph(); - p4.add(new Chunk("4. ", boldSmallFont)); - p4.add(new Chunk("Rilevazione Centrale dei Rischi riferita agli ultimi 36 mesi disponibili alla data di presentazione della Domanda", boldSmallFont)); - document.add(p4); - document.add(new Paragraph(" ")); - - -// 5. Schema di presentazione dei dati di bilancio - Paragraph p5 = new Paragraph(); - p5.add(new Chunk("5. ", boldSmallFont)); - p5.add(new Chunk("Schema di presentazione dei dati di bilancio", boldSmallFont)); - document.add(p5); - document.add(new Paragraph(" ")); - - -// 6. Dettagli bilanci in forma abbreviata - Paragraph p6 = new Paragraph(); - p6.add(new Chunk("6. ", boldSmallFont)); - p6.add(new Chunk("Dettagli bilanci in forma abbreviata", boldSmallFont)); - document.add(p6); - document.add(new Paragraph(" ")); - - -// 7. Relazione aziendale illustrativa - Paragraph p7 = new Paragraph(); - p7.add(new Chunk("7. ", boldSmallFont)); - p7.add(new Chunk("Relazione aziendale illustrativa", boldSmallFont)); - document.add(p7); - document.add(new Paragraph(" ")); - - addColoredLines(writer,document,greenColor); +// document.add(new Paragraph(" ")); +// +//// pageEvent.setTotalPages(writer.getPageNumber()); +// document.newPage(); +//// pageEvent.setTotalPages(writer.getPageNumber()); +// document.add(new Paragraph("Documenti Allegati", sectionFont)); +// document.add(new Paragraph(" ")); +// +// +//// 1. Autocertificazione possesso Requisiti +// Paragraph p1 = new Paragraph(); +// p1.add(new Chunk("1. ", boldSmallFont)); +// p1.add(new Chunk("Autocertificazione possesso Requisiti ", boldSmallFont)); +// p1.add(new Chunk("ai sensi degli artt. 46 e 47 del DPR 445/2000", smallFont)); +// document.add(p1); +// document.add(new Paragraph(" ")); +// +// +// +//// 2. Informativa Privacy relativa al trattamento dei dati personali +// Paragraph p2 = new Paragraph(); +// p2.add(new Chunk("2. ", boldSmallFont)); +// p2.add(new Chunk("Informativa Privacy relativa al trattamento dei dati personali", boldSmallFont)); +// document.add(p2); +// document.add(new Paragraph(" ")); +// +// +//// 3. Dati richiesti per la valutazione dell’adeguatezza dei flussi finanziari +// Paragraph p3 = new Paragraph(); +// p3.add(new Chunk("3. ", boldSmallFont)); +// p3.add(new Chunk("Dati richiesti per la valutazione dell’adeguatezza dei flussi finanziari prospettici come da tabella di cui all’Appendice 9", boldSmallFont)); +// document.add(p3); +// document.add(new Paragraph(" ")); +// +// +//// 4. Rilevazione Centrale dei Rischi +// Paragraph p4 = new Paragraph(); +// p4.add(new Chunk("4. ", boldSmallFont)); +// p4.add(new Chunk("Rilevazione Centrale dei Rischi riferita agli ultimi 36 mesi disponibili alla data di presentazione della Domanda", boldSmallFont)); +// document.add(p4); +// document.add(new Paragraph(" ")); +// +// +//// 5. Schema di presentazione dei dati di bilancio +// Paragraph p5 = new Paragraph(); +// p5.add(new Chunk("5. ", boldSmallFont)); +// p5.add(new Chunk("Schema di presentazione dei dati di bilancio", boldSmallFont)); +// document.add(p5); +// document.add(new Paragraph(" ")); +// +// +//// 6. Dettagli bilanci in forma abbreviata +// Paragraph p6 = new Paragraph(); +// p6.add(new Chunk("6. ", boldSmallFont)); +// p6.add(new Chunk("Dettagli bilanci in forma abbreviata", boldSmallFont)); +// document.add(p6); +// document.add(new Paragraph(" ")); +// +// +//// 7. Relazione aziendale illustrativa +// Paragraph p7 = new Paragraph(); +// p7.add(new Chunk("7. ", boldSmallFont)); +// p7.add(new Chunk("Relazione aziendale illustrativa", boldSmallFont)); +// document.add(p7); +// document.add(new Paragraph(" ")); +// +// addColoredLines(writer,document,greenColor); document.close(); @@ -272,14 +273,17 @@ public class PdfDao { document.add(valueTable); } else { - PdfPCell valueCell = new PdfPCell(new Phrase(String.valueOf(value), valueFont)); + String fieldValue1= (String) value; + if(Utils.isValidDateString(fieldValue1)){ + fieldValue1=Utils.formatDateString(String.valueOf(value)); + } + PdfPCell valueCell = new PdfPCell(new Phrase(fieldValue1, valueFont)); valueCell.setPadding(5f); // Increase padding for better spacing valueCell.setPaddingLeft(leftMargin); // Increase left margin for value valueCell.setBorder(Rectangle.NO_BORDER); // Remove border for value cell valueCell.setMinimumHeight(30f); valueCell.setVerticalAlignment(Element.ALIGN_MIDDLE); valueCell.setCellEvent(new RoundedCorners()); // Apply rounded corners - valueTable.addCell(valueCell); document.add(valueTable); } @@ -356,6 +360,7 @@ public class PdfDao { PdfPCell headerCell = new PdfPCell(new Phrase(headerValue)); // Create a new PdfPCell for the header headerCell.setHorizontalAlignment(Element.ALIGN_CENTER); // Center align headerCell.setVerticalAlignment(Element.ALIGN_MIDDLE); + headerCell.setFixedHeight(rowHeight); headerCell.setBackgroundColor(new BaseColor(178, 190, 181)); // Light gray background for header table.addCell(headerCell); // Add the header cell to the table @@ -364,16 +369,15 @@ public class PdfDao { } // Add data rows matching stateFieldMap keys - for (Map.Entry stateField : stateFieldMap.entrySet()) { - for (String key : orderedKeys) { // Iterate over the ordered keys - Object value = row.getOrDefault(key, ""); // Fetch value or use empty string if key not present - PdfPCell dynamicCell = new PdfPCell(new Phrase(value != null ? value.toString() : "", textFont)); - dynamicCell.setBackgroundColor(new BaseColor(239, 243, 248)); // Light blue for the cell - dynamicCell.setMinimumHeight(rowHeight); - dynamicCell.setPadding(7f); + for (String key : orderedKeys) { + Object value = row.getOrDefault(key, ""); // Fetch value or use empty string if key not present + PdfPCell dataCell = new PdfPCell(new Phrase(value != null ? value.toString() : "", textFont)); + dataCell.setBackgroundColor(new BaseColor(239, 243, 248)); // Light blue for the cell + dataCell.setMinimumHeight(rowHeight); + dataCell.setFixedHeight(rowHeight); + dataCell.setPadding(7f); - table.addCell(dynamicCell); // Add the dynamically created cell to the table - } + table.addCell(dataCell); // Add the cell to the table } // Check if adding another row would exceed max height @@ -485,7 +489,7 @@ public class PdfDao { } fieldValue = matchedLabels; } - + // Further processing of field value (e.g., finding labels in options) fieldValue = findLabelInOptions(content.getSettings(), fieldValue); } else { @@ -494,7 +498,9 @@ public class PdfDao { } try { - addLabelValuePair(writer,document, contentLabel, fieldValue, labelFont,valueFont,content); + if((contentLabel!=null && Boolean.FALSE.equals(contentLabel.isEmpty())) || (fieldValue!=null && !StringUtils.isEmpty((CharSequence) fieldValue))) { + addLabelValuePair(writer, document, contentLabel, fieldValue, labelFont, valueFont, content); + } } catch (DocumentException e) { log.error("Error checking object: " + e.getMessage(), e); diff --git a/src/main/java/net/gepafin/tendermanagement/util/Utils.java b/src/main/java/net/gepafin/tendermanagement/util/Utils.java index a845aaad..1c86aa6b 100644 --- a/src/main/java/net/gepafin/tendermanagement/util/Utils.java +++ b/src/main/java/net/gepafin/tendermanagement/util/Utils.java @@ -4,12 +4,18 @@ import java.lang.reflect.Field; import java.lang.reflect.Type; import java.nio.charset.StandardCharsets; import java.security.SecureRandom; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.time.LocalDate; +import java.time.format.DateTimeFormatter; +import java.time.format.DateTimeParseException; import java.util.*; import java.util.function.Consumer; import java.util.function.Supplier; import java.util.regex.Pattern; import java.util.stream.Collectors; +import com.itextpdf.styledxmlparser.jsoup.Jsoup; import jakarta.servlet.http.HttpServletRequest; import org.apache.commons.collections4.MapUtils; import org.slf4j.Logger; @@ -369,5 +375,25 @@ public class Utils { throw new RuntimeException("Error converting map to string", e); } } + public static boolean isValidDateString(String dateStr) { + Pattern datePattern = Pattern.compile("\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}"); + return datePattern.matcher(dateStr).matches(); + } + // Method to convert a valid date string to the "dd-MM-yyyy" format + public static String formatDateString(String dateStr) { + String originalFormatPattern = "yyyy-MM-dd'T'HH:mm:ss"; + String targetFormatPattern = "dd-MM-yyyy"; + + try { + SimpleDateFormat originalFormat = new SimpleDateFormat(originalFormatPattern); + Date date = originalFormat.parse(dateStr); + SimpleDateFormat targetFormat = new SimpleDateFormat(targetFormatPattern); + + return targetFormat.format(date); + } catch (ParseException e) { + log.error("error while prcoessing date formate"); + return null; + } + } } From fc6293b3d386b1d8a27b2954ff2a6e4b6ecaa3da Mon Sep 17 00:00:00 2001 From: rajesh Date: Mon, 28 Oct 2024 19:54:35 +0530 Subject: [PATCH 09/23] updated pdf code --- src/main/java/net/gepafin/tendermanagement/dao/PdfDao.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/net/gepafin/tendermanagement/dao/PdfDao.java b/src/main/java/net/gepafin/tendermanagement/dao/PdfDao.java index 702c61d1..4318127e 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/PdfDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/PdfDao.java @@ -465,7 +465,7 @@ public class PdfDao { .collect(Collectors.toList()); fieldValue = names; } - } else if (name.equals("checkboxes")) { + } else if (name.equals("checkboxes") && fieldValue instanceof List) { List check = (List) fieldValue; List settingResponseBeans = content.getSettings(); List matchedLabels = new ArrayList<>(); From 564d5d5dd2e602feaee53c233e3349a03dbb7a1c Mon Sep 17 00:00:00 2001 From: nisha Date: Mon, 28 Oct 2024 20:07:11 +0530 Subject: [PATCH 10/23] Updated code for pdf table issue --- .../gepafin/tendermanagement/dao/PdfDao.java | 29 ++++++++++++------- .../gepafin/tendermanagement/util/Utils.java | 27 +++++++++++++++++ 2 files changed, 46 insertions(+), 10 deletions(-) diff --git a/src/main/java/net/gepafin/tendermanagement/dao/PdfDao.java b/src/main/java/net/gepafin/tendermanagement/dao/PdfDao.java index 4318127e..2cf1d32b 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/PdfDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/PdfDao.java @@ -277,6 +277,9 @@ public class PdfDao { if(Utils.isValidDateString(fieldValue1)){ fieldValue1=Utils.formatDateString(String.valueOf(value)); } + if(Boolean.TRUE.equals(Utils.isItalianFormattedAmount(fieldValue)) ){ + fieldValue= String.valueOf(Utils.convertItalianAmountToDouble(fieldValue)); + } PdfPCell valueCell = new PdfPCell(new Phrase(fieldValue1, valueFont)); valueCell.setPadding(5f); // Increase padding for better spacing valueCell.setPaddingLeft(leftMargin); // Increase left margin for value @@ -352,7 +355,6 @@ public class PdfDao { List orderedKeys = new ArrayList<>(trueKeys); orderedKeys.addAll(falseKeys); // Iterate through extracted data to populate the table - for (Map row : extractedData) { // Add headers once if (!headersAdded) { for (String key : orderedKeys) { @@ -369,16 +371,23 @@ public class PdfDao { } // Add data rows matching stateFieldMap keys - for (String key : orderedKeys) { - Object value = row.getOrDefault(key, ""); // Fetch value or use empty string if key not present - PdfPCell dataCell = new PdfPCell(new Phrase(value != null ? value.toString() : "", textFont)); - dataCell.setBackgroundColor(new BaseColor(239, 243, 248)); // Light blue for the cell - dataCell.setMinimumHeight(rowHeight); - dataCell.setFixedHeight(rowHeight); - dataCell.setPadding(7f); + for (Map row : extractedData) { + // Add data rows matching stateFieldMap keys + for (String key : orderedKeys) { + if (stateFieldMap.containsKey(key)) { // Only add data cell if key is in stateFieldMap + Object value = row.getOrDefault(key, ""); // Fetch value or use empty string if key not present + String fieldValue= (String) value; + if(Boolean.TRUE.equals(Utils.isItalianFormattedAmount(fieldValue)) ){ + fieldValue= String.valueOf(Utils.convertItalianAmountToDouble(fieldValue)); + } + PdfPCell dataCell = new PdfPCell(new Phrase(fieldValue != null ?fieldValue: "", textFont)); + dataCell.setBackgroundColor(new BaseColor(239, 243, 248)); // Light blue for the cell + dataCell.setMinimumHeight(rowHeight); + dataCell.setPadding(7f); - table.addCell(dataCell); // Add the cell to the table - } + table.addCell(dataCell); // Add the cell to the table + } + } // Check if adding another row would exceed max height if (table.getTotalHeight() + rowHeight > maxTableHeight) { diff --git a/src/main/java/net/gepafin/tendermanagement/util/Utils.java b/src/main/java/net/gepafin/tendermanagement/util/Utils.java index 1c86aa6b..53050f6c 100644 --- a/src/main/java/net/gepafin/tendermanagement/util/Utils.java +++ b/src/main/java/net/gepafin/tendermanagement/util/Utils.java @@ -4,6 +4,8 @@ import java.lang.reflect.Field; import java.lang.reflect.Type; import java.nio.charset.StandardCharsets; import java.security.SecureRandom; +import java.text.DecimalFormat; +import java.text.NumberFormat; import java.text.ParseException; import java.text.SimpleDateFormat; import java.time.LocalDate; @@ -396,4 +398,29 @@ public class Utils { return null; } } + public static String convertItalianAmountToDouble(String amount) throws NumberFormatException { + // Step 1: Remove the thousands separator and replace the decimal separator + String normalizedAmount = amount.replace(".", "").replace(",", "."); + + // Step 2: Parse the string to a double + double value = Double.parseDouble(normalizedAmount); + if (value <= 0) { + return amount; + } + // Step 3: Format the double to 2 decimal places + DecimalFormat decimalFormat = new DecimalFormat("#.00"); + return decimalFormat.format(value); // Return formatted string + } + public static boolean isItalianFormattedAmount(String input) { + // Regular expression to match Italian-style amounts (e.g., 41.003,00 or 123,45) + if (!input.contains(",")) { + return false; // Return false if there is no comma + } + String sanitizedInput = input.replace(",", ""); + + // Step 2: Check if the remaining string is a whole number + String wholeNumberPattern = "^\\d+$"; // Regex to match whole numbers + + return sanitizedInput.matches(wholeNumberPattern); + } } From bf1c252c6e0b2bed1b5465a95ca2ffc84c31597a Mon Sep 17 00:00:00 2001 From: nisha Date: Mon, 28 Oct 2024 22:15:25 +0530 Subject: [PATCH 11/23] Updated code for pdf updation --- .../gepafin/tendermanagement/dao/PdfDao.java | 7 ++- .../gepafin/tendermanagement/util/Utils.java | 52 ++++++++++++++----- 2 files changed, 42 insertions(+), 17 deletions(-) diff --git a/src/main/java/net/gepafin/tendermanagement/dao/PdfDao.java b/src/main/java/net/gepafin/tendermanagement/dao/PdfDao.java index 2cf1d32b..d2e29e84 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/PdfDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/PdfDao.java @@ -278,7 +278,7 @@ public class PdfDao { fieldValue1=Utils.formatDateString(String.valueOf(value)); } if(Boolean.TRUE.equals(Utils.isItalianFormattedAmount(fieldValue)) ){ - fieldValue= String.valueOf(Utils.convertItalianAmountToDouble(fieldValue)); + fieldValue= String.valueOf(Utils.convertToItalianFormat(fieldValue)); } PdfPCell valueCell = new PdfPCell(new Phrase(fieldValue1, valueFont)); valueCell.setPadding(5f); // Increase padding for better spacing @@ -362,7 +362,6 @@ public class PdfDao { PdfPCell headerCell = new PdfPCell(new Phrase(headerValue)); // Create a new PdfPCell for the header headerCell.setHorizontalAlignment(Element.ALIGN_CENTER); // Center align headerCell.setVerticalAlignment(Element.ALIGN_MIDDLE); - headerCell.setFixedHeight(rowHeight); headerCell.setBackgroundColor(new BaseColor(178, 190, 181)); // Light gray background for header table.addCell(headerCell); // Add the header cell to the table @@ -378,7 +377,7 @@ public class PdfDao { Object value = row.getOrDefault(key, ""); // Fetch value or use empty string if key not present String fieldValue= (String) value; if(Boolean.TRUE.equals(Utils.isItalianFormattedAmount(fieldValue)) ){ - fieldValue= String.valueOf(Utils.convertItalianAmountToDouble(fieldValue)); + fieldValue= String.valueOf(Utils.convertToItalianFormat(fieldValue)); } PdfPCell dataCell = new PdfPCell(new Phrase(fieldValue != null ?fieldValue: "", textFont)); dataCell.setBackgroundColor(new BaseColor(239, 243, 248)); // Light blue for the cell @@ -498,7 +497,7 @@ public class PdfDao { } fieldValue = matchedLabels; } - + // Further processing of field value (e.g., finding labels in options) fieldValue = findLabelInOptions(content.getSettings(), fieldValue); } else { diff --git a/src/main/java/net/gepafin/tendermanagement/util/Utils.java b/src/main/java/net/gepafin/tendermanagement/util/Utils.java index 53050f6c..cb8aa153 100644 --- a/src/main/java/net/gepafin/tendermanagement/util/Utils.java +++ b/src/main/java/net/gepafin/tendermanagement/util/Utils.java @@ -398,24 +398,50 @@ public class Utils { return null; } } - public static String convertItalianAmountToDouble(String amount) throws NumberFormatException { - // Step 1: Remove the thousands separator and replace the decimal separator - String normalizedAmount = amount.replace(".", "").replace(",", "."); +// public static String convertItalianAmountToDouble(String amount) throws NumberFormatException { +// // Step 1: Remove the thousands separator and replace the decimal separator +// String normalizedAmount = amount.replace(".", "").replace(",", "."); +// +// // Step 2: Parse the string to a double +// double value = Double.parseDouble(normalizedAmount); +// if (value <= 0) { +// return amount; +// } +// // Step 3: Format the double to 2 decimal places +// DecimalFormat decimalFormat = new DecimalFormat("#.00"); +// return decimalFormat.format(value); // Return formatted string +// } - // Step 2: Parse the string to a double - double value = Double.parseDouble(normalizedAmount); - if (value <= 0) { - return amount; + public static String convertToItalianFormat(String amount) { + try { + // Step 1: Sanitize and standardize the input + String sanitizedAmount = amount.trim(); + if (sanitizedAmount.matches("\\d")) { + return sanitizedAmount; + } + // Step 2: Handle Italian-style input (e.g., "37.192,00") + if (sanitizedAmount.contains(".") && sanitizedAmount.contains(",")) { + // Assume the period is a thousand separator and the comma is a decimal separator + sanitizedAmount = sanitizedAmount.replace(".", "").replace(",", "."); + } else if (sanitizedAmount.contains(",")) { + // If the input contains only a comma, treat it as a decimal separator + sanitizedAmount = sanitizedAmount.replace(",", "."); + } + // Step 3: Parse the cleaned-up string into a double + double parsedAmount = Double.parseDouble(sanitizedAmount); + // Step 4: Format the parsed amount to Italian format + NumberFormat italianFormat = NumberFormat.getInstance(Locale.ITALY); + italianFormat.setMinimumFractionDigits(2); + italianFormat.setMaximumFractionDigits(2); + + return italianFormat.format(parsedAmount); + } catch (NumberFormatException e) { + // In case of any issues with parsing, return a default or error message + return "Invalid amount format"; } - // Step 3: Format the double to 2 decimal places - DecimalFormat decimalFormat = new DecimalFormat("#.00"); - return decimalFormat.format(value); // Return formatted string } public static boolean isItalianFormattedAmount(String input) { // Regular expression to match Italian-style amounts (e.g., 41.003,00 or 123,45) - if (!input.contains(",")) { - return false; // Return false if there is no comma - } String sanitizedInput = input.replace(",", ""); // Step 2: Check if the remaining string is a whole number From efad8596dc1f549ba8d4b986221f453684c818df Mon Sep 17 00:00:00 2001 From: rajesh Date: Mon, 28 Oct 2024 23:21:16 +0530 Subject: [PATCH 12/23] updated code for html content for pdf --- .../gepafin/tendermanagement/dao/PdfDao.java | 14 ++-- .../tendermanagement/util/PdfUtils.java | 66 +++++++++++++++++++ 2 files changed, 76 insertions(+), 4 deletions(-) create mode 100644 src/main/java/net/gepafin/tendermanagement/util/PdfUtils.java diff --git a/src/main/java/net/gepafin/tendermanagement/dao/PdfDao.java b/src/main/java/net/gepafin/tendermanagement/dao/PdfDao.java index d2e29e84..766492ec 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/PdfDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/PdfDao.java @@ -14,6 +14,7 @@ import net.gepafin.tendermanagement.entities.*; import net.gepafin.tendermanagement.model.request.FieldLabelValuePairRequest; import net.gepafin.tendermanagement.model.response.*; import net.gepafin.tendermanagement.service.CallService; +import net.gepafin.tendermanagement.util.PdfUtils; import net.gepafin.tendermanagement.util.Utils; import net.gepafin.tendermanagement.util.Validator; import org.apache.commons.lang3.StringUtils; @@ -207,7 +208,9 @@ public class PdfDao { // Loop through the list of strings and create a cell for each string for (String item : values) { - PdfPCell valueCell = new PdfPCell(new Phrase(item, valueFont)); + +// PdfPCell valueCell = new PdfPCell(new Phrase(item, valueFont)); + PdfPCell valueCell = PdfUtils.htmlToPdfPCell(item, valueFont); valueCell.setPadding(5f); // Increase padding for better spacing valueCell.setPaddingLeft(leftMargin); // Increase left margin for value valueCell.setBorder(Rectangle.NO_BORDER); // Remove border for value cell @@ -280,7 +283,8 @@ public class PdfDao { if(Boolean.TRUE.equals(Utils.isItalianFormattedAmount(fieldValue)) ){ fieldValue= String.valueOf(Utils.convertToItalianFormat(fieldValue)); } - PdfPCell valueCell = new PdfPCell(new Phrase(fieldValue1, valueFont)); +// PdfPCell valueCell = new PdfPCell(new Phrase(fieldValue1, valueFont)); + PdfPCell valueCell = PdfUtils.htmlToPdfPCell(fieldValue1, valueFont); valueCell.setPadding(5f); // Increase padding for better spacing valueCell.setPaddingLeft(leftMargin); // Increase left margin for value valueCell.setBorder(Rectangle.NO_BORDER); // Remove border for value cell @@ -359,7 +363,8 @@ public class PdfDao { if (!headersAdded) { for (String key : orderedKeys) { String headerValue = stateFieldMap.get(key); // Header text - PdfPCell headerCell = new PdfPCell(new Phrase(headerValue)); // Create a new PdfPCell for the header +// PdfPCell headerCell = new PdfPCell(new Phrase(headerValue)); // Create a new PdfPCell for the header + PdfPCell headerCell = PdfUtils.htmlToPdfPCell(headerValue, null); headerCell.setHorizontalAlignment(Element.ALIGN_CENTER); // Center align headerCell.setVerticalAlignment(Element.ALIGN_MIDDLE); headerCell.setBackgroundColor(new BaseColor(178, 190, 181)); // Light gray background for header @@ -379,7 +384,8 @@ public class PdfDao { if(Boolean.TRUE.equals(Utils.isItalianFormattedAmount(fieldValue)) ){ fieldValue= String.valueOf(Utils.convertToItalianFormat(fieldValue)); } - PdfPCell dataCell = new PdfPCell(new Phrase(fieldValue != null ?fieldValue: "", textFont)); +// PdfPCell dataCell = new PdfPCell(new Phrase(fieldValue != null ?fieldValue: "", textFont)); + PdfPCell dataCell = PdfUtils.htmlToPdfPCell(value != null ? value.toString() : "", textFont); dataCell.setBackgroundColor(new BaseColor(239, 243, 248)); // Light blue for the cell dataCell.setMinimumHeight(rowHeight); dataCell.setPadding(7f); diff --git a/src/main/java/net/gepafin/tendermanagement/util/PdfUtils.java b/src/main/java/net/gepafin/tendermanagement/util/PdfUtils.java new file mode 100644 index 00000000..cfa32b03 --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/util/PdfUtils.java @@ -0,0 +1,66 @@ +package net.gepafin.tendermanagement.util; +import com.itextpdf.text.DocumentException; +import com.itextpdf.text.Element; +import com.itextpdf.text.Font; +import com.itextpdf.text.pdf.PdfPCell; +import com.itextpdf.text.html.simpleparser.HTMLWorker; +import com.itextpdf.text.html.simpleparser.StyleSheet; +import com.itextpdf.text.Paragraph; + +import java.io.StringReader; +import java.util.List; + +import org.springframework.stereotype.Component; + +@Component +public class PdfUtils { + + + + public static PdfPCell htmlToPdfPCell(String htmlContent, Font font) { + PdfPCell cell = new PdfPCell(); + + // Check if the content is not null or empty + if (htmlContent != null && !htmlContent.trim().isEmpty()) { + // Wrap plain text in a paragraph tag if it doesn't contain any HTML + // Check if the string does not contain any '<' or '>' characters + if (!htmlContent.contains("<") || !htmlContent.contains(">")) { + htmlContent = "

" + htmlContent + "

"; // Wrap in paragraph tags + } + + try { + // Create a list to hold the elements parsed from the HTML + List elements = HTMLWorker.parseToList(new StringReader(htmlContent), new StyleSheet()); + + // Create a paragraph to hold the formatted text + Paragraph paragraph = new Paragraph(); + + // Add each element to the paragraph + for (Element element : elements) { + // If the element is a Paragraph, set the font directly + if (element instanceof Paragraph) { + ((Paragraph) element).setFont(font); + } + // If the element is a Chunk, set the font directly + else if (element instanceof com.itextpdf.text.Chunk) { + ((com.itextpdf.text.Chunk) element).setFont(font); + } + // Add the element to the paragraph + paragraph.add(element); + } + + // Add the paragraph to the cell + cell.addElement(paragraph); + + } catch (Exception e) { + e.printStackTrace(); // Log the exception for debugging + } + } + + return cell; + } + +} + + + From 823ac3347020e8487d9011e09dee360c78664a48 Mon Sep 17 00:00:00 2001 From: nisha Date: Tue, 29 Oct 2024 13:15:36 +0530 Subject: [PATCH 13/23] Updated code for removing attached document from pdf --- .../gepafin/tendermanagement/dao/PdfDao.java | 41 +++++++++++-------- 1 file changed, 23 insertions(+), 18 deletions(-) diff --git a/src/main/java/net/gepafin/tendermanagement/dao/PdfDao.java b/src/main/java/net/gepafin/tendermanagement/dao/PdfDao.java index 766492ec..6a2c2b8c 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/PdfDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/PdfDao.java @@ -211,12 +211,14 @@ public class PdfDao { // PdfPCell valueCell = new PdfPCell(new Phrase(item, valueFont)); PdfPCell valueCell = PdfUtils.htmlToPdfPCell(item, valueFont); - valueCell.setPadding(5f); // Increase padding for better spacing + valueCell.setFixedHeight(30f); // Set a fixed height for the cell + valueCell.setPaddingLeft(10f); // Adjust left padding as needed + valueCell.setPaddingTop(0f); // Remove padding from top to allow vertical centering + valueCell.setPaddingBottom(6f); valueCell.setPaddingLeft(leftMargin); // Increase left margin for value valueCell.setBorder(Rectangle.NO_BORDER); // Remove border for value cell - valueCell.setMinimumHeight(30f); valueCell.setVerticalAlignment(Element.ALIGN_MIDDLE); - valueCell.setCellEvent(new RoundedCorners()); // Apply rounded corners + valueCell.setHorizontalAlignment(Element.ALIGN_LEFT); valueCell.setCellEvent(new RoundedCorners()); // Apply rounded corners // Add the cell to the table valueTable.addCell(valueCell); @@ -285,11 +287,14 @@ public class PdfDao { } // PdfPCell valueCell = new PdfPCell(new Phrase(fieldValue1, valueFont)); PdfPCell valueCell = PdfUtils.htmlToPdfPCell(fieldValue1, valueFont); - valueCell.setPadding(5f); // Increase padding for better spacing + valueCell.setFixedHeight(30f); // Set a fixed height for the cell + valueCell.setPaddingLeft(10f); // Adjust left padding as needed + valueCell.setPaddingTop(0f); // Remove padding from top to allow vertical centering + valueCell.setPaddingBottom(6f); valueCell.setPaddingLeft(leftMargin); // Increase left margin for value valueCell.setBorder(Rectangle.NO_BORDER); // Remove border for value cell - valueCell.setMinimumHeight(30f); valueCell.setVerticalAlignment(Element.ALIGN_MIDDLE); + valueCell.setHorizontalAlignment(Element.ALIGN_LEFT); valueCell.setCellEvent(new RoundedCorners()); // Apply rounded corners valueTable.addCell(valueCell); document.add(valueTable); @@ -303,6 +308,7 @@ public class PdfDao { // Create a PdfPTable with dynamic column count based on stateFieldMap size Map stateFieldMap = new HashMap<>(); Map stateFieldBoolean = new HashMap<>(); +// Font textFont = FontFactory.getFont(FontFactory.HELVETICA, 12, Font.NORMAL, new BaseColor(178, 190, 181)); // Gray text // Populate stateFieldMap from contentResponseBean settings contentResponseBean.getSettings().stream() @@ -364,11 +370,14 @@ public class PdfDao { for (String key : orderedKeys) { String headerValue = stateFieldMap.get(key); // Header text // PdfPCell headerCell = new PdfPCell(new Phrase(headerValue)); // Create a new PdfPCell for the header - PdfPCell headerCell = PdfUtils.htmlToPdfPCell(headerValue, null); + PdfPCell headerCell = PdfUtils.htmlToPdfPCell(headerValue, textFont); headerCell.setHorizontalAlignment(Element.ALIGN_CENTER); // Center align headerCell.setVerticalAlignment(Element.ALIGN_MIDDLE); headerCell.setBackgroundColor(new BaseColor(178, 190, 181)); // Light gray background for header - + headerCell.setFixedHeight(30f); // Set a fixed height for the cell + headerCell.setPaddingLeft(10f); // Adjust left padding as needed + headerCell.setPaddingTop(0f); // Remove padding from top to allow vertical centering + headerCell.setPaddingBottom(6f); table.addCell(headerCell); // Add the header cell to the table } headersAdded = true; // Prevent headers from being added again @@ -385,11 +394,13 @@ public class PdfDao { fieldValue= String.valueOf(Utils.convertToItalianFormat(fieldValue)); } // PdfPCell dataCell = new PdfPCell(new Phrase(fieldValue != null ?fieldValue: "", textFont)); - PdfPCell dataCell = PdfUtils.htmlToPdfPCell(value != null ? value.toString() : "", textFont); + PdfPCell dataCell = PdfUtils.htmlToPdfPCell(fieldValue != null ? fieldValue : "", textFont); dataCell.setBackgroundColor(new BaseColor(239, 243, 248)); // Light blue for the cell - dataCell.setMinimumHeight(rowHeight); - dataCell.setPadding(7f); - + dataCell.setPaddingLeft(10f); // Adjust left padding as needed + dataCell.setPaddingTop(0f); // Remove padding from top to allow vertical centering + dataCell.setPaddingBottom(6f); + dataCell.setVerticalAlignment(Element.ALIGN_MIDDLE); + dataCell.setHorizontalAlignment(Element.ALIGN_LEFT); table.addCell(dataCell); // Add the cell to the table } } @@ -472,13 +483,7 @@ public class PdfDao { // Process 'fileupload' and 'checkboxes' cases as in the original logic if (name.equals("fileupload")) { - if (fieldValue instanceof List && ((List) fieldValue).stream().allMatch(item -> item instanceof DocumentResponseBean)) { - List documentList = (List) fieldValue; - List names = documentList.stream() - .map(DocumentResponseBean::getName) - .collect(Collectors.toList()); - fieldValue = names; - } + continue; } else if (name.equals("checkboxes") && fieldValue instanceof List) { List check = (List) fieldValue; List settingResponseBeans = content.getSettings(); From 4e549e3e7ac3a950d0f03332ec528c43238d90cc Mon Sep 17 00:00:00 2001 From: piyushkag Date: Tue, 29 Oct 2024 21:31:35 +0530 Subject: [PATCH 14/23] fixed s3 call document download issue --- .../net/gepafin/tendermanagement/dao/ApplicationDao.java | 4 ++-- .../java/net/gepafin/tendermanagement/dao/CallDao.java | 9 ++++++--- .../net/gepafin/tendermanagement/dao/DelegationDao.java | 8 ++++---- .../net/gepafin/tendermanagement/dao/DocumentDao.java | 7 +++---- src/main/resources/application.properties | 8 ++++---- 5 files changed, 19 insertions(+), 17 deletions(-) diff --git a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java index 2332a194..5a03fc55 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java @@ -119,8 +119,8 @@ public class ApplicationDao { @Autowired private ApplicationSignedDocumentRepository applicationSignedDocumentRepository; - @Value("${aws.s3.url.folder.signed.document}") - private String signedDocumentS3Folder; +// @Value("${aws.s3.url.folder.signed.document}") +// private String signedDocumentS3Folder; @Value("${default.hub.uuid}") private String defaultHubUuid; diff --git a/src/main/java/net/gepafin/tendermanagement/dao/CallDao.java b/src/main/java/net/gepafin/tendermanagement/dao/CallDao.java index b52aa97b..39736a57 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/CallDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/CallDao.java @@ -21,7 +21,6 @@ import net.gepafin.tendermanagement.util.DateTimeUtil; import net.gepafin.tendermanagement.util.Utils; import org.h2.util.IOUtils; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; import org.springframework.util.StringUtils; @@ -94,14 +93,17 @@ public class CallDao { @Autowired private FormDao formDao; - @Value("${aws.s3.url.folder}") - private String s3Folder; +// @Value("${aws.s3.url.folder}") +// private String s3Folder; @Autowired private AmazonS3Service amazonS3Service; @Autowired private CriteriaFormFieldRepository criteriaFormFieldRepository; + + @Autowired + private S3PathConfig s3PathConfig; public CallResponse createCallStep1(CreateCallRequestStep1 createCallRequest, UserEntity userEntity) { createCallRequest.setRegionId(userEntity.getRoleEntity().getRegion().getId()); @@ -127,6 +129,7 @@ public class CallDao { ZipOutputStream zos = new ZipOutputStream(zipOutputStream)) { for (DocumentEntity document : documents) { + String s3Folder = s3PathConfig.generateDocumentPath(DocumentSourceTypeEnum.CALL, callId, 0L); try (InputStream fileInputStream = amazonS3Service.getFile(s3Folder, document.getFilePath())) { String fileName = Utils.extractFileName(document.getFilePath()); ZipEntry zipEntry = new ZipEntry(fileName); diff --git a/src/main/java/net/gepafin/tendermanagement/dao/DelegationDao.java b/src/main/java/net/gepafin/tendermanagement/dao/DelegationDao.java index 20ae2cca..2243edf0 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/DelegationDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/DelegationDao.java @@ -8,10 +8,10 @@ import java.util.Map; import java.util.function.Function; import net.gepafin.tendermanagement.enums.DocOtherSourceTypeEnum; + 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; @@ -58,8 +58,8 @@ public class DelegationDao { @Autowired private S3PathConfig s3ConfigBean; - @Value("${aws.s3.url.folder.delegation}") - private String s3Folder; +// @Value("${aws.s3.url.folder.delegation}") +// private String s3Folder; @Autowired private UserCompanyDelegationRepository userCompanyDelegationRepository; @@ -67,9 +67,9 @@ public class DelegationDao { @Autowired private Validator validator; - public ByteArrayOutputStream generateDocument(Map placeholders, String templateName) { try { + String s3Folder = s3ConfigBean.generateDocumentPathForOther(DocOtherSourceTypeEnum.USER_DELEGATION, 0L, 0L); InputStream templateStream = amazonS3Service.getFile(s3Folder ,templateName); XWPFDocument doc = loadTemplate(templateStream); replacePlaceholders(doc, placeholders); diff --git a/src/main/java/net/gepafin/tendermanagement/dao/DocumentDao.java b/src/main/java/net/gepafin/tendermanagement/dao/DocumentDao.java index 226848f7..ffcbad26 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/DocumentDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/DocumentDao.java @@ -7,7 +7,6 @@ import net.gepafin.tendermanagement.enums.DocumentSourceTypeEnum; import net.gepafin.tendermanagement.repositories.ApplicationRepository; import net.gepafin.tendermanagement.web.rest.api.errors.CustomValidationException; 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; @@ -49,8 +48,8 @@ public class DocumentDao { @Autowired private ApplicationRepository applicationFormRepository; - @Value("${aws.s3.url.folder}") - private String s3Folder; +// @Value("${aws.s3.url.folder}") +// private String s3Folder; public List uploadFiles(List files, Long sourceId, DocumentSourceTypeEnum sourceType, DocumentTypeEnum fileType) { List documentEntities = new ArrayList<>(); @@ -141,7 +140,7 @@ public class DocumentDao { try { Long callId; Long applicationId; - if(type.equals("APPLICATION")){ + if(type.equals(DocumentSourceTypeEnum.APPLICATION)){ callId = applicationFormRepository.findCallIdById(id); applicationId = id; }else{ diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 2ad3ba65..03fc5d67 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -4,7 +4,7 @@ spring.application.name=tendermanagement spring.servlet.multipart.max-file-size=300MB spring.servlet.multipart.max-request-size=300MB -spring.profiles.active=testing +spring.profiles.active=local # JPA Configuration @@ -30,9 +30,9 @@ aws.secret.access.key=FtnkzF8E3vtqPrVnloqMyNSUSqg0f9Z9L0R7qQOu 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 -aws.s3.url.folder.signed.document=gepafin/signed-document +#aws.s3.url.folder=gepafin +#aws.s3.url.folder.delegation=gepafin/delegation +#aws.s3.url.folder.signed.document=gepafin/signed-document # 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 From 6ab1e48efc9e7d8880c89e5596423ca940b1267f Mon Sep 17 00:00:00 2001 From: piyushkag Date: Tue, 29 Oct 2024 21:36:45 +0530 Subject: [PATCH 15/23] updated application property --- src/main/resources/application.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 03fc5d67..283bf93d 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -4,7 +4,7 @@ spring.application.name=tendermanagement spring.servlet.multipart.max-file-size=300MB spring.servlet.multipart.max-request-size=300MB -spring.profiles.active=local +spring.profiles.active=testing # JPA Configuration From 16e4d32f257d7d5babe9f3382776b4055371689d Mon Sep 17 00:00:00 2001 From: piyushkag Date: Wed, 30 Oct 2024 09:55:51 +0530 Subject: [PATCH 16/23] updated code --- .../java/net/gepafin/tendermanagement/dao/DelegationDao.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/net/gepafin/tendermanagement/dao/DelegationDao.java b/src/main/java/net/gepafin/tendermanagement/dao/DelegationDao.java index 2243edf0..dfc65ec7 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/DelegationDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/DelegationDao.java @@ -69,7 +69,7 @@ public class DelegationDao { public ByteArrayOutputStream generateDocument(Map placeholders, String templateName) { try { - String s3Folder = s3ConfigBean.generateDocumentPathForOther(DocOtherSourceTypeEnum.USER_DELEGATION, 0L, 0L); + String s3Folder = s3ConfigBean.generateDocumentPathForOther(DocOtherSourceTypeEnum.TEMPLATE, 0L, 0L); InputStream templateStream = amazonS3Service.getFile(s3Folder ,templateName); XWPFDocument doc = loadTemplate(templateStream); replacePlaceholders(doc, placeholders); From fc43b8d08210e8c8ae6e01553f8a1485c2c3324a Mon Sep 17 00:00:00 2001 From: rajesh Date: Tue, 29 Oct 2024 19:47:11 +0530 Subject: [PATCH 17/23] Updated code for updating application status form AWAITING to DRAFT --- .../net/gepafin/tendermanagement/dao/ApplicationDao.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java index 5a03fc55..ccb9281f 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java @@ -615,8 +615,11 @@ public class ApplicationDao { sendMailToUserAndCompany(userEntity, applicationEntity); sendMailTodefaultSystemAndGepafin(userEntity, applicationEntity); applicationEntity.setStatus(status.getValue()); - applicationEntity = saveApplicationEntity(applicationEntity); } + if (status.equals(ApplicationStatusTypeEnum.DRAFT) && Boolean.TRUE.equals(applicationEntity.getStatus().equals(ApplicationStatusTypeEnum.AWAITING.getValue()))) { + applicationEntity.setStatus(status.getValue()); + } + applicationEntity = saveApplicationEntity(applicationEntity); return getApplicationResponse(applicationEntity); From e45aa789c647240d362958a61bfcb9b5dbb50102 Mon Sep 17 00:00:00 2001 From: rajesh Date: Wed, 30 Oct 2024 17:54:26 +0530 Subject: [PATCH 18/23] Resolved conflicts --- .../tendermanagement/dao/ApplicationDao.java | 12 ++++-- .../gepafin/tendermanagement/dao/HubDao.java | 2 +- .../dao/SystemEmailTemplatesDao.java | 43 +++++++++++++------ .../tendermanagement/entities/HubEntity.java | 4 ++ .../tendermanagement/service/HubService.java | 1 + .../service/SystemEmailTemplatesService.java | 4 +- .../service/impl/HubServiceImpl.java | 4 ++ .../impl/SystemEmailTemplatesServiceImpl.java | 6 +-- src/main/resources/application.properties | 2 + .../db/changelog/db.changelog-1.0.0.xml | 21 +++++++++ ...e_for_application_submition_30-10-2024.sql | 37 ++++++++++++++++ 11 files changed, 114 insertions(+), 22 deletions(-) create mode 100644 src/main/resources/db/dump/updated_system_email_template_for_application_submition_30-10-2024.sql diff --git a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java index ccb9281f..f8c8e0c8 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java @@ -20,6 +20,7 @@ import net.gepafin.tendermanagement.service.CallService; import net.gepafin.tendermanagement.service.CompanyService; import net.gepafin.tendermanagement.service.DocumentService; import net.gepafin.tendermanagement.service.FormService; +import net.gepafin.tendermanagement.service.HubService; import net.gepafin.tendermanagement.service.SystemEmailTemplatesService; import net.gepafin.tendermanagement.service.UserService; import net.gepafin.tendermanagement.util.DateTimeUtil; @@ -129,7 +130,10 @@ public class ApplicationDao { private UserService userService; @Autowired - S3PathConfig s3ConfigBean; + private S3PathConfig s3ConfigBean; + + @Autowired + private HubService hubService; public ApplicationResponseBean createApplication(HttpServletRequest request, ApplicationRequestBean applicationRequestBean, Long formId, Long applicationId) { @@ -722,9 +726,10 @@ public class ApplicationDao { CallEntity call =applicationEntity.getCall(); CompanyEntity company = applicationEntity.getCompany(); ProtocolEntity protocol = applicationEntity.getProtocol(); + HubEntity hub = hubService.valdateHub(applicationEntity.getHubId()); SystemEmailTemplateResponse systemEmailTemplateResponse = systemEmailTemplatesService .retrieveTemplateByTypeAndCall(SystemEmailTemplatesEntityTypeEnum.APPLICATION_SUBMISSION_TO_USER_AND_COMPANY, - call, null); + hub, null); // Create the map for subject placeholders Map subjectPlaceholders = new HashMap<>(); @@ -755,9 +760,10 @@ public class ApplicationDao { CallEntity call = applicationEntity.getCall(); CompanyEntity company = applicationEntity.getCompany(); ProtocolEntity protocol = applicationEntity.getProtocol(); + HubEntity hub = hubService.valdateHub(applicationEntity.getHubId()); SystemEmailTemplateResponse systemEmailTemplateResponse = systemEmailTemplatesService .retrieveTemplateByTypeAndCall(SystemEmailTemplatesEntityTypeEnum.APPLICATION_SUBMISSION_TO_GEPAFIN, - call, null); + hub, null); // Create the map for subject placeholders Map subjectPlaceholders = new HashMap<>(); diff --git a/src/main/java/net/gepafin/tendermanagement/dao/HubDao.java b/src/main/java/net/gepafin/tendermanagement/dao/HubDao.java index 3d5d6e7d..ee6e0d8a 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/HubDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/HubDao.java @@ -49,7 +49,7 @@ public class HubDao { hubRepository.save(hubEntity); } - private HubEntity validateHub(Long hubId) { + public HubEntity validateHub(Long hubId) { return hubRepository.findById(hubId) .orElseThrow(() -> new ResourceNotFoundException(Status.NOT_FOUND, Translator.toLocale(GepafinConstant.HUB_NOT_FOUND))); diff --git a/src/main/java/net/gepafin/tendermanagement/dao/SystemEmailTemplatesDao.java b/src/main/java/net/gepafin/tendermanagement/dao/SystemEmailTemplatesDao.java index 9218a33d..1665a724 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/SystemEmailTemplatesDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/SystemEmailTemplatesDao.java @@ -9,7 +9,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; -import net.gepafin.tendermanagement.entities.CallEntity; +import net.gepafin.tendermanagement.entities.HubEntity; import net.gepafin.tendermanagement.entities.SystemEmailTemplatesEntity; import net.gepafin.tendermanagement.entities.SystemEmailTemplatesEntity.SystemEmailTemplatesEntityTypeEnum; import net.gepafin.tendermanagement.model.response.SystemEmailTemplateResponse; @@ -25,24 +25,27 @@ public class SystemEmailTemplatesDao { @Value("${fe.base.url}") private String feBaseUrl; + @Value("${default.email.signature}") + private String defaultEmailSignature; - public SystemEmailTemplateResponse retrieveTemplate(SystemEmailTemplatesEntityTypeEnum type, CallEntity call, Locale language) { + + public SystemEmailTemplateResponse retrieveTemplate(SystemEmailTemplatesEntityTypeEnum type, HubEntity hub, Locale language) { SystemEmailTemplatesEntity dbSystemEmailTemplatesEntity = null; - if(call != null){ + if(hub != null){ // dbSystemEmailTemplatesEntity = systemEmailTemplatesRespository // .findByTypeAndCallId(type.getValue(), call.getId()); } - if(dbSystemEmailTemplatesEntity == null){ + if(dbSystemEmailTemplatesEntity == null) { dbSystemEmailTemplatesEntity = systemEmailTemplatesRespository .findByType(type.getValue()); } - SystemEmailTemplateResponse systemEmailTemplateResponse = replaceHtmlContant(dbSystemEmailTemplatesEntity, call, language, Boolean.TRUE); + SystemEmailTemplateResponse systemEmailTemplateResponse = replaceHtmlContant(dbSystemEmailTemplatesEntity, hub, language, Boolean.TRUE); return systemEmailTemplateResponse; } private SystemEmailTemplateResponse replaceHtmlContant(SystemEmailTemplatesEntity dbSystemEmailTemplatesEntity, - CallEntity call, Locale language1, Boolean isDefaultReplace) { + HubEntity hub, Locale language1, Boolean isDefaultReplace) { String language = null; String htmlContent = dbSystemEmailTemplatesEntity.getHtmlContent(); String subject = dbSystemEmailTemplatesEntity.getSubject(); @@ -69,7 +72,8 @@ public class SystemEmailTemplatesDao { } - htmlContent = replacePlatformLinkPlaceholder(call, htmlContent, languageMap); + htmlContent = replacePlatformLinkPlaceholderAndEmailSignature(hub, htmlContent, languageMap); + subject = replacePlatformLinkPlaceholderAndEmailSignature(hub, subject, languageMap); SystemEmailTemplateResponse systemEmailTemplateResponse = new SystemEmailTemplateResponse(); systemEmailTemplateResponse.setHtmlContent(htmlContent); systemEmailTemplateResponse.setSubject(subject); @@ -102,15 +106,28 @@ public class SystemEmailTemplatesDao { } return ""; } - private String replacePlatformLinkPlaceholder(CallEntity call, String htmlContent, + private String replacePlatformLinkPlaceholderAndEmailSignature(HubEntity hub, String htmlContent, Map languageMap) { - String platformLink = feBaseUrl; + htmlContent = replacePlatformLinkPlaceholder(hub, htmlContent, languageMap); + htmlContent = replaceEmailSignature(hub, htmlContent, languageMap); -// if(hubEntity != null && Boolean.FALSE.equals(isEmpty(hubEntity.getDomainName()))){ -// platformLink = hubEntity.getDomainName(); -// } - htmlContent = htmlContent.replace("{{platform_link}}", platformLink); return htmlContent; } + private String replaceEmailSignature(HubEntity hub, String htmlContent, Map languageMap) { + String emailSignature = defaultEmailSignature; + if(hub != null && Boolean.FALSE.equals(StringUtils.isEmpty(hub.getEmailSignature()))){ + emailSignature = hub.getEmailSignature(); + } + return htmlContent.replace("{{email_signature}}", emailSignature); + } + + private String replacePlatformLinkPlaceholder(HubEntity hub, String htmlContent, Map languageMap) { + String platformLink = feBaseUrl; + if(hub != null && Boolean.FALSE.equals(StringUtils.isEmpty(hub.getDomainName()))){ + platformLink = hub.getDomainName(); + } + return htmlContent.replace("{{platform_link}}", platformLink); + } + } diff --git a/src/main/java/net/gepafin/tendermanagement/entities/HubEntity.java b/src/main/java/net/gepafin/tendermanagement/entities/HubEntity.java index 1b03f913..f3796342 100644 --- a/src/main/java/net/gepafin/tendermanagement/entities/HubEntity.java +++ b/src/main/java/net/gepafin/tendermanagement/entities/HubEntity.java @@ -42,4 +42,8 @@ public class HubEntity extends BaseEntity{ @Column(name = "UNIQUE_UUID") private String uniqueUuid; + + @Column(name = "EMAIL_SIGNATURE") + private String emailSignature; + } diff --git a/src/main/java/net/gepafin/tendermanagement/service/HubService.java b/src/main/java/net/gepafin/tendermanagement/service/HubService.java index 397bc533..ad763419 100644 --- a/src/main/java/net/gepafin/tendermanagement/service/HubService.java +++ b/src/main/java/net/gepafin/tendermanagement/service/HubService.java @@ -15,4 +15,5 @@ public interface HubService { void deleteHub(Long hubId); HubEntity getHubByUuid(String hubUuid); HubResponseBean getHubByHubUuid(String uuid); + HubEntity valdateHub(Long hubId); } diff --git a/src/main/java/net/gepafin/tendermanagement/service/SystemEmailTemplatesService.java b/src/main/java/net/gepafin/tendermanagement/service/SystemEmailTemplatesService.java index b40dc80f..5d50893f 100644 --- a/src/main/java/net/gepafin/tendermanagement/service/SystemEmailTemplatesService.java +++ b/src/main/java/net/gepafin/tendermanagement/service/SystemEmailTemplatesService.java @@ -2,12 +2,12 @@ package net.gepafin.tendermanagement.service; import java.util.Locale; -import net.gepafin.tendermanagement.entities.CallEntity; +import net.gepafin.tendermanagement.entities.HubEntity; import net.gepafin.tendermanagement.entities.SystemEmailTemplatesEntity.SystemEmailTemplatesEntityTypeEnum; import net.gepafin.tendermanagement.model.response.SystemEmailTemplateResponse; public interface SystemEmailTemplatesService { - SystemEmailTemplateResponse retrieveTemplateByTypeAndCall(SystemEmailTemplatesEntityTypeEnum type, CallEntity call, Locale language); + SystemEmailTemplateResponse retrieveTemplateByTypeAndCall(SystemEmailTemplatesEntityTypeEnum type, HubEntity hub, Locale language); } diff --git a/src/main/java/net/gepafin/tendermanagement/service/impl/HubServiceImpl.java b/src/main/java/net/gepafin/tendermanagement/service/impl/HubServiceImpl.java index 513a89e4..3490a0e6 100644 --- a/src/main/java/net/gepafin/tendermanagement/service/impl/HubServiceImpl.java +++ b/src/main/java/net/gepafin/tendermanagement/service/impl/HubServiceImpl.java @@ -56,4 +56,8 @@ public class HubServiceImpl implements HubService { public HubResponseBean getHubByHubUuid(String uuid) { return hubDao.getHubByHubUuid(uuid); } + @Override + public HubEntity valdateHub(Long hubId) { + return hubDao.validateHub(hubId); + } } diff --git a/src/main/java/net/gepafin/tendermanagement/service/impl/SystemEmailTemplatesServiceImpl.java b/src/main/java/net/gepafin/tendermanagement/service/impl/SystemEmailTemplatesServiceImpl.java index 802f2580..34885c5b 100644 --- a/src/main/java/net/gepafin/tendermanagement/service/impl/SystemEmailTemplatesServiceImpl.java +++ b/src/main/java/net/gepafin/tendermanagement/service/impl/SystemEmailTemplatesServiceImpl.java @@ -6,7 +6,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import net.gepafin.tendermanagement.dao.SystemEmailTemplatesDao; -import net.gepafin.tendermanagement.entities.CallEntity; +import net.gepafin.tendermanagement.entities.HubEntity; import net.gepafin.tendermanagement.entities.SystemEmailTemplatesEntity.SystemEmailTemplatesEntityTypeEnum; import net.gepafin.tendermanagement.model.response.SystemEmailTemplateResponse; import net.gepafin.tendermanagement.service.SystemEmailTemplatesService; @@ -19,8 +19,8 @@ public class SystemEmailTemplatesServiceImpl implements SystemEmailTemplatesServ @Override - public SystemEmailTemplateResponse retrieveTemplateByTypeAndCall(SystemEmailTemplatesEntityTypeEnum type, CallEntity call, Locale language) { - return systemEmailTemplatesDao.retrieveTemplate(type, call, language); + public SystemEmailTemplateResponse retrieveTemplateByTypeAndCall(SystemEmailTemplatesEntityTypeEnum type, HubEntity hub, Locale language) { + return systemEmailTemplatesDao.retrieveTemplate(type, hub, language); } diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 283bf93d..45432caf 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -60,3 +60,5 @@ mailGun_base_url=https://api.eu.mailgun.net/ apiKey=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 #senderEmail=mailer@bflows.net +default.email.signature=Gepafin S.p.a + 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 73ad16f7..a4980a25 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 @@ -1483,5 +1483,26 @@ + + + + + + + + + + + + + + UNIQUE_UUID = 'p4lk3bcx1RStqTaIVVbXs' + + + + UNIQUE_UUID = 't7jh5wfg9QXylNaTZkPoE' + + diff --git a/src/main/resources/db/dump/updated_system_email_template_for_application_submition_30-10-2024.sql b/src/main/resources/db/dump/updated_system_email_template_for_application_submition_30-10-2024.sql new file mode 100644 index 00000000..035a64cf --- /dev/null +++ b/src/main/resources/db/dump/updated_system_email_template_for_application_submition_30-10-2024.sql @@ -0,0 +1,37 @@ +UPDATE gepafin_schema.system_email_template SET html_content=' + +
+

Buongiorno,

+

+ Si comunica che, in riferimento alla domanda di concessione di + Finanziamento agevolato a valere sul Fondo prestiti + {{call_name}} di cui all''oggetto, la stessa è stata + regolarmente acquisita ed è stata registrata con Protocollo n. + {{protocol_number}} del {{date}} alle + {{time}}. +

+

Distinti Saluti,

+

+ {{email_signature}} +

+
+ +' WHERE "type"='APPLICATION_SUBMISSION_TO_USER_AND_COMPANY' AND "system"=true ; + + +UPDATE gepafin_schema.system_email_template SET html_content=' + +
+

+ In riferimento alla domanda di concessione di Finanziamento agevolato a valere sul Fondo prestiti + {{call_name}} di cui all’oggetto, la stessa è stata regolarmente acquisita ed è stata + registrata con Protocollo n. {{protocol_number}} del {{date}} alle {{time}}. +

+

Distinti Saluti,

+

+ {{email_signature}} +

+
+ +' WHERE "type"='APPLICATION_SUBMISSION_TO_GEPAFIN' AND "system"=true; + From 40e65231dc9dc8f2ad0cf48087c9ba1c482b619d Mon Sep 17 00:00:00 2001 From: nisha Date: Wed, 30 Oct 2024 16:47:36 +0530 Subject: [PATCH 19/23] Resolved conflicts --- .../gepafin/tendermanagement/dao/PdfDao.java | 22 +++++++++++++++++-- .../tendermanagement/entities/HubEntity.java | 4 +++- src/main/resources/application.properties | 2 ++ .../db/changelog/db.changelog-1.0.0.xml | 17 +++++++++++++- 4 files changed, 41 insertions(+), 4 deletions(-) diff --git a/src/main/java/net/gepafin/tendermanagement/dao/PdfDao.java b/src/main/java/net/gepafin/tendermanagement/dao/PdfDao.java index 6a2c2b8c..7fe594f3 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/PdfDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/PdfDao.java @@ -13,6 +13,7 @@ import jakarta.servlet.http.HttpServletRequest; import net.gepafin.tendermanagement.entities.*; import net.gepafin.tendermanagement.model.request.FieldLabelValuePairRequest; import net.gepafin.tendermanagement.model.response.*; +import net.gepafin.tendermanagement.repositories.HubRepository; import net.gepafin.tendermanagement.service.CallService; import net.gepafin.tendermanagement.util.PdfUtils; import net.gepafin.tendermanagement.util.Utils; @@ -21,6 +22,7 @@ import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; //import com.itextpdf.layout.element. @@ -29,11 +31,13 @@ import java.io.ByteArrayOutputStream; import java.io.IOException; import java.util.*; import java.util.List; -import java.util.stream.Collectors; @Component public class PdfDao { + @Value("${default.hub.pdf.banner}") + private String defaultLogoUrl; + @Autowired private CallService callService; @@ -43,6 +47,9 @@ public class PdfDao { @Autowired private Validator validator; + @Autowired + private HubRepository hubRepository; + public static final Logger log = LoggerFactory.getLogger(PdfDao.class); public byte[] generatePdf(HttpServletRequest request,Long applicationId) { @@ -61,9 +68,20 @@ public class PdfDao { // CustomPageEvent pageEvent = new CustomPageEvent(call.getName(), 0); // writer.setPageEvent(pageEvent); document.open(); + String logoUrl=defaultLogoUrl; + + Optional hubEntity=hubRepository.findById(applicationEntity.getHubId()); + if(hubEntity.isPresent()) { + if (hubEntity.get().getUniqueUuid().equals("p4lk3bcx1RStqTaIVVbXs")) { + defaultLogoUrl = hubEntity.get().getPdfBanner(); + } + if (hubEntity.get().getUniqueUuid().equals("t7jh5wfg9QXylNaTZkPoE")) { + defaultLogoUrl = hubEntity.get().getPdfBanner(); + } + } // pageEvent.setTotalPages(writer.getPageNumber()); // addLogo(document, "logo.jpg"); // Add your image path here the migration code after cherry-pick - addLogo(document, "https://mementoresources.s3.eu-west-1.amazonaws.com/gepafin/logo.jpg"); + addLogo(document, logoUrl); BaseColor customColor = new BaseColor(0, 128, 0); // Adjust RGB values as needed diff --git a/src/main/java/net/gepafin/tendermanagement/entities/HubEntity.java b/src/main/java/net/gepafin/tendermanagement/entities/HubEntity.java index f3796342..b8ae74a9 100644 --- a/src/main/java/net/gepafin/tendermanagement/entities/HubEntity.java +++ b/src/main/java/net/gepafin/tendermanagement/entities/HubEntity.java @@ -45,5 +45,7 @@ public class HubEntity extends BaseEntity{ @Column(name = "EMAIL_SIGNATURE") private String emailSignature; - + + @Column(name="PDF_BANNER") + private String pdfBanner; } diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 45432caf..13e7addb 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -62,3 +62,5 @@ apiKey=xkeysib-d15439fedd7ff36d86676ac248153fc2c496ed9b879ca9dc8cee9a27fa309087- default.email.signature=Gepafin S.p.a +default.hub.pdf.banner=https://mementoresources.s3.amazonaws.com/gepafin/staging/template/gepafin-logo.jpg + 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 a4980a25..ed4e78ec 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 @@ -1504,5 +1504,20 @@ UNIQUE_UUID = 't7jh5wfg9QXylNaTZkPoE' - + + + + + + + + UNIQUE_UUID = 'p4lk3bcx1RStqTaIVVbXs' + + + + UNIQUE_UUID = 't7jh5wfg9QXylNaTZkPoE' + + + + From 6abaf8368212b9d52a33903b8b5503c15f97a032 Mon Sep 17 00:00:00 2001 From: rbonazzo-KZ <66477605+rbonazzo-KZ@users.noreply.github.com> Date: Thu, 31 Oct 2024 12:18:41 +0100 Subject: [PATCH 20/23] Update ApplicationDao.java Comment Lines sending email to Beneficiary --- .../net/gepafin/tendermanagement/dao/ApplicationDao.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java index f8c8e0c8..3bf81c6f 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java @@ -616,7 +616,7 @@ public class ApplicationDao { applicationEntity.setStatus(ApplicationStatusTypeEnum.SUBMIT.getValue()); applicationEntity.setSubmissionDate(DateTimeUtil.DateServerToUTC(LocalDateTime.now())); applicationEntity = saveApplicationEntity(applicationEntity); - sendMailToUserAndCompany(userEntity, applicationEntity); + //sendMailToUserAndCompany(userEntity, applicationEntity); sendMailTodefaultSystemAndGepafin(userEntity, applicationEntity); applicationEntity.setStatus(status.getValue()); } @@ -746,13 +746,14 @@ public class ApplicationDao { // Replace placeholders in the subject and body String subject = Utils.replacePlaceholders(systemEmailTemplateResponse.getSubject(), subjectPlaceholders); String body = Utils.replacePlaceholders(systemEmailTemplateResponse.getHtmlContent(), bodyPlaceholders); - + /** String email = userEntity.getEmail(); if (userEntity.getBeneficiary() != null) { email = userEntity.getBeneficiary().getEmail(); } mailUtil.sendByMailGun(subject, body, List.of(email), null); mailUtil.sendByMailGun(subject, body, List.of(applicationEntity.getCompany().getEmail()), null); + **/ } @@ -783,7 +784,7 @@ public class ApplicationDao { mailUtil.sendByMailGun(subject, body, List.of(defaultSystemReceiverEmail), null); - mailUtil.sendByMailGun(subject, body, List.of(gepafinEmail), null); + //mailUtil.sendByMailGun(subject, body, List.of(gepafinEmail), null); mailUtil.sendByMailGun(subject, body, List.of(rinaldoEmail), null); if(validator.isProductionProfileActivated()) { mailUtil.sendByMailGun(subject, body, List.of(carloEmail), null); From 759fad7f695d339b989fea0e4f8886a68a6f9c1b Mon Sep 17 00:00:00 2001 From: nisha Date: Tue, 5 Nov 2024 15:03:02 +0530 Subject: [PATCH 21/23] Updated code for adding list of document --- .../gepafin/tendermanagement/dao/PdfDao.java | 45 +++++++++++++++---- 1 file changed, 37 insertions(+), 8 deletions(-) diff --git a/src/main/java/net/gepafin/tendermanagement/dao/PdfDao.java b/src/main/java/net/gepafin/tendermanagement/dao/PdfDao.java index 6a2c2b8c..d4899964 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/PdfDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/PdfDao.java @@ -458,7 +458,7 @@ public class PdfDao { String contentId = content.getId(); // Content ID String label = content.getLabel(); // Content label String name = content.getName(); // Content name - Object fieldValue = null; + Object fieldValue = ""; String contentLabel = content.getSettings().stream() .filter(setting -> "label".equals(setting.getName())) // Filter settings by name @@ -467,6 +467,32 @@ public class PdfDao { .findFirst() // Get the first matching value .orElse(null); // If no match is found, set label to null // Find the form field in the response that matches the contentId + if (name.equals("paragraph")){ + String paragraph = content.getSettings().stream() + .filter(setting -> "text".equals(setting.getName())) // Filter settings by name + .map(SettingResponseBean::getValue) // Extract the value from the matching setting + .map(Object::toString) // Convert the value to a string + .findFirst() // Get the first matching value + .orElse(null); + Paragraph labelParagraph = new Paragraph(); + PdfPCell labelCell = new PdfPCell(PdfUtils.htmlToPdfPCell(paragraph,labelFont)); + labelCell.setBorder(Rectangle.NO_BORDER); + labelCell.setGrayFill(7); + labelCell.setPadding(5); + + // Create a PdfPTable with 1 column and add the PdfPCell to it + PdfPTable table = new PdfPTable(1); + table.setWidthPercentage(100); + table.addCell(labelCell); + labelParagraph.add(table); + try { + document.add(labelParagraph); + document.add(new Paragraph(" ")); + + } catch (DocumentException e) { + throw new RuntimeException(e); + } + } Optional matchingFormField = formFields.stream() .filter(formField -> formField.getFieldId().equals(contentId)) .findFirst(); @@ -483,7 +509,13 @@ public class PdfDao { // Process 'fileupload' and 'checkboxes' cases as in the original logic if (name.equals("fileupload")) { - continue; + if (fieldValue instanceof List && ((List) fieldValue).stream().allMatch(item -> item instanceof DocumentResponseBean)) { + List documentList = (List) fieldValue; + List names = documentList.stream() + .map(DocumentResponseBean::getName) + .collect(Collectors.toList()); + fieldValue = names; + } } else if (name.equals("checkboxes") && fieldValue instanceof List) { List check = (List) fieldValue; List settingResponseBeans = content.getSettings(); @@ -511,15 +543,12 @@ public class PdfDao { // Further processing of field value (e.g., finding labels in options) fieldValue = findLabelInOptions(content.getSettings(), fieldValue); - } else { - // If no matching form field is found, store contentId with an empty string - fieldValue = ""; } - try { - if((contentLabel!=null && Boolean.FALSE.equals(contentLabel.isEmpty())) || (fieldValue!=null && !StringUtils.isEmpty((CharSequence) fieldValue))) { - addLabelValuePair(writer, document, contentLabel, fieldValue, labelFont, valueFont, content); + if((contentLabel==null || StringUtils.isEmpty(contentLabel)) && (fieldValue==null || StringUtils.isEmpty(fieldValue.toString()))) { + continue; } + addLabelValuePair(writer, document, contentLabel, fieldValue, labelFont, valueFont, content); } catch (DocumentException e) { log.error("Error checking object: " + e.getMessage(), e); From 6d5b1f2fd85a02986284b7a705adde67a3618b76 Mon Sep 17 00:00:00 2001 From: nisha Date: Tue, 5 Nov 2024 16:29:00 +0530 Subject: [PATCH 22/23] Updated code --- src/main/java/net/gepafin/tendermanagement/dao/PdfDao.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/net/gepafin/tendermanagement/dao/PdfDao.java b/src/main/java/net/gepafin/tendermanagement/dao/PdfDao.java index 01c829ae..550bd240 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/PdfDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/PdfDao.java @@ -31,6 +31,7 @@ import java.io.ByteArrayOutputStream; import java.io.IOException; import java.util.*; import java.util.List; +import java.util.stream.Collectors; @Component public class PdfDao { From a63bd84e39aa35a8674623323bcf72f7b8f0091a Mon Sep 17 00:00:00 2001 From: piyuskag Date: Tue, 5 Nov 2024 20:47:06 +0530 Subject: [PATCH 23/23] Added call_id property for file upload type validation specific to call_id. --- .../tendermanagement/dao/ApplicationDao.java | 16 +++++++++++++++- src/main/resources/application.properties | 2 ++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java index 3bf81c6f..4a83b837 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java @@ -32,6 +32,7 @@ import net.gepafin.tendermanagement.web.rest.api.errors.CustomValidationExceptio import net.gepafin.tendermanagement.web.rest.api.errors.ResourceNotFoundException; import net.gepafin.tendermanagement.web.rest.api.errors.Status; +import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -114,6 +115,9 @@ public class ApplicationDao { @Value("${carlo_email}") private String carloEmail; + @Value("${call.id}") + private String callId; + @Autowired private AmazonS3Service amazonS3Service; @@ -795,7 +799,7 @@ public class ApplicationDao { MultipartFile file) { ApplicationEntity applicationEntity = validateApplication(applicationId); validator.validateUserWithCompany(request, applicationEntity.getCompany().getId()); - validateFileType(file); + validateFileTypeForCall(file, applicationEntity); ApplicationSignedDocumentEntity applicationSignedDocument = applicationSignedDocumentRepository .findByApplicationIdAndStatus(applicationId, ApplicationSignedDocumentStatusEnum.ACTIVE.getValue()); if (applicationSignedDocument != null) { @@ -815,6 +819,16 @@ public class ApplicationDao { applicationRepository.save(applicationEntity); return convertApplicationSignedDocumentToApplicationSignedDocumentResponse(applicationSignedDocument); } + + private void validateFileTypeForCall(MultipartFile file, ApplicationEntity applicationEntity) { + List validCallIds = Arrays.asList(callId.split(",")); + if (applicationEntity != null && validCallIds.contains(applicationEntity.getCall().getId().toString())) { + return; + } + validateFileType(file); + } + + private UploadFileOnAmazonS3Response uploadFileOnAmazonS3ForUserSignedDocument(MultipartFile file, Long callId, Long applicationId) { try { String s3Path = generateS3PathForDelegation(callId, applicationId); diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 13e7addb..f19adfb0 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -23,6 +23,8 @@ spring.liquibase.enabled=true springdoc.api-docs.path=/v1/api-docs springdoc.swagger-ui.tagsSorter=alpha +#signed_document_callIds for more file type upload feature. +call.id=10 #aws configuration aws.access.key.id=AKIAVWDQWCUEOSUN4LUW