Skip to content

Commit 2bad2f4

Browse files
committed
FIN-350 add exporting of opening balances for liability accounts to the export of profile.
1 parent a590c97 commit 2bad2f4

File tree

6 files changed

+131
-3
lines changed

6 files changed

+131
-3
lines changed

bpmn-process/src/main/java/com/jongsoft/finance/serialized/ExportJson.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,5 +20,6 @@ public class ExportJson implements Serializable {
2020
private List<BudgetJson> budgetPeriods;
2121
private List<ContractJson> contracts;
2222
private List<String> tags;
23+
private List<TransactionJson> transactions;
2324

2425
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
package com.jongsoft.finance.serialized;
2+
3+
import com.jongsoft.finance.domain.transaction.Transaction;
4+
import io.micronaut.serde.annotation.Serdeable;
5+
import lombok.AllArgsConstructor;
6+
import lombok.Builder;
7+
import lombok.Getter;
8+
9+
import java.io.Serializable;
10+
import java.time.LocalDate;
11+
12+
@Builder
13+
@Getter
14+
@Serdeable
15+
@AllArgsConstructor
16+
public class TransactionJson implements Serializable {
17+
18+
private final String fromAccount;
19+
private final String toAccount;
20+
21+
private final String description;
22+
private final String currency;
23+
private final double amount;
24+
25+
private final LocalDate date;
26+
private final LocalDate interestDate;
27+
private final LocalDate bookDate;
28+
29+
public static TransactionJson fromDomain(Transaction transaction) {
30+
return TransactionJson.builder()
31+
.fromAccount(transaction.computeFrom().getName())
32+
.toAccount(transaction.computeTo().getName())
33+
.description(transaction.getDescription())
34+
.currency(transaction.getCurrency())
35+
.amount(transaction.computeAmount(transaction.computeFrom()))
36+
.date(transaction.getDate())
37+
.interestDate(transaction.getInterestDate())
38+
.bookDate(transaction.getBookDate())
39+
.build();
40+
}
41+
}

bpmn-process/src/main/resources/schema/profile.schema.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,12 @@
3939
"items": {
4040
"type": "string"
4141
}
42+
},
43+
"transactions": {
44+
"type": "array",
45+
"items": {
46+
"$ref": "https://www.pledger.io/schemas/transaction.schema.json"
47+
}
4248
}
4349
}
4450
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
{
2+
"$schema": "https://json-schema.org/draft/2020-12/schema",
3+
"$id": "https://www.pledger.io/schemas/transaction.schema.json",
4+
"title": "Transaction",
5+
"type": "object",
6+
"properties": {
7+
"date": {
8+
"type": "string",
9+
"format": "date",
10+
"description": "The date of the transaction."
11+
},
12+
"interestDate": {
13+
"type": "string",
14+
"format": "date",
15+
"description": "The interest date of the transaction."
16+
},
17+
"bookDate": {
18+
"type": "string",
19+
"format": "date",
20+
"description": "The book date of the transaction."
21+
},
22+
"amount": {
23+
"type": "number",
24+
"description": "The amount of the transaction."
25+
},
26+
"currency": {
27+
"type": "string",
28+
"description": "The currency of the transaction."
29+
},
30+
"description": {
31+
"type": "string",
32+
"description": "The description of the transaction."
33+
},
34+
"fromAccount": {
35+
"type": "string",
36+
"description": "The account from which the transaction was made."
37+
},
38+
"toAccount": {
39+
"type": "string",
40+
"description": "The account to which the transaction was made."
41+
}
42+
},
43+
"required": ["date", "amount", "currency", "description", "fromAccount", "toAccount"]
44+
}

