Skip to content

Commit 58dc20b

Browse files
committed
FINERACT-2247: New command processing - Currency Management (org.apache.fineract.organisation.monetary)
1 parent ba06234 commit 58dc20b

File tree

42 files changed

+405
-538
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

42 files changed

+405
-538
lines changed
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
/**
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
package org.apache.fineract.organisation.monetary.api;
20+
21+
import io.swagger.v3.oas.annotations.Operation;
22+
import io.swagger.v3.oas.annotations.tags.Tag;
23+
import jakarta.ws.rs.Consumes;
24+
import jakarta.ws.rs.GET;
25+
import jakarta.ws.rs.PUT;
26+
import jakarta.ws.rs.Path;
27+
import jakarta.ws.rs.Produces;
28+
import jakarta.ws.rs.core.MediaType;
29+
import java.util.UUID;
30+
import java.util.function.Supplier;
31+
import lombok.RequiredArgsConstructor;
32+
import org.apache.fineract.command.core.CommandPipeline;
33+
import org.apache.fineract.infrastructure.core.service.DateUtils;
34+
import org.apache.fineract.organisation.monetary.command.CurrencyUpdateCommand;
35+
import org.apache.fineract.organisation.monetary.data.CurrencyConfigurationData;
36+
import org.apache.fineract.organisation.monetary.data.CurrencyUpdateRequest;
37+
import org.apache.fineract.organisation.monetary.data.CurrencyUpdateResponse;
38+
import org.apache.fineract.organisation.monetary.service.OrganisationCurrencyReadPlatformService;
39+
import org.springframework.stereotype.Component;
40+
41+
@Path("/v1/currencies")
42+
@Component
43+
@Tag(name = "Currency", description = "Application related configuration around viewing/updating the currencies permitted for use within the MFI.")
44+
@RequiredArgsConstructor
45+
public class CurrenciesApiResource {
46+
47+
private final OrganisationCurrencyReadPlatformService readPlatformService;
48+
private final CommandPipeline commandPipeline;
49+
50+
@GET
51+
@Consumes({ MediaType.APPLICATION_JSON })
52+
@Produces({ MediaType.APPLICATION_JSON })
53+
@Operation(summary = "Retrieve Currency Configuration", description = """
54+
Returns the list of currencies permitted for use AND the list of currencies not selected (but available for selection).
55+
56+
Example Requests:
57+
58+
currencies
59+
currencies?fields=selectedCurrencyOptions
60+
""")
61+
public CurrencyConfigurationData retrieveCurrencies() {
62+
return readPlatformService.retrieveCurrencyConfiguration();
63+
}
64+
65+
@PUT
66+
@Consumes({ MediaType.APPLICATION_JSON })
67+
@Produces({ MediaType.APPLICATION_JSON })
68+
@Operation(summary = "Update Currency Configuration", description = "Updates the list of currencies permitted for use.")
69+
public CurrencyUpdateResponse updateCurrencies(CurrencyUpdateRequest request) {
70+
final var command = new CurrencyUpdateCommand();
71+
72+
command.setId(UUID.randomUUID());
73+
command.setCreatedAt(DateUtils.getAuditOffsetDateTime());
74+
command.setPayload(request);
75+
76+
final Supplier<CurrencyUpdateResponse> response = commandPipeline.send(command);
77+
78+
return response.get();
79+
}
80+
}

fineract-core/src/main/java/org/apache/fineract/organisation/monetary/data/MoneyData.java renamed to fineract-core/src/main/java/org/apache/fineract/organisation/monetary/command/CurrencyUpdateCommand.java

Lines changed: 8 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -16,35 +16,13 @@
1616
* specific language governing permissions and limitations
1717
* under the License.
1818
*/
19-
package org.apache.fineract.organisation.monetary.data;
19+
package org.apache.fineract.organisation.monetary.command;
2020

21-
import java.math.BigDecimal;
21+
import lombok.Data;
22+
import lombok.EqualsAndHashCode;
23+
import org.apache.fineract.command.core.Command;
24+
import org.apache.fineract.organisation.monetary.data.CurrencyUpdateRequest;
2225

23-
/**
24-
* Immutable data object representing currency.
25-
*/
26-
public class MoneyData {
27-
28-
private final String code;
29-
private final BigDecimal amount;
30-
private final int decimalPlaces;
31-
32-
public MoneyData(final String code, final BigDecimal amount, final int decimalPlaces) {
33-
this.code = code;
34-
this.amount = amount;
35-
this.decimalPlaces = decimalPlaces;
36-
}
37-
38-
public String getCode() {
39-
return this.code;
40-
}
41-
42-
public BigDecimal getAmount() {
43-
return this.amount;
44-
}
45-
46-
public int getDecimalPlaces() {
47-
return this.decimalPlaces;
48-
}
49-
50-
}
26+
@Data
27+
@EqualsAndHashCode(callSuper = true)
28+
public class CurrencyUpdateCommand extends Command<CurrencyUpdateRequest> {}

