Skip to content

Commit 02409ef

Browse files
committed
Merge branch 'apache:develop' into FINERACT-1152-fix-loan-reschedule-end-date-validation
2 parents ed88191 + 3e14990 commit 02409ef

File tree

66 files changed

+1748
-1550
lines changed

Some content is hidden

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

66 files changed

+1748
-1550
lines changed

custom/acme/note/starter/dependencies.gradle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ dependencies {
2222
implementation('org.springframework.boot:spring-boot-starter')
2323
testImplementation(project(':fineract-core'))
2424
testImplementation(project(':fineract-loan'))
25+
testImplementation(project(':fineract-savings'))
2526
testImplementation(project(':fineract-provider'))
2627
testImplementation('org.springframework.boot:spring-boot-starter-jdbc')
2728
testImplementation('org.springframework.boot:spring-boot-starter-data-jpa')

custom/acme/note/starter/src/test/java/com/acme/fineract/portfolio/note/starter/AcmeNoteServiceStepDefinitions.java

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@
2121
import static org.assertj.core.api.Assertions.assertThat;
2222

2323
import io.cucumber.java8.En;
24-
import org.springframework.boot.autoconfigure.AutoConfigurations;
2524
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
2625

2726
public class AcmeNoteServiceStepDefinitions implements En {
@@ -33,13 +32,10 @@ public class AcmeNoteServiceStepDefinitions implements En {
3332
private ApplicationContextRunner contextRunner;
3433

3534
public AcmeNoteServiceStepDefinitions() {
36-
Given("/^An auto configuration (.*) and a service configuration (.*)$/",
37-
(String autoConfigurationClassName, String configurationClassName) -> {
38-
contextRunner = new ApplicationContextRunner()
39-
.withConfiguration(AutoConfigurations.of(Class.forName(autoConfigurationClassName)))
40-
.withPropertyValues("acme.note.enabled", "true")
41-
.withUserConfiguration(Class.forName(configurationClassName.trim()));
42-
});
35+
Given("/^A service configuration (.*)$/", (String configurationClassName) -> {
36+
contextRunner = new ApplicationContextRunner().withPropertyValues("acme.note.enabled", "true")
37+
.withUserConfiguration(Class.forName(configurationClassName.trim()));
38+
});
4339

4440
When("/^The user retrieves the service of interface class (.*)$/", (String interfaceClassName) -> {
4541
contextRunner.run(ctx -> {

custom/acme/note/starter/src/test/java/com/acme/fineract/portfolio/note/starter/TestDefaultConfiguration.java

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -28,51 +28,59 @@
2828
import org.apache.fineract.portfolio.loanaccount.domain.LoanRepositoryWrapper;
2929
import org.apache.fineract.portfolio.loanaccount.domain.LoanTransactionRepository;
3030
import org.apache.fineract.portfolio.note.domain.NoteRepository;
31+
import org.apache.fineract.portfolio.savings.domain.SavingsAccountRepository;
3132
import org.springframework.boot.context.properties.EnableConfigurationProperties;
3233
import org.springframework.context.annotation.Bean;
34+
import org.springframework.context.annotation.ComponentScan;
3335
import org.springframework.jdbc.core.JdbcTemplate;
3436

3537
@EnableConfigurationProperties({ FineractProperties.class })
36-
public class TestDefaultConfiguration {
38+
@ComponentScan("org.apache.fineract.portfolio.note.service")
39+
class TestDefaultConfiguration {
3740
// NOTE: unfortunately an abastract base class that contains all these mock functions won't work
3841

3942
@Bean
40-
public RoutingDataSourceServiceFactory routingDataSourceServiceFactory() {
43+
RoutingDataSourceServiceFactory routingDataSourceServiceFactory() {
4144
return mock(RoutingDataSourceServiceFactory.class);
4245
}
4346

4447
@Bean
45-
public RoutingDataSource routingDataSource() {
48+
RoutingDataSource routingDataSource() {
4649
return mock(RoutingDataSource.class);
4750
}
4851

4952
@Bean
50-
public JdbcTemplate jdbcTemplate() {
53+
JdbcTemplate jdbcTemplate() {
5154
return mock(JdbcTemplate.class);
5255
}
5356

5457
@Bean
55-
public NoteRepository noteRepository() {
58+
NoteRepository noteRepository() {
5659
return mock(NoteRepository.class);
5760
}
5861

5962
@Bean
60-
public ClientRepositoryWrapper clientRepository() {
63+
ClientRepositoryWrapper clientRepository() {
6164
return mock(ClientRepositoryWrapper.class);
6265
}
6366

6467
@Bean
65-
public GroupRepository groupRepository() {
68+
GroupRepository groupRepository() {
6669
return mock(GroupRepository.class);
6770
}
6871

6972
@Bean
70-
public LoanRepositoryWrapper loanRepository() {
73+
LoanRepositoryWrapper loanRepository() {
7174
return mock(LoanRepositoryWrapper.class);
7275
}
7376

7477
@Bean
75-
public LoanTransactionRepository loanTransactionRepository() {
78+
LoanTransactionRepository loanTransactionRepository() {
7679
return mock(LoanTransactionRepository.class);
7780
}
81+
82+
@Bean
83+
SavingsAccountRepository savingsAccountRepository() {
84+
return mock(SavingsAccountRepository.class);
85+
}
7886
}

custom/acme/note/starter/src/test/java/com/acme/fineract/portfolio/note/starter/TestOverrideConfiguration.java

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -32,46 +32,46 @@
3232
import org.springframework.jdbc.core.JdbcTemplate;
3333

3434
@ComponentScan("com.acme.fineract")
35-
public class TestOverrideConfiguration {
35+
class TestOverrideConfiguration {
3636
// NOTE: unfortunately an abastract base class that contains all these mock functions won't work
3737

3838
@Bean
39-
public RoutingDataSourceServiceFactory routingDataSourceServiceFactory() {
39+
RoutingDataSourceServiceFactory routingDataSourceServiceFactory() {
4040
return mock(RoutingDataSourceServiceFactory.class);
4141
}
4242

4343
@Bean
44-
public RoutingDataSource routingDataSource() {
44+
RoutingDataSource routingDataSource() {
4545
return mock(RoutingDataSource.class);
4646
}
4747

4848
@Bean
49-
public JdbcTemplate jdbcTemplate() {
49+
JdbcTemplate jdbcTemplate() {
5050
return mock(JdbcTemplate.class);
5151
}
5252

5353
@Bean
54-
public NoteRepository noteRepository() {
54+
NoteRepository noteRepository() {
5555
return mock(NoteRepository.class);
5656
}
5757

5858
@Bean
59-
public ClientRepositoryWrapper clientRepository() {
59+
ClientRepositoryWrapper clientRepository() {
6060
return mock(ClientRepositoryWrapper.class);
6161
}
6262

6363
@Bean
64-
public GroupRepository groupRepository() {
64+
GroupRepository groupRepository() {
6565
return mock(GroupRepository.class);
6666
}
6767

6868
@Bean
69-
public LoanRepositoryWrapper loanRepository() {
69+
LoanRepositoryWrapper loanRepository() {
7070
return mock(LoanRepositoryWrapper.class);
7171
}
7272

7373
@Bean
74-
public LoanTransactionRepository loanTransactionRepository() {
74+
LoanTransactionRepository loanTransactionRepository() {
7575
return mock(LoanTransactionRepository.class);
7676
}
7777
}

custom/acme/note/starter/src/test/resources/features/note.feature

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,13 @@ Feature: Note Feature
2121

2222
@modules
2323
Scenario Outline: Verify that the dummy service returns the correct message
24-
Given An auto configuration <autoConfigurationClass> and a service configuration <configurationClass>
24+
Given A service configuration <configurationClass>
2525
When The user retrieves the service of interface class <interfaceClass>
2626
Then The service class should match <serviceClass>
2727

2828
Examples:
29-
| autoConfigurationClass | configurationClass | interfaceClass | serviceClass |
30-
| org.apache.fineract.portfolio.note.starter.NoteAutoConfiguration | com.acme.fineract.portfolio.note.starter.TestDefaultConfiguration | org.apache.fineract.portfolio.note.service.NoteReadPlatformService | org.apache.fineract.portfolio.note.service.NoteReadPlatformServiceImpl |
31-
| org.apache.fineract.portfolio.note.starter.NoteAutoConfiguration | com.acme.fineract.portfolio.note.starter.TestDefaultConfiguration | org.apache.fineract.portfolio.note.service.NoteWritePlatformService | org.apache.fineract.portfolio.note.service.NoteWritePlatformServiceJpaRepositoryImpl |
32-
| org.apache.fineract.portfolio.note.starter.NoteAutoConfiguration | com.acme.fineract.portfolio.note.starter.TestOverrideConfiguration | org.apache.fineract.portfolio.note.service.NoteReadPlatformService | com.acme.fineract.portfolio.note.service.AcmeNoteReadPlatformService |
33-
| org.apache.fineract.portfolio.note.starter.NoteAutoConfiguration | com.acme.fineract.portfolio.note.starter.TestOverrideConfiguration | org.apache.fineract.portfolio.note.service.NoteWritePlatformService | com.acme.fineract.portfolio.note.service.AcmeNoteWritePlatformService |
29+
| configurationClass | interfaceClass | serviceClass |
30+
| com.acme.fineract.portfolio.note.starter.TestDefaultConfiguration | org.apache.fineract.portfolio.note.service.NoteReadPlatformService | org.apache.fineract.portfolio.note.service.NoteReadPlatformServiceImpl |
31+
| com.acme.fineract.portfolio.note.starter.TestDefaultConfiguration | org.apache.fineract.portfolio.note.service.NoteWritePlatformService | org.apache.fineract.portfolio.note.service.NoteWritePlatformServiceImpl |
32+
| com.acme.fineract.portfolio.note.starter.TestOverrideConfiguration | org.apache.fineract.portfolio.note.service.NoteReadPlatformService | com.acme.fineract.portfolio.note.service.AcmeNoteReadPlatformService |
33+
| com.acme.fineract.portfolio.note.starter.TestOverrideConfiguration | org.apache.fineract.portfolio.note.service.NoteWritePlatformService | com.acme.fineract.portfolio.note.service.AcmeNoteWritePlatformService |

fineract-core/src/main/java/org/apache/fineract/commands/service/CommandWrapperBuilder.java

Lines changed: 7 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@
2121
import static org.apache.fineract.useradministration.service.AppUserConstants.PASSWORD;
2222
import static org.apache.fineract.useradministration.service.AppUserConstants.REPEAT_PASSWORD;
2323

24-
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
2524
import java.util.Arrays;
2625
import java.util.HashSet;
2726
import java.util.Set;
@@ -34,7 +33,6 @@
3433

3534
public class CommandWrapperBuilder {
3635

37-
private Long officeId;
3836
private Long groupId;
3937
private Long clientId;
4038
private Long loanId;
@@ -47,27 +45,21 @@ public class CommandWrapperBuilder {
4745
private String json = "{}";
4846
private String transactionId;
4947
private Long productId;
50-
private Long templateId;
51-
private Long creditBureauId;
5248
private Long organisationCreditBureauId;
5349
private String jobName;
54-
private String idempotencyKey;
5550
private ExternalId loanExternalId;
5651
private Set<String> sanitizeJsonKeys;
5752

58-
@SuppressFBWarnings(value = "UWF_UNWRITTEN_FIELD", justification = "TODO: fix this!")
5953
public CommandWrapper build() {
60-
return new CommandWrapper(this.officeId, this.groupId, this.clientId, this.loanId, this.savingsId, this.actionName, this.entityName,
61-
this.entityId, this.subentityId, this.href, this.json, this.transactionId, this.productId, this.templateId,
62-
this.creditBureauId, this.organisationCreditBureauId, this.jobName, this.idempotencyKey, this.loanExternalId,
63-
this.sanitizeJsonKeys);
54+
return new CommandWrapper(null, this.groupId, this.clientId, this.loanId, this.savingsId, this.actionName, this.entityName,
55+
this.entityId, this.subentityId, this.href, this.json, this.transactionId, this.productId, null, null,
56+
this.organisationCreditBureauId, this.jobName, null, this.loanExternalId, this.sanitizeJsonKeys);
6457
}
6558

6659
public CommandWrapper build(String idempotencyKey) {
67-
return new CommandWrapper(this.officeId, this.groupId, this.clientId, this.loanId, this.savingsId, this.actionName, this.entityName,
68-
this.entityId, this.subentityId, this.href, this.json, this.transactionId, this.productId, this.templateId,
69-
this.creditBureauId, this.organisationCreditBureauId, this.jobName, idempotencyKey, this.loanExternalId,
70-
this.sanitizeJsonKeys);
60+
return new CommandWrapper(null, this.groupId, this.clientId, this.loanId, this.savingsId, this.actionName, this.entityName,
61+
this.entityId, this.subentityId, this.href, this.json, this.transactionId, this.productId, null, null,
62+
this.organisationCreditBureauId, this.jobName, idempotencyKey, this.loanExternalId, this.sanitizeJsonKeys);
7163
}
7264

7365
public CommandWrapperBuilder updateCreditBureau() {
@@ -123,7 +115,7 @@ public CommandWrapperBuilder deleteCreditReport(final Long creditBureauId) {
123115
public CommandWrapperBuilder createCreditBureauLoanProductMapping(final long organisationCreditBureauId) {
124116
this.actionName = "CREATE";
125117
this.entityName = "CREDITBUREAU_LOANPRODUCT_MAPPING";
126-
this.entityId = creditBureauId;
118+
this.entityId = null; // TODO: fix this, was always null
127119
this.href = "/creditBureauConfiguration/template";
128120
this.organisationCreditBureauId = organisationCreditBureauId;
129121
return this;
@@ -2279,42 +2271,6 @@ public CommandWrapperBuilder executeSchedulerJob(final Long jobId) {
22792271
return this;
22802272
}
22812273

2282-
public CommandWrapperBuilder createMeeting(final CommandWrapper resourceDetails, final String supportedEntityType,
2283-
final Long supportedEntityId) {
2284-
this.actionName = "CREATE";
2285-
this.entityName = "MEETING";
2286-
this.clientId = resourceDetails.getClientId();
2287-
this.loanId = resourceDetails.getLoanId();
2288-
this.groupId = resourceDetails.getGroupId();
2289-
this.href = "/" + supportedEntityType + "/" + supportedEntityId + "/meetings";
2290-
return this;
2291-
}
2292-
2293-
public CommandWrapperBuilder updateMeeting(final String supportedEntityType, final Long supportedEntityId, final Long meetingId) {
2294-
this.actionName = "UPDATE";
2295-
this.entityName = "MEETING";
2296-
this.entityId = meetingId;
2297-
this.href = "/" + supportedEntityType + "/" + supportedEntityId + "/meetings/" + meetingId;
2298-
return this;
2299-
}
2300-
2301-
public CommandWrapperBuilder deleteMeeting(final String supportedEntityType, final Long supportedEntityId, final Long meetingId) {
2302-
this.actionName = "DELETE";
2303-
this.entityName = "MEETING";
2304-
this.entityId = meetingId;
2305-
this.href = "/" + supportedEntityType + "/" + supportedEntityId + "/meetings/" + meetingId;
2306-
return this;
2307-
}
2308-
2309-
public CommandWrapperBuilder saveOrUpdateAttendance(final Long entityId, final String supportedEntityType,
2310-
final Long supportedEntityId) {
2311-
this.actionName = "SAVEORUPDATEATTENDANCE";
2312-
this.entityName = "MEETING";
2313-
this.entityId = entityId;
2314-
this.href = "/" + supportedEntityType + "/" + supportedEntityId + "/meetings/" + entityId + "?command=saveOrUpdateAttendance";
2315-
return this;
2316-
}
2317-
23182274
/**
23192275
* Deposit account mappings
23202276
*/

fineract-doc/src/docs/en/chapters/custom/service-note.adoc

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,6 @@ include::{rootdir}/fineract-core/src/main/java/org/apache/fineract/portfolio/not
1818
include::{rootdir}/fineract-core/src/main/java/org/apache/fineract/portfolio/note/service/NoteReadPlatformService.java[lines=19..]
1919
----
2020

21-
== Auto Start Configuration
21+
== Configuration
2222

2323
The rules to replace the Note services are very simple. If you provide an alternative implementation of the services then the default implementations will *not* be loaded.
24-
25-
.Note Auto Starter Configuration
26-
[source,java]
27-
----
28-
include::{rootdir}/fineract-provider/src/main/java/org/apache/fineract/portfolio/note/starter/NoteAutoConfiguration.java[lines=19..]
29-
----

fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/config/SecurityConfig.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -354,6 +354,15 @@ public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
354354
.hasAnyAuthority(ALL_FUNCTIONS, ALL_FUNCTIONS_WRITE, "CREATE_STAFF")
355355
.requestMatchers(API_MATCHER.matcher(HttpMethod.PUT, "/api/*/staff/*"))
356356
.hasAnyAuthority(ALL_FUNCTIONS, ALL_FUNCTIONS_WRITE, "UPDATE_STAFF")
357+
// meeting
358+
.requestMatchers(API_MATCHER.matcher(HttpMethod.GET, "/api/*/*/*/meeting/*"))
359+
.hasAnyAuthority(ALL_FUNCTIONS, ALL_FUNCTIONS_READ, "READ_MEETING")
360+
.requestMatchers(API_MATCHER.matcher(HttpMethod.POST, "/api/*/*/*/meeting/*"))
361+
.hasAnyAuthority(ALL_FUNCTIONS, ALL_FUNCTIONS_WRITE, "CREATE_MEETING")
362+
.requestMatchers(API_MATCHER.matcher(HttpMethod.PUT, "/api/*/*/*/meeting/*"))
363+
.hasAnyAuthority(ALL_FUNCTIONS, ALL_FUNCTIONS_WRITE, "UPDATE_MEETING")
364+
.requestMatchers(API_MATCHER.matcher(HttpMethod.DELETE, "/api/*/*/*/meeting/*"))
365+
.hasAnyAuthority(ALL_FUNCTIONS, ALL_FUNCTIONS_WRITE, "DELETE_MEETING")
357366

358367
.requestMatchers(API_MATCHER.matcher(HttpMethod.POST, "/api/*/twofactor/validate")).fullyAuthenticated()
359368
.requestMatchers(API_MATCHER.matcher("/api/*/twofactor")).fullyAuthenticated()

0 commit comments

Comments
 (0)