diff --git a/helm/values-dev.yaml b/helm/values-dev.yaml
index 9eb43ee3..c02bb0e6 100644
--- a/helm/values-dev.yaml
+++ b/helm/values-dev.yaml
@@ -111,11 +111,14 @@ microservice-chart:
OTEL_TRACES_SAMPLER: "always_on"
MAX_DATE_DIFF_MILLIS: "1800000" # 30min
MAX_DATE_DIFF_NOTIFY_MILLIS: "1800000" # 30nin
+ MAX_DATE_DIFF_CART_MILLIS: "1800000" # 30nin
TRIGGER_NOTIFY_REC_SCHEDULE: "0 0 */2 * * *"
RECOVER_FAILED_CRON: "0 0 */2 * * *"
+ RECOVER_FAILED_CART_CRON: "0 0 */2 * * *"
AZURE_FUNCTIONS_MESH_JAVA_OPTS: "-javaagent:/home/site/wwwroot/jmx_prometheus_javaagent-0.19.0.jar=12345:/home/site/wwwroot/config.yaml -javaagent:/home/site/wwwroot/opentelemetry-javaagent.jar -Xmx768m -XX:+UseG1GC"
FAILED_AUTORECOVER_ENABLED: "true"
NOT_NOTIFIED_AUTORECOVER_ENABLED: "true"
+ FAILED_CART_AUTORECOVER_ENABLED: "true"
RECOVER_FAILED_MASSIVE_MAX_DAYS: "0"
RECOVER_NOT_NOTIFIED_MASSIVE_MAX_DAYS: "0"
RECOVER_NOT_NOTIFIED_MASSIVE_MAX_RECORDS: "200"
diff --git a/helm/values-prod.yaml b/helm/values-prod.yaml
index cfbde027..f7635b96 100644
--- a/helm/values-prod.yaml
+++ b/helm/values-prod.yaml
@@ -111,11 +111,14 @@ microservice-chart:
OTEL_TRACES_SAMPLER: "always_on"
MAX_DATE_DIFF_MILLIS: "1800000" # 30min
MAX_DATE_DIFF_NOTIFY_MILLIS: "1800000" # 30nin
+ MAX_DATE_DIFF_CART_MILLIS: "1800000" # 30nin
TRIGGER_NOTIFY_REC_SCHEDULE: "0 0 */1 * * *"
RECOVER_FAILED_CRON: "0 0 */1 * * *"
+ RECOVER_FAILED_CART_CRON: "0 0 */1 * * *"
AZURE_FUNCTIONS_MESH_JAVA_OPTS: "-javaagent:/home/site/wwwroot/jmx_prometheus_javaagent-0.19.0.jar=12345:/home/site/wwwroot/config.yaml -javaagent:/home/site/wwwroot/opentelemetry-javaagent.jar -Xmx768m -XX:+UseG1GC"
FAILED_AUTORECOVER_ENABLED: "true"
NOT_NOTIFIED_AUTORECOVER_ENABLED: "true"
+ FAILED_CART_AUTORECOVER_ENABLED: "false"
RECOVER_FAILED_MASSIVE_MAX_DAYS: "0"
RECOVER_NOT_NOTIFIED_MASSIVE_MAX_DAYS: "0"
RECOVER_NOT_NOTIFIED_MASSIVE_MAX_RECORDS: "200"
diff --git a/helm/values-uat.yaml b/helm/values-uat.yaml
index 89b42de0..b524cd23 100644
--- a/helm/values-uat.yaml
+++ b/helm/values-uat.yaml
@@ -111,11 +111,14 @@ microservice-chart:
OTEL_TRACES_SAMPLER: "always_on"
MAX_DATE_DIFF_MILLIS: "1800000" # 30min
MAX_DATE_DIFF_NOTIFY_MILLIS: "1800000" # 30nin
+ MAX_DATE_DIFF_CART_MILLIS: "1800000" # 30nin
TRIGGER_NOTIFY_REC_SCHEDULE: "0 0 */1 * * *"
RECOVER_FAILED_CRON: "0 0 */1 * * *"
+ RECOVER_FAILED_CART_CRON: "0 0 */1 * * *"
AZURE_FUNCTIONS_MESH_JAVA_OPTS: "-javaagent:/home/site/wwwroot/jmx_prometheus_javaagent-0.19.0.jar=12345:/home/site/wwwroot/config.yaml -javaagent:/home/site/wwwroot/opentelemetry-javaagent.jar -Xmx768m -XX:+UseG1GC"
FAILED_AUTORECOVER_ENABLED: "true"
NOT_NOTIFIED_AUTORECOVER_ENABLED: "true"
+ FAILED_CART_AUTORECOVER_ENABLED: "false"
RECOVER_FAILED_MASSIVE_MAX_DAYS: "0"
RECOVER_NOT_NOTIFIED_MASSIVE_MAX_DAYS: "0"
RECOVER_NOT_NOTIFIED_MASSIVE_MAX_RECORDS: "200"
diff --git a/openapi/openapi.json b/openapi/openapi.json
index 43afe56b..3344f411 100644
--- a/openapi/openapi.json
+++ b/openapi/openapi.json
@@ -535,6 +535,15 @@
"type": "string"
},
"required": true
+ },
+ {
+ "in": "query",
+ "name": "isCart",
+ "description": "Boolean to determine if the id refers to a cart",
+ "schema": {
+ "type": "string"
+ },
+ "required": false
}
],
"responses": {
@@ -886,6 +895,241 @@
}
]
},
+ "/carts/{cart-id}/recover-failed": {
+ "post": {
+ "tags": [
+ "API-recoverFailedCart"
+ ],
+ "summary": "Recover a cart in FAILED or INSERTED status",
+ "operationId": "RecoverFailedCart",
+ "parameters": [
+ {
+ "in": "path",
+ "name": "cart-id",
+ "description": "Cart id.",
+ "schema": {
+ "type": "string"
+ },
+ "required": true
+ }
+ ],
+ "requestBody": {
+ "content": {
+ "application/json": {}
+ },
+ "required": false
+ },
+ "responses": {
+ "200": {
+ "description": "Successful Calls.",
+ "headers": {
+ "X-Request-Id": {
+ "description": "This header identifies the call",
+ "schema": {
+ "type": "string"
+ }
+ }
+ },
+ "content": {
+ "text/plain": {
+ "schema": {
+ "type": "string",
+ "example": "Receipt with eventId 76abb1f1-c9f9-4ead-9e66-12fec4d51042 recovered"
+ }
+ }
+ }
+ },
+ "400": {
+ "description": "Bad request.",
+ "headers": {
+ "X-Request-Id": {
+ "description": "This header identifies the call",
+ "schema": {
+ "type": "string"
+ }
+ }
+ },
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ProblemJson"
+ }
+ }
+ }
+ },
+ "404": {
+ "description": "Receipt or BizEvent not found",
+ "headers": {
+ "X-Request-Id": {
+ "description": "This header identifies the call",
+ "schema": {
+ "type": "string"
+ }
+ }
+ },
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ProblemJson"
+ }
+ }
+ }
+ },
+ "500": {
+ "description": "Error processing the request",
+ "headers": {
+ "X-Request-Id": {
+ "description": "This header identifies the call",
+ "schema": {
+ "type": "string"
+ }
+ }
+ },
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ProblemJson"
+ }
+ }
+ }
+ },
+ "default": {
+ "description": "Unexpected error.",
+ "headers": {
+ "X-Request-Id": {
+ "description": "This header identifies the call",
+ "schema": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ },
+ "security": [
+ {
+ "ApiKey": []
+ }
+ ]
+ },
+ "parameters": [
+ {
+ "name": "X-Request-Id",
+ "in": "header",
+ "description": "This header identifies the call, if not passed it is self-generated. This ID is returned in the response.",
+ "schema": {
+ "type": "string"
+ }
+ }
+ ]
+ },
+ "/carts/recover-failed": {
+ "post": {
+ "tags": [
+ "API-recoverCartFailed"
+ ],
+ "summary": "Recover a group of cart in FAILED, or INSERTED status",
+ "operationId": "RecoverFailedCartMassive",
+ "parameters": [
+ {
+ "in": "query",
+ "name": "status",
+ "schema": {
+ "type": "string"
+ },
+ "required": true
+ }
+ ],
+ "requestBody": {
+ "content": {
+ "application/json": {}
+ },
+ "required": false
+ },
+ "responses": {
+ "200": {
+ "description": "Successful Calls.",
+ "headers": {
+ "X-Request-Id": {
+ "description": "This header identifies the call",
+ "schema": {
+ "type": "string"
+ }
+ }
+ },
+ "content": {
+ "text/plain": {
+ "schema": {
+ "type": "string",
+ "example": "Recovered 10 carts"
+ }
+ }
+ }
+ },
+ "400": {
+ "description": "Bad request",
+ "headers": {
+ "X-Request-Id": {
+ "description": "This header identifies the call",
+ "schema": {
+ "type": "string"
+ }
+ }
+ },
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ProblemJson"
+ }
+ }
+ }
+ },
+ "500": {
+ "description": "Error processing the request",
+ "headers": {
+ "X-Request-Id": {
+ "description": "This header identifies the call",
+ "schema": {
+ "type": "string"
+ }
+ }
+ },
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ProblemJson"
+ }
+ }
+ }
+ },
+ "default": {
+ "description": "Unexpected error.",
+ "headers": {
+ "X-Request-Id": {
+ "description": "This header identifies the call",
+ "schema": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ },
+ "security": [
+ {
+ "ApiKey": []
+ }
+ ]
+ },
+ "parameters": [
+ {
+ "name": "X-Request-Id",
+ "in": "header",
+ "description": "This header identifies the call, if not passed it is self-generated. This ID is returned in the response.",
+ "schema": {
+ "type": "string"
+ }
+ }
+ ]
+ },
"/receipts/{event-id}/recover-failed": {
"post": {
"tags": [
@@ -902,6 +1146,15 @@
"type": "string"
},
"required": true
+ },
+ {
+ "in": "query",
+ "name": "isCart",
+ "description": "Boolean to determine if the id refers to a cart",
+ "schema": {
+ "type": "string"
+ },
+ "required": false
}
],
"requestBody": {
@@ -1137,6 +1390,15 @@
"type": "string"
},
"required": true
+ },
+ {
+ "in": "query",
+ "name": "isCart",
+ "description": "Boolean to determine if the id refers to a cart",
+ "schema": {
+ "type": "string"
+ },
+ "required": false
}
],
"requestBody": {
@@ -1372,6 +1634,15 @@
"type": "string"
},
"required": true
+ },
+ {
+ "in": "query",
+ "name": "isCart",
+ "description": "Boolean to determine if the id refers to a cart",
+ "schema": {
+ "type": "string"
+ },
+ "required": false
}
],
"requestBody": {
diff --git a/src/main/java/it/gov/pagopa/receipt/pdf/helpdesk/ReceiptToReviewed.java b/src/main/java/it/gov/pagopa/receipt/pdf/helpdesk/ReceiptToReviewed.java
index 6280ac54..0be97d64 100644
--- a/src/main/java/it/gov/pagopa/receipt/pdf/helpdesk/ReceiptToReviewed.java
+++ b/src/main/java/it/gov/pagopa/receipt/pdf/helpdesk/ReceiptToReviewed.java
@@ -6,6 +6,7 @@
import it.gov.pagopa.receipt.pdf.helpdesk.client.impl.ReceiptCosmosClientImpl;
import it.gov.pagopa.receipt.pdf.helpdesk.entity.receipt.ReceiptError;
import it.gov.pagopa.receipt.pdf.helpdesk.entity.receipt.enumeration.ReceiptErrorStatusType;
+import it.gov.pagopa.receipt.pdf.helpdesk.exception.CartNotFoundException;
import it.gov.pagopa.receipt.pdf.helpdesk.exception.ReceiptNotFoundException;
import it.gov.pagopa.receipt.pdf.helpdesk.model.ProblemJson;
import org.slf4j.Logger;
diff --git a/src/main/java/it/gov/pagopa/receipt/pdf/helpdesk/RecoverFailedCart.java b/src/main/java/it/gov/pagopa/receipt/pdf/helpdesk/RecoverFailedCart.java
new file mode 100644
index 00000000..f660850c
--- /dev/null
+++ b/src/main/java/it/gov/pagopa/receipt/pdf/helpdesk/RecoverFailedCart.java
@@ -0,0 +1,193 @@
+package it.gov.pagopa.receipt.pdf.helpdesk;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.microsoft.azure.functions.*;
+import com.microsoft.azure.functions.annotation.*;
+import it.gov.pagopa.receipt.pdf.helpdesk.client.BizEventCosmosClient;
+import it.gov.pagopa.receipt.pdf.helpdesk.client.CartReceiptsCosmosClient;
+import it.gov.pagopa.receipt.pdf.helpdesk.client.impl.BizEventCosmosClientImpl;
+import it.gov.pagopa.receipt.pdf.helpdesk.client.impl.CartReceiptsCosmosClientImpl;
+import it.gov.pagopa.receipt.pdf.helpdesk.entity.cart.CartForReceipt;
+import it.gov.pagopa.receipt.pdf.helpdesk.entity.cart.CartStatusType;
+import it.gov.pagopa.receipt.pdf.helpdesk.entity.event.BizEvent;
+import it.gov.pagopa.receipt.pdf.helpdesk.entity.receipt.Receipt;
+import it.gov.pagopa.receipt.pdf.helpdesk.entity.receipt.enumeration.ReceiptStatusType;
+import it.gov.pagopa.receipt.pdf.helpdesk.exception.BizEventNotFoundException;
+import it.gov.pagopa.receipt.pdf.helpdesk.exception.CartNotFoundException;
+import it.gov.pagopa.receipt.pdf.helpdesk.exception.PDVTokenizerException;
+import it.gov.pagopa.receipt.pdf.helpdesk.model.ProblemJson;
+import it.gov.pagopa.receipt.pdf.helpdesk.service.BizEventToReceiptService;
+import it.gov.pagopa.receipt.pdf.helpdesk.service.ReceiptCosmosService;
+import it.gov.pagopa.receipt.pdf.helpdesk.service.impl.BizEventToReceiptServiceImpl;
+import it.gov.pagopa.receipt.pdf.helpdesk.service.impl.ReceiptCosmosServiceImpl;
+import it.gov.pagopa.receipt.pdf.helpdesk.utils.BizEventToReceiptUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.time.LocalDateTime;
+import java.util.List;
+import java.util.Optional;
+
+import static it.gov.pagopa.receipt.pdf.helpdesk.utils.BizEventToReceiptUtils.isReceiptStatusValid;
+
+/**
+ * Azure Functions with Azure Http trigger.
+ */
+public class RecoverFailedCart {
+
+ private final Logger logger = LoggerFactory.getLogger(RecoverFailedCart.class);
+
+ private final BizEventToReceiptService bizEventToReceiptService;
+ private final CartReceiptsCosmosClient cartReceiptsCosmosClient;
+
+ public RecoverFailedCart(){
+ this.bizEventToReceiptService = new BizEventToReceiptServiceImpl();
+ this.cartReceiptsCosmosClient = CartReceiptsCosmosClientImpl.getInstance();
+ }
+
+ RecoverFailedCart(BizEventToReceiptService bizEventToReceiptService,
+ CartReceiptsCosmosClient cartReceiptsCosmosClient){
+ this.bizEventToReceiptService = bizEventToReceiptService;
+ this.cartReceiptsCosmosClient = cartReceiptsCosmosClient;
+ }
+
+ /**
+ * This function will be invoked when a Http Trigger occurs.
+ *
+ * It recovers the receipt with the specified biz event id that has the following status:
+ * - ({@link ReceiptStatusType#INSERTED})
+ * - ({@link ReceiptStatusType#FAILED})
+ * - ({@link ReceiptStatusType#NOT_QUEUE_SENT})
+ *
+ * It creates the receipts if not exist and send on queue the event in order to proceed with the receipt generation.
+ *
+ * @return response with {@link HttpStatus#OK} if the operation succeeded
+ */
+ @FunctionName("RecoverFailedCart")
+ public HttpResponseMessage run (
+ @HttpTrigger(name = "RecoverFailedCartTrigger",
+ methods = {HttpMethod.POST},
+ route = "cart/{cart-id}/recover-failed",
+ authLevel = AuthorizationLevel.ANONYMOUS)
+ HttpRequestMessage> request,
+ @BindingName("cart-id") String cartId,
+ @CosmosDBOutput(
+ name = "CartReceiptDatastore",
+ databaseName = "db",
+ collectionName = "cart-for-receipt",
+ connectionStringSetting = "COSMOS_RECEIPTS_CONN_STRING")
+ OutputBinding cartForReceiptDocumentdb,
+ final ExecutionContext context) {
+ logger.info("[{}] function called at {}", context.getFunctionName(), LocalDateTime.now());
+
+ if (cartId == null || cartId.isBlank()) {
+ return request
+ .createResponseBuilder(HttpStatus.BAD_REQUEST)
+ .body(ProblemJson.builder()
+ .title(HttpStatus.BAD_REQUEST.name())
+ .detail("Please pass a valid transaction id")
+ .status(HttpStatus.BAD_REQUEST.value())
+ .build())
+ .build();
+ }
+
+ try {
+
+ CartForReceipt cartForReceipt = cartReceiptsCosmosClient.getCartItem(cartId);
+
+ if (!cartForReceipt.getStatus().equals(CartStatusType.FAILED) && !cartForReceipt.getStatus().equals(CartStatusType.INSERTED)) {
+ String responseMsg = String.format("The requested cart with transaction ID %s is not in the expected status",
+ cartForReceipt.getId());
+ return request
+ .createResponseBuilder(HttpStatus.INTERNAL_SERVER_ERROR)
+ .body(ProblemJson.builder()
+ .title(HttpStatus.INTERNAL_SERVER_ERROR.name())
+ .detail(responseMsg)
+ .status(HttpStatus.INTERNAL_SERVER_ERROR.value())
+ .build())
+ .build();
+ }
+
+ if (cartForReceipt.getTotalNotice() != cartForReceipt.getCartPaymentId().size()) {
+ logger.info("[{}] Not all items collected for cart with id {}, this event will be skipped",
+ context.getFunctionName(), cartForReceipt.getId());
+ return request
+ .createResponseBuilder(HttpStatus.BAD_REQUEST)
+ .body(ProblemJson.builder()
+ .title(HttpStatus.BAD_REQUEST.name())
+ .detail("Items not found on cart for the id")
+ .status(HttpStatus.BAD_REQUEST.value())
+ .build())
+ .build();
+ }
+
+ List bizEventList = this.bizEventToReceiptService.getCartBizEvents(cartForReceipt.getId());
+ Receipt receipt = this.bizEventToReceiptService.createCartReceipt(bizEventList);
+
+ if (!isReceiptStatusValid(receipt)) {
+ logger.error("[{}] Failed to process cart with id {}: fail to tokenize fiscal codes",
+ context.getFunctionName(), cartForReceipt.getId());
+ return request
+ .createResponseBuilder(HttpStatus.INTERNAL_SERVER_ERROR)
+ .body(ProblemJson.builder()
+ .title(HttpStatus.INTERNAL_SERVER_ERROR.name())
+ .detail("Failed to process cart: fail to tokenize fiscal codes")
+ .status(HttpStatus.INTERNAL_SERVER_ERROR.value())
+ .build())
+ .build();
+ }
+
+ // Add receipt to items to be saved on CosmosDB
+ this.bizEventToReceiptService.handleSaveReceipt(receipt);
+
+ if (!isReceiptStatusValid(receipt)) {
+ logger.error("[{}] Failed to process cart with id {}: fail to save receipt",
+ context.getFunctionName(), cartForReceipt.getId());
+ return request
+ .createResponseBuilder(HttpStatus.INTERNAL_SERVER_ERROR)
+ .body(ProblemJson.builder()
+ .title(HttpStatus.INTERNAL_SERVER_ERROR.name())
+ .detail("Failed to process cart: fail to save receipt")
+ .status(HttpStatus.INTERNAL_SERVER_ERROR.value())
+ .build())
+ .build();
+ }
+
+ // Send biz event as message to queue (to be processed from the other function)
+ this.bizEventToReceiptService.handleSendMessageToQueue(bizEventList, receipt);
+
+
+ if (!isReceiptStatusValid(receipt)) {
+ return request
+ .createResponseBuilder(HttpStatus.INTERNAL_SERVER_ERROR)
+ .body(ProblemJson.builder()
+ .title(HttpStatus.INTERNAL_SERVER_ERROR.name())
+ .detail("Failed to process cart: fail to send message queue")
+ .status(HttpStatus.INTERNAL_SERVER_ERROR.value())
+ .build())
+ .build();
+ }
+ cartForReceipt.setStatus(CartStatusType.SENT);
+ logger.info("[{}] Cart with id {} processes successfully. Cart with status: {} and receipt with status: {}",
+ context.getFunctionName(), cartForReceipt.getId(), cartForReceipt.getStatus(), receipt.getStatus());
+ cartForReceiptDocumentdb.setValue(cartForReceipt);
+ String responseMsg = String.format("Cart with id %s recovered", cartId);
+ return request.createResponseBuilder(HttpStatus.OK)
+ .body(responseMsg)
+ .build();
+
+ } catch (CartNotFoundException exception) {
+ String msg = String.format("Unable to retrieve the cart with id %s", cartId);
+ logger.error(msg, exception);
+ return request
+ .createResponseBuilder(HttpStatus.NOT_FOUND)
+ .body(ProblemJson.builder()
+ .title(HttpStatus.NOT_FOUND.name())
+ .detail(msg)
+ .status(HttpStatus.NOT_FOUND.value())
+ .build())
+ .build();
+ }
+
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/it/gov/pagopa/receipt/pdf/helpdesk/RecoverFailedCartMassive.java b/src/main/java/it/gov/pagopa/receipt/pdf/helpdesk/RecoverFailedCartMassive.java
new file mode 100644
index 00000000..08eb9465
--- /dev/null
+++ b/src/main/java/it/gov/pagopa/receipt/pdf/helpdesk/RecoverFailedCartMassive.java
@@ -0,0 +1,137 @@
+package it.gov.pagopa.receipt.pdf.helpdesk;
+
+import com.microsoft.azure.functions.*;
+import com.microsoft.azure.functions.annotation.AuthorizationLevel;
+import com.microsoft.azure.functions.annotation.CosmosDBOutput;
+import com.microsoft.azure.functions.annotation.FunctionName;
+import com.microsoft.azure.functions.annotation.HttpTrigger;
+import it.gov.pagopa.receipt.pdf.helpdesk.client.CartReceiptsCosmosClient;
+import it.gov.pagopa.receipt.pdf.helpdesk.client.impl.CartReceiptsCosmosClientImpl;
+import it.gov.pagopa.receipt.pdf.helpdesk.entity.cart.CartForReceipt;
+import it.gov.pagopa.receipt.pdf.helpdesk.entity.cart.CartStatusType;
+import it.gov.pagopa.receipt.pdf.helpdesk.model.MassiveRecoverCartResult;
+import it.gov.pagopa.receipt.pdf.helpdesk.model.ProblemJson;
+import it.gov.pagopa.receipt.pdf.helpdesk.service.BizEventToReceiptService;
+import it.gov.pagopa.receipt.pdf.helpdesk.service.impl.BizEventToReceiptServiceImpl;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.time.LocalDateTime;
+import java.util.List;
+import java.util.NoSuchElementException;
+import java.util.Optional;
+
+import static it.gov.pagopa.receipt.pdf.helpdesk.utils.BizEventToReceiptUtils.massiveRecoverCartByStatus;
+
+/**
+ * Azure Functions with Azure Http trigger.
+ */
+public class RecoverFailedCartMassive {
+
+ private final Logger logger = LoggerFactory.getLogger(RecoverFailedCartMassive.class);
+
+ private final BizEventToReceiptService bizEventToReceiptService;
+ private final CartReceiptsCosmosClient cartReceiptsCosmosClient;
+
+ public RecoverFailedCartMassive() {
+ this.bizEventToReceiptService = new BizEventToReceiptServiceImpl();
+ this.cartReceiptsCosmosClient = CartReceiptsCosmosClientImpl.getInstance();
+ }
+
+ RecoverFailedCartMassive(BizEventToReceiptService bizEventToReceiptService,
+ CartReceiptsCosmosClient cartReceiptsCosmosClient) {
+ this.bizEventToReceiptService = bizEventToReceiptService;
+ this.cartReceiptsCosmosClient = cartReceiptsCosmosClient;
+ }
+
+ /**
+ * This function will be invoked when a Http Trigger occurs.
+ *
+ * It recovers all the carts with the specified status that has to be one of:
+ * - ({@link it.gov.pagopa.receipt.pdf.helpdesk.entity.cart.CartStatusType#INSERTED})
+ * - ({@link it.gov.pagopa.receipt.pdf.helpdesk.entity.cart.CartStatusType#FAILED})
+ *
+ * It attempts to recreate and send receipt data based on cart having a failed or stuck status.
+ *
+ * @return response with {@link HttpStatus#OK} if the operation succeeded
+ */
+ @FunctionName("RecoverFailedCartMassive")
+ public HttpResponseMessage run(
+ @HttpTrigger(name = "RecoverFailedCartMassiveTrigger",
+ methods = {HttpMethod.POST},
+ route = "carts/recover-failed",
+ authLevel = AuthorizationLevel.ANONYMOUS)
+ HttpRequestMessage> request,
+ @CosmosDBOutput(
+ name = "CartReceiptDatastore",
+ databaseName = "db",
+ collectionName = "cart-for-receipt",
+ connectionStringSetting = "COSMOS_RECEIPTS_CONN_STRING")
+ OutputBinding> cartForReceiptDocumentdb,
+ final ExecutionContext context) {
+ logger.info("[{}] function called at {}", context.getFunctionName(), LocalDateTime.now());
+
+ // Get named parameter
+ String status = request.getQueryParameters().get("status");
+ if (status == null) {
+ return request
+ .createResponseBuilder(HttpStatus.BAD_REQUEST)
+ .body(ProblemJson.builder()
+ .title(HttpStatus.BAD_REQUEST.name())
+ .detail("Please pass a status to recover")
+ .status(HttpStatus.BAD_REQUEST.value())
+ .build())
+ .build();
+ }
+
+ CartStatusType statusType;
+ try {
+ statusType = CartStatusType.valueOf(status);
+ } catch (IllegalArgumentException e) {
+ return request
+ .createResponseBuilder(HttpStatus.BAD_REQUEST)
+ .body(ProblemJson.builder()
+ .title(HttpStatus.BAD_REQUEST.name())
+ .detail("Please pass a valid status to recover")
+ .status(HttpStatus.BAD_REQUEST.value())
+ .build())
+ .build();
+ }
+
+ MassiveRecoverCartResult recoverResult;
+ try {
+ recoverResult = massiveRecoverCartByStatus(
+ context, bizEventToReceiptService, cartReceiptsCosmosClient, logger, statusType);
+ } catch (Exception e) {
+ logger.error("[{}] Unexpected error during recover of failed cart", context.getFunctionName(), e);
+ return request
+ .createResponseBuilder(HttpStatus.INTERNAL_SERVER_ERROR)
+ .body(ProblemJson.builder()
+ .title(HttpStatus.INTERNAL_SERVER_ERROR.name())
+ .detail(e.getMessage())
+ .status(HttpStatus.INTERNAL_SERVER_ERROR.value())
+ .build())
+ .build();
+ }
+ List cartItems = recoverResult.getCartItems();
+ int errorCounter = recoverResult.getErrorCounter();
+
+ cartForReceiptDocumentdb.setValue(cartItems);
+ if (errorCounter > 0) {
+ String msg = String.format("Recovered %s carts but %s encountered an error.", cartItems.size(), errorCounter);
+ return request
+ .createResponseBuilder(HttpStatus.INTERNAL_SERVER_ERROR)
+ .body(ProblemJson.builder()
+ .title("Partial OK")
+ .detail(msg)
+ .status(HttpStatus.MULTI_STATUS.value())
+ .build())
+ .build();
+ }
+ String responseMsg = String.format("Recovered %s carts", cartItems.size());
+ return request.createResponseBuilder(HttpStatus.OK)
+ .body(responseMsg)
+ .build();
+ }
+
+}
\ No newline at end of file
diff --git a/src/main/java/it/gov/pagopa/receipt/pdf/helpdesk/RecoverFailedCartScheduled.java b/src/main/java/it/gov/pagopa/receipt/pdf/helpdesk/RecoverFailedCartScheduled.java
new file mode 100644
index 00000000..e55686f6
--- /dev/null
+++ b/src/main/java/it/gov/pagopa/receipt/pdf/helpdesk/RecoverFailedCartScheduled.java
@@ -0,0 +1,104 @@
+package it.gov.pagopa.receipt.pdf.helpdesk;
+
+import com.microsoft.azure.functions.ExecutionContext;
+import com.microsoft.azure.functions.OutputBinding;
+import com.microsoft.azure.functions.annotation.CosmosDBOutput;
+import com.microsoft.azure.functions.annotation.FunctionName;
+import com.microsoft.azure.functions.annotation.TimerTrigger;
+import it.gov.pagopa.receipt.pdf.helpdesk.client.BizEventCosmosClient;
+import it.gov.pagopa.receipt.pdf.helpdesk.client.CartReceiptsCosmosClient;
+import it.gov.pagopa.receipt.pdf.helpdesk.client.impl.BizEventCosmosClientImpl;
+import it.gov.pagopa.receipt.pdf.helpdesk.client.impl.CartReceiptsCosmosClientImpl;
+import it.gov.pagopa.receipt.pdf.helpdesk.entity.cart.CartForReceipt;
+import it.gov.pagopa.receipt.pdf.helpdesk.entity.cart.CartStatusType;
+import it.gov.pagopa.receipt.pdf.helpdesk.entity.receipt.Receipt;
+import it.gov.pagopa.receipt.pdf.helpdesk.entity.receipt.enumeration.ReceiptStatusType;
+import it.gov.pagopa.receipt.pdf.helpdesk.model.MassiveRecoverCartResult;
+import it.gov.pagopa.receipt.pdf.helpdesk.model.MassiveRecoverResult;
+import it.gov.pagopa.receipt.pdf.helpdesk.service.BizEventToReceiptService;
+import it.gov.pagopa.receipt.pdf.helpdesk.service.ReceiptCosmosService;
+import it.gov.pagopa.receipt.pdf.helpdesk.service.impl.BizEventToReceiptServiceImpl;
+import it.gov.pagopa.receipt.pdf.helpdesk.service.impl.ReceiptCosmosServiceImpl;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.time.LocalDateTime;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.NoSuchElementException;
+
+import static it.gov.pagopa.receipt.pdf.helpdesk.utils.BizEventToReceiptUtils.massiveRecoverByStatus;
+import static it.gov.pagopa.receipt.pdf.helpdesk.utils.BizEventToReceiptUtils.massiveRecoverCartByStatus;
+
+/**
+ * Azure Functions with Timer trigger.
+ */
+public class RecoverFailedCartScheduled {
+
+ private final Logger logger = LoggerFactory.getLogger(RecoverFailedCartScheduled.class);
+
+ private final boolean isEnabled = Boolean.parseBoolean(System.getenv().getOrDefault("FAILED_CART_AUTORECOVER_ENABLED", "true"));
+
+ private final BizEventToReceiptService bizEventToReceiptService;
+
+ private final CartReceiptsCosmosClient cartReceiptsCosmosClient;
+
+ public RecoverFailedCartScheduled() {
+ this.bizEventToReceiptService = new BizEventToReceiptServiceImpl();
+ this.cartReceiptsCosmosClient = CartReceiptsCosmosClientImpl.getInstance();
+ }
+
+ RecoverFailedCartScheduled(BizEventToReceiptService bizEventToReceiptService,
+ CartReceiptsCosmosClient cartReceiptsCosmosClient) {
+ this.bizEventToReceiptService = bizEventToReceiptService;
+ this.cartReceiptsCosmosClient = cartReceiptsCosmosClient;
+ }
+
+ /**
+ * This function will be invoked periodically according to the specified schedule.
+ *
+ * It recovers all the receipts with the following status:
+ * - ({@link it.gov.pagopa.receipt.pdf.helpdesk.entity.cart.CartStatusType#INSERTED})
+ * - ({@link it.gov.pagopa.receipt.pdf.helpdesk.entity.cart.CartStatusType#FAILED})
+ *
+ * It creates the receipts if not exist and send on queue the event in order to proceed with the receipt generation.
+ */
+ @FunctionName("RecoverFailedCartScheduled")
+ public void run(
+ @TimerTrigger(name = "timerInfo", schedule = "%RECOVER_FAILED_CART_CRON%") String timerInfo,
+ @CosmosDBOutput(
+ name = "CartReceiptDatastore",
+ databaseName = "db",
+ collectionName = "cart-for-receipt",
+ connectionStringSetting = "COSMOS_RECEIPTS_CONN_STRING")
+ OutputBinding> cartForReceiptDocumentdb,
+ final ExecutionContext context
+ ) {
+ if (isEnabled) {
+ logger.info("[{}] function called at {}", context.getFunctionName(), LocalDateTime.now());
+ List cartForReceipts = new ArrayList<>();
+
+ cartForReceipts.addAll(recover(context, CartStatusType.INSERTED));
+ cartForReceipts.addAll(recover(context, CartStatusType.FAILED));
+
+ cartForReceiptDocumentdb.setValue(cartForReceipts);
+ }
+ }
+
+ private List recover(ExecutionContext context, CartStatusType statusType) {
+ try {
+ MassiveRecoverCartResult recoverResult = massiveRecoverCartByStatus(
+ context, bizEventToReceiptService, cartReceiptsCosmosClient, logger, statusType);
+ if (recoverResult.getErrorCounter() > 0) {
+ logger.error("[{}] Error recovering {} failed cart for status {}",
+ context.getFunctionName(), recoverResult.getErrorCounter(), statusType);
+ }
+ return recoverResult.getCartItems();
+ } catch (Exception e) {
+ logger.error("[{}] Unexpected error during recover of failed cart for status {}",
+ context.getFunctionName(), statusType, e);
+ return Collections.emptyList();
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/it/gov/pagopa/receipt/pdf/helpdesk/RecoverFailedReceipt.java b/src/main/java/it/gov/pagopa/receipt/pdf/helpdesk/RecoverFailedReceipt.java
index f36b8441..3e86c87e 100644
--- a/src/main/java/it/gov/pagopa/receipt/pdf/helpdesk/RecoverFailedReceipt.java
+++ b/src/main/java/it/gov/pagopa/receipt/pdf/helpdesk/RecoverFailedReceipt.java
@@ -95,9 +95,12 @@ public HttpResponseMessage run (
.build();
}
+ Boolean isCart = Boolean.parseBoolean(request.getQueryParameters().getOrDefault(
+ "isCart", "false"));
+
try {
Receipt receipt = BizEventToReceiptUtils.getEvent(eventId, context, this.bizEventToReceiptService,
- this.bizEventCosmosClient, this.receiptCosmosService, null, logger);
+ this.bizEventCosmosClient, this.receiptCosmosService, null, logger, isCart);
documentdb.setValue(receipt);
String responseMsg = String.format("Receipt with eventId %s recovered", eventId);
diff --git a/src/main/java/it/gov/pagopa/receipt/pdf/helpdesk/RecoverNotNotifiedReceipt.java b/src/main/java/it/gov/pagopa/receipt/pdf/helpdesk/RecoverNotNotifiedReceipt.java
index 70a49fb3..b0ed5b64 100644
--- a/src/main/java/it/gov/pagopa/receipt/pdf/helpdesk/RecoverNotNotifiedReceipt.java
+++ b/src/main/java/it/gov/pagopa/receipt/pdf/helpdesk/RecoverNotNotifiedReceipt.java
@@ -11,8 +11,10 @@
import com.microsoft.azure.functions.annotation.CosmosDBOutput;
import com.microsoft.azure.functions.annotation.FunctionName;
import com.microsoft.azure.functions.annotation.HttpTrigger;
+import it.gov.pagopa.receipt.pdf.helpdesk.entity.event.BizEvent;
import it.gov.pagopa.receipt.pdf.helpdesk.entity.receipt.Receipt;
import it.gov.pagopa.receipt.pdf.helpdesk.entity.receipt.enumeration.ReceiptStatusType;
+import it.gov.pagopa.receipt.pdf.helpdesk.exception.CartNotFoundException;
import it.gov.pagopa.receipt.pdf.helpdesk.exception.ReceiptNotFoundException;
import it.gov.pagopa.receipt.pdf.helpdesk.model.ProblemJson;
import it.gov.pagopa.receipt.pdf.helpdesk.service.ReceiptCosmosService;
diff --git a/src/main/java/it/gov/pagopa/receipt/pdf/helpdesk/RegenerateReceiptPdf.java b/src/main/java/it/gov/pagopa/receipt/pdf/helpdesk/RegenerateReceiptPdf.java
index 1f4cfc61..a5be8265 100644
--- a/src/main/java/it/gov/pagopa/receipt/pdf/helpdesk/RegenerateReceiptPdf.java
+++ b/src/main/java/it/gov/pagopa/receipt/pdf/helpdesk/RegenerateReceiptPdf.java
@@ -23,6 +23,8 @@
import java.io.IOException;
import java.nio.file.Path;
import java.time.LocalDateTime;
+import java.util.Collections;
+import java.util.List;
import java.util.Optional;
import static it.gov.pagopa.receipt.pdf.helpdesk.utils.GenerateReceiptUtils.*;
@@ -85,7 +87,18 @@ public HttpResponseMessage run (
try {
- BizEvent bizEvent = bizEventCosmosClient.getBizEventDocument(eventId);
+ Boolean isCart = Boolean.parseBoolean(request.getQueryParameters().getOrDefault(
+ "isCart", "false"));
+
+ BizEvent bizEvent;
+ List listBizEvent = null;
+
+ if (isCart) {
+ listBizEvent = bizEventToReceiptService.getCartBizEvents(eventId);
+ bizEvent = listBizEvent.get(0);
+ } else {
+ bizEvent = bizEventCosmosClient.getBizEventDocument(eventId);
+ }
//Retrieve receipt's data from CosmosDB
Receipt receipt = getReceipt(context, bizEvent, receiptCosmosClient, logger);
@@ -107,7 +120,8 @@ && isHasAllAttachments(receipt)
if (receipt.getEventData().getDebtorFiscalCode() == null ||
receipt.getEventData().getPayerFiscalCode() == null) {
- BizEventToReceiptUtils.tokenizeReceipt(bizEventToReceiptService, bizEvent, receipt);
+ BizEventToReceiptUtils.tokenizeReceipt(bizEventToReceiptService, isCart ?
+ listBizEvent : Collections.singletonList(bizEvent), receipt);
documentdb.setValue(receipt);
}
@@ -117,7 +131,8 @@ && isHasAllAttachments(receipt)
documentdb.setValue(receipt);
}
- pdfGeneration = generateReceiptPdfService.generateReceipts(receipt, bizEvent, workingDirPath);
+ pdfGeneration = generateReceiptPdfService.generateReceipts(receipt, isCart ?
+ listBizEvent : Collections.singletonList(bizEvent), workingDirPath);
//Verify PDF generation success
boolean success = true;
diff --git a/src/main/java/it/gov/pagopa/receipt/pdf/helpdesk/client/BizEventCosmosClient.java b/src/main/java/it/gov/pagopa/receipt/pdf/helpdesk/client/BizEventCosmosClient.java
index d9422a71..f9905f17 100644
--- a/src/main/java/it/gov/pagopa/receipt/pdf/helpdesk/client/BizEventCosmosClient.java
+++ b/src/main/java/it/gov/pagopa/receipt/pdf/helpdesk/client/BizEventCosmosClient.java
@@ -1,5 +1,6 @@
package it.gov.pagopa.receipt.pdf.helpdesk.client;
+import com.azure.cosmos.models.FeedResponse;
import it.gov.pagopa.receipt.pdf.helpdesk.entity.event.BizEvent;
import it.gov.pagopa.receipt.pdf.helpdesk.exception.BizEventNotFoundException;
@@ -23,4 +24,14 @@ public interface BizEventCosmosClient {
* @throws BizEventNotFoundException in case no biz-event has been found with the given idEvent
*/
BizEvent getBizEventDocumentByOrganizationFiscalCodeAndIUV(String organizationFiscalCode, String iuv) throws BizEventNotFoundException;
+
+ /**
+ * Retrieve all biz-event documents related to a specific cart from CosmosDB database
+ *
+ * @param transactionId id that identifies the cart
+ * @param continuationToken Paged query continuation token
+ * @param pageSize the page size
+ * @return a list of biz-event document
+ */
+ Iterable> getAllBizEventDocument(String transactionId, String continuationToken, Integer pageSize);
}
diff --git a/src/main/java/it/gov/pagopa/receipt/pdf/helpdesk/client/CartReceiptsCosmosClient.java b/src/main/java/it/gov/pagopa/receipt/pdf/helpdesk/client/CartReceiptsCosmosClient.java
new file mode 100644
index 00000000..69489ec1
--- /dev/null
+++ b/src/main/java/it/gov/pagopa/receipt/pdf/helpdesk/client/CartReceiptsCosmosClient.java
@@ -0,0 +1,18 @@
+package it.gov.pagopa.receipt.pdf.helpdesk.client;
+
+import com.azure.cosmos.models.CosmosItemResponse;
+import com.azure.cosmos.models.FeedResponse;
+import it.gov.pagopa.receipt.pdf.helpdesk.entity.cart.CartForReceipt;
+import it.gov.pagopa.receipt.pdf.helpdesk.entity.cart.CartStatusType;
+import it.gov.pagopa.receipt.pdf.helpdesk.exception.CartNotFoundException;
+
+public interface CartReceiptsCosmosClient {
+
+ CartForReceipt getCartItem(String eventId) throws CartNotFoundException;
+
+ CosmosItemResponse saveCart(CartForReceipt receipt);
+
+ Iterable> getFailedCarts(String continuationToken, int size);
+
+ Iterable> getInsertedCarts(String continuationToken, int size);
+}
diff --git a/src/main/java/it/gov/pagopa/receipt/pdf/helpdesk/client/impl/BizEventCosmosClientImpl.java b/src/main/java/it/gov/pagopa/receipt/pdf/helpdesk/client/impl/BizEventCosmosClientImpl.java
index a71dcd34..0cdff8ff 100644
--- a/src/main/java/it/gov/pagopa/receipt/pdf/helpdesk/client/impl/BizEventCosmosClientImpl.java
+++ b/src/main/java/it/gov/pagopa/receipt/pdf/helpdesk/client/impl/BizEventCosmosClientImpl.java
@@ -5,6 +5,7 @@
import com.azure.cosmos.CosmosContainer;
import com.azure.cosmos.CosmosDatabase;
import com.azure.cosmos.models.CosmosQueryRequestOptions;
+import com.azure.cosmos.models.FeedResponse;
import com.azure.cosmos.util.CosmosPagedIterable;
import it.gov.pagopa.receipt.pdf.helpdesk.client.BizEventCosmosClient;
import it.gov.pagopa.receipt.pdf.helpdesk.entity.event.BizEvent;
@@ -84,4 +85,23 @@ public BizEvent getBizEventDocumentByOrganizationFiscalCodeAndIUV(String organiz
}
throw new BizEventNotFoundException("Document not found in the defined container");
}
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Iterable> getAllBizEventDocument(String transactionId, String continuationToken, Integer pageSize) {
+ CosmosDatabase cosmosDatabase = this.cosmosClient.getDatabase(databaseId);
+ CosmosContainer cosmosContainer = cosmosDatabase.getContainer(containerId);
+
+ //Build query
+ String query = String.format("SELECT * FROM c WHERE c.transactionDetails.transaction.transactionId = '%s'",
+ transactionId);
+
+ //Query the container
+ return cosmosContainer
+ .queryItems(query, new CosmosQueryRequestOptions(), BizEvent.class)
+ .iterableByPage(continuationToken, pageSize);
+ }
+
}
diff --git a/src/main/java/it/gov/pagopa/receipt/pdf/helpdesk/client/impl/CartReceiptsCosmosClientImpl.java b/src/main/java/it/gov/pagopa/receipt/pdf/helpdesk/client/impl/CartReceiptsCosmosClientImpl.java
new file mode 100644
index 00000000..0f1be3a9
--- /dev/null
+++ b/src/main/java/it/gov/pagopa/receipt/pdf/helpdesk/client/impl/CartReceiptsCosmosClientImpl.java
@@ -0,0 +1,131 @@
+package it.gov.pagopa.receipt.pdf.helpdesk.client.impl;
+
+import com.azure.cosmos.*;
+import com.azure.cosmos.models.CosmosItemResponse;
+import com.azure.cosmos.models.CosmosQueryRequestOptions;
+import com.azure.cosmos.models.FeedResponse;
+import com.azure.cosmos.util.CosmosPagedIterable;
+import it.gov.pagopa.receipt.pdf.helpdesk.client.CartReceiptsCosmosClient;
+import it.gov.pagopa.receipt.pdf.helpdesk.entity.cart.CartForReceipt;
+import it.gov.pagopa.receipt.pdf.helpdesk.entity.cart.CartStatusType;
+import it.gov.pagopa.receipt.pdf.helpdesk.entity.receipt.enumeration.ReceiptStatusType;
+import it.gov.pagopa.receipt.pdf.helpdesk.exception.CartNotFoundException;
+import it.gov.pagopa.receipt.pdf.helpdesk.exception.ReceiptNotFoundException;
+
+import java.time.OffsetDateTime;
+import java.time.temporal.ChronoUnit;
+
+public class CartReceiptsCosmosClientImpl implements CartReceiptsCosmosClient {
+
+ private static CartReceiptsCosmosClientImpl instance;
+ private final String databaseId = System.getenv("COSMOS_RECEIPT_DB_NAME");
+ private final String cartForReceiptContainerName = System.getenv("CART_FOR_RECEIPT_CONTAINER_NAME");
+
+ private final String millisDiff = System.getenv("MAX_DATE_DIFF_CART_MILLIS");
+
+ private final String numDaysCartNotSent = System.getenv().getOrDefault("RECOVER_CART_MASSIVE_MAX_DAYS", "0");
+
+
+ private final CosmosClient cosmosClient;
+
+ private CartReceiptsCosmosClientImpl() {
+ String azureKey = System.getenv("COSMOS_RECEIPT_KEY");
+ String serviceEndpoint = System.getenv("COSMOS_RECEIPT_SERVICE_ENDPOINT");
+
+ this.cosmosClient = new CosmosClientBuilder()
+ .endpoint(serviceEndpoint)
+ .key(azureKey)
+ .consistencyLevel(ConsistencyLevel.STRONG)
+ .buildClient();
+ }
+
+ public CartReceiptsCosmosClientImpl(CosmosClient cosmosClient) {
+ this.cosmosClient = cosmosClient;
+ }
+
+ public static CartReceiptsCosmosClientImpl getInstance() {
+ if (instance == null) {
+ instance = new CartReceiptsCosmosClientImpl();
+ }
+
+ return instance;
+ }
+
+ /**
+ * Retrieve receipt document from CosmosDB database
+ *
+ * @param eventId Biz-event id
+ * @return receipt document
+ * @throws ReceiptNotFoundException in case no receipt has been found with the given idEvent
+ */
+ @Override
+ public CartForReceipt getCartItem(String eventId) throws CartNotFoundException {
+ CosmosDatabase cosmosDatabase = this.cosmosClient.getDatabase(databaseId);
+
+ CosmosContainer cosmosContainer = cosmosDatabase.getContainer(cartForReceiptContainerName);
+
+ //Build query
+ String query = "SELECT * FROM c WHERE c.id = " + "'" + eventId + "'";
+
+ //Query the container
+ CosmosPagedIterable queryResponse = cosmosContainer
+ .queryItems(query, new CosmosQueryRequestOptions(), CartForReceipt.class);
+
+ if (queryResponse.iterator().hasNext()) {
+ return queryResponse.iterator().next();
+ } else {
+ throw new CartNotFoundException("Document not found in the defined container");
+ }
+
+ }
+
+ /**
+ * Save Cart For Receipt on CosmosDB database
+ *
+ * @param receipt Cart Data to save
+ * @return cart-to-receipts documents
+ */
+ @Override
+ public CosmosItemResponse saveCart(CartForReceipt receipt) {
+ CosmosDatabase cosmosDatabase = this.cosmosClient.getDatabase(databaseId);
+ CosmosContainer cosmosContainer = cosmosDatabase.getContainer(cartForReceiptContainerName);
+ return cosmosContainer.createItem(receipt);
+ }
+
+ @Override
+ public Iterable> getFailedCarts(String continuationToken, int size) {
+ CosmosDatabase cosmosDatabase = this.cosmosClient.getDatabase(databaseId);
+ CosmosContainer cosmosContainer = cosmosDatabase.getContainer(cartForReceiptContainerName);
+
+ //Build query
+ String query = String.format("SELECT * FROM c WHERE (c.status = '%s') AND c._ts >= %s",
+ CartStatusType.FAILED,
+ OffsetDateTime.now().truncatedTo(ChronoUnit.DAYS).minusDays(
+ Long.parseLong(numDaysCartNotSent)).toInstant().toEpochMilli());
+
+ //Query the container
+ return cosmosContainer
+ .queryItems(query, new CosmosQueryRequestOptions(), CartForReceipt.class)
+ .iterableByPage(continuationToken,size);
+ }
+
+ @Override
+ public Iterable> getInsertedCarts(String continuationToken, int size) {
+ CosmosDatabase cosmosDatabase = this.cosmosClient.getDatabase(databaseId);
+ CosmosContainer cosmosContainer = cosmosDatabase.getContainer(cartForReceiptContainerName);
+
+ //Build query
+ String query = String.format("SELECT * FROM c WHERE (c.status = '%s' AND c._ts >= %s " +
+ "AND ( %s - c._ts) >= %s)",
+ ReceiptStatusType.INSERTED,
+ OffsetDateTime.now().truncatedTo(ChronoUnit.DAYS).minusDays(
+ Long.parseLong(numDaysCartNotSent)).toInstant().toEpochMilli(),
+ OffsetDateTime.now().toInstant().toEpochMilli(), millisDiff);
+
+ //Query the container
+ return cosmosContainer
+ .queryItems(query, new CosmosQueryRequestOptions(), CartForReceipt.class)
+ .iterableByPage(continuationToken,100);
+ }
+
+}
diff --git a/src/main/java/it/gov/pagopa/receipt/pdf/helpdesk/entity/cart/CartForReceipt.java b/src/main/java/it/gov/pagopa/receipt/pdf/helpdesk/entity/cart/CartForReceipt.java
index 444cfb5e..78c4c496 100644
--- a/src/main/java/it/gov/pagopa/receipt/pdf/helpdesk/entity/cart/CartForReceipt.java
+++ b/src/main/java/it/gov/pagopa/receipt/pdf/helpdesk/entity/cart/CartForReceipt.java
@@ -13,10 +13,9 @@
@Builder
@Data
public class CartForReceipt {
-
private String id;
private Set cartPaymentId;
private Integer totalNotice;
private CartStatusType status;
private ReasonError reasonError;
-}
\ No newline at end of file
+}
diff --git a/src/main/java/it/gov/pagopa/receipt/pdf/helpdesk/model/MassiveRecoverCartResult.java b/src/main/java/it/gov/pagopa/receipt/pdf/helpdesk/model/MassiveRecoverCartResult.java
new file mode 100644
index 00000000..9f47f668
--- /dev/null
+++ b/src/main/java/it/gov/pagopa/receipt/pdf/helpdesk/model/MassiveRecoverCartResult.java
@@ -0,0 +1,17 @@
+package it.gov.pagopa.receipt.pdf.helpdesk.model;
+
+import it.gov.pagopa.receipt.pdf.helpdesk.entity.cart.CartForReceipt;
+import it.gov.pagopa.receipt.pdf.helpdesk.entity.receipt.CartItem;
+import it.gov.pagopa.receipt.pdf.helpdesk.entity.receipt.Receipt;
+import lombok.Builder;
+import lombok.Data;
+
+import java.util.List;
+
+@Data
+@Builder
+public class MassiveRecoverCartResult {
+
+ private List cartItems;
+ private int errorCounter;
+}
diff --git a/src/main/java/it/gov/pagopa/receipt/pdf/helpdesk/service/BizEventToReceiptService.java b/src/main/java/it/gov/pagopa/receipt/pdf/helpdesk/service/BizEventToReceiptService.java
index ad494ef1..ae9b0055 100644
--- a/src/main/java/it/gov/pagopa/receipt/pdf/helpdesk/service/BizEventToReceiptService.java
+++ b/src/main/java/it/gov/pagopa/receipt/pdf/helpdesk/service/BizEventToReceiptService.java
@@ -7,16 +7,17 @@
import it.gov.pagopa.receipt.pdf.helpdesk.entity.receipt.Receipt;
import it.gov.pagopa.receipt.pdf.helpdesk.exception.PDVTokenizerException;
+import java.util.List;
+
public interface BizEventToReceiptService {
/**
* Handles sending biz-events as message to queue and updates receipt's status
*
- * @param bizEvent Biz-event from CosmosDB
+ * @param bizEventList Biz-event list from CosmosDB
* @param receipt Receipt to update
*/
- void handleSendMessageToQueue(BizEvent bizEvent, Receipt receipt);
-
+ void handleSendMessageToQueue(List bizEventList, Receipt receipt);
/**
* Retrieve conditionally the transaction creation date from biz-event
@@ -36,4 +37,23 @@ public interface BizEventToReceiptService {
* @throws PDVTokenizerException if an error occur when invoking the PDV Tokenizer
*/
void tokenizeFiscalCodes(BizEvent bizEvent, Receipt receipt, EventData eventData) throws JsonProcessingException, PDVTokenizerException;
+
+ void handleSaveReceipt(Receipt receipt);
+
+ /**
+ * Retrieve all events that are associated to the cart with the specified id
+ *
+ * @param cartId the id of the cart
+ * @return a list of biz-events
+ */
+ List getCartBizEvents(String cartId);
+
+ /**
+ * Creates the receipt for a cart, using the tokenizer service to mask the PII, based on
+ * the provided list of BizEvent
+ *
+ * @param bizEventList a list og BizEvent
+ * @return a receipt
+ */
+ Receipt createCartReceipt(List bizEventList);
}
diff --git a/src/main/java/it/gov/pagopa/receipt/pdf/helpdesk/service/BuildTemplateService.java b/src/main/java/it/gov/pagopa/receipt/pdf/helpdesk/service/BuildTemplateService.java
index b2206fbd..b833bb07 100644
--- a/src/main/java/it/gov/pagopa/receipt/pdf/helpdesk/service/BuildTemplateService.java
+++ b/src/main/java/it/gov/pagopa/receipt/pdf/helpdesk/service/BuildTemplateService.java
@@ -5,18 +5,20 @@
import it.gov.pagopa.receipt.pdf.helpdesk.exception.TemplateDataMappingException;
import it.gov.pagopa.receipt.pdf.helpdesk.model.template.ReceiptPDFTemplate;
+import java.util.List;
+
public interface BuildTemplateService {
/**
* Maps a bizEvent to the json needed to compile the template
*
- * @param bizEvent Biz-event from queue message
+ * @param bizEvents Biz-events from queue message
* @param partialTemplate boolean that indicates the type of template
* @param receipt Receipt from CosmosDB
* @return {@link ReceiptPDFTemplate} compiled template
* @throws {@link TemplateDataMappingException} when mandatory fields are missing
*/
- ReceiptPDFTemplate buildTemplate(BizEvent bizEvent, boolean partialTemplate, Receipt receipt) throws TemplateDataMappingException;
+ ReceiptPDFTemplate buildTemplate(List bizEvents, boolean partialTemplate, Receipt receipt) throws TemplateDataMappingException;
}
diff --git a/src/main/java/it/gov/pagopa/receipt/pdf/helpdesk/service/GenerateReceiptPdfService.java b/src/main/java/it/gov/pagopa/receipt/pdf/helpdesk/service/GenerateReceiptPdfService.java
index 7ed5ba6c..799a7751 100644
--- a/src/main/java/it/gov/pagopa/receipt/pdf/helpdesk/service/GenerateReceiptPdfService.java
+++ b/src/main/java/it/gov/pagopa/receipt/pdf/helpdesk/service/GenerateReceiptPdfService.java
@@ -6,6 +6,7 @@
import it.gov.pagopa.receipt.pdf.helpdesk.model.PdfGeneration;
import java.nio.file.Path;
+import java.util.List;
public interface GenerateReceiptPdfService {
@@ -13,10 +14,10 @@ public interface GenerateReceiptPdfService {
* Handles conditionally the generation of the PDF's receipts based on the provided bizEvent
*
* @param receipt the Receipt that hold the status of the elaboration
- * @param bizEvent Biz-event from queue message
+ * @param bizEvents Biz-events from queue message
* @return {@link PdfGeneration} object with the result of the PDF generation and store or the relatives error messages
*/
- PdfGeneration generateReceipts(Receipt receipt, BizEvent bizEvent, Path workingDirPath);
+ PdfGeneration generateReceipts(Receipt receipt, List bizEvents, Path workingDirPath);
/**
* Verifies if the PDF generation process succeeded or not, and update the receipt with the result
diff --git a/src/main/java/it/gov/pagopa/receipt/pdf/helpdesk/service/impl/BizEventToReceiptServiceImpl.java b/src/main/java/it/gov/pagopa/receipt/pdf/helpdesk/service/impl/BizEventToReceiptServiceImpl.java
index a4896615..a8337a2d 100644
--- a/src/main/java/it/gov/pagopa/receipt/pdf/helpdesk/service/impl/BizEventToReceiptServiceImpl.java
+++ b/src/main/java/it/gov/pagopa/receipt/pdf/helpdesk/service/impl/BizEventToReceiptServiceImpl.java
@@ -2,14 +2,18 @@
import com.azure.core.http.rest.Response;
import com.azure.cosmos.models.CosmosItemResponse;
+import com.azure.cosmos.models.FeedResponse;
import com.azure.storage.queue.models.SendMessageResult;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.microsoft.azure.functions.HttpStatus;
+import it.gov.pagopa.receipt.pdf.helpdesk.client.BizEventCosmosClient;
import it.gov.pagopa.receipt.pdf.helpdesk.client.ReceiptCosmosClient;
import it.gov.pagopa.receipt.pdf.helpdesk.client.ReceiptQueueClient;
+import it.gov.pagopa.receipt.pdf.helpdesk.client.impl.BizEventCosmosClientImpl;
import it.gov.pagopa.receipt.pdf.helpdesk.client.impl.ReceiptCosmosClientImpl;
import it.gov.pagopa.receipt.pdf.helpdesk.client.impl.ReceiptQueueClientImpl;
import it.gov.pagopa.receipt.pdf.helpdesk.entity.event.BizEvent;
+import it.gov.pagopa.receipt.pdf.helpdesk.entity.receipt.CartItem;
import it.gov.pagopa.receipt.pdf.helpdesk.entity.receipt.EventData;
import it.gov.pagopa.receipt.pdf.helpdesk.entity.receipt.ReasonError;
import it.gov.pagopa.receipt.pdf.helpdesk.entity.receipt.Receipt;
@@ -22,9 +26,12 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import java.math.BigDecimal;
import java.nio.charset.StandardCharsets;
-import java.util.Base64;
-import java.util.Objects;
+import java.util.*;
+import java.util.concurrent.atomic.AtomicReference;
+
+import static it.gov.pagopa.receipt.pdf.helpdesk.utils.BizEventToReceiptUtils.getItemSubject;
public class BizEventToReceiptServiceImpl implements BizEventToReceiptService {
@@ -33,35 +40,48 @@ public class BizEventToReceiptServiceImpl implements BizEventToReceiptService {
private final PDVTokenizerServiceRetryWrapper pdvTokenizerService;
private final ReceiptQueueClient queueClient;
+ private final BizEventCosmosClient bizEventCosmosClient;
+
+ private final ReceiptCosmosClient receiptCosmosClient;
+
public BizEventToReceiptServiceImpl() {
this.pdvTokenizerService = new PDVTokenizerServiceRetryWrapperImpl();
this.queueClient = ReceiptQueueClientImpl.getInstance();
+ this.bizEventCosmosClient = BizEventCosmosClientImpl.getInstance();
+ this.receiptCosmosClient = ReceiptCosmosClientImpl.getInstance();
}
- public BizEventToReceiptServiceImpl(PDVTokenizerServiceRetryWrapper pdvTokenizerService, ReceiptQueueClient queueClient) {
+ public BizEventToReceiptServiceImpl(PDVTokenizerServiceRetryWrapper pdvTokenizerService,
+ ReceiptQueueClient queueClient, BizEventCosmosClient bizEventCosmosClient,
+ ReceiptCosmosClient receiptCosmosClient) {
this.pdvTokenizerService = pdvTokenizerService;
this.queueClient = queueClient;
+ this.bizEventCosmosClient = bizEventCosmosClient;
+ this.receiptCosmosClient = receiptCosmosClient;
}
/**
* {@inheritDoc}
*/
@Override
- public void handleSendMessageToQueue(BizEvent bizEvent, Receipt receipt) {
+ public void handleSendMessageToQueue(List bizEventList, Receipt receipt) {
//Encode biz-event to base64 string
String messageText = Base64.getMimeEncoder().encodeToString(
- Objects.requireNonNull(ObjectMapperUtils.writeValueAsString(bizEvent)).getBytes(StandardCharsets.UTF_8)
- );
+ Objects.requireNonNull(ObjectMapperUtils.writeValueAsString(bizEventList)).getBytes(StandardCharsets.UTF_8));
//Add message to the queue
int statusCode;
try {
Response sendMessageResult = queueClient.sendMessageToQueue(messageText);
-
statusCode = sendMessageResult.getStatusCode();
} catch (Exception e) {
statusCode = ReasonErrorCode.ERROR_QUEUE.getCode();
- logger.error(String.format("Sending BizEvent with id %s to queue failed", bizEvent.getId()), e);
+ if (bizEventList.size() == 1) {
+ logger.error("Sending BizEvent with id {} to queue failed", bizEventList.get(0).getId(), e);
+ } else {
+ logger.error("Failed to enqueue cart with id {}",
+ bizEventList.get(0).getTransactionDetails().getTransaction().getIdTransaction(), e);
+ }
}
if (statusCode != HttpStatus.CREATED.value()) {
@@ -131,6 +151,34 @@ public void tokenizeFiscalCodes(BizEvent bizEvent, Receipt receipt, EventData ev
}
}
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void handleSaveReceipt(Receipt receipt) {
+ int statusCode;
+
+ try {
+ receipt.setStatus(ReceiptStatusType.INSERTED);
+ receipt.setInsertedAt(System.currentTimeMillis());
+ CosmosItemResponse response = receiptCosmosClient.saveReceipts(receipt);
+
+ statusCode = response.getStatusCode();
+ } catch (Exception e) {
+ statusCode = ReasonErrorCode.ERROR_COSMOS.getCode();
+ logger.error("Save receipt with eventId {} on cosmos failed", receipt.getEventId(), e);
+ }
+
+ if (statusCode != (HttpStatus.CREATED.value())) {
+ String errorString = String.format(
+ "[BizEventToReceiptService] Error saving receipt to cosmos for receipt with eventId %s, cosmos client responded with status %s",
+ receipt.getEventId(), statusCode);
+ handleError(receipt, ReceiptStatusType.FAILED, errorString, statusCode);
+ //Error info
+ logger.error(errorString);
+ }
+ }
+
/**
* Handles errors for PDV tokenizer and updates receipt's status accordingly
*
@@ -143,4 +191,82 @@ private void handleTokenizerException(Receipt receipt, String errorMessage, int
ReasonError reasonError = new ReasonError(statusCode, errorMessage);
receipt.setReasonErr(reasonError);
}
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public List getCartBizEvents(String cartId) {
+ List bizEventList = new ArrayList<>();
+ String continuationToken = null;
+ do {
+ Iterable> feedResponseIterator =
+ this.bizEventCosmosClient.getAllBizEventDocument(cartId, continuationToken, 100);
+
+ for (FeedResponse page : feedResponseIterator) {
+ bizEventList.addAll(page.getResults());
+ continuationToken = page.getContinuationToken();
+ }
+ } while (continuationToken != null);
+ return bizEventList;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Receipt createCartReceipt(List bizEventList) {
+ Receipt receipt = new Receipt();
+ BizEvent firstBizEvent = bizEventList.get(0);
+ String carId = firstBizEvent.getTransactionDetails().getTransaction().getTransactionId();
+
+ // Insert biz-event data into receipt
+ receipt.setId(String.format("%s-%s", carId, UUID.randomUUID()));
+ receipt.setEventId(carId);
+ receipt.setIsCart(true);
+
+ EventData eventData = new EventData();
+ try {
+ this.tokenizeFiscalCodes(firstBizEvent, receipt, eventData);
+ } catch (Exception e) {
+ logger.error("Error tokenizing receipt for cart with id {}", carId, e);
+ receipt.setStatus(ReceiptStatusType.FAILED);
+ return receipt;
+ }
+
+ eventData.setTransactionCreationDate(this.getTransactionCreationDate(firstBizEvent));
+
+ AtomicReference amount = new AtomicReference<>(BigDecimal.ZERO);
+ List cartItems = new ArrayList<>();
+ bizEventList.forEach(bizEvent -> {
+ BigDecimal amountExtracted = getAmount(bizEvent);
+ amount.updateAndGet(v -> v.add(amountExtracted));
+ cartItems.add(
+ CartItem.builder()
+ .payeeName(bizEvent.getCreditor() != null ? bizEvent.getCreditor().getCompanyName() : null)
+ .subject(getItemSubject(bizEvent))
+ .build());
+ });
+
+ if (!amount.get().equals(BigDecimal.ZERO)) {
+ eventData.setAmount(amount.get().toString());
+ }
+
+ eventData.setCart(cartItems);
+
+ receipt.setEventData(eventData);
+ return receipt;
+ }
+
+ public static BigDecimal getAmount(BizEvent bizEvent) {
+ if (bizEvent.getTransactionDetails() != null && bizEvent.getTransactionDetails().getTransaction() != null
+ && bizEvent.getTransactionDetails().getTransaction().getGrandTotal() != 0) {
+ return new BigDecimal(bizEvent.getTransactionDetails().getTransaction().getGrandTotal());
+ }
+ if (bizEvent.getPaymentInfo() != null && bizEvent.getPaymentInfo().getAmount() != null) {
+ return new BigDecimal(bizEvent.getPaymentInfo().getAmount());
+ }
+ return BigDecimal.ZERO;
+ }
+
}
diff --git a/src/main/java/it/gov/pagopa/receipt/pdf/helpdesk/service/impl/BuildTemplateServiceImpl.java b/src/main/java/it/gov/pagopa/receipt/pdf/helpdesk/service/impl/BuildTemplateServiceImpl.java
index 119631eb..e6e57edd 100644
--- a/src/main/java/it/gov/pagopa/receipt/pdf/helpdesk/service/impl/BuildTemplateServiceImpl.java
+++ b/src/main/java/it/gov/pagopa/receipt/pdf/helpdesk/service/impl/BuildTemplateServiceImpl.java
@@ -33,8 +33,6 @@ public class BuildTemplateServiceImpl implements BuildTemplateService {
private static final String BRAND_LOGO_MAP_ENV_KEY = "BRAND_LOGO_MAP";
private static final String PSP_CONFIG_FILE_JSON_FILE_NAME = "psp_config_file.json";
- private static final String PAGO_PA_CHANNEL_IO = "IO";
- private static final String PAGO_PA_CHANNEL_IO_PAY = "IO-PAY";
private static final String RECEIPT_DATE_FORMAT = "dd MMMM yyyy, HH:mm:ss";
/**
@@ -45,6 +43,7 @@ public class BuildTemplateServiceImpl implements BuildTemplateService {
private static final Map pspMap;
public static final String MODEL_TYPE_IUV = "1";
public static final String MODEL_TYPE_NOTICE = "2";
+ public static final String DEBTOR_ANONIMO_CF = "ANONIMO";
static {
try {
@@ -70,14 +69,15 @@ public class BuildTemplateServiceImpl implements BuildTemplateService {
* {@inheritDoc}
*/
@Override
- public ReceiptPDFTemplate buildTemplate(BizEvent bizEvent, boolean isGeneratingDebtor, Receipt receipt) throws TemplateDataMappingException {
+ public ReceiptPDFTemplate buildTemplate(List listOfBizEvents, boolean isGeneratingDebtor, Receipt receipt) throws TemplateDataMappingException {
+ BizEvent bizEvent = listOfBizEvents.get(0);
boolean requestedByDebtor = getRequestByDebtor(isGeneratingDebtor, bizEvent);
return ReceiptPDFTemplate.builder()
- .serviceCustomerId(getServiceCustomerId(bizEvent))
+ .serviceCustomerId(getServiceCustomerId(receipt))
.transaction(Transaction.builder()
.timestamp(getTimestamp(bizEvent))
- .amount(getAmount(bizEvent))
+ .amount(getAmount(receipt))
.psp(getPsp(bizEvent))
.rrn(getRnn(bizEvent))
.paymentMethod(PaymentMethod.builder()
@@ -98,37 +98,52 @@ public ReceiptPDFTemplate buildTemplate(BizEvent bizEvent, boolean isGeneratingD
.build())
.build())
.cart(Cart.builder()
- .items(Collections.singletonList(
- Item.builder()
- .refNumber(RefNumber.builder()
- .type(getRefNumberType(bizEvent))
- .value(getRefNumberValue(bizEvent))
- .build())
- .debtor("ANONIMO".equals(receipt.getEventData().getDebtorFiscalCode()) ?
- null :
- Debtor.builder()
- .fullName(getDebtorFullName(bizEvent))
- .taxCode(getDebtorTaxCode(bizEvent))
- .build())
- .payee(Payee.builder()
- .name(getPayeeName(bizEvent))
- .taxCode(getPayeeTaxCode(bizEvent))
- .build())
- .subject(getItemSubject(receipt))
- .amount(getItemAmount(bizEvent))
- .build()
- ))
- //Cart items total amount w/o fee, TODO change it with multiple cart items implementation
- .amountPartial(getItemAmount(bizEvent))
+ .items(getCartItems(listOfBizEvents, receipt))
+ .amountPartial(getCartAmountPartial(listOfBizEvents))
.build())
.build();
}
- private String getServiceCustomerId(BizEvent event) throws TemplateDataMappingException {
- if (event.getId() != null) {
- return event.getId();
+ private List- getCartItems(List listOfBizEvents, Receipt receipt) throws TemplateDataMappingException {
+ List
- cartItems = new ArrayList<>();
+ for (int i = 0; i < listOfBizEvents.size(); i++) {
+ BizEvent bizEvent = listOfBizEvents.get(i);
+ cartItems.add(
+ Item.builder()
+ .refNumber(RefNumber.builder()
+ .type(getRefNumberType(bizEvent))
+ .value(getRefNumberValue(bizEvent))
+ .build())
+ .debtor(DEBTOR_ANONIMO_CF.equals(receipt.getEventData().getDebtorFiscalCode()) ?
+ null :Debtor.builder()
+ .fullName(getDebtorFullName(bizEvent))
+ .taxCode(getDebtorTaxCode(bizEvent))
+ .build())
+ .payee(Payee.builder()
+ .name(getPayeeName(bizEvent))
+ .taxCode(getPayeeTaxCode(bizEvent))
+ .build())
+ .subject(getItemSubject(receipt, i))
+ .amount(getItemAmount(bizEvent, true))
+ .build()
+ );
}
- throw new TemplateDataMappingException(formatErrorMessage(TemplateDataField.SERVICE_CUSTOMER_ID), ReasonErrorCode.ERROR_TEMPLATE_PDF.getCode());
+ return cartItems;
+ }
+
+ private String getCartAmountPartial(List listOfBizEvents) throws TemplateDataMappingException {
+ double amountPartial = 0;
+ for (BizEvent bizEvent : listOfBizEvents) {
+ amountPartial = amountPartial + Double.parseDouble(getItemAmount(bizEvent, false));
+ }
+ return currencyFormat(String.valueOf(amountPartial));
+ }
+
+ private String getServiceCustomerId(Receipt receipt) throws TemplateDataMappingException {
+ if (receipt.getEventId() != null) {
+ return receipt.getEventId();
+ }
+ throw new TemplateDataMappingException(formatErrorMessage(TemplateDataField.SERVICE_CUSTOMER_ID, receipt.getId(), false), ReasonErrorCode.ERROR_TEMPLATE_PDF.getCode());
}
private String getTimestamp(BizEvent event) throws TemplateDataMappingException {
@@ -142,22 +157,15 @@ private String getTimestamp(BizEvent event) throws TemplateDataMappingException
if (event.getPaymentInfo() != null && event.getPaymentInfo().getPaymentDateTime() != null) {
return dateFormat(event.getPaymentInfo().getPaymentDateTime());
}
- throw new TemplateDataMappingException(formatErrorMessage(TemplateDataField.TRANSACTION_TIMESTAMP), ReasonErrorCode.ERROR_TEMPLATE_PDF.getCode());
+ throw new TemplateDataMappingException(formatErrorMessage(TemplateDataField.TRANSACTION_TIMESTAMP, event.getId(), true), ReasonErrorCode.ERROR_TEMPLATE_PDF.getCode());
}
- private String getAmount(BizEvent event) throws TemplateDataMappingException {
- if (
- event.getTransactionDetails() != null &&
- event.getTransactionDetails().getTransaction() != null &&
- event.getTransactionDetails().getTransaction().getGrandTotal() != 0L
- ) {
- // Amount in transactionDetails is defined in cents (es. 25500 not 255.00)
- return currencyFormat(String.valueOf(event.getTransactionDetails().getTransaction().getGrandTotal() / 100.00));
+ private String getAmount(Receipt receipt) throws TemplateDataMappingException {
+ if(receipt.getEventData() != null &&
+ receipt.getEventData().getAmount() != null){
+ return receipt.getEventData().getAmount();
}
- if (event.getPaymentInfo() != null && event.getPaymentInfo().getAmount() != null) {
- return currencyFormat(event.getPaymentInfo().getAmount());
- }
- throw new TemplateDataMappingException(formatErrorMessage(TemplateDataField.TRANSACTION_AMOUNT), ReasonErrorCode.ERROR_TEMPLATE_PDF.getCode());
+ throw new TemplateDataMappingException(formatErrorMessage(TemplateDataField.TRANSACTION_AMOUNT, receipt.getId(), false), ReasonErrorCode.ERROR_TEMPLATE_PDF.getCode());
}
private String getRnn(BizEvent event) throws TemplateDataMappingException {
@@ -176,7 +184,7 @@ private String getRnn(BizEvent event) throws TemplateDataMappingException {
return event.getPaymentInfo().getIUR();
}
}
- throw new TemplateDataMappingException(formatErrorMessage(TemplateDataField.TRANSACTION_RRN), ReasonErrorCode.ERROR_TEMPLATE_PDF.getCode());
+ throw new TemplateDataMappingException(formatErrorMessage(TemplateDataField.TRANSACTION_RRN, event.getId(), true), ReasonErrorCode.ERROR_TEMPLATE_PDF.getCode());
}
private String getAuthCode(BizEvent event) {
@@ -228,7 +236,7 @@ private String getUserFullName(BizEvent event) throws TemplateDataMappingExcepti
if (event.getPayer() != null && event.getPayer().getFullName() != null) {
return event.getPayer().getFullName();
}
- throw new TemplateDataMappingException(formatErrorMessage(TemplateDataField.USER_DATA_FULL_NAME), ReasonErrorCode.ERROR_TEMPLATE_PDF.getCode());
+ throw new TemplateDataMappingException(formatErrorMessage(TemplateDataField.USER_DATA_FULL_NAME, event.getId(), true), ReasonErrorCode.ERROR_TEMPLATE_PDF.getCode());
}
private String getUserTaxCode(BizEvent event) throws TemplateDataMappingException {
@@ -242,7 +250,7 @@ private String getUserTaxCode(BizEvent event) throws TemplateDataMappingExceptio
if (event.getPayer() != null && event.getPayer().getEntityUniqueIdentifierValue() != null) {
return event.getPayer().getEntityUniqueIdentifierValue();
}
- throw new TemplateDataMappingException(formatErrorMessage(TemplateDataField.USER_DATA_TAX_CODE), ReasonErrorCode.ERROR_TEMPLATE_PDF.getCode());
+ throw new TemplateDataMappingException(formatErrorMessage(TemplateDataField.USER_DATA_TAX_CODE, event.getId(), true), ReasonErrorCode.ERROR_TEMPLATE_PDF.getCode());
}
private String getRefNumberType(BizEvent event) throws TemplateDataMappingException {
@@ -254,7 +262,7 @@ private String getRefNumberType(BizEvent event) throws TemplateDataMappingExcept
return REF_TYPE_NOTICE;
}
}
- throw new TemplateDataMappingException(formatErrorMessage(TemplateDataField.CART_ITEM_REF_NUMBER_TYPE), ReasonErrorCode.ERROR_TEMPLATE_PDF.getCode());
+ throw new TemplateDataMappingException(formatErrorMessage(TemplateDataField.CART_ITEM_REF_NUMBER_TYPE, event.getId(), true), ReasonErrorCode.ERROR_TEMPLATE_PDF.getCode());
}
private String getRefNumberValue(BizEvent event) throws TemplateDataMappingException {
@@ -266,7 +274,7 @@ private String getRefNumberValue(BizEvent event) throws TemplateDataMappingExcep
return event.getDebtorPosition().getNoticeNumber();
}
}
- throw new TemplateDataMappingException(formatErrorMessage(TemplateDataField.CART_ITEM_REF_NUMBER_VALUE), ReasonErrorCode.ERROR_TEMPLATE_PDF.getCode());
+ throw new TemplateDataMappingException(formatErrorMessage(TemplateDataField.CART_ITEM_REF_NUMBER_VALUE, event.getId(), true), ReasonErrorCode.ERROR_TEMPLATE_PDF.getCode());
}
private String getDebtorFullName(BizEvent event) {
@@ -277,7 +285,7 @@ private String getDebtorTaxCode(BizEvent event) throws TemplateDataMappingExcept
if (event.getDebtor() != null && event.getDebtor().getEntityUniqueIdentifierValue() != null) {
return event.getDebtor().getEntityUniqueIdentifierValue();
}
- throw new TemplateDataMappingException(formatErrorMessage(TemplateDataField.CART_ITEM_DEBTOR_TAX_CODE), ReasonErrorCode.ERROR_TEMPLATE_PDF.getCode());
+ throw new TemplateDataMappingException(formatErrorMessage(TemplateDataField.CART_ITEM_DEBTOR_TAX_CODE, event.getId(), true), ReasonErrorCode.ERROR_TEMPLATE_PDF.getCode());
}
private String getPayeeName(BizEvent event) {
@@ -288,25 +296,25 @@ private String getPayeeTaxCode(BizEvent event) throws TemplateDataMappingExcepti
if (event.getCreditor() != null && event.getCreditor().getIdPA() != null) {
return event.getCreditor().getIdPA();
}
- throw new TemplateDataMappingException(formatErrorMessage(TemplateDataField.CART_ITEM_PAYEE_TAX_CODE), ReasonErrorCode.ERROR_TEMPLATE_PDF.getCode());
+ throw new TemplateDataMappingException(formatErrorMessage(TemplateDataField.CART_ITEM_PAYEE_TAX_CODE, event.getId(), true), ReasonErrorCode.ERROR_TEMPLATE_PDF.getCode());
}
- private String getItemSubject(Receipt receipt) throws TemplateDataMappingException {
+ private String getItemSubject(Receipt receipt, int index) throws TemplateDataMappingException {
if (receipt.getEventData() != null &&
!receipt.getEventData().getCart().isEmpty() &&
- receipt.getEventData().getCart().get(0) != null
+ receipt.getEventData().getCart().get(index) != null &&
+ receipt.getEventData().getCart().get(index).getSubject() != null
) {
- return receipt.getEventData().getCart().get(0).getSubject();
+ return receipt.getEventData().getCart().get(index).getSubject();
}
-
- throw new TemplateDataMappingException(formatErrorMessage(TemplateDataField.CART_ITEM_SUBJECT), ReasonErrorCode.ERROR_TEMPLATE_PDF.getCode());
+ throw new TemplateDataMappingException(formatErrorMessage(TemplateDataField.CART_ITEM_SUBJECT, receipt.getId(), false), ReasonErrorCode.ERROR_TEMPLATE_PDF.getCode());
}
- private String getItemAmount(BizEvent event) throws TemplateDataMappingException {
+ private String getItemAmount(BizEvent event, boolean currencyFormatted) throws TemplateDataMappingException {
if (event.getPaymentInfo() != null && event.getPaymentInfo().getAmount() != null) {
- return currencyFormat(event.getPaymentInfo().getAmount());
+ return currencyFormatted ? currencyFormat(event.getPaymentInfo().getAmount()) : event.getPaymentInfo().getAmount();
}
- throw new TemplateDataMappingException(formatErrorMessage(TemplateDataField.CART_ITEM_AMOUNT), ReasonErrorCode.ERROR_TEMPLATE_PDF.getCode());
+ throw new TemplateDataMappingException(formatErrorMessage(TemplateDataField.CART_ITEM_AMOUNT, event.getId(), true), ReasonErrorCode.ERROR_TEMPLATE_PDF.getCode());
}
private String getPspFee(BizEvent event) {
@@ -327,26 +335,26 @@ private PSP getPsp(BizEvent event) throws TemplateDataMappingException {
.getOrDefault(event.getPsp().getIdPsp(), new LinkedHashMap<>());
String pspFee = getPspFee(event);
return PSP.builder()
- .name(getOrThrow(info, "name", TemplateDataField.TRANSACTION_PSP_NAME))
+ .name(getOrThrow(info, "name", TemplateDataField.TRANSACTION_PSP_NAME, event.getId()))
.fee(PSPFee.builder()
.amount(pspFee)
.build())
- .companyName(getOrThrow(info, "companyName", TemplateDataField.TRANSACTION_PSP_COMPANY_NAME))
- .address(getOrThrow(info, "address", TemplateDataField.TRANSACTION_PSP_ADDRESS))
- .city(getOrThrow(info, "city", TemplateDataField.TRANSACTION_PSP_CITY))
- .province(getOrThrow(info, "province", TemplateDataField.TRANSACTION_PSP_PROVINCE))
- .buildingNumber(getOrThrow(info, "buildingNumber", TemplateDataField.TRANSACTION_PSP_BUILDING_NUMBER))
- .postalCode(getOrThrow(info, "postalCode", TemplateDataField.TRANSACTION_PSP_POSTAL_CODE))
- .logo(pspFee != null ? getOrThrow(info, "logo", TemplateDataField.TRANSACTION_PSP_LOGO) : info.get("logo"))
+ .companyName(getOrThrow(info, "companyName", TemplateDataField.TRANSACTION_PSP_COMPANY_NAME, event.getId()))
+ .address(getOrThrow(info, "address", TemplateDataField.TRANSACTION_PSP_ADDRESS, event.getId()))
+ .city(getOrThrow(info, "city", TemplateDataField.TRANSACTION_PSP_CITY, event.getId()))
+ .province(getOrThrow(info, "province", TemplateDataField.TRANSACTION_PSP_PROVINCE, event.getId()))
+ .buildingNumber(getOrThrow(info, "buildingNumber", TemplateDataField.TRANSACTION_PSP_BUILDING_NUMBER, event.getId()))
+ .postalCode(getOrThrow(info, "postalCode", TemplateDataField.TRANSACTION_PSP_POSTAL_CODE, event.getId()))
+ .logo(pspFee != null ? getOrThrow(info, "logo", TemplateDataField.TRANSACTION_PSP_LOGO, event.getId()) : info.get("logo"))
.build();
}
- throw new TemplateDataMappingException(formatErrorMessage(TemplateDataField.TRANSACTION_PSP), ReasonErrorCode.ERROR_TEMPLATE_PDF.getCode());
+ throw new TemplateDataMappingException(formatErrorMessage(TemplateDataField.TRANSACTION_PSP, event.getId(), true), ReasonErrorCode.ERROR_TEMPLATE_PDF.getCode());
}
- private String getOrThrow(LinkedHashMap map, String key, String errorKey) throws TemplateDataMappingException {
+ private String getOrThrow(LinkedHashMap map, String key, String errorKey, String eventId) throws TemplateDataMappingException {
String value = map.get(key);
if (value == null) {
- throw new TemplateDataMappingException(formatErrorMessage(errorKey), ReasonErrorCode.ERROR_TEMPLATE_PDF.getCode());
+ throw new TemplateDataMappingException(formatErrorMessage(errorKey, eventId, true), ReasonErrorCode.ERROR_TEMPLATE_PDF.getCode());
}
return value;
}
@@ -354,11 +362,11 @@ private String getOrThrow(LinkedHashMap map, String key, String
private boolean getProcessedByPagoPA(BizEvent event) {
if (event.getTransactionDetails() != null) {
if (event.getTransactionDetails().getTransaction() != null &&
- event.getTransactionDetails().getTransaction().getOrigin() != null) {
+ event.getTransactionDetails().getTransaction().getOrigin() != null) {
return true;
}
if (event.getTransactionDetails().getInfo() != null &&
- event.getTransactionDetails().getInfo().getClientId() != null) {
+ event.getTransactionDetails().getInfo().getClientId() != null) {
return true;
}
}
@@ -419,8 +427,9 @@ private String dateFormat(String date) throws TemplateDataMappingException {
}
}
- private String formatErrorMessage(String missingProperty) {
- return String.format(TemplateDataField.ERROR_MAPPING_MESSAGE, missingProperty);
+ private String formatErrorMessage(String missingProperty, String id, Boolean isEvent) {
+ String object = Boolean.TRUE.equals(isEvent) ? "bizEvent" : "receipt";
+ return String.format(TemplateDataField.ERROR_MAPPING_MESSAGE, object, missingProperty, object, id);
}
private String formatFullName(String fullName, String fiscalCode) {
diff --git a/src/main/java/it/gov/pagopa/receipt/pdf/helpdesk/service/impl/GenerateReceiptPdfServiceImpl.java b/src/main/java/it/gov/pagopa/receipt/pdf/helpdesk/service/impl/GenerateReceiptPdfServiceImpl.java
index 9ce925e5..400f52d6 100644
--- a/src/main/java/it/gov/pagopa/receipt/pdf/helpdesk/service/impl/GenerateReceiptPdfServiceImpl.java
+++ b/src/main/java/it/gov/pagopa/receipt/pdf/helpdesk/service/impl/GenerateReceiptPdfServiceImpl.java
@@ -28,6 +28,7 @@
import java.io.FileInputStream;
import java.net.URL;
import java.nio.file.Path;
+import java.util.List;
import java.util.Objects;
import static org.apache.http.HttpStatus.SC_OK;
@@ -58,7 +59,7 @@ public GenerateReceiptPdfServiceImpl() {
* {@inheritDoc}
*/
@Override
- public PdfGeneration generateReceipts(Receipt receipt, BizEvent bizEvent, Path workingDirPath) {
+ public PdfGeneration generateReceipts(Receipt receipt, List listOfBizEvents, Path workingDirPath) {
PdfGeneration pdfGeneration = new PdfGeneration();
String debtorCF = receipt.getEventData().getDebtorFiscalCode();
@@ -69,13 +70,13 @@ public PdfGeneration generateReceipts(Receipt receipt, BizEvent bizEvent, Path w
if (payerCF.equals(debtorCF)) {
pdfGeneration.setGenerateOnlyDebtor(true);
//Generate debtor's complete PDF
- PdfMetadata generationResult = generateAndSavePDFReceipt(bizEvent, receipt, receipt.getMdAttach().getName(), false, workingDirPath);
+ PdfMetadata generationResult = generateAndSavePDFReceipt(listOfBizEvents, receipt, receipt.getMdAttach().getName(), false, workingDirPath);
pdfGeneration.setDebtorMetadata(generationResult);
return pdfGeneration;
}
//Generate payer's complete PDF
- PdfMetadata generationResult = generateAndSavePDFReceipt(bizEvent, receipt, receipt.getMdAttachPayer().getName(), false, workingDirPath);
+ PdfMetadata generationResult = generateAndSavePDFReceipt(listOfBizEvents, receipt, receipt.getMdAttachPayer().getName(), false, workingDirPath);
pdfGeneration.setPayerMetadata(generationResult);
} else {
@@ -84,7 +85,7 @@ public PdfGeneration generateReceipts(Receipt receipt, BizEvent bizEvent, Path w
//Generate debtor's partial PDF
if (!"ANONIMO".equals(debtorCF)) {
- PdfMetadata generationResult = generateAndSavePDFReceipt(bizEvent, receipt, receipt.getMdAttach().getName(), true, workingDirPath);
+ PdfMetadata generationResult = generateAndSavePDFReceipt(listOfBizEvents, receipt, receipt.getMdAttach().getName(), true, workingDirPath);
pdfGeneration.setDebtorMetadata(generationResult);
}
@@ -132,13 +133,13 @@ public boolean verifyAndUpdateReceipt(Receipt receipt, PdfGeneration pdfGenerati
return result;
}
- private PdfMetadata generateAndSavePDFReceipt(BizEvent bizEvent, Receipt receipt, String blobName, boolean isGeneratingDebtor, Path workingDirPath) {
+ private PdfMetadata generateAndSavePDFReceipt(List listOfBizEvents, Receipt receipt, String blobName, boolean isGeneratingDebtor, Path workingDirPath) {
try {
- ReceiptPDFTemplate template = buildTemplateService.buildTemplate(bizEvent, isGeneratingDebtor, receipt);
+ ReceiptPDFTemplate template = buildTemplateService.buildTemplate(listOfBizEvents, isGeneratingDebtor, receipt);
PdfEngineResponse pdfEngineResponse = generatePDFReceipt(template, workingDirPath);
return saveToBlobStorage(pdfEngineResponse, blobName);
} catch (PDFReceiptGenerationException e) {
- logger.error("An error occurred when generating or saving the PDF receipt for biz-event {}. Error: {}", bizEvent.getId(), e.getMessage(), e);
+ logger.error("An error occurred when generating or saving the PDF receipt with eventId {}. Error: {}", receipt.getEventId(), e.getMessage(), e);
return PdfMetadata.builder().statusCode(e.getStatusCode()).errorMessage(e.getMessage()).build();
}
}
diff --git a/src/main/java/it/gov/pagopa/receipt/pdf/helpdesk/utils/BizEventToReceiptUtils.java b/src/main/java/it/gov/pagopa/receipt/pdf/helpdesk/utils/BizEventToReceiptUtils.java
index 8343ad81..1a43daf7 100644
--- a/src/main/java/it/gov/pagopa/receipt/pdf/helpdesk/utils/BizEventToReceiptUtils.java
+++ b/src/main/java/it/gov/pagopa/receipt/pdf/helpdesk/utils/BizEventToReceiptUtils.java
@@ -3,7 +3,11 @@
import com.azure.cosmos.models.FeedResponse;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.microsoft.azure.functions.ExecutionContext;
+import com.microsoft.azure.functions.HttpStatus;
import it.gov.pagopa.receipt.pdf.helpdesk.client.BizEventCosmosClient;
+import it.gov.pagopa.receipt.pdf.helpdesk.client.CartReceiptsCosmosClient;
+import it.gov.pagopa.receipt.pdf.helpdesk.entity.cart.CartForReceipt;
+import it.gov.pagopa.receipt.pdf.helpdesk.entity.cart.CartStatusType;
import it.gov.pagopa.receipt.pdf.helpdesk.entity.event.BizEvent;
import it.gov.pagopa.receipt.pdf.helpdesk.entity.event.Transfer;
import it.gov.pagopa.receipt.pdf.helpdesk.entity.event.enumeration.BizEventStatusType;
@@ -14,18 +18,24 @@
import it.gov.pagopa.receipt.pdf.helpdesk.exception.BizEventNotFoundException;
import it.gov.pagopa.receipt.pdf.helpdesk.exception.PDVTokenizerException;
import it.gov.pagopa.receipt.pdf.helpdesk.exception.ReceiptNotFoundException;
+import it.gov.pagopa.receipt.pdf.helpdesk.model.MassiveRecoverCartResult;
import it.gov.pagopa.receipt.pdf.helpdesk.model.MassiveRecoverResult;
+import it.gov.pagopa.receipt.pdf.helpdesk.model.ProblemJson;
import it.gov.pagopa.receipt.pdf.helpdesk.service.BizEventToReceiptService;
import it.gov.pagopa.receipt.pdf.helpdesk.service.ReceiptCosmosService;
import org.slf4j.Logger;
+import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.UUID;
+import java.util.concurrent.atomic.AtomicReference;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
+import static it.gov.pagopa.receipt.pdf.helpdesk.service.impl.BizEventToReceiptServiceImpl.getAmount;
+
public class BizEventToReceiptUtils {
private static final String REMITTANCE_INFORMATION_REGEX = "/TXT/(.*)";
@@ -37,19 +47,62 @@ public static Receipt getEvent(
BizEventCosmosClient bizEventCosmosClient,
ReceiptCosmosService receiptCosmosService,
Receipt receipt,
- Logger logger
+ Logger logger,
+ Boolean isCart
) throws BizEventNotFoundException, PDVTokenizerException, JsonProcessingException {
- BizEvent bizEvent = bizEventCosmosClient.getBizEventDocument(eventId);
- if (isBizEventInvalid(bizEvent, context, logger)) {
+ List listCart = null;
+ BizEvent bizEvent;
+
+ if (isCart) {
+ listCart = bizEventToReceiptService.getCartBizEvents(eventId);
+ bizEvent = listCart.get(0);
+ } else {
+ bizEvent = bizEventCosmosClient.getBizEventDocument(eventId);
+ }
+
+ if (isCart) {
+ Integer intTotalNotice = Integer.parseInt(bizEvent.getPaymentInfo().getTotalNotice());
+ if (!intTotalNotice.equals(listCart.size())) {
+ return null;
+ }
+ for (BizEvent event : listCart) {
+ if (isBizEventInvalid(event, context, logger)) {
+ return null;
+ }
+ }
+ } else if (isBizEventInvalid(bizEvent, context, logger)) {
return null;
}
+
+
if (receipt == null) {
try {
receipt = receiptCosmosService.getReceipt(eventId);
} catch (ReceiptNotFoundException e) {
receipt = BizEventToReceiptUtils.createReceipt(bizEvent,
bizEventToReceiptService, logger);
+ EventData eventData = receipt.getEventData();
+ if (isCart) {
+ AtomicReference amount = new AtomicReference<>(BigDecimal.ZERO);
+ List cartItems = new ArrayList<>();
+ listCart.forEach(event -> {
+ BigDecimal amountExtracted = getAmount(bizEvent);
+ amount.updateAndGet(v -> v.add(amountExtracted));
+ cartItems.add(
+ CartItem.builder()
+ .payeeName(bizEvent.getCreditor() != null ?
+ bizEvent.getCreditor().getCompanyName() : null)
+ .subject(getItemSubject(bizEvent))
+ .build());
+ });
+
+ if (!amount.get().equals(BigDecimal.ZERO)) {
+ eventData.setAmount(amount.get().toString());
+ }
+
+ eventData.setCart(cartItems);
+ }
receipt.setStatus(ReceiptStatusType.FAILED);
}
}
@@ -60,10 +113,11 @@ public static Receipt getEvent(
receipt.getStatus().equals(ReceiptStatusType.NOT_QUEUE_SENT)
)) {
if (receipt.getEventData() == null || receipt.getEventData().getDebtorFiscalCode() == null) {
- tokenizeReceipt(bizEventToReceiptService, bizEvent, receipt);
+ tokenizeReceipt(bizEventToReceiptService, isCart ? listCart : Collections.singletonList(bizEvent), receipt);
}
receipt.setStatus(ReceiptStatusType.INSERTED);
- bizEventToReceiptService.handleSendMessageToQueue(bizEvent, receipt);
+ bizEventToReceiptService.handleSendMessageToQueue(isCart ? listCart :
+ Collections.singletonList(bizEvent), receipt);
if (receipt.getStatus() != ReceiptStatusType.NOT_QUEUE_SENT) {
receipt.setInsertedAt(System.currentTimeMillis());
receipt.setReasonErr(null);
@@ -92,7 +146,8 @@ public static MassiveRecoverResult massiveRecoverByStatus(
for (Receipt receipt : page.getResults()) {
try {
Receipt restored = getEvent(receipt.getEventId(), context, bizEventToReceiptService,
- bizEventCosmosClient, receiptCosmosService, receipt, logger);
+ bizEventCosmosClient, receiptCosmosService, receipt, logger, receipt.getIsCart() != null ?
+ receipt.getIsCart() : false);
receiptList.add(restored);
} catch (Exception e) {
logger.error(e.getMessage(), e);
@@ -135,10 +190,17 @@ public static Receipt createReceipt(BizEvent bizEvent, BizEventToReceiptService
eventData.setTransactionCreationDate(
service.getTransactionCreationDate(bizEvent));
- eventData.setAmount(bizEvent.getPaymentInfo() != null ?
- bizEvent.getPaymentInfo().getAmount() : null);
+ eventData.setAmount(
+ bizEvent.getTransactionDetails() != null && bizEvent
+ .getTransactionDetails().getTransaction() != null ?
+ String.valueOf(bizEvent.getTransactionDetails().getTransaction().getGrandTotal()) :
+ bizEvent.getPaymentInfo() != null ? bizEvent.getPaymentInfo().getAmount() : null
+ );
- List cartItems = getCartItems(bizEvent);
+ CartItem item = new CartItem();
+ item.setPayeeName(bizEvent.getCreditor() != null ? bizEvent.getCreditor().getCompanyName() : null);
+ item.setSubject(getItemSubject(bizEvent));
+ List cartItems = Collections.singletonList(item);
eventData.setCart(cartItems);
receipt.setEventData(eventData);
@@ -212,28 +274,37 @@ public static boolean isBizEventInvalid(BizEvent bizEvent, ExecutionContext cont
return false;
}
- public static void tokenizeReceipt(BizEventToReceiptService service, BizEvent bizEvent, Receipt receipt)
+ public static void tokenizeReceipt(BizEventToReceiptService service, List bizEvents, Receipt receipt)
throws PDVTokenizerException, JsonProcessingException {
+ BizEvent firstEvent = bizEvents.get(0);
if (receipt.getEventData() == null) {
EventData eventData = new EventData();
receipt.setEventData(eventData);
eventData.setTransactionCreationDate(
- service.getTransactionCreationDate(bizEvent));
- eventData.setAmount(bizEvent.getPaymentInfo() != null ?
- bizEvent.getPaymentInfo().getAmount() : null);
+ service.getTransactionCreationDate(firstEvent));
+
+ AtomicReference amount = new AtomicReference<>(BigDecimal.ZERO);
+ List cartItems = new ArrayList<>();
+ bizEvents.forEach(bizEvent -> {
+ BigDecimal amountExtracted = getAmount(bizEvent);
+ amount.updateAndGet(v -> v.add(amountExtracted));
+ cartItems.add(
+ CartItem.builder()
+ .payeeName(bizEvent.getCreditor() != null ? bizEvent.getCreditor().getCompanyName() : null)
+ .subject(getItemSubject(bizEvent))
+ .build());
+ });
+
+ if (!amount.get().equals(BigDecimal.ZERO)) {
+ eventData.setAmount(amount.get().toString());
+ }
+
+ eventData.setCart(cartItems);
- createCart(bizEvent, eventData);
}
- service.tokenizeFiscalCodes(bizEvent, receipt, receipt.getEventData());
+ service.tokenizeFiscalCodes(firstEvent, receipt, receipt.getEventData());
}
- private static void createCart(BizEvent bizEvent, EventData eventData) {
- CartItem item = new CartItem();
- item.setPayeeName(bizEvent.getCreditor() != null ? bizEvent.getCreditor().getCompanyName() : null);
- item.setSubject(getItemSubject(bizEvent));
- List cartItems = Collections.singletonList(item);
- eventData.setCart(cartItems);
- }
/**
* Retrieve RemittanceInformation from BizEvent
@@ -241,7 +312,7 @@ private static void createCart(BizEvent bizEvent, EventData eventData) {
* @param bizEvent BizEvent from which retrieve the data
* @return the remittance information
*/
- private static String getItemSubject(BizEvent bizEvent) {
+ public static String getItemSubject(BizEvent bizEvent) {
if (bizEvent.getPaymentInfo() != null && bizEvent.getPaymentInfo().getRemittanceInformation() != null) {
return bizEvent.getPaymentInfo().getRemittanceInformation();
}
@@ -277,5 +348,67 @@ private static String formatRemittanceInformation(String remittanceInformation)
return remittanceInformation;
}
+ public static boolean isReceiptStatusValid(Receipt receipt) {
+ return receipt.getStatus() != ReceiptStatusType.FAILED && receipt.getStatus() != ReceiptStatusType.NOT_QUEUE_SENT;
+ }
+
+ public static MassiveRecoverCartResult massiveRecoverCartByStatus(
+ ExecutionContext context, BizEventToReceiptService bizEventToReceiptService,
+ CartReceiptsCosmosClient cartReceiptsCosmosClient,
+ Logger logger, CartStatusType statusType) {
+ int errorCounter = 0;
+ List cartItems = new ArrayList<>();
+ String continuationToken = null;
+ if (statusType == null) {
+ throw new IllegalArgumentException("at least one status must be specified");
+ }
+ do {
+ Iterable> feedResponseIterator = null;
+
+ if (statusType.equals(CartStatusType.FAILED)) {
+ feedResponseIterator = cartReceiptsCosmosClient.getFailedCarts(continuationToken, 100);
+ }
+ if (statusType.equals(CartStatusType.INSERTED)) {
+ feedResponseIterator = cartReceiptsCosmosClient.getInsertedCarts(continuationToken, 100);
+ }
+
+ assert feedResponseIterator != null;
+ for (FeedResponse page : feedResponseIterator) {
+ for (CartForReceipt cart : page.getResults()) {
+ try {
+ List bizEventList = bizEventToReceiptService.getCartBizEvents(cart.getId());
+ Receipt receipt = bizEventToReceiptService.createCartReceipt(bizEventList);
+
+ if (!isReceiptStatusValid(receipt)) {
+ logger.error("[{}] Failed to process cart with id {}: fail to tokenize fiscal codes",
+ context.getFunctionName(), cart.getId());
+ throw new Exception("receipt status not valid");
+ }
+
+ // Add receipt to items to be saved on CosmosDB
+ bizEventToReceiptService.handleSaveReceipt(receipt);
+
+ if (!isReceiptStatusValid(receipt)) {
+ throw new Exception("receipt not valid");
+ }
+
+ // Send biz event as message to queue (to be processed from the other function)
+ bizEventToReceiptService.handleSendMessageToQueue(bizEventList, receipt);
+ cart.setStatus(CartStatusType.SENT);
+ cartItems.add(cart);
+ } catch (Exception e) {
+ logger.error(e.getMessage(), e);
+ errorCounter++;
+ }
+ }
+ continuationToken = page.getContinuationToken();
+ }
+ } while (continuationToken != null);
+ return MassiveRecoverCartResult.builder()
+ .cartItems(cartItems)
+ .errorCounter(errorCounter)
+ .build();
+ }
+
private BizEventToReceiptUtils() {}
}
diff --git a/src/main/java/it/gov/pagopa/receipt/pdf/helpdesk/utils/GenerateReceiptUtils.java b/src/main/java/it/gov/pagopa/receipt/pdf/helpdesk/utils/GenerateReceiptUtils.java
index bf32a680..d04f6aea 100644
--- a/src/main/java/it/gov/pagopa/receipt/pdf/helpdesk/utils/GenerateReceiptUtils.java
+++ b/src/main/java/it/gov/pagopa/receipt/pdf/helpdesk/utils/GenerateReceiptUtils.java
@@ -25,16 +25,6 @@ public class GenerateReceiptUtils {
private static final String WORKING_DIRECTORY_PATH = System.getenv().getOrDefault("WORKING_DIRECTORY_PATH", "");
- public static BizEvent getBizEventFromMessage(ExecutionContext context, String bizEventMessage) throws BizEventNotValidException {
- try {
- return ObjectMapperUtils.mapString(bizEventMessage, BizEvent.class);
- } catch (JsonProcessingException e) {
- String errorMsg = String.format("[%s] Error parsing the message coming from the queue",
- context.getFunctionName());
- throw new BizEventNotValidException(errorMsg, e);
- }
- }
-
public static Path createWorkingDirectory() throws IOException {
File workingDirectory = new File(WORKING_DIRECTORY_PATH);
if (!workingDirectory.exists()) {
diff --git a/src/test/java/it/gov/pagopa/receipt/pdf/helpdesk/ReceiptToReviewedTest.java b/src/test/java/it/gov/pagopa/receipt/pdf/helpdesk/ReceiptToReviewedTest.java
index f51e66cf..57d646a7 100644
--- a/src/test/java/it/gov/pagopa/receipt/pdf/helpdesk/ReceiptToReviewedTest.java
+++ b/src/test/java/it/gov/pagopa/receipt/pdf/helpdesk/ReceiptToReviewedTest.java
@@ -1,9 +1,14 @@
package it.gov.pagopa.receipt.pdf.helpdesk;
+import com.azure.cosmos.models.FeedResponse;
import com.microsoft.azure.functions.*;
import it.gov.pagopa.receipt.pdf.helpdesk.client.ReceiptCosmosClient;
+import it.gov.pagopa.receipt.pdf.helpdesk.entity.cart.CartForReceipt;
+import it.gov.pagopa.receipt.pdf.helpdesk.entity.cart.CartStatusType;
+import it.gov.pagopa.receipt.pdf.helpdesk.entity.event.BizEvent;
import it.gov.pagopa.receipt.pdf.helpdesk.entity.receipt.ReceiptError;
import it.gov.pagopa.receipt.pdf.helpdesk.entity.receipt.enumeration.ReceiptErrorStatusType;
+import it.gov.pagopa.receipt.pdf.helpdesk.exception.CartNotFoundException;
import it.gov.pagopa.receipt.pdf.helpdesk.exception.ReceiptNotFoundException;
import it.gov.pagopa.receipt.pdf.helpdesk.model.ReceiptToReviewedRequest;
import it.gov.pagopa.receipt.pdf.helpdesk.util.HttpResponseMessageMock;
@@ -12,10 +17,11 @@
import org.mockito.ArgumentCaptor;
import org.mockito.Captor;
import org.mockito.Mock;
+import org.mockito.Mockito;
import org.mockito.junit.jupiter.MockitoExtension;
import org.mockito.stubbing.Answer;
-import java.util.Optional;
+import java.util.*;
import java.util.concurrent.atomic.AtomicReference;
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
@@ -63,6 +69,36 @@ void requestWithValidBizEventSaveReceiptErrorInReviewed() throws ReceiptNotFound
assertEquals(ReceiptErrorStatusType.REVIEWED, captured.getStatus());
}
+ @Test
+ void requestWithValidCartSaveReceiptErrorInReviewed() throws ReceiptNotFoundException, CartNotFoundException {
+ doAnswer((Answer) invocation -> {
+ HttpStatus status = (HttpStatus) invocation.getArguments()[0];
+ return new HttpResponseMessageMock.HttpResponseMessageBuilderMock().status(status);
+ }).when(request).createResponseBuilder(any(HttpStatus.class));
+
+ ReceiptError receiptError = ReceiptError.builder()
+ .bizEventId(BIZ_EVENT_ID)
+ .status(ReceiptErrorStatusType.TO_REVIEW)
+ .build();
+ when(receiptCosmosClient.getReceiptError(BIZ_EVENT_ID)).thenReturn(receiptError);
+
+ when(request.getQueryParameters()).thenReturn(Collections.singletonMap("isCart","true"));
+
+ when(receiptCosmosClient.getCartDocument(any())).thenReturn(generateCart());
+
+ function = spy(new ReceiptToReviewed(receiptCosmosClient));
+
+ // test execution
+ AtomicReference responseMessage = new AtomicReference<>();
+ assertDoesNotThrow(() -> responseMessage.set(function.run(request, BIZ_EVENT_ID, documentdb,executionContextMock )));
+ assertEquals(HttpStatus.OK, responseMessage.get().getStatus());
+
+ verify(documentdb).setValue(receiptErrorCaptor.capture());
+ ReceiptError captured = receiptErrorCaptor.getValue();
+ assertEquals(BIZ_EVENT_ID, captured.getBizEventId());
+ assertEquals(ReceiptErrorStatusType.REVIEWED, captured.getStatus());
+ }
+
@Test
void requestWithValidBizEventIdButReceiptNotFound() throws ReceiptNotFoundException {
doAnswer((Answer) invocation -> {
@@ -120,4 +156,14 @@ void requestWithoutEventIdReturnsBadRequest() {
verifyNoInteractions(documentdb);
}
+
+ private CartForReceipt generateCart() {
+ CartForReceipt cart = new CartForReceipt();
+ cart.setId("1");
+ cart.setStatus(CartStatusType.FAILED);
+ cart.setTotalNotice(1);
+ cart.setCartPaymentId(new HashSet<>(new ArrayList<>(
+ List.of(new String[]{"valid_biz_event_id"}))));
+ return cart;
+ }
}
\ No newline at end of file
diff --git a/src/test/java/it/gov/pagopa/receipt/pdf/helpdesk/RecoverFailedCartMassiveScheduledTest.java b/src/test/java/it/gov/pagopa/receipt/pdf/helpdesk/RecoverFailedCartMassiveScheduledTest.java
new file mode 100644
index 00000000..2e84a05d
--- /dev/null
+++ b/src/test/java/it/gov/pagopa/receipt/pdf/helpdesk/RecoverFailedCartMassiveScheduledTest.java
@@ -0,0 +1,214 @@
+package it.gov.pagopa.receipt.pdf.helpdesk;
+
+import com.azure.cosmos.models.ModelBridgeInternal;
+import com.microsoft.azure.functions.*;
+import it.gov.pagopa.receipt.pdf.helpdesk.client.CartReceiptsCosmosClient;
+import it.gov.pagopa.receipt.pdf.helpdesk.client.impl.BizEventCosmosClientImpl;
+import it.gov.pagopa.receipt.pdf.helpdesk.entity.cart.CartForReceipt;
+import it.gov.pagopa.receipt.pdf.helpdesk.entity.cart.CartStatusType;
+import it.gov.pagopa.receipt.pdf.helpdesk.entity.event.*;
+import it.gov.pagopa.receipt.pdf.helpdesk.entity.event.enumeration.BizEventStatusType;
+import it.gov.pagopa.receipt.pdf.helpdesk.entity.receipt.ReasonError;
+import it.gov.pagopa.receipt.pdf.helpdesk.entity.receipt.Receipt;
+import it.gov.pagopa.receipt.pdf.helpdesk.entity.receipt.enumeration.ReceiptStatusType;
+import it.gov.pagopa.receipt.pdf.helpdesk.exception.BizEventNotFoundException;
+import it.gov.pagopa.receipt.pdf.helpdesk.service.BizEventToReceiptService;
+import it.gov.pagopa.receipt.pdf.helpdesk.util.HttpResponseMessageMock;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.*;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.mockito.junit.jupiter.MockitoSettings;
+import org.mockito.quality.Strictness;
+import org.mockito.stubbing.Answer;
+
+import java.time.LocalDateTime;
+import java.util.*;
+
+import static org.junit.jupiter.api.Assertions.*;
+import static org.mockito.Mockito.*;
+
+@ExtendWith(MockitoExtension.class)
+@MockitoSettings(strictness = Strictness.LENIENT)
+class RecoverFailedCartMassiveScheduledTest {
+
+ private final String TOKENIZED_DEBTOR_FISCAL_CODE = "tokenizedDebtorFiscalCode";
+ private final String TOKENIZED_PAYER_FISCAL_CODE = "tokenizedPayerFiscalCode";
+ private final String EVENT_ID = "a valid id";
+
+ @Mock
+ private ExecutionContext contextMock;
+ @Mock
+ private CartReceiptsCosmosClient cartReceiptsCosmosClientMock;
+ @Mock
+ private BizEventCosmosClientImpl bizEventCosmosClientMock;
+ @Mock
+ private BizEventToReceiptService bizEventToReceiptServiceMock;
+
+ @Mock
+ private HttpRequestMessage> requestMock;
+
+ @Captor
+ private ArgumentCaptor
> cartForReceiptCaptor;
+
+ @Spy
+ private OutputBinding> documentdb;
+
+ private AutoCloseable closeable;
+
+ private RecoverFailedCartScheduled sut;
+
+ @BeforeEach
+ public void openMocks() {
+ closeable = MockitoAnnotations.openMocks(this);
+ sut = spy(new RecoverFailedCartScheduled(bizEventToReceiptServiceMock, cartReceiptsCosmosClientMock));
+ }
+
+ @AfterEach
+ public void releaseMocks() throws Exception {
+ closeable.close();
+ }
+
+ @Test
+ void recoverFailedReceiptMassiveSuccess() throws BizEventNotFoundException {
+ when(requestMock.getQueryParameters())
+ .thenReturn(Collections.singletonMap("status", CartStatusType.FAILED.name()));
+
+ when(cartReceiptsCosmosClientMock.getFailedCarts(any(), eq(100)))
+ .thenReturn(Collections.singletonList(ModelBridgeInternal
+ .createFeedResponse(Collections.singletonList(generateCart()),
+ Collections.emptyMap())));
+
+ when(bizEventCosmosClientMock.getBizEventDocument(EVENT_ID))
+ .thenReturn(generateValidBizEvent(EVENT_ID));
+ when(bizEventToReceiptServiceMock.createCartReceipt(any())).thenReturn(buildReceipt());
+
+ doAnswer((Answer) invocation -> {
+ HttpStatus status = (HttpStatus) invocation.getArguments()[0];
+ return new HttpResponseMessageMock.HttpResponseMessageBuilderMock().status(status);
+ }).when(requestMock).createResponseBuilder(any(HttpStatus.class));
+
+ // test execution
+ assertDoesNotThrow(() -> sut.run("info", documentdb, contextMock));
+
+ verify(documentdb).setValue(cartForReceiptCaptor.capture());
+ assertEquals(1, cartForReceiptCaptor.getValue().size());
+
+ }
+
+ @Test
+ void recoverFailedErrorWhenFailHandleCart() throws BizEventNotFoundException {
+ when(requestMock.getQueryParameters())
+ .thenReturn(Collections.singletonMap("status", CartStatusType.FAILED.name()));
+
+ when(cartReceiptsCosmosClientMock.getFailedCarts(any(), eq(100)))
+ .thenReturn(Collections.singletonList(ModelBridgeInternal
+ .createFeedResponse(Collections.singletonList(generateCart()),
+ Collections.emptyMap())));
+
+ when(bizEventCosmosClientMock.getBizEventDocument(EVENT_ID))
+ .thenReturn(generateValidBizEvent(EVENT_ID));
+ when(bizEventToReceiptServiceMock.createCartReceipt(any())).thenAnswer(x -> {
+ throw new Exception("test");
+ });
+
+ doAnswer((Answer) invocation -> {
+ HttpStatus status = (HttpStatus) invocation.getArguments()[0];
+ return new HttpResponseMessageMock.HttpResponseMessageBuilderMock().status(status);
+ }).when(requestMock).createResponseBuilder(any(HttpStatus.class));
+
+ // test execution
+ assertDoesNotThrow(() -> sut.run("info", documentdb, contextMock));
+
+ verify(documentdb).setValue(cartForReceiptCaptor.capture());
+ assertEquals(0, cartForReceiptCaptor.getValue().size());
+
+ }
+
+ @Test
+ void recoverFailedErrorWhenFailRecover() throws BizEventNotFoundException {
+ when(requestMock.getQueryParameters())
+ .thenReturn(Collections.singletonMap("status", CartStatusType.FAILED.name()));
+
+ when(cartReceiptsCosmosClientMock.getFailedCarts(any(), eq(100)))
+ .thenAnswer(x -> new Exception("error"));
+
+
+ doAnswer((Answer) invocation -> {
+ HttpStatus status = (HttpStatus) invocation.getArguments()[0];
+ return new HttpResponseMessageMock.HttpResponseMessageBuilderMock().status(status);
+ }).when(requestMock).createResponseBuilder(any(HttpStatus.class));
+
+ // test execution
+ assertDoesNotThrow(() -> sut.run("info", documentdb, contextMock));
+
+ verify(documentdb).setValue(cartForReceiptCaptor.capture());
+ assertEquals(0, cartForReceiptCaptor.getValue().size());
+
+ }
+
+ private BizEvent generateValidBizEvent(String totalNotice){
+ BizEvent item = new BizEvent();
+
+ Payer payer = new Payer();
+ payer.setEntityUniqueIdentifierValue(TOKENIZED_PAYER_FISCAL_CODE);
+ Debtor debtor = new Debtor();
+ debtor.setEntityUniqueIdentifierValue(TOKENIZED_DEBTOR_FISCAL_CODE);
+
+ TransactionDetails transactionDetails = new TransactionDetails();
+ Transaction transaction = new Transaction();
+ transaction.setCreationDate(String.valueOf(LocalDateTime.now()));
+ transactionDetails.setTransaction(transaction);
+
+ PaymentInfo paymentInfo = new PaymentInfo();
+ paymentInfo.setTotalNotice(totalNotice);
+
+ item.setEventStatus(BizEventStatusType.DONE);
+ item.setId(EVENT_ID);
+ item.setPayer(payer);
+ item.setDebtor(debtor);
+ item.setTransactionDetails(transactionDetails);
+ item.setPaymentInfo(paymentInfo);
+
+ return item;
+ }
+
+ private CartForReceipt generateCart() {
+ CartForReceipt cart = new CartForReceipt();
+ cart.setId("1");
+ cart.setStatus(CartStatusType.FAILED);
+ cart.setTotalNotice(2);
+ cart.setCartPaymentId(new HashSet<>(new ArrayList<>(
+ List.of(new String[]{"1", "2"}))));
+ return cart;
+ }
+
+ private CartForReceipt generateInsertedCart() {
+ CartForReceipt cart = generateCart();
+ cart.setStatus(CartStatusType.INSERTED);
+ return cart;
+ }
+
+ private Receipt buildReceipt() {
+ return Receipt.builder()
+ .eventId(EVENT_ID)
+ .status(ReceiptStatusType.IO_ERROR_TO_NOTIFY)
+ .reasonErr(ReasonError.builder()
+ .code(500)
+ .message("error message")
+ .build())
+ .reasonErrPayer(ReasonError.builder()
+ .code(500)
+ .message("error message")
+ .build())
+ .numRetry(0)
+ .notificationNumRetry(6)
+ .insertedAt(0)
+ .generatedAt(0)
+ .notifiedAt(0)
+ .build();
+ }
+
+}
\ No newline at end of file
diff --git a/src/test/java/it/gov/pagopa/receipt/pdf/helpdesk/RecoverFailedCartMassiveTest.java b/src/test/java/it/gov/pagopa/receipt/pdf/helpdesk/RecoverFailedCartMassiveTest.java
new file mode 100644
index 00000000..93f5f6d4
--- /dev/null
+++ b/src/test/java/it/gov/pagopa/receipt/pdf/helpdesk/RecoverFailedCartMassiveTest.java
@@ -0,0 +1,304 @@
+package it.gov.pagopa.receipt.pdf.helpdesk;
+
+import com.azure.cosmos.models.ModelBridgeInternal;
+import com.microsoft.azure.functions.*;
+import it.gov.pagopa.receipt.pdf.helpdesk.client.CartReceiptsCosmosClient;
+import it.gov.pagopa.receipt.pdf.helpdesk.client.impl.BizEventCosmosClientImpl;
+import it.gov.pagopa.receipt.pdf.helpdesk.entity.cart.CartForReceipt;
+import it.gov.pagopa.receipt.pdf.helpdesk.entity.cart.CartStatusType;
+import it.gov.pagopa.receipt.pdf.helpdesk.entity.event.*;
+import it.gov.pagopa.receipt.pdf.helpdesk.entity.event.enumeration.BizEventStatusType;
+import it.gov.pagopa.receipt.pdf.helpdesk.entity.receipt.CartItem;
+import it.gov.pagopa.receipt.pdf.helpdesk.entity.receipt.EventData;
+import it.gov.pagopa.receipt.pdf.helpdesk.entity.receipt.ReasonError;
+import it.gov.pagopa.receipt.pdf.helpdesk.entity.receipt.Receipt;
+import it.gov.pagopa.receipt.pdf.helpdesk.entity.receipt.enumeration.ReceiptStatusType;
+import it.gov.pagopa.receipt.pdf.helpdesk.exception.BizEventNotFoundException;
+import it.gov.pagopa.receipt.pdf.helpdesk.exception.PDVTokenizerException;
+import it.gov.pagopa.receipt.pdf.helpdesk.model.ProblemJson;
+import it.gov.pagopa.receipt.pdf.helpdesk.service.BizEventToReceiptService;
+import it.gov.pagopa.receipt.pdf.helpdesk.service.ReceiptCosmosService;
+import it.gov.pagopa.receipt.pdf.helpdesk.util.HttpResponseMessageMock;
+import lombok.SneakyThrows;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.*;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.mockito.junit.jupiter.MockitoSettings;
+import org.mockito.quality.Strictness;
+import org.mockito.stubbing.Answer;
+
+import java.time.LocalDateTime;
+import java.util.*;
+
+import static org.junit.jupiter.api.Assertions.*;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.*;
+
+@ExtendWith(MockitoExtension.class)
+@MockitoSettings(strictness = Strictness.LENIENT)
+class RecoverFailedCartMassiveTest {
+
+ private final String TOKENIZED_DEBTOR_FISCAL_CODE = "tokenizedDebtorFiscalCode";
+ private final String TOKENIZED_PAYER_FISCAL_CODE = "tokenizedPayerFiscalCode";
+ private final String EVENT_ID = "a valid id";
+
+ @Mock
+ private ExecutionContext contextMock;
+ @Mock
+ private CartReceiptsCosmosClient cartReceiptsCosmosClientMock;
+ @Mock
+ private BizEventCosmosClientImpl bizEventCosmosClientMock;
+ @Mock
+ private BizEventToReceiptService bizEventToReceiptServiceMock;
+
+ @Mock
+ private HttpRequestMessage> requestMock;
+
+ @Captor
+ private ArgumentCaptor> cartForReceiptCaptor;
+
+ @Spy
+ private OutputBinding> documentdb;
+
+ private AutoCloseable closeable;
+
+ private RecoverFailedCartMassive sut;
+
+ @BeforeEach
+ public void openMocks() {
+ closeable = MockitoAnnotations.openMocks(this);
+ sut = spy(new RecoverFailedCartMassive(bizEventToReceiptServiceMock, cartReceiptsCosmosClientMock));
+ }
+
+ @AfterEach
+ public void releaseMocks() throws Exception {
+ closeable.close();
+ }
+
+ @Test
+ void recoverFailedReceiptMassiveSuccess() throws BizEventNotFoundException {
+ when(requestMock.getQueryParameters())
+ .thenReturn(Collections.singletonMap("status", CartStatusType.FAILED.name()));
+
+ when(cartReceiptsCosmosClientMock.getFailedCarts(any(), eq(100)))
+ .thenReturn(Collections.singletonList(ModelBridgeInternal
+ .createFeedResponse(Collections.singletonList(generateCart()),
+ Collections.emptyMap())));
+
+ when(bizEventCosmosClientMock.getBizEventDocument(EVENT_ID))
+ .thenReturn(generateValidBizEvent(EVENT_ID));
+ when(bizEventToReceiptServiceMock.createCartReceipt(any())).thenReturn(buildReceipt());
+
+ doAnswer((Answer) invocation -> {
+ HttpStatus status = (HttpStatus) invocation.getArguments()[0];
+ return new HttpResponseMessageMock.HttpResponseMessageBuilderMock().status(status);
+ }).when(requestMock).createResponseBuilder(any(HttpStatus.class));
+
+ // test execution
+ HttpResponseMessage response = assertDoesNotThrow(() -> sut.run(requestMock, documentdb, contextMock));
+
+ // test assertion
+ assertNotNull(response);
+ assertEquals(HttpStatus.OK, response.getStatus());
+ assertNotNull(response.getBody());
+
+ verify(documentdb).setValue(cartForReceiptCaptor.capture());
+ assertEquals(1, cartForReceiptCaptor.getValue().size());
+ CartForReceipt captured = cartForReceiptCaptor.getValue().get(0);
+ assertEquals(CartStatusType.SENT, captured.getStatus());
+ }
+
+ @Test
+ void recoverInsertedReceiptMassiveSuccess() throws BizEventNotFoundException {
+ when(requestMock.getQueryParameters())
+ .thenReturn(Collections.singletonMap("status", CartStatusType.INSERTED.name()));
+
+ when(cartReceiptsCosmosClientMock.getInsertedCarts(any(), eq(100)))
+ .thenReturn(Collections.singletonList(ModelBridgeInternal
+ .createFeedResponse(Collections.singletonList(generateInsertedCart()),
+ Collections.emptyMap())));
+
+ when(bizEventCosmosClientMock.getBizEventDocument(EVENT_ID))
+ .thenReturn(generateValidBizEvent(EVENT_ID));
+ when(bizEventToReceiptServiceMock.createCartReceipt(any())).thenReturn(buildReceipt());
+
+ doAnswer((Answer) invocation -> {
+ HttpStatus status = (HttpStatus) invocation.getArguments()[0];
+ return new HttpResponseMessageMock.HttpResponseMessageBuilderMock().status(status);
+ }).when(requestMock).createResponseBuilder(any(HttpStatus.class));
+
+ // test execution
+ HttpResponseMessage response = assertDoesNotThrow(() -> sut.run(requestMock, documentdb, contextMock));
+
+ // test assertion
+ assertNotNull(response);
+ assertEquals(HttpStatus.OK, response.getStatus());
+ assertNotNull(response.getBody());
+
+ verify(documentdb).setValue(cartForReceiptCaptor.capture());
+ assertEquals(1, cartForReceiptCaptor.getValue().size());
+ CartForReceipt captured = cartForReceiptCaptor.getValue().get(0);
+ assertEquals(CartStatusType.SENT, captured.getStatus());
+ }
+
+ @Test
+ void recoverErrorIfStatusWrong() {
+ when(requestMock.getQueryParameters())
+ .thenReturn(Collections.singletonMap("status", "a wrong statys"));
+
+ doAnswer((Answer) invocation -> {
+ HttpStatus status = (HttpStatus) invocation.getArguments()[0];
+ return new HttpResponseMessageMock.HttpResponseMessageBuilderMock().status(status);
+ }).when(requestMock).createResponseBuilder(any(HttpStatus.class));
+
+ // test execution
+ HttpResponseMessage response = assertDoesNotThrow(() -> sut.run(requestMock, documentdb, contextMock));
+
+ // test assertion
+ assertNotNull(response);
+ assertEquals(HttpStatus.BAD_REQUEST, response.getStatus());
+ assertNotNull(response.getBody());
+
+ }
+
+ @Test
+ void recoverErrorIfStatusNull() {
+ when(requestMock.getQueryParameters())
+ .thenReturn(Collections.singletonMap("status", null));
+
+ doAnswer((Answer) invocation -> {
+ HttpStatus status = (HttpStatus) invocation.getArguments()[0];
+ return new HttpResponseMessageMock.HttpResponseMessageBuilderMock().status(status);
+ }).when(requestMock).createResponseBuilder(any(HttpStatus.class));
+
+ // test execution
+ HttpResponseMessage response = assertDoesNotThrow(() -> sut.run(requestMock, documentdb, contextMock));
+
+ // test assertion
+ assertNotNull(response);
+ assertEquals(HttpStatus.BAD_REQUEST, response.getStatus());
+ assertNotNull(response.getBody());
+
+ }
+
+ @Test
+ void recoverFailedErrorWhenFailHandleCart() throws BizEventNotFoundException {
+ when(requestMock.getQueryParameters())
+ .thenReturn(Collections.singletonMap("status", CartStatusType.FAILED.name()));
+
+ when(cartReceiptsCosmosClientMock.getFailedCarts(any(), eq(100)))
+ .thenReturn(Collections.singletonList(ModelBridgeInternal
+ .createFeedResponse(Collections.singletonList(generateCart()),
+ Collections.emptyMap())));
+
+ when(bizEventCosmosClientMock.getBizEventDocument(EVENT_ID))
+ .thenReturn(generateValidBizEvent(EVENT_ID));
+ when(bizEventToReceiptServiceMock.createCartReceipt(any())).thenAnswer(x -> {
+ throw new Exception("test");
+ });
+
+ doAnswer((Answer) invocation -> {
+ HttpStatus status = (HttpStatus) invocation.getArguments()[0];
+ return new HttpResponseMessageMock.HttpResponseMessageBuilderMock().status(status);
+ }).when(requestMock).createResponseBuilder(any(HttpStatus.class));
+
+ // test execution
+ HttpResponseMessage response = assertDoesNotThrow(() -> sut.run(requestMock, documentdb, contextMock));
+
+ // test assertion
+ assertNotNull(response);
+ assertEquals(HttpStatus.INTERNAL_SERVER_ERROR, response.getStatus());
+ assertNotNull(response.getBody());
+
+ }
+
+ @Test
+ void recoverFailedErrorWhenFailRecover() throws BizEventNotFoundException {
+ when(requestMock.getQueryParameters())
+ .thenReturn(Collections.singletonMap("status", CartStatusType.FAILED.name()));
+
+ when(cartReceiptsCosmosClientMock.getFailedCarts(any(), eq(100)))
+ .thenAnswer(x -> new Exception("error"));
+
+
+ doAnswer((Answer) invocation -> {
+ HttpStatus status = (HttpStatus) invocation.getArguments()[0];
+ return new HttpResponseMessageMock.HttpResponseMessageBuilderMock().status(status);
+ }).when(requestMock).createResponseBuilder(any(HttpStatus.class));
+
+ // test execution
+ HttpResponseMessage response = assertDoesNotThrow(() -> sut.run(requestMock, documentdb, contextMock));
+
+ // test assertion
+ assertNotNull(response);
+ assertEquals(HttpStatus.INTERNAL_SERVER_ERROR, response.getStatus());
+ assertNotNull(response.getBody());
+
+ }
+
+ private BizEvent generateValidBizEvent(String totalNotice){
+ BizEvent item = new BizEvent();
+
+ Payer payer = new Payer();
+ payer.setEntityUniqueIdentifierValue(TOKENIZED_PAYER_FISCAL_CODE);
+ Debtor debtor = new Debtor();
+ debtor.setEntityUniqueIdentifierValue(TOKENIZED_DEBTOR_FISCAL_CODE);
+
+ TransactionDetails transactionDetails = new TransactionDetails();
+ Transaction transaction = new Transaction();
+ transaction.setCreationDate(String.valueOf(LocalDateTime.now()));
+ transactionDetails.setTransaction(transaction);
+
+ PaymentInfo paymentInfo = new PaymentInfo();
+ paymentInfo.setTotalNotice(totalNotice);
+
+ item.setEventStatus(BizEventStatusType.DONE);
+ item.setId(EVENT_ID);
+ item.setPayer(payer);
+ item.setDebtor(debtor);
+ item.setTransactionDetails(transactionDetails);
+ item.setPaymentInfo(paymentInfo);
+
+ return item;
+ }
+
+ private CartForReceipt generateCart() {
+ CartForReceipt cart = new CartForReceipt();
+ cart.setId("1");
+ cart.setStatus(CartStatusType.FAILED);
+ cart.setTotalNotice(2);
+ cart.setCartPaymentId(new HashSet<>(new ArrayList<>(
+ List.of(new String[]{"1", "2"}))));
+ return cart;
+ }
+
+ private CartForReceipt generateInsertedCart() {
+ CartForReceipt cart = generateCart();
+ cart.setStatus(CartStatusType.INSERTED);
+ return cart;
+ }
+
+ private Receipt buildReceipt() {
+ return Receipt.builder()
+ .eventId(EVENT_ID)
+ .status(ReceiptStatusType.IO_ERROR_TO_NOTIFY)
+ .reasonErr(ReasonError.builder()
+ .code(500)
+ .message("error message")
+ .build())
+ .reasonErrPayer(ReasonError.builder()
+ .code(500)
+ .message("error message")
+ .build())
+ .numRetry(0)
+ .notificationNumRetry(6)
+ .insertedAt(0)
+ .generatedAt(0)
+ .notifiedAt(0)
+ .build();
+ }
+
+}
\ No newline at end of file
diff --git a/src/test/java/it/gov/pagopa/receipt/pdf/helpdesk/RecoverFailedCartTest.java b/src/test/java/it/gov/pagopa/receipt/pdf/helpdesk/RecoverFailedCartTest.java
new file mode 100644
index 00000000..6d8c63fe
--- /dev/null
+++ b/src/test/java/it/gov/pagopa/receipt/pdf/helpdesk/RecoverFailedCartTest.java
@@ -0,0 +1,330 @@
+package it.gov.pagopa.receipt.pdf.helpdesk;
+
+import com.azure.core.http.rest.Response;
+import com.azure.cosmos.models.CosmosItemResponse;
+import com.azure.cosmos.models.FeedResponse;
+import com.azure.storage.queue.models.SendMessageResult;
+import com.microsoft.azure.functions.*;
+import it.gov.pagopa.receipt.pdf.helpdesk.client.BizEventCosmosClient;
+import it.gov.pagopa.receipt.pdf.helpdesk.client.ReceiptCosmosClient;
+import it.gov.pagopa.receipt.pdf.helpdesk.client.ReceiptQueueClient;
+import it.gov.pagopa.receipt.pdf.helpdesk.client.impl.BizEventCosmosClientImpl;
+import it.gov.pagopa.receipt.pdf.helpdesk.client.impl.CartReceiptsCosmosClientImpl;
+import it.gov.pagopa.receipt.pdf.helpdesk.client.impl.ReceiptCosmosClientImpl;
+import it.gov.pagopa.receipt.pdf.helpdesk.entity.cart.CartForReceipt;
+import it.gov.pagopa.receipt.pdf.helpdesk.entity.cart.CartStatusType;
+import it.gov.pagopa.receipt.pdf.helpdesk.entity.event.*;
+import it.gov.pagopa.receipt.pdf.helpdesk.entity.event.enumeration.BizEventStatusType;
+import it.gov.pagopa.receipt.pdf.helpdesk.entity.receipt.CartItem;
+import it.gov.pagopa.receipt.pdf.helpdesk.entity.receipt.EventData;
+import it.gov.pagopa.receipt.pdf.helpdesk.entity.receipt.Receipt;
+import it.gov.pagopa.receipt.pdf.helpdesk.entity.receipt.enumeration.ReceiptStatusType;
+import it.gov.pagopa.receipt.pdf.helpdesk.exception.BizEventNotFoundException;
+import it.gov.pagopa.receipt.pdf.helpdesk.exception.CartNotFoundException;
+import it.gov.pagopa.receipt.pdf.helpdesk.exception.PDVTokenizerException;
+import it.gov.pagopa.receipt.pdf.helpdesk.exception.ReceiptNotFoundException;
+import it.gov.pagopa.receipt.pdf.helpdesk.model.ProblemJson;
+import it.gov.pagopa.receipt.pdf.helpdesk.service.PDVTokenizerServiceRetryWrapper;
+import it.gov.pagopa.receipt.pdf.helpdesk.service.ReceiptCosmosService;
+import it.gov.pagopa.receipt.pdf.helpdesk.service.impl.BizEventToReceiptServiceImpl;
+import it.gov.pagopa.receipt.pdf.helpdesk.util.HttpResponseMessageMock;
+import lombok.SneakyThrows;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.*;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.mockito.junit.jupiter.MockitoSettings;
+import org.mockito.quality.Strictness;
+import org.mockito.stubbing.Answer;
+
+import java.time.LocalDateTime;
+import java.util.*;
+
+import static org.junit.jupiter.api.Assertions.*;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.*;
+
+@ExtendWith(MockitoExtension.class)
+@MockitoSettings(strictness = Strictness.LENIENT)
+class RecoverFailedCartTest {
+
+ private final String PAYER_FISCAL_CODE = "a valid payer CF";
+ private final String DEBTOR_FISCAL_CODE = "a valid debtor CF";
+ private final String TOKENIZED_DEBTOR_FISCAL_CODE = "tokenizedDebtorFiscalCode";
+ private final String TOKENIZED_PAYER_FISCAL_CODE = "tokenizedPayerFiscalCode";
+ private final String EVENT_ID = "a valid id";
+
+ public static final String HTTP_MESSAGE_ERROR = "an error occured";
+
+ @Mock
+ private ExecutionContext contextMock;
+ @Mock
+ private PDVTokenizerServiceRetryWrapper pdvTokenizerServiceMock;
+ @Mock
+ private ReceiptCosmosService receiptCosmosServiceMock;
+ @Mock
+ private ReceiptQueueClient queueClientMock;
+ @Mock
+ private BizEventCosmosClient bizEventCosmosClientMock;
+
+ @Mock
+ private ReceiptCosmosClient receiptCosmosClient;
+
+ @Mock
+ private CartReceiptsCosmosClientImpl cartReceiptsCosmosClient;
+
+ @Mock
+ private HttpRequestMessage> requestMock;
+
+ @Captor
+ private ArgumentCaptor cartForReceiptArgumentCaptor;
+
+ @Spy
+ private OutputBinding documentdb;
+
+ private AutoCloseable closeable;
+
+ private RecoverFailedCart sut;
+
+ @BeforeEach
+ public void openMocks() {
+ closeable = MockitoAnnotations.openMocks(this);
+ BizEventToReceiptServiceImpl receiptService = new BizEventToReceiptServiceImpl(
+ pdvTokenizerServiceMock, queueClientMock, bizEventCosmosClientMock, receiptCosmosClient);
+ sut = spy(new RecoverFailedCart(receiptService, cartReceiptsCosmosClient));
+ }
+
+ @AfterEach
+ public void releaseMocks() throws Exception {
+ closeable.close();
+ }
+
+
+ @Test
+ void requestOnValidCartShouldResend() throws CartNotFoundException {
+
+ Response queueResponse = mock(Response.class);
+ when(queueResponse.getStatusCode()).thenReturn(HttpStatus.CREATED.value());
+ when(queueClientMock.sendMessageToQueue(anyString())).thenReturn(queueResponse);
+
+ when(cartReceiptsCosmosClient.getCartItem(EVENT_ID)).thenReturn(generateCart());
+
+ CosmosItemResponse responseCosmos = Mockito.mock(CosmosItemResponse.class);
+ when(responseCosmos.getStatusCode()).thenReturn(201);
+ when(receiptCosmosClient.saveReceipts(any())).thenReturn(responseCosmos);
+
+ FeedResponse feedResponseMock = mock(FeedResponse.class);
+ List receiptList = Collections.singletonList(generateValidBizEvent("1"));
+ when(feedResponseMock.getResults()).thenReturn(receiptList);
+ doReturn(Collections.singletonList(feedResponseMock)).when(bizEventCosmosClientMock)
+ .getAllBizEventDocument(Mockito.eq("1"), any(), any());
+
+ doAnswer((Answer) invocation -> {
+ HttpStatus status = (HttpStatus) invocation.getArguments()[0];
+ return new HttpResponseMessageMock.HttpResponseMessageBuilderMock().status(status);
+ }).when(requestMock).createResponseBuilder(any(HttpStatus.class));
+
+ // test execution
+ HttpResponseMessage response = assertDoesNotThrow(() -> sut.run(requestMock, EVENT_ID, documentdb, contextMock));
+
+ // test assertion
+ assertNotNull(response);
+ assertEquals(HttpStatus.OK, response.getStatus());
+ assertNotNull(response.getBody());
+
+ verify(documentdb).setValue(cartForReceiptArgumentCaptor.capture());
+ CartForReceipt captured = cartForReceiptArgumentCaptor.getValue();
+ assertEquals(CartStatusType.SENT, captured.getStatus());
+ }
+
+ @Test
+ void requestOnUncompleteCartShouldntResend() throws CartNotFoundException {
+
+ Response queueResponse = mock(Response.class);
+ when(queueResponse.getStatusCode()).thenReturn(HttpStatus.CREATED.value());
+ when(queueClientMock.sendMessageToQueue(anyString())).thenReturn(queueResponse);
+
+ CartForReceipt cart = generateCart();
+ cart.setCartPaymentId(Collections.emptySet());
+ when(cartReceiptsCosmosClient.getCartItem(EVENT_ID)).thenReturn(cart);
+
+ doAnswer((Answer) invocation -> {
+ HttpStatus status = (HttpStatus) invocation.getArguments()[0];
+ return new HttpResponseMessageMock.HttpResponseMessageBuilderMock().status(status);
+ }).when(requestMock).createResponseBuilder(any(HttpStatus.class));
+
+ // test execution
+ HttpResponseMessage response = assertDoesNotThrow(() -> sut.run(requestMock, EVENT_ID, documentdb, contextMock));
+
+ // test assertion
+ assertNotNull(response);
+ assertEquals(HttpStatus.BAD_REQUEST, response.getStatus());
+ assertNotNull(response.getBody());
+
+ }
+
+ @Test
+ void requestOnAlreadySentCartShouldntResend() throws CartNotFoundException {
+
+ Response queueResponse = mock(Response.class);
+ when(queueResponse.getStatusCode()).thenReturn(HttpStatus.CREATED.value());
+ when(queueClientMock.sendMessageToQueue(anyString())).thenReturn(queueResponse);
+
+ CartForReceipt cart = generateCart();
+ cart.setStatus(CartStatusType.SENT);
+ when(cartReceiptsCosmosClient.getCartItem(EVENT_ID)).thenReturn(cart);
+
+ doAnswer((Answer) invocation -> {
+ HttpStatus status = (HttpStatus) invocation.getArguments()[0];
+ return new HttpResponseMessageMock.HttpResponseMessageBuilderMock().status(status);
+ }).when(requestMock).createResponseBuilder(any(HttpStatus.class));
+
+ // test execution
+ HttpResponseMessage response = assertDoesNotThrow(() -> sut.run(requestMock, EVENT_ID, documentdb, contextMock));
+
+ // test assertion
+ assertNotNull(response);
+ assertEquals(HttpStatus.INTERNAL_SERVER_ERROR, response.getStatus());
+ assertNotNull(response.getBody());
+
+ }
+
+ @Test
+ void requestWithMissingCartOnRequestIdShouldReturnNotFound() throws CartNotFoundException {
+ when(cartReceiptsCosmosClient.getCartItem(EVENT_ID)).thenThrow(CartNotFoundException.class);
+
+ doAnswer((Answer) invocation -> {
+ HttpStatus status = (HttpStatus) invocation.getArguments()[0];
+ return new HttpResponseMessageMock.HttpResponseMessageBuilderMock().status(status);
+ }).when(requestMock).createResponseBuilder(any(HttpStatus.class));
+
+ // test execution
+ HttpResponseMessage response = assertDoesNotThrow(() -> sut.run(requestMock, EVENT_ID, documentdb, contextMock));
+
+ assertNotNull(response);
+ assertEquals(HttpStatus.NOT_FOUND, response.getStatus());
+ assertNotNull(response.getBody());
+ }
+
+ @Test
+ void requestWithMissingCartIdShouldReturnError() throws CartNotFoundException {
+ doAnswer((Answer) invocation -> {
+ HttpStatus status = (HttpStatus) invocation.getArguments()[0];
+ return new HttpResponseMessageMock.HttpResponseMessageBuilderMock().status(status);
+ }).when(requestMock).createResponseBuilder(any(HttpStatus.class));
+
+ // test execution
+ HttpResponseMessage response = assertDoesNotThrow(() -> sut.run(requestMock, null, documentdb, contextMock));
+
+ assertNotNull(response);
+ assertEquals(HttpStatus.BAD_REQUEST, response.getStatus());
+ assertNotNull(response.getBody());
+ }
+
+ @Test
+ @SneakyThrows
+ void errorTokenizingFiscalCodes() {
+ when(bizEventCosmosClientMock.getBizEventDocument(EVENT_ID)).thenReturn(generateValidBizEvent("1"));
+ when(receiptCosmosServiceMock.getReceipt(EVENT_ID)).thenThrow(ReceiptNotFoundException.class);
+ lenient().when(pdvTokenizerServiceMock.generateTokenForFiscalCodeWithRetry(DEBTOR_FISCAL_CODE))
+ .thenThrow(new PDVTokenizerException(HTTP_MESSAGE_ERROR, org.apache.http.HttpStatus.SC_INTERNAL_SERVER_ERROR));
+
+
+ doAnswer((Answer) invocation -> {
+ HttpStatus status = (HttpStatus) invocation.getArguments()[0];
+ return new HttpResponseMessageMock.HttpResponseMessageBuilderMock().status(status);
+ }).when(requestMock).createResponseBuilder(any(HttpStatus.class));
+
+ when(cartReceiptsCosmosClient.getCartItem(EVENT_ID)).thenReturn(generateCart());
+
+ FeedResponse feedResponseMock = mock(FeedResponse.class);
+ List receiptList = Collections.singletonList(generateValidBizEvent("1"));
+ when(feedResponseMock.getResults()).thenReturn(receiptList);
+ doReturn(Collections.singletonList(feedResponseMock)).when(bizEventCosmosClientMock)
+ .getAllBizEventDocument(Mockito.eq("1"), any(), any());
+ // test execution
+ HttpResponseMessage response = assertDoesNotThrow(() -> sut.run(requestMock, EVENT_ID, documentdb, contextMock));
+
+ // test assertion
+ assertNotNull(response);
+ assertEquals(HttpStatus.INTERNAL_SERVER_ERROR, response.getStatus());
+
+ ProblemJson problemJson = (ProblemJson) response.getBody();
+ assertNotNull(problemJson);
+ assertEquals(HttpStatus.INTERNAL_SERVER_ERROR.value(), problemJson.getStatus());
+ assertEquals(HttpStatus.INTERNAL_SERVER_ERROR.name(), problemJson.getTitle());
+ assertNotNull(problemJson.getDetail());
+
+ verifyNoInteractions(queueClientMock);
+ }
+
+ @Test
+ @SneakyThrows
+ void errorAddingMessageToQueue() {
+ when(pdvTokenizerServiceMock.generateTokenForFiscalCodeWithRetry(DEBTOR_FISCAL_CODE))
+ .thenReturn(TOKENIZED_DEBTOR_FISCAL_CODE);
+ when(pdvTokenizerServiceMock.generateTokenForFiscalCodeWithRetry(PAYER_FISCAL_CODE))
+ .thenReturn(TOKENIZED_PAYER_FISCAL_CODE);
+
+ Response queueResponse = mock(Response.class);
+ when(queueResponse.getStatusCode()).thenReturn(HttpStatus.FORBIDDEN.value());
+ when(queueClientMock.sendMessageToQueue(anyString())).thenReturn(queueResponse);
+
+ when(cartReceiptsCosmosClient.getCartItem(EVENT_ID)).thenReturn(generateCart());
+
+ FeedResponse feedResponseMock = mock(FeedResponse.class);
+ List receiptList = Collections.singletonList(generateValidBizEvent("1"));
+ when(feedResponseMock.getResults()).thenReturn(receiptList);
+ doReturn(Collections.singletonList(feedResponseMock)).when(bizEventCosmosClientMock)
+ .getAllBizEventDocument(Mockito.eq("1"), any(), any());
+ doAnswer((Answer) invocation -> {
+ HttpStatus status = (HttpStatus) invocation.getArguments()[0];
+ return new HttpResponseMessageMock.HttpResponseMessageBuilderMock().status(status);
+ }).when(requestMock).createResponseBuilder(any(HttpStatus.class));
+
+ // test execution
+ assertDoesNotThrow(() -> sut.run(requestMock, EVENT_ID, documentdb, contextMock));
+ }
+
+
+
+ private BizEvent generateValidBizEvent(String totalNotice){
+ BizEvent item = new BizEvent();
+
+ Payer payer = new Payer();
+ payer.setEntityUniqueIdentifierValue(PAYER_FISCAL_CODE);
+ Debtor debtor = new Debtor();
+ debtor.setEntityUniqueIdentifierValue(DEBTOR_FISCAL_CODE);
+
+ TransactionDetails transactionDetails = new TransactionDetails();
+ Transaction transaction = new Transaction();
+ transaction.setCreationDate(String.valueOf(LocalDateTime.now()));
+ transactionDetails.setTransaction(transaction);
+
+ PaymentInfo paymentInfo = new PaymentInfo();
+ paymentInfo.setTotalNotice(totalNotice);
+ paymentInfo.setAmount("102.30");
+
+ item.setEventStatus(BizEventStatusType.DONE);
+ item.setId(EVENT_ID);
+ item.setPayer(payer);
+ item.setDebtor(debtor);
+ item.setTransactionDetails(transactionDetails);
+ item.setPaymentInfo(paymentInfo);
+
+ return item;
+ }
+
+ private CartForReceipt generateCart() {
+ CartForReceipt cart = new CartForReceipt();
+ cart.setId("1");
+ cart.setStatus(CartStatusType.FAILED);
+ cart.setTotalNotice(2);
+ cart.setCartPaymentId(new HashSet<>(new ArrayList<>(
+ List.of(new String[]{"1", "2"}))));
+ return cart;
+ }
+
+}
\ No newline at end of file
diff --git a/src/test/java/it/gov/pagopa/receipt/pdf/helpdesk/RecoverFailedReceiptTest.java b/src/test/java/it/gov/pagopa/receipt/pdf/helpdesk/RecoverFailedReceiptTest.java
index f85bb948..98c5d0a1 100644
--- a/src/test/java/it/gov/pagopa/receipt/pdf/helpdesk/RecoverFailedReceiptTest.java
+++ b/src/test/java/it/gov/pagopa/receipt/pdf/helpdesk/RecoverFailedReceiptTest.java
@@ -1,6 +1,7 @@
package it.gov.pagopa.receipt.pdf.helpdesk;
import com.azure.core.http.rest.Response;
+import com.azure.cosmos.models.FeedResponse;
import com.azure.storage.queue.models.SendMessageResult;
import com.microsoft.azure.functions.ExecutionContext;
import com.microsoft.azure.functions.HttpRequestMessage;
@@ -9,6 +10,7 @@
import com.microsoft.azure.functions.OutputBinding;
import it.gov.pagopa.receipt.pdf.helpdesk.client.ReceiptQueueClient;
import it.gov.pagopa.receipt.pdf.helpdesk.client.impl.BizEventCosmosClientImpl;
+import it.gov.pagopa.receipt.pdf.helpdesk.client.impl.ReceiptCosmosClientImpl;
import it.gov.pagopa.receipt.pdf.helpdesk.entity.event.*;
import it.gov.pagopa.receipt.pdf.helpdesk.entity.event.enumeration.BizEventStatusType;
import it.gov.pagopa.receipt.pdf.helpdesk.entity.receipt.CartItem;
@@ -28,11 +30,7 @@
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
-import org.mockito.ArgumentCaptor;
-import org.mockito.Captor;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-import org.mockito.Spy;
+import org.mockito.*;
import org.mockito.junit.jupiter.MockitoExtension;
import org.mockito.stubbing.Answer;
@@ -45,14 +43,7 @@
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.mockito.ArgumentMatchers.anyString;
-import static org.mockito.Mockito.any;
-import static org.mockito.Mockito.doAnswer;
-import static org.mockito.Mockito.lenient;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyNoInteractions;
-import static org.mockito.Mockito.when;
+import static org.mockito.Mockito.*;
@ExtendWith(MockitoExtension.class)
class RecoverFailedReceiptTest {
@@ -76,6 +67,9 @@ class RecoverFailedReceiptTest {
@Mock
private BizEventCosmosClientImpl bizEventCosmosClientMock;
+ @Mock
+ private ReceiptCosmosClientImpl receiptCosmosClient;
+
@Mock
private HttpRequestMessage> requestMock;
@@ -92,7 +86,8 @@ class RecoverFailedReceiptTest {
@BeforeEach
public void openMocks() {
closeable = MockitoAnnotations.openMocks(this);
- BizEventToReceiptServiceImpl receiptService = new BizEventToReceiptServiceImpl(pdvTokenizerServiceMock, queueClientMock);
+ BizEventToReceiptServiceImpl receiptService = new BizEventToReceiptServiceImpl(
+ pdvTokenizerServiceMock, queueClientMock, bizEventCosmosClientMock, receiptCosmosClient);
sut = spy(new RecoverFailedReceipt(receiptService, bizEventCosmosClientMock, receiptCosmosServiceMock));
}
@@ -141,6 +136,51 @@ void requestOnValidBizEventShouldCreateRequest() {
assertEquals(1, captured.getEventData().getCart().size());
}
+ @Test
+ @SneakyThrows
+ void requestOnValidCartShouldCreateRequest() {
+ when(pdvTokenizerServiceMock.generateTokenForFiscalCodeWithRetry(DEBTOR_FISCAL_CODE))
+ .thenReturn(TOKENIZED_DEBTOR_FISCAL_CODE);
+ when(pdvTokenizerServiceMock.generateTokenForFiscalCodeWithRetry(PAYER_FISCAL_CODE))
+ .thenReturn(TOKENIZED_PAYER_FISCAL_CODE);
+
+ Response queueResponse = mock(Response.class);
+ when(queueResponse.getStatusCode()).thenReturn(HttpStatus.CREATED.value());
+ when(queueClientMock.sendMessageToQueue(anyString())).thenReturn(queueResponse);
+
+ when(requestMock.getQueryParameters()).thenReturn(Collections.singletonMap("isCart","true"));
+
+ FeedResponse feedResponseMock = mock(FeedResponse.class);
+ List receiptList = Collections.singletonList(generateValidBizEvent("1"));
+ when(feedResponseMock.getResults()).thenReturn(receiptList);
+ doReturn(Collections.singletonList(feedResponseMock)).when(bizEventCosmosClientMock)
+ .getAllBizEventDocument(Mockito.eq("a valid id"), any(), any());
+
+ when(receiptCosmosServiceMock.getReceipt(EVENT_ID)).thenThrow(ReceiptNotFoundException.class);
+
+ doAnswer((Answer) invocation -> {
+ HttpStatus status = (HttpStatus) invocation.getArguments()[0];
+ return new HttpResponseMessageMock.HttpResponseMessageBuilderMock().status(status);
+ }).when(requestMock).createResponseBuilder(any(HttpStatus.class));
+
+ // test execution
+ HttpResponseMessage response = assertDoesNotThrow(() -> sut.run(requestMock, EVENT_ID, documentdb, contextMock));
+
+ // test assertion
+ assertNotNull(response);
+ assertEquals(HttpStatus.OK, response.getStatus());
+ assertNotNull(response.getBody());
+
+ verify(documentdb).setValue(receiptCaptor.capture());
+ Receipt captured = receiptCaptor.getValue();
+ assertEquals(ReceiptStatusType.INSERTED, captured.getStatus());
+ assertEquals(EVENT_ID, captured.getEventId());
+ assertEquals(TOKENIZED_PAYER_FISCAL_CODE, captured.getEventData().getPayerFiscalCode());
+ assertEquals(TOKENIZED_DEBTOR_FISCAL_CODE, captured.getEventData().getDebtorFiscalCode());
+ assertNotNull(captured.getEventData().getCart());
+ assertEquals(1, captured.getEventData().getCart().size());
+ }
+
@Test
@SneakyThrows
void requestOnValidBizEventTransactionDetailsShouldCreateRequest() {
@@ -216,6 +256,45 @@ void requestOnValidBizEventAndFailedReceiptShouldResend() throws BizEventNotFoun
assertEquals(1, captured.getEventData().getCart().size());
}
+ @Test
+ void requestOnValidCartAndFailedReceiptShouldResend() throws BizEventNotFoundException, ReceiptNotFoundException {
+ when(receiptCosmosServiceMock.getReceipt(EVENT_ID)).thenReturn(createFailedReceipt());
+
+ Response queueResponse = mock(Response.class);
+ when(queueResponse.getStatusCode()).thenReturn(HttpStatus.CREATED.value());
+ when(queueClientMock.sendMessageToQueue(anyString())).thenReturn(queueResponse);
+
+ FeedResponse feedResponseMock = mock(FeedResponse.class);
+ List receiptList = Collections.singletonList(generateValidBizEvent("1"));
+ when(feedResponseMock.getResults()).thenReturn(receiptList);
+ doReturn(Collections.singletonList(feedResponseMock)).when(bizEventCosmosClientMock)
+ .getAllBizEventDocument(Mockito.eq("a valid id"), any(), any());
+
+ doAnswer((Answer) invocation -> {
+ HttpStatus status = (HttpStatus) invocation.getArguments()[0];
+ return new HttpResponseMessageMock.HttpResponseMessageBuilderMock().status(status);
+ }).when(requestMock).createResponseBuilder(any(HttpStatus.class));
+
+ when(requestMock.getQueryParameters()).thenReturn(Collections.singletonMap("isCart","true"));
+
+ // test execution
+ HttpResponseMessage response = assertDoesNotThrow(() -> sut.run(requestMock, EVENT_ID, documentdb, contextMock));
+
+ // test assertion
+ assertNotNull(response);
+ assertEquals(HttpStatus.OK, response.getStatus());
+ assertNotNull(response.getBody());
+
+ verify(documentdb).setValue(receiptCaptor.capture());
+ Receipt captured = receiptCaptor.getValue();
+ assertEquals(ReceiptStatusType.INSERTED, captured.getStatus());
+ assertEquals(EVENT_ID, captured.getEventId());
+ assertEquals(TOKENIZED_PAYER_FISCAL_CODE, captured.getEventData().getPayerFiscalCode());
+ assertEquals(TOKENIZED_DEBTOR_FISCAL_CODE, captured.getEventData().getDebtorFiscalCode());
+ assertNotNull(captured.getEventData().getCart());
+ assertEquals(1, captured.getEventData().getCart().size());
+ }
+
@Test
@SneakyThrows
void requestOnValidBizEventAndFailedReceiptWithoutEventDataShouldUpdateWithToken() {
diff --git a/src/test/java/it/gov/pagopa/receipt/pdf/helpdesk/RecoverNotNotifiedReceiptTest.java b/src/test/java/it/gov/pagopa/receipt/pdf/helpdesk/RecoverNotNotifiedReceiptTest.java
index a87be3d7..dbb4cbe2 100644
--- a/src/test/java/it/gov/pagopa/receipt/pdf/helpdesk/RecoverNotNotifiedReceiptTest.java
+++ b/src/test/java/it/gov/pagopa/receipt/pdf/helpdesk/RecoverNotNotifiedReceiptTest.java
@@ -5,9 +5,12 @@
import com.microsoft.azure.functions.HttpResponseMessage;
import com.microsoft.azure.functions.HttpStatus;
import com.microsoft.azure.functions.OutputBinding;
+import it.gov.pagopa.receipt.pdf.helpdesk.entity.cart.CartForReceipt;
+import it.gov.pagopa.receipt.pdf.helpdesk.entity.cart.CartStatusType;
import it.gov.pagopa.receipt.pdf.helpdesk.entity.receipt.ReasonError;
import it.gov.pagopa.receipt.pdf.helpdesk.entity.receipt.Receipt;
import it.gov.pagopa.receipt.pdf.helpdesk.entity.receipt.enumeration.ReceiptStatusType;
+import it.gov.pagopa.receipt.pdf.helpdesk.exception.CartNotFoundException;
import it.gov.pagopa.receipt.pdf.helpdesk.exception.ReceiptNotFoundException;
import it.gov.pagopa.receipt.pdf.helpdesk.model.ProblemJson;
import it.gov.pagopa.receipt.pdf.helpdesk.service.ReceiptCosmosService;
@@ -24,8 +27,7 @@
import org.mockito.junit.jupiter.MockitoExtension;
import org.mockito.stubbing.Answer;
-import java.util.List;
-import java.util.Optional;
+import java.util.*;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
@@ -101,6 +103,39 @@ void recoverNotNotifiedReceiptSuccess() throws ReceiptNotFoundException {
assertNull(captured.getReasonErrPayer());
}
+ @Test
+ void recoverNotNotifiedCartReceiptSuccess() throws ReceiptNotFoundException, CartNotFoundException {
+ Receipt receipt = buildReceipt();
+ when(receiptCosmosServiceMock.getReceipt(EVENT_ID)).thenReturn(receipt);
+
+ doAnswer((Answer) invocation -> {
+ HttpStatus status = (HttpStatus) invocation.getArguments()[0];
+ return new HttpResponseMessageMock.HttpResponseMessageBuilderMock().status(status);
+ }).when(requestMock).createResponseBuilder(any(HttpStatus.class));
+
+ when(requestMock.getQueryParameters()).thenReturn(Collections.singletonMap("isCart","true"));
+
+ when(receiptCosmosServiceMock.getCart(any())).thenReturn(generateCart());
+
+ // test execution
+ HttpResponseMessage response = sut.run(requestMock, EVENT_ID, documentReceipts, executionContextMock);
+
+ // test assertion
+ assertNotNull(response);
+ assertEquals(HttpStatus.OK, response.getStatus());
+ assertNotNull(response.getBody());
+
+ verify(documentReceipts).setValue(receiptCaptor.capture());
+
+ assertEquals(1, receiptCaptor.getValue().size());
+ Receipt captured = receiptCaptor.getValue().get(0);
+ assertEquals(ReceiptStatusType.GENERATED, captured.getStatus());
+ assertEquals(EVENT_ID, captured.getEventId());
+ assertEquals(0, captured.getNotificationNumRetry());
+ assertNull(captured.getReasonErr());
+ assertNull(captured.getReasonErrPayer());
+ }
+
@Test
void recoverReceiptFailForMissingEventId() {
doAnswer((Answer) invocation -> {
@@ -217,4 +252,14 @@ private Receipt buildReceipt() {
.notifiedAt(0)
.build();
}
+
+ private CartForReceipt generateCart() {
+ CartForReceipt cart = new CartForReceipt();
+ cart.setId("1");
+ cart.setStatus(CartStatusType.FAILED);
+ cart.setTotalNotice(1);
+ cart.setCartPaymentId(new HashSet<>(new ArrayList<>(
+ List.of(new String[]{"eventId"}))));
+ return cart;
+ }
}
\ No newline at end of file
diff --git a/src/test/java/it/gov/pagopa/receipt/pdf/helpdesk/client/impl/CartReceiptsCosmosClientImplTest.java b/src/test/java/it/gov/pagopa/receipt/pdf/helpdesk/client/impl/CartReceiptsCosmosClientImplTest.java
new file mode 100644
index 00000000..32965dbc
--- /dev/null
+++ b/src/test/java/it/gov/pagopa/receipt/pdf/helpdesk/client/impl/CartReceiptsCosmosClientImplTest.java
@@ -0,0 +1,116 @@
+package it.gov.pagopa.receipt.pdf.helpdesk.client.impl;
+
+import com.azure.cosmos.CosmosClient;
+import com.azure.cosmos.CosmosContainer;
+import com.azure.cosmos.CosmosDatabase;
+import com.azure.cosmos.util.CosmosPagedIterable;
+import it.gov.pagopa.receipt.pdf.helpdesk.entity.cart.CartForReceipt;
+import it.gov.pagopa.receipt.pdf.helpdesk.entity.receipt.Receipt;
+import it.gov.pagopa.receipt.pdf.helpdesk.exception.CartNotFoundException;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+import java.util.Iterator;
+
+import static org.mockito.ArgumentMatchers.*;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+import static uk.org.webcompere.systemstubs.SystemStubs.withEnvironmentVariables;
+
+class CartReceiptsCosmosClientImplTest {
+
+ @Test
+ void testSingletonConnectionError() throws Exception {
+ String mockKey = "mockKeymockKeymockKeymockKeymockKeymockKeymockKeymockKeymockKeymockKeymockKeymockKeyMK==";
+ withEnvironmentVariables(
+ "COSMOS_RECEIPT_KEY", mockKey,
+ "COSMOS_RECEIPT_SERVICE_ENDPOINT", ""
+ ).execute(() -> Assertions.assertThrows(IllegalArgumentException.class, CartReceiptsCosmosClientImpl::getInstance)
+ );
+ }
+
+ @Test
+ void runOk_Cart() throws CartNotFoundException {
+ Long CART_ID = 1L;
+
+ CosmosClient mockClient = mock(CosmosClient.class);
+
+ CosmosDatabase mockDatabase = mock(CosmosDatabase.class);
+ CosmosContainer mockContainer = mock(CosmosContainer.class);
+
+ CosmosPagedIterable mockIterable = mock(CosmosPagedIterable.class);
+
+ Iterator mockIterator = mock(Iterator.class);
+ CartForReceipt cartForReceipt = new CartForReceipt();
+ cartForReceipt.setId(CART_ID.toString());
+
+ when(mockIterator.hasNext()).thenReturn(true);
+ when(mockIterator.next()).thenReturn(cartForReceipt);
+
+ when(mockIterable.iterator()).thenReturn(mockIterator);
+
+ when(mockContainer.queryItems(anyString(), any(), eq(CartForReceipt.class))).thenReturn(
+ mockIterable
+ );
+ when(mockDatabase.getContainer(any())).thenReturn(mockContainer);
+ when(mockClient.getDatabase(any())).thenReturn(mockDatabase);
+
+ CartReceiptsCosmosClientImpl client = new CartReceiptsCosmosClientImpl(mockClient);
+
+ Assertions.assertDoesNotThrow(() -> client.getCartItem(String.valueOf(CART_ID)));
+
+ CartForReceipt cartResponse = client.getCartItem(String.valueOf(CART_ID));
+
+ Assertions.assertEquals(CART_ID.toString(), cartResponse.getId());
+
+ }
+
+ @Test
+ void runKo_Cart() {
+ CosmosClient mockClient = mock(CosmosClient.class);
+
+ CosmosDatabase mockDatabase = mock(CosmosDatabase.class);
+ CosmosContainer mockContainer = mock(CosmosContainer.class);
+
+ CosmosPagedIterable mockIterable = mock(CosmosPagedIterable.class);
+
+ Iterator mockIterator = mock(Iterator.class);
+
+ when(mockIterator.hasNext()).thenReturn(false);
+
+ when(mockIterable.iterator()).thenReturn(mockIterator);
+
+ when(mockContainer.queryItems(anyString(), any(), eq(CartForReceipt.class))).thenReturn(
+ mockIterable
+ );
+ when(mockDatabase.getContainer(any())).thenReturn(mockContainer);
+ when(mockClient.getDatabase(any())).thenReturn(mockDatabase);
+
+ CartReceiptsCosmosClientImpl client = new CartReceiptsCosmosClientImpl(mockClient);
+
+ Assertions.assertThrows(CartNotFoundException.class, () -> client.getCartItem("an invalid receipt id"));
+ }
+
+ @Test
+ void runOk_SaveCart() throws CartNotFoundException {
+ Long CART_ID = 1L;
+
+ CosmosClient mockClient = mock(CosmosClient.class);
+
+ CosmosDatabase mockDatabase = mock(CosmosDatabase.class);
+ CosmosContainer mockContainer = mock(CosmosContainer.class);
+
+ CartForReceipt cartForReceipt = new CartForReceipt();
+
+ cartForReceipt.setId(CART_ID.toString());
+
+ when(mockDatabase.getContainer(any())).thenReturn(mockContainer);
+ when(mockClient.getDatabase(any())).thenReturn(mockDatabase);
+
+ CartReceiptsCosmosClientImpl client = new CartReceiptsCosmosClientImpl(mockClient);
+
+ Assertions.assertDoesNotThrow(() -> client.saveCart(cartForReceipt));
+
+ }
+
+}
\ No newline at end of file
diff --git a/src/test/java/it/gov/pagopa/receipt/pdf/helpdesk/service/impl/BizEventToReceiptServiceImplTest.java b/src/test/java/it/gov/pagopa/receipt/pdf/helpdesk/service/impl/BizEventToReceiptServiceImplTest.java
new file mode 100644
index 00000000..673adec0
--- /dev/null
+++ b/src/test/java/it/gov/pagopa/receipt/pdf/helpdesk/service/impl/BizEventToReceiptServiceImplTest.java
@@ -0,0 +1,59 @@
+package it.gov.pagopa.receipt.pdf.helpdesk.service.impl;
+
+import com.azure.cosmos.models.FeedResponse;
+import it.gov.pagopa.receipt.pdf.helpdesk.client.BizEventCosmosClient;
+import it.gov.pagopa.receipt.pdf.helpdesk.client.impl.ReceiptCosmosClientImpl;
+import it.gov.pagopa.receipt.pdf.helpdesk.client.impl.ReceiptQueueClientImpl;
+import it.gov.pagopa.receipt.pdf.helpdesk.entity.event.BizEvent;
+import it.gov.pagopa.receipt.pdf.helpdesk.service.PDVTokenizerServiceRetryWrapper;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.mockito.junit.jupiter.MockitoSettings;
+import org.mockito.quality.Strictness;
+import uk.org.webcompere.systemstubs.jupiter.SystemStubsExtension;
+
+import java.util.Collections;
+
+import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.*;
+
+@ExtendWith({MockitoExtension.class, SystemStubsExtension.class})
+@MockitoSettings(strictness = Strictness.LENIENT)
+public class BizEventToReceiptServiceImplTest {
+
+ private BizEventToReceiptServiceImpl bizEventToReceiptService;
+ @Mock
+ private PDVTokenizerServiceRetryWrapper pdvTokenizerServiceMock;
+ @Mock
+ private ReceiptCosmosClientImpl receiptCosmosClient;
+ @Mock
+ private BizEventCosmosClient bizEventCosmosClientMock;
+ @Mock
+ private ReceiptQueueClientImpl queueClient;
+
+
+ @BeforeEach
+ public void init() {
+ bizEventToReceiptService = new BizEventToReceiptServiceImpl(
+ pdvTokenizerServiceMock,
+ queueClient,
+ bizEventCosmosClientMock,
+ receiptCosmosClient
+ );
+ }
+
+ @Test
+ public void run_OK_getCartBizEvents() {
+ FeedResponse feedResponseMock = mock(FeedResponse.class);
+ when(feedResponseMock.getResults()).thenReturn(Collections.singletonList(new BizEvent()));
+ doReturn(Collections.singletonList(feedResponseMock)).when(bizEventCosmosClientMock)
+ .getAllBizEventDocument(Mockito.eq("1"), any(), any());
+ assertDoesNotThrow(() -> bizEventToReceiptService.getCartBizEvents("1"));
+ }
+
+}
diff --git a/src/test/java/it/gov/pagopa/receipt/pdf/helpdesk/service/impl/BuildTemplateServiceImplTest.java b/src/test/java/it/gov/pagopa/receipt/pdf/helpdesk/service/impl/BuildTemplateServiceImplTest.java
index 9e59a1f3..1039b391 100644
--- a/src/test/java/it/gov/pagopa/receipt/pdf/helpdesk/service/impl/BuildTemplateServiceImplTest.java
+++ b/src/test/java/it/gov/pagopa/receipt/pdf/helpdesk/service/impl/BuildTemplateServiceImplTest.java
@@ -12,9 +12,9 @@
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
+import java.math.BigDecimal;
+import java.text.NumberFormat;
+import java.util.*;
import java.util.concurrent.atomic.AtomicReference;
import static org.junit.jupiter.api.Assertions.*;
@@ -77,10 +77,13 @@ class BuildTemplateServiceImplTest {
private static final String NOT_PAGO_PA_CHANNEL = "NOT_PAGO_PA_CHANNEL";
private static final String ID_PA = "idPa";
private static final String USER_NAME = "user_name";
- private static final String USER_SURNAME = "user_surname";
+ private static final String USER_SURNAME = "user_surname";
private static final String USER_FORMATTED_FULL_NAME = "user_name user_surname";
private static final String USER_TAX_CODE = "user tax code";
public static final String PAGOPA_PA_CHANNEL_ID = "pagopa channel";
+ public static final String RECEIPT_ID = "receipt-id";
+ public static final String BIZ_EVENT = "bizEvent";
+ public static final String RECEIPT = "receipt";
private BuildTemplateServiceImpl buildTemplateService;
@BeforeEach
@@ -94,7 +97,7 @@ void setUp() throws Exception {
@Test
void mapTemplateAllFieldsSuccessCompleteTemplateAndIOChannel() {
- BizEvent event = BizEvent.builder()
+ List bizEventList = Collections.singletonList(BizEvent.builder()
.id(BIZ_EVENT_ID)
.idPaymentManager(BIZ_EVENT_ID)
.debtorPosition(DebtorPosition.builder()
@@ -142,11 +145,12 @@ void mapTemplateAllFieldsSuccessCompleteTemplateAndIOChannel() {
.build())
.build())
.eventStatus(BizEventStatusType.DONE)
- .build();
- Receipt receipt = Receipt.builder().eventData(EventData.builder().cart(List.of(CartItem.builder().subject(REMITTANCE_INFORMATION).build())).build()).build();
+ .build()
+ );
+ Receipt receipt = Receipt.builder().eventId(BIZ_EVENT_ID).eventData(EventData.builder().amount(FORMATTED_GRAND_TOTAL).cart(List.of(CartItem.builder().subject(REMITTANCE_INFORMATION).build())).build()).build();
AtomicReference atomicReference = new AtomicReference<>();
- assertDoesNotThrow(() -> atomicReference.set(buildTemplateService.buildTemplate(event, GENERATED_BY_DEBTOR, receipt)));
+ assertDoesNotThrow(() -> atomicReference.set(buildTemplateService.buildTemplate(bizEventList, GENERATED_BY_DEBTOR, receipt)));
ReceiptPDFTemplate receiptPdfTemplate = atomicReference.get();
@@ -189,7 +193,7 @@ void mapTemplateAllFieldsSuccessCompleteTemplateAndIOChannel() {
@Test
void mapTemplateAllFieldsSuccessCompleteTemplateAndIOChannelAndDateZonedDSTWinter() {
- BizEvent event = BizEvent.builder()
+ List bizEventList = Collections.singletonList(BizEvent.builder()
.id(BIZ_EVENT_ID)
.idPaymentManager(BIZ_EVENT_ID)
.debtorPosition(DebtorPosition.builder()
@@ -237,11 +241,11 @@ void mapTemplateAllFieldsSuccessCompleteTemplateAndIOChannelAndDateZonedDSTWinte
.build())
.build())
.eventStatus(BizEventStatusType.DONE)
- .build();
- Receipt receipt = Receipt.builder().eventData(EventData.builder().cart(List.of(CartItem.builder().subject(REMITTANCE_INFORMATION).build())).build()).build();
+ .build());
+ Receipt receipt = Receipt.builder().eventId(BIZ_EVENT_ID).eventData(EventData.builder().amount(FORMATTED_GRAND_TOTAL).cart(List.of(CartItem.builder().subject(REMITTANCE_INFORMATION).build())).build()).build();
AtomicReference atomicReference = new AtomicReference<>();
- assertDoesNotThrow(() -> atomicReference.set(buildTemplateService.buildTemplate(event, GENERATED_BY_DEBTOR, receipt)));
+ assertDoesNotThrow(() -> atomicReference.set(buildTemplateService.buildTemplate(bizEventList, GENERATED_BY_DEBTOR, receipt)));
ReceiptPDFTemplate receiptPdfTemplate = atomicReference.get();
@@ -284,7 +288,7 @@ void mapTemplateAllFieldsSuccessCompleteTemplateAndIOChannelAndDateZonedDSTWinte
@Test
void mapTemplateAllFieldsSuccessCompleteTemplateAndIOChannelAndDateZonedDSTSummer() {
- BizEvent event = BizEvent.builder()
+ List bizEventList = Collections.singletonList(BizEvent.builder()
.id(BIZ_EVENT_ID)
.idPaymentManager(BIZ_EVENT_ID)
.debtorPosition(DebtorPosition.builder()
@@ -332,11 +336,11 @@ void mapTemplateAllFieldsSuccessCompleteTemplateAndIOChannelAndDateZonedDSTSumme
.build())
.build())
.eventStatus(BizEventStatusType.DONE)
- .build();
- Receipt receipt = Receipt.builder().eventData(EventData.builder().cart(List.of(CartItem.builder().subject(REMITTANCE_INFORMATION).build())).build()).build();
+ .build());
+ Receipt receipt = Receipt.builder().eventId(BIZ_EVENT_ID).eventData(EventData.builder().amount(FORMATTED_GRAND_TOTAL).cart(List.of(CartItem.builder().subject(REMITTANCE_INFORMATION).build())).build()).build();
AtomicReference atomicReference = new AtomicReference<>();
- assertDoesNotThrow(() -> atomicReference.set(buildTemplateService.buildTemplate(event, GENERATED_BY_DEBTOR, receipt)));
+ assertDoesNotThrow(() -> atomicReference.set(buildTemplateService.buildTemplate(bizEventList, GENERATED_BY_DEBTOR, receipt)));
ReceiptPDFTemplate receiptPdfTemplate = atomicReference.get();
@@ -379,7 +383,7 @@ void mapTemplateAllFieldsSuccessCompleteTemplateAndIOChannelAndDateZonedDSTSumme
@Test
void mapTemplateAllFieldsSuccessCompleteTemplateAndIOChannelAndDateZonedWithMillisecondsDSTWinter() {
- BizEvent event = BizEvent.builder()
+ List bizEventList = Collections.singletonList(BizEvent.builder()
.id(BIZ_EVENT_ID)
.idPaymentManager(BIZ_EVENT_ID)
.debtorPosition(DebtorPosition.builder()
@@ -427,11 +431,11 @@ void mapTemplateAllFieldsSuccessCompleteTemplateAndIOChannelAndDateZonedWithMill
.build())
.build())
.eventStatus(BizEventStatusType.DONE)
- .build();
- Receipt receipt = Receipt.builder().eventData(EventData.builder().cart(List.of(CartItem.builder().subject(REMITTANCE_INFORMATION).build())).build()).build();
+ .build());
+ Receipt receipt = Receipt.builder().eventId(BIZ_EVENT_ID).eventData(EventData.builder().amount(FORMATTED_GRAND_TOTAL).cart(List.of(CartItem.builder().subject(REMITTANCE_INFORMATION).build())).build()).build();
AtomicReference atomicReference = new AtomicReference<>();
- assertDoesNotThrow(() -> atomicReference.set(buildTemplateService.buildTemplate(event, GENERATED_BY_DEBTOR, receipt)));
+ assertDoesNotThrow(() -> atomicReference.set(buildTemplateService.buildTemplate(bizEventList, GENERATED_BY_DEBTOR, receipt)));
ReceiptPDFTemplate receiptPdfTemplate = atomicReference.get();
@@ -474,7 +478,7 @@ void mapTemplateAllFieldsSuccessCompleteTemplateAndIOChannelAndDateZonedWithMill
@Test
void mapTemplateAllFieldsSuccessCompleteTemplateAndIOChannelAndDateZonedWithMillisecondsDSTSummer() {
- BizEvent event = BizEvent.builder()
+ List bizEventList = Collections.singletonList(BizEvent.builder()
.id(BIZ_EVENT_ID)
.idPaymentManager(BIZ_EVENT_ID)
.debtorPosition(DebtorPosition.builder()
@@ -522,11 +526,11 @@ void mapTemplateAllFieldsSuccessCompleteTemplateAndIOChannelAndDateZonedWithMill
.build())
.build())
.eventStatus(BizEventStatusType.DONE)
- .build();
- Receipt receipt = Receipt.builder().eventData(EventData.builder().cart(List.of(CartItem.builder().subject(REMITTANCE_INFORMATION).build())).build()).build();
+ .build());
+ Receipt receipt = Receipt.builder().eventId(BIZ_EVENT_ID).eventData(EventData.builder().amount(FORMATTED_GRAND_TOTAL).cart(List.of(CartItem.builder().subject(REMITTANCE_INFORMATION).build())).build()).build();
AtomicReference atomicReference = new AtomicReference<>();
- assertDoesNotThrow(() -> atomicReference.set(buildTemplateService.buildTemplate(event, GENERATED_BY_DEBTOR, receipt)));
+ assertDoesNotThrow(() -> atomicReference.set(buildTemplateService.buildTemplate(bizEventList, GENERATED_BY_DEBTOR, receipt)));
ReceiptPDFTemplate receiptPdfTemplate = atomicReference.get();
@@ -569,7 +573,7 @@ void mapTemplateAllFieldsSuccessCompleteTemplateAndIOChannelAndDateZonedWithMill
@Test
void mapTemplateAllFieldsSuccessCompleteTemplateAndPagoPaChannelOnTransactionOrigin() {
- BizEvent event = BizEvent.builder()
+ List bizEventList = Collections.singletonList(BizEvent.builder()
.id(BIZ_EVENT_ID)
.idPaymentManager(BIZ_EVENT_ID)
.debtorPosition(DebtorPosition.builder()
@@ -617,11 +621,11 @@ void mapTemplateAllFieldsSuccessCompleteTemplateAndPagoPaChannelOnTransactionOri
.build())
.build())
.eventStatus(BizEventStatusType.DONE)
- .build();
- Receipt receipt = Receipt.builder().eventData(EventData.builder().cart(List.of(CartItem.builder().subject(REMITTANCE_INFORMATION).build())).build()).build();
+ .build());
+ Receipt receipt = Receipt.builder().eventId(BIZ_EVENT_ID).eventData(EventData.builder().amount(FORMATTED_GRAND_TOTAL).cart(List.of(CartItem.builder().subject(REMITTANCE_INFORMATION).build())).build()).build();
AtomicReference atomicReference = new AtomicReference<>();
- assertDoesNotThrow(() -> atomicReference.set(buildTemplateService.buildTemplate(event, GENERATED_BY_DEBTOR, receipt)));
+ assertDoesNotThrow(() -> atomicReference.set(buildTemplateService.buildTemplate(bizEventList, GENERATED_BY_DEBTOR, receipt)));
ReceiptPDFTemplate receiptPdfTemplate = atomicReference.get();
@@ -664,7 +668,7 @@ void mapTemplateAllFieldsSuccessCompleteTemplateAndPagoPaChannelOnTransactionOri
@Test
void mapTemplateAllFieldsSuccessCompleteTemplateAndPagoPaChannelOnChannelId() {
- BizEvent event = BizEvent.builder()
+ List bizEventList = Collections.singletonList(BizEvent.builder()
.id(BIZ_EVENT_ID)
.idPaymentManager(BIZ_EVENT_ID)
.debtorPosition(DebtorPosition.builder()
@@ -712,11 +716,11 @@ void mapTemplateAllFieldsSuccessCompleteTemplateAndPagoPaChannelOnChannelId() {
.build())
.build())
.eventStatus(BizEventStatusType.DONE)
- .build();
- Receipt receipt = Receipt.builder().eventData(EventData.builder().cart(List.of(CartItem.builder().subject(REMITTANCE_INFORMATION).build())).build()).build();
+ .build());
+ Receipt receipt = Receipt.builder().eventId(BIZ_EVENT_ID).eventData(EventData.builder().cart(List.of(CartItem.builder().subject(REMITTANCE_INFORMATION).build())).amount(FORMATTED_GRAND_TOTAL).build()).build();
AtomicReference atomicReference = new AtomicReference<>();
- assertDoesNotThrow(() -> atomicReference.set(buildTemplateService.buildTemplate(event, GENERATED_BY_DEBTOR, receipt)));
+ assertDoesNotThrow(() -> atomicReference.set(buildTemplateService.buildTemplate(bizEventList, GENERATED_BY_DEBTOR, receipt)));
ReceiptPDFTemplate receiptPdfTemplate = atomicReference.get();
@@ -759,7 +763,7 @@ void mapTemplateAllFieldsSuccessCompleteTemplateAndPagoPaChannelOnChannelId() {
@Test
void mapTemplateAllFieldsSuccessPartialTemplateAndNotPagoPaChannel() {
- BizEvent event = BizEvent.builder()
+ List bizEventList = Collections.singletonList(BizEvent.builder()
.id(BIZ_EVENT_ID)
.debtorPosition(DebtorPosition.builder()
.noticeNumber(NOTICE_NUMBER)
@@ -787,11 +791,11 @@ void mapTemplateAllFieldsSuccessPartialTemplateAndNotPagoPaChannel() {
.IUR(IUR)
.build())
.eventStatus(BizEventStatusType.DONE)
- .build();
- Receipt receipt = Receipt.builder().eventData(EventData.builder().cart(List.of(CartItem.builder().subject(REMITTANCE_INFORMATION).build())).build()).build();
+ .build());
+ Receipt receipt = Receipt.builder().eventId(BIZ_EVENT_ID).eventData(EventData.builder().amount(FORMATTED_AMOUNT).cart(List.of(CartItem.builder().subject(REMITTANCE_INFORMATION).build())).build()).build();
AtomicReference atomicReference = new AtomicReference<>();
- assertDoesNotThrow(() -> atomicReference.set(buildTemplateService.buildTemplate(event, GENERATED_BY_DEBTOR, receipt)));
+ assertDoesNotThrow(() -> atomicReference.set(buildTemplateService.buildTemplate(bizEventList, GENERATED_BY_DEBTOR, receipt)));
ReceiptPDFTemplate receiptPdfTemplate = atomicReference.get();
@@ -835,7 +839,7 @@ void mapTemplateAllFieldsSuccessPartialTemplateAndNotPagoPaChannel() {
@Test
void mapTemplateWithoutTransactionDetailsSuccess() {
- BizEvent event = BizEvent.builder()
+ List bizEventList = Collections.singletonList(BizEvent.builder()
.id(BIZ_EVENT_ID)
.debtorPosition(DebtorPosition.builder()
.iuv(IUV)
@@ -863,11 +867,11 @@ void mapTemplateWithoutTransactionDetailsSuccess() {
.IUR(IUR)
.build())
.eventStatus(BizEventStatusType.DONE)
- .build();
- Receipt receipt = Receipt.builder().eventData(EventData.builder().cart(List.of(CartItem.builder().subject(REMITTANCE_INFORMATION).build())).build()).build();
+ .build());
+ Receipt receipt = Receipt.builder().eventId(BIZ_EVENT_ID).eventData(EventData.builder().amount(FORMATTED_AMOUNT).cart(List.of(CartItem.builder().subject(REMITTANCE_INFORMATION).build())).build()).build();
AtomicReference atomicReference = new AtomicReference<>();
- assertDoesNotThrow(() -> atomicReference.set(buildTemplateService.buildTemplate(event, GENERATED_BY_DEBTOR, receipt)));
+ assertDoesNotThrow(() -> atomicReference.set(buildTemplateService.buildTemplate(bizEventList, GENERATED_BY_DEBTOR, receipt)));
ReceiptPDFTemplate receiptPdfTemplate = atomicReference.get();
@@ -910,7 +914,7 @@ void mapTemplateWithoutTransactionDetailsSuccess() {
@Test
void mapTemplateWithoutTransactionDetailsAndPaymentTokenSuccess() {
- BizEvent event = BizEvent.builder()
+ List bizEventList = Collections.singletonList(BizEvent.builder()
.id(BIZ_EVENT_ID)
.debtorPosition(DebtorPosition.builder()
.iuv(IUV)
@@ -937,11 +941,11 @@ void mapTemplateWithoutTransactionDetailsAndPaymentTokenSuccess() {
.IUR(IUR)
.build())
.eventStatus(BizEventStatusType.DONE)
- .build();
- Receipt receipt = Receipt.builder().eventData(EventData.builder().cart(List.of(CartItem.builder().subject(REMITTANCE_INFORMATION).build())).build()).build();
+ .build());
+ Receipt receipt = Receipt.builder().eventId(BIZ_EVENT_ID).eventData(EventData.builder().amount(FORMATTED_AMOUNT).cart(List.of(CartItem.builder().subject(REMITTANCE_INFORMATION).build())).build()).build();
AtomicReference atomicReference = new AtomicReference<>();
- assertDoesNotThrow(() -> atomicReference.set(buildTemplateService.buildTemplate(event, GENERATED_BY_DEBTOR, receipt)));
+ assertDoesNotThrow(() -> atomicReference.set(buildTemplateService.buildTemplate(bizEventList, GENERATED_BY_DEBTOR, receipt)));
ReceiptPDFTemplate receiptPdfTemplate = atomicReference.get();
@@ -983,7 +987,7 @@ void mapTemplateWithoutTransactionDetailsAndPaymentTokenSuccess() {
@Test
void mapTemplateAllFieldsSuccessDebtorFullNameEmpty() {
- BizEvent event = BizEvent.builder()
+ List bizEventList = Collections.singletonList(BizEvent.builder()
.id(BIZ_EVENT_ID)
.idPaymentManager(BIZ_EVENT_ID)
.debtorPosition(DebtorPosition.builder()
@@ -1031,11 +1035,11 @@ void mapTemplateAllFieldsSuccessDebtorFullNameEmpty() {
.build())
.build())
.eventStatus(BizEventStatusType.DONE)
- .build();
- Receipt receipt = Receipt.builder().eventData(EventData.builder().cart(List.of(CartItem.builder().subject(REMITTANCE_INFORMATION).build())).build()).build();
+ .build());
+ Receipt receipt = Receipt.builder().eventId(BIZ_EVENT_ID).eventData(EventData.builder().amount(FORMATTED_GRAND_TOTAL).cart(List.of(CartItem.builder().subject(REMITTANCE_INFORMATION).build())).build()).build();
AtomicReference atomicReference = new AtomicReference<>();
- assertDoesNotThrow(() -> atomicReference.set(buildTemplateService.buildTemplate(event, GENERATED_BY_DEBTOR, receipt)));
+ assertDoesNotThrow(() -> atomicReference.set(buildTemplateService.buildTemplate(bizEventList, GENERATED_BY_DEBTOR, receipt)));
ReceiptPDFTemplate receiptPdfTemplate = atomicReference.get();
@@ -1078,7 +1082,7 @@ void mapTemplateAllFieldsSuccessDebtorFullNameEmpty() {
@Test
void mapTemplateAllFieldsSuccessDebtorFullNameWithSpecialChar() {
- BizEvent event = BizEvent.builder()
+ List bizEventList = Collections.singletonList(BizEvent.builder()
.id(BIZ_EVENT_ID)
.idPaymentManager(BIZ_EVENT_ID)
.debtorPosition(DebtorPosition.builder()
@@ -1126,11 +1130,11 @@ void mapTemplateAllFieldsSuccessDebtorFullNameWithSpecialChar() {
.build())
.build())
.eventStatus(BizEventStatusType.DONE)
- .build();
- Receipt receipt = Receipt.builder().eventData(EventData.builder().cart(List.of(CartItem.builder().subject(REMITTANCE_INFORMATION).build())).build()).build();
+ .build());
+ Receipt receipt = Receipt.builder().eventId(BIZ_EVENT_ID).eventData(EventData.builder().amount(FORMATTED_GRAND_TOTAL).cart(List.of(CartItem.builder().subject(REMITTANCE_INFORMATION).build())).build()).build();
AtomicReference atomicReference = new AtomicReference<>();
- assertDoesNotThrow(() -> atomicReference.set(buildTemplateService.buildTemplate(event, GENERATED_BY_DEBTOR, receipt)));
+ assertDoesNotThrow(() -> atomicReference.set(buildTemplateService.buildTemplate(bizEventList, GENERATED_BY_DEBTOR, receipt)));
ReceiptPDFTemplate receiptPdfTemplate = atomicReference.get();
@@ -1173,7 +1177,7 @@ void mapTemplateAllFieldsSuccessDebtorFullNameWithSpecialChar() {
@Test
void mapTemplateAllFieldsSuccessDebtorFullNameEqualsFiscalCode() {
- BizEvent event = BizEvent.builder()
+ List bizEventList = Collections.singletonList(BizEvent.builder()
.id(BIZ_EVENT_ID)
.idPaymentManager(BIZ_EVENT_ID)
.debtorPosition(DebtorPosition.builder()
@@ -1221,11 +1225,11 @@ void mapTemplateAllFieldsSuccessDebtorFullNameEqualsFiscalCode() {
.build())
.build())
.eventStatus(BizEventStatusType.DONE)
- .build();
- Receipt receipt = Receipt.builder().eventData(EventData.builder().cart(List.of(CartItem.builder().subject(REMITTANCE_INFORMATION).build())).build()).build();
+ .build());
+ Receipt receipt = Receipt.builder().eventId(BIZ_EVENT_ID).eventData(EventData.builder().amount(FORMATTED_GRAND_TOTAL).cart(List.of(CartItem.builder().subject(REMITTANCE_INFORMATION).build())).build()).build();
AtomicReference atomicReference = new AtomicReference<>();
- assertDoesNotThrow(() -> atomicReference.set(buildTemplateService.buildTemplate(event, GENERATED_BY_DEBTOR, receipt)));
+ assertDoesNotThrow(() -> atomicReference.set(buildTemplateService.buildTemplate(bizEventList, GENERATED_BY_DEBTOR, receipt)));
ReceiptPDFTemplate receiptPdfTemplate = atomicReference.get();
@@ -1268,7 +1272,7 @@ void mapTemplateAllFieldsSuccessDebtorFullNameEqualsFiscalCode() {
@Test
void mapTemplateLeastAmountOfInfoSuccessPayer() {
- BizEvent event = BizEvent.builder()
+ List bizEventList = Collections.singletonList(BizEvent.builder()
.id(BIZ_EVENT_ID)
.paymentInfo(PaymentInfo.builder()
.IUR(IUR)
@@ -1294,16 +1298,14 @@ void mapTemplateLeastAmountOfInfoSuccessPayer() {
.creditor(Creditor.builder()
.idPA(ID_PA)
.build())
- .build();
- EventData eventData = EventData.builder().cart(Collections.singletonList(
- CartItem.builder().subject(REMITTANCE_INFORMATION).build())).build();
- assertDoesNotThrow(() -> buildTemplateService.buildTemplate(event, GENERATED_BY_PAYER,
- Receipt.builder().eventData(eventData).build()));
+ .build());
+ Receipt receipt = Receipt.builder().eventId(BIZ_EVENT_ID).eventData(EventData.builder().amount(FORMATTED_GRAND_TOTAL).cart(List.of(CartItem.builder().subject(REMITTANCE_INFORMATION).build())).build()).build();
+ assertDoesNotThrow(() -> buildTemplateService.buildTemplate(bizEventList, GENERATED_BY_PAYER, receipt));
}
@Test
void mapTemplateLeastAmountOfInfoSuccessDebtor() {
- BizEvent event = BizEvent.builder()
+ List bizEventList = Collections.singletonList(BizEvent.builder()
.id(BIZ_EVENT_ID)
.paymentInfo(PaymentInfo.builder()
.IUR(IUR)
@@ -1325,16 +1327,14 @@ void mapTemplateLeastAmountOfInfoSuccessDebtor() {
.creditor(Creditor.builder()
.idPA(ID_PA)
.build())
- .build();
- EventData eventData = EventData.builder().cart(Collections.singletonList(
- CartItem.builder().subject(REMITTANCE_INFORMATION).build())).build();
- assertDoesNotThrow(() -> buildTemplateService.buildTemplate(
- event, GENERATED_BY_DEBTOR, Receipt.builder().eventData(eventData).build()));
+ .build());
+ Receipt receipt = Receipt.builder().eventId(BIZ_EVENT_ID).eventData(EventData.builder().amount(FORMATTED_GRAND_TOTAL).cart(List.of(CartItem.builder().subject(REMITTANCE_INFORMATION).build())).build()).build();
+ assertDoesNotThrow(() -> buildTemplateService.buildTemplate(bizEventList, GENERATED_BY_DEBTOR, receipt));
}
@Test
void mapTemplateSuccessRequestByDebtorTrueWithoutPayerAndUserFiscalCode() {
- BizEvent event = BizEvent.builder()
+ List bizEventList = Collections.singletonList(BizEvent.builder()
.id(BIZ_EVENT_ID)
.paymentInfo(PaymentInfo.builder()
.IUR(IUR)
@@ -1362,12 +1362,10 @@ void mapTemplateSuccessRequestByDebtorTrueWithoutPayerAndUserFiscalCode() {
)
.build()
)
- .build();
+ .build());
AtomicReference atomicReference = new AtomicReference<>();
- EventData eventData = EventData.builder().cart(Collections.singletonList(
- CartItem.builder().subject(REMITTANCE_INFORMATION).build())).build();
- assertDoesNotThrow(() -> atomicReference.set(buildTemplateService.buildTemplate(
- event, GENERATED_BY_DEBTOR, Receipt.builder().eventData(eventData).build())));
+ Receipt receipt = Receipt.builder().eventId(BIZ_EVENT_ID).eventData(EventData.builder().amount(FORMATTED_GRAND_TOTAL).cart(List.of(CartItem.builder().subject(REMITTANCE_INFORMATION).build())).build()).build();
+ assertDoesNotThrow(() -> atomicReference.set(buildTemplateService.buildTemplate(bizEventList, GENERATED_BY_DEBTOR, receipt)));
ReceiptPDFTemplate receiptPDFTemplate = atomicReference.get();
assertTrue(receiptPDFTemplate.getTransaction().isRequestedByDebtor());
@@ -1375,7 +1373,7 @@ void mapTemplateSuccessRequestByDebtorTrueWithoutPayerAndUserFiscalCode() {
@Test
void mapTemplateSuccessRequestByDebtorTrueWithPayerFiscalCodeDifferent() {
- BizEvent event = BizEvent.builder()
+ List bizEventList = Collections.singletonList(BizEvent.builder()
.id(BIZ_EVENT_ID)
.paymentInfo(PaymentInfo.builder()
.IUR(IUR)
@@ -1406,12 +1404,10 @@ void mapTemplateSuccessRequestByDebtorTrueWithPayerFiscalCodeDifferent() {
)
.build()
)
- .build();
+ .build());
AtomicReference atomicReference = new AtomicReference<>();
- EventData eventData = EventData.builder().cart(Collections.singletonList(
- CartItem.builder().subject(REMITTANCE_INFORMATION).build())).build();
- assertDoesNotThrow(() -> atomicReference.set(buildTemplateService.buildTemplate(
- event, GENERATED_BY_DEBTOR, Receipt.builder().eventData(eventData).build())));
+ Receipt receipt = Receipt.builder().eventId(BIZ_EVENT_ID).eventData(EventData.builder().amount(FORMATTED_GRAND_TOTAL).cart(List.of(CartItem.builder().subject(REMITTANCE_INFORMATION).build())).build()).build();
+ assertDoesNotThrow(() -> atomicReference.set(buildTemplateService.buildTemplate(bizEventList, GENERATED_BY_DEBTOR, receipt)));
ReceiptPDFTemplate receiptPDFTemplate = atomicReference.get();
assertTrue(receiptPDFTemplate.getTransaction().isRequestedByDebtor());
@@ -1419,7 +1415,7 @@ void mapTemplateSuccessRequestByDebtorTrueWithPayerFiscalCodeDifferent() {
@Test
void mapTemplateSuccessRequestByDebtorTrueWithUserFiscalCodeDifferent() {
- BizEvent event = BizEvent.builder()
+ List bizEventList = Collections.singletonList(BizEvent.builder()
.id(BIZ_EVENT_ID)
.paymentInfo(PaymentInfo.builder()
.IUR(IUR)
@@ -1448,12 +1444,10 @@ void mapTemplateSuccessRequestByDebtorTrueWithUserFiscalCodeDifferent() {
.user(User.builder().fiscalCode(PAYER_VALID_CF).build())
.build()
)
- .build();
+ .build());
AtomicReference atomicReference = new AtomicReference<>();
- EventData eventData = EventData.builder().cart(Collections.singletonList(
- CartItem.builder().subject(REMITTANCE_INFORMATION).build())).build();
- assertDoesNotThrow(() -> atomicReference.set(buildTemplateService.buildTemplate(event,
- GENERATED_BY_DEBTOR, Receipt.builder().eventData(eventData).build())));
+ Receipt receipt = Receipt.builder().eventId(BIZ_EVENT_ID).eventData(EventData.builder().amount(FORMATTED_GRAND_TOTAL).cart(List.of(CartItem.builder().subject(REMITTANCE_INFORMATION).build())).build()).build();
+ assertDoesNotThrow(() -> atomicReference.set(buildTemplateService.buildTemplate(bizEventList, GENERATED_BY_DEBTOR, receipt)));
ReceiptPDFTemplate receiptPDFTemplate = atomicReference.get();
assertTrue(receiptPDFTemplate.getTransaction().isRequestedByDebtor());
@@ -1461,7 +1455,7 @@ void mapTemplateSuccessRequestByDebtorTrueWithUserFiscalCodeDifferent() {
@Test
void mapTemplateSuccessRequestByDebtorFalseWithPayerAndUserFiscalCodeEqual() {
- BizEvent event = BizEvent.builder()
+ List bizEventList = Collections.singletonList(BizEvent.builder()
.id(BIZ_EVENT_ID)
.paymentInfo(PaymentInfo.builder()
.IUR(IUR)
@@ -1494,12 +1488,10 @@ void mapTemplateSuccessRequestByDebtorFalseWithPayerAndUserFiscalCodeEqual() {
.user(User.builder().fiscalCode(DEBTOR_VALID_CF).build())
.build()
)
- .build();
+ .build());
AtomicReference atomicReference = new AtomicReference<>();
- EventData eventData = EventData.builder().cart(Collections.singletonList(
- CartItem.builder().subject(REMITTANCE_INFORMATION).build())).build();
- assertDoesNotThrow(() -> atomicReference.set(buildTemplateService.buildTemplate(
- event, GENERATED_BY_DEBTOR, Receipt.builder().eventData(eventData).build())));
+ Receipt receipt = Receipt.builder().eventId(BIZ_EVENT_ID).eventData(EventData.builder().amount(FORMATTED_GRAND_TOTAL).cart(List.of(CartItem.builder().subject(REMITTANCE_INFORMATION).build())).build()).build();
+ assertDoesNotThrow(() -> atomicReference.set(buildTemplateService.buildTemplate(bizEventList, GENERATED_BY_DEBTOR, receipt)));
ReceiptPDFTemplate receiptPDFTemplate = atomicReference.get();
assertFalse(receiptPDFTemplate.getTransaction().isRequestedByDebtor());
@@ -1507,7 +1499,7 @@ void mapTemplateSuccessRequestByDebtorFalseWithPayerAndUserFiscalCodeEqual() {
@Test
void mapTemplateSuccessRequestByDebtorFalseWhenGeneratedByPayer() {
- BizEvent event = BizEvent.builder()
+ List bizEventList = Collections.singletonList(BizEvent.builder()
.id(BIZ_EVENT_ID)
.paymentInfo(PaymentInfo.builder()
.IUR(IUR)
@@ -1539,12 +1531,10 @@ void mapTemplateSuccessRequestByDebtorFalseWhenGeneratedByPayer() {
)
.build()
)
- .build();
+ .build());
AtomicReference atomicReference = new AtomicReference<>();
- EventData eventData = EventData.builder().cart(Collections.singletonList(
- CartItem.builder().subject(REMITTANCE_INFORMATION).build())).build();
- assertDoesNotThrow(() -> atomicReference.set(buildTemplateService.buildTemplate(event, GENERATED_BY_PAYER,
- Receipt.builder().eventData(eventData).build())));
+ Receipt receipt = Receipt.builder().eventId(BIZ_EVENT_ID).eventData(EventData.builder().amount(FORMATTED_GRAND_TOTAL).cart(List.of(CartItem.builder().subject(REMITTANCE_INFORMATION).build())).build()).build();
+ assertDoesNotThrow(() -> atomicReference.set(buildTemplateService.buildTemplate(bizEventList, GENERATED_BY_PAYER, receipt)));
ReceiptPDFTemplate receiptPDFTemplate = atomicReference.get();
assertFalse(receiptPDFTemplate.getTransaction().isRequestedByDebtor());
@@ -1552,7 +1542,7 @@ void mapTemplateSuccessRequestByDebtorFalseWhenGeneratedByPayer() {
@Test
void mapTemplateSuccessWithUserNameAndSurname() {
- BizEvent event = BizEvent.builder()
+ List bizEventList = Collections.singletonList(BizEvent.builder()
.id(BIZ_EVENT_ID)
.paymentInfo(PaymentInfo.builder()
.IUR(IUR)
@@ -1587,12 +1577,10 @@ void mapTemplateSuccessWithUserNameAndSurname() {
.build())
.build()
)
- .build();
+ .build());
AtomicReference atomicReference = new AtomicReference<>();
- EventData eventData = EventData.builder().cart(Collections.singletonList(
- CartItem.builder().subject(REMITTANCE_INFORMATION).build())).build();
- assertDoesNotThrow(() -> atomicReference.set(buildTemplateService.buildTemplate
- (event, GENERATED_BY_PAYER, Receipt.builder().eventData(eventData).build())));
+ Receipt receipt = Receipt.builder().eventId(BIZ_EVENT_ID).eventData(EventData.builder().amount(FORMATTED_GRAND_TOTAL).cart(List.of(CartItem.builder().subject(REMITTANCE_INFORMATION).build())).build()).build();
+ assertDoesNotThrow(() -> atomicReference.set(buildTemplateService.buildTemplate(bizEventList, GENERATED_BY_PAYER, receipt)));
ReceiptPDFTemplate receiptPDFTemplate = atomicReference.get();
assertEquals(USER_FORMATTED_FULL_NAME, receiptPDFTemplate.getUser().getData().getFullName());
@@ -1600,7 +1588,7 @@ void mapTemplateSuccessWithUserNameAndSurname() {
@Test
void mapTemplateSuccessWithUserTaxCodeFromTransaction() {
- BizEvent event = BizEvent.builder()
+ List bizEventList = Collections.singletonList(BizEvent.builder()
.id(BIZ_EVENT_ID)
.paymentInfo(PaymentInfo.builder()
.IUR(IUR)
@@ -1636,12 +1624,10 @@ void mapTemplateSuccessWithUserTaxCodeFromTransaction() {
.build())
.build()
)
- .build();
+ .build());
AtomicReference atomicReference = new AtomicReference<>();
- EventData eventData = EventData.builder().cart(Collections.singletonList(
- CartItem.builder().subject(REMITTANCE_INFORMATION).build())).build();
- assertDoesNotThrow(() -> atomicReference.set(buildTemplateService.buildTemplate(
- event, GENERATED_BY_PAYER, Receipt.builder().eventData(eventData).build())));
+ Receipt receipt = Receipt.builder().eventId(BIZ_EVENT_ID).eventData(EventData.builder().cart(List.of(CartItem.builder().subject(REMITTANCE_INFORMATION).build())).amount(FORMATTED_GRAND_TOTAL).build()).build();
+ assertDoesNotThrow(() -> atomicReference.set(buildTemplateService.buildTemplate(bizEventList, GENERATED_BY_PAYER, receipt)));
ReceiptPDFTemplate receiptPDFTemplate = atomicReference.get();
assertEquals(USER_TAX_CODE, receiptPDFTemplate.getUser().getData().getTaxCode());
@@ -1649,56 +1635,56 @@ void mapTemplateSuccessWithUserTaxCodeFromTransaction() {
@Test
void mapTemplateNoServiceCustomerIdError() {
- BizEvent event = new BizEvent();
- TemplateDataMappingException e = assertThrows(TemplateDataMappingException.class, () -> buildTemplateService.buildTemplate(event, GENERATED_BY_PAYER, Receipt.builder().build()));
+ List bizEventList = Collections.singletonList(new BizEvent());
+ TemplateDataMappingException e = assertThrows(TemplateDataMappingException.class, () -> buildTemplateService.buildTemplate(bizEventList, GENERATED_BY_PAYER, Receipt.builder().build()));
assertEquals(ReasonErrorCode.ERROR_TEMPLATE_PDF.getCode(), e.getStatusCode());
- assertEquals(String.format(TemplateDataField.ERROR_MAPPING_MESSAGE, TemplateDataField.SERVICE_CUSTOMER_ID), e.getMessage());
+ assertEquals(String.format(TemplateDataField.ERROR_MAPPING_MESSAGE, RECEIPT, TemplateDataField.SERVICE_CUSTOMER_ID, RECEIPT, null), e.getMessage());
}
@Test
void mapTemplateNoTransactionTimestampError() {
- BizEvent event = BizEvent.builder().id(BIZ_EVENT_ID).paymentInfo(PaymentInfo.builder().IUR(IUR).build()).build();
- TemplateDataMappingException e = assertThrows(TemplateDataMappingException.class, () -> buildTemplateService.buildTemplate(event, GENERATED_BY_PAYER, Receipt.builder().build()));
+ List bizEventList = Collections.singletonList(BizEvent.builder().id(BIZ_EVENT_ID).paymentInfo(PaymentInfo.builder().IUR(IUR).build()).build());
+ TemplateDataMappingException e = assertThrows(TemplateDataMappingException.class, () -> buildTemplateService.buildTemplate(bizEventList, GENERATED_BY_PAYER, Receipt.builder().eventId(BIZ_EVENT_ID).build()));
assertEquals(ReasonErrorCode.ERROR_TEMPLATE_PDF.getCode(), e.getStatusCode());
- assertEquals(String.format(TemplateDataField.ERROR_MAPPING_MESSAGE, TemplateDataField.TRANSACTION_TIMESTAMP), e.getMessage());
+ assertEquals(String.format(TemplateDataField.ERROR_MAPPING_MESSAGE, BIZ_EVENT, TemplateDataField.TRANSACTION_TIMESTAMP, BIZ_EVENT, BIZ_EVENT_ID), e.getMessage());
}
@Test
void mapTemplateNoTransactionAmountError() {
- BizEvent event = BizEvent.builder()
+ List bizEventList = Collections.singletonList(BizEvent.builder()
.id(BIZ_EVENT_ID)
.paymentInfo(PaymentInfo.builder()
.IUR(IUR)
.paymentDateTime(DATE_TIME_TIMESTAMP_MILLISECONDS_DST_WINTER)
.build())
- .build();
- TemplateDataMappingException e = assertThrows(TemplateDataMappingException.class, () -> buildTemplateService.buildTemplate(event, GENERATED_BY_PAYER, Receipt.builder().build()));
+ .build());
+ TemplateDataMappingException e = assertThrows(TemplateDataMappingException.class, () -> buildTemplateService.buildTemplate(bizEventList, GENERATED_BY_PAYER, Receipt.builder().id(RECEIPT_ID).eventId(BIZ_EVENT_ID).build()));
assertEquals(ReasonErrorCode.ERROR_TEMPLATE_PDF.getCode(), e.getStatusCode());
- assertEquals(String.format(TemplateDataField.ERROR_MAPPING_MESSAGE, TemplateDataField.TRANSACTION_AMOUNT), e.getMessage());
+ assertEquals(String.format(TemplateDataField.ERROR_MAPPING_MESSAGE, RECEIPT,TemplateDataField.TRANSACTION_AMOUNT, RECEIPT,RECEIPT_ID), e.getMessage());
}
@Test
void mapTemplateNoPspError() {
- BizEvent event = BizEvent.builder()
+ List bizEventList = Collections.singletonList(BizEvent.builder()
.id(BIZ_EVENT_ID)
.paymentInfo(PaymentInfo.builder()
.IUR(IUR)
.paymentDateTime(DATE_TIME_TIMESTAMP_MILLISECONDS_DST_WINTER)
.amount(AMOUNT_WITHOUT_CENTS)
.build())
- .build();
- TemplateDataMappingException e = assertThrows(TemplateDataMappingException.class, () -> buildTemplateService.buildTemplate(event, GENERATED_BY_PAYER, Receipt.builder().build()));
+ .build());
+ TemplateDataMappingException e = assertThrows(TemplateDataMappingException.class, () -> buildTemplateService.buildTemplate(bizEventList, GENERATED_BY_PAYER, Receipt.builder().eventId(BIZ_EVENT_ID).eventData(EventData.builder().amount(FORMATTED_GRAND_TOTAL).build()).build()));
assertEquals(ReasonErrorCode.ERROR_TEMPLATE_PDF.getCode(), e.getStatusCode());
- assertEquals(String.format(TemplateDataField.ERROR_MAPPING_MESSAGE, TemplateDataField.TRANSACTION_PSP), e.getMessage());
+ assertEquals(String.format(TemplateDataField.ERROR_MAPPING_MESSAGE, BIZ_EVENT,TemplateDataField.TRANSACTION_PSP, BIZ_EVENT,BIZ_EVENT_ID), e.getMessage());
}
@Test
void mapTemplateNoPspNameError() {
- BizEvent event = BizEvent.builder()
+ List bizEventList = Collections.singletonList(BizEvent.builder()
.id(BIZ_EVENT_ID)
.paymentInfo(PaymentInfo.builder()
.IUR(IUR)
@@ -1708,16 +1694,16 @@ void mapTemplateNoPspNameError() {
.psp(Psp.builder()
.idPsp("noName")
.build())
- .build();
- TemplateDataMappingException e = assertThrows(TemplateDataMappingException.class, () -> buildTemplateService.buildTemplate(event, GENERATED_BY_PAYER, Receipt.builder().build()));
+ .build());
+ TemplateDataMappingException e = assertThrows(TemplateDataMappingException.class, () -> buildTemplateService.buildTemplate(bizEventList, GENERATED_BY_PAYER, Receipt.builder().eventId(BIZ_EVENT_ID).eventData(EventData.builder().amount(FORMATTED_GRAND_TOTAL).build()).build()));
assertEquals(ReasonErrorCode.ERROR_TEMPLATE_PDF.getCode(), e.getStatusCode());
- assertEquals(String.format(TemplateDataField.ERROR_MAPPING_MESSAGE, TemplateDataField.TRANSACTION_PSP_NAME), e.getMessage());
+ assertEquals(String.format(TemplateDataField.ERROR_MAPPING_MESSAGE, BIZ_EVENT,TemplateDataField.TRANSACTION_PSP_NAME, BIZ_EVENT, BIZ_EVENT_ID), e.getMessage());
}
@Test
void mapTemplateNoPspCompanyNameError() {
- BizEvent event = BizEvent.builder()
+ List bizEventList = Collections.singletonList(BizEvent.builder()
.id(BIZ_EVENT_ID)
.paymentInfo(PaymentInfo.builder()
.IUR(IUR)
@@ -1728,16 +1714,16 @@ void mapTemplateNoPspCompanyNameError() {
.idPsp("noCompanyName")
.psp(PSP_NAME)
.build())
- .build();
- TemplateDataMappingException e = assertThrows(TemplateDataMappingException.class, () -> buildTemplateService.buildTemplate(event, GENERATED_BY_PAYER, Receipt.builder().build()));
+ .build());
+ TemplateDataMappingException e = assertThrows(TemplateDataMappingException.class, () -> buildTemplateService.buildTemplate(bizEventList, GENERATED_BY_PAYER, Receipt.builder().id(RECEIPT_ID).eventId(BIZ_EVENT_ID).eventData(EventData.builder().amount(FORMATTED_GRAND_TOTAL).build()).build()));
assertEquals(ReasonErrorCode.ERROR_TEMPLATE_PDF.getCode(), e.getStatusCode());
- assertEquals(String.format(TemplateDataField.ERROR_MAPPING_MESSAGE, TemplateDataField.TRANSACTION_PSP_COMPANY_NAME), e.getMessage());
+ assertEquals(String.format(TemplateDataField.ERROR_MAPPING_MESSAGE, BIZ_EVENT,TemplateDataField.TRANSACTION_PSP_COMPANY_NAME, BIZ_EVENT,BIZ_EVENT_ID), e.getMessage());
}
@Test
void mapTemplateNoPspAddressError() {
- BizEvent event = BizEvent.builder()
+ List bizEventList = Collections.singletonList(BizEvent.builder()
.id(BIZ_EVENT_ID)
.paymentInfo(PaymentInfo.builder()
.IUR(IUR)
@@ -1748,16 +1734,18 @@ void mapTemplateNoPspAddressError() {
.idPsp("noAddress")
.psp(PSP_NAME)
.build())
- .build();
- TemplateDataMappingException e = assertThrows(TemplateDataMappingException.class, () -> buildTemplateService.buildTemplate(event, GENERATED_BY_PAYER, Receipt.builder().build()));
+ .build());
+ TemplateDataMappingException e = assertThrows(TemplateDataMappingException.class, () -> buildTemplateService.buildTemplate(bizEventList, GENERATED_BY_PAYER, Receipt.builder().id(RECEIPT_ID).eventId(BIZ_EVENT_ID).eventData(EventData.builder().amount(FORMATTED_GRAND_TOTAL).build()).build()));
assertEquals(ReasonErrorCode.ERROR_TEMPLATE_PDF.getCode(), e.getStatusCode());
- assertEquals(String.format(TemplateDataField.ERROR_MAPPING_MESSAGE, TemplateDataField.TRANSACTION_PSP_ADDRESS), e.getMessage());
+ assertEquals(String.format(TemplateDataField.ERROR_MAPPING_MESSAGE,
+
+ BIZ_EVENT,TemplateDataField.TRANSACTION_PSP_ADDRESS, BIZ_EVENT, BIZ_EVENT_ID), e.getMessage());
}
@Test
void mapTemplateNoPspCityError() {
- BizEvent event = BizEvent.builder()
+ List bizEventList = Collections.singletonList(BizEvent.builder()
.id(BIZ_EVENT_ID)
.paymentInfo(PaymentInfo.builder()
.IUR(IUR)
@@ -1768,16 +1756,16 @@ void mapTemplateNoPspCityError() {
.idPsp("noCity")
.psp(PSP_NAME)
.build())
- .build();
- TemplateDataMappingException e = assertThrows(TemplateDataMappingException.class, () -> buildTemplateService.buildTemplate(event, GENERATED_BY_PAYER, Receipt.builder().build()));
+ .build());
+ TemplateDataMappingException e = assertThrows(TemplateDataMappingException.class, () -> buildTemplateService.buildTemplate(bizEventList, GENERATED_BY_PAYER, Receipt.builder().id(RECEIPT_ID).eventId(BIZ_EVENT_ID).eventData(EventData.builder().amount(FORMATTED_GRAND_TOTAL).build()).build()));
assertEquals(ReasonErrorCode.ERROR_TEMPLATE_PDF.getCode(), e.getStatusCode());
- assertEquals(String.format(TemplateDataField.ERROR_MAPPING_MESSAGE, TemplateDataField.TRANSACTION_PSP_CITY), e.getMessage());
+ assertEquals(String.format(TemplateDataField.ERROR_MAPPING_MESSAGE, BIZ_EVENT,TemplateDataField.TRANSACTION_PSP_CITY, BIZ_EVENT, BIZ_EVENT_ID ), e.getMessage());
}
@Test
void mapTemplateNoPspProvinceError() {
- BizEvent event = BizEvent.builder()
+ List bizEventList = Collections.singletonList(BizEvent.builder()
.id(BIZ_EVENT_ID)
.paymentInfo(PaymentInfo.builder()
.IUR(IUR)
@@ -1788,16 +1776,16 @@ void mapTemplateNoPspProvinceError() {
.idPsp("noProvince")
.psp(PSP_NAME)
.build())
- .build();
- TemplateDataMappingException e = assertThrows(TemplateDataMappingException.class, () -> buildTemplateService.buildTemplate(event, GENERATED_BY_PAYER, Receipt.builder().build()));
+ .build());
+ TemplateDataMappingException e = assertThrows(TemplateDataMappingException.class, () -> buildTemplateService.buildTemplate(bizEventList, GENERATED_BY_PAYER, Receipt.builder().eventId(BIZ_EVENT_ID).eventData(EventData.builder().amount(FORMATTED_GRAND_TOTAL).build()).build()));
assertEquals(ReasonErrorCode.ERROR_TEMPLATE_PDF.getCode(), e.getStatusCode());
- assertEquals(String.format(TemplateDataField.ERROR_MAPPING_MESSAGE, TemplateDataField.TRANSACTION_PSP_PROVINCE), e.getMessage());
+ assertEquals(String.format(TemplateDataField.ERROR_MAPPING_MESSAGE, BIZ_EVENT,TemplateDataField.TRANSACTION_PSP_PROVINCE, BIZ_EVENT,BIZ_EVENT_ID), e.getMessage());
}
@Test
void mapTemplateNoPspBuildingNumberError() {
- BizEvent event = BizEvent.builder()
+ List bizEventList = Collections.singletonList(BizEvent.builder()
.id(BIZ_EVENT_ID)
.paymentInfo(PaymentInfo.builder()
.IUR(IUR)
@@ -1808,16 +1796,16 @@ void mapTemplateNoPspBuildingNumberError() {
.idPsp("noBuildingNumber")
.psp(PSP_NAME)
.build())
- .build();
- TemplateDataMappingException e = assertThrows(TemplateDataMappingException.class, () -> buildTemplateService.buildTemplate(event, GENERATED_BY_PAYER, Receipt.builder().build()));
+ .build());
+ TemplateDataMappingException e = assertThrows(TemplateDataMappingException.class, () -> buildTemplateService.buildTemplate(bizEventList, GENERATED_BY_PAYER, Receipt.builder().id(RECEIPT_ID).eventId(BIZ_EVENT_ID).eventData(EventData.builder().amount(FORMATTED_GRAND_TOTAL).build()).build()));
assertEquals(ReasonErrorCode.ERROR_TEMPLATE_PDF.getCode(), e.getStatusCode());
- assertEquals(String.format(TemplateDataField.ERROR_MAPPING_MESSAGE, TemplateDataField.TRANSACTION_PSP_BUILDING_NUMBER), e.getMessage());
+ assertEquals(String.format(TemplateDataField.ERROR_MAPPING_MESSAGE, BIZ_EVENT,TemplateDataField.TRANSACTION_PSP_BUILDING_NUMBER, BIZ_EVENT, BIZ_EVENT_ID), e.getMessage());
}
@Test
void mapTemplateNoPspPostalCodeError() {
- BizEvent event = BizEvent.builder()
+ List bizEventList = Collections.singletonList(BizEvent.builder()
.id(BIZ_EVENT_ID)
.paymentInfo(PaymentInfo.builder()
.IUR(IUR)
@@ -1828,16 +1816,16 @@ void mapTemplateNoPspPostalCodeError() {
.idPsp("noPostalCode")
.psp(PSP_NAME)
.build())
- .build();
- TemplateDataMappingException e = assertThrows(TemplateDataMappingException.class, () -> buildTemplateService.buildTemplate(event, GENERATED_BY_PAYER, Receipt.builder().build()));
+ .build());
+ TemplateDataMappingException e = assertThrows(TemplateDataMappingException.class, () -> buildTemplateService.buildTemplate(bizEventList, GENERATED_BY_PAYER, Receipt.builder().eventId(BIZ_EVENT_ID).eventData(EventData.builder().amount(FORMATTED_GRAND_TOTAL).build()).build()));
assertEquals(ReasonErrorCode.ERROR_TEMPLATE_PDF.getCode(), e.getStatusCode());
- assertEquals(String.format(TemplateDataField.ERROR_MAPPING_MESSAGE, TemplateDataField.TRANSACTION_PSP_POSTAL_CODE), e.getMessage());
+ assertEquals(String.format(TemplateDataField.ERROR_MAPPING_MESSAGE, BIZ_EVENT,TemplateDataField.TRANSACTION_PSP_POSTAL_CODE, BIZ_EVENT,BIZ_EVENT_ID), e.getMessage());
}
@Test
void mapTemplateNoPspLogoError() {
- BizEvent event = BizEvent.builder()
+ List bizEventList = Collections.singletonList(BizEvent.builder()
.id(BIZ_EVENT_ID)
.paymentInfo(PaymentInfo.builder()
.IUR(IUR)
@@ -1853,16 +1841,16 @@ void mapTemplateNoPspLogoError() {
.fee(FEE_LONG)
.build())
.build())
- .build();
- TemplateDataMappingException e = assertThrows(TemplateDataMappingException.class, () -> buildTemplateService.buildTemplate(event, GENERATED_BY_PAYER, Receipt.builder().build()));
+ .build());
+ TemplateDataMappingException e = assertThrows(TemplateDataMappingException.class, () -> buildTemplateService.buildTemplate(bizEventList, GENERATED_BY_PAYER, Receipt.builder().id(RECEIPT_ID).eventId(BIZ_EVENT_ID).eventData(EventData.builder().amount(FORMATTED_GRAND_TOTAL).build()).build()));
assertEquals(ReasonErrorCode.ERROR_TEMPLATE_PDF.getCode(), e.getStatusCode());
- assertEquals(String.format(TemplateDataField.ERROR_MAPPING_MESSAGE, TemplateDataField.TRANSACTION_PSP_LOGO), e.getMessage());
+ assertEquals(String.format(TemplateDataField.ERROR_MAPPING_MESSAGE, BIZ_EVENT, TemplateDataField.TRANSACTION_PSP_LOGO, BIZ_EVENT,BIZ_EVENT_ID), e.getMessage());
}
@Test
void mapTemplateNoRrnError() {
- BizEvent event = BizEvent.builder()
+ List bizEventList = Collections.singletonList(BizEvent.builder()
.id(BIZ_EVENT_ID)
.paymentInfo(PaymentInfo.builder()
.paymentDateTime(DATE_TIME_TIMESTAMP_MILLISECONDS_DST_WINTER)
@@ -1877,16 +1865,16 @@ void mapTemplateNoRrnError() {
.idTransaction(ID_TRANSACTION)
.build())
.build())
- .build();
- TemplateDataMappingException e = assertThrows(TemplateDataMappingException.class, () -> buildTemplateService.buildTemplate(event, GENERATED_BY_PAYER, Receipt.builder().build()));
+ .build());
+ TemplateDataMappingException e = assertThrows(TemplateDataMappingException.class, () -> buildTemplateService.buildTemplate(bizEventList, GENERATED_BY_PAYER, Receipt.builder().eventId(BIZ_EVENT_ID).eventData(EventData.builder().amount(FORMATTED_GRAND_TOTAL).build()).build()));
assertEquals(ReasonErrorCode.ERROR_TEMPLATE_PDF.getCode(), e.getStatusCode());
- assertEquals(String.format(TemplateDataField.ERROR_MAPPING_MESSAGE, TemplateDataField.TRANSACTION_RRN), e.getMessage());
+ assertEquals(String.format(TemplateDataField.ERROR_MAPPING_MESSAGE, BIZ_EVENT,TemplateDataField.TRANSACTION_RRN, BIZ_EVENT,BIZ_EVENT_ID), e.getMessage());
}
@Test
void mapTemplateNoUserDataFullNameError() {
- BizEvent event = BizEvent.builder()
+ List bizEventList = Collections.singletonList(BizEvent.builder()
.id(BIZ_EVENT_ID)
.paymentInfo(PaymentInfo.builder()
.IUR(IUR)
@@ -1897,16 +1885,16 @@ void mapTemplateNoUserDataFullNameError() {
.idPsp(ID_PSP)
.psp(PSP_NAME)
.build())
- .build();
- TemplateDataMappingException e = assertThrows(TemplateDataMappingException.class, () -> buildTemplateService.buildTemplate(event, GENERATED_BY_PAYER, Receipt.builder().build()));
+ .build());
+ TemplateDataMappingException e = assertThrows(TemplateDataMappingException.class, () -> buildTemplateService.buildTemplate(bizEventList, GENERATED_BY_PAYER, Receipt.builder().eventId(BIZ_EVENT_ID).eventData(EventData.builder().amount(FORMATTED_GRAND_TOTAL).build()).build()));
assertEquals(ReasonErrorCode.ERROR_TEMPLATE_PDF.getCode(), e.getStatusCode());
- assertEquals(String.format(TemplateDataField.ERROR_MAPPING_MESSAGE, TemplateDataField.USER_DATA_FULL_NAME), e.getMessage());
+ assertEquals(String.format(TemplateDataField.ERROR_MAPPING_MESSAGE, BIZ_EVENT,TemplateDataField.USER_DATA_FULL_NAME, BIZ_EVENT,BIZ_EVENT_ID), e.getMessage());
}
@Test
void mapTemplateNoUserDataTaxCodeError() {
- BizEvent event = BizEvent.builder()
+ List bizEventList = Collections.singletonList(BizEvent.builder()
.id(BIZ_EVENT_ID)
.paymentInfo(PaymentInfo.builder()
.IUR(IUR)
@@ -1920,16 +1908,16 @@ void mapTemplateNoUserDataTaxCodeError() {
.payer(Payer.builder()
.fullName(PAYER_FULL_NAME)
.build())
- .build();
- TemplateDataMappingException e = assertThrows(TemplateDataMappingException.class, () -> buildTemplateService.buildTemplate(event, GENERATED_BY_PAYER, Receipt.builder().build()));
+ .build());
+ TemplateDataMappingException e = assertThrows(TemplateDataMappingException.class, () -> buildTemplateService.buildTemplate(bizEventList, GENERATED_BY_PAYER, Receipt.builder().eventId(BIZ_EVENT_ID).eventData(EventData.builder().amount(FORMATTED_GRAND_TOTAL).build()).build()));
assertEquals(ReasonErrorCode.ERROR_TEMPLATE_PDF.getCode(), e.getStatusCode());
- assertEquals(String.format(TemplateDataField.ERROR_MAPPING_MESSAGE, TemplateDataField.USER_DATA_TAX_CODE), e.getMessage());
+ assertEquals(String.format(TemplateDataField.ERROR_MAPPING_MESSAGE, BIZ_EVENT,TemplateDataField.USER_DATA_TAX_CODE, BIZ_EVENT,BIZ_EVENT_ID), e.getMessage());
}
@Test
void mapTemplateNoCartItemRefNumberTypeError() {
- BizEvent event = BizEvent.builder()
+ List bizEventList = Collections.singletonList(BizEvent.builder()
.id(BIZ_EVENT_ID)
.paymentInfo(PaymentInfo.builder()
.IUR(IUR)
@@ -1944,16 +1932,16 @@ void mapTemplateNoCartItemRefNumberTypeError() {
.fullName(PAYER_FULL_NAME)
.entityUniqueIdentifierValue(PAYER_VALID_CF)
.build())
- .build();
- TemplateDataMappingException e = assertThrows(TemplateDataMappingException.class, () -> buildTemplateService.buildTemplate(event, GENERATED_BY_PAYER, Receipt.builder().build()));
+ .build());
+ TemplateDataMappingException e = assertThrows(TemplateDataMappingException.class, () -> buildTemplateService.buildTemplate(bizEventList, GENERATED_BY_PAYER, Receipt.builder().eventId(BIZ_EVENT_ID).eventData(EventData.builder().amount(FORMATTED_GRAND_TOTAL).build()).build()));
assertEquals(ReasonErrorCode.ERROR_TEMPLATE_PDF.getCode(), e.getStatusCode());
- assertEquals(String.format(TemplateDataField.ERROR_MAPPING_MESSAGE, TemplateDataField.CART_ITEM_REF_NUMBER_TYPE), e.getMessage());
+ assertEquals(String.format(TemplateDataField.ERROR_MAPPING_MESSAGE, BIZ_EVENT,TemplateDataField.CART_ITEM_REF_NUMBER_TYPE, BIZ_EVENT, BIZ_EVENT_ID), e.getMessage());
}
@Test
void mapTemplateNoCartItemRefNumberValueIUVError() {
- BizEvent event = BizEvent.builder()
+ List bizEventList = Collections.singletonList(BizEvent.builder()
.id(BIZ_EVENT_ID)
.paymentInfo(PaymentInfo.builder()
.IUR(IUR)
@@ -1971,16 +1959,16 @@ void mapTemplateNoCartItemRefNumberValueIUVError() {
.debtorPosition(DebtorPosition.builder()
.modelType(MODEL_TYPE_IUV_CODE)
.build())
- .build();
- TemplateDataMappingException e = assertThrows(TemplateDataMappingException.class, () -> buildTemplateService.buildTemplate(event, GENERATED_BY_PAYER, Receipt.builder().build()));
+ .build());
+ TemplateDataMappingException e = assertThrows(TemplateDataMappingException.class, () -> buildTemplateService.buildTemplate(bizEventList, GENERATED_BY_PAYER, Receipt.builder().id(RECEIPT_ID).eventId(BIZ_EVENT_ID).eventData(EventData.builder().amount(FORMATTED_GRAND_TOTAL).build()).build()));
assertEquals(ReasonErrorCode.ERROR_TEMPLATE_PDF.getCode(), e.getStatusCode());
- assertEquals(String.format(TemplateDataField.ERROR_MAPPING_MESSAGE, TemplateDataField.CART_ITEM_REF_NUMBER_VALUE), e.getMessage());
+ assertEquals(String.format(TemplateDataField.ERROR_MAPPING_MESSAGE, BIZ_EVENT,TemplateDataField.CART_ITEM_REF_NUMBER_VALUE, BIZ_EVENT, BIZ_EVENT_ID), e.getMessage());
}
@Test
void mapTemplateWrongModelTypeError() {
- BizEvent event = BizEvent.builder()
+ List bizEventList = Collections.singletonList(BizEvent.builder()
.id(BIZ_EVENT_ID)
.paymentInfo(PaymentInfo.builder()
.IUR(IUR)
@@ -1999,16 +1987,16 @@ void mapTemplateWrongModelTypeError() {
.iuv(IUV)
.modelType(MODEL_TYPE_NOTICE_CODE)
.build())
- .build();
- TemplateDataMappingException e = assertThrows(TemplateDataMappingException.class, () -> buildTemplateService.buildTemplate(event, GENERATED_BY_PAYER, Receipt.builder().build()));
+ .build());
+ TemplateDataMappingException e = assertThrows(TemplateDataMappingException.class, () -> buildTemplateService.buildTemplate(bizEventList, GENERATED_BY_PAYER, Receipt.builder().eventId(BIZ_EVENT_ID).eventData(EventData.builder().amount(FORMATTED_GRAND_TOTAL).build()).build()));
assertEquals(ReasonErrorCode.ERROR_TEMPLATE_PDF.getCode(), e.getStatusCode());
- assertEquals(String.format(TemplateDataField.ERROR_MAPPING_MESSAGE, TemplateDataField.CART_ITEM_REF_NUMBER_VALUE), e.getMessage());
+ assertEquals(String.format(TemplateDataField.ERROR_MAPPING_MESSAGE, BIZ_EVENT,TemplateDataField.CART_ITEM_REF_NUMBER_VALUE, BIZ_EVENT,BIZ_EVENT_ID), e.getMessage());
}
@Test
void mapTemplateNoCartItemDebtorTaxCodeValueError() {
- BizEvent event = BizEvent.builder()
+ List bizEventList = Collections.singletonList(BizEvent.builder()
.id(BIZ_EVENT_ID)
.paymentInfo(PaymentInfo.builder()
.IUR(IUR)
@@ -2027,17 +2015,17 @@ void mapTemplateNoCartItemDebtorTaxCodeValueError() {
.modelType(MODEL_TYPE_IUV_CODE)
.iuv(IUV)
.build())
- .build();
- TemplateDataMappingException e = assertThrows(TemplateDataMappingException.class, () -> buildTemplateService.buildTemplate(event, GENERATED_BY_PAYER,
- Receipt.builder().eventData(EventData.builder().debtorFiscalCode("DEBTOR_FC").build()).build()));
+ .build());
+ TemplateDataMappingException e = assertThrows(TemplateDataMappingException.class, () -> buildTemplateService.buildTemplate(bizEventList, GENERATED_BY_PAYER,
+ Receipt.builder().id(RECEIPT_ID).eventId(BIZ_EVENT_ID).eventData(EventData.builder().amount(FORMATTED_GRAND_TOTAL).debtorFiscalCode(DEBTOR_VALID_CF).build()).build()));
assertEquals(ReasonErrorCode.ERROR_TEMPLATE_PDF.getCode(), e.getStatusCode());
- assertEquals(String.format(TemplateDataField.ERROR_MAPPING_MESSAGE, TemplateDataField.CART_ITEM_DEBTOR_TAX_CODE), e.getMessage());
+ assertEquals(String.format(TemplateDataField.ERROR_MAPPING_MESSAGE, BIZ_EVENT,TemplateDataField.CART_ITEM_DEBTOR_TAX_CODE, BIZ_EVENT, BIZ_EVENT_ID), e.getMessage());
}
@Test
void mapTemplateNoCartItemPayeeTaxCodeValueError() {
- BizEvent event = BizEvent.builder()
+ List bizEventList = Collections.singletonList(BizEvent.builder()
.id(BIZ_EVENT_ID)
.paymentInfo(PaymentInfo.builder()
.IUR(IUR)
@@ -2059,17 +2047,17 @@ void mapTemplateNoCartItemPayeeTaxCodeValueError() {
.debtor(Debtor.builder()
.entityUniqueIdentifierValue(DEBTOR_VALID_CF)
.build())
- .build();
- TemplateDataMappingException e = assertThrows(TemplateDataMappingException.class, () -> buildTemplateService.buildTemplate(event, GENERATED_BY_PAYER,
- Receipt.builder().eventData(EventData.builder().debtorFiscalCode("DEBTOR_FC").build()).build()));
+ .build());
+ TemplateDataMappingException e = assertThrows(TemplateDataMappingException.class, () -> buildTemplateService.buildTemplate(bizEventList, GENERATED_BY_PAYER, Receipt.builder().id(RECEIPT_ID).eventId(BIZ_EVENT_ID).eventData(
+ EventData.builder().amount(FORMATTED_GRAND_TOTAL).debtorFiscalCode(DEBTOR_VALID_CF).build()).build()));
assertEquals(ReasonErrorCode.ERROR_TEMPLATE_PDF.getCode(), e.getStatusCode());
- assertEquals(String.format(TemplateDataField.ERROR_MAPPING_MESSAGE, TemplateDataField.CART_ITEM_PAYEE_TAX_CODE), e.getMessage());
+ assertEquals(String.format(TemplateDataField.ERROR_MAPPING_MESSAGE, BIZ_EVENT,TemplateDataField.CART_ITEM_PAYEE_TAX_CODE, BIZ_EVENT,BIZ_EVENT_ID), e.getMessage());
}
@Test
void mapTemplateNoCartItemAmountValueError() {
- BizEvent event = BizEvent.builder()
+ List bizEventList = Collections.singletonList(BizEvent.builder()
.id(BIZ_EVENT_ID)
.paymentInfo(PaymentInfo.builder()
.IUR(IUR)
@@ -2101,13 +2089,172 @@ void mapTemplateNoCartItemAmountValueError() {
)
.build()
)
- .build();
- EventData eventData = EventData.builder().cart(Collections.singletonList(
- CartItem.builder().subject(REMITTANCE_INFORMATION).build())).build();
+ .build());
+ Receipt receipt = Receipt.builder().id(RECEIPT_ID).eventId(BIZ_EVENT_ID).eventData(EventData.builder().amount(FORMATTED_GRAND_TOTAL).cart(List.of(CartItem.builder().subject(REMITTANCE_INFORMATION).build())).build()).build();
+ TemplateDataMappingException e = assertThrows(TemplateDataMappingException.class, () -> buildTemplateService.buildTemplate(bizEventList, GENERATED_BY_PAYER, receipt));
+
+ assertEquals(ReasonErrorCode.ERROR_TEMPLATE_PDF.getCode(), e.getStatusCode());
+ assertEquals(String.format(TemplateDataField.ERROR_MAPPING_MESSAGE, BIZ_EVENT,TemplateDataField.CART_ITEM_AMOUNT, BIZ_EVENT, BIZ_EVENT_ID), e.getMessage());
+ }
+
+ @Test
+ void mapTemplateNoCartItemSubjectError() {
+ List listOfBizEvents = Collections.singletonList(BizEvent.builder()
+ .id(BIZ_EVENT_ID)
+ .paymentInfo(PaymentInfo.builder()
+ .IUR(IUR)
+ .paymentDateTime(DATE_TIME_TIMESTAMP_MILLISECONDS_DST_WINTER)
+ .remittanceInformation(REMITTANCE_INFORMATION)
+ .build())
+ .psp(Psp.builder()
+ .idPsp(ID_PSP)
+ .psp(PSP_NAME)
+ .build())
+ .payer(Payer.builder()
+ .fullName(PAYER_FULL_NAME)
+ .entityUniqueIdentifierValue(PAYER_VALID_CF)
+ .build())
+ .debtorPosition(DebtorPosition.builder()
+ .modelType(MODEL_TYPE_IUV_CODE)
+ .iuv(IUV)
+ .build())
+ .debtor(Debtor.builder()
+ .entityUniqueIdentifierValue(DEBTOR_VALID_CF)
+ .build())
+ .creditor(Creditor.builder()
+ .companyName(COMPANY_NAME)
+ .idPA(ID_PA)
+ .build())
+ .transactionDetails(TransactionDetails.builder()
+ .transaction(Transaction.builder()
+ .grandTotal(GRAND_TOTAL_LONG).build()
+ )
+ .build()
+ )
+ .build());
TemplateDataMappingException e = assertThrows(TemplateDataMappingException.class, () ->
- buildTemplateService.buildTemplate(event, GENERATED_BY_PAYER, Receipt.builder().eventData(eventData).build()));
+ buildTemplateService.buildTemplate(listOfBizEvents, GENERATED_BY_PAYER, Receipt.builder().id(RECEIPT_ID).eventId(BIZ_EVENT_ID).eventData(
+ EventData.builder().amount(FORMATTED_GRAND_TOTAL).cart(Collections.singletonList(CartItem.builder().build()))
+ .debtorFiscalCode(DEBTOR_VALID_CF).build()).build()));
assertEquals(ReasonErrorCode.ERROR_TEMPLATE_PDF.getCode(), e.getStatusCode());
- assertEquals(String.format(TemplateDataField.ERROR_MAPPING_MESSAGE, TemplateDataField.CART_ITEM_AMOUNT), e.getMessage());
+ assertEquals(String.format(TemplateDataField.ERROR_MAPPING_MESSAGE, RECEIPT, TemplateDataField.CART_ITEM_SUBJECT, RECEIPT,RECEIPT_ID), e.getMessage());
+ }
+
+ @Test
+ void mapTemplateAllFieldsSuccessMultipleBizEvents() {
+ List bizEventList = new ArrayList<>();
+ List cartItemList = new ArrayList<>();
+ for (int i = 0; i < 5; i++) {
+ bizEventList.add(
+ BizEvent.builder()
+ .id(BIZ_EVENT_ID + i)
+ .idPaymentManager(BIZ_EVENT_ID)
+ .debtorPosition(DebtorPosition.builder()
+ .iuv(IUV+i)
+ .modelType(MODEL_TYPE_IUV_CODE)
+ .build())
+ .creditor(Creditor.builder()
+ .companyName(COMPANY_NAME)
+ .idPA(ID_PA)
+ .build())
+ .psp(Psp.builder()
+ .idPsp(ID_PSP)
+ .psp(PSP_NAME)
+ .build())
+ .debtor(Debtor.builder()
+ .fullName(DEBTOR_FULL_NAME)
+ .entityUniqueIdentifierValue(DEBTOR_VALID_CF)
+ .build())
+ .payer(Payer.builder().fullName(PAYER_FULL_NAME).entityUniqueIdentifierValue(PAYER_VALID_CF).build())
+ .paymentInfo(PaymentInfo.builder()
+ .paymentDateTime(DATE_TIME_TIMESTAMP_MILLISECONDS_DST_WINTER)
+ .paymentToken(PAYMENT_TOKEN)
+ .amount(AMOUNT_WITHOUT_CENTS)
+ .fee(FEE_WITH_SINGLE_DIGIT_CENTS)
+ .remittanceInformation(REMITTANCE_INFORMATION)
+ .IUR(IUR)
+ .build())
+ .transactionDetails(TransactionDetails.builder()
+ .wallet(WalletItem.builder()
+ .info(Info.builder().brand(BRAND).holder(HOLDER_FULL_NAME).build())
+ .onboardingChannel(PAGO_PA_CHANNEL_IO)
+ .build())
+ .transaction(Transaction.builder()
+ .idTransaction(ID_TRANSACTION)
+ .grandTotal(GRAND_TOTAL_LONG)
+ .amount(AMOUNT_LONG)
+ .fee(FEE_LONG)
+ .rrn(RRN)
+ .numAut(AUTH_CODE)
+ .creationDate(DATE_TIME_TIMESTAMP_ZONED_DST_WINTER)
+ .psp(TransactionPsp.builder()
+ .businessName(PSP_NAME)
+ .build())
+ .origin(PAGOPA_PA_CHANNEL_ID)
+ .build())
+ .build())
+ .eventStatus(BizEventStatusType.DONE)
+ .build()
+ );
+
+ cartItemList.add(
+ CartItem.builder().subject(REMITTANCE_INFORMATION + i).build()
+ );
+ }
+ Receipt receipt = Receipt.builder().eventId(String.valueOf(ID_TRANSACTION)).eventData(EventData.builder().amount(FORMATTED_GRAND_TOTAL).cart(cartItemList).build()).build();
+
+ AtomicReference atomicReference = new AtomicReference<>();
+ assertDoesNotThrow(() -> atomicReference.set(buildTemplateService.buildTemplate(bizEventList, GENERATED_BY_DEBTOR, receipt)));
+
+ ReceiptPDFTemplate receiptPdfTemplate = atomicReference.get();
+
+ assertNotNull(receiptPdfTemplate);
+ assertEquals(String.valueOf(ID_TRANSACTION), receiptPdfTemplate.getServiceCustomerId());
+
+ it.gov.pagopa.receipt.pdf.helpdesk.model.template.Transaction transaction = receiptPdfTemplate.getTransaction();
+ assertEquals(DATE_TIME_TIMESTAMP_FORMATTED_DST_WINTER, transaction.getTimestamp());
+ assertEquals(FORMATTED_GRAND_TOTAL, transaction.getAmount());
+ assertEquals(PSP_LOGO, transaction.getPsp().getLogo());
+ assertEquals(FORMATTED_FEE, transaction.getPsp().getFee().getAmount());
+ assertEquals(PSP_NAME, transaction.getPsp().getName());
+ assertEquals(PSP_CITY, transaction.getPsp().getCity());
+ assertEquals(PSP_COMPANY, transaction.getPsp().getCompanyName());
+ assertEquals(PSP_POSTAL_CODE, transaction.getPsp().getPostalCode());
+ assertEquals(PSP_ADDRESS, transaction.getPsp().getAddress());
+ assertEquals(PSP_BUILDING_NUMBER, transaction.getPsp().getBuildingNumber());
+ assertEquals(PSP_PROVINCE, transaction.getPsp().getProvince());
+ assertEquals(RRN, transaction.getRrn());
+ assertEquals(BRAND, transaction.getPaymentMethod().getName());
+ assertEquals(BRAND_ASSET_URL, transaction.getPaymentMethod().getLogo());
+ assertEquals(HOLDER_FULL_NAME, transaction.getPaymentMethod().getAccountHolder());
+ assertEquals(AUTH_CODE, transaction.getAuthCode());
+ assertEquals(GENERATED_BY_DEBTOR, transaction.isRequestedByDebtor());
+ assertTrue(transaction.isProcessedByPagoPA());
+
+ assertNull(receiptPdfTemplate.getUser());
+
+ it.gov.pagopa.receipt.pdf.helpdesk.model.template.Cart cart = receiptPdfTemplate.getCart();
+ String decurrenciedFormattedAmount = FORMATTED_AMOUNT.replace(".", "").replace(",", ".");
+ assertEquals(currencyFormat(String.valueOf(Double.parseDouble(decurrenciedFormattedAmount)*bizEventList.size())), cart.getAmountPartial());
+
+ for (int i = 0; i < bizEventList.size(); i++) {
+ assertEquals(FORMATTED_AMOUNT, cart.getItems().get(i).getAmount());
+ assertEquals(DEBTOR_FULL_NAME, cart.getItems().get(i).getDebtor().getFullName());
+ assertEquals(DEBTOR_VALID_CF, cart.getItems().get(i).getDebtor().getTaxCode());
+ assertEquals(REMITTANCE_INFORMATION+i, cart.getItems().get(i).getSubject());
+ assertEquals(COMPANY_NAME, cart.getItems().get(i).getPayee().getName());
+ assertEquals(ID_PA, cart.getItems().get(i).getPayee().getTaxCode());
+ assertEquals(MODEL_TYPE_IUV_TEXT, cart.getItems().get(i).getRefNumber().getType());
+ assertEquals(IUV+i, cart.getItems().get(i).getRefNumber().getValue());
+ }
+ }
+
+ private String currencyFormat(String value) {
+ BigDecimal valueToFormat = new BigDecimal(value);
+ NumberFormat numberFormat = NumberFormat.getInstance(Locale.ITALY);
+ numberFormat.setMaximumFractionDigits(2);
+ numberFormat.setMinimumFractionDigits(2);
+ return numberFormat.format(valueToFormat);
}
}
\ No newline at end of file
diff --git a/src/test/java/it/gov/pagopa/receipt/pdf/helpdesk/service/impl/GenerateReceiptPdfServiceImplTest.java b/src/test/java/it/gov/pagopa/receipt/pdf/helpdesk/service/impl/GenerateReceiptPdfServiceImplTest.java
index 9bb2ecb0..beaf685e 100644
--- a/src/test/java/it/gov/pagopa/receipt/pdf/helpdesk/service/impl/GenerateReceiptPdfServiceImplTest.java
+++ b/src/test/java/it/gov/pagopa/receipt/pdf/helpdesk/service/impl/GenerateReceiptPdfServiceImplTest.java
@@ -29,6 +29,7 @@
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
+import java.util.Collections;
import static it.gov.pagopa.receipt.pdf.helpdesk.service.impl.GenerateReceiptPdfServiceImpl.ALREADY_CREATED;
import static org.apache.http.HttpStatus.SC_OK;
@@ -99,7 +100,7 @@ void generateReceiptsPayerNullWithSuccess() throws Exception {
doReturn(new ReceiptPDFTemplate())
.when(buildTemplateServiceMock).buildTemplate(any(), anyBoolean(), any());
- PdfGeneration pdfGeneration = sut.generateReceipts(receiptOnly, bizEventOnly,Path.of("/tmp"));
+ PdfGeneration pdfGeneration = sut.generateReceipts(receiptOnly, Collections.singletonList(bizEventOnly),Path.of("/tmp"));
assertNotNull(pdfGeneration);
assertTrue(pdfGeneration.isGenerateOnlyDebtor());
@@ -127,7 +128,7 @@ void generateReceiptsSameDebtorPayerWithSuccess() throws Exception {
doReturn(new ReceiptPDFTemplate())
.when(buildTemplateServiceMock).buildTemplate(any(), anyBoolean(), any());
- PdfGeneration pdfGeneration = sut.generateReceipts(receiptOnly, bizEventOnly,Path.of("/tmp"));
+ PdfGeneration pdfGeneration = sut.generateReceipts(receiptOnly, Collections.singletonList(bizEventOnly),Path.of("/tmp"));
assertNotNull(pdfGeneration);
assertTrue(pdfGeneration.isGenerateOnlyDebtor());
@@ -157,7 +158,8 @@ void generateReceiptsDifferentDebtorPayerWithSuccess() throws Exception {
doReturn(new ReceiptPDFTemplate())
.when(buildTemplateServiceMock).buildTemplate(any(), anyBoolean(), any());
- PdfGeneration pdfGeneration = sut.generateReceipts(receiptOnly, bizEventOnly,Path.of("/tmp"));
+ PdfGeneration pdfGeneration = sut.generateReceipts(receiptOnly, Collections.singletonList(bizEventOnly),Path.of("/tmp"));
+
assertNotNull(pdfGeneration);
assertFalse(pdfGeneration.isGenerateOnlyDebtor());
@@ -187,7 +189,7 @@ void generateReceiptsPayerNullFailPDFEngineCallReturn500() throws Exception {
doReturn(new ReceiptPDFTemplate())
.when(buildTemplateServiceMock).buildTemplate(any(), anyBoolean(), any());
- PdfGeneration pdfGeneration = sut.generateReceipts(receiptOnly, bizEventOnly,Path.of("/tmp"));
+ PdfGeneration pdfGeneration = sut.generateReceipts(receiptOnly, Collections.singletonList(bizEventOnly),Path.of("/tmp"));
assertNotNull(pdfGeneration);
assertTrue(pdfGeneration.isGenerateOnlyDebtor());
@@ -211,7 +213,7 @@ void generateReceiptsPayerNullFailBuildTemplateData() throws Exception {
doThrow(new TemplateDataMappingException("error message", ReasonErrorCode.ERROR_TEMPLATE_PDF.getCode()))
.when(buildTemplateServiceMock).buildTemplate(any(), anyBoolean(), any());
- PdfGeneration pdfGeneration = sut.generateReceipts(receiptOnly, bizEventOnly,Path.of("/tmp"));
+ PdfGeneration pdfGeneration = sut.generateReceipts(receiptOnly, Collections.singletonList(bizEventOnly),Path.of("/tmp"));
assertNotNull(pdfGeneration);
assertTrue(pdfGeneration.isGenerateOnlyDebtor());
@@ -238,7 +240,7 @@ void generateReceiptsPayerNullFailSaveToBlobStorageThrowsException() throws Exce
doReturn(new ReceiptPDFTemplate())
.when(buildTemplateServiceMock).buildTemplate(any(), anyBoolean(), any());
- PdfGeneration pdfGeneration = sut.generateReceipts(receiptOnly, bizEventOnly,Path.of("/tmp"));
+ PdfGeneration pdfGeneration = sut.generateReceipts(receiptOnly, Collections.singletonList(bizEventOnly),Path.of("/tmp"));
assertNotNull(pdfGeneration);
assertTrue(pdfGeneration.isGenerateOnlyDebtor());
@@ -266,7 +268,7 @@ void generateReceiptsPayerNullFailSaveToBlobStorageReturn500() throws Exception
doReturn(new ReceiptPDFTemplate())
.when(buildTemplateServiceMock).buildTemplate(any(), anyBoolean(), any());
- PdfGeneration pdfGeneration = sut.generateReceipts(receiptOnly, bizEventOnly,Path.of("/tmp"));
+ PdfGeneration pdfGeneration = sut.generateReceipts(receiptOnly, Collections.singletonList(bizEventOnly),Path.of("/tmp"));
assertNotNull(pdfGeneration);
assertTrue(pdfGeneration.isGenerateOnlyDebtor());
diff --git a/src/test/java/it/gov/pagopa/receipt/pdf/helpdesk/utils/BizEventToReceiptUtilsTest.java b/src/test/java/it/gov/pagopa/receipt/pdf/helpdesk/utils/BizEventToReceiptUtilsTest.java
index 61d2c29f..51442181 100644
--- a/src/test/java/it/gov/pagopa/receipt/pdf/helpdesk/utils/BizEventToReceiptUtilsTest.java
+++ b/src/test/java/it/gov/pagopa/receipt/pdf/helpdesk/utils/BizEventToReceiptUtilsTest.java
@@ -2,6 +2,7 @@
import com.fasterxml.jackson.core.JsonProcessingException;
import com.microsoft.azure.functions.HttpStatus;
+import it.gov.pagopa.receipt.pdf.helpdesk.client.impl.BizEventCosmosClientImpl;
import it.gov.pagopa.receipt.pdf.helpdesk.client.impl.ReceiptCosmosClientImpl;
import it.gov.pagopa.receipt.pdf.helpdesk.client.impl.ReceiptQueueClientImpl;
import it.gov.pagopa.receipt.pdf.helpdesk.entity.event.*;
@@ -48,7 +49,8 @@ void createReceiptSuccessWithPaymentInfo() throws PDVTokenizerException, JsonPro
when(pdvTokenizerServiceMock.generateTokenForFiscalCodeWithRetry(DEBTOR_FISCAL_CODE)).thenReturn(TOKENIZED_DEBTOR_FISCAL_CODE);
when(pdvTokenizerServiceMock.generateTokenForFiscalCodeWithRetry(PAYER_FISCAL_CODE)).thenReturn(TOKENIZED_PAYER_FISCAL_CODE);
- BizEventToReceiptServiceImpl receiptService = new BizEventToReceiptServiceImpl(pdvTokenizerServiceMock, mock(ReceiptQueueClientImpl.class));
+ BizEventToReceiptServiceImpl receiptService = new BizEventToReceiptServiceImpl(
+ pdvTokenizerServiceMock, mock(ReceiptQueueClientImpl.class), mock(BizEventCosmosClientImpl.class), mock(ReceiptCosmosClientImpl.class));
Receipt receipt = BizEventToReceiptUtils.createReceipt(generateValidBizEvent(false,false), receiptService, logger);
@@ -64,7 +66,8 @@ void createReceiptSuccessWithoutPaymentInfoButWithTransferList() throws PDVToken
when(pdvTokenizerServiceMock.generateTokenForFiscalCodeWithRetry(DEBTOR_FISCAL_CODE)).thenReturn(TOKENIZED_DEBTOR_FISCAL_CODE);
when(pdvTokenizerServiceMock.generateTokenForFiscalCodeWithRetry(PAYER_FISCAL_CODE)).thenReturn(TOKENIZED_PAYER_FISCAL_CODE);
- BizEventToReceiptServiceImpl receiptService = new BizEventToReceiptServiceImpl(pdvTokenizerServiceMock, mock(ReceiptQueueClientImpl.class));
+ BizEventToReceiptServiceImpl receiptService = new BizEventToReceiptServiceImpl(
+ pdvTokenizerServiceMock, mock(ReceiptQueueClientImpl.class), mock(BizEventCosmosClientImpl.class), mock(ReceiptCosmosClientImpl.class));
Receipt receipt = BizEventToReceiptUtils.createReceipt(generateValidBizEvent(false,true), receiptService, logger);
@@ -80,7 +83,8 @@ void createReceiptSuccessWithoutRemittanceInformation() throws PDVTokenizerExcep
when(pdvTokenizerServiceMock.generateTokenForFiscalCodeWithRetry(DEBTOR_FISCAL_CODE)).thenReturn(TOKENIZED_DEBTOR_FISCAL_CODE);
when(pdvTokenizerServiceMock.generateTokenForFiscalCodeWithRetry(PAYER_FISCAL_CODE)).thenReturn(TOKENIZED_PAYER_FISCAL_CODE);
- BizEventToReceiptServiceImpl receiptService = new BizEventToReceiptServiceImpl(pdvTokenizerServiceMock, mock(ReceiptQueueClientImpl.class));
+ BizEventToReceiptServiceImpl receiptService = new BizEventToReceiptServiceImpl(
+ pdvTokenizerServiceMock, mock(ReceiptQueueClientImpl.class), mock(BizEventCosmosClientImpl.class), mock(ReceiptCosmosClientImpl.class));
Receipt receipt = BizEventToReceiptUtils.createReceipt(generateValidBizEvent(true,false), receiptService, logger);
@@ -95,7 +99,8 @@ void createReceiptSuccessWithoutRemittanceInformation() throws PDVTokenizerExcep
void createReceiptSuccessWithTokenizerFailed() throws PDVTokenizerException, JsonProcessingException {
when(pdvTokenizerServiceMock.generateTokenForFiscalCodeWithRetry(DEBTOR_FISCAL_CODE)).thenThrow(new PDVTokenizerException("exception", HttpStatus.I_AM_A_TEAPOT.value()));
- BizEventToReceiptServiceImpl receiptService = new BizEventToReceiptServiceImpl(pdvTokenizerServiceMock, mock(ReceiptQueueClientImpl.class));
+ BizEventToReceiptServiceImpl receiptService = new BizEventToReceiptServiceImpl(
+ pdvTokenizerServiceMock, mock(ReceiptQueueClientImpl.class), mock(BizEventCosmosClientImpl.class), mock(ReceiptCosmosClientImpl.class));
Receipt receipt = BizEventToReceiptUtils.createReceipt(generateValidBizEvent(false,false), receiptService, logger);