fintrack-api/src/main/java/com/jongsoft/finance/rest/profile/ProfileExportResource.java

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,9 @@
99
import com.jongsoft.finance.domain.transaction.TransactionRule;
1010
import com.jongsoft.finance.domain.user.Budget;
1111
import com.jongsoft.finance.domain.user.Category;
12+
import com.jongsoft.finance.factory.FilterFactory;
1213
import com.jongsoft.finance.providers.DataProvider;
14+
import com.jongsoft.finance.providers.TransactionProvider;
1315
import com.jongsoft.finance.security.AuthenticationFacade;
1416
import com.jongsoft.finance.serialized.*;
1517
import com.jongsoft.lang.Collections;
@@ -37,6 +39,8 @@ public class ProfileExportResource {
3739
private final List<Exportable<?>> exportable;
3840
private final List<DataProvider<?>> dataProviders;
3941
private final StorageService storageService;
42+
private final TransactionProvider transactionProvider;
43+
private final FilterFactory filterFactory;
4044

4145
@Get
4246
@Operation(
@@ -65,14 +69,15 @@ public HttpResponse<ExportJson> export() {
6569
rule,
6670
this::loadRelation))
6771
.toJava())
72+
.transactions(lookupRelevantTransactions())
6873
.build();
6974

7075
return HttpResponse.ok(exportJson)
7176
.header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + exportFileName + "\"")
7277
.header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON);
7378
}
7479

75-
@SuppressWarnings("unchecked")
80+
@SuppressWarnings({"unchecked", "rawtypes"})
7681
private <T> Sequence<T> lookupAllOf(Class<T> forClass) {
7782
for (Exportable exporter : exportable) {
7883
if (exporter.supports(forClass)) {
@@ -83,7 +88,21 @@ private <T> Sequence<T> lookupAllOf(Class<T> forClass) {
8388
return Collections.List();
8489
}
8590

86-
@SuppressWarnings("unchecked")
91+
private List<TransactionJson> lookupRelevantTransactions() {
92+
// we also want to export all opening balance transactions for liability accounts
93+
var filter = filterFactory.transaction()
94+
.page(0)
95+
.pageSize(Integer.MAX_VALUE)
96+
.onlyIncome(false)
97+
.description("Opening balance", true);
98+
99+
return transactionProvider.lookup(filter)
100+
.content()
101+
.map(TransactionJson::fromDomain)
102+
.toJava();
103+
}
104+
105+
@SuppressWarnings({"unchecked", "rawtypes"})
87106
private String loadRelation(RuleColumn column, String value) {
88107
if (column == RuleColumn.TAGS) {
89108
return value;

fintrack-api/src/test/java/com/jongsoft/finance/rest/profile/ProfileExportResourceTest.java

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,35 @@
11
package com.jongsoft.finance.rest.profile;
22

3+
import com.jongsoft.finance.ResultPage;
4+
import com.jongsoft.finance.providers.TransactionProvider;
35
import com.jongsoft.finance.rest.TestSetup;
6+
import io.micronaut.context.annotation.Replaces;
47
import io.micronaut.http.HttpHeaders;
5-
import io.micronaut.test.extensions.junit5.annotation.MicronautTest;
8+
import io.micronaut.test.annotation.MockBean;
69
import io.restassured.specification.RequestSpecification;
10+
import jakarta.inject.Inject;
711
import org.junit.jupiter.api.DisplayName;
812
import org.junit.jupiter.api.Test;
13+
import org.mockito.Mockito;
914

1015
@DisplayName("Profile export resource")
1116
class ProfileExportResourceTest extends TestSetup {
1217

18+
@Replaces
19+
@MockBean
20+
TransactionProvider transactionProvider() {
21+
return Mockito.mock(TransactionProvider.class);
22+
}
23+
24+
@Inject
25+
private TransactionProvider transactionProvider;
26+
1327
@Test
1428
@DisplayName("should export profile")
1529
void export(RequestSpecification spec) {
30+
Mockito.when(transactionProvider.lookup(Mockito.any(TransactionProvider.FilterCommand.class)))
31+
.thenReturn(ResultPage.of());
32+
1633
// @formatter:off
1734
spec.when()
1835
.get("/api/profile/export")

0 commit comments

Comments
 (0)