Skip to content

Commit 5af0091

Browse files
authored
Merge pull request #8 from Backbase/feature/CB-5400-add-code-samples-for-payments-add-custom-batch-type-document
CB-5400: Code samples for the "Add a custom batch type" community page.
2 parents dbdc791 + 571116f commit 5af0091

File tree

6 files changed

+296
-0
lines changed

6 files changed

+296
-0
lines changed
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
This project contains code samples documented in the following section in [Backbase Community](https://community.backbase.com/documentation/ServiceSDK/latest/index):
2+
3+
* [Add a custom batch type](https://community.backbase.com/documentation/DBS/latest/payments_add_custom_batch_type)
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
{
2+
"label": "Salary_Sep2019_high",
3+
"priority": "high",
4+
"own-account": "AT622643775968303743",
5+
"requested-execution-date": "25/09/2019",
6+
"batch-total-amount": "10950",
7+
"batch-payments-count": "2",
8+
"payments": [
9+
{
10+
"counterparty-name": "Lia Kyriake",
11+
"counterparty-account": "IT65C0300203280264373466638",
12+
"amount": "6100"
13+
},
14+
{
15+
"counterparty-name": "Samuel Claus",
16+
"counterparty-account": "LU890103769859624113",
17+
"amount": "4850"
18+
}
19+
]
20+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
**/*.iml
2+
**/*.ipr
3+
**/*.iws
4+
**/*.log
5+
**/.classpath
6+
**/.idea/
7+
**/.project
8+
**/.settings
9+
**/target/
10+
**/*.class
11+
12+
# General
13+
.DS_Store
14+
.AppleDouble
15+
.LSOverride
16+
17+
18+
.vscode/*
19+
!.vscode/settings.json
20+
!.vscode/tasks.json
21+
!.vscode/launch.json
22+
!.vscode/extensions.json
23+
*.code-workspace
24+
25+
# Local History for Visual Studio Code
26+
.history/
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
2+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
3+
<modelVersion>4.0.0</modelVersion>
4+
5+
<parent>
6+
<groupId>com.backbase.buildingblocks</groupId>
7+
<artifactId>backbase-service-extension-starter-parent</artifactId>
8+
<version>12.1.0</version>
9+
</parent>
10+
11+
<groupId>com.backbase.dbs.paymentorder</groupId>
12+
<artifactId>lorem-ipsum-batch-upload-type-service-extension</artifactId>
13+
<version>1.0.0-SNAPSHOT</version>
14+
15+
<properties>
16+
17+
<!-- docker configuration -->
18+
<docker.image.name>harbor.backbase.eu/experimental/${project.artifactId}</docker.image.name>
19+
<docker.image.tag>${project.version}</docker.image.tag>
20+
21+
<!-- base image -->
22+
<docker.base.tag>DBS-2.20.1</docker.base.tag>
23+
<docker.base.name>repo.backbase.com/backbase-docker-releases/payment-order-service</docker.base.name>
24+
</properties>
25+
26+
<dependencyManagement>
27+
<dependencies>
28+
<dependency>
29+
<groupId>com.backbase.dbs</groupId>
30+
<artifactId>banking-services-bom</artifactId>
31+
<version>2.20.1</version>
32+
<type>pom</type>
33+
<scope>import</scope>
34+
</dependency>
35+
</dependencies>
36+
</dependencyManagement>
37+
38+
<dependencies>
39+
<dependency>
40+
<groupId>com.backbase.dbs.paymentorder</groupId>
41+
<artifactId>payment-order-service</artifactId>
42+
<classifier>classes</classifier>
43+
<scope>provided</scope>
44+
</dependency>
45+
<dependency>
46+
<groupId>org.springframework.boot</groupId>
47+
<artifactId>spring-boot-starter-test</artifactId>
48+
<scope>test</scope>
49+
</dependency>
50+
</dependencies>
51+
</project>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
package com.backbase.dbs.payment.batch.parser.type;
2+
3+
import com.backbase.buildingblocks.presentation.errors.BadRequestException;
4+
import com.backbase.dbs.payment.batch.config.BatchConfiguration;
5+
import com.backbase.dbs.payment.batch.model.BatchHeader;
6+
import com.backbase.dbs.payment.batch.model.BatchPayment;
7+
import com.backbase.dbs.payment.batch.model.BatchUploadHeader;
8+
import com.backbase.dbs.payment.batch.parser.BatchParseCallback;
9+
import com.backbase.dbs.payment.batch.parser.DigestBatchParser;
10+
import com.fasterxml.jackson.core.JsonFactory;
11+
import com.fasterxml.jackson.core.JsonLocation;
12+
import com.fasterxml.jackson.core.JsonParser;
13+
import com.fasterxml.jackson.core.JsonToken;
14+
import java.io.InputStream;
15+
import java.math.BigDecimal;
16+
import java.time.LocalDate;
17+
import java.time.format.DateTimeFormatter;
18+
import java.util.Collections;
19+
import org.springframework.beans.factory.annotation.Autowired;
20+
import org.springframework.stereotype.Component;
21+
22+
@Component
23+
public class LoremIpsumBatchParser extends DigestBatchParser {
24+
25+
public static final String LOREM_IPSUM_TYPE = "LOREM_IPSUM";
26+
27+
@Autowired
28+
public LoremIpsumBatchParser(BatchConfiguration batchConfiguration) {
29+
super(batchConfiguration);
30+
}
31+
32+
public String getBatchUploadType() {
33+
return LOREM_IPSUM_TYPE;
34+
}
35+
36+
public void parseBatches(InputStream inputStream, BatchParseCallback callback) {
37+
38+
try (JsonParser parser = new JsonFactory().createParser(inputStream)) {
39+
callback.onBatchUpload(new BatchUploadHeader().batchFileType(LOREM_IPSUM_TYPE));
40+
BatchHeader batchHeader = new BatchHeader().currency("EUR").batchType("SEPACT");
41+
parser.nextToken();
42+
while (parser.nextToken() != JsonToken.END_OBJECT) {
43+
switch (parser.getCurrentName()) {
44+
case "label":
45+
batchHeader.batchName(parser.nextTextValue());
46+
break;
47+
case "priority":
48+
// priority is non-standard field and will be stored in the additions map
49+
batchHeader.additions(Collections.singletonMap("priority", parser.nextTextValue()));
50+
break;
51+
case "own-account":
52+
batchHeader.originatorAccount(parser.nextTextValue());
53+
break;
54+
case "requested-execution-date":
55+
batchHeader.requestedExecutionDate(
56+
LocalDate.parse(parser.nextTextValue(), DateTimeFormatter.ofPattern("dd/MM/yyyy")));
57+
break;
58+
case "batch-total-amount":
59+
batchHeader.batchTotalCreditAmount(new BigDecimal(parser.nextTextValue()));
60+
break;
61+
case "batch-payments-count":
62+
batchHeader.batchPaymentsCount(Integer.valueOf(parser.nextTextValue()));
63+
break;
64+
case "payments":
65+
callback.onBatch(batchHeader);
66+
parser.nextToken();
67+
while (parser.nextToken() != JsonToken.END_ARRAY) {
68+
BatchPayment batchPayment = new BatchPayment().currency("EUR")
69+
.location(formatJsonLocation(parser.getCurrentLocation()));
70+
while (parser.nextToken() != JsonToken.END_OBJECT) {
71+
switch (parser.getCurrentName()) {
72+
case "counterparty-name":
73+
batchPayment.counterpartyName(parser.nextTextValue());
74+
break;
75+
case "counterparty-account":
76+
batchPayment.counterpartyAccount(parser.nextTextValue());
77+
break;
78+
case "amount":
79+
batchPayment.amount(new BigDecimal(parser.nextTextValue()));
80+
break;
81+
default:
82+
throw new BadRequestException("Batch is not valid");
83+
}
84+
}
85+
callback.onPaymentRecord(batchPayment);
86+
}
87+
callback.onBatchEnd();
88+
break;
89+
default:
90+
throw new BadRequestException("Batch is not valid");
91+
}
92+
}
93+
callback.onBatchUploadEnd();
94+
} catch (Exception e) {
95+
callback.onBatchUploadError(new RuntimeException(e));
96+
}
97+
}
98+
99+
private static String formatJsonLocation(JsonLocation jsonLocation) {
100+
return String.format("Line: %d, Column: %d", jsonLocation.getLineNr(), jsonLocation.getColumnNr());
101+
}
102+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
2+
package com.backbase.dbs.payment.batch.validator.type;
3+
4+
import com.backbase.buildingblocks.presentation.errors.BadRequestException;
5+
import com.backbase.buildingblocks.presentation.errors.Error;
6+
import com.backbase.dbs.payment.batch.model.BatchHeader;
7+
import com.backbase.dbs.payment.batch.model.BatchPayment;
8+
import com.backbase.dbs.payment.batch.model.BatchUploadHeader;
9+
import com.backbase.dbs.payment.batch.model.BatchUploadReport;
10+
import com.backbase.dbs.payment.batch.parser.type.LoremIpsumBatchParser;
11+
import com.backbase.dbs.payment.batch.service.ErrorFactory;
12+
import com.backbase.dbs.payment.batch.validator.BatchTypeValidator;
13+
import com.backbase.dbs.paymentorder.spec.v2.batchuploads.FileDto;
14+
import java.math.BigDecimal;
15+
import java.util.Collections;
16+
import java.util.List;
17+
import java.util.Map;
18+
import org.springframework.stereotype.Component;
19+
20+
@Component
21+
public class LoremIpsumBatchValidator implements BatchTypeValidator {
22+
23+
private static final String[] BATCH_FILE_TYPES = {LoremIpsumBatchParser.LOREM_IPSUM_TYPE};
24+
25+
private static final String[] BATCH_TYPES = {"SEPACT"};
26+
27+
private static final Map<String, List<String>> BATCH_TYPE_FILE_EXTENSIONS =
28+
Collections.singletonMap(LoremIpsumBatchParser.LOREM_IPSUM_TYPE, Collections.singletonList("json"));
29+
30+
public Map<String, List<String>> getSupportedBatchTypesExtensions() {
31+
return BATCH_TYPE_FILE_EXTENSIONS;
32+
}
33+
34+
public String[] getSupportedBatchUploadTypes() {
35+
return BATCH_FILE_TYPES;
36+
}
37+
38+
public String[] getSupportedBatchTypes() {
39+
return BATCH_TYPES;
40+
}
41+
42+
public void validate(FileDto fileDto, BatchUploadReport batchUploadReport) {
43+
// add file validation logic here
44+
}
45+
46+
public void validate(BatchUploadHeader batchUploadHeader, BatchUploadReport batchUploadReport) {
47+
// add batch upload pre-validation logic here
48+
}
49+
50+
public void validate(BatchHeader batchHeader, BatchUploadReport batchUploadReport) {
51+
// add batch order pre-validation logic here
52+
53+
if (batchHeader.getBatchTotalCreditAmount().compareTo(BigDecimal.ZERO) <= 0) {
54+
// We do not propagate batch order location because the upload always has one batch order
55+
batchUploadReport.addError(
56+
ErrorFactory.createAmountIsNotPositiveError("batch-total-amount",
57+
batchHeader.getBatchTotalCreditAmount()));
58+
}
59+
}
60+
61+
public void validate(BatchPayment batchPayment, BatchUploadReport batchUploadReport) {
62+
// add batch payment validation logic here
63+
64+
if (batchPayment.getAmount().compareTo(BigDecimal.ZERO) <= 0) {
65+
// We do propagate batch payment location to be able to easily locate the problematic payment
66+
batchUploadReport.addError(withLocation(
67+
ErrorFactory.createAmountIsNotPositiveError("amount", batchPayment.getAmount()),
68+
batchPayment.getLocation()));
69+
}
70+
}
71+
72+
public void validateAfter(BatchHeader batchHeader, BatchUploadReport batchUploadReport) {
73+
// add batch order post-validation logic here
74+
75+
// We check for error in this after-hook only to be able to collect several validation problems across the file
76+
// It is possible to check for errors in the pre-hook to have fail-fast behavior
77+
checkForErrors(batchUploadReport);
78+
}
79+
80+
public void validateAfter(BatchUploadHeader batchUploadHeader, BatchUploadReport batchUploadReport) {
81+
// add batch upload post-validation logic here
82+
}
83+
84+
private static Error withLocation(Error error, String location) {
85+
error.getContext().put("location", location);
86+
return error;
87+
}
88+
89+
private static void checkForErrors(BatchUploadReport report) {
90+
if (report.hasErrors()) {
91+
throw new BadRequestException().withMessage("Batch is not valid").withErrors(report.getErrors());
92+
}
93+
}
94+
}

0 commit comments

Comments
 (0)