fineract-core/src/main/java/org/apache/fineract/organisation/monetary/data/request/CurrencyRequest.java renamed to fineract-core/src/main/java/org/apache/fineract/organisation/monetary/data/CurrencyConfigurationData.java

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,25 @@
1616
* specific language governing permissions and limitations
1717
* under the License.
1818
*/
19-
package org.apache.fineract.organisation.monetary.data.request;
19+
package org.apache.fineract.organisation.monetary.data;
2020

2121
import java.io.Serial;
2222
import java.io.Serializable;
2323
import java.util.List;
24+
import lombok.AllArgsConstructor;
25+
import lombok.Builder;
26+
import lombok.Data;
27+
import lombok.NoArgsConstructor;
2428

25-
public record CurrencyRequest(List<String> currencies) implements Serializable {
29+
@Builder
30+
@Data
31+
@NoArgsConstructor
32+
@AllArgsConstructor
33+
public class CurrencyConfigurationData implements Serializable {
2634

2735
@Serial
2836
private static final long serialVersionUID = 1L;
37+
38+
private List<CurrencyData> selectedCurrencyOptions;
39+
private List<CurrencyData> currencyOptions;
2940
}

fineract-core/src/main/java/org/apache/fineract/organisation/monetary/data/CurrencyData.java

Lines changed: 19 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -18,26 +18,29 @@
1818
*/
1919
package org.apache.fineract.organisation.monetary.data;
2020

21+
import java.io.Serial;
2122
import java.io.Serializable;
22-
import lombok.EqualsAndHashCode;
23-
import lombok.Getter;
24-
import org.apache.fineract.infrastructure.core.config.MapstructMapperConfig;
25-
import org.apache.fineract.organisation.monetary.domain.MonetaryCurrency;
23+
import lombok.AllArgsConstructor;
24+
import lombok.Builder;
25+
import lombok.Data;
26+
import lombok.NoArgsConstructor;
2627

27-
/**
28-
* Immutable data object representing currency.
29-
*/
30-
@Getter
31-
@EqualsAndHashCode
28+
@Builder
29+
@Data
30+
@NoArgsConstructor
31+
@AllArgsConstructor
3232
public class CurrencyData implements Serializable {
3333

34-
private final String code;
35-
private final String name;
36-
private final int decimalPlaces;
37-
private final Integer inMultiplesOf;
38-
private final String displaySymbol;
39-
private final String nameCode;
40-
private final String displayLabel;
34+
@Serial
35+
private static final long serialVersionUID = 1L;
36+
37+
private String code;
38+
private String name;
39+
private int decimalPlaces;
40+
private Integer inMultiplesOf;
41+
private String displaySymbol;
42+
private String nameCode;
43+
private String displayLabel;
4144

4245
public static CurrencyData blank() {
4346
return new CurrencyData("", "", 0, 0, "", "");
@@ -90,11 +93,4 @@ private String generateDisplayLabel() {
9093
return builder.toString();
9194
}
9295

93-
@org.mapstruct.Mapper(config = MapstructMapperConfig.class)
94-
public interface Mapper {
95-
96-
default CurrencyData map(MonetaryCurrency source) {
97-
return source.toData();
98-
}
99-
}
10096
}

fineract-core/src/main/java/org/apache/fineract/organisation/monetary/data/ApplicationCurrencyConfigurationData.java renamed to fineract-core/src/main/java/org/apache/fineract/organisation/monetary/data/CurrencyUpdateRequest.java

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -18,25 +18,26 @@
1818
*/
1919
package org.apache.fineract.organisation.monetary.data;
2020

21+
import jakarta.validation.constraints.NotEmpty;
22+
import jakarta.validation.constraints.NotNull;
2123
import java.io.Serial;
2224
import java.io.Serializable;
23-
import java.util.Collection;
24-
import lombok.Getter;
25-
import lombok.RequiredArgsConstructor;
25+
import java.util.List;
26+
import lombok.AllArgsConstructor;
27+
import lombok.Builder;
28+
import lombok.Data;
29+
import lombok.NoArgsConstructor;
2630

27-
/**
28-
* Immutable data object for application currency.
29-
*/
30-
31-
@Getter
32-
@RequiredArgsConstructor
33-
public class ApplicationCurrencyConfigurationData implements Serializable {
31+
@Builder
32+
@Data
33+
@NoArgsConstructor
34+
@AllArgsConstructor
35+
public class CurrencyUpdateRequest implements Serializable {
3436

3537
@Serial
3638
private static final long serialVersionUID = 1L;
3739

38-
@SuppressWarnings("unused")
39-
private final Collection<CurrencyData> selectedCurrencyOptions;
40-
@SuppressWarnings("unused")
41-
private final Collection<CurrencyData> currencyOptions;
40+
@NotNull(message = "{org.apache.fineract.organisation.monetary.currencies.not-null}")
41+
@NotEmpty(message = "{org.apache.fineract.organisation.monetary.currencies.not-empty}")
42+
private List<String> currencies;
4243
}
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
/**
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
package org.apache.fineract.organisation.monetary.data;
20+
21+
import com.fasterxml.jackson.annotation.JsonProperty;
22+
import io.swagger.v3.oas.annotations.media.Schema;
23+
import java.io.Serial;
24+
import java.io.Serializable;
25+
import java.util.List;
26+
import java.util.Map;
27+
import lombok.AllArgsConstructor;
28+
import lombok.Builder;
29+
import lombok.Data;
30+
import lombok.NoArgsConstructor;
31+
32+
@Builder
33+
@Data
34+
@NoArgsConstructor
35+
@AllArgsConstructor
36+
public class CurrencyUpdateResponse implements Serializable {
37+
38+
@Serial
39+
private static final long serialVersionUID = 1L;
40+
41+
@Schema(example = """
42+
[
43+
"KES",
44+
"BND",
45+
"LBP",
46+
"GHC",
47+
"USD",
48+
"XOF",
49+
"AED",
50+
"AMD"
51+
]
52+
""")
53+
private List<String> currencies;
54+
55+
@Deprecated(forRemoval = true)
56+
@JsonProperty("changes")
57+
public Map<String, Object> getChanges() {
58+
// TODO: remove this one day... we should never use hashmaps in such trivial cases!!!
59+
return Map.of("currencies", currencies);
60+
}
61+
}

fineract-core/src/main/java/org/apache/fineract/organisation/monetary/domain/ApplicationCurrencyRepositoryWrapper.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ public ApplicationCurrency findOneWithNotFoundDetection(final MonetaryCurrency c
5151
}
5252

5353
final ApplicationCurrency applicationCurrency = ApplicationCurrency.from(defaultApplicationCurrency,
54-
currency.getDigitsAfterDecimal(), currency.getCurrencyInMultiplesOf());
54+
currency.getDigitsAfterDecimal(), currency.getInMultiplesOf());
5555

5656
return applicationCurrency;
5757
}

fineract-core/src/main/java/org/apache/fineract/organisation/monetary/domain/MonetaryCurrency.java

Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,10 @@
2020

2121
import jakarta.persistence.Column;
2222
import jakarta.persistence.Embeddable;
23+
import lombok.Getter;
2324
import org.apache.fineract.organisation.monetary.data.CurrencyData;
2425

26+
@Getter
2527
@Embeddable
2628
public class MonetaryCurrency {
2729

@@ -74,17 +76,4 @@ public CurrencyData toData() {
7476
}
7577
return currencyData;
7678
}
77-
78-
public String getCode() {
79-
return this.code;
80-
}
81-
82-
public int getDigitsAfterDecimal() {
83-
return this.digitsAfterDecimal;
84-
}
85-
86-
public Integer getCurrencyInMultiplesOf() {
87-
return this.inMultiplesOf;
88-
}
89-
9079
}

fineract-provider/src/main/java/org/apache/fineract/organisation/monetary/handler/UpdateCurrencyCommandHandler.java renamed to fineract-core/src/main/java/org/apache/fineract/organisation/monetary/handler/CurrencyUpdateCommandHandler.java

Lines changed: 13 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -18,30 +18,26 @@
1818
*/
1919
package org.apache.fineract.organisation.monetary.handler;
2020

21-
import org.apache.fineract.commands.annotation.CommandType;
22-
import org.apache.fineract.commands.handler.NewCommandSourceHandler;
23-
import org.apache.fineract.infrastructure.core.api.JsonCommand;
24-
import org.apache.fineract.infrastructure.core.data.CommandProcessingResult;
21+
import lombok.RequiredArgsConstructor;
22+
import lombok.extern.slf4j.Slf4j;
23+
import org.apache.fineract.command.core.Command;
24+
import org.apache.fineract.command.core.CommandHandler;
25+
import org.apache.fineract.organisation.monetary.data.CurrencyUpdateRequest;
26+
import org.apache.fineract.organisation.monetary.data.CurrencyUpdateResponse;
2527
import org.apache.fineract.organisation.monetary.service.CurrencyWritePlatformService;
26-
import org.springframework.beans.factory.annotation.Autowired;
27-
import org.springframework.stereotype.Service;
28+
import org.springframework.stereotype.Component;
2829
import org.springframework.transaction.annotation.Transactional;
2930

30-
@Service
31-
@CommandType(entity = "CURRENCY", action = "UPDATE")
32-
public class UpdateCurrencyCommandHandler implements NewCommandSourceHandler {
31+
@Slf4j
32+
@Component
33+
@RequiredArgsConstructor
34+
public class CurrencyUpdateCommandHandler implements CommandHandler<CurrencyUpdateRequest, CurrencyUpdateResponse> {
3335

3436
private final CurrencyWritePlatformService writePlatformService;
3537

36-
@Autowired
37-
public UpdateCurrencyCommandHandler(final CurrencyWritePlatformService writePlatformService) {
38-
this.writePlatformService = writePlatformService;
39-
}
40-
4138
@Transactional
4239
@Override
43-
public CommandProcessingResult processCommand(final JsonCommand command) {
44-
45-
return this.writePlatformService.updateAllowedCurrencies(command);
40+
public CurrencyUpdateResponse handle(final Command<CurrencyUpdateRequest> command) {
41+
return writePlatformService.updateAllowedCurrencies(command.getPayload());
4642
}
4743
}

0 commit comments

Comments
 (0)