Merge remote-tracking branch 'upstream/develop' into develop

This commit is contained in:
Zoltan Nebli
2020-08-12 21:35:50 +02:00
1026 changed files with 13619 additions and 69517 deletions
+6 -1
View File
@@ -74,6 +74,11 @@ script:
# and Docker test does not run if integration test fails, which makes PR failure easier to understand.
# @see https://docs.travis-ci.com/user/job-lifecycle/#customizing-the-build-phase
# NOTE: Sleep after docker-compose increased to 60 seconds as often Travis would fail to get Docker up in 30 seconds
- ./gradlew --console=plain licenseMain licenseTest licenseIntegrationTest check && ./gradlew --console=plain integrationTest --fail-fast && sudo service mysql stop && docker-compose build && docker-compose up -d && sleep 30s && http --verify=no --timeout 240 --check-status get https://localhost:8443/fineract-provider/actuator/health && (( $(http --verify=no --timeout 30 --check-status --body get https://localhost:8443/fineract-provider/actuator/info | wc --chars) > 100 ))
- ./gradlew --console=plain -PautomatedBuild=true -q licenseMain licenseTest licenseIntegrationTest check && ./gradlew --console=plain -PautomatedBuild=true integrationTest --fail-fast && sudo service mysql stop && docker-compose build && docker-compose up -d && sleep 60s && http --verify=no --timeout 240 --check-status get https://localhost:8443/fineract-provider/actuator/health && (( $(http --verify=no --timeout 30 --check-status --body get https://localhost:8443/fineract-provider/actuator/info | wc --chars) > 100 ))
# We stop the mysql system service when running the Docker test to avoid port 3306 conflicts (unless we run the mysql in docker-compose on another port; req. FINERACT-773)
# The fany /actuator/info test makes sure that has more than 100 characters of JSON to test that the git.properties worked (see FINERACT-983)
# Generate and Build Swagger Code
- ls
- ./gradlew generateSwaggerCode
- cd build/swagger-code-fineract && mvn test
+2 -2
View File
@@ -22,7 +22,7 @@ RUN apt-get update -qq && apt-get install -y wget
COPY . fineract
WORKDIR /fineract
RUN ./gradlew --no-daemon -x rat -x test bootJar
RUN ./gradlew -PautomatedBuild=true --no-daemon -q -x rat -x test bootJar
WORKDIR /fineract/target
RUN jar -xf /fineract/build/libs/fineract-provider.jar
@@ -33,7 +33,7 @@ RUN jar -xf /fineract/build/libs/fineract-provider.jar
# allowing implementations to switch the driver used by changing start-up parameters (for both tenants and each tenant DB)
# The commented out lines in the docker-compose.yml illustrate how to do this.
WORKDIR /fineract/target/BOOT-INF/lib
RUN wget https://repo1.maven.org/maven2/mysql/mysql-connector-java/8.0.20/mysql-connector-java-8.0.20.jar
RUN wget -q https://repo1.maven.org/maven2/mysql/mysql-connector-java/8.0.20/mysql-connector-java-8.0.20.jar
# =========================================
+4 -2
View File
@@ -249,9 +249,11 @@ complies with the [Apache Software Foundation third-party license policy](https:
Apache Fineract Platform API
============
The API for the Fineract-platform (project named 'Apache Fineract') is documented in the API-docs under <b><i>Full API Matrix</i></b> and can be viewed [here](https://demo.fineract.dev/fineract-provider/api-docs/apiLive.htm "API Documentation").
The API for Fineract is documented in [apiLive.htm](fineract-provider/src/main/resources/static/api-docs/apiLive.htm), and the [apiLive.htm can be viewed on Fineract.dev](https://demo.fineract.dev/fineract-provider/api-docs/apiLive.htm "API Documentation"). If you have your own Fineract instance running, you can find this documentation under [/fineract-provider/api-docs/apiLive.htm](https://localhost:8443/fineract-provider/api-docs/apiLive.htm).
If you have your own Fineract instance running, you can find the same documentation under '(your host:port)/fineract-provider/api-docs/apiLive.htm' under your. The Swagger documentation (work in progress) can be accessed under '(your host:port)/fineract-provider/swagger-ui/index.html'
The Swagger documentation (work in progress; see [FINERACT-733](https://issues.apache.org/jira/browse/FINERACT-733)) can be accessed under [/fineract-provider/swagger-ui/index.html](https://localhost:8443/fineract-provider/swagger-ui/index.html) and [live Swagger UI here on Fineract.dev](https://demo.fineract.dev/fineract-provider/swagger-ui/index.html).
Apache Fineract supports client code generation using [Swagger Codegen](https://github.com/swagger-api/swagger-codegen) based on the [OpenAPI Specification](https://swagger.io/specification/). For more instructions on how to generate the client code, check [docs/developers/swagger/client.md](docs/developers/swagger/client.md).
API clients (Web UIs, Mobile, etc.)
+1 -1
View File
@@ -79,7 +79,7 @@
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.align_tags_descriptions_grouped" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.comment.line_length" value="80"/>
<setting id="org.eclipse.jdt.core.formatter.comment.line_length" value="120"/>
<setting id="org.eclipse.jdt.core.formatter.use_on_off_tags" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.keep_method_body_on_one_line" value="one_line_if_empty"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression" value="do not insert"/>
+26
View File
@@ -0,0 +1,26 @@
Generate Apache Fineract API Client
============
Apache Fineract supports client code generation using [Swagger Codegen](https://github.com/swagger-api/swagger-codegen). Project supports [all clients](https://github.com/swagger-api/swagger-codegen#overview) supported by Swagger Codegen. It uses [OpenAPI Specification Version 3.0.3](https://swagger.io/specification/).
## Generate API Client
In root directory of the project:
- Run `./gradlew build`
- Run `./gradlew generateSwaggerCode`
The client code will be generated under `build/swagger-code-fineract`
## Build API Client:
- Run `cd build/swagger-code-fineract`
- Run `./gradlew build`
## Customize Code Generator:
Swagger Codegen provides several options to customize the generated code. [Here](https://openapi-generator.tech/docs/generators/java/) are the options available for customization.
- Open `fineract-provider/config/swagger/config.json`
- Customize options
- Build the project again as mentioned in **Generate API Client Code** section
+255 -172
View File
@@ -20,10 +20,17 @@ description = '''\
Run as:
gradle clean bootRun'''
group = 'org.apache.fineract'
buildDir = new File(rootProject.projectDir, "../build")
repositories {
jcenter()
mavenCentral()
}
project.ext.jerseyVersion = '1.19.4'
ext["groovy.version"] = '3.0.3'
buildscript {
ext {
jacocoVersion = '0.8.5'
@@ -35,28 +42,28 @@ buildscript {
}
dependencies {
classpath 'io.spring.gradle:dependency-management-plugin:1.0.9.RELEASE'
classpath 'com.bmuschko:gradle-cargo-plugin:2.7.1',
'nl.javadude.gradle.plugins:license-gradle-plugin:0.11.0',
'org.zeroturnaround:gradle-jrebel-plugin:1.1.10',
'org.springframework.boot:spring-boot-gradle-plugin:2.2.7.RELEASE'
// below
classpath 'org.apache.openjpa:openjpa:3.1.1' // when upgrading, also change OpenJPA version repeated below in dependencyManagement!
classpath 'io.spring.gradle:dependency-management-plugin:1.0.10.RELEASE'
classpath 'com.bmuschko:gradle-cargo-plugin:2.7.1'
classpath 'org.zeroturnaround:gradle-jrebel-plugin:1.1.10'
classpath 'org.springframework.boot:spring-boot-gradle-plugin:2.3.2.RELEASE'
classpath 'gradle.plugin.com.hierynomus.gradle.plugins:license-gradle-plugin:0.15.0'
classpath 'org.apache.openjpa:openjpa:3.1.2' // when upgrading, also change OpenJPA version repeated below in dependencyManagement!
classpath 'com.radcortez.gradle:openjpa-gradle-plugin:3.1.0'
classpath 'org.nosphere.apache:creadur-rat-gradle:0.7.0'
classpath "gradle.plugin.com.github.spotbugs.snom:spotbugs-gradle-plugin:4.4.1"
classpath "gradle.plugin.com.github.spotbugs.snom:spotbugs-gradle-plugin:4.5.0"
classpath "gradle.plugin.com.github.andygoossens:gradle-modernizer-plugin:1.3.0"
classpath "gradle.plugin.com.gorylenko.gradle-git-properties:gradle-git-properties:2.2.2"
classpath "gradle.plugin.com.gorylenko.gradle-git-properties:gradle-git-properties:2.2.3"
classpath "net.ltgt.gradle:gradle-errorprone-plugin:1.2.1"
classpath "com.diffplug.spotless:spotless-plugin-gradle:4.4.0"
classpath "io.swagger.core.v3:swagger-gradle-plugin:2.1.2"
classpath "com.diffplug.spotless:spotless-plugin-gradle:5.1.1"
classpath "io.swagger.core.v3:swagger-gradle-plugin:2.1.4"
classpath "gradle.plugin.org.hidetake:gradle-swagger-generator-plugin:2.18.2"
}
}
apply plugin: 'io.spring.dependency-management'
apply plugin: "org.nosphere.apache.rat"
apply plugin: 'rebel'
apply plugin: 'license'
apply plugin: 'com.github.hierynomus.license'
apply plugin: 'war'
apply plugin: 'org.springframework.boot'
apply plugin: 'eclipse'
@@ -71,8 +78,9 @@ apply plugin: 'com.github.andygoossens.gradle-modernizer-plugin'
apply plugin: 'jacoco'
apply plugin: "com.gorylenko.gradle-git-properties"
apply plugin: "net.ltgt.errorprone"
apply plugin: "com.diffplug.gradle.spotless"
apply plugin: "com.diffplug.spotless"
apply plugin: "io.swagger.core.v3.swagger-gradle-plugin"
apply plugin: "org.hidetake.swagger.generator"
dependencyManagement {
imports {
@@ -80,44 +88,46 @@ dependencyManagement {
}
dependencies {
// As much as possible, we avoid fixed versions, and prefer inheriting them from the Spring BOM, thus NOT listing versions here.
// (The :+ seems to mean latest available version available on Maven Central, which we should also avoid, as it's not isolated?)
// We use fixed versions, instead of inheriting them from the Spring BOM, to be able to be on more recent ones.
// We do not use :+ to get the latest available version available on Maven Central, as that could suddenly break things.
// We use the Renovate Bot to automatically propose Pull Requests (PRs) when upgrades for all of these versions are available.
dependency 'org.springframework.security.oauth:spring-security-oauth2:2.5.0.RELEASE'
dependency "org.apache.openjpa:openjpa:3.1.1" // when upgrading, also change OpenJPA version repeated above in buildscript!
dependency 'org.apache.openjpa:openjpa:3.1.2' // when upgrading, also change OpenJPA version repeated above in buildscript!
dependency 'com.squareup.retrofit:retrofit:1.9.0'
dependency 'com.squareup.okhttp:okhttp:2.7.5'
dependency 'com.squareup.okhttp:okhttp-urlconnection:2.7.5'
dependency 'com.google.guava:guava:29.0-jre'
dependency 'com.google.code.gson:gson:2.8.6'
dependency 'org.apache.commons:commons-email:1.5'
dependency 'commons-io:commons-io:2.7'
dependency 'org.drizzle.jdbc:drizzle-jdbc:1.4'
dependency 'com.github.librepdf:openpdf:1.3.19'
dependency 'com.github.librepdf:openpdf:1.3.20'
dependency 'org.mnode.ical4j:ical4j:3.0.19'
dependency 'org.flywaydb:flyway-core:6.4.4'
dependency 'org.flywaydb:flyway-core:6.5.4'
dependency 'org.quartz-scheduler:quartz:2.3.2'
dependency 'com.amazonaws:aws-java-sdk-s3:1.11.804'
dependency 'com.amazonaws:aws-java-sdk-s3:1.11.832'
dependency 'org.ehcache:ehcache:3.8.1'
dependency 'com.github.spullara.mustache.java:compiler:0.9.6'
dependency 'com.jayway.jsonpath:json-path:2.4.0'
dependency 'org.apache.tika:tika-core:1.24.1'
dependency 'org.apache.httpcomponents:httpclient:4.5.12'
dependency 'io.swagger:swagger-jersey-jaxrs:1.6.1'
dependency 'io.swagger.core.v3:swagger-annotations:2.1.4'
dependency 'jakarta.management.j2ee:jakarta.management.j2ee-api:1.1.4'
dependency 'jakarta.jms:jakarta.jms-api:2.0.3'
dependency 'jakarta.xml.bind:jakarta.xml.bind-api:2.3.3'
dependency 'org.apache.activemq:activemq-broker:5.15.13'
dependency 'org.apache.bval:org.apache.bval.bundle:2.0.3'
dependency 'org.mockito:mockito-core:3.3.3'
dependency 'org.mockito:mockito-junit-jupiter:3.3.3'
dependency 'io.github.classgraph:classgraph:4.8.86'
dependency 'jakarta.validation:jakarta.validation-api:3.0.0'
dependency 'org.apache.activemq:activemq-broker:5.16.0'
dependency 'org.apache.bval:org.apache.bval.bundle:2.0.4'
dependency 'org.mockito:mockito-core:3.4.6'
dependency 'org.mockito:mockito-junit-jupiter:3.4.6'
dependency 'io.github.classgraph:classgraph:4.8.87'
dependency 'org.awaitility:awaitility:4.0.3'
dependency 'com.github.spotbugs:spotbugs-annotations:4.0.4'
dependency 'com.github.spotbugs:spotbugs-annotations:4.1.1'
dependency 'javax.cache:cache-api:1.1.1'
dependency 'org.mock-server:mockserver-junit-jupiter:5.10'
// If this is upgraded, you need to change path in WebFrontEndConfiguration
dependency 'org.webjars.npm:swagger-ui-dist:3.27.0'
dependency 'org.mock-server:mockserver-junit-jupiter:5.11.0'
dependency 'org.webjars.npm:swagger-ui-dist:3.31.1'
dependency 'org.webjars:webjars-locator-core:0.46'
dependency ('org.dom4j:dom4j:2.1.3') {
exclude 'relaxngDatatype:relaxngDatatype' // already in com.sun.xml.bind:jaxb-osgi:2.3.0.1
@@ -155,16 +165,6 @@ sourceCompatibility = JavaVersion.VERSION_11
/* define binary compatibility version */
targetCompatibility = JavaVersion.VERSION_11
project.ext.mysqlUser='root'
project.ext.mysqlPassword='mysql'
group = 'org.apache.fineract'
buildDir = new File(rootProject.projectDir, "../build")
repositories {
jcenter()
// mavenLocal() // useful for local dev using MariaDB4j SNAPSHOTs (not needed for real-world non-SNAPHOT builds)
}
// If we are running Gradle within Eclipse to enhance classes with OpenJPA,
// set the classes directory to point to Eclipse's default build directory
if (project.hasProperty('env') && project.getProperty('env') == 'eclipse')
@@ -179,8 +179,15 @@ eclipse
}
}
// Configuration for the OpenJPA enhance task
// https://github.com/radcortez/openjpa-gradle-plugin
System.setProperty("openjpa.Log", "commons")
openjpa {
includes = ['**/AbstractPersistableCustom.class', '**/domain/*.class']
includes = [
'**/AbstractPersistableCustom.class',
'**/domain/*.class'
]
enhance {
enforcePropertyRestrictions true
}
@@ -189,11 +196,13 @@ openjpa {
// Configuration for Swagger documentation generation task
// https://github.com/swagger-api/swagger-core/tree/master/modules/swagger-gradle-plugin
resolve {
logging.captureStandardOutput LogLevel.INFO
outputFileName = 'fineract'
outputFormat = 'JSON'
outputFormat = 'YAML'
prettyPrint = 'TRUE'
classpath = sourceSets.main.runtimeClasspath
outputDir = file("${buildDir}/classes/java/main/static/swagger-ui")
openApiFile = file("config/swagger/fineract-input.yaml")
}
// Configuration for JaCoCo code coverage task
@@ -201,36 +210,45 @@ resolve {
jacoco {
toolVersion = jacocoVersion
reportsDir = file("$buildDir/reports/jacoco")
}
jacocoTestReport{
reports{
jacocoTestReport {
reports {
html.enabled=true
xml.enabled=true
html.destination file("${buildDir}/code-coverage")
}
}
// Configuration for the spotless plugin
// https://github.com/diffplug/spotless/tree/main/plugin-gradle
spotless {
format 'misc', {
target '**/*.md', '**/*.properties', '**/*.gradle', '**/.gitignore', '**/*.yml', '**/*.xml', '**/**.json', '**/*.sql'
targetExclude '**/build/**', '**/bin/**', '**/.settings/**'
indentWithSpaces(4)
endWithNewline()
trimTrailingWhitespace()
}
format 'misc', {
target '**/*.md', '**/*.properties', '**/.gitignore', '**/*.yml', '**/*.xml', '**/**.json', '**/*.sql'
targetExclude '**/build/**', '**/bin/**', '**/.settings/**','**/.idea/**'
indentWithSpaces(4)
endWithNewline()
trimTrailingWhitespace()
}
java {
importOrder() //sort imports alphabetically
removeUnusedImports()
eclipse().configFile '../config/fineractdev-formatter.xml'
endWithNewline()
trimTrailingWhitespace()
groovyGradle {
target '*.gradle', '**/*.gradle'
greclipse()
indentWithSpaces(4)
endWithNewline()
trimTrailingWhitespace()
}
// Enforce style modifier order
custom 'Modifier ordering', {
def modifierRanking = [
java {
importOrder() //sort imports alphabetically
removeUnusedImports()
eclipse().configFile '../config/fineractdev-formatter.xml'
endWithNewline()
trimTrailingWhitespace()
// Enforce style modifier order
custom 'Modifier ordering', {
def modifierRanking = [
public : 1,
protected : 2,
private : 3,
@@ -243,20 +261,19 @@ spotless {
synchronized: 10,
native : 11,
strictfp : 12]
// Find any instance of multiple modifiers. Lead with a non-word character to avoid
// accidental matching against for instance, "an alternative default value"
it.replaceAll(/\W(?:public |protected |private |abstract |default |static |final |transient |volatile |synchronized |native |strictfp ){2,}/, {
// Do not replace the leading non-word character. Identify the modifiers
it.replaceAll(/(?:public |protected |private |abstract |default |static |final |transient |volatile |synchronized |native |strictfp ){2,}/, {
// Sort the modifiers according to the ranking above
it.split().sort({ modifierRanking[it] }).join(' ') + ' '
}
)
// Find any instance of multiple modifiers. Lead with a non-word character to avoid
// accidental matching against for instance, "an alternative default value"
it.replaceAll(/\W(?:public |protected |private |abstract |default |static |final |transient |volatile |synchronized |native |strictfp ){2,}/, {
// Do not replace the leading non-word character. Identify the modifiers
it.replaceAll(/(?:public |protected |private |abstract |default |static |final |transient |volatile |synchronized |native |strictfp ){2,}/, {
// Sort the modifiers according to the ranking above
it.split().sort({ modifierRanking[it] }).join(' ') + ' '
}
)
}
)
}
)
}
}
}
lineEndings 'UNIX'
}
@@ -289,7 +306,7 @@ rat {
'**/.gitignore',
'**/.gitkeep',
'**/*.iml',
//Notice files
// Notice files
'**/NOTICE_RELEASE',
'**/NOTICE_SOURCE',
// Swagger License
@@ -304,8 +321,7 @@ rat {
'**/native/**',
'**/wrapper/**',
'**/build/**',
//Api Docs
// Api Docs
'**/api-docs/*.*',
'**/docs/system-architecture/.htaccess',
'**/docs/system-architecture/404.html',
@@ -313,14 +329,11 @@ rat {
'**/docs/system-architecture/**/*.xml',
'**/bootstrap-3.0.0/assets/application.js',
'**/system-architecture/js/plugins.js',
//Apache License
// Apache License
'**/bootstrap-3.0.0/assets/less.js',
'**/css/bootstrap-3.0.0/**/*.*',
//Public Domain See http://www.JSON.org/js.html
// Public Domain See http://www.JSON.org/js.html
'**/bootstrap-3.0.0/assets/json2.js.htm',
// MIT License
'**/modernizr-2.6.2.min.js',
'**/css/normalize.css',
@@ -335,12 +348,10 @@ rat {
'**/system-architecture/js/vendor/toc-0.1.2/jquery.toc.min.js',
'**/assets/respond.min.js',
'**/assets/html5shiv.js',
//BSD License
// BSD License
'**/assets/uglify.js',
//Ignore out folder
// Ignore out folder
'**/out/**',
// Git build info
"**/git.properties",
]
@@ -369,13 +380,34 @@ configurations {
}
tasks.withType(JavaCompile) {
options.compilerArgs += ["-Xlint:unchecked","-Xlint:cast","-Xlint:auxiliaryclass","-Xlint:deprecation",
"-Xlint:dep-ann","-Xlint:divzero","-Xlint:empty","-Xlint:exports","-Xlint:fallthrough",
"-Xlint:finally","-Xlint:module","-Xlint:opens","-Xlint:options","-Xlint:overloads",
"-Xlint:overrides","-Xlint:path","-Xlint:processing","-Xlint:removal",
"-Xlint:requires-automatic","-Xlint:requires-transitive-automatic","-Xlint:try",
"-Xlint:varargs","-Xlint:preview","-Xlint:static","-Werror"]
// TODO FINERACT-959 (gradually) enable -Xlint:all (see "javac -help -X")
options.compilerArgs += [
"-Xlint:unchecked",
"-Xlint:cast",
"-Xlint:auxiliaryclass",
"-Xlint:deprecation",
"-Xlint:dep-ann",
"-Xlint:divzero",
"-Xlint:empty",
"-Xlint:exports",
"-Xlint:fallthrough",
"-Xlint:finally",
"-Xlint:module",
"-Xlint:opens",
"-Xlint:options",
"-Xlint:overloads",
"-Xlint:overrides",
"-Xlint:path",
"-Xlint:processing",
"-Xlint:removal",
"-Xlint:requires-automatic",
"-Xlint:requires-transitive-automatic",
"-Xlint:try",
"-Xlint:varargs",
"-Xlint:preview",
"-Xlint:static",
"-Werror"
]
// TODO FINERACT-959 (gradually) enable -Xlint:all (see "javac -help -X")
options.deprecation = true
options.errorprone {
@@ -383,28 +415,15 @@ tasks.withType(JavaCompile) {
//Todo Remove necessary checks from this list
disable(
"UnusedVariable",
"SameNameButDifferent",
"UnusedMethod",
"ModifiedButNotUsed",
"TypeParameterUnusedInFormals",
"UnusedNestedClass",
"UndefinedEquals",
"JdkObsolete",
"EmptyBlockTag",
"MissingSummary",
"MutablePublicArray",
"InvalidParam",
"ReturnFromVoid",
"AlmostJavadoc",
"PublicConstructorForAbstractClass",
"ProtectedMembersInFinalClass",
"StaticAssignmentInConstructor",
"UnescapedEntity",
"InvalidBlockTag",
"ModifyCollectionInEnhancedForLoop",
"NonCanonicalType",
"InvalidInlineTag",
)
)
//TODO gradually enable these checks
error(
"DefaultCharset",
@@ -429,6 +448,7 @@ tasks.withType(JavaCompile) {
"StreamResourceLeak",
"TruthIncompatibleType",
"ByteBufferBackingArray",
"SameNameButDifferent",
"OrphanedFormatString",
"CatchAndPrintStackTrace",
"ObjectToString",
@@ -456,35 +476,52 @@ tasks.withType(JavaCompile) {
"NarrowingCompoundAssignment",
"MissingCasesInEnumSwitch",
"ReferenceEquality",
"UndefinedEquals",
"PublicConstructorForAbstractClass",
"UnescapedEntity",
"ModifyCollectionInEnhancedForLoop",
"NonCanonicalType",
"InvalidInlineTag",
"MutablePublicArray",
"StaticAssignmentInConstructor",
"ProtectedMembersInFinalClass",
"OperatorPrecedence",
"EqualsGetClass",
"EqualsUnsafeCast",
"DoubleBraceInitialization",
"UnnecessaryDefaultInEnumSwitch",
"UnusedNestedClass",
"UnusedMethod",
"ModifiedButNotUsed",
"InconsistentCapitalization",
"MissingOverride",
// "InvalidBlockTag",
// "InconsistentOverloads",
// "MethodCanBeStatic",
// "Var",
// "ConstantField",
// "UnnecessaryDefaultInEnumSwitch",
// "FieldCanBeFinal"
)
// "InvalidBlockTag",
// "InconsistentOverloads",
// "MethodCanBeStatic",
// "Var",
// "ConstantField",
// "UnnecessaryDefaultInEnumSwitch",
// "FieldCanBeFinal"
)
}
options.compilerArgs +=["-Xmaxwarns",1500,"-Xmaxerrs",1500]
options.compilerArgs +=[
"-Xmaxwarns",
1500,
"-Xmaxerrs",
1500
]
}
apply from: 'dependencies.gradle'
/* TODO https://issues.apache.org/jira/browse/FINERACT-939 (dev-dependencies.gradle has been removed, as totally broken)
// Pick up dependencies based on the environment, defaults to production
if (project.hasProperty('env') && project.getProperty('env') == 'dev') {
apply from: 'dev-dependencies.gradle'
} else {
apply from: 'dependencies.gradle'
}
*/
// Pick up dependencies based on the environment, defaults to production
if (project.hasProperty('env') && project.getProperty('env') == 'dev') {
apply from: 'dev-dependencies.gradle'
} else {
apply from: 'dependencies.gradle'
}
*/
/* Enable Oauth2 authentication based on environment, default to HTTP basic auth */
if (project.hasProperty('security') && project.getProperty('security') == 'oauth') {
@@ -517,6 +554,8 @@ if (project.hasProperty('security') && project.getProperty('security') == 'oauth
}
}
// Configuration for the modernizer plugin
// https://github.com/andygoossens/gradle-modernizer-plugin
modernizer {
includeTestClasses = true
failOnViolations = true
@@ -534,41 +573,47 @@ modernizer {
exclusions = []
exclusionPatterns = [
// To be removed when https://issues.apache.org/jira/browse/FINERACT-826 is fixed
// To be removed when https://issues.apache.org/jira/browse/FINERACT-826 is fixed
'org/joda/time/.*'
]
}
compileJava{
compileJava {
dependsOn rat
dependsOn spotlessCheck
finalizedBy resolve
if (project.hasProperty("automatedBuild")) {
dependsOn(spotlessCheck)
} else {
dependsOn(spotlessApply)
}
}
/*
pmd {
sourceSets = [sourceSets.main]
}
*/
war {
from('../licenses/binary/') { // notice the parens
from('../licenses/binary/') {
// notice the parens
into "WEB-INF/licenses/binary/" // no leading slash
}
from('../LICENSE_RELEASE') { // notice the parens
from('../LICENSE_RELEASE') {
// notice the parens
into "WEB-INF/" // no leading slash
}
from('../NOTICE_RELEASE') { // notice the parens
from('../NOTICE_RELEASE') {
// notice the parens
into "WEB-INF/" // no leading slash
}
rename ('LICENSE_RELEASE', 'LICENSE')
rename ('NOTICE_RELEASE', 'NOTICE')
from('../DISCLAIMER') { // notice the parens
from('../DISCLAIMER') {
// notice the parens
into "WEB-INF/" // no leading slash
}
war.finalizedBy(bootWar)
}
// Configuration for Gradle license plug-in
// https://github.com/hierynomus/license-gradle-plugin
license {
header rootProject.file('../APACHE_LICENSETEXT.md')
excludes([
@@ -584,48 +629,58 @@ license {
}
task licenseFormatBuildScripts (type:nl.javadude.gradle.plugins.license.License) {
source = fileTree(dir: '../', includes: ['**/*.bat', '**/*.sh', '**/*.sql'])
source = fileTree(dir: '../', includes: [
'**/*.bat',
'**/*.sh',
'**/*.sql'
])
}
licenseFormat.dependsOn licenseFormatBuildScripts
configurations
{
tomcat
}
dependencies {
tomcat "org.apache.tomcat:tomcat:9.0.36@zip"
}
// Configuration for the errorprone plugin
// https://github.com/tbroyer/gradle-errorprone-plugin
dependencies {
errorprone "com.google.errorprone:error_prone_core:2.4.0"
}
cargo {
containerId "tomcat9x"
local {
installer {
installConfiguration = configurations.tomcat
downloadDir = file("$buildDir/download")
extractDir = file("$buildDir/tomcat")
// Configuration for the Gradle Cargo plugin
// https://github.com/bmuschko/gradle-cargo-plugin
configurations
{
tomcat
}
dependencies {
tomcat "org.apache.tomcat:tomcat:9.0.37@zip"
}
cargo {
containerId "tomcat9x"
local {
installer {
installConfiguration = configurations.tomcat
downloadDir = file("$buildDir/download")
extractDir = file("$buildDir/tomcat")
}
startStopTimeout = 240000
containerProperties {
property 'cargo.tomcat.connector.keystoreFile', file('src/main/resources/keystore.jks')
property 'cargo.tomcat.connector.keystorePass', 'openmf'
property 'cargo.tomcat.httpSecure', true
property 'cargo.tomcat.connector.sslProtocol', 'TLS'
property 'cargo.tomcat.connector.clientAuth', false
property 'cargo.protocol', 'https'
property 'cargo.servlet.port', 8443
}
}
startStopTimeout = 240000
containerProperties {
property 'cargo.tomcat.connector.keystoreFile', file('src/main/resources/keystore.jks')
property 'cargo.tomcat.connector.keystorePass', 'openmf'
property 'cargo.tomcat.httpSecure', true
property 'cargo.tomcat.connector.sslProtocol', 'TLS'
property 'cargo.tomcat.connector.clientAuth', false
property 'cargo.protocol', 'https'
property 'cargo.servlet.port', 8443
}
}
}
cargoRunLocal.dependsOn bootWar
cargoStartLocal.dependsOn bootWar
cargoStartLocal.mustRunAfter "integrationTestClasses"
cargoStartLocal.mustRunAfter "enhance"
cargoStartLocal.mustRunAfter "resolve"
/* http://stackoverflow.com/questions/19653311/jpa-repository-works-in-idea-and-production-but-not-in-gradle */
sourceSets.main.output.resourcesDir = sourceSets.main.java.outputDir
@@ -649,7 +704,7 @@ if (!(project.hasProperty('env') && project.getProperty('env') == 'dev')) {
}
sourceSets {
integrationTest {
integrationTest {
compileClasspath += main.output + test.output
runtimeClasspath += main.output + test.output
}
@@ -671,7 +726,8 @@ task integrationTest(type:Test) {
integrationTest {
useJUnitPlatform()
testLogging { // FINERACT-927
testLogging {
// FINERACT-927
events "skipped", "failed"
showStandardStreams = false
exceptionFormat "full"
@@ -679,26 +735,33 @@ integrationTest {
}
test {
useJUnitPlatform()
testLogging { // FINERACT-927
testLogging {
// FINERACT-927
events "skipped", "failed"
showStandardStreams = false
exceptionFormat "full"
}
}
// Configuration for the Checkstyle plugin
// https://docs.gradle.org/current/userguide/checkstyle_plugin.html
dependencies {
checkstyle 'com.puppycrawl.tools:checkstyle:8.35'
checkstyle 'com.github.sevntu-checkstyle:sevntu-checks:1.37.1'
}
// Configuration for SQL tasks
// https://docs.groovy-lang.org/latest/html/api/groovy/sql/Sql.html
import groovy.sql.Sql
repositories {
mavenCentral()
}
project.ext.mysqlUser='root'
project.ext.mysqlPassword='mysql'
configurations {
driver
}
dependencies {
driver 'org.drizzle.jdbc:drizzle-jdbc:1.4'
checkstyle 'com.puppycrawl.tools:checkstyle:8.33'
checkstyle 'com.github.sevntu-checkstyle:sevntu-checks:1.37.1'
}
URLClassLoader loader = GroovyObject.class.classLoader
@@ -742,6 +805,9 @@ bootJar {
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
}
// Configuration for spotbugs plugin
// https://github.com/spotbugs/spotbugs-gradle-plugin
// To generate an HTML report instead of XML
spotbugs {
reportLevel = 'high'
@@ -773,6 +839,8 @@ spotbugsIntegrationTest {
}
}
// Configuration for git properties gradle plugin
// https://github.com/n0mer/gradle-git-properties
gitProperties {
gitPropertiesResourceDir = "$buildDir/classes/java/main/resources"
dateFormat = "yyyy-MM-dd'T'HH:mmZ"
@@ -782,3 +850,18 @@ gitProperties {
// make sure the generateGitProperties task always executes (even when git.properties is not changed)
generateGitProperties.outputs.upToDateWhen { false }
//This is for swagger code generation
dependencies {
swaggerCodegen 'io.swagger.codegen.v3:swagger-codegen-cli:3.0.18'
}
swaggerSources {
fineract {
inputFile = file('../build/classes/java/main/static/swagger-ui/fineract.yaml')
code {
language = 'java'
configFile = file('config/swagger/config.json')
}
}
}
@@ -46,10 +46,16 @@
<module name="TreeWalker">
<module name="ParameterName">
<property name="format" value="^[a-z][a-z0-9][a-zA-Z0-9]*$|[a-z]"/>
<message key="name.invalidPattern"
value="Parameter name ''{0}'' must match pattern ''{1}''."/>
</module>
<module name="SeparatorWrap">
<property name="tokens" value="DOT"/>
<property name="option" value="nl"/>
</module>
<module name="com.github.sevntu.checkstyle.checks.coding.AvoidHidingCauseExceptionCheck" />
<module name="SuppressWarningsHolder" />
<module name="RegexpSinglelineJava">
<property name="format" value="System\.(out)|(err)\.print(ln)?\("/>
@@ -160,6 +166,11 @@
<property name="format" value="^[a-z][a-zA-Z0-9_]*$"/>
<message key="name.invalidPattern"
value="Method name ''{0}'' must match pattern ''{1}''."/>
</module>
<module name="ClassTypeParameterName">
<property name="format" value="(^[A-Z][0-9]?)$|([A-Z][a-zA-Z0-9]*[T]$)"/>
<message key="name.invalidPattern"
value="Class type name ''{0}'' must match pattern ''{1}''."/>
</module>
<module name="MutableException"/>
<module name="WhitespaceAround">
@@ -174,6 +185,15 @@
</module>
<module name="ParenPad" />
<module name="ModifierOrder"/>
<module name="LocalVariableName">
<property name="tokens" value="VARIABLE_DEF"/>
<property name="format" value="^[a-z][a-z0-9][a-zA-Z0-9]*$|[a-z]"/>
<property name="allowOneCharVarInForLoop" value="true"/>
<message key="name.invalidPattern"
value="Local variable name ''{0}'' must match pattern ''{1}''."/>
</module>
<module name="AvoidNoArgumentSuperConstructorCall"/>
<module name="AvoidDoubleBraceInitialization"/>
<!-- TODO Enable many more checks (go about this one by one, step by step, raise separate PRs fixing and then enforcing):
<module name="HiddenField">
@@ -189,7 +209,7 @@
<module name="IllegalCatch"/>
<module name="com.github.sevntu.checkstyle.checks.coding.AvoidHidingCauseExceptionCheck" />
@@ -215,23 +235,8 @@
<message key="name.invalidPattern"
value="Member name ''{0}'' must match pattern ''{1}''."/>
</module>
<module name="ParameterName">
<property name="format" value="^[a-z][a-z0-9][a-zA-Z0-9]*$"/>
<message key="name.invalidPattern"
value="Parameter name ''{0}'' must match pattern ''{1}''."/>
</module>
<module name="LocalVariableName">
<property name="tokens" value="VARIABLE_DEF"/>
<property name="format" value="^[a-z][a-z0-9][a-zA-Z0-9]*$"/>
<property name="allowOneCharVarInForLoop" value="true"/>
<message key="name.invalidPattern"
value="Local variable name ''{0}'' must match pattern ''{1}''."/>
</module>
<module name="ClassTypeParameterName">
<property name="format" value="(^[A-Z][0-9]?)$|([A-Z][a-zA-Z0-9]*[T]$)"/>
<message key="name.invalidPattern"
value="Class type name ''{0}'' must match pattern ''{1}''."/>
</module>
<module name="ConstantName" />
@@ -0,0 +1,11 @@
{
"groupId": "org.apache.fineract",
"artifactId": "client",
"artifactVersion": "1.4.0",
"invokerPackage": "org.apache.fineract.client",
"modelPackage": "org.apache.fineract.client.models",
"apiPackage": "org.apache.fineract.client.services",
"dateLibrary": "java8",
"hideGenerationTimestamp": "true",
"library": "retrofit2"
}
@@ -0,0 +1,37 @@
openapi: 3.0.3
info:
version: 1.4.0
title: Apache Fineract
description: |-
Apache Fineract is a secure, multi-tenanted microfinance platform
The goal of the Apache Fineract API is to empower developers to build apps on top of the Apache Fineract Platform<br>The [reference app](https://cui.fineract.dev) (username: mifos, password: password) works on the same demo tenant as the interactive links in this documentation
- The API is organized around [REST](https://en.wikipedia.org/wiki/Representational_state_transfer)
- Find out more about Apache Fineract [here](/fineract-provider/api-docs/apiLive.htm#top)
- You can [Try The API From Your Browser](/fineract-provider/api-docs/apiLive.htm#interact)
- The Generic Options are available [here](/fineract-provider/api-docs/apiLive.htm#genopts)
- Find out more about [Updating Dates and Numbers](/fineract-provider/api-docs/apiLive.htm#dates_and_numbers)
- For the Authentication and the Basic of HTTP and HTTPS refer [here](/fineract-provider/api-docs/apiLive.htm#authentication_overview)
- Check about ERROR codes [here](/fineract-provider/api-docs/apiLive.htm#errors)
Please refer to the [old documentation](/fineract-provider/api-docs/apiLive.htm) for any documentation queries
contact:
email: dev@fineract.apache.org
license:
name: Apache 2.0
url: 'http://www.apache.org/licenses/LICENSE-2.0.html'
servers:
- url: https://demo.fineract.dev/fineract-provider/api/v1
components:
securitySchemes:
basicAuth:
type: http
scheme: basic
tenantid:
type: apiKey
in: header
name: fineract-platform-tenantid
security:
- basicAuth: []
tenantid: []
+19 -15
View File
@@ -20,7 +20,7 @@ dependencies {
providedRuntime("org.springframework.boot:spring-boot-starter-tomcat")
spotbugsPlugins "jp.skypencil.findbugs.slf4j:bug-pattern:1.5.0@jar"
spotbugs 'com.github.spotbugs:spotbugs:4.0.4'
spotbugs 'com.github.spotbugs:spotbugs:4.1.1'
// Never use "compile" scope, but make all dependencies either 'implementation', 'runtimeOnly' or 'testCompile'.
// Note that we never use 'api', because Fineract at least currently is a simple monolithic application ("WAR"), not a library.
@@ -46,12 +46,13 @@ dependencies {
'com.sun.jersey.contribs:jersey-multipart',
'joda-time:joda-time',
'com.google.guava:guava',
'com.google.code.gson:gson',
'com.sun.jersey:jersey-core',
'com.squareup.retrofit:retrofit',
'jakarta.jms:jakarta.jms-api',
'jakarta.management.j2ee:jakarta.management.j2ee-api',
'jakarta.validation:jakarta.validation-api',
'com.squareup.okhttp:okhttp',
'com.squareup.okhttp:okhttp-urlconnection',
@@ -70,17 +71,17 @@ dependencies {
'com.github.spullara.mustache.java:compiler',
'com.jayway.jsonpath:json-path',
// JAX-B dependencies for JDK 9+
'jakarta.xml.bind:jakarta.xml.bind-api',
'org.dom4j:dom4j',
// JAX-B dependencies for JDK 9+
'jakarta.xml.bind:jakarta.xml.bind-api',
'javax.cache:cache-api',
'org.dom4j:dom4j',
'com.github.spotbugs:spotbugs-annotations'
)
implementation ('io.swagger:swagger-jersey-jaxrs') {
exclude group: 'javax.validation'
}
'javax.cache:cache-api',
'com.github.spotbugs:spotbugs-annotations',
'io.swagger.core.v3:swagger-annotations',
'org.webjars:webjars-locator-core'
)
implementation ('org.apache.activemq:activemq-broker') {
exclude group: 'org.apache.geronimo.specs'
}
@@ -100,8 +101,9 @@ dependencies {
implementation ('org.mnode.ical4j:ical4j') {
exclude group: 'commons-logging'
}
implementation ('org.ehcache:ehcache') {
exclude group: 'org.glassfish.jaxb', module: 'jaxb-runtime'
runtimeOnly('org.ehcache:ehcache') {
exclude group: 'com.sun.activation'
}
// runtimeOnly dependencies are things that Fineract code has no direct compile time dependency on, but which must be present at run-time
@@ -113,7 +115,7 @@ dependencies {
// Although fineract (at the time of writing) doesn't have any compile time dep. on httpclient,
// it's useful to have this for the Spring Boot TestRestTemplate http://docs.spring.io/spring-boot/docs/current-SNAPSHOT/reference/htmlsingle/#boot-features-rest-templates-test-utility
'org.apache.httpcomponents:httpclient',
)
)
// testCompile dependencies are ONLY used in src/test and/or src/integrationTest, not src/main.
// Do NOT repeat dependencies which are ALREADY in implementation or runtimeOnly!
@@ -123,14 +125,16 @@ dependencies {
'org.junit.platform:junit-platform-runner', // required to be able to run tests directly under Eclipse, see FINERACT-943 & FINERACT-1021
'io.github.classgraph:classgraph',
'org.awaitility:awaitility'
)
)
testImplementation('org.mock-server:mockserver-junit-jupiter') {
exclude group: 'com.sun.mail', module: 'mailapi'
exclude group: 'javax.servlet', module: 'javax.servlet-api'
exclude group: 'javax.validation'
}
testImplementation ('io.rest-assured:rest-assured') {
exclude group: 'commons-logging'
exclude group: 'org.apache.sling'
exclude group: 'com.sun.xml.bind'
}
testImplementation ('org.springframework.boot:spring-boot-starter-test') {
exclude group: 'com.jayway.jsonpath', module: 'json-path'
Binary file not shown.
+1 -1
View File
@@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.5-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-6.6-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
+1 -1
View File
@@ -130,7 +130,7 @@ fi
if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
JAVACMD=`cygpath --unix "$JAVACMD"`
# We build the pattern for arguments to be converted via cygpath
+3 -18
View File
@@ -40,7 +40,7 @@ if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto init
if "%ERRORLEVEL%" == "0" goto execute
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
@@ -54,7 +54,7 @@ goto fail
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto init
if exist "%JAVA_EXE%" goto execute
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
@@ -64,21 +64,6 @@ echo location of your Java installation.
goto fail
:init
@rem Get command-line arguments, handling Windows variants
if not "%OS%" == "Windows_NT" goto win9xME_args
:win9xME_args
@rem Slurp the command line arguments.
set CMD_LINE_ARGS=
set _SKIP=2
:win9xME_args_slurp
if "x%~1" == "x" goto execute
set CMD_LINE_ARGS=%*
:execute
@rem Setup the command line
@@ -86,7 +71,7 @@ set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
:end
@rem End local scope for the variables with windows NT shell
@@ -25,4 +25,3 @@ management.info.git.mode=FULL
# FINERACT-914
server.forward-headers-strategy=framework
spring.cache.jcache.config=classpath:/META-INF/spring/ehcache.xml
@@ -26,4 +26,3 @@ management.info.git.mode=FULL
# FINERACT-914
server.forward-headers-strategy=framework
spring.cache.jcache.config=classpath:/META-INF/spring/ehcache.xml
@@ -74,8 +74,8 @@ public class AccountNumberPreferencesTest {
private Integer savingsAccountNumberPreferenceId;
private Integer groupsAccountNumberPreferenceId;
private Integer centerAccountNumberPreferenceId;
private final String MINIMUM_OPENING_BALANCE = "1000.0";
private final String ACCOUNT_TYPE_INDIVIDUAL = "INDIVIDUAL";
private static final String MINIMUM_OPENING_BALANCE = "1000.0";
private static final String ACCOUNT_TYPE_INDIVIDUAL = "INDIVIDUAL";
private Boolean isAccountPreferenceSetUp = false;
private Integer clientTypeCodeId;
private String clientCodeValueName;
@@ -112,8 +112,7 @@ public class AccountNumberPreferencesTest {
this.deleteAllAccountNumberPreferences();
/*
* Validate the default account number generation rules for clients,
* loans and savings accounts.
* Validate the default account number generation rules for clients, loans and savings accounts.
*/
this.validateDefaultAccountNumberGeneration();
@@ -121,8 +120,7 @@ public class AccountNumberPreferencesTest {
this.createAccountNumberPreference();
/*
* Validate account number preference rules apply to Clients,Loans and
* Saving Accounts
* Validate account number preference rules apply to Clients,Loans and Saving Accounts
*/
this.validateAccountNumberGenerationWithPreferences();
@@ -130,8 +128,7 @@ public class AccountNumberPreferencesTest {
this.updateAccountNumberPreference();
/*
* Validate account number preference rules apply to Clients,Loans and
* Saving Accounts after Updation
* Validate account number preference rules apply to Clients,Loans and Saving Accounts after Updation
*/
this.validateAccountNumberGenerationWithPreferences();
@@ -450,7 +447,7 @@ public class AccountNumberPreferencesTest {
.withMinBalanceForInterestCalculation(minBalanceForInterestCalculation)
//
.withMinRequiredBalance(minRequiredBalance).withEnforceMinRequiredBalance(enforceMinRequiredBalance)
.withMinimumOpenningBalance(this.MINIMUM_OPENING_BALANCE).build();
.withMinimumOpenningBalance(MINIMUM_OPENING_BALANCE).build();
this.savingsProductId = SavingsProductHelper.createSavingsProduct(savingsProductJSON, this.requestSpec, this.responseSpec);
LOG.info("Sucessfully created savings product (ID: {} )", this.savingsProductId);
@@ -80,8 +80,8 @@ public class AccountTransferTest {
private AccountHelper accountHelper;
private JournalEntryHelper journalEntryHelper;
Float TRANSFER_AMOUNT = Float.valueOf(ACCOUNT_TRANSFER_AMOUNT);
Float TRANSFER_AMOUNT_ADJUST = Float.valueOf(ACCOUNT_TRANSFER_AMOUNT_ADJUST);
static Float TRANSFER_AMOUNT = Float.valueOf(ACCOUNT_TRANSFER_AMOUNT);
static Float TRANSFER_AMOUNT_ADJUST = Float.valueOf(ACCOUNT_TRANSFER_AMOUNT_ADJUST);
private FinancialActivityAccountHelper financialActivityAccountHelper;
private Integer financialActivityAccountId;
@@ -74,33 +74,33 @@ public class AccountingScenarioIntegrationTest {
private static RequestSpecification requestSpec;
private static ResponseSpecification responseSpec;
private final String DATE_OF_JOINING = "01 January 2011";
private static final String DATE_OF_JOINING = "01 January 2011";
private final Float LP_PRINCIPAL = 10000.0f;
private final String LP_REPAYMENTS = "5";
private final String LP_REPAYMENT_PERIOD = "2";
private final String LP_INTEREST_RATE = "1";
private final String EXPECTED_DISBURSAL_DATE = "04 March 2011";
private final String LOAN_APPLICATION_SUBMISSION_DATE = "3 March 2011";
private final String TRANSACTION_DATE = "01 March 2013";
private final String LOAN_TERM_FREQUENCY = "10";
private final String INDIVIDUAL_LOAN = "individual";
private static final Float LP_PRINCIPAL = 10000.0f;
private static final String LP_REPAYMENTS = "5";
private static final String LP_REPAYMENT_PERIOD = "2";
private static final String LP_INTEREST_RATE = "1";
private static final String EXPECTED_DISBURSAL_DATE = "04 March 2011";
private static final String LOAN_APPLICATION_SUBMISSION_DATE = "3 March 2011";
private static final String TRANSACTION_DATE = "01 March 2013";
private static final String LOAN_TERM_FREQUENCY = "10";
private static final String INDIVIDUAL_LOAN = "individual";
public static final String ACCOUNT_TYPE_INDIVIDUAL = "INDIVIDUAL";
public static final String MINIMUM_OPENING_BALANCE = "1000.0";
public static final String DEPOSIT_AMOUNT = "7000";
public static final String WITHDRAWAL_AMOUNT = "3000";
public static final String WITHDRAWAL_AMOUNT_ADJUSTED = "2000";
Float SP_BALANCE = Float.valueOf(MINIMUM_OPENING_BALANCE);
Float SP_DEPOSIT_AMOUNT = Float.valueOf(DEPOSIT_AMOUNT);
Float SP_WITHDRAWAL_AMOUNT = Float.valueOf(WITHDRAWAL_AMOUNT);
Float SP_WITHDRAWAL_AMOUNT_ADJUSTED = Float.valueOf(WITHDRAWAL_AMOUNT_ADJUSTED);
static Float SP_BALANCE = Float.valueOf(MINIMUM_OPENING_BALANCE);
static Float SP_DEPOSIT_AMOUNT = Float.valueOf(DEPOSIT_AMOUNT);
static Float SP_WITHDRAWAL_AMOUNT = Float.valueOf(WITHDRAWAL_AMOUNT);
static Float SP_WITHDRAWAL_AMOUNT_ADJUSTED = Float.valueOf(WITHDRAWAL_AMOUNT_ADJUSTED);
private final String[] REPAYMENT_DATE = { "", "04 May 2011", "04 July 2011", "04 September 2011", "04 November 2011",
private static final String[] REPAYMENT_DATE = { "", "04 May 2011", "04 July 2011", "04 September 2011", "04 November 2011",
"04 January 2012" };
private final Float[] REPAYMENT_AMOUNT = { .0f, 2200.0f, 3000.0f, 900.0f, 2000.0f, 2500.0f };
private static final Float[] REPAYMENT_AMOUNT = { .0f, 2200.0f, 3000.0f, 900.0f, 2000.0f, 2500.0f };
private final Float AMOUNT_TO_BE_WAIVE = 400.0f;
private static final Float AMOUNT_TO_BE_WAIVE = 400.0f;
private LoanTransactionHelper loanTransactionHelper;
private AccountHelper accountHelper;
private JournalEntryHelper journalEntryHelper;
@@ -136,17 +136,17 @@ public class AccountingScenarioIntegrationTest {
final Integer loanProductID = createLoanProductWithUpfrontAccrualAccountingEnabled(assetAccount, incomeAccount, expenseAccount,
overpaymentAccount);
final Integer clientID = ClientHelper.createClient(requestSpec, responseSpec, this.DATE_OF_JOINING);
final Integer clientID = ClientHelper.createClient(requestSpec, responseSpec, DATE_OF_JOINING);
final Integer loanID = applyForLoanApplication(clientID, loanProductID);
HashMap loanStatusHashMap = LoanStatusChecker.getStatusOfLoan(requestSpec, responseSpec, loanID);
LoanStatusChecker.verifyLoanIsPending(loanStatusHashMap);
loanStatusHashMap = this.loanTransactionHelper.approveLoan(this.EXPECTED_DISBURSAL_DATE, loanID);
loanStatusHashMap = this.loanTransactionHelper.approveLoan(EXPECTED_DISBURSAL_DATE, loanID);
LoanStatusChecker.verifyLoanIsApproved(loanStatusHashMap);
LoanStatusChecker.verifyLoanIsWaitingForDisbursal(loanStatusHashMap);
loanStatusHashMap = this.loanTransactionHelper.disburseLoan(this.EXPECTED_DISBURSAL_DATE, loanID);
loanStatusHashMap = this.loanTransactionHelper.disburseLoan(EXPECTED_DISBURSAL_DATE, loanID);
LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap);
// CHECK ACCOUNT ENTRIES
@@ -154,84 +154,84 @@ public class AccountingScenarioIntegrationTest {
final float PRINCIPAL_VALUE_FOR_EACH_PERIOD = 2000.0f;
final float TOTAL_INTEREST = 1000.0f;
final JournalEntry[] assetAccountInitialEntry = { new JournalEntry(TOTAL_INTEREST, JournalEntry.TransactionType.DEBIT),
new JournalEntry(this.LP_PRINCIPAL, JournalEntry.TransactionType.CREDIT),
new JournalEntry(this.LP_PRINCIPAL, JournalEntry.TransactionType.DEBIT), };
this.journalEntryHelper.checkJournalEntryForAssetAccount(assetAccount, this.EXPECTED_DISBURSAL_DATE, assetAccountInitialEntry);
new JournalEntry(LP_PRINCIPAL, JournalEntry.TransactionType.CREDIT),
new JournalEntry(LP_PRINCIPAL, JournalEntry.TransactionType.DEBIT), };
this.journalEntryHelper.checkJournalEntryForAssetAccount(assetAccount, EXPECTED_DISBURSAL_DATE, assetAccountInitialEntry);
LOG.info("CHECKING INCOME: ******************************************");
final JournalEntry incomeJournalEntry = new JournalEntry(TOTAL_INTEREST, JournalEntry.TransactionType.CREDIT);
this.journalEntryHelper.checkJournalEntryForIncomeAccount(incomeAccount, this.EXPECTED_DISBURSAL_DATE, incomeJournalEntry);
this.journalEntryHelper.checkJournalEntryForIncomeAccount(incomeAccount, EXPECTED_DISBURSAL_DATE, incomeJournalEntry);
// MAKE 1
LOG.info("Repayment 1 ......");
this.loanTransactionHelper.makeRepayment(this.REPAYMENT_DATE[1], this.REPAYMENT_AMOUNT[1], loanID);
this.loanTransactionHelper.makeRepayment(REPAYMENT_DATE[1], REPAYMENT_AMOUNT[1], loanID);
final float FIRST_INTEREST = 200.0f;
final float FIRST_PRINCIPAL = 2000.0f;
float expected_value = this.LP_PRINCIPAL - PRINCIPAL_VALUE_FOR_EACH_PERIOD;
float expected_value = LP_PRINCIPAL - PRINCIPAL_VALUE_FOR_EACH_PERIOD;
this.loanTransactionHelper.verifyRepaymentScheduleEntryFor(1, expected_value, loanID);
final JournalEntry[] assetAccountFirstEntry = { new JournalEntry(this.REPAYMENT_AMOUNT[1], JournalEntry.TransactionType.DEBIT),
final JournalEntry[] assetAccountFirstEntry = { new JournalEntry(REPAYMENT_AMOUNT[1], JournalEntry.TransactionType.DEBIT),
new JournalEntry(FIRST_INTEREST + FIRST_PRINCIPAL, JournalEntry.TransactionType.CREDIT) };
this.journalEntryHelper.checkJournalEntryForAssetAccount(assetAccount, this.REPAYMENT_DATE[1], assetAccountFirstEntry);
this.journalEntryHelper.checkJournalEntryForAssetAccount(assetAccount, REPAYMENT_DATE[1], assetAccountFirstEntry);
LOG.info("Repayment 1 Done......");
// REPAYMENT 2
LOG.info("Repayment 2 ......");
this.loanTransactionHelper.makeRepayment(this.REPAYMENT_DATE[2], this.REPAYMENT_AMOUNT[2], loanID);
this.loanTransactionHelper.makeRepayment(REPAYMENT_DATE[2], REPAYMENT_AMOUNT[2], loanID);
final float SECOND_AND_THIRD_INTEREST = 400.0f;
final float SECOND_PRINCIPAL = this.REPAYMENT_AMOUNT[2] - SECOND_AND_THIRD_INTEREST;
final float SECOND_PRINCIPAL = REPAYMENT_AMOUNT[2] - SECOND_AND_THIRD_INTEREST;
expected_value = expected_value - PRINCIPAL_VALUE_FOR_EACH_PERIOD;
this.loanTransactionHelper.verifyRepaymentScheduleEntryFor(2, expected_value, loanID);
final JournalEntry[] assetAccountSecondEntry = { new JournalEntry(this.REPAYMENT_AMOUNT[2], JournalEntry.TransactionType.DEBIT),
final JournalEntry[] assetAccountSecondEntry = { new JournalEntry(REPAYMENT_AMOUNT[2], JournalEntry.TransactionType.DEBIT),
new JournalEntry(SECOND_AND_THIRD_INTEREST + SECOND_PRINCIPAL, JournalEntry.TransactionType.CREDIT) };
this.journalEntryHelper.checkJournalEntryForAssetAccount(assetAccount, this.REPAYMENT_DATE[2], assetAccountSecondEntry);
this.journalEntryHelper.checkJournalEntryForAssetAccount(assetAccount, REPAYMENT_DATE[2], assetAccountSecondEntry);
LOG.info("Repayment 2 Done ......");
// WAIVE INTEREST
LOG.info("Waive Interest ......");
this.loanTransactionHelper.waiveInterest(this.REPAYMENT_DATE[4], this.AMOUNT_TO_BE_WAIVE.toString(), loanID);
this.loanTransactionHelper.waiveInterest(REPAYMENT_DATE[4], AMOUNT_TO_BE_WAIVE.toString(), loanID);
final JournalEntry waivedEntry = new JournalEntry(this.AMOUNT_TO_BE_WAIVE, JournalEntry.TransactionType.CREDIT);
this.journalEntryHelper.checkJournalEntryForAssetAccount(assetAccount, this.REPAYMENT_DATE[4], waivedEntry);
final JournalEntry waivedEntry = new JournalEntry(AMOUNT_TO_BE_WAIVE, JournalEntry.TransactionType.CREDIT);
this.journalEntryHelper.checkJournalEntryForAssetAccount(assetAccount, REPAYMENT_DATE[4], waivedEntry);
final JournalEntry expenseJournalEntry = new JournalEntry(this.AMOUNT_TO_BE_WAIVE, JournalEntry.TransactionType.DEBIT);
this.journalEntryHelper.checkJournalEntryForExpenseAccount(expenseAccount, this.REPAYMENT_DATE[4], expenseJournalEntry);
final JournalEntry expenseJournalEntry = new JournalEntry(AMOUNT_TO_BE_WAIVE, JournalEntry.TransactionType.DEBIT);
this.journalEntryHelper.checkJournalEntryForExpenseAccount(expenseAccount, REPAYMENT_DATE[4], expenseJournalEntry);
LOG.info("Waive Interest Done......");
// REPAYMENT 3
LOG.info("Repayment 3 ......");
this.loanTransactionHelper.makeRepayment(this.REPAYMENT_DATE[3], this.REPAYMENT_AMOUNT[3], loanID);
this.loanTransactionHelper.makeRepayment(REPAYMENT_DATE[3], REPAYMENT_AMOUNT[3], loanID);
expected_value = expected_value - PRINCIPAL_VALUE_FOR_EACH_PERIOD;
final JournalEntry[] assetAccountThirdEntry = { new JournalEntry(this.REPAYMENT_AMOUNT[3], JournalEntry.TransactionType.DEBIT),
new JournalEntry(this.REPAYMENT_AMOUNT[3], JournalEntry.TransactionType.CREDIT) };
final JournalEntry[] assetAccountThirdEntry = { new JournalEntry(REPAYMENT_AMOUNT[3], JournalEntry.TransactionType.DEBIT),
new JournalEntry(REPAYMENT_AMOUNT[3], JournalEntry.TransactionType.CREDIT) };
this.loanTransactionHelper.verifyRepaymentScheduleEntryFor(3, expected_value, loanID);
this.journalEntryHelper.checkJournalEntryForAssetAccount(assetAccount, this.REPAYMENT_DATE[3], assetAccountThirdEntry);
this.journalEntryHelper.checkJournalEntryForAssetAccount(assetAccount, REPAYMENT_DATE[3], assetAccountThirdEntry);
LOG.info("Repayment 3 Done ......");
// REPAYMENT 4
LOG.info("Repayment 4 ......");
this.loanTransactionHelper.makeRepayment(this.REPAYMENT_DATE[4], this.REPAYMENT_AMOUNT[4], loanID);
this.loanTransactionHelper.makeRepayment(REPAYMENT_DATE[4], REPAYMENT_AMOUNT[4], loanID);
expected_value = expected_value - PRINCIPAL_VALUE_FOR_EACH_PERIOD;
this.loanTransactionHelper.verifyRepaymentScheduleEntryFor(4, expected_value, loanID);
final JournalEntry[] assetAccountFourthEntry = { new JournalEntry(this.REPAYMENT_AMOUNT[4], JournalEntry.TransactionType.DEBIT),
new JournalEntry(this.REPAYMENT_AMOUNT[4], JournalEntry.TransactionType.CREDIT) };
this.journalEntryHelper.checkJournalEntryForAssetAccount(assetAccount, this.REPAYMENT_DATE[4], assetAccountFourthEntry);
final JournalEntry[] assetAccountFourthEntry = { new JournalEntry(REPAYMENT_AMOUNT[4], JournalEntry.TransactionType.DEBIT),
new JournalEntry(REPAYMENT_AMOUNT[4], JournalEntry.TransactionType.CREDIT) };
this.journalEntryHelper.checkJournalEntryForAssetAccount(assetAccount, REPAYMENT_DATE[4], assetAccountFourthEntry);
LOG.info("Repayment 4 Done ......");
// Repayment 5
LOG.info("Repayment 5 ......");
final JournalEntry[] assetAccountFifthEntry = { new JournalEntry(this.REPAYMENT_AMOUNT[5], JournalEntry.TransactionType.DEBIT),
new JournalEntry(this.REPAYMENT_AMOUNT[5], JournalEntry.TransactionType.CREDIT) };
final JournalEntry[] assetAccountFifthEntry = { new JournalEntry(REPAYMENT_AMOUNT[5], JournalEntry.TransactionType.DEBIT),
new JournalEntry(REPAYMENT_AMOUNT[5], JournalEntry.TransactionType.CREDIT) };
expected_value = expected_value - PRINCIPAL_VALUE_FOR_EACH_PERIOD;
this.loanTransactionHelper.makeRepayment(this.REPAYMENT_DATE[5], this.REPAYMENT_AMOUNT[5], loanID);
this.loanTransactionHelper.makeRepayment(REPAYMENT_DATE[5], REPAYMENT_AMOUNT[5], loanID);
this.loanTransactionHelper.verifyRepaymentScheduleEntryFor(5, expected_value, loanID);
this.journalEntryHelper.checkJournalEntryForAssetAccount(assetAccount, this.REPAYMENT_DATE[5], assetAccountFifthEntry);
this.journalEntryHelper.checkJournalEntryForAssetAccount(assetAccount, REPAYMENT_DATE[5], assetAccountFifthEntry);
LOG.info("Repayment 5 Done ......");
}
private Integer createLoanProductWithUpfrontAccrualAccountingEnabled(final Account... accounts) {
LOG.info("------------------------------CREATING NEW LOAN PRODUCT ---------------------------------------");
final String loanProductJSON = new LoanProductTestBuilder().withPrincipal(this.LP_PRINCIPAL.toString()).withRepaymentTypeAsMonth()
.withRepaymentAfterEvery(this.LP_REPAYMENT_PERIOD).withNumberOfRepayments(this.LP_REPAYMENTS).withRepaymentTypeAsMonth()
.withinterestRatePerPeriod(this.LP_INTEREST_RATE).withInterestRateFrequencyTypeAsMonths()
final String loanProductJSON = new LoanProductTestBuilder().withPrincipal(LP_PRINCIPAL.toString()).withRepaymentTypeAsMonth()
.withRepaymentAfterEvery(LP_REPAYMENT_PERIOD).withNumberOfRepayments(LP_REPAYMENTS).withRepaymentTypeAsMonth()
.withinterestRatePerPeriod(LP_INTEREST_RATE).withInterestRateFrequencyTypeAsMonths()
.withAmortizationTypeAsEqualPrincipalPayment().withInterestTypeAsFlat().withAccountingRuleUpfrontAccrual(accounts)
.build(null);
return this.loanTransactionHelper.getLoanProductId(loanProductJSON);
@@ -239,13 +239,13 @@ public class AccountingScenarioIntegrationTest {
private Integer applyForLoanApplication(final Integer clientID, final Integer loanProductID) {
LOG.info("--------------------------------APPLYING FOR LOAN APPLICATION--------------------------------");
final String loanApplicationJSON = new LoanApplicationTestBuilder().withPrincipal(this.LP_PRINCIPAL.toString())
.withLoanTermFrequency(this.LOAN_TERM_FREQUENCY).withLoanTermFrequencyAsMonths().withNumberOfRepayments(this.LP_REPAYMENTS)
.withRepaymentEveryAfter(this.LP_REPAYMENT_PERIOD).withRepaymentFrequencyTypeAsMonths()
.withInterestRatePerPeriod(this.LP_INTEREST_RATE).withInterestTypeAsFlatBalance()
.withAmortizationTypeAsEqualPrincipalPayments().withInterestCalculationPeriodTypeSameAsRepaymentPeriod()
.withExpectedDisbursementDate(this.EXPECTED_DISBURSAL_DATE).withSubmittedOnDate(this.LOAN_APPLICATION_SUBMISSION_DATE)
.withLoanType(this.INDIVIDUAL_LOAN).build(clientID.toString(), loanProductID.toString(), null);
final String loanApplicationJSON = new LoanApplicationTestBuilder().withPrincipal(LP_PRINCIPAL.toString())
.withLoanTermFrequency(LOAN_TERM_FREQUENCY).withLoanTermFrequencyAsMonths().withNumberOfRepayments(LP_REPAYMENTS)
.withRepaymentEveryAfter(LP_REPAYMENT_PERIOD).withRepaymentFrequencyTypeAsMonths()
.withInterestRatePerPeriod(LP_INTEREST_RATE).withInterestTypeAsFlatBalance().withAmortizationTypeAsEqualPrincipalPayments()
.withInterestCalculationPeriodTypeSameAsRepaymentPeriod().withExpectedDisbursementDate(EXPECTED_DISBURSAL_DATE)
.withSubmittedOnDate(LOAN_APPLICATION_SUBMISSION_DATE).withLoanType(INDIVIDUAL_LOAN)
.build(clientID.toString(), loanProductID.toString(), null);
return this.loanTransactionHelper.getLoanId(loanApplicationJSON);
}
@@ -261,7 +261,7 @@ public class AccountingScenarioIntegrationTest {
final Integer savingsProductID = createSavingsProduct(MINIMUM_OPENING_BALANCE, assetAccount, incomeAccount, expenseAccount,
liabilityAccount);
final Integer clientID = ClientHelper.createClient(requestSpec, responseSpec, this.DATE_OF_JOINING);
final Integer clientID = ClientHelper.createClient(requestSpec, responseSpec, DATE_OF_JOINING);
final Integer savingsID = this.savingsAccountHelper.applyForSavingsApplication(clientID, savingsProductID, ACCOUNT_TYPE_INDIVIDUAL);
HashMap savingsStatusHashMap = SavingsStatusChecker.getStatusOfSavings(requestSpec, responseSpec, savingsID);
@@ -274,11 +274,10 @@ public class AccountingScenarioIntegrationTest {
SavingsStatusChecker.verifySavingsIsActive(savingsStatusHashMap);
// Checking initial Account entries.
final JournalEntry[] assetAccountInitialEntry = { new JournalEntry(this.SP_BALANCE, JournalEntry.TransactionType.DEBIT) };
final JournalEntry[] liablilityAccountInitialEntry = { new JournalEntry(this.SP_BALANCE, JournalEntry.TransactionType.CREDIT) };
this.journalEntryHelper.checkJournalEntryForAssetAccount(assetAccount, this.TRANSACTION_DATE, assetAccountInitialEntry);
this.journalEntryHelper.checkJournalEntryForLiabilityAccount(liabilityAccount, this.TRANSACTION_DATE,
liablilityAccountInitialEntry);
final JournalEntry[] assetAccountInitialEntry = { new JournalEntry(SP_BALANCE, JournalEntry.TransactionType.DEBIT) };
final JournalEntry[] liablilityAccountInitialEntry = { new JournalEntry(SP_BALANCE, JournalEntry.TransactionType.CREDIT) };
this.journalEntryHelper.checkJournalEntryForAssetAccount(assetAccount, TRANSACTION_DATE, assetAccountInitialEntry);
this.journalEntryHelper.checkJournalEntryForLiabilityAccount(liabilityAccount, TRANSACTION_DATE, liablilityAccountInitialEntry);
// First Transaction-Deposit
this.savingsAccountHelper.depositToSavingsAccount(savingsID, DEPOSIT_AMOUNT, SavingsAccountHelper.TRANSACTION_DATE,
@@ -289,11 +288,11 @@ public class AccountingScenarioIntegrationTest {
LOG.info("----------------------Verifying Journal Entry after the Transaction Deposit----------------------------");
final JournalEntry[] assetAccountFirstTransactionEntry = {
new JournalEntry(this.SP_DEPOSIT_AMOUNT, JournalEntry.TransactionType.DEBIT) };
new JournalEntry(SP_DEPOSIT_AMOUNT, JournalEntry.TransactionType.DEBIT) };
final JournalEntry[] liabililityAccountFirstTransactionEntry = {
new JournalEntry(this.SP_DEPOSIT_AMOUNT, JournalEntry.TransactionType.CREDIT) };
this.journalEntryHelper.checkJournalEntryForAssetAccount(assetAccount, this.TRANSACTION_DATE, assetAccountFirstTransactionEntry);
this.journalEntryHelper.checkJournalEntryForLiabilityAccount(liabilityAccount, this.TRANSACTION_DATE,
new JournalEntry(SP_DEPOSIT_AMOUNT, JournalEntry.TransactionType.CREDIT) };
this.journalEntryHelper.checkJournalEntryForAssetAccount(assetAccount, TRANSACTION_DATE, assetAccountFirstTransactionEntry);
this.journalEntryHelper.checkJournalEntryForLiabilityAccount(liabilityAccount, TRANSACTION_DATE,
liabililityAccountFirstTransactionEntry);
// Second Transaction-Withdrawal
@@ -305,11 +304,11 @@ public class AccountingScenarioIntegrationTest {
LOG.info("-------------------Verifying Journal Entry after the Transaction Withdrawal----------------------");
final JournalEntry[] assetAccountSecondTransactionEntry = {
new JournalEntry(this.SP_WITHDRAWAL_AMOUNT, JournalEntry.TransactionType.CREDIT) };
new JournalEntry(SP_WITHDRAWAL_AMOUNT, JournalEntry.TransactionType.CREDIT) };
final JournalEntry[] liabililityAccountSecondTransactionEntry = {
new JournalEntry(this.SP_WITHDRAWAL_AMOUNT, JournalEntry.TransactionType.DEBIT) };
this.journalEntryHelper.checkJournalEntryForAssetAccount(assetAccount, this.TRANSACTION_DATE, assetAccountSecondTransactionEntry);
this.journalEntryHelper.checkJournalEntryForLiabilityAccount(liabilityAccount, this.TRANSACTION_DATE,
new JournalEntry(SP_WITHDRAWAL_AMOUNT, JournalEntry.TransactionType.DEBIT) };
this.journalEntryHelper.checkJournalEntryForAssetAccount(assetAccount, TRANSACTION_DATE, assetAccountSecondTransactionEntry);
this.journalEntryHelper.checkJournalEntryForLiabilityAccount(liabilityAccount, TRANSACTION_DATE,
liabililityAccountSecondTransactionEntry);
// Third Transaction-Add Charges for Withdrawal Fee
@@ -331,14 +330,14 @@ public class AccountingScenarioIntegrationTest {
balance = balance - SP_WITHDRAWAL_AMOUNT_ADJUSTED - chargeAmount;
final JournalEntry[] liabililityAccountThirdTransactionEntry = { new JournalEntry(chargeAmount, JournalEntry.TransactionType.DEBIT),
new JournalEntry(this.SP_WITHDRAWAL_AMOUNT_ADJUSTED, JournalEntry.TransactionType.DEBIT) };
new JournalEntry(SP_WITHDRAWAL_AMOUNT_ADJUSTED, JournalEntry.TransactionType.DEBIT) };
final JournalEntry[] assetAccountThirdTransactionEntry = {
new JournalEntry(this.SP_WITHDRAWAL_AMOUNT_ADJUSTED, JournalEntry.TransactionType.CREDIT) };
new JournalEntry(SP_WITHDRAWAL_AMOUNT_ADJUSTED, JournalEntry.TransactionType.CREDIT) };
final JournalEntry[] incomeAccountThirdTransactionEntry = { new JournalEntry(chargeAmount, JournalEntry.TransactionType.CREDIT) };
this.journalEntryHelper.checkJournalEntryForAssetAccount(assetAccount, this.TRANSACTION_DATE, assetAccountThirdTransactionEntry);
this.journalEntryHelper.checkJournalEntryForLiabilityAccount(liabilityAccount, this.TRANSACTION_DATE,
this.journalEntryHelper.checkJournalEntryForAssetAccount(assetAccount, TRANSACTION_DATE, assetAccountThirdTransactionEntry);
this.journalEntryHelper.checkJournalEntryForLiabilityAccount(liabilityAccount, TRANSACTION_DATE,
liabililityAccountThirdTransactionEntry);
this.journalEntryHelper.checkJournalEntryForIncomeAccount(incomeAccount, this.TRANSACTION_DATE, incomeAccountThirdTransactionEntry);
this.journalEntryHelper.checkJournalEntryForIncomeAccount(incomeAccount, TRANSACTION_DATE, incomeAccountThirdTransactionEntry);
// Verifying Balance after applying Charge for Withdrawal Fee
assertEquals(balance, summary.get("accountBalance"), "Verifying Balance");
@@ -563,26 +562,26 @@ public class AccountingScenarioIntegrationTest {
final Integer loanProductID = createLoanProductWithPeriodicAccrualAccountingEnabled(assetAccount, incomeAccount, expenseAccount,
overpaymentAccount);
final Integer clientID = ClientHelper.createClient(requestSpec, responseSpec, this.DATE_OF_JOINING);
final Integer clientID = ClientHelper.createClient(requestSpec, responseSpec, DATE_OF_JOINING);
final Integer loanID = applyForLoanApplication(clientID, loanProductID);
HashMap loanStatusHashMap = LoanStatusChecker.getStatusOfLoan(requestSpec, responseSpec, loanID);
LoanStatusChecker.verifyLoanIsPending(loanStatusHashMap);
loanStatusHashMap = this.loanTransactionHelper.approveLoan(this.EXPECTED_DISBURSAL_DATE, loanID);
loanStatusHashMap = this.loanTransactionHelper.approveLoan(EXPECTED_DISBURSAL_DATE, loanID);
LoanStatusChecker.verifyLoanIsApproved(loanStatusHashMap);
LoanStatusChecker.verifyLoanIsWaitingForDisbursal(loanStatusHashMap);
loanStatusHashMap = this.loanTransactionHelper.disburseLoan(this.EXPECTED_DISBURSAL_DATE, loanID);
loanStatusHashMap = this.loanTransactionHelper.disburseLoan(EXPECTED_DISBURSAL_DATE, loanID);
LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap);
// CHECK ACCOUNT ENTRIES
LOG.info("Entries ......");
final float PRINCIPAL_VALUE_FOR_EACH_PERIOD = 2000.0f;
final float TOTAL_INTEREST = 1000.0f;
final JournalEntry[] assetAccountInitialEntry = { new JournalEntry(this.LP_PRINCIPAL, JournalEntry.TransactionType.CREDIT),
new JournalEntry(this.LP_PRINCIPAL, JournalEntry.TransactionType.DEBIT), };
this.journalEntryHelper.checkJournalEntryForAssetAccount(assetAccount, this.EXPECTED_DISBURSAL_DATE, assetAccountInitialEntry);
final JournalEntry[] assetAccountInitialEntry = { new JournalEntry(LP_PRINCIPAL, JournalEntry.TransactionType.CREDIT),
new JournalEntry(LP_PRINCIPAL, JournalEntry.TransactionType.DEBIT), };
this.journalEntryHelper.checkJournalEntryForAssetAccount(assetAccount, EXPECTED_DISBURSAL_DATE, assetAccountInitialEntry);
final String jobName = "Add Accrual Transactions";
@@ -594,75 +593,75 @@ public class AccountingScenarioIntegrationTest {
final float FIRST_PRINCIPAL = 2000.0f;
final float FEE_PORTION = 0.0f;
final float PENALTY_PORTION = 0.0f;
this.loanTransactionHelper.checkAccrualTransactionForRepayment(getDateAsLocalDate(this.REPAYMENT_DATE[1]), FIRST_INTEREST,
FEE_PORTION, PENALTY_PORTION, loanID);
this.loanTransactionHelper.makeRepayment(this.REPAYMENT_DATE[1], this.REPAYMENT_AMOUNT[1], loanID);
float expected_value = this.LP_PRINCIPAL - PRINCIPAL_VALUE_FOR_EACH_PERIOD;
this.loanTransactionHelper.checkAccrualTransactionForRepayment(getDateAsLocalDate(REPAYMENT_DATE[1]), FIRST_INTEREST, FEE_PORTION,
PENALTY_PORTION, loanID);
this.loanTransactionHelper.makeRepayment(REPAYMENT_DATE[1], REPAYMENT_AMOUNT[1], loanID);
float expected_value = LP_PRINCIPAL - PRINCIPAL_VALUE_FOR_EACH_PERIOD;
this.loanTransactionHelper.verifyRepaymentScheduleEntryFor(1, expected_value, loanID);
final JournalEntry[] assetAccountFirstEntry = { new JournalEntry(this.REPAYMENT_AMOUNT[1], JournalEntry.TransactionType.DEBIT),
final JournalEntry[] assetAccountFirstEntry = { new JournalEntry(REPAYMENT_AMOUNT[1], JournalEntry.TransactionType.DEBIT),
new JournalEntry(FIRST_INTEREST + FIRST_PRINCIPAL, JournalEntry.TransactionType.CREDIT) };
this.journalEntryHelper.checkJournalEntryForAssetAccount(assetAccount, this.REPAYMENT_DATE[1], assetAccountFirstEntry);
this.journalEntryHelper.checkJournalEntryForAssetAccount(assetAccount, REPAYMENT_DATE[1], assetAccountFirstEntry);
LOG.info("Repayment 1 Done......");
// REPAYMENT 2
LOG.info("Repayment 2 ......");
this.loanTransactionHelper.makeRepayment(this.REPAYMENT_DATE[2], this.REPAYMENT_AMOUNT[2], loanID);
this.loanTransactionHelper.makeRepayment(REPAYMENT_DATE[2], REPAYMENT_AMOUNT[2], loanID);
final float SECOND_AND_THIRD_INTEREST = 400.0f;
final float SECOND_PRINCIPAL = this.REPAYMENT_AMOUNT[2] - SECOND_AND_THIRD_INTEREST;
final float SECOND_PRINCIPAL = REPAYMENT_AMOUNT[2] - SECOND_AND_THIRD_INTEREST;
expected_value = expected_value - PRINCIPAL_VALUE_FOR_EACH_PERIOD;
this.loanTransactionHelper.checkAccrualTransactionForRepayment(getDateAsLocalDate(this.REPAYMENT_DATE[2]), FIRST_INTEREST,
FEE_PORTION, PENALTY_PORTION, loanID);
this.loanTransactionHelper.checkAccrualTransactionForRepayment(getDateAsLocalDate(this.REPAYMENT_DATE[3]), FIRST_INTEREST,
FEE_PORTION, PENALTY_PORTION, loanID);
this.loanTransactionHelper.checkAccrualTransactionForRepayment(getDateAsLocalDate(REPAYMENT_DATE[2]), FIRST_INTEREST, FEE_PORTION,
PENALTY_PORTION, loanID);
this.loanTransactionHelper.checkAccrualTransactionForRepayment(getDateAsLocalDate(REPAYMENT_DATE[3]), FIRST_INTEREST, FEE_PORTION,
PENALTY_PORTION, loanID);
this.loanTransactionHelper.verifyRepaymentScheduleEntryFor(2, expected_value, loanID);
final JournalEntry[] assetAccountSecondEntry = { new JournalEntry(this.REPAYMENT_AMOUNT[2], JournalEntry.TransactionType.DEBIT),
final JournalEntry[] assetAccountSecondEntry = { new JournalEntry(REPAYMENT_AMOUNT[2], JournalEntry.TransactionType.DEBIT),
new JournalEntry(SECOND_AND_THIRD_INTEREST + SECOND_PRINCIPAL, JournalEntry.TransactionType.CREDIT) };
this.journalEntryHelper.checkJournalEntryForAssetAccount(assetAccount, this.REPAYMENT_DATE[2], assetAccountSecondEntry);
this.journalEntryHelper.checkJournalEntryForAssetAccount(assetAccount, REPAYMENT_DATE[2], assetAccountSecondEntry);
LOG.info("Repayment 2 Done ......");
// WAIVE INTEREST
LOG.info("Waive Interest ......");
this.loanTransactionHelper.checkAccrualTransactionForRepayment(getDateAsLocalDate(this.REPAYMENT_DATE[4]), FIRST_INTEREST,
FEE_PORTION, PENALTY_PORTION, loanID);
this.loanTransactionHelper.checkAccrualTransactionForRepayment(getDateAsLocalDate(this.REPAYMENT_DATE[5]), FIRST_INTEREST,
FEE_PORTION, PENALTY_PORTION, loanID);
this.loanTransactionHelper.waiveInterest(this.REPAYMENT_DATE[4], this.AMOUNT_TO_BE_WAIVE.toString(), loanID);
this.loanTransactionHelper.checkAccrualTransactionForRepayment(getDateAsLocalDate(REPAYMENT_DATE[4]), FIRST_INTEREST, FEE_PORTION,
PENALTY_PORTION, loanID);
this.loanTransactionHelper.checkAccrualTransactionForRepayment(getDateAsLocalDate(REPAYMENT_DATE[5]), FIRST_INTEREST, FEE_PORTION,
PENALTY_PORTION, loanID);
this.loanTransactionHelper.waiveInterest(REPAYMENT_DATE[4], AMOUNT_TO_BE_WAIVE.toString(), loanID);
final JournalEntry waivedEntry = new JournalEntry(this.AMOUNT_TO_BE_WAIVE, JournalEntry.TransactionType.CREDIT);
this.journalEntryHelper.checkJournalEntryForAssetAccount(assetAccount, this.REPAYMENT_DATE[4], waivedEntry);
final JournalEntry waivedEntry = new JournalEntry(AMOUNT_TO_BE_WAIVE, JournalEntry.TransactionType.CREDIT);
this.journalEntryHelper.checkJournalEntryForAssetAccount(assetAccount, REPAYMENT_DATE[4], waivedEntry);
final JournalEntry expenseJournalEntry = new JournalEntry(this.AMOUNT_TO_BE_WAIVE, JournalEntry.TransactionType.DEBIT);
this.journalEntryHelper.checkJournalEntryForExpenseAccount(expenseAccount, this.REPAYMENT_DATE[4], expenseJournalEntry);
final JournalEntry expenseJournalEntry = new JournalEntry(AMOUNT_TO_BE_WAIVE, JournalEntry.TransactionType.DEBIT);
this.journalEntryHelper.checkJournalEntryForExpenseAccount(expenseAccount, REPAYMENT_DATE[4], expenseJournalEntry);
LOG.info("Waive Interest Done......");
// REPAYMENT 3
LOG.info("Repayment 3 ......");
this.loanTransactionHelper.makeRepayment(this.REPAYMENT_DATE[3], this.REPAYMENT_AMOUNT[3], loanID);
this.loanTransactionHelper.makeRepayment(REPAYMENT_DATE[3], REPAYMENT_AMOUNT[3], loanID);
expected_value = expected_value - PRINCIPAL_VALUE_FOR_EACH_PERIOD;
final JournalEntry[] assetAccountThirdEntry = { new JournalEntry(this.REPAYMENT_AMOUNT[3], JournalEntry.TransactionType.DEBIT),
new JournalEntry(this.REPAYMENT_AMOUNT[3], JournalEntry.TransactionType.CREDIT) };
final JournalEntry[] assetAccountThirdEntry = { new JournalEntry(REPAYMENT_AMOUNT[3], JournalEntry.TransactionType.DEBIT),
new JournalEntry(REPAYMENT_AMOUNT[3], JournalEntry.TransactionType.CREDIT) };
this.loanTransactionHelper.verifyRepaymentScheduleEntryFor(3, expected_value, loanID);
this.journalEntryHelper.checkJournalEntryForAssetAccount(assetAccount, this.REPAYMENT_DATE[3], assetAccountThirdEntry);
this.journalEntryHelper.checkJournalEntryForAssetAccount(assetAccount, REPAYMENT_DATE[3], assetAccountThirdEntry);
LOG.info("Repayment 3 Done ......");
// REPAYMENT 4
LOG.info("Repayment 4 ......");
this.loanTransactionHelper.makeRepayment(this.REPAYMENT_DATE[4], this.REPAYMENT_AMOUNT[4], loanID);
this.loanTransactionHelper.makeRepayment(REPAYMENT_DATE[4], REPAYMENT_AMOUNT[4], loanID);
expected_value = expected_value - PRINCIPAL_VALUE_FOR_EACH_PERIOD;
this.loanTransactionHelper.verifyRepaymentScheduleEntryFor(4, expected_value, loanID);
final JournalEntry[] assetAccountFourthEntry = { new JournalEntry(this.REPAYMENT_AMOUNT[4], JournalEntry.TransactionType.DEBIT),
new JournalEntry(this.REPAYMENT_AMOUNT[4], JournalEntry.TransactionType.CREDIT) };
this.journalEntryHelper.checkJournalEntryForAssetAccount(assetAccount, this.REPAYMENT_DATE[4], assetAccountFourthEntry);
final JournalEntry[] assetAccountFourthEntry = { new JournalEntry(REPAYMENT_AMOUNT[4], JournalEntry.TransactionType.DEBIT),
new JournalEntry(REPAYMENT_AMOUNT[4], JournalEntry.TransactionType.CREDIT) };
this.journalEntryHelper.checkJournalEntryForAssetAccount(assetAccount, REPAYMENT_DATE[4], assetAccountFourthEntry);
LOG.info("Repayment 4 Done ......");
// Repayment 5
LOG.info("Repayment 5 ......");
final JournalEntry[] assetAccountFifthEntry = { new JournalEntry(this.REPAYMENT_AMOUNT[5], JournalEntry.TransactionType.DEBIT),
new JournalEntry(this.REPAYMENT_AMOUNT[5], JournalEntry.TransactionType.CREDIT) };
final JournalEntry[] assetAccountFifthEntry = { new JournalEntry(REPAYMENT_AMOUNT[5], JournalEntry.TransactionType.DEBIT),
new JournalEntry(REPAYMENT_AMOUNT[5], JournalEntry.TransactionType.CREDIT) };
expected_value = expected_value - PRINCIPAL_VALUE_FOR_EACH_PERIOD;
this.loanTransactionHelper.makeRepayment(this.REPAYMENT_DATE[5], this.REPAYMENT_AMOUNT[5], loanID);
this.loanTransactionHelper.makeRepayment(REPAYMENT_DATE[5], REPAYMENT_AMOUNT[5], loanID);
this.loanTransactionHelper.verifyRepaymentScheduleEntryFor(5, expected_value, loanID);
this.journalEntryHelper.checkJournalEntryForAssetAccount(assetAccount, this.REPAYMENT_DATE[5], assetAccountFifthEntry);
this.journalEntryHelper.checkJournalEntryForAssetAccount(assetAccount, REPAYMENT_DATE[5], assetAccountFifthEntry);
LOG.info("Repayment 5 Done ......");
}
@@ -676,26 +675,26 @@ public class AccountingScenarioIntegrationTest {
final Integer loanProductID = createLoanProductWithPeriodicAccrualAccountingEnabled(assetAccount, incomeAccount, expenseAccount,
overpaymentAccount);
final Integer clientID = ClientHelper.createClient(requestSpec, responseSpec, this.DATE_OF_JOINING);
final Integer clientID = ClientHelper.createClient(requestSpec, responseSpec, DATE_OF_JOINING);
final Integer loanID = applyForLoanApplication(clientID, loanProductID);
HashMap loanStatusHashMap = LoanStatusChecker.getStatusOfLoan(requestSpec, responseSpec, loanID);
LoanStatusChecker.verifyLoanIsPending(loanStatusHashMap);
loanStatusHashMap = this.loanTransactionHelper.approveLoan(this.EXPECTED_DISBURSAL_DATE, loanID);
loanStatusHashMap = this.loanTransactionHelper.approveLoan(EXPECTED_DISBURSAL_DATE, loanID);
LoanStatusChecker.verifyLoanIsApproved(loanStatusHashMap);
LoanStatusChecker.verifyLoanIsWaitingForDisbursal(loanStatusHashMap);
loanStatusHashMap = this.loanTransactionHelper.disburseLoan(this.EXPECTED_DISBURSAL_DATE, loanID);
loanStatusHashMap = this.loanTransactionHelper.disburseLoan(EXPECTED_DISBURSAL_DATE, loanID);
LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap);
// CHECK ACCOUNT ENTRIES
LOG.info("Entries ......");
final float PRINCIPAL_VALUE_FOR_EACH_PERIOD = 2000.0f;
final float TOTAL_INTEREST = 1000.0f;
final JournalEntry[] assetAccountInitialEntry = { new JournalEntry(this.LP_PRINCIPAL, JournalEntry.TransactionType.CREDIT),
new JournalEntry(this.LP_PRINCIPAL, JournalEntry.TransactionType.DEBIT), };
this.journalEntryHelper.checkJournalEntryForAssetAccount(assetAccount, this.EXPECTED_DISBURSAL_DATE, assetAccountInitialEntry);
final JournalEntry[] assetAccountInitialEntry = { new JournalEntry(LP_PRINCIPAL, JournalEntry.TransactionType.CREDIT),
new JournalEntry(LP_PRINCIPAL, JournalEntry.TransactionType.DEBIT), };
this.journalEntryHelper.checkJournalEntryForAssetAccount(assetAccount, EXPECTED_DISBURSAL_DATE, assetAccountInitialEntry);
final String jobName = "Add Accrual Transactions";
@@ -707,15 +706,15 @@ public class AccountingScenarioIntegrationTest {
final float FIRST_PRINCIPAL = 2000.0f;
final float FEE_PORTION = 0.0f;
final float PENALTY_PORTION = 0.0f;
this.loanTransactionHelper.checkAccrualTransactionForRepayment(getDateAsLocalDate(this.REPAYMENT_DATE[1]), FIRST_INTEREST,
FEE_PORTION, PENALTY_PORTION, loanID);
this.loanTransactionHelper.makeRepayment(this.REPAYMENT_DATE[1], 15000f, loanID);
float expected_value = this.LP_PRINCIPAL - PRINCIPAL_VALUE_FOR_EACH_PERIOD;
this.loanTransactionHelper.checkAccrualTransactionForRepayment(getDateAsLocalDate(REPAYMENT_DATE[1]), FIRST_INTEREST, FEE_PORTION,
PENALTY_PORTION, loanID);
this.loanTransactionHelper.makeRepayment(REPAYMENT_DATE[1], 15000f, loanID);
float expected_value = LP_PRINCIPAL - PRINCIPAL_VALUE_FOR_EACH_PERIOD;
this.loanTransactionHelper.verifyRepaymentScheduleEntryFor(1, expected_value, loanID);
final JournalEntry[] assetAccountEntry = { new JournalEntry(15000f, JournalEntry.TransactionType.DEBIT),
new JournalEntry(11000f, JournalEntry.TransactionType.CREDIT) };
this.journalEntryHelper.checkJournalEntryForAssetAccount(assetAccount, this.REPAYMENT_DATE[1], assetAccountEntry);
this.journalEntryHelper.checkJournalEntryForLiabilityAccount(overpaymentAccount, this.REPAYMENT_DATE[1],
this.journalEntryHelper.checkJournalEntryForAssetAccount(assetAccount, REPAYMENT_DATE[1], assetAccountEntry);
this.journalEntryHelper.checkJournalEntryForLiabilityAccount(overpaymentAccount, REPAYMENT_DATE[1],
new JournalEntry(4000f, JournalEntry.TransactionType.CREDIT));
LOG.info("Repayment Done......");
@@ -731,7 +730,7 @@ public class AccountingScenarioIntegrationTest {
final Integer loanProductID = createLoanProductWithPeriodicAccrualAccountingEnabled(assetAccount, incomeAccount, expenseAccount,
overpaymentAccount);
final Integer clientID = ClientHelper.createClient(requestSpec, responseSpec, this.DATE_OF_JOINING);
final Integer clientID = ClientHelper.createClient(requestSpec, responseSpec, DATE_OF_JOINING);
final Integer loanID = applyForLoanApplication(clientID, loanProductID);
final float FEE_PORTION = 50.0f;
@@ -744,7 +743,7 @@ public class AccountingScenarioIntegrationTest {
HashMap loanStatusHashMap = LoanStatusChecker.getStatusOfLoan(requestSpec, responseSpec, loanID);
LoanStatusChecker.verifyLoanIsPending(loanStatusHashMap);
loanStatusHashMap = this.loanTransactionHelper.approveLoan(this.EXPECTED_DISBURSAL_DATE, loanID);
loanStatusHashMap = this.loanTransactionHelper.approveLoan(EXPECTED_DISBURSAL_DATE, loanID);
LoanStatusChecker.verifyLoanIsApproved(loanStatusHashMap);
LoanStatusChecker.verifyLoanIsWaitingForDisbursal(loanStatusHashMap);
@@ -776,8 +775,8 @@ public class AccountingScenarioIntegrationTest {
LOG.info("Entries ......");
final float PRINCIPAL_VALUE_FOR_EACH_PERIOD = 2000.0f;
final float TOTAL_INTEREST = 1000.0f;
final JournalEntry[] assetAccountInitialEntry = { new JournalEntry(this.LP_PRINCIPAL, JournalEntry.TransactionType.CREDIT),
new JournalEntry(this.LP_PRINCIPAL, JournalEntry.TransactionType.DEBIT), };
final JournalEntry[] assetAccountInitialEntry = { new JournalEntry(LP_PRINCIPAL, JournalEntry.TransactionType.CREDIT),
new JournalEntry(LP_PRINCIPAL, JournalEntry.TransactionType.DEBIT), };
this.journalEntryHelper.checkJournalEntryForAssetAccount(assetAccount, LOAN_DISBURSEMENT_DATE, assetAccountInitialEntry);
final String jobName = "Add Periodic Accrual Transactions";
@@ -802,10 +801,10 @@ public class AccountingScenarioIntegrationTest {
float totalInterest = (float) loanSchedule.get(1).get("interestOriginalDue");
DecimalFormat numberFormat = new DecimalFormat("#.00", new DecimalFormatSymbols(Locale.US));
float INTEREST_4_DAYS = totalInterest / totalDaysInPeriod * 4;
INTEREST_4_DAYS = Float.valueOf(numberFormat.format(INTEREST_4_DAYS));
float interest4Days = totalInterest / totalDaysInPeriod * 4;
interest4Days = Float.valueOf(numberFormat.format(interest4Days));
this.loanTransactionHelper.checkAccrualTransactionForRepayment(getDateAsLocalDate(currentDate), INTEREST_4_DAYS, FEE_PORTION,
this.loanTransactionHelper.checkAccrualTransactionForRepayment(getDateAsLocalDate(currentDate), interest4Days, FEE_PORTION,
PENALTY_PORTION, loanID);
}
@@ -820,7 +819,7 @@ public class AccountingScenarioIntegrationTest {
final Integer loanProductID = createLoanProductWithPeriodicAccrualAccountingEnabled(assetAccount, incomeAccount, expenseAccount,
overpaymentAccount);
final Integer clientID = ClientHelper.createClient(requestSpec, responseSpec, this.DATE_OF_JOINING);
final Integer clientID = ClientHelper.createClient(requestSpec, responseSpec, DATE_OF_JOINING);
final Integer loanID = applyForLoanApplication(clientID, loanProductID);
final float FEE_PORTION = 50.0f;
@@ -841,7 +840,7 @@ public class AccountingScenarioIntegrationTest {
HashMap loanStatusHashMap = LoanStatusChecker.getStatusOfLoan(requestSpec, responseSpec, loanID);
LoanStatusChecker.verifyLoanIsPending(loanStatusHashMap);
loanStatusHashMap = this.loanTransactionHelper.approveLoan(this.EXPECTED_DISBURSAL_DATE, loanID);
loanStatusHashMap = this.loanTransactionHelper.approveLoan(EXPECTED_DISBURSAL_DATE, loanID);
LoanStatusChecker.verifyLoanIsApproved(loanStatusHashMap);
LoanStatusChecker.verifyLoanIsWaitingForDisbursal(loanStatusHashMap);
@@ -882,8 +881,8 @@ public class AccountingScenarioIntegrationTest {
LOG.info("Entries ......");
final float PRINCIPAL_VALUE_FOR_EACH_PERIOD = 2000.0f;
final float TOTAL_INTEREST = 1000.0f;
final JournalEntry[] assetAccountInitialEntry = { new JournalEntry(this.LP_PRINCIPAL, JournalEntry.TransactionType.CREDIT),
new JournalEntry(this.LP_PRINCIPAL, JournalEntry.TransactionType.DEBIT), };
final JournalEntry[] assetAccountInitialEntry = { new JournalEntry(LP_PRINCIPAL, JournalEntry.TransactionType.CREDIT),
new JournalEntry(LP_PRINCIPAL, JournalEntry.TransactionType.DEBIT), };
this.journalEntryHelper.checkJournalEntryForAssetAccount(assetAccount, LOAN_DISBURSEMENT_DATE, assetAccountInitialEntry);
this.periodicAccrualAccountingHelper.runPeriodicAccrualAccounting(runOndate);
@@ -906,15 +905,15 @@ public class AccountingScenarioIntegrationTest {
float totalInterest = (float) loanSchedule.get(1).get("interestOriginalDue");
DecimalFormat numberFormat = new DecimalFormat("#.00", new DecimalFormatSymbols(Locale.US));
float INTEREST_3_DAYS = totalInterest / totalDaysInPeriod * 3;
INTEREST_3_DAYS = Float.valueOf(numberFormat.format(INTEREST_3_DAYS));
this.loanTransactionHelper.checkAccrualTransactionForRepayment(getDateAsLocalDate(runOndate), INTEREST_3_DAYS, FEE_PORTION,
float interest3Days = totalInterest / totalDaysInPeriod * 3;
interest3Days = Float.valueOf(numberFormat.format(interest3Days));
this.loanTransactionHelper.checkAccrualTransactionForRepayment(getDateAsLocalDate(runOndate), interest3Days, FEE_PORTION,
PENALTY_PORTION, loanID);
runOndate = dateFormat.format(todayDate.getTime());
this.periodicAccrualAccountingHelper.runPeriodicAccrualAccounting(runOndate);
float interestPerDay = (totalInterest / totalDaysInPeriod * 4) - INTEREST_3_DAYS;
float interestPerDay = (totalInterest / totalDaysInPeriod * 4) - interest3Days;
interestPerDay = Float.valueOf(numberFormat.format(interestPerDay));
this.loanTransactionHelper.checkAccrualTransactionForRepayment(getDateAsLocalDate(runOndate), interestPerDay, NEXT_FEE_PORTION,
NEXT_PENALTY_PORTION, loanID);
@@ -923,9 +922,9 @@ public class AccountingScenarioIntegrationTest {
private Integer createLoanProductWithPeriodicAccrualAccountingEnabled(final Account... accounts) {
LOG.info("------------------------------CREATING NEW LOAN PRODUCT ---------------------------------------");
final String loanProductJSON = new LoanProductTestBuilder().withPrincipal(this.LP_PRINCIPAL.toString()).withRepaymentTypeAsMonth()
.withRepaymentAfterEvery(this.LP_REPAYMENT_PERIOD).withNumberOfRepayments(this.LP_REPAYMENTS).withRepaymentTypeAsMonth()
.withinterestRatePerPeriod(this.LP_INTEREST_RATE).withInterestRateFrequencyTypeAsMonths()
final String loanProductJSON = new LoanProductTestBuilder().withPrincipal(LP_PRINCIPAL.toString()).withRepaymentTypeAsMonth()
.withRepaymentAfterEvery(LP_REPAYMENT_PERIOD).withNumberOfRepayments(LP_REPAYMENTS).withRepaymentTypeAsMonth()
.withinterestRatePerPeriod(LP_INTEREST_RATE).withInterestRateFrequencyTypeAsMonths()
.withAmortizationTypeAsEqualPrincipalPayment().withInterestTypeAsFlat().withAccountingRulePeriodicAccrual(accounts)
.withDaysInMonth("30").withDaysInYear("365").build(null);
return this.loanTransactionHelper.getLoanProductId(loanProductJSON);
@@ -941,101 +940,101 @@ public class AccountingScenarioIntegrationTest {
final Integer loanProductID = createLoanProductWithCashBasedAccountingEnabled(assetAccount, incomeAccount, expenseAccount,
overpaymentAccount);
final Integer clientID = ClientHelper.createClient(requestSpec, responseSpec, this.DATE_OF_JOINING);
final Integer clientID = ClientHelper.createClient(requestSpec, responseSpec, DATE_OF_JOINING);
final Integer loanID = applyForLoanApplication(clientID, loanProductID);
HashMap loanStatusHashMap = LoanStatusChecker.getStatusOfLoan(requestSpec, responseSpec, loanID);
LoanStatusChecker.verifyLoanIsPending(loanStatusHashMap);
loanStatusHashMap = this.loanTransactionHelper.approveLoan(this.EXPECTED_DISBURSAL_DATE, loanID);
loanStatusHashMap = this.loanTransactionHelper.approveLoan(EXPECTED_DISBURSAL_DATE, loanID);
LoanStatusChecker.verifyLoanIsApproved(loanStatusHashMap);
LoanStatusChecker.verifyLoanIsWaitingForDisbursal(loanStatusHashMap);
loanStatusHashMap = this.loanTransactionHelper.disburseLoan(this.EXPECTED_DISBURSAL_DATE, loanID);
loanStatusHashMap = this.loanTransactionHelper.disburseLoan(EXPECTED_DISBURSAL_DATE, loanID);
LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap);
// CHECK ACCOUNT ENTRIES
LOG.info("Entries ......");
final float PRINCIPAL_VALUE_FOR_EACH_PERIOD = 2000.0f;
final float TOTAL_INTEREST = 1000.0f;
final JournalEntry[] assetAccountInitialEntry = { new JournalEntry(this.LP_PRINCIPAL, JournalEntry.TransactionType.CREDIT),
new JournalEntry(this.LP_PRINCIPAL, JournalEntry.TransactionType.DEBIT) };
this.journalEntryHelper.checkJournalEntryForAssetAccount(assetAccount, this.EXPECTED_DISBURSAL_DATE, assetAccountInitialEntry);
final JournalEntry[] assetAccountInitialEntry = { new JournalEntry(LP_PRINCIPAL, JournalEntry.TransactionType.CREDIT),
new JournalEntry(LP_PRINCIPAL, JournalEntry.TransactionType.DEBIT) };
this.journalEntryHelper.checkJournalEntryForAssetAccount(assetAccount, EXPECTED_DISBURSAL_DATE, assetAccountInitialEntry);
// MAKE 1
LOG.info("Repayment 1 ......");
this.loanTransactionHelper.makeRepayment(this.REPAYMENT_DATE[1], this.REPAYMENT_AMOUNT[1], loanID);
this.loanTransactionHelper.makeRepayment(REPAYMENT_DATE[1], REPAYMENT_AMOUNT[1], loanID);
final float FIRST_INTEREST = 200.0f;
final float FIRST_PRINCIPAL = 2000.0f;
float expected_value = this.LP_PRINCIPAL - PRINCIPAL_VALUE_FOR_EACH_PERIOD;
float expected_value = LP_PRINCIPAL - PRINCIPAL_VALUE_FOR_EACH_PERIOD;
this.loanTransactionHelper.verifyRepaymentScheduleEntryFor(1, expected_value, loanID);
final JournalEntry[] assetAccountFirstEntry = { new JournalEntry(this.REPAYMENT_AMOUNT[1], JournalEntry.TransactionType.DEBIT),
final JournalEntry[] assetAccountFirstEntry = { new JournalEntry(REPAYMENT_AMOUNT[1], JournalEntry.TransactionType.DEBIT),
new JournalEntry(FIRST_PRINCIPAL, JournalEntry.TransactionType.CREDIT) };
this.journalEntryHelper.checkJournalEntryForAssetAccount(assetAccount, this.REPAYMENT_DATE[1], assetAccountFirstEntry);
this.journalEntryHelper.checkJournalEntryForAssetAccount(assetAccount, REPAYMENT_DATE[1], assetAccountFirstEntry);
LOG.info("CHECKING INCOME: ******************************************");
this.journalEntryHelper.checkJournalEntryForIncomeAccount(incomeAccount, this.REPAYMENT_DATE[1],
this.journalEntryHelper.checkJournalEntryForIncomeAccount(incomeAccount, REPAYMENT_DATE[1],
new JournalEntry(FIRST_INTEREST, JournalEntry.TransactionType.CREDIT));
LOG.info("Repayment 1 Done......");
// REPAYMENT 2
LOG.info("Repayment 2 ......");
this.loanTransactionHelper.makeRepayment(this.REPAYMENT_DATE[2], this.REPAYMENT_AMOUNT[2], loanID);
this.loanTransactionHelper.makeRepayment(REPAYMENT_DATE[2], REPAYMENT_AMOUNT[2], loanID);
final float SECOND_AND_THIRD_INTEREST = 400.0f;
final float SECOND_PRINCIPAL = this.REPAYMENT_AMOUNT[2] - SECOND_AND_THIRD_INTEREST;
final float SECOND_PRINCIPAL = REPAYMENT_AMOUNT[2] - SECOND_AND_THIRD_INTEREST;
expected_value = expected_value - PRINCIPAL_VALUE_FOR_EACH_PERIOD;
this.loanTransactionHelper.verifyRepaymentScheduleEntryFor(2, expected_value, loanID);
final JournalEntry[] assetAccountSecondEntry = { new JournalEntry(this.REPAYMENT_AMOUNT[2], JournalEntry.TransactionType.DEBIT),
final JournalEntry[] assetAccountSecondEntry = { new JournalEntry(REPAYMENT_AMOUNT[2], JournalEntry.TransactionType.DEBIT),
new JournalEntry(SECOND_PRINCIPAL, JournalEntry.TransactionType.CREDIT), };
this.journalEntryHelper.checkJournalEntryForAssetAccount(assetAccount, this.REPAYMENT_DATE[2], assetAccountSecondEntry);
this.journalEntryHelper.checkJournalEntryForAssetAccount(assetAccount, REPAYMENT_DATE[2], assetAccountSecondEntry);
LOG.info("CHECKING INCOME: ******************************************");
this.journalEntryHelper.checkJournalEntryForIncomeAccount(incomeAccount, this.REPAYMENT_DATE[2],
this.journalEntryHelper.checkJournalEntryForIncomeAccount(incomeAccount, REPAYMENT_DATE[2],
new JournalEntry(SECOND_AND_THIRD_INTEREST, JournalEntry.TransactionType.CREDIT));
LOG.info("Repayment 2 Done ......");
// WAIVE INTEREST
LOG.info("Waive Interest ......");
Integer transactionId = this.loanTransactionHelper.waiveInterestAndReturnTransactionId(this.REPAYMENT_DATE[4],
this.AMOUNT_TO_BE_WAIVE.toString(), loanID);
Integer transactionId = this.loanTransactionHelper.waiveInterestAndReturnTransactionId(REPAYMENT_DATE[4],
AMOUNT_TO_BE_WAIVE.toString(), loanID);
// waive of fees and interest are not considered in cash based
// accounting,
this.journalEntryHelper.ensureNoAccountingTransactionsWithTransactionId("L" + transactionId);
// REPAYMENT 3
LOG.info("Repayment 3 ......");
this.loanTransactionHelper.makeRepayment(this.REPAYMENT_DATE[3], this.REPAYMENT_AMOUNT[3], loanID);
this.loanTransactionHelper.makeRepayment(REPAYMENT_DATE[3], REPAYMENT_AMOUNT[3], loanID);
expected_value = expected_value - PRINCIPAL_VALUE_FOR_EACH_PERIOD;
final JournalEntry[] assetAccountThirdEntry = { new JournalEntry(this.REPAYMENT_AMOUNT[3], JournalEntry.TransactionType.DEBIT),
new JournalEntry(this.REPAYMENT_AMOUNT[3], JournalEntry.TransactionType.CREDIT) };
final JournalEntry[] assetAccountThirdEntry = { new JournalEntry(REPAYMENT_AMOUNT[3], JournalEntry.TransactionType.DEBIT),
new JournalEntry(REPAYMENT_AMOUNT[3], JournalEntry.TransactionType.CREDIT) };
this.loanTransactionHelper.verifyRepaymentScheduleEntryFor(3, expected_value, loanID);
this.journalEntryHelper.checkJournalEntryForAssetAccount(assetAccount, this.REPAYMENT_DATE[3], assetAccountThirdEntry);
this.journalEntryHelper.checkJournalEntryForAssetAccount(assetAccount, REPAYMENT_DATE[3], assetAccountThirdEntry);
LOG.info("Repayment 3 Done ......");
// REPAYMENT 4
LOG.info("Repayment 4 ......");
this.loanTransactionHelper.makeRepayment(this.REPAYMENT_DATE[4], this.REPAYMENT_AMOUNT[4], loanID);
this.loanTransactionHelper.makeRepayment(REPAYMENT_DATE[4], REPAYMENT_AMOUNT[4], loanID);
expected_value = expected_value - PRINCIPAL_VALUE_FOR_EACH_PERIOD;
this.loanTransactionHelper.verifyRepaymentScheduleEntryFor(4, expected_value, loanID);
final JournalEntry[] assetAccountFourthEntry = { new JournalEntry(this.REPAYMENT_AMOUNT[4], JournalEntry.TransactionType.DEBIT),
new JournalEntry(this.REPAYMENT_AMOUNT[4], JournalEntry.TransactionType.CREDIT) };
this.journalEntryHelper.checkJournalEntryForAssetAccount(assetAccount, this.REPAYMENT_DATE[4], assetAccountFourthEntry);
final JournalEntry[] assetAccountFourthEntry = { new JournalEntry(REPAYMENT_AMOUNT[4], JournalEntry.TransactionType.DEBIT),
new JournalEntry(REPAYMENT_AMOUNT[4], JournalEntry.TransactionType.CREDIT) };
this.journalEntryHelper.checkJournalEntryForAssetAccount(assetAccount, REPAYMENT_DATE[4], assetAccountFourthEntry);
LOG.info("Repayment 4 Done ......");
// Repayment 5
LOG.info("Repayment 5 ......");
final JournalEntry[] assetAccountFifthEntry = { new JournalEntry(this.REPAYMENT_AMOUNT[5], JournalEntry.TransactionType.DEBIT),
new JournalEntry(this.REPAYMENT_AMOUNT[5], JournalEntry.TransactionType.CREDIT) };
final JournalEntry[] assetAccountFifthEntry = { new JournalEntry(REPAYMENT_AMOUNT[5], JournalEntry.TransactionType.DEBIT),
new JournalEntry(REPAYMENT_AMOUNT[5], JournalEntry.TransactionType.CREDIT) };
expected_value = expected_value - PRINCIPAL_VALUE_FOR_EACH_PERIOD;
this.loanTransactionHelper.makeRepayment(this.REPAYMENT_DATE[5], this.REPAYMENT_AMOUNT[5], loanID);
this.loanTransactionHelper.makeRepayment(REPAYMENT_DATE[5], REPAYMENT_AMOUNT[5], loanID);
this.loanTransactionHelper.verifyRepaymentScheduleEntryFor(5, expected_value, loanID);
this.journalEntryHelper.checkJournalEntryForAssetAccount(assetAccount, this.REPAYMENT_DATE[5], assetAccountFifthEntry);
this.journalEntryHelper.checkJournalEntryForAssetAccount(assetAccount, REPAYMENT_DATE[5], assetAccountFifthEntry);
LOG.info("Repayment 5 Done ......");
}
private Integer createLoanProductWithCashBasedAccountingEnabled(final Account... accounts) {
LOG.info("------------------------------CREATING NEW LOAN PRODUCT ---------------------------------------");
final String loanProductJSON = new LoanProductTestBuilder().withPrincipal(this.LP_PRINCIPAL.toString()).withRepaymentTypeAsMonth()
.withRepaymentAfterEvery(this.LP_REPAYMENT_PERIOD).withNumberOfRepayments(this.LP_REPAYMENTS).withRepaymentTypeAsMonth()
.withinterestRatePerPeriod(this.LP_INTEREST_RATE).withInterestRateFrequencyTypeAsMonths()
final String loanProductJSON = new LoanProductTestBuilder().withPrincipal(LP_PRINCIPAL.toString()).withRepaymentTypeAsMonth()
.withRepaymentAfterEvery(LP_REPAYMENT_PERIOD).withNumberOfRepayments(LP_REPAYMENTS).withRepaymentTypeAsMonth()
.withinterestRatePerPeriod(LP_INTEREST_RATE).withInterestRateFrequencyTypeAsMonths()
.withAmortizationTypeAsEqualPrincipalPayment().withInterestTypeAsFlat().withAccountingRuleAsCashBased(accounts).build(null);
return this.loanTransactionHelper.getLoanProductId(loanProductJSON);
}
@@ -0,0 +1,140 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.fineract.integrationtests;
import io.restassured.builder.RequestSpecBuilder;
import io.restassured.builder.ResponseSpecBuilder;
import io.restassured.http.ContentType;
import io.restassured.specification.RequestSpecification;
import io.restassured.specification.ResponseSpecification;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Random;
import org.apache.fineract.integrationtests.common.AuditHelper;
import org.apache.fineract.integrationtests.common.ClientHelper;
import org.apache.fineract.integrationtests.common.OfficeHelper;
import org.apache.fineract.integrationtests.common.Utils;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
/**
*
* @author Manthan Surkar
*
*/
public class AuditIntegrationTest {
private ResponseSpecification responseSpec;
private RequestSpecification requestSpec;
private ClientHelper clientHelper;
private AuditHelper auditHelper;
/**
* Sets up the essential settings for the TEST like contentType, expectedStatusCode. It uses the '@BeforeEach'
* annotation provided by jUnit.
*/
@BeforeEach
public void setup() {
Utils.initializeRESTAssured();
this.requestSpec = new RequestSpecBuilder().setContentType(ContentType.JSON).build();
this.requestSpec.header("Authorization", "Basic " + Utils.loginIntoServerAndGetBase64EncodedAuthenticationKey());
this.responseSpec = new ResponseSpecBuilder().expectStatusCode(200).build();
this.auditHelper = new AuditHelper(this.requestSpec, this.responseSpec);
this.clientHelper = new ClientHelper(this.requestSpec, this.responseSpec);
}
/**
* Here we Create/Update different Entities and verify an audit is generated for each action. This can be further
* extened with more entities and actions in similiar way.
*/
@SuppressWarnings("unchecked")
@Test
public void auditShouldbeCreated() {
// Audits recieved after all actions are performed.
List<HashMap<String, Object>> auditsRecieved;
// Audits recieved before any action is performed, needed in special
// cases eg: reactivate client, close client
List<HashMap<String, Object>> auditsRecievedInitial;
// When Client is created: Count should be "1"
final Integer clientId = ClientHelper.createClient(this.requestSpec, this.responseSpec);
Assertions.assertNotNull(clientId);
auditsRecieved = auditHelper.getAuditDetails(clientId, "CREATE", "CLIENT");
auditHelper.verifyOneAuditOnly(auditsRecieved, clientId, "CREATE", "CLIENT");
// Performs multiple close and reactivate on client
for (int i = 0; i < 4; i++) {
// Close
auditsRecievedInitial = auditHelper.getAuditDetails(clientId, "CLOSE", "CLIENT");
this.clientHelper.closeClient(clientId);
auditsRecieved = auditHelper.getAuditDetails(clientId, "CLOSE", "CLIENT");
auditHelper.verifyMultipleAuditsOnserver(auditsRecievedInitial, auditsRecieved, clientId, "CLOSE", "CLIENT");
// Activate
auditsRecievedInitial = auditHelper.getAuditDetails(clientId, "REACTIVATE", "CLIENT");
this.clientHelper.reactivateClient(clientId);
auditsRecieved = auditHelper.getAuditDetails(clientId, "REACTIVATE", "CLIENT");
auditHelper.verifyMultipleAuditsOnserver(auditsRecievedInitial, auditsRecieved, clientId, "REACTIVATE", "CLIENT");
}
// When Office is created
OfficeHelper officeHelper = new OfficeHelper(requestSpec, responseSpec);
int officeId = officeHelper.createOffice("22 June 2020");
auditsRecieved = auditHelper.getAuditDetails(officeId, "CREATE", "OFFICE");
auditHelper.verifyOneAuditOnly(auditsRecieved, officeId, "CREATE", "OFFICE");
}
@Test
public void checkAuditsWithLimitParam() {
// Create client
final Integer clientId = ClientHelper.createClient(this.requestSpec, this.responseSpec);
// The following loop would ensure database have atleast 8 audits.
for (int i = 0; i < 4; i++) {
// Close client
this.clientHelper.closeClient(clientId);
// Activate client
this.clientHelper.reactivateClient(clientId);
}
Random rand = new Random();
for (int i = 0; i < 3; i++) {
// limit contains a number between 1-8
int limit = rand.nextInt(7) + 1;
auditHelper.verifyLimitParameterfor(limit);
}
}
@Test
public void checkIfOrderBySupported() {
final List<String> shouldBeSupportedFor = Arrays.asList("checkedOnDate", "officeName", "resourceId", "clientId", "processingResult",
"clientName", "maker", "subresourceId", "checker", "savingsAccountNo", "loanAccountNo", "groupName", "entityName",
"madeOnDate", "id", "loanId", "actionName");
for (int i = 0; i < shouldBeSupportedFor.size(); i++) {
auditHelper.verifyOrderBysupported(shouldBeSupportedFor.get(i));
}
}
}
@@ -41,10 +41,8 @@ import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
/**
* Test class for
* {@link org.apache.fineract.batch.command.CommandStrategyProvider}. This tests
* the response provided by commandStrategy by injecting it with a
* {@code BatchRequest}.
* Test class for {@link org.apache.fineract.batch.command.CommandStrategyProvider}. This tests the response provided by
* commandStrategy by injecting it with a {@code BatchRequest}.
*
* @author RishabhShukla
*
@@ -57,9 +55,8 @@ public class BatchApiTest {
private RequestSpecification requestSpec;
/**
* Sets up the essential settings for the TEST like contentType,
* expectedStatusCode. It uses the '@BeforeEach' annotation provided by
* jUnit.
* Sets up the essential settings for the TEST like contentType, expectedStatusCode. It uses the '@BeforeEach'
* annotation provided by jUnit.
*/
@BeforeEach
public void setup() {
@@ -70,9 +67,8 @@ public class BatchApiTest {
}
/**
* Tests for the unimplemented command Strategies by returning 501 status
* code. For a unknownRequest a statusCode 501 is returned back with
* response.
* Tests for the unimplemented command Strategies by returning 501 status code. For a unknownRequest a statusCode
* 501 is returned back with response.
*
* @see org.apache.fineract.batch.command.internal.UnknownCommandStrategy
*/
@@ -93,9 +89,8 @@ public class BatchApiTest {
}
/**
* Tests for the successful response for a createClient request from
* createClientCommand. A successful response with statusCode '200' is
* returned back.
* Tests for the successful response for a createClient request from createClientCommand. A successful response with
* statusCode '200' is returned back.
*
* @see org.apache.fineract.batch.command.internal.CreateClientCommandStrategy
*/
@@ -113,10 +108,9 @@ public class BatchApiTest {
}
/**
* Tests for an erroneous response with statusCode '501' if transaction
* fails. If Query Parameter 'enclosingTransaction' is set to 'true' and if
* one of the request in BatchRequest fails then all transactions are rolled
* back.
* Tests for an erroneous response with statusCode '501' if transaction fails. If Query Parameter
* 'enclosingTransaction' is set to 'true' and if one of the request in BatchRequest fails then all transactions are
* rolled back.
*
* @see org.apache.fineract.batch.command.internal.CreateClientCommandStrategy
* @see org.apache.fineract.batch.api.BatchApiResource
@@ -156,9 +150,8 @@ public class BatchApiTest {
}
/**
* Tests that a client information was successfully updated through
* updateClientCommand. A 'changes' parameter is returned in the response
* after successful update of client information.
* Tests that a client information was successfully updated through updateClientCommand. A 'changes' parameter is
* returned in the response after successful update of client information.
*
* @see org.apache.fineract.batch.command.internal.UpdateClientCommandStrategy
*/
@@ -190,10 +183,8 @@ public class BatchApiTest {
}
/**
* Tests that a ApplyLoanCommand was successfully executed and returned a
* 200(OK) status. It creates a new client and apply a loan to that client.
* This also verifies the successful resolution of dependencies among two
* requests.
* Tests that a ApplyLoanCommand was successfully executed and returned a 200(OK) status. It creates a new client
* and apply a loan to that client. This also verifies the successful resolution of dependencies among two requests.
*
* @see org.apache.fineract.batch.command.internal.ApplyLoanCommandStrategy
*/
@@ -240,9 +231,8 @@ public class BatchApiTest {
}
/**
* Tests that a new savings accounts was applied to an existing client and a
* 200(OK) status was returned. It first creates a new client and a savings
* product, then uses the cliendId and ProductId to apply a savings account.
* Tests that a new savings accounts was applied to an existing client and a 200(OK) status was returned. It first
* creates a new client and a savings product, then uses the cliendId and ProductId to apply a savings account.
*
* @see org.apache.fineract.batch.command.internal.ApplySavingsCommandStrategy
*/
@@ -282,10 +272,9 @@ public class BatchApiTest {
}
/**
* Tests that a new charge was added to a newly created loan and charges are
* Collected properly 200(OK) status was returned for successful responses.
* It first creates a new client and apply a loan, then creates a new charge
* for the create loan and then fetches all the applied charges
* Tests that a new charge was added to a newly created loan and charges are Collected properly 200(OK) status was
* returned for successful responses. It first creates a new client and apply a loan, then creates a new charge for
* the create loan and then fetches all the applied charges
*
* @see org.apache.fineract.batch.command.internal.CollectChargesCommandStrategy
* @see org.apache.fineract.batch.command.internal.CreateChargeCommandStrategy
@@ -334,10 +323,9 @@ public class BatchApiTest {
}
/**
* Tests that batch repayment for loans is happening properly. Collected
* properly 200(OK) status was returned for successful responses. It first
* creates a new loan and then makes two repayments for it and then verifies
* that 200(OK) is returned for the repayment requests.
* Tests that batch repayment for loans is happening properly. Collected properly 200(OK) status was returned for
* successful responses. It first creates a new loan and then makes two repayments for it and then verifies that
* 200(OK) is returned for the repayment requests.
*
* @see org.apache.fineract.batch.command.internal.RepayLoanCommandStrategy
*/
@@ -398,9 +386,8 @@ public class BatchApiTest {
}
/**
* Test for the successful activation of a pending client using
* 'ActivateClientCommandStrategy'. A '200' status code is expected on
* successful activation.
* Test for the successful activation of a pending client using 'ActivateClientCommandStrategy'. A '200' status code
* is expected on successful activation.
*
* @see org.apache.fineract.batch.command.internal.ActivateClientCommandStrategy
*/
@@ -428,9 +415,8 @@ public class BatchApiTest {
}
/**
* Test for the successful approval and disbursal of a loan using
* 'ApproveLoanCommandStrategy' and 'DisburseLoanCommandStrategy'. A '200'
* status code is expected on successful activation.
* Test for the successful approval and disbursal of a loan using 'ApproveLoanCommandStrategy' and
* 'DisburseLoanCommandStrategy'. A '200' status code is expected on successful activation.
*
* @see org.apache.fineract.batch.command.internal.ApproveLoanCommandStrategy
* @see org.apache.fineract.batch.command.internal.DisburseLoanCommandStrategy
@@ -483,9 +469,8 @@ public class BatchApiTest {
}
/**
* Test for the successful create client, apply loan,approval and disbursal
* of a loan using Batch API with enclosingTransaction. A '200' status code
* is expected on successful activation.
* Test for the successful create client, apply loan,approval and disbursal of a loan using Batch API with
* enclosingTransaction. A '200' status code is expected on successful activation.
*
* @see org.apache.fineract.batch.command.internal.ApproveLoanCommandStrategy
* @see org.apache.fineract.batch.command.internal.DisburseLoanCommandStrategy
@@ -40,9 +40,8 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Test class for testing the integration of Batch API with custom batch
* requests and various user defined workflow. Like in the case of mifos
* community-app
* Test class for testing the integration of Batch API with custom batch requests and various user defined workflow.
* Like in the case of mifos community-app
*
* @author Rishabh Shukla
*/
@@ -53,13 +52,12 @@ public class BatchRequestsIntegrationTest {
private RequestSpecification requestSpec;
public BatchRequestsIntegrationTest() {
super();
}
/**
* Sets up the essential settings for the TEST like contentType,
* expectedStatusCode. It uses the '@BeforeEach' annotation provided by
* jUnit.
* Sets up the essential settings for the TEST like contentType, expectedStatusCode. It uses the '@BeforeEach'
* annotation provided by jUnit.
*/
@BeforeEach
public void setup() {
@@ -72,12 +70,10 @@ public class BatchRequestsIntegrationTest {
@Test
/**
* Tests that a loan is successfully applied to client members of a group.
* Firstly, it'll create a few new clients and then will add those clients
* to the group. Then a few loans will be created and one of those loans
* will be chosen at random and similarily a few of the created clients will
* be chosen on random. Now, the selected loan will be applied to these
* clients through Batch - API ApplyLoanCommandStrategy.
* Tests that a loan is successfully applied to client members of a group. Firstly, it'll create a few new clients
* and then will add those clients to the group. Then a few loans will be created and one of those loans will be
* chosen at random and similarily a few of the created clients will be chosen on random. Now, the selected loan
* will be applied to these clients through Batch - API ApplyLoanCommandStrategy.
*/
public void shouldReturnOkStatusForLoansAppliedToSelectedClients() {
@@ -62,9 +62,8 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Client Loan Integration Test for checking Loan Application Repayments
* Schedule, loan charges, penalties, loan repayments and verifying accounting
* transactions
* Client Loan Integration Test for checking Loan Application Repayments Schedule, loan charges, penalties, loan
* repayments and verifying accounting transactions
*/
@SuppressWarnings({ "rawtypes", "unchecked" })
public class ClientLoanIntegrationTest {
@@ -1249,8 +1248,7 @@ public class ClientLoanIntegrationTest {
}
/***
* Test case for checking CashBasedAccounting functionality adding charges
* with calculation type flat
* Test case for checking CashBasedAccounting functionality adding charges with calculation type flat
*/
@Test
public void loanWithFlatCahargesAndCashBasedAccountingEnabled() {
@@ -1426,8 +1424,8 @@ public class ClientLoanIntegrationTest {
}
/***
* Test case for checking CashBasedAccounting functionality adding charges
* with calculation type percentage of amount
* Test case for checking CashBasedAccounting functionality adding charges with calculation type percentage of
* amount
*/
@Test
public void loanWithCahargesOfTypeAmountPercentageAndCashBasedAccountingEnabled() {
@@ -1606,8 +1604,8 @@ public class ClientLoanIntegrationTest {
}
/***
* Test case for checking CashBasedAccounting functionality adding charges
* with calculation type percentage of amount plus interest
* Test case for checking CashBasedAccounting functionality adding charges with calculation type percentage of
* amount plus interest
*/
@Test
public void loanWithCahargesOfTypeAmountPlusInterestPercentageAndCashBasedAccountingEnabled() {
@@ -1787,8 +1785,7 @@ public class ClientLoanIntegrationTest {
}
/***
* Test case for checking AccuralUpfrontAccounting functionality adding
* charges with calculation type flat
* Test case for checking AccuralUpfrontAccounting functionality adding charges with calculation type flat
*/
@Test
public void loanWithFlatCahargesAndUpfrontAccrualAccountingEnabled() {
@@ -1981,8 +1978,8 @@ public class ClientLoanIntegrationTest {
}
/***
* Test case for checking AccuralUpfrontAccounting functionality adding
* charges with calculation type percentage of amount
* Test case for checking AccuralUpfrontAccounting functionality adding charges with calculation type percentage of
* amount
*/
@Test
public void loanWithCahargesAndUpfrontAccrualAccountingEnabled() {
@@ -2171,8 +2168,8 @@ public class ClientLoanIntegrationTest {
}
/***
* Test case for checking AccuralUpfrontAccounting functionality adding
* charges with calculation type percentage of amount plus interest
* Test case for checking AccuralUpfrontAccounting functionality adding charges with calculation type percentage of
* amount plus interest
*/
@Test
public void loanWithCahargesOfTypeAmountPlusInterestPercentageAndUpfrontAccrualAccountingEnabled() {
@@ -2368,8 +2365,7 @@ public class ClientLoanIntegrationTest {
}
/***
* Test case for checking AccuralPeriodicAccounting functionality adding
* charges with calculation type flat
* Test case for checking AccuralPeriodicAccounting functionality adding charges with calculation type flat
*/
@Test
public void loanWithFlatChargesAndPeriodicAccrualAccountingEnabled() throws InterruptedException {
@@ -2467,14 +2463,10 @@ public class ClientLoanIntegrationTest {
validateCharge(flatInstallmentFee, loanCharges, "50", "100.00", "50.0", "50.0");
/*
* this.journalEntryHelper.checkJournalEntryForAssetAccount(
* assetAccount, "20 September 2011", new
* JournalEntry(Float.valueOf("50.0"),
* JournalEntry.TransactionType.CREDIT));
* this.journalEntryHelper.checkJournalEntryForExpenseAccount
* (expenseAccount, "20 September 2011", new
* JournalEntry(Float.valueOf("50.0"),
* JournalEntry.TransactionType.DEBIT));
* this.journalEntryHelper.checkJournalEntryForAssetAccount( assetAccount, "20 September 2011", new
* JournalEntry(Float.valueOf("50.0"), JournalEntry.TransactionType.CREDIT));
* this.journalEntryHelper.checkJournalEntryForExpenseAccount (expenseAccount, "20 September 2011", new
* JournalEntry(Float.valueOf("50.0"), JournalEntry.TransactionType.DEBIT));
*/
final String jobName = "Add Accrual Transactions";
@@ -2561,8 +2553,8 @@ public class ClientLoanIntegrationTest {
}
/**
* Test case for checking AccuralPeriodicAccounting functionality adding
* charges with calculation type percentage of amount
* Test case for checking AccuralPeriodicAccounting functionality adding charges with calculation type percentage of
* amount
*/
@Test
public void loanWithChargesOfTypeAmountPercentageAndPeriodicAccrualAccountingEnabled() throws InterruptedException {
@@ -2663,14 +2655,10 @@ public class ClientLoanIntegrationTest {
validateCharge(percentageInstallmentFee, loanCharges, "1", "61.19", "29.11", "29.70");
/*
* this.journalEntryHelper.checkJournalEntryForAssetAccount(
* assetAccount, "20 September 2011", new
* JournalEntry(Float.valueOf("29.7"),
* JournalEntry.TransactionType.CREDIT));
* this.journalEntryHelper.checkJournalEntryForExpenseAccount
* (expenseAccount, "20 September 2011", new
* JournalEntry(Float.valueOf("29.7"),
* JournalEntry.TransactionType.DEBIT));
* this.journalEntryHelper.checkJournalEntryForAssetAccount( assetAccount, "20 September 2011", new
* JournalEntry(Float.valueOf("29.7"), JournalEntry.TransactionType.CREDIT));
* this.journalEntryHelper.checkJournalEntryForExpenseAccount (expenseAccount, "20 September 2011", new
* JournalEntry(Float.valueOf("29.7"), JournalEntry.TransactionType.DEBIT));
*/
final String jobName = "Add Accrual Transactions";
@@ -2758,8 +2746,8 @@ public class ClientLoanIntegrationTest {
}
/***
* Test case for checking AccuralPeriodicAccounting functionality adding
* charges with calculation type percentage of amount and interest
* Test case for checking AccuralPeriodicAccounting functionality adding charges with calculation type percentage of
* amount and interest
*/
@Test
public void loanWithChargesOfTypeAmountPlusInterestPercentageAndPeriodicAccrualAccountingEnabled() throws InterruptedException {
@@ -2861,13 +2849,10 @@ public class ClientLoanIntegrationTest {
validateCharge(amountPlusInterestPercentageInstallmentFee, loanCharges, "1", "63.02", "31.51", "31.51");
/*
* this.journalEntryHelper.checkJournalEntryForAssetAccount(
* assetAccount, "20 September 2011", new JournalEntry(
* Float.valueOf("31.51"), JournalEntry.TransactionType.CREDIT));
* this.journalEntryHelper.checkJournalEntryForExpenseAccount
* (expenseAccount, "20 September 2011", new
* JournalEntry(Float.valueOf("31.51"),
* JournalEntry.TransactionType.DEBIT));
* this.journalEntryHelper.checkJournalEntryForAssetAccount( assetAccount, "20 September 2011", new
* JournalEntry( Float.valueOf("31.51"), JournalEntry.TransactionType.CREDIT));
* this.journalEntryHelper.checkJournalEntryForExpenseAccount (expenseAccount, "20 September 2011", new
* JournalEntry(Float.valueOf("31.51"), JournalEntry.TransactionType.DEBIT));
*/
final String jobName = "Add Accrual Transactions";
@@ -3032,8 +3017,7 @@ public class ClientLoanIntegrationTest {
validateNumberForEqual("0.00", String.valueOf(firstInstallment.get("totalOutstandingForPeriod")));
/***
* Verify 2nd and 3rd repayments dues before making excess payment for
* installment no 2
* Verify 2nd and 3rd repayments dues before making excess payment for installment no 2
*/
HashMap secondInstallment = loanSchedule.get(2);
HashMap thirdInstallment = loanSchedule.get(3);
@@ -3051,18 +3035,15 @@ public class ClientLoanIntegrationTest {
loanSchedule.clear();
loanSchedule = this.loanTransactionHelper.getLoanRepaymentSchedule(this.requestSpec, this.responseSpec, loanID);
/***
* Verify 2nd and 3rd repayments after making excess payment for
* installment no 2
* Verify 2nd and 3rd repayments after making excess payment for installment no 2
*/
secondInstallment = loanSchedule.get(2);
validateNumberForEqual("0.00", String.valueOf(secondInstallment.get("totalOutstandingForPeriod")));
/***
* According to RBI Excess payment should go to principal portion of
* next installment, but as interest recalculation is not implemented,
* it wont make any difference to schedule even though if we made excess
* payment, so excess payments will behave the same as regular payment
* with the excess amount
* According to RBI Excess payment should go to principal portion of next installment, but as interest
* recalculation is not implemented, it wont make any difference to schedule even though if we made excess
* payment, so excess payments will behave the same as regular payment with the excess amount
*/
thirdInstallment = loanSchedule.get(3);
validateNumberForEqual("3200", String.valueOf(thirdInstallment.get("totalOutstandingForPeriod")));
@@ -3072,16 +3053,14 @@ public class ClientLoanIntegrationTest {
validateNumberForEqual("100.00", String.valueOf(thirdInstallment.get("interestOutstanding")));
/***
* Make payment with due amount of 3rd installment on 4th installment
* date
* Make payment with due amount of 3rd installment on 4th installment date
*/
this.loanTransactionHelper.makeRepayment("20 January 2012", Float.valueOf("3200"), loanID);
loanSchedule.clear();
loanSchedule = this.loanTransactionHelper.getLoanRepaymentSchedule(this.requestSpec, this.responseSpec, loanID);
/***
* Verify overdue interests are deducted first and then remaining amount
* for interest portion of due installment
* Verify overdue interests are deducted first and then remaining amount for interest portion of due installment
*/
thirdInstallment = loanSchedule.get(3);
HashMap fourthInstallment = loanSchedule.get(4);
@@ -3216,8 +3195,8 @@ public class ClientLoanIntegrationTest {
String prepayAmount = String.valueOf(prepayDetail.get("amount"));
validateNumberForEqualWithMsg("verify pre-close amount", "3551.93", prepayAmount);
todaysDate = Calendar.getInstance(Utils.getTimeZoneOfTenant());
String LOAN_REPAYMENT_DATE = dateFormat.format(todaysDate.getTime());
this.loanTransactionHelper.makeRepayment(LOAN_REPAYMENT_DATE, Float.valueOf(prepayAmount), loanID);
final String loanRepaymentDate = dateFormat.format(todaysDate.getTime());
this.loanTransactionHelper.makeRepayment(loanRepaymentDate, Float.valueOf(prepayAmount), loanID);
loanStatusHashMap = LoanStatusChecker.getStatusOfLoan(this.requestSpec, this.responseSpec, loanID);
LoanStatusChecker.verifyLoanAccountIsClosed(loanStatusHashMap);
}
@@ -3310,8 +3289,8 @@ public class ClientLoanIntegrationTest {
String prepayAmount = String.valueOf(prepayDetail.get("amount"));
validateNumberForEqualWithMsg("verify pre-close amount", preCloseAmount, prepayAmount);
todaysDate = Calendar.getInstance(Utils.getTimeZoneOfTenant());
String LOAN_REPAYMENT_DATE = dateFormat.format(todaysDate.getTime());
this.loanTransactionHelper.makeRepayment(LOAN_REPAYMENT_DATE, Float.valueOf(prepayAmount), loanID);
final String loanRepaymentDate = dateFormat.format(todaysDate.getTime());
this.loanTransactionHelper.makeRepayment(loanRepaymentDate, Float.valueOf(prepayAmount), loanID);
loanStatusHashMap = LoanStatusChecker.getStatusOfLoan(this.requestSpec, this.responseSpec, loanID);
LoanStatusChecker.verifyLoanAccountIsClosed(loanStatusHashMap);
}
@@ -3406,8 +3385,8 @@ public class ClientLoanIntegrationTest {
HashMap prepayDetail = this.loanTransactionHelper.getPrepayAmount(this.requestSpec, this.responseSpec, loanID);
String prepayAmount = String.valueOf(prepayDetail.get("amount"));
todaysDate = Calendar.getInstance(Utils.getTimeZoneOfTenant());
String LOAN_REPAYMENT_DATE = dateFormat.format(todaysDate.getTime());
this.loanTransactionHelper.makeRepayment(LOAN_REPAYMENT_DATE, Float.valueOf(prepayAmount), loanID);
final String loanRepaymentDate = dateFormat.format(todaysDate.getTime());
this.loanTransactionHelper.makeRepayment(loanRepaymentDate, Float.valueOf(prepayAmount), loanID);
loanStatusHashMap = LoanStatusChecker.getStatusOfLoan(this.requestSpec, this.responseSpec, loanID);
LoanStatusChecker.verifyLoanAccountIsClosed(loanStatusHashMap);
}
@@ -3517,8 +3496,8 @@ public class ClientLoanIntegrationTest {
HashMap prepayDetail = this.loanTransactionHelper.getPrepayAmount(this.requestSpec, this.responseSpec, loanID);
String prepayAmount = String.valueOf(prepayDetail.get("amount"));
todaysDate = Calendar.getInstance(Utils.getTimeZoneOfTenant());
String LOAN_REPAYMENT_DATE = dateFormat.format(todaysDate.getTime());
this.loanTransactionHelper.makeRepayment(LOAN_REPAYMENT_DATE, Float.valueOf(prepayAmount), loanID);
final String loanRepaymentDate = dateFormat.format(todaysDate.getTime());
this.loanTransactionHelper.makeRepayment(loanRepaymentDate, Float.valueOf(prepayAmount), loanID);
loanStatusHashMap = LoanStatusChecker.getStatusOfLoan(this.requestSpec, this.responseSpec, loanID);
LoanStatusChecker.verifyLoanAccountIsClosed(loanStatusHashMap);
@@ -3634,8 +3613,8 @@ public class ClientLoanIntegrationTest {
HashMap prepayDetail = this.loanTransactionHelper.getPrepayAmount(this.requestSpec, this.responseSpec, loanID);
String prepayAmount = String.valueOf(prepayDetail.get("amount"));
todaysDate = Calendar.getInstance(Utils.getTimeZoneOfTenant());
String LOAN_REPAYMENT_DATE = dateFormat.format(todaysDate.getTime());
this.loanTransactionHelper.makeRepayment(LOAN_REPAYMENT_DATE, Float.valueOf(prepayAmount), loanID);
final String loanRepaymentDate = dateFormat.format(todaysDate.getTime());
this.loanTransactionHelper.makeRepayment(loanRepaymentDate, Float.valueOf(prepayAmount), loanID);
loanStatusHashMap = LoanStatusChecker.getStatusOfLoan(this.requestSpec, this.responseSpec, loanID);
LoanStatusChecker.verifyLoanAccountIsClosed(loanStatusHashMap);
@@ -3752,8 +3731,8 @@ public class ClientLoanIntegrationTest {
String prepayAmount = String.valueOf(prepayDetail.get("amount"));
validateNumberForEqualWithMsg("verify pre-close amount", preCloseAmount, prepayAmount);
todaysDate = Calendar.getInstance(Utils.getTimeZoneOfTenant());
String LOAN_REPAYMENT_DATE = dateFormat.format(todaysDate.getTime());
this.loanTransactionHelper.makeRepayment(LOAN_REPAYMENT_DATE, Float.valueOf(prepayAmount), loanID);
final String loanRepaymentDate = dateFormat.format(todaysDate.getTime());
this.loanTransactionHelper.makeRepayment(loanRepaymentDate, Float.valueOf(prepayAmount), loanID);
loanStatusHashMap = LoanStatusChecker.getStatusOfLoan(this.requestSpec, this.responseSpec, loanID);
LoanStatusChecker.verifyLoanAccountIsClosed(loanStatusHashMap);
}
@@ -3967,8 +3946,8 @@ public class ClientLoanIntegrationTest {
HashMap prepayDetail = this.loanTransactionHelper.getPrepayAmount(this.requestSpec, this.responseSpec, loanID);
String prepayAmount = String.valueOf(prepayDetail.get("amount"));
todaysDate = Calendar.getInstance(Utils.getTimeZoneOfTenant());
String LOAN_REPAYMENT_DATE = dateFormat.format(todaysDate.getTime());
this.loanTransactionHelper.makeRepayment(LOAN_REPAYMENT_DATE, Float.valueOf(prepayAmount), loanID);
final String loanRepaymentDate = dateFormat.format(todaysDate.getTime());
this.loanTransactionHelper.makeRepayment(loanRepaymentDate, Float.valueOf(prepayAmount), loanID);
loanStatusHashMap = LoanStatusChecker.getStatusOfLoan(this.requestSpec, this.responseSpec, loanID);
LoanStatusChecker.verifyLoanAccountIsClosed(loanStatusHashMap);
@@ -4210,8 +4189,8 @@ public class ClientLoanIntegrationTest {
String prepayAmount = String.valueOf(prepayDetail.get("amount"));
validateNumberForEqualWithMsg("verify pre-close amount", preCloseAmount, prepayAmount);
todaysDate = Calendar.getInstance(Utils.getTimeZoneOfTenant());
String LOAN_REPAYMENT_DATE = dateFormat.format(todaysDate.getTime());
this.loanTransactionHelper.makeRepayment(LOAN_REPAYMENT_DATE, Float.valueOf(prepayAmount), loanID);
final String loanRepaymentDate = dateFormat.format(todaysDate.getTime());
this.loanTransactionHelper.makeRepayment(loanRepaymentDate, Float.valueOf(prepayAmount), loanID);
loanStatusHashMap = LoanStatusChecker.getStatusOfLoan(this.requestSpec, this.responseSpec, loanID);
LoanStatusChecker.verifyLoanAccountIsClosed(loanStatusHashMap);
}
@@ -4386,6 +4365,14 @@ public class ClientLoanIntegrationTest {
Calendar fourMonthsfromNowCalendar = Calendar.getInstance(Utils.getTimeZoneOfTenant());
fourMonthsfromNowCalendar.add(Calendar.MONTH, -4);
// FINERACT-885: If the loan starts on day 27-31th of month and not all months have that
// many days, then loan payment will get reset to a day of month less than today's day
// and 4th payment will be in the past. In such case, start the loan a few days later,
// so that 4th payment is guaranteed to be in the future.
if (fourMonthsfromNowCalendar.get(Calendar.DAY_OF_MONTH) > 27) {
fourMonthsfromNowCalendar.add(Calendar.DAY_OF_MONTH, 4);
}
String fourMonthsfromNow = Utils.convertDateToURLFormat(fourMonthsfromNowCalendar);
this.loanTransactionHelper = new LoanTransactionHelper(this.requestSpec, this.responseSpec);
@@ -4498,7 +4485,9 @@ public class ClientLoanIntegrationTest {
// refund 20 means paid: principal 1980, interest 240, fees 50, penalty
// 0
fourMonthsfromNowCalendar.add(Calendar.MONTH, 1);
// FINERACT-885: As loan may not have started exactly four months ago,
// make final payment today and not four months from start (as that may be in the future)
fourMonthsfromNowCalendar.setTime(Utils.getLocalDateOfTenant().toDate());
final String now = Utils.convertDateToURLFormat(fourMonthsfromNowCalendar);
this.loanTransactionHelper.makeRefundByCash(now, Float.valueOf("20"), loanID);
@@ -4547,6 +4536,14 @@ public class ClientLoanIntegrationTest {
Calendar fourMonthsfromNowCalendar = Calendar.getInstance(Utils.getTimeZoneOfTenant());
fourMonthsfromNowCalendar.add(Calendar.MONTH, -4);
// FINERACT-885: If the loan starts on day 27-31th of month and not all months have that
// many days, then loan payment will get reset to a day of month less than today's day
// and 4th payment will be in the past. In such case, start the loan a few days later,
// so that 4th payment is guaranteed to be in the future.
if (fourMonthsfromNowCalendar.get(Calendar.DAY_OF_MONTH) > 27) {
fourMonthsfromNowCalendar.add(Calendar.DAY_OF_MONTH, 4);
}
String fourMonthsfromNow = Utils.convertDateToURLFormat(fourMonthsfromNowCalendar);
this.loanTransactionHelper = new LoanTransactionHelper(this.requestSpec, this.responseSpec);
@@ -4657,7 +4654,9 @@ public class ClientLoanIntegrationTest {
// refund 20 means paid: principal 1980, interest 240, fees 50, penalty
// 0
fourMonthsfromNowCalendar.add(Calendar.MONTH, 1);
// FINERACT-885: As loan may not have started exactly four months ago,
// make final payment today and not four months from start (as that may be in the future)
fourMonthsfromNowCalendar.setTime(Utils.getLocalDateOfTenant().toDate());
final String now = Utils.convertDateToURLFormat(fourMonthsfromNowCalendar);
this.loanTransactionHelper.makeRefundByCash(now, Float.valueOf("20"), loanID);
@@ -4705,6 +4704,14 @@ public class ClientLoanIntegrationTest {
Calendar fourMonthsfromNowCalendar = Calendar.getInstance(Utils.getTimeZoneOfTenant());
fourMonthsfromNowCalendar.add(Calendar.MONTH, -4);
// FINERACT-885: If the loan starts on day 27-31th of month and not all months have that
// many days, then loan payment will get reset to a day of month less than today's day
// and 4th payment will be in the past. In such case, start the loan a few days later,
// so that 4th payment is guaranteed to be in the future.
if (fourMonthsfromNowCalendar.get(Calendar.DAY_OF_MONTH) > 27) {
fourMonthsfromNowCalendar.add(Calendar.DAY_OF_MONTH, 4);
}
String fourMonthsfromNow = Utils.convertDateToURLFormat(fourMonthsfromNowCalendar);
this.loanTransactionHelper = new LoanTransactionHelper(this.requestSpec, this.responseSpec);
@@ -4836,22 +4843,24 @@ public class ClientLoanIntegrationTest {
// refund 20 means paid: principal 1980, interest 240, fees 50, penalty
// 0
Float TRANSFER_AMOUNT = 20f;
Float transferAmountValue = 20f;
fourMonthsfromNowCalendar.add(Calendar.MONTH, 1);
// FINERACT-885: As loan may not have started exactly four months ago,
// make final payment today and not four months from start (as that may be in the future)
fourMonthsfromNowCalendar.setTime(Utils.getLocalDateOfTenant().toDate());
final String now = Utils.convertDateToURLFormat(fourMonthsfromNowCalendar);
final String FROM_LOAN_ACCOUNT_TYPE = "1";
final String TO_SAVINGS_ACCOUNT_TYPE = "2";
this.accountTransferHelper.refundLoanByTransfer(now, clientID, loanID, clientID, savingsId, FROM_LOAN_ACCOUNT_TYPE,
TO_SAVINGS_ACCOUNT_TYPE, TRANSFER_AMOUNT.toString());
TO_SAVINGS_ACCOUNT_TYPE, transferAmountValue.toString());
Float toSavingsBalance = Float.valueOf(MINIMUM_OPENING_BALANCE);
HashMap toSavingsSummaryAfter = this.savingsAccountHelper.getSavingsSummary(savingsId);
toSavingsBalance += TRANSFER_AMOUNT;
toSavingsBalance += transferAmountValue;
// Verifying toSavings Account Balance after Account Transfer
assertEquals(toSavingsBalance, toSavingsSummaryAfter.get("accountBalance"),
@@ -4875,14 +4884,14 @@ public class ClientLoanIntegrationTest {
// refund 2000 means paid: principal 0, interest 220, fees 50, penalty 0
// final String now = Utils.convertDate(fourMonthsfromNowCalendar);
TRANSFER_AMOUNT = 2000f;
transferAmountValue = 2000f;
this.accountTransferHelper.refundLoanByTransfer(now, clientID, loanID, clientID, savingsId, FROM_LOAN_ACCOUNT_TYPE,
TO_SAVINGS_ACCOUNT_TYPE, TRANSFER_AMOUNT.toString());
TO_SAVINGS_ACCOUNT_TYPE, transferAmountValue.toString());
toSavingsSummaryAfter = this.savingsAccountHelper.getSavingsSummary(savingsId);
toSavingsBalance += TRANSFER_AMOUNT;
toSavingsBalance += transferAmountValue;
// Verifying toSavings Account Balance after Account Transfer
assertEquals(toSavingsBalance, toSavingsSummaryAfter.get("accountBalance"),
@@ -4948,8 +4957,8 @@ public class ClientLoanIntegrationTest {
.withMoratorium("2", "3").withLoanProductConfiguration(loanProductConfigurationAsFalse).build(null));
LOG.info("-------------------LOAN PRODUCT CREATED WITH ATTRIBUTE CONFIGURATION AS FALSE---------------------- {}", loanProductID);
/*
* Try to override attribute values in loan account when attribute
* configurations are set to false at product level
* Try to override attribute values in loan account when attribute configurations are set to false at product
* level
*/
loanID = applyForLoanApplicationWithProductConfigurationAsFalse(clientID, loanProductID, proposedAmount);
LOG.info("--------------------------LOAN CREATED WITH ID------------------------- {}", loanID);
@@ -656,9 +656,8 @@ public class ClientSavingsIntegrationTest {
}
/***
* Test case for overdraft account functionality. Open account with zero
* balance, perform transactions then post interest and verify posted
* interest
* Test case for overdraft account functionality. Open account with zero balance, perform transactions then post
* interest and verify posted interest
*/
@SuppressWarnings("unchecked")
@Test
@@ -675,8 +674,7 @@ public class ClientSavingsIntegrationTest {
final String minBalanceForInterestCalculation = null;
/***
* Create savings product with zero opening balance and overdraft
* enabled
* Create savings product with zero opening balance and overdraft enabled
*/
final String zeroOpeningBalance = "0.0";
final String minRequiredBalance = null;
@@ -734,9 +732,8 @@ public class ClientSavingsIntegrationTest {
Float balance = Float.valueOf(zeroOpeningBalance);
/***
* Perform withdraw transaction, verify account balance(account balance
* will go to negative as no deposits are there prior to this
* transaction)
* Perform withdraw transaction, verify account balance(account balance will go to negative as no deposits are
* there prior to this transaction)
*/
Integer withdrawTransactionId = (Integer) this.savingsAccountHelper.withdrawalFromSavingsAccount(savingsId, WITHDRAW_AMOUNT,
ACTIVATION_DATE, CommonConstants.RESPONSE_RESOURCE_ID);
@@ -746,8 +743,7 @@ public class ClientSavingsIntegrationTest {
assertEquals(balance, withdrawTransaction.get("runningBalance"), "Verifying Balance after Withdrawal");
/***
* Perform Deposit transaction on last day of month and verify account
* balance.
* Perform Deposit transaction on last day of month and verify account balance.
*
* @param transactionDate
* this value is every time last day of previous month
@@ -768,9 +764,8 @@ public class ClientSavingsIntegrationTest {
Float actualInterestPosted = Float.valueOf(summary.get("totalInterestPosted").toString());
/***
* Calculate expected interest to be posted, interest should be posted
* for one day only because deposit transaction happened on last day of
* month before this account balance is negative.
* Calculate expected interest to be posted, interest should be posted for one day only because deposit
* transaction happened on last day of month before this account balance is negative.
*/
final Float nominalAnnualInterest = Float.valueOf(accountDetails.get("nominalAnnualInterestRate").toString());
final HashMap interestCalculationDaysInYearType = (HashMap) accountDetails.get("interestCalculationDaysInYearType");
@@ -781,8 +776,7 @@ public class ClientSavingsIntegrationTest {
Float interestPosted = (float) (interestPerDay * balance * 1);
/***
* Apply rounding on interestPosted, actualInterestPosted and verify
* both are same
* Apply rounding on interestPosted, actualInterestPosted and verify both are same
*/
DecimalFormat decimalFormat = new DecimalFormat("", new DecimalFormatSymbols(Locale.US));
decimalFormat.applyPattern("#.###");
@@ -812,8 +806,7 @@ public class ClientSavingsIntegrationTest {
final String minBalanceForInterestCalculation = null;
/***
* Create savings product with zero opening balance and overdraft
* enabled
* Create savings product with zero opening balance and overdraft enabled
*/
final String zeroOpeningBalance = "0.0";
final String minRequiredBalance = null;
@@ -873,11 +866,10 @@ public class ClientSavingsIntegrationTest {
// yyyy",Locale.US);
Calendar transactionDate = Calendar.getInstance();
transactionDate.set(Calendar.DAY_OF_MONTH, 2);
String TRANSACTION_DATE = dateFormat.format(transactionDate.getTime());
String transactionDateValue = dateFormat.format(transactionDate.getTime());
/***
* Perform Deposit transaction on last day of month and verify account
* balance.
* Perform Deposit transaction on last day of month and verify account balance.
*
* @param transactionDate
* this value is every time last day of previous month
@@ -890,9 +882,8 @@ public class ClientSavingsIntegrationTest {
assertEquals(balance, depositTransaction.get("runningBalance"), "Verifying Balance after Deposit");
/***
* Calculate expected interest to be posted, interest should be posted
* for one day only because deposit transaction happened on last day of
* month before this account balance is negative.
* Calculate expected interest to be posted, interest should be posted for one day only because deposit
* transaction happened on last day of month before this account balance is negative.
*/
this.savingsAccountHelper.postInterestForSavings(savingsId);
HashMap accountDetails = this.savingsAccountHelper.getSavingsDetails(savingsId);
@@ -908,8 +899,7 @@ public class ClientSavingsIntegrationTest {
Float interestPosted = (float) (interestPerDay * balance * 1);
/***
* Apply rounding on interestPosted, actualInterestPosted and verify
* both are same
* Apply rounding on interestPosted, actualInterestPosted and verify both are same
*/
DecimalFormat decimalFormat = new DecimalFormat("", new DecimalFormatSymbols(Locale.US));
decimalFormat.applyPattern("#.###");
@@ -917,7 +907,7 @@ public class ClientSavingsIntegrationTest {
accountDetailsPostInterestPosted = Float.valueOf(decimalFormat.format(accountDetailsPostInterestPosted));
assertEquals(interestPosted, accountDetailsPostInterestPosted, "Verifying interest posted");
this.savingsAccountHelper.postInterestAsOnSavings(savingsId, TRANSACTION_DATE);
this.savingsAccountHelper.postInterestAsOnSavings(savingsId, transactionDateValue);
HashMap accountTransactionDetails = this.savingsAccountHelper.getSavingsDetails(savingsId);
summary = (HashMap) accountDetails.get("summary");
Float accountDetailsPostInterest = Float.valueOf(summary.get("totalInterestPosted").toString());
@@ -931,8 +921,7 @@ public class ClientSavingsIntegrationTest {
interestPosted = (float) (interestPerDay * balance * 1);
/***
* Apply rounding on interestPosted, actualInterestPosted and verify
* both are same
* Apply rounding on interestPosted, actualInterestPosted and verify both are same
*/
decimalFormat = new DecimalFormat("", new DecimalFormatSymbols(Locale.US));
decimalFormat.applyPattern("#.###");
@@ -942,9 +931,9 @@ public class ClientSavingsIntegrationTest {
LOG.info("-----Post Interest As on Successfully Worked----------");
transactionDate.set(Calendar.DAY_OF_MONTH, 3);
TRANSACTION_DATE = dateFormat.format(transactionDate.getTime());
transactionDateValue = dateFormat.format(transactionDate.getTime());
this.savingsAccountHelper.postInterestAsOnSavings(savingsId, TRANSACTION_DATE);
this.savingsAccountHelper.postInterestAsOnSavings(savingsId, transactionDateValue);
accountTransactionDetails = this.savingsAccountHelper.getSavingsDetails(savingsId);
summary = (HashMap) accountDetails.get("summary");
accountDetailsPostInterest = Float.valueOf(summary.get("totalInterestPosted").toString());
@@ -958,8 +947,7 @@ public class ClientSavingsIntegrationTest {
interestPosted = (float) (interestPerDay * balance * 1);
/***
* Apply rounding on interestPosted, actualInterestPosted and verify
* both are same
* Apply rounding on interestPosted, actualInterestPosted and verify both are same
*/
decimalFormat = new DecimalFormat("", new DecimalFormatSymbols(Locale.US));
decimalFormat.applyPattern("#.###");
@@ -973,9 +961,9 @@ public class ClientSavingsIntegrationTest {
Calendar transactionCalendarDateFormat = Calendar.getInstance();
transactionCalendarDateFormat.add(Calendar.DAY_OF_MONTH, 0);
transactionDate.set(Calendar.DAY_OF_MONTH, 22);
TRANSACTION_DATE = dateFormat.format(transactionDate.getTime());
transactionDateValue = dateFormat.format(transactionDate.getTime());
if (Calendar.DAY_OF_MONTH >= 22) {
this.savingsAccountHelper.postInterestAsOnSavings(savingsId, TRANSACTION_DATE);
this.savingsAccountHelper.postInterestAsOnSavings(savingsId, transactionDateValue);
accountTransactionDetails = this.savingsAccountHelper.getSavingsDetails(savingsId);
summary = (HashMap) accountTransactionDetails.get("summary");
accountDetailsPostInterest = Float.valueOf(summary.get("totalInterestPosted").toString());
@@ -989,8 +977,7 @@ public class ClientSavingsIntegrationTest {
interestPosted = (float) (interestPerDay * balance * 19);
/***
* Apply rounding on interestPosted, actualInterestPosted and verify
* both are same
* Apply rounding on interestPosted, actualInterestPosted and verify both are same
*/
decimalFormat = new DecimalFormat("", new DecimalFormatSymbols(Locale.US));
decimalFormat.applyPattern("#.###");
@@ -1002,11 +989,11 @@ public class ClientSavingsIntegrationTest {
DateFormat lastTransactionDateFormat = new SimpleDateFormat("dd MMMM yyyy", Locale.US);
Calendar postedLastDate = Calendar.getInstance();
int numberOfDateOfMonth = postedLastDate.getActualMaximum(Calendar.DAY_OF_MONTH);
TRANSACTION_DATE = lastTransactionDateFormat.format(transactionDate.getTime());
transactionDateValue = lastTransactionDateFormat.format(transactionDate.getTime());
if (Calendar.DAY_OF_MONTH == numberOfDateOfMonth) {
this.savingsAccountHelper.postInterestAsOnSavings(savingsId, TRANSACTION_DATE);
this.savingsAccountHelper.postInterestAsOnSavings(savingsId, transactionDateValue);
accountTransactionDetails = this.savingsAccountHelper.getSavingsDetails(savingsId);
summary = (HashMap) accountTransactionDetails.get("summary");
accountDetailsPostInterest = Float.valueOf(summary.get("totalInterestPosted").toString());
@@ -1020,8 +1007,7 @@ public class ClientSavingsIntegrationTest {
interestPosted = (float) (interestPerDay * balance * 8);
/***
* Apply rounding on interestPosted, actualInterestPosted and verify
* both are same
* Apply rounding on interestPosted, actualInterestPosted and verify both are same
*/
decimalFormat = new DecimalFormat("", new DecimalFormatSymbols(Locale.US));
decimalFormat.applyPattern("#.###");
@@ -1032,8 +1018,8 @@ public class ClientSavingsIntegrationTest {
}
transactionDate.set(Calendar.DAY_OF_MONTH, 1);
TRANSACTION_DATE = dateFormat.format(transactionDate.getTime());
this.savingsAccountHelper.postInterestAsOnSavings(savingsId, TRANSACTION_DATE);
transactionDateValue = dateFormat.format(transactionDate.getTime());
this.savingsAccountHelper.postInterestAsOnSavings(savingsId, transactionDateValue);
accountTransactionDetails = this.savingsAccountHelper.getSavingsDetails(savingsId);
summary = (HashMap) accountTransactionDetails.get("summary");
accountDetailsPostInterest = Float.valueOf(summary.get("totalInterestPosted").toString());
@@ -1047,8 +1033,7 @@ public class ClientSavingsIntegrationTest {
interestPosted = (float) (interestPerDay * balance * 1);
/***
* Apply rounding on interestPosted, actualInterestPosted and verify
* both are same
* Apply rounding on interestPosted, actualInterestPosted and verify both are same
*/
decimalFormat = new DecimalFormat("", new DecimalFormatSymbols(Locale.US));
decimalFormat.applyPattern("#.###");
@@ -1072,8 +1057,7 @@ public class ClientSavingsIntegrationTest {
final String minBalanceForInterestCalculation = null;
/***
* Create savings product with zero opening balance and overdraft
* enabled
* Create savings product with zero opening balance and overdraft enabled
*/
final String zeroOpeningBalance = "0.0";
final String minRequiredBalance = null;
@@ -1133,12 +1117,11 @@ public class ClientSavingsIntegrationTest {
// yyyy", Locale.US);
Calendar transactionDate = Calendar.getInstance();
transactionDate.set(Calendar.DAY_OF_MONTH, 2);
String TRANSACTION_DATE = dateFormat.format(transactionDate.getTime());
String transactionDateValue = dateFormat.format(transactionDate.getTime());
/***
* Perform withdraw transaction, verify account balance(account balance
* will go to negative as no deposits are there prior to this
* transaction)
* Perform withdraw transaction, verify account balance(account balance will go to negative as no deposits are
* there prior to this transaction)
*/
Integer withdrawTransactionId = (Integer) this.savingsAccountHelper.withdrawalFromSavingsAccount(savingsId, WITHDRAW_AMOUNT,
ACTIVATION_DATE, CommonConstants.RESPONSE_RESOURCE_ID);
@@ -1148,8 +1131,7 @@ public class ClientSavingsIntegrationTest {
assertEquals(balance, withdrawTransaction.get("runningBalance"), "Verifying Balance after Withdrawal");
/***
* Perform Deposit transaction on last day of month and verify account
* balance.
* Perform Deposit transaction on last day of month and verify account balance.
*
* @param transactionDate
* this value is every time last day of previous month
@@ -1162,9 +1144,8 @@ public class ClientSavingsIntegrationTest {
assertEquals(balance, depositTransaction.get("runningBalance"), "Verifying Balance after Deposit");
/***
* Calculate expected interest to be posted, interest should be posted
* for one day only because deposit transaction happened on last day of
* month before this account balance is negative.
* Calculate expected interest to be posted, interest should be posted for one day only because deposit
* transaction happened on last day of month before this account balance is negative.
*/
this.savingsAccountHelper.postInterestForSavings(savingsId);
HashMap accountDetails = this.savingsAccountHelper.getSavingsDetails(savingsId);
@@ -1180,8 +1161,7 @@ public class ClientSavingsIntegrationTest {
Float interestPosted = (float) (interestPerDay * balance * 1);
/***
* Apply rounding on interestPosted, actualInterestPosted and verify
* both are same
* Apply rounding on interestPosted, actualInterestPosted and verify both are same
*/
DecimalFormat decimalFormat = new DecimalFormat("", new DecimalFormatSymbols(Locale.US));
decimalFormat.applyPattern("#.###");
@@ -1189,7 +1169,7 @@ public class ClientSavingsIntegrationTest {
accountDetailsPostInterestPosted = Float.valueOf(decimalFormat.format(accountDetailsPostInterestPosted));
assertEquals(interestPosted, accountDetailsPostInterestPosted, "Verifying interest posted");
this.savingsAccountHelper.postInterestAsOnSavings(savingsId, TRANSACTION_DATE);
this.savingsAccountHelper.postInterestAsOnSavings(savingsId, transactionDateValue);
HashMap accountTransactionDetails = this.savingsAccountHelper.getSavingsDetails(savingsId);
summary = (HashMap) accountDetails.get("summary");
Float accountDetailsPostInterest = Float.valueOf(summary.get("totalInterestPosted").toString());
@@ -1203,8 +1183,7 @@ public class ClientSavingsIntegrationTest {
interestPosted = (float) (interestPerDay * balance * 1);
/***
* Apply rounding on interestPosted, actualInterestPosted and verify
* both are same
* Apply rounding on interestPosted, actualInterestPosted and verify both are same
*/
decimalFormat = new DecimalFormat("", new DecimalFormatSymbols(Locale.US));
decimalFormat.applyPattern("#.###");
@@ -1214,9 +1193,9 @@ public class ClientSavingsIntegrationTest {
LOG.info("-----Post Interest As on Successfully Worked----------");
transactionDate.set(Calendar.DAY_OF_MONTH, 3);
TRANSACTION_DATE = dateFormat.format(transactionDate.getTime());
transactionDateValue = dateFormat.format(transactionDate.getTime());
this.savingsAccountHelper.postInterestAsOnSavings(savingsId, TRANSACTION_DATE);
this.savingsAccountHelper.postInterestAsOnSavings(savingsId, transactionDateValue);
accountTransactionDetails = this.savingsAccountHelper.getSavingsDetails(savingsId);
summary = (HashMap) accountDetails.get("summary");
accountDetailsPostInterest = Float.valueOf(summary.get("totalInterestPosted").toString());
@@ -1230,8 +1209,7 @@ public class ClientSavingsIntegrationTest {
interestPosted = (float) (interestPerDay * balance * 1);
/***
* Apply rounding on interestPosted, actualInterestPosted and verify
* both are same
* Apply rounding on interestPosted, actualInterestPosted and verify both are same
*/
decimalFormat = new DecimalFormat("", new DecimalFormatSymbols(Locale.US));
decimalFormat.applyPattern("#.###");
@@ -1245,9 +1223,9 @@ public class ClientSavingsIntegrationTest {
Calendar transactionCalendarDateFormat = Calendar.getInstance();
transactionCalendarDateFormat.add(Calendar.DAY_OF_MONTH, 0);
transactionDate.set(Calendar.DAY_OF_MONTH, 22);
TRANSACTION_DATE = dateFormat.format(transactionDate.getTime());
transactionDateValue = dateFormat.format(transactionDate.getTime());
if (Calendar.DAY_OF_MONTH >= 22) {
this.savingsAccountHelper.postInterestAsOnSavings(savingsId, TRANSACTION_DATE);
this.savingsAccountHelper.postInterestAsOnSavings(savingsId, transactionDateValue);
accountTransactionDetails = this.savingsAccountHelper.getSavingsDetails(savingsId);
summary = (HashMap) accountTransactionDetails.get("summary");
accountDetailsPostInterest = Float.valueOf(summary.get("totalInterestPosted").toString());
@@ -1261,8 +1239,7 @@ public class ClientSavingsIntegrationTest {
interestPosted = (float) (interestPerDay * balance * 19);
/***
* Apply rounding on interestPosted, actualInterestPosted and verify
* both are same
* Apply rounding on interestPosted, actualInterestPosted and verify both are same
*/
decimalFormat = new DecimalFormat("", new DecimalFormatSymbols(Locale.US));
decimalFormat.applyPattern("#.###");
@@ -1274,11 +1251,11 @@ public class ClientSavingsIntegrationTest {
DateFormat lastTransactionDateFormat = new SimpleDateFormat("dd MMMM yyyy", Locale.US);
Calendar postedLastDate = Calendar.getInstance();
int numberOfDateOfMonth = postedLastDate.getActualMaximum(Calendar.DAY_OF_MONTH);
TRANSACTION_DATE = lastTransactionDateFormat.format(transactionDate.getTime());
transactionDateValue = lastTransactionDateFormat.format(transactionDate.getTime());
if (Calendar.DAY_OF_MONTH == numberOfDateOfMonth) {
this.savingsAccountHelper.postInterestAsOnSavings(savingsId, TRANSACTION_DATE);
this.savingsAccountHelper.postInterestAsOnSavings(savingsId, transactionDateValue);
accountTransactionDetails = this.savingsAccountHelper.getSavingsDetails(savingsId);
summary = (HashMap) accountTransactionDetails.get("summary");
accountDetailsPostInterest = Float.valueOf(summary.get("totalInterestPosted").toString());
@@ -1292,8 +1269,7 @@ public class ClientSavingsIntegrationTest {
interestPosted = (float) (interestPerDay * balance * 8);
/***
* Apply rounding on interestPosted, actualInterestPosted and verify
* both are same
* Apply rounding on interestPosted, actualInterestPosted and verify both are same
*/
decimalFormat = new DecimalFormat("", new DecimalFormatSymbols(Locale.US));
decimalFormat.applyPattern("#.###");
@@ -1304,8 +1280,8 @@ public class ClientSavingsIntegrationTest {
}
transactionDate.set(Calendar.DAY_OF_MONTH, 1);
TRANSACTION_DATE = dateFormat.format(transactionDate.getTime());
this.savingsAccountHelper.postInterestAsOnSavings(savingsId, TRANSACTION_DATE);
transactionDateValue = dateFormat.format(transactionDate.getTime());
this.savingsAccountHelper.postInterestAsOnSavings(savingsId, transactionDateValue);
accountTransactionDetails = this.savingsAccountHelper.getSavingsDetails(savingsId);
summary = (HashMap) accountTransactionDetails.get("summary");
accountDetailsPostInterest = Float.valueOf(summary.get("totalInterestPosted").toString());
@@ -1319,8 +1295,7 @@ public class ClientSavingsIntegrationTest {
interestPosted = (float) (interestPerDay * balance * 1);
/***
* Apply rounding on interestPosted, actualInterestPosted and verify
* both are same
* Apply rounding on interestPosted, actualInterestPosted and verify both are same
*/
decimalFormat = new DecimalFormat("", new DecimalFormatSymbols(Locale.US));
decimalFormat.applyPattern("#.###");
@@ -1344,8 +1319,7 @@ public class ClientSavingsIntegrationTest {
final String minBalanceForInterestCalculation = null;
/***
* Create savings product with zero opening balance and overdraft
* enabled
* Create savings product with zero opening balance and overdraft enabled
*/
final String zeroOpeningBalance = "0.0";
final String minRequiredBalance = null;
@@ -1408,9 +1382,8 @@ public class ClientSavingsIntegrationTest {
Float balance = Float.valueOf(zeroOpeningBalance);
/***
* Perform withdraw transaction, verify account balance(account balance
* will go to negative as no deposits are there prior to this
* transaction)
* Perform withdraw transaction, verify account balance(account balance will go to negative as no deposits are
* there prior to this transaction)
*/
Integer withdrawTransactionId = (Integer) this.savingsAccountHelper.withdrawalFromSavingsAccount(savingsId, WITHDRAW_AMOUNT,
ACTIVATION_DATE, CommonConstants.RESPONSE_RESOURCE_ID);
@@ -1420,8 +1393,7 @@ public class ClientSavingsIntegrationTest {
assertEquals(balance, withdrawTransaction.get("runningBalance"), "Verifying Balance after Withdrawal");
/***
* Perform Deposit transaction on last day of month and verify account
* balance.
* Perform Deposit transaction on last day of month and verify account balance.
*
* @param transactionDate
* this value is every time last day of previous month
@@ -1442,9 +1414,8 @@ public class ClientSavingsIntegrationTest {
Float actualInterestPosted = Float.valueOf(summary.get("totalInterestPosted").toString());
/***
* Calculate expected interest to be posted, interest should be posted
* for one day only because deposit transaction happened on last day of
* month before this account balance is negative.
* Calculate expected interest to be posted, interest should be posted for one day only because deposit
* transaction happened on last day of month before this account balance is negative.
*/
this.savingsAccountHelper.postInterestAsOnSavings(savingsId, POSTED_TRANSACTION_DATE);
HashMap accountDetailsPostInterest = this.savingsAccountHelper.getSavingsDetails(savingsId);
@@ -1453,9 +1424,8 @@ public class ClientSavingsIntegrationTest {
Float accountDetailsPostInterestPosted = Float.valueOf(summary.get("totalInterestPosted").toString());
/***
* Calculate expected interest to be posted, interest should be posted
* for one day only because deposit transaction happened on last day of
* month before this account balance is negative.
* Calculate expected interest to be posted, interest should be posted for one day only because deposit
* transaction happened on last day of month before this account balance is negative.
*/
final Float nominalAnnualInterest = Float.valueOf(accountDetails.get("nominalAnnualInterestRate").toString());
final HashMap interestCalculationDaysInYearType = (HashMap) accountDetails.get("interestCalculationDaysInYearType");
@@ -1466,8 +1436,7 @@ public class ClientSavingsIntegrationTest {
Float interestPosted = (float) (interestPerDay * balance * 1);
/***
* Apply rounding on interestPosted, actualInterestPosted and verify
* both are same
* Apply rounding on interestPosted, actualInterestPosted and verify both are same
*/
DecimalFormat decimalFormat = new DecimalFormat("", new DecimalFormatSymbols(Locale.US));
decimalFormat.applyPattern("#.###");
@@ -1518,8 +1487,7 @@ public class ClientSavingsIntegrationTest {
final String minBalanceForInterestCalculation = null;
/***
* Create savings product with zero opening balance and overdraft
* enabled
* Create savings product with zero opening balance and overdraft enabled
*/
final String zeroOpeningBalance = "0.0";
final String minRequiredBalance = null;
@@ -1587,9 +1555,8 @@ public class ClientSavingsIntegrationTest {
Float balance = Float.valueOf(zeroOpeningBalance);
/***
* Perform withdraw transaction, verify account balance(account balance
* will go to negative as no deposits are there prior to this
* transaction)
* Perform withdraw transaction, verify account balance(account balance will go to negative as no deposits are
* there prior to this transaction)
*/
Integer withdrawTransactionId = (Integer) this.savingsAccountHelper.withdrawalFromSavingsAccount(savingsId, WITHDRAW_AMOUNT,
ACTIVATION_DATE, CommonConstants.RESPONSE_RESOURCE_ID);
@@ -1599,8 +1566,7 @@ public class ClientSavingsIntegrationTest {
assertEquals(balance, withdrawTransaction.get("runningBalance"), "Verifying Balance after Withdrawal");
/***
* Perform Deposit transaction on last day of month and verify account
* balance.
* Perform Deposit transaction on last day of month and verify account balance.
*
* @param transactionDate
* this value is every time last day of previous month
@@ -1621,9 +1587,8 @@ public class ClientSavingsIntegrationTest {
Float actualInterestPosted = Float.valueOf(summary.get("totalInterestPosted").toString());
/***
* Calculate expected interest to be posted, interest should be posted
* for one day only because deposit transaction happened on last day of
* month before this account balance is negative.
* Calculate expected interest to be posted, interest should be posted for one day only because deposit
* transaction happened on last day of month before this account balance is negative.
*/
final Float nominalAnnualInterest = Float.valueOf(accountDetails.get("nominalAnnualInterestRate").toString());
final HashMap interestCalculationDaysInYearType = (HashMap) accountDetails.get("interestCalculationDaysInYearType");
@@ -1634,8 +1599,7 @@ public class ClientSavingsIntegrationTest {
Float interestPosted = (float) (interestPerDay * balance * 1);
/***
* Apply rounding on interestPosted, actualInterestPosted and verify
* both are same
* Apply rounding on interestPosted, actualInterestPosted and verify both are same
*/
DecimalFormat decimalFormat = new DecimalFormat("", new DecimalFormatSymbols(Locale.US));
decimalFormat.applyPattern("#.###");
@@ -1826,9 +1790,9 @@ public class ClientSavingsIntegrationTest {
final DateTimeFormatter formatter = DateTimeFormat.forPattern("dd MMMM yyyy");
LocalDate transactionDate = new LocalDate();
for (int i = 0; i < 4; i++) {
String TRANSACTION_DATE = formatter.print(transactionDate);
String transactionDateValue = formatter.print(transactionDate);
Integer depositTransactionId = (Integer) this.savingsAccountHelper.depositToSavingsAccount(savingsList.get(i), DEPOSIT_AMOUNT,
TRANSACTION_DATE, CommonConstants.RESPONSE_RESOURCE_ID);
transactionDateValue, CommonConstants.RESPONSE_RESOURCE_ID);
transactionDate = transactionDate.minusDays(30);
}
@@ -1857,9 +1821,9 @@ public class ClientSavingsIntegrationTest {
balance -= chargeAmt;
assertEquals(balance, summary.get("accountBalance"), "Verifying account Balance");
String TRANSACTION_DATE = formatter.print(new LocalDate());
String transactionDateValue = formatter.print(new LocalDate());
Integer depositTransactionId = (Integer) this.savingsAccountHelper.depositToSavingsAccount(savingsList.get(1), DEPOSIT_AMOUNT,
TRANSACTION_DATE, CommonConstants.RESPONSE_RESOURCE_ID);
transactionDateValue, CommonConstants.RESPONSE_RESOURCE_ID);
savingsStatusHashMap = SavingsStatusChecker.getStatusOfSavings(this.requestSpec, this.responseSpec, savingsList.get(1));
SavingsStatusChecker.verifySavingsIsActive(savingsStatusHashMap);
savingsStatusHashMap = SavingsStatusChecker.getSubStatusOfSavings(this.requestSpec, this.responseSpec, savingsList.get(1));
@@ -1876,9 +1840,9 @@ public class ClientSavingsIntegrationTest {
balance -= chargeAmt;
assertEquals(balance, summary.get("accountBalance"), "Verifying account Balance");
TRANSACTION_DATE = formatter.print(new LocalDate());
transactionDateValue = formatter.print(new LocalDate());
depositTransactionId = (Integer) this.savingsAccountHelper.depositToSavingsAccount(savingsList.get(2), DEPOSIT_AMOUNT,
TRANSACTION_DATE, CommonConstants.RESPONSE_RESOURCE_ID);
transactionDateValue, CommonConstants.RESPONSE_RESOURCE_ID);
savingsStatusHashMap = SavingsStatusChecker.getStatusOfSavings(this.requestSpec, this.responseSpec, savingsList.get(2));
SavingsStatusChecker.verifySavingsIsActive(savingsStatusHashMap);
savingsStatusHashMap = SavingsStatusChecker.getSubStatusOfSavings(this.requestSpec, this.responseSpec, savingsList.get(2));
@@ -1957,13 +1921,10 @@ public class ClientSavingsIntegrationTest {
}
/*
* private void verifySavingsInterest(final Object savingsInterest) {
* LOG.info(
* "--------------------VERIFYING THE BALANCE, INTEREST --------------------------"
* );
* private void verifySavingsInterest(final Object savingsInterest) { LOG.info(
* "--------------------VERIFYING THE BALANCE, INTEREST --------------------------" );
*
* assertEquals("Verifying Interest Calculation", Float.valueOf("238.3399"),
* savingsInterest); }
* assertEquals("Verifying Interest Calculation", Float.valueOf("238.3399"), savingsInterest); }
*/
@SuppressWarnings("unchecked")
@@ -2082,8 +2043,8 @@ public class ClientSavingsIntegrationTest {
}
/**
* incorrect savings account balance when charge transaction is reversed
* during an overdraft recalculate Daily Balances
* incorrect savings account balance when charge transaction is reversed during an overdraft recalculate Daily
* Balances
*/
@Test
@@ -49,7 +49,7 @@ public class ConcurrencyIntegrationTest {
private static final String NO_ACCOUNTING = "1";
final int MYTHREADS = 30;
static final int MYTHREADS = 30;
@BeforeEach
public void setup() {
@@ -46,8 +46,7 @@ import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
/**
* Tests loan schedule change based on group meeting changes and loan
* rescheduling
* Tests loan schedule change based on group meeting changes and loan rescheduling
**/
@SuppressWarnings({ "rawtypes" })
@Disabled
@@ -83,15 +83,13 @@ public class FinancialActivityAccountsTest {
Assertions.assertNotNull(financialActivityAccountId);
/***
* Fetch Created Financial Activity to Account Mapping and validate
* created values
* Fetch Created Financial Activity to Account Mapping and validate created values
**/
assertFinancialActivityAccountCreation(financialActivityAccountId, LIABILITY_TRANSFER_FINANCIAL_ACTIVITY_ID,
liabilityTransferAccount);
/**
* Update Existing Financial Activity to Account Mapping and assert
* changes
* Update Existing Financial Activity to Account Mapping and assert changes
**/
Account newLiabilityTransferAccount = accountHelper.createLiabilityAccount();
Assertions.assertNotNull(newLiabilityTransferAccount);
@@ -120,8 +118,7 @@ public class FinancialActivityAccountsTest {
duplicateFinancialActivityAccountError.get(0).get(CommonConstants.RESPONSE_ERROR_MESSAGE_CODE));
/**
* Associating incorrect GL account types with a financial activity
* should fail
* Associating incorrect GL account types with a financial activity should fail
**/
List<HashMap> invalidFinancialActivityAccountError = (List<HashMap>) financialActivityAccountHelper.updateFinancialActivityAccount(
financialActivityAccountId, assetTransferFinancialActivityId, newLiabilityTransferAccount.getAccountID(),
@@ -59,6 +59,7 @@ import org.joda.time.Months;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -104,10 +105,11 @@ public class FixedDepositTest {
// TODO Given the difference in calculation methods in test vs application,
// the exact values
// returned may differ enough to cause differences in rounding. Given this,
// we only compare the full
// digits. A proper solution would be to implement the exact interest
// we only compare that the result is within THRESHOLD of the expected amount.
// A proper solution would be to implement the exact interest
// calculation in this test,
// and then to compare the exact results
public static final Float THRESHOLD = 1.0f;
@BeforeEach
public void setup() {
@@ -121,8 +123,8 @@ public class FixedDepositTest {
}
/***
* Test case for Fixed Deposit Account premature closure with transaction
* type withdrawal and Cash Based accounting enabled
* Test case for Fixed Deposit Account premature closure with transaction type withdrawal and Cash Based accounting
* enabled
*/
@Test
public void testFixedDepositAccountWithPrematureClosureTypeWithdrawal() {
@@ -202,8 +204,7 @@ public class FixedDepositTest {
Float depositAmount = (Float) accountSummary.get("totalDeposits");
/***
* Verify journal entries posted for initial deposit transaction which
* happened at activation time
* Verify journal entries posted for initial deposit transaction which happened at activation time
*/
final JournalEntry[] assetAccountInitialEntry = { new JournalEntry(depositAmount, JournalEntry.TransactionType.DEBIT) };
final JournalEntry[] liablilityAccountInitialEntry = { new JournalEntry(depositAmount, JournalEntry.TransactionType.CREDIT) };
@@ -336,8 +337,7 @@ public class FixedDepositTest {
Float depositAmount = (Float) accountSummary.get("totalDeposits");
/***
* Verify journal entries posted for initial deposit transaction which
* happened at activation time
* Verify journal entries posted for initial deposit transaction which happened at activation time
*/
final JournalEntry[] assetAccountInitialEntry = { new JournalEntry(depositAmount, JournalEntry.TransactionType.DEBIT) };
final JournalEntry[] liablilityAccountInitialEntry = { new JournalEntry(depositAmount, JournalEntry.TransactionType.CREDIT) };
@@ -398,6 +398,7 @@ public class FixedDepositTest {
}
@Disabled // FINERACT-1099
@Test
public void testFixedDepositAccountClosureTypeWithdrawal_WITH_HOLD_TAX() throws InterruptedException {
this.fixedDepositProductHelper = new FixedDepositProductHelper(this.requestSpec, this.responseSpec);
@@ -479,8 +480,7 @@ public class FixedDepositTest {
Float depositAmount = (Float) accountSummary.get("totalDeposits");
/***
* Verify journal entries posted for initial deposit transaction which
* happened at activation time
* Verify journal entries posted for initial deposit transaction which happened at activation time
*/
final JournalEntry[] assetAccountInitialEntry = { new JournalEntry(depositAmount, JournalEntry.TransactionType.DEBIT) };
final JournalEntry[] liablilityAccountInitialEntry = { new JournalEntry(depositAmount, JournalEntry.TransactionType.CREDIT) };
@@ -686,8 +686,8 @@ public class FixedDepositTest {
}
/***
* Test case for FD Account premature closure with transaction transfers to
* savings account and Cash Based accounting enabled
* Test case for FD Account premature closure with transaction transfers to savings account and Cash Based
* accounting enabled
*/
@Test
public void testFixedDepositAccountWithPrematureClosureTypeTransferToSavings() {
@@ -777,8 +777,7 @@ public class FixedDepositTest {
Float depositAmount = (Float) accountSummary.get("totalDeposits");
/***
* Verify journal entries posted for initial deposit transaction which
* happened at activation time
* Verify journal entries posted for initial deposit transaction which happened at activation time
*/
final JournalEntry[] assetAccountInitialEntry = { new JournalEntry(depositAmount, JournalEntry.TransactionType.DEBIT) };
final JournalEntry[] liablilityAccountInitialEntry = { new JournalEntry(depositAmount, JournalEntry.TransactionType.CREDIT) };
@@ -834,9 +833,8 @@ public class FixedDepositTest {
Float prematurityAmount = (Float) fixedDepositData.get("maturityAmount");
/***
* Verify journal entry transactions for preclosure transaction As this
* transaction is an account transfer you should get financial account
* mapping details and verify amounts
* Verify journal entry transactions for preclosure transaction As this transaction is an account transfer you
* should get financial account mapping details and verify amounts
*/
this.journalEntryHelper.checkJournalEntryForLiabilityAccount(liabilityAccount, CLOSED_ON_DATE,
new JournalEntry(prematurityAmount, JournalEntry.TransactionType.CREDIT),
@@ -855,8 +853,8 @@ public class FixedDepositTest {
}
/***
* Test case for Fixed Deposit Account premature closure with transaction
* type ReInvest and Cash Based accounting enabled
* Test case for Fixed Deposit Account premature closure with transaction type ReInvest and Cash Based accounting
* enabled
*/
@Test
public void testFixedDepositAccountWithPrematureClosureTypeReinvest() {
@@ -930,8 +928,7 @@ public class FixedDepositTest {
Float depositAmount = (Float) accountSummary.get("totalDeposits");
/***
* Verify journal entries posted for initial deposit transaction which
* happened at activation time
* Verify journal entries posted for initial deposit transaction which happened at activation time
*/
final JournalEntry[] assetAccountInitialEntry = { new JournalEntry(depositAmount, JournalEntry.TransactionType.DEBIT) };
final JournalEntry[] liablilityAccountInitialEntry = { new JournalEntry(depositAmount, JournalEntry.TransactionType.CREDIT) };
@@ -982,7 +979,7 @@ public class FixedDepositTest {
todaysDate = Calendar.getInstance();
todaysDate.add(Calendar.MONTH, -1);
monthDayFormat.format(todaysDate.getTime());
String SUBMITTED_ON_DATE = dateFormat.format(todaysDate.getTime());
String submittedOnDate = dateFormat.format(todaysDate.getTime());
Integer clientId = ClientHelper.createClient(this.requestSpec, this.responseSpec);
Assertions.assertNotNull(clientId);
@@ -995,13 +992,13 @@ public class FixedDepositTest {
FixedDepositProductHelper.retrieveFixedDepositProductById(this.requestSpec, this.responseSpec, fixedDepositProductId.toString());
Integer fixedDepositAccountId = applyForFixedDepositApplication(clientId.toString(), fixedDepositProductId.toString(),
SUBMITTED_ON_DATE, WHOLE_TERM);
submittedOnDate, WHOLE_TERM);
Assertions.assertNotNull(fixedDepositAccountId);
todaysDate.add(Calendar.DATE, -1);
SUBMITTED_ON_DATE = dateFormat.format(todaysDate.getTime());
submittedOnDate = dateFormat.format(todaysDate.getTime());
HashMap modificationsHashMap = this.fixedDepositAccountHelper.updateFixedDepositAccount(clientId.toString(),
fixedDepositProductId.toString(), fixedDepositAccountId.toString(), VALID_FROM, VALID_TO, WHOLE_TERM, SUBMITTED_ON_DATE);
fixedDepositProductId.toString(), fixedDepositAccountId.toString(), VALID_FROM, VALID_TO, WHOLE_TERM, submittedOnDate);
Assertions.assertTrue(modificationsHashMap.containsKey("submittedOnDate"));
}
@@ -1230,10 +1227,8 @@ public class FixedDepositTest {
principal = FixedDepositAccountHelper.getPrincipalAfterCompoundingInterest(todaysDate, principal, depositPeriod, interestPerDay,
MONTHLY_INTERVAL, MONTHLY_INTERVAL);
principal = (float) Math.floor(principal);
maturityAmount = (float) Math.floor(maturityAmount);
LOG.info("{}", principal.toString());
Assertions.assertEquals(principal, maturityAmount, "Verifying Maturity amount for Fixed Deposit Account");
Assertions.assertTrue(Math.abs(principal - maturityAmount) < THRESHOLD, "Verifying Maturity amount for Fixed Deposit Account");
}
@Test
@@ -1302,10 +1297,8 @@ public class FixedDepositTest {
principal = FixedDepositAccountHelper.getPrincipalAfterCompoundingInterest(todaysDate, principal, depositPeriod, interestPerDay,
MONTHLY_INTERVAL, MONTHLY_INTERVAL);
principal = (float) Math.floor(principal);
maturityAmount = (float) Math.floor(maturityAmount);
LOG.info("{}", principal.toString());
Assertions.assertEquals(principal, maturityAmount, "Verifying Maturity amount for Fixed Deposit Account");
Assertions.assertTrue(Math.abs(principal - maturityAmount) < THRESHOLD, "Verifying Maturity amount for Fixed Deposit Account");
}
@Test
@@ -1402,10 +1395,9 @@ public class FixedDepositTest {
fixedDepositAccountData = FixedDepositAccountHelper.getFixedDepositAccountById(this.requestSpec, this.responseSpec,
fixedDepositAccountId);
principal = (float) Math.floor(principal);
Float maturityAmount = (float) Math.floor((Float) fixedDepositAccountData.get("maturityAmount"));
Float maturityAmount = (float) fixedDepositAccountData.get("maturityAmount");
Assertions.assertEquals(principal, maturityAmount, "Verifying Pre-Closure maturity amount");
Assertions.assertTrue(Math.abs(principal - maturityAmount) < THRESHOLD, "Verifying Pre-Closure maturity amount");
}
@@ -1488,7 +1480,6 @@ public class FixedDepositTest {
principal += interestPerMonth;
todaysDate.add(Calendar.DATE, daysInMonth);
LOG.info("{}", monthDayFormat.format(todaysDate.getTime()));
interestPerMonth = (float) (interestPerDay * principal * currentDate);
LOG.info("IPM = {}", interestPerMonth);
principal += interestPerMonth;
@@ -1507,10 +1498,9 @@ public class FixedDepositTest {
fixedDepositAccountData = FixedDepositAccountHelper.getFixedDepositAccountById(this.requestSpec, this.responseSpec,
fixedDepositAccountId);
principal = (float) Math.floor(principal);
Float maturityAmount = (float) Math.floor((Float) fixedDepositAccountData.get("maturityAmount"));
Float maturityAmount = (float) fixedDepositAccountData.get("maturityAmount");
Assertions.assertEquals(principal, maturityAmount, "Verifying Pre-Closure maturity amount");
Assertions.assertTrue(Math.abs(principal - maturityAmount) < THRESHOLD, "Verifying Pre-Closure maturity amount");
}
@@ -1617,10 +1607,10 @@ public class FixedDepositTest {
fixedDepositAccountData = FixedDepositAccountHelper.getFixedDepositAccountById(this.requestSpec, this.responseSpec,
fixedDepositAccountId);
Double expectedPrematureAmount = Math.floor(principal);
Double maturityAmount = Math.floor((float) fixedDepositAccountData.get("maturityAmount"));
Float expectedPrematureAmount = principal;
Float maturityAmount = (float) fixedDepositAccountData.get("maturityAmount");
Assertions.assertEquals(expectedPrematureAmount, maturityAmount, "Verifying Pre-Closure maturity amount");
Assertions.assertTrue(Math.abs(expectedPrematureAmount - maturityAmount) < THRESHOLD, "Verifying Pre-Closure maturity amount");
}
@@ -1731,10 +1721,10 @@ public class FixedDepositTest {
fixedDepositAccountData = FixedDepositAccountHelper.getFixedDepositAccountById(this.requestSpec, this.responseSpec,
fixedDepositAccountId);
Float expectedPrematureAmount = (float) Math.floor(principal);
Float maturityAmount = (float) Math.floor((Float) fixedDepositAccountData.get("maturityAmount"));
Float expectedPrematureAmount = principal;
Float maturityAmount = (Float) fixedDepositAccountData.get("maturityAmount");
Assertions.assertEquals(expectedPrematureAmount, maturityAmount, "Verifying Pre-Closure maturity amount");
Assertions.assertTrue(Math.abs(expectedPrematureAmount - maturityAmount) < THRESHOLD, "Verifying Pre-Closure maturity amount");
}
@@ -1805,10 +1795,8 @@ public class FixedDepositTest {
principal = FixedDepositAccountHelper.getPrincipalAfterCompoundingInterest(todaysDate, principal, depositPeriod, interestPerDay,
DAILY_COMPOUNDING_INTERVAL, MONTHLY_INTERVAL);
principal = (float) Math.floor(principal);
maturityAmount = (float) Math.floor(maturityAmount);
LOG.info("{}", principal.toString());
Assertions.assertEquals(principal, maturityAmount, "Verifying Maturity amount for Fixed Deposit Account");
Assertions.assertTrue(Math.abs(principal - maturityAmount) < THRESHOLD, "Verifying Maturity amount for Fixed Deposit Account");
}
@@ -1963,10 +1951,10 @@ public class FixedDepositTest {
fixedDepositAccountData = FixedDepositAccountHelper.getFixedDepositAccountById(this.requestSpec, this.responseSpec,
fixedDepositAccountId);
Double expectedPrematureAmount = Math.floor(principal);
Double maturityAmount = Math.floor((Float) fixedDepositAccountData.get("maturityAmount"));
Float expectedPrematureAmount = principal;
Float maturityAmount = (Float) fixedDepositAccountData.get("maturityAmount");
Assertions.assertEquals(expectedPrematureAmount, maturityAmount, "Verifying Maturity amount");
Assertions.assertTrue(Math.abs(expectedPrematureAmount - maturityAmount) < THRESHOLD, "Verifying Maturity amount");
}
@@ -2046,10 +2034,10 @@ public class FixedDepositTest {
fixedDepositAccountData = FixedDepositAccountHelper.getFixedDepositAccountById(this.requestSpec, this.responseSpec,
fixedDepositAccountId);
Double expectedPrematureAmount = Math.floor(principal);
Double maturityAmount = Math.floor((Float) fixedDepositAccountData.get("maturityAmount"));
Float expectedPrematureAmount = principal;
Float maturityAmount = (Float) fixedDepositAccountData.get("maturityAmount");
Assertions.assertEquals(expectedPrematureAmount, maturityAmount, "Verifying Maturity amount");
Assertions.assertTrue(Math.abs(expectedPrematureAmount - maturityAmount) < THRESHOLD, "Verifying Maturity amount");
}
@@ -2127,10 +2115,10 @@ public class FixedDepositTest {
fixedDepositAccountData = FixedDepositAccountHelper.getFixedDepositAccountById(this.requestSpec, this.responseSpec,
fixedDepositAccountId);
Double expectedPrematureAmount = Math.floor(principal);
Double maturityAmount = Math.floor((Float) fixedDepositAccountData.get("maturityAmount"));
Float expectedPrematureAmount = principal;
Float maturityAmount = (Float) fixedDepositAccountData.get("maturityAmount");
Assertions.assertEquals(expectedPrematureAmount, maturityAmount, "Verifying Pre-Closure maturity amount");
Assertions.assertTrue(Math.abs(expectedPrematureAmount - maturityAmount) < THRESHOLD, "Verifying Pre-Closure maturity amount");
}
@@ -2208,10 +2196,10 @@ public class FixedDepositTest {
fixedDepositAccountData = FixedDepositAccountHelper.getFixedDepositAccountById(this.requestSpec, this.responseSpec,
fixedDepositAccountId);
Double expectedPrematureAmount = Math.floor(principal);
Double maturityAmount = Math.floor((Float) fixedDepositAccountData.get("maturityAmount"));
Float expectedPrematureAmount = principal;
Float maturityAmount = (Float) fixedDepositAccountData.get("maturityAmount");
Assertions.assertEquals(expectedPrematureAmount, maturityAmount, "Verifying Pre-Closure maturity amount");
Assertions.assertTrue(Math.abs(expectedPrematureAmount - maturityAmount) < THRESHOLD, "Verifying Pre-Closure maturity amount");
}
@@ -2289,10 +2277,10 @@ public class FixedDepositTest {
fixedDepositAccountData = FixedDepositAccountHelper.getFixedDepositAccountById(this.requestSpec, this.responseSpec,
fixedDepositAccountId);
Double expectedPrematureAmount = Math.floor(principal);
Double maturityAmount = Math.floor((Float) fixedDepositAccountData.get("maturityAmount"));
Float expectedPrematureAmount = principal;
Float maturityAmount = (Float) fixedDepositAccountData.get("maturityAmount");
Assertions.assertEquals(expectedPrematureAmount, maturityAmount, "Verifying Pre-Closure maturity amount");
Assertions.assertTrue(Math.abs(expectedPrematureAmount - maturityAmount) < THRESHOLD, "Verifying Pre-Closure maturity amount");
}
@Test
@@ -2369,15 +2357,15 @@ public class FixedDepositTest {
fixedDepositAccountData = FixedDepositAccountHelper.getFixedDepositAccountById(this.requestSpec, this.responseSpec,
fixedDepositAccountId);
Double expectedPrematureAmount = Math.floor(principal);
Double maturityAmount = Math.floor((Float) fixedDepositAccountData.get("maturityAmount"));
Float expectedPrematureAmount = principal;
Float maturityAmount = (Float) fixedDepositAccountData.get("maturityAmount");
Assertions.assertEquals(expectedPrematureAmount, maturityAmount, "Verifying Pre-Closure maturity amount");
Assertions.assertTrue(Math.abs(expectedPrematureAmount - maturityAmount) < THRESHOLD, "Verifying Pre-Closure maturity amount");
}
/***
* Test case for Fixed Deposit Account rollover with maturity instruction as
* re invest maturity amount(principal+interest)
* Test case for Fixed Deposit Account rollover with maturity instruction as re invest maturity
* amount(principal+interest)
*/
@Test
public void testFixedDepositAccountWithRolloverMaturityAmount() {
@@ -2457,8 +2445,7 @@ public class FixedDepositTest {
}
/***
* Test case for Fixed Deposit Account rollover with maturity instruction as
* re invest principal only
* Test case for Fixed Deposit Account rollover with maturity instruction as re invest principal only
*/
@Test
public void testFixedDepositAccountWithRolloverPrincipal() {
@@ -2648,8 +2635,7 @@ public class FixedDepositTest {
List<HashMap> financialActivities = this.financialActivityAccountHelper.getAllFinancialActivityAccounts(this.responseSpec);
final Account financialAccount;
/***
* if no financial activities are defined for account transfers, create
* liability financial accounting mappings
* if no financial activities are defined for account transfers, create liability financial accounting mappings
*/
if (financialActivities.isEmpty()) {
financialAccount = createLiabilityFinancialAccountTransferType(LIABILITY_TRANSFER_FINANCIAL_ACTIVITY_ID);
@@ -2677,16 +2663,16 @@ public class FixedDepositTest {
return financialAccount;
}
private Account createLiabilityFinancialAccountTransferType(final Integer LIABILITY_TRANSFER_FINANCIAL_ACTIVITY_ID) {
private Account createLiabilityFinancialAccountTransferType(final Integer liabilityTransferFinancialActivityId) {
/***
* Create and verify financial account transfer type is created
*/
final Account liabilityAccountForMapping = this.accountHelper.createLiabilityAccount();
Integer financialActivityAccountId = (Integer) financialActivityAccountHelper.createFinancialActivityAccount(
LIABILITY_TRANSFER_FINANCIAL_ACTIVITY_ID, liabilityAccountForMapping.getAccountID(), this.responseSpec,
liabilityTransferFinancialActivityId, liabilityAccountForMapping.getAccountID(), this.responseSpec,
CommonConstants.RESPONSE_RESOURCE_ID);
Assertions.assertNotNull(financialActivityAccountId);
assertFinancialActivityAccountCreation(financialActivityAccountId, LIABILITY_TRANSFER_FINANCIAL_ACTIVITY_ID,
assertFinancialActivityAccountCreation(financialActivityAccountId, liabilityTransferFinancialActivityId,
liabilityAccountForMapping);
return liabilityAccountForMapping;
}
@@ -78,8 +78,7 @@ public class FlexibleSavingsInterestPostingIntegrationTest {
this.savingsAccountHelper.depositToSavingsAccount(savingsId, "1000", startDate, CommonConstants.RESPONSE_RESOURCE_ID);
/***
* Perform Post interest transaction and verify the posted transaction
* date
* Perform Post interest transaction and verify the posted transaction date
*/
this.savingsAccountHelper.postInterestForSavings(savingsId);
HashMap accountDetails = this.savingsAccountHelper.getSavingsDetails(savingsId);
@@ -160,8 +160,7 @@ public class GlobalConfigurationTest {
Assertions.assertNotNull(configId);
/*
* Update force-password-reset-days with value as 0 and Enable
* as true - failure case
* Update force-password-reset-days with value as 0 and Enable as true - failure case
*/
ArrayList error = (ArrayList) GlobalConfigurationHelper.updatePasswordResetDaysForGlobalConfiguration(this.requestSpec,
this.httpStatusForidden, configId, newValue, newBooleanValue, CommonConstants.RESPONSE_ERROR);
@@ -172,8 +171,7 @@ public class GlobalConfigurationTest {
"Force Password Reset days value must be greater than zero.");
/*
* Update force-password-reset-days with value as 50 and Enable
* as true - success case
* Update force-password-reset-days with value as 50 and Enable as true - success case
*/
final HashMap updateSuccess = (HashMap) GlobalConfigurationHelper.updatePasswordResetDaysForGlobalConfiguration(
this.requestSpec, this.responseSpec, configId, "50", newBooleanValue, "changes");
@@ -185,8 +183,7 @@ public class GlobalConfigurationTest {
Assertions.assertNotNull(updateSuccess1);
/*
* Update without sending value and Enable as true - failure
* case
* Update without sending value and Enable as true - failure case
*/
ArrayList failure = (ArrayList) GlobalConfigurationHelper.updatePasswordResetDaysForGlobalConfiguration(this.requestSpec,
this.httpStatusForidden, configId, null, newBooleanValue, CommonConstants.RESPONSE_ERROR);
@@ -41,8 +41,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Group Test for checking Group: Creation, Activation, Client Association,
* Updating & Deletion
* Group Test for checking Group: Creation, Activation, Client Association, Updating & Deletion
*/
public class GroupTest {
@@ -65,13 +65,15 @@ public class HookIntegrationTest {
// http://www.jamesward.com/2014/06/11/testing-webhooks-was-a-pain-so-i-fixed-the-glitch
final String uniqueId = UUID.randomUUID().toString();
final String payloadURL = "http://echo-webhook.herokuapp.com:80/" + uniqueId + "?";
this.hookHelper.createHook(payloadURL);
final Integer hookId = this.hookHelper.createHook(payloadURL);
Assertions.assertNotNull(hookId);
final Integer createdOfficeID = this.officeHelper.createOffice("01 January 2012");
Assertions.assertNotNull(createdOfficeID);
try {
/**
* sleep for a three seconds after each failure to increase the
* likelihood of the previous request for creating office completing
* sleep for a three seconds after each failure to increase the likelihood of the previous request for
* creating office completing
**/
for (int i = 0; i < 6; i++) {
@@ -93,6 +95,8 @@ public class HookIntegrationTest {
fail("Failed to connect to https://echo-webhook.herokuapp.com platform");
}
throw new RuntimeException(e);
} finally {
this.hookHelper.deleteHook(hookId.longValue());
}
}
@@ -87,8 +87,7 @@ public class LoanApplicationApprovalTest {
}
/*
* Negative test case: Approved amount non zero is greater than proposed
* amount
* Negative test case: Approved amount non zero is greater than proposed amount
*/
@Test
public void loanApplicationApprovedAmountGreaterThanProposedAmount() {
@@ -236,10 +235,8 @@ public class LoanApplicationApprovalTest {
/* If tranches are not specified for a multi-disburse loan */
/**
* error =
* this.loanTransactionHelper.approveLoanForTranches(approveDate,
* expectedDisbursementDate, approvalAmount5, loanID, approveTranche5,
* CommonConstants.RESPONSE_ERROR);
* error = this.loanTransactionHelper.approveLoanForTranches(approveDate, expectedDisbursementDate,
* approvalAmount5, loanID, approveTranche5, CommonConstants.RESPONSE_ERROR);
* assertEquals("error.msg.disbursementData.required",
* error.get(0).get(CommonConstants.RESPONSE_ERROR_MESSAGE_CODE));
**/
@@ -232,113 +232,79 @@ public class LoanDisbursementDetailsIntegrationTest {
/* Uncomment and modify test builder values once MIFOSX-2006 is closed. */
/*
* private void validateRepaymentScheduleWithoutEMI(ArrayList<HashMap>
* periods){ LoanDisbursementTestBuilder expectedRepaymentSchedule0 = new
* LoanDisbursementTestBuilder( "[2015, 6, 1]", 0.0f, 0.0f, null, null,
* 5000.0f, null, null, null);
* private void validateRepaymentScheduleWithoutEMI(ArrayList<HashMap> periods){ LoanDisbursementTestBuilder
* expectedRepaymentSchedule0 = new LoanDisbursementTestBuilder( "[2015, 6, 1]", 0.0f, 0.0f, null, null, 5000.0f,
* null, null, null);
*
* LoanDisbursementTestBuilder expectedRepaymentSchedule1 = new
* LoanDisbursementTestBuilder( "[2015, 7, 1]", 800.0f, 800.0f, 50.0f,
* 750.0f, 4250.0f, 750.0f, 750.0f, "[2015, 6, 1]");
* LoanDisbursementTestBuilder expectedRepaymentSchedule1 = new LoanDisbursementTestBuilder( "[2015, 7, 1]", 800.0f,
* 800.0f, 50.0f, 750.0f, 4250.0f, 750.0f, 750.0f, "[2015, 6, 1]");
*
* LoanDisbursementTestBuilder expectedRepaymentSchedule2 = new
* LoanDisbursementTestBuilder( "[2015, 8, 1]", 800.0f, 800.0f, 42.5f,
* 757.5f, 3492.5f, 757.5f, 757.5f, "[2015, 7, 1]");
* LoanDisbursementTestBuilder expectedRepaymentSchedule2 = new LoanDisbursementTestBuilder( "[2015, 8, 1]", 800.0f,
* 800.0f, 42.5f, 757.5f, 3492.5f, 757.5f, 757.5f, "[2015, 7, 1]");
*
* LoanDisbursementTestBuilder expectedRepaymentSchedule3 = new
* LoanDisbursementTestBuilder( "[2015, 9, 1]", 0.0f, 0.0f, null, null,
* 5000.0f, null, null, null);
* LoanDisbursementTestBuilder expectedRepaymentSchedule3 = new LoanDisbursementTestBuilder( "[2015, 9, 1]", 0.0f,
* 0.0f, null, null, 5000.0f, null, null, null);
*
* LoanDisbursementTestBuilder expectedRepaymentSchedule4 = new
* LoanDisbursementTestBuilder( "[2015, 9, 1]", 800.0f, 800.0f, 34.92f,
* 765.08f, 7727.42f, 765.08f, 765.08f, "[2015, 8, 1]");
* LoanDisbursementTestBuilder expectedRepaymentSchedule4 = new LoanDisbursementTestBuilder( "[2015, 9, 1]", 800.0f,
* 800.0f, 34.92f, 765.08f, 7727.42f, 765.08f, 765.08f, "[2015, 8, 1]");
*
* LoanDisbursementTestBuilder expectedRepaymentSchedule5 = new
* LoanDisbursementTestBuilder( "[2015, 10, 1]", 800.0f, 800.0f, 77.27f,
* 722.73f, 7004.69f, 722.73f, 722.73f, "[2015, 9, 1]");
* LoanDisbursementTestBuilder expectedRepaymentSchedule5 = new LoanDisbursementTestBuilder( "[2015, 10, 1]",
* 800.0f, 800.0f, 77.27f, 722.73f, 7004.69f, 722.73f, 722.73f, "[2015, 9, 1]");
*
* LoanDisbursementTestBuilder expectedRepaymentSchedule6 = new
* LoanDisbursementTestBuilder( "[2015, 11, 1]", 800.0f, 800.0f, 70.05f,
* 729.95f, 6274.74f, 729.95f, 729.95f, "[2015, 10, 1]");
* LoanDisbursementTestBuilder expectedRepaymentSchedule6 = new LoanDisbursementTestBuilder( "[2015, 11, 1]",
* 800.0f, 800.0f, 70.05f, 729.95f, 6274.74f, 729.95f, 729.95f, "[2015, 10, 1]");
*
* LoanDisbursementTestBuilder expectedRepaymentSchedule7 = new
* LoanDisbursementTestBuilder( "[2015, 12, 1]", 800.0f, 800.0f, 62.75f,
* 737.25f, 5537.49f, 737.25f, 737.25f, "[2015, 11, 1]");
* LoanDisbursementTestBuilder expectedRepaymentSchedule7 = new LoanDisbursementTestBuilder( "[2015, 12, 1]",
* 800.0f, 800.0f, 62.75f, 737.25f, 5537.49f, 737.25f, 737.25f, "[2015, 11, 1]");
*
* LoanDisbursementTestBuilder expectedRepaymentSchedule8 = new
* LoanDisbursementTestBuilder( "[2016, 1, 1]", 800.0f, 800.0f, 55.37f,
* 744.63f, 4792.86f, 744.63f, 744.63f, "[2015, 12, 1]");
* LoanDisbursementTestBuilder expectedRepaymentSchedule8 = new LoanDisbursementTestBuilder( "[2016, 1, 1]", 800.0f,
* 800.0f, 55.37f, 744.63f, 4792.86f, 744.63f, 744.63f, "[2015, 12, 1]");
*
* LoanDisbursementTestBuilder expectedRepaymentSchedule9 = new
* LoanDisbursementTestBuilder( "[2016, 2, 1]", 800.0f, 800.0f, 47.93f,
* 752.07f, 4040.79f, 752.07f, 752.07f, "[2016, 1, 1]");
* LoanDisbursementTestBuilder expectedRepaymentSchedule9 = new LoanDisbursementTestBuilder( "[2016, 2, 1]", 800.0f,
* 800.0f, 47.93f, 752.07f, 4040.79f, 752.07f, 752.07f, "[2016, 1, 1]");
*
* LoanDisbursementTestBuilder expectedRepaymentSchedule10 = new
* LoanDisbursementTestBuilder( "[2016, 3, 1]", 800.0f, 800.0f, 40.41f,
* 759.59f, 3281.2f, 759.59f, 759.59f, "[2016, 2, 1]");
* LoanDisbursementTestBuilder expectedRepaymentSchedule10 = new LoanDisbursementTestBuilder( "[2016, 3, 1]",
* 800.0f, 800.0f, 40.41f, 759.59f, 3281.2f, 759.59f, 759.59f, "[2016, 2, 1]");
*
* LoanDisbursementTestBuilder expectedRepaymentSchedule11 = new
* LoanDisbursementTestBuilder( "[2016, 4, 1]", 800.0f, 800.0f, 32.81f,
* 767.19f, 2514.01f, 767.19f, 767.19f, "[2016, 3, 1]");
* LoanDisbursementTestBuilder expectedRepaymentSchedule11 = new LoanDisbursementTestBuilder( "[2016, 4, 1]",
* 800.0f, 800.0f, 32.81f, 767.19f, 2514.01f, 767.19f, 767.19f, "[2016, 3, 1]");
*
* LoanDisbursementTestBuilder expectedRepaymentSchedule12 = new
* LoanDisbursementTestBuilder( "[2016, 5, 1]", 800.0f, 800.0f, 25.14f,
* 774.86f, 1739.15f, 774.86f, 774.86f, "[2016, 4, 1]");
* LoanDisbursementTestBuilder expectedRepaymentSchedule12 = new LoanDisbursementTestBuilder( "[2016, 5, 1]",
* 800.0f, 800.0f, 25.14f, 774.86f, 1739.15f, 774.86f, 774.86f, "[2016, 4, 1]");
*
* LoanDisbursementTestBuilder expectedRepaymentSchedule13 = new
* LoanDisbursementTestBuilder( "[2016, 6, 1]", 800.0f, 800.0f, 17.39f,
* 782.61f, 956.54f, 782.61f, 782.61f, "[2016, 5, 1]");
* LoanDisbursementTestBuilder expectedRepaymentSchedule13 = new LoanDisbursementTestBuilder( "[2016, 6, 1]",
* 800.0f, 800.0f, 17.39f, 782.61f, 956.54f, 782.61f, 782.61f, "[2016, 5, 1]");
*
* LoanDisbursementTestBuilder expectedRepaymentSchedule14 = new
* LoanDisbursementTestBuilder( "[2016, 7, 1]", 966.11f, 966.11f, 9.57f,
* 956.54f, 0.0f, 956.54f, 956.54f, "[2016, 6, 1]");
* LoanDisbursementTestBuilder expectedRepaymentSchedule14 = new LoanDisbursementTestBuilder( "[2016, 7, 1]",
* 966.11f, 966.11f, 9.57f, 956.54f, 0.0f, 956.54f, 956.54f, "[2016, 6, 1]");
*
* ArrayList<LoanDisbursementTestBuilder> list = new
* ArrayList<LoanDisbursementTestBuilder>();
* list.add(expectedRepaymentSchedule0);
* list.add(expectedRepaymentSchedule1);
* list.add(expectedRepaymentSchedule2);
* list.add(expectedRepaymentSchedule3);
* list.add(expectedRepaymentSchedule4);
* list.add(expectedRepaymentSchedule5);
* list.add(expectedRepaymentSchedule6);
* list.add(expectedRepaymentSchedule7);
* list.add(expectedRepaymentSchedule8);
* list.add(expectedRepaymentSchedule9);
* list.add(expectedRepaymentSchedule10);
* list.add(expectedRepaymentSchedule11);
* list.add(expectedRepaymentSchedule12);
* list.add(expectedRepaymentSchedule13);
* list.add(expectedRepaymentSchedule14);
* ArrayList<LoanDisbursementTestBuilder> list = new ArrayList<LoanDisbursementTestBuilder>();
* list.add(expectedRepaymentSchedule0); list.add(expectedRepaymentSchedule1); list.add(expectedRepaymentSchedule2);
* list.add(expectedRepaymentSchedule3); list.add(expectedRepaymentSchedule4); list.add(expectedRepaymentSchedule5);
* list.add(expectedRepaymentSchedule6); list.add(expectedRepaymentSchedule7); list.add(expectedRepaymentSchedule8);
* list.add(expectedRepaymentSchedule9); list.add(expectedRepaymentSchedule10);
* list.add(expectedRepaymentSchedule11); list.add(expectedRepaymentSchedule12);
* list.add(expectedRepaymentSchedule13); list.add(expectedRepaymentSchedule14);
*
* for (int i = 0; i < list.size(); i++) {
* this.assertRepaymentScheduleValuesWithoutEMI(periods.get(i), list.get(i),
* for (int i = 0; i < list.size(); i++) { this.assertRepaymentScheduleValuesWithoutEMI(periods.get(i), list.get(i),
* i); } }
*
* private void assertRepaymentScheduleValuesWithoutEMI(HashMap period,
* LoanDisbursementTestBuilder expectedRepaymentSchedule, int position) {
* private void assertRepaymentScheduleValuesWithoutEMI(HashMap period, LoanDisbursementTestBuilder
* expectedRepaymentSchedule, int position) {
*
* assertEquals(period.get("dueDate").toString(),
* expectedRepaymentSchedule.getDueDate());
* assertEquals(period.get("dueDate").toString(), expectedRepaymentSchedule.getDueDate());
* assertEquals(period.get("principalLoanBalanceOutstanding"),
* expectedRepaymentSchedule.getPrincipalLoanBalanceOutstanding());
* assertEquals(period.get("totalOriginalDueForPeriod"),
* expectedRepaymentSchedule.getTotalOriginalDueForPeriod());
* assertEquals(period.get("totalOutstandingForPeriod"),
* expectedRepaymentSchedule.getTotalOutstandingForPeriod());
* assertEquals(period.get("totalOriginalDueForPeriod"), expectedRepaymentSchedule.getTotalOriginalDueForPeriod());
* assertEquals(period.get("totalOutstandingForPeriod"), expectedRepaymentSchedule.getTotalOutstandingForPeriod());
*
* if (position != 0 && position != 3) {
*
* assertEquals(period.get("interestOutstanding"),
* expectedRepaymentSchedule.getInterestOutstanding());
* assertEquals(period.get("principalOutstanding"),
* expectedRepaymentSchedule.getPrincipalOutstanding());
* assertEquals(period.get("principalDue"),
* expectedRepaymentSchedule.getPrincipalDue());
* assertEquals(period.get("principalOriginalDue"),
* expectedRepaymentSchedule.getPrincipalOriginalDue());
* assertEquals(period.get("fromDate").toString(),
* expectedRepaymentSchedule.getFromDate()); } }
* assertEquals(period.get("interestOutstanding"), expectedRepaymentSchedule.getInterestOutstanding());
* assertEquals(period.get("principalOutstanding"), expectedRepaymentSchedule.getPrincipalOutstanding());
* assertEquals(period.get("principalDue"), expectedRepaymentSchedule.getPrincipalDue());
* assertEquals(period.get("principalOriginalDue"), expectedRepaymentSchedule.getPrincipalOriginalDue());
* assertEquals(period.get("fromDate").toString(), expectedRepaymentSchedule.getFromDate()); } }
*/
private Integer applyForLoanApplicationWithEmiAmount(final Integer clientID, final Integer loanProductID, final String proposedAmount,
List<HashMap> tranches, final String installmentAmount) {
@@ -37,8 +37,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Client Loan Integration Test for checking Loan Disbursement with Waive
* Interest and Write-Off.
* Client Loan Integration Test for checking Loan Disbursement with Waive Interest and Write-Off.
*/
@SuppressWarnings({ "rawtypes" })
public class LoanWithWaiveInterestAndWriteOffIntegrationTest {
@@ -47,20 +46,20 @@ public class LoanWithWaiveInterestAndWriteOffIntegrationTest {
private ResponseSpecification responseSpec;
private RequestSpecification requestSpec;
private final String LP_PRINCIPAL = "12,000.00";
private final String LP_REPAYMENTS = "2";
private final String LP_REPAYMENT_PERIOD = "6";
private final String LP_INTEREST_RATE = "1";
private final String PRINCIPAL = "4,500.00";
private final String LOAN_TERM_FREQUENCY = "18";
private final String NUMBER_OF_REPAYMENTS = "9";
private final String REPAYMENT_PERIOD = "2";
private final String DISBURSEMENT_DATE = "30 October 2010";
private final String LOAN_APPLICATION_SUBMISSION_DATE = "23 September 2010";
private final String EXPECTED_DISBURSAL_DATE = "28 October 2010";
private final String RATE_OF_INTEREST_PER_PERIOD = "2";
private final String DATE_OF_JOINING = "04 March 2009";
private final String INTEREST_VALUE_AMOUNT = "40.00";
private static final String LP_PRINCIPAL = "12,000.00";
private static final String LP_REPAYMENTS = "2";
private static final String LP_REPAYMENT_PERIOD = "6";
private static final String LP_INTEREST_RATE = "1";
private static final String PRINCIPAL = "4,500.00";
private static final String LOAN_TERM_FREQUENCY = "18";
private static final String NUMBER_OF_REPAYMENTS = "9";
private static final String REPAYMENT_PERIOD = "2";
private static final String DISBURSEMENT_DATE = "30 October 2010";
private static final String LOAN_APPLICATION_SUBMISSION_DATE = "23 September 2010";
private static final String EXPECTED_DISBURSAL_DATE = "28 October 2010";
private static final String RATE_OF_INTEREST_PER_PERIOD = "2";
private static final String DATE_OF_JOINING = "04 March 2009";
private static final String INTEREST_VALUE_AMOUNT = "40.00";
private LoanTransactionHelper loanTransactionHelper;
@BeforeEach
@@ -75,7 +74,7 @@ public class LoanWithWaiveInterestAndWriteOffIntegrationTest {
@Test
public void checkClientLoanCreateAndDisburseFlow() {
// CREATE CLIENT
final Integer clientID = ClientHelper.createClient(this.requestSpec, this.responseSpec, this.DATE_OF_JOINING);
final Integer clientID = ClientHelper.createClient(this.requestSpec, this.responseSpec, DATE_OF_JOINING);
ClientHelper.verifyClientCreatedOnServer(this.requestSpec, this.responseSpec, clientID);
// CREATE LOAN PRODUCT
@@ -101,7 +100,7 @@ public class LoanWithWaiveInterestAndWriteOffIntegrationTest {
LoanStatusChecker.verifyLoanIsWaitingForDisbursal(loanStatusHashMap);
// DISBURSE
loanStatusHashMap = this.loanTransactionHelper.disburseLoan(this.DISBURSEMENT_DATE, loanID);
loanStatusHashMap = this.loanTransactionHelper.disburseLoan(DISBURSEMENT_DATE, loanID);
LOG.info("DISBURSE {}", loanStatusHashMap.toString());
LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap);
@@ -114,7 +113,7 @@ public class LoanWithWaiveInterestAndWriteOffIntegrationTest {
LoanStatusChecker.verifyLoanIsWaitingForDisbursal(loanStatusHashMap);
// DIBURSE AGAIN
loanStatusHashMap = this.loanTransactionHelper.disburseLoan(this.DISBURSEMENT_DATE, loanID);
loanStatusHashMap = this.loanTransactionHelper.disburseLoan(DISBURSEMENT_DATE, loanID);
LOG.info("DISBURSE {}", loanStatusHashMap);
LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap);
@@ -125,13 +124,13 @@ public class LoanWithWaiveInterestAndWriteOffIntegrationTest {
this.loanTransactionHelper.verifyRepaymentScheduleEntryFor(1, 4000.0F, loanID);
this.loanTransactionHelper.makeRepayment("1 January 2011", repayment_with_interest, loanID);
this.loanTransactionHelper.makeRepayment("1 March 2011", repayment_with_interest, loanID);
this.loanTransactionHelper.waiveInterest("1 May 2011", this.INTEREST_VALUE_AMOUNT, loanID);
this.loanTransactionHelper.waiveInterest("1 May 2011", INTEREST_VALUE_AMOUNT, loanID);
this.loanTransactionHelper.makeRepayment("1 May 2011", repayment_without_interest, loanID);
this.loanTransactionHelper.makeRepayment("1 July 2011", repayment_with_interest, loanID);
this.loanTransactionHelper.waiveInterest("1 September 2011", this.INTEREST_VALUE_AMOUNT, loanID);
this.loanTransactionHelper.waiveInterest("1 September 2011", INTEREST_VALUE_AMOUNT, loanID);
this.loanTransactionHelper.makeRepayment("1 September 2011", repayment_without_interest, loanID);
this.loanTransactionHelper.makeRepayment("1 November 2011", repayment_with_interest, loanID);
this.loanTransactionHelper.waiveInterest("1 January 2012", this.INTEREST_VALUE_AMOUNT, loanID);
this.loanTransactionHelper.waiveInterest("1 January 2012", INTEREST_VALUE_AMOUNT, loanID);
this.loanTransactionHelper.makeRepayment("1 January 2012", repayment_without_interest, loanID);
this.loanTransactionHelper.verifyRepaymentScheduleEntryFor(7, 1000.0f, loanID);
@@ -143,7 +142,7 @@ public class LoanWithWaiveInterestAndWriteOffIntegrationTest {
@Test
public void checkClientLoan_WRITTEN_OFF() {
// CREATE CLIENT
final Integer clientID = ClientHelper.createClient(this.requestSpec, this.responseSpec, this.DATE_OF_JOINING);
final Integer clientID = ClientHelper.createClient(this.requestSpec, this.responseSpec, DATE_OF_JOINING);
ClientHelper.verifyClientCreatedOnServer(this.requestSpec, this.responseSpec, clientID);
// CREATE LOAN PRODUCT
@@ -160,7 +159,7 @@ public class LoanWithWaiveInterestAndWriteOffIntegrationTest {
LoanStatusChecker.verifyLoanIsWaitingForDisbursal(loanStatusHashMap);
// DISBURSE
loanStatusHashMap = this.loanTransactionHelper.disburseLoan(this.DISBURSEMENT_DATE, loanID);
loanStatusHashMap = this.loanTransactionHelper.disburseLoan(DISBURSEMENT_DATE, loanID);
LOG.info("DISBURSE {}", loanStatusHashMap);
LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap);
@@ -196,9 +195,9 @@ public class LoanWithWaiveInterestAndWriteOffIntegrationTest {
private Integer createLoanProduct() {
LOG.info("------------------------------CREATING NEW LOAN PRODUCT ---------------------------------------");
final String loanProductJSON = new LoanProductTestBuilder().withPrincipal(this.LP_PRINCIPAL).withRepaymentTypeAsMonth()
.withRepaymentAfterEvery(this.LP_REPAYMENT_PERIOD).withNumberOfRepayments(this.LP_REPAYMENTS).withRepaymentTypeAsMonth()
.withinterestRatePerPeriod(this.LP_INTEREST_RATE).withInterestRateFrequencyTypeAsMonths()
final String loanProductJSON = new LoanProductTestBuilder().withPrincipal(LP_PRINCIPAL).withRepaymentTypeAsMonth()
.withRepaymentAfterEvery(LP_REPAYMENT_PERIOD).withNumberOfRepayments(LP_REPAYMENTS).withRepaymentTypeAsMonth()
.withinterestRatePerPeriod(LP_INTEREST_RATE).withInterestRateFrequencyTypeAsMonths()
.withAmortizationTypeAsEqualPrincipalPayment().withInterestTypeAsFlat().build(null);
return this.loanTransactionHelper.getLoanProductId(loanProductJSON);
@@ -206,13 +205,13 @@ public class LoanWithWaiveInterestAndWriteOffIntegrationTest {
private Integer applyForLoanApplication(final Integer clientID, final Integer loanProductID) {
LOG.info("--------------------------------APPLYING FOR LOAN APPLICATION--------------------------------");
final String loanApplicationJSON = new LoanApplicationTestBuilder().withPrincipal(this.PRINCIPAL)
.withLoanTermFrequency(this.LOAN_TERM_FREQUENCY).withLoanTermFrequencyAsMonths()
.withNumberOfRepayments(this.NUMBER_OF_REPAYMENTS).withRepaymentEveryAfter(this.REPAYMENT_PERIOD)
.withRepaymentFrequencyTypeAsMonths().withInterestRatePerPeriod(this.RATE_OF_INTEREST_PER_PERIOD)
.withInterestTypeAsFlatBalance().withAmortizationTypeAsEqualInstallments()
.withInterestCalculationPeriodTypeSameAsRepaymentPeriod().withExpectedDisbursementDate(this.EXPECTED_DISBURSAL_DATE)
.withSubmittedOnDate(this.LOAN_APPLICATION_SUBMISSION_DATE).build(clientID.toString(), loanProductID.toString(), null);
final String loanApplicationJSON = new LoanApplicationTestBuilder().withPrincipal(PRINCIPAL)
.withLoanTermFrequency(LOAN_TERM_FREQUENCY).withLoanTermFrequencyAsMonths().withNumberOfRepayments(NUMBER_OF_REPAYMENTS)
.withRepaymentEveryAfter(REPAYMENT_PERIOD).withRepaymentFrequencyTypeAsMonths()
.withInterestRatePerPeriod(RATE_OF_INTEREST_PER_PERIOD).withInterestTypeAsFlatBalance()
.withAmortizationTypeAsEqualInstallments().withInterestCalculationPeriodTypeSameAsRepaymentPeriod()
.withExpectedDisbursementDate(EXPECTED_DISBURSAL_DATE).withSubmittedOnDate(LOAN_APPLICATION_SUBMISSION_DATE)
.build(clientID.toString(), loanProductID.toString(), null);
return this.loanTransactionHelper.getLoanId(loanApplicationJSON);
}
}
@@ -66,9 +66,8 @@ public class MinimumDaysBetweenDisbursalAndFirstRepaymentTest {
}
/*
* MinimumDaysBetweenDisbursalAndFirstRepayment is set to 7 days and days
* between disbursal date and first repayment is set as 7. system should
* allow to create this loan and allow to disburse
* MinimumDaysBetweenDisbursalAndFirstRepayment is set to 7 days and days between disbursal date and first repayment
* is set as 7. system should allow to create this loan and allow to disburse
*/
@Test
public void createLoanEntity_WITH_DAY_BETWEEN_DISB_DATE_AND_REPAY_START_DATE_GREATER_THAN_MIN_DAY_CRITERIA() {
@@ -112,9 +111,8 @@ public class MinimumDaysBetweenDisbursalAndFirstRepaymentTest {
}
/*
* MinimumDaysBetweenDisbursalAndFirstRepayment is set to 7 days and days
* between disbursal date and first repayment is set as 7. system should
* allow to create this loan and allow to disburse
* MinimumDaysBetweenDisbursalAndFirstRepayment is set to 7 days and days between disbursal date and first repayment
* is set as 7. system should allow to create this loan and allow to disburse
*/
@SuppressWarnings("unchecked")
@Test
@@ -74,13 +74,13 @@ public class SchedulerJobsTestResults {
private static final String FROM_ACCOUNT_TYPE_SAVINGS = "2";
private static final String TO_ACCOUNT_TYPE_LOAN = "1";
private static final String TO_ACCOUNT_TYPE_SAVINGS = "2";
private final String DATE_OF_JOINING = "01 January 2011";
private static final String DATE_OF_JOINING = "01 January 2011";
private final String TRANSACTION_DATE = "01 March 2013";
private static final String TRANSACTION_DATE = "01 March 2013";
public static final String ACCOUNT_TYPE_INDIVIDUAL = "INDIVIDUAL";
public static final String MINIMUM_OPENING_BALANCE = "1000";
Float SP_BALANCE = Float.valueOf(MINIMUM_OPENING_BALANCE);
static Float SP_BALANCE = Float.valueOf(MINIMUM_OPENING_BALANCE);
private static ResponseSpecification responseSpec;
private static RequestSpecification requestSpec;
@@ -399,7 +399,7 @@ public class SchedulerJobsTestResults {
final Integer savingsProductID = createSavingsProduct(MINIMUM_OPENING_BALANCE, assetAccount, incomeAccount, expenseAccount,
liabilityAccount);
final Integer clientID = ClientHelper.createClient(requestSpec, responseSpec, this.DATE_OF_JOINING);
final Integer clientID = ClientHelper.createClient(requestSpec, responseSpec, DATE_OF_JOINING);
final Integer savingsID = this.savingsAccountHelper.applyForSavingsApplication(clientID, savingsProductID, ACCOUNT_TYPE_INDIVIDUAL);
HashMap savingsStatusHashMap = SavingsStatusChecker.getStatusOfSavings(requestSpec, responseSpec, savingsID);
@@ -412,11 +412,10 @@ public class SchedulerJobsTestResults {
SavingsStatusChecker.verifySavingsIsActive(savingsStatusHashMap);
// Checking initial Account entries.
final JournalEntry[] assetAccountInitialEntry = { new JournalEntry(this.SP_BALANCE, JournalEntry.TransactionType.DEBIT) };
final JournalEntry[] liablilityAccountInitialEntry = { new JournalEntry(this.SP_BALANCE, JournalEntry.TransactionType.CREDIT) };
this.journalEntryHelper.checkJournalEntryForAssetAccount(assetAccount, this.TRANSACTION_DATE, assetAccountInitialEntry);
this.journalEntryHelper.checkJournalEntryForLiabilityAccount(liabilityAccount, this.TRANSACTION_DATE,
liablilityAccountInitialEntry);
final JournalEntry[] assetAccountInitialEntry = { new JournalEntry(SP_BALANCE, JournalEntry.TransactionType.DEBIT) };
final JournalEntry[] liablilityAccountInitialEntry = { new JournalEntry(SP_BALANCE, JournalEntry.TransactionType.CREDIT) };
this.journalEntryHelper.checkJournalEntryForAssetAccount(assetAccount, TRANSACTION_DATE, assetAccountInitialEntry);
this.journalEntryHelper.checkJournalEntryForLiabilityAccount(liabilityAccount, TRANSACTION_DATE, liablilityAccountInitialEntry);
String JobName = "Update Accounting Running Balances";
@@ -28,8 +28,7 @@ import org.apache.fineract.integrationtests.common.loans.LoanTransactionHelper;
import org.junit.jupiter.api.BeforeEach;
/**
* Client Loan Integration Test for checking Loan Application Repayment
* Schedule.
* Client Loan Integration Test for checking Loan Application Repayment Schedule.
*/
@SuppressWarnings({ "rawtypes", "unchecked" })
public class SurveyIntegrationTest {
@@ -0,0 +1,51 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.fineract.integrationtests;
import io.restassured.builder.RequestSpecBuilder;
import io.restassured.builder.ResponseSpecBuilder;
import io.restassured.http.ContentType;
import io.restassured.specification.RequestSpecification;
import io.restassured.specification.ResponseSpecification;
import org.apache.fineract.integrationtests.common.Utils;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
/**
* @author Manthan Surkar
*/
public class SwaggeruiTest {
private ResponseSpecification responseSpec;
private RequestSpecification requestSpec;
@BeforeEach
public void setup() {
Utils.initializeRESTAssured();
this.requestSpec = new RequestSpecBuilder().setContentType(ContentType.JSON).build();
this.responseSpec = new ResponseSpecBuilder().expectStatusCode(200).build();
}
@Test
public void testSwaggeruiAccess() {
Utils.performServerGet(requestSpec, responseSpec, "/fineract-provider/swagger-ui", null);
Utils.performServerGet(requestSpec, responseSpec, "/fineract-provider/swagger-ui/index.html", null);
}
}
@@ -34,9 +34,9 @@ import org.junit.jupiter.api.Test;
public class TemplateIntegrationTest {
private final String GET_TEMPLATES_URL = "/fineract-provider/api/v1/templates?tenantIdentifier=default";
private final String GET_TEMPLATE_ID_URL = "/fineract-provider/api/v1/templates/%s?tenantIdentifier=default";
private final String RESPONSE_ATTRIBUTE_NAME = "name";
private static final String GET_TEMPLATES_URL = "/fineract-provider/api/v1/templates?tenantIdentifier=default";
private static final String RESPONSE_ATTRIBUTE_NAME = "name";
private ResponseSpecification responseSpec;
private RequestSpecification requestSpec;
@@ -61,22 +61,21 @@ public class TemplateIntegrationTest {
map.put("text", "Hello {{template}}");
map.put("mappers", metadata);
ArrayList<?> get = Utils.performServerGet(this.requestSpec, this.responseSpec, this.GET_TEMPLATES_URL, "");
ArrayList<?> get = Utils.performServerGet(this.requestSpec, this.responseSpec, GET_TEMPLATES_URL, "");
final int entriesBeforeTest = get.size();
final Integer id = Utils.performServerPost(this.requestSpec, this.responseSpec, this.GET_TEMPLATES_URL, new Gson().toJson(map),
final Integer id = Utils.performServerPost(this.requestSpec, this.responseSpec, GET_TEMPLATES_URL, new Gson().toJson(map),
"resourceId");
final String templateUrlForId = String.format(this.GET_TEMPLATE_ID_URL, id);
final String templateUrlForId = String.format("/fineract-provider/api/v1/templates/%s?tenantIdentifier=default", id);
final String getrequest2 = Utils.performServerGet(this.requestSpec, this.responseSpec, templateUrlForId,
this.RESPONSE_ATTRIBUTE_NAME);
final String getrequest2 = Utils.performServerGet(this.requestSpec, this.responseSpec, templateUrlForId, RESPONSE_ATTRIBUTE_NAME);
Assertions.assertTrue(getrequest2.equals("foo"));
Utils.performServerDelete(this.requestSpec, this.responseSpec, templateUrlForId, "");
get = Utils.performServerGet(this.requestSpec, this.responseSpec, this.GET_TEMPLATES_URL, "");
get = Utils.performServerGet(this.requestSpec, this.responseSpec, GET_TEMPLATES_URL, "");
final int entriesAfterTest = get.size();
Assertions.assertEquals(entriesBeforeTest, entriesAfterTest);
@@ -32,6 +32,7 @@ import org.apache.fineract.integrationtests.common.Utils;
import org.apache.fineract.integrationtests.common.organisation.StaffHelper;
import org.apache.fineract.integrationtests.useradministration.roles.RolesHelper;
import org.apache.fineract.integrationtests.useradministration.users.UserHelper;
import org.apache.fineract.useradministration.service.AppUserConstants;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
@@ -155,4 +156,19 @@ public class UserAdministrationTest {
reason.get("defaultUserMessage"));
}
@Test
public void testDeleteSystemUser() {
final Integer userId = UserHelper.getUserId(requestSpec, responseSpec, AppUserConstants.SYSTEM_USER_NAME);
Assertions.assertNotNull(userId);
UserHelper.deleteUser(requestSpec, expectStatusCode(403), userId.intValue());
}
@Test
public void testModifySystemUser() {
final Integer userId = UserHelper.getUserId(requestSpec, responseSpec, AppUserConstants.SYSTEM_USER_NAME);
Assertions.assertNotNull(userId);
final List errors = (List) UserHelper.updateUser(this.requestSpec, expectStatusCode(403), userId, "systemtest", "errors");
}
}
@@ -0,0 +1,108 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.fineract.integrationtests.common;
import static org.junit.jupiter.api.Assertions.assertEquals;
import io.restassured.specification.RequestSpecification;
import io.restassured.specification.ResponseSpecification;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
*
* @author Manthan Surkar
*
*/
public class AuditHelper {
private ResponseSpecification responseSpec;
private RequestSpecification requestSpec;
private static final Logger LOG = LoggerFactory.getLogger(AuditHelper.class);
private static final String AUDIT_BASE_URL = "/fineract-provider/api/v1/audits?" + Utils.TENANT_IDENTIFIER;
public AuditHelper(final RequestSpecification requestSpec, final ResponseSpecification responseSpec) {
this.requestSpec = requestSpec;
this.responseSpec = responseSpec;
}
public List getAuditDetails(final Integer resourceId, final String actionName, final String entityName) {
final String AUDIT_URL = "/fineract-provider/api/v1/audits/?" + "entityName=" + entityName + "&resourceId=" + resourceId
+ "&actionName=" + actionName + "&orderBy=id&sortBy=DSC&" + Utils.TENANT_IDENTIFIER;
List<HashMap<String, Object>> responseAudits = Utils.performServerGet(requestSpec, responseSpec, AUDIT_URL, "");
return responseAudits;
}
public List getAuditDetails(final int limit) {
final String AUDIT_URL = "/fineract-provider/api/v1/audits?paged=true&limit=" + Integer.toString(limit) + "&"
+ Utils.TENANT_IDENTIFIER;
LinkedHashMap responseAudits = Utils.performServerGet(requestSpec, responseSpec, AUDIT_URL, "");
return (List) responseAudits.get("pageItems");
}
/**
* Some audit actions can only be done once Eg: Creation of a client with id 123, hence we verify number of audits
* For such operations is "equal" to 1 always
*/
public void verifyOneAuditOnly(List<HashMap<String, Object>> auditsToCheck, Integer id, String actionName, String entityType) {
LOG.info("------------------------------CHECK IF AUDIT CREATED------------------------------------\n");
assertEquals(1, auditsToCheck.size(), "More than one audit created");
HashMap<String, Object> auditToCheck = auditsToCheck.get(0);
String actual = auditToCheck.get("actionName").toString() + " is done on " + auditToCheck.get("entityName").toString() + " with id "
+ auditToCheck.get("resourceId").toString();
String expected = actionName + " is done on " + entityType + " with id " + id;
assertEquals(expected, actual, "Error in creating audit!");
}
public void verifyMultipleAuditsOnserver(List<HashMap<String, Object>> auditsRecievedInitial,
List<HashMap<String, Object>> auditsRecieved, Integer id, String actionName, String entityType) {
LOG.info("------------------------------CHECK IF AUDIT CREATED------------------------------------\n");
assertEquals(auditsRecievedInitial.size() + 1, auditsRecieved.size(), "Audit is not Created");
Comparator<HashMap<String, Object>> compareById = (HashMap<String, Object> a, HashMap<String, Object> b) -> a.get("id").toString()
.compareTo(b.get("id").toString());
Collections.sort(auditsRecieved, compareById.reversed());
// First element is new audit created(Sorted DESC by Id)
HashMap<String, Object> auditToCheck = auditsRecieved.get(0);
String actual = auditToCheck.get("actionName").toString() + " is done on " + auditToCheck.get("entityName").toString() + " with id "
+ auditToCheck.get("resourceId").toString();
String expected = actionName + " is done on " + entityType + " with id " + id;
assertEquals(expected, actual, "Error in creating audit!");
}
public void verifyLimitParameterfor(final int limit) {
assertEquals(limit, getAuditDetails(limit).size(), "Incorrect number of audits recieved for limit: " + Integer.toString(limit));
}
public void verifyOrderBysupported(final String orderByValue) {
final String AUDIT_URL = "/fineract-provider/api/v1/audits/?paged=true&orderBy=" + orderByValue + "&" + Utils.TENANT_IDENTIFIER;
Utils.performServerGet(requestSpec, responseSpec, AUDIT_URL, "");
}
}
@@ -32,9 +32,8 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Helper class for {@link org.apache.fineract.integrationtests.BatchApiTest}.
* It takes care of creation of {@code BatchRequest} list and posting this list
* to the server.
* Helper class for {@link org.apache.fineract.integrationtests.BatchApiTest}. It takes care of creation of
* {@code BatchRequest} list and posting this list to the server.
*
* @author Rishabh Shukla
*
@@ -47,7 +46,7 @@ public final class BatchHelper {
private static final String BATCH_API_URL_EXT = BATCH_API_URL + "&enclosingTransaction=true";
private BatchHelper() {
super();
}
/**
@@ -74,16 +73,15 @@ public final class BatchHelper {
* Returns the converted string response into JSON.
*
* @param json
* @return List<BatchResponse>
* @return {@code List<BatchResponse>}
*/
private static List<BatchResponse> fromJsonString(final String json) {
return new Gson().fromJson(json, new TypeToken<List<BatchResponse>>() {}.getType());
}
/**
* Returns a list of BatchResponse with query parameter enclosing
* transaction set to false by posting the jsonified BatchRequest to the
* server.
* Returns a list of BatchResponse with query parameter enclosing transaction set to false by posting the jsonified
* BatchRequest to the server.
*
* @param requestSpec
* @param responseSpec
@@ -97,9 +95,8 @@ public final class BatchHelper {
}
/**
* Returns a list of BatchResponse with query parameter enclosing
* transaction set to true by posting the jsonified BatchRequest to the
* server.
* Returns a list of BatchResponse with query parameter enclosing transaction set to true by posting the jsonified
* BatchRequest to the server.
*
* @param requestSpec
* @param responseSpec
@@ -113,11 +110,10 @@ public final class BatchHelper {
}
/**
* Returns a BatchResponse based on the given BatchRequest, by posting the
* request to the server.
* Returns a BatchResponse based on the given BatchRequest, by posting the request to the server.
*
* @param BatchRequest
* @return List<BatchResponse>
* @return {@code List<BatchResponse>}
*/
public static List<BatchResponse> postWithSingleRequest(final RequestSpecification requestSpec,
final ResponseSpecification responseSpec, final BatchRequest br) {
@@ -137,9 +133,8 @@ public final class BatchHelper {
}
/**
* Creates and returns a
* {@link org.apache.fineract.batch.command.internal.CreateClientCommandStrategy}
* Request as one of the request in Batch.
* Creates and returns a {@link org.apache.fineract.batch.command.internal.CreateClientCommandStrategy} Request as
* one of the request in Batch.
*
* @param reqId
* @param externalId
@@ -168,9 +163,8 @@ public final class BatchHelper {
}
/**
* Creates and returns a
* {@link org.apache.fineract.batch.command.internal.CreateClientCommandStrategy}
* Request as one of the request in Batch.
* Creates and returns a {@link org.apache.fineract.batch.command.internal.CreateClientCommandStrategy} Request as
* one of the request in Batch.
*
* @param reqId
* @param externalId
@@ -200,9 +194,8 @@ public final class BatchHelper {
}
/**
* Creates and returns a
* {@link org.apache.fineract.batch.command.internal.UpdateClientCommandStrategy}
* Request with given requestId and reference.
* Creates and returns a {@link org.apache.fineract.batch.command.internal.UpdateClientCommandStrategy} Request with
* given requestId and reference.
*
* @param reqId
* @param clientId
@@ -222,9 +215,8 @@ public final class BatchHelper {
}
/**
* Creates and returns a
* {@link org.apache.fineract.batch.command.internal.ApplyLoanCommandStrategy}
* Request with given requestId and reference.
* Creates and returns a {@link org.apache.fineract.batch.command.internal.ApplyLoanCommandStrategy} Request with
* given requestId and reference.
*
* @param requestId
* @param reference
@@ -253,9 +245,8 @@ public final class BatchHelper {
}
/**
* Creates and returns a
* {@link org.apache.fineract.batch.command.internal.ApplySavingsCommandStrategy}
* Request with given requestId and reference.
* Creates and returns a {@link org.apache.fineract.batch.command.internal.ApplySavingsCommandStrategy} Request with
* given requestId and reference.
*
* @param requestId
* @param reference
@@ -279,9 +270,8 @@ public final class BatchHelper {
}
/**
* Creates and returns a
* {@link org.apache.fineract.batch.command.internal.CreateChargeCommandStrategy}
* Request with given requestId and reference
* Creates and returns a {@link org.apache.fineract.batch.command.internal.CreateChargeCommandStrategy} Request with
* given requestId and reference
*
* @param requestId
* @param reference
@@ -303,9 +293,8 @@ public final class BatchHelper {
}
/**
* Creates and returns a
* {@link org.apache.fineract.batch.command.internal.CollectChargesCommandStrategy}
* Request with given requestId and reference.
* Creates and returns a {@link org.apache.fineract.batch.command.internal.CollectChargesCommandStrategy} Request
* with given requestId and reference.
*
* @param requestId
* @param reference
@@ -325,9 +314,8 @@ public final class BatchHelper {
}
/**
* Creates and returns a
* {@link org.apache.fineract.batch.command.internal.ActivateClientCommandStrategy}
* Request with given requestId and reference.
* Creates and returns a {@link org.apache.fineract.batch.command.internal.ActivateClientCommandStrategy} Request
* with given requestId and reference.
*
*
* @param requestId
@@ -348,9 +336,8 @@ public final class BatchHelper {
}
/**
* Creates and returns a
* {@link org.apache.fineract.batch.command.internal.ApproveLoanCommandStrategy}
* Request with given requestId and reference.
* Creates and returns a {@link org.apache.fineract.batch.command.internal.ApproveLoanCommandStrategy} Request with
* given requestId and reference.
*
*
* @param requestId
@@ -371,9 +358,8 @@ public final class BatchHelper {
}
/**
* Creates and returns a
* {@link org.apache.fineract.batch.command.internal.DisburseLoanCommandStrategy}
* Request with given requestId and reference.
* Creates and returns a {@link org.apache.fineract.batch.command.internal.DisburseLoanCommandStrategy} Request with
* given requestId and reference.
*
*
* @param requestId
@@ -393,9 +379,8 @@ public final class BatchHelper {
}
/**
* Creates and returns a
* {@link org.apache.fineract.batch.command.internal.RepayLoanCommandStrategy}
* Request with given requestId.
* Creates and returns a {@link org.apache.fineract.batch.command.internal.RepayLoanCommandStrategy} Request with
* given requestId.
*
*
* @param requestId
@@ -416,8 +401,7 @@ public final class BatchHelper {
}
/**
* Checks that the client with given externalId is not created on the
* server.
* Checks that the client with given externalId is not created on the server.
*
* @param requestSpec
* @param responseSpec
@@ -66,9 +66,8 @@ public class ClientChargesTest {
Assertions.assertNotNull(clientId);
/**
* create a charge for loan and try to associate to client created in
* the above lines.it will be an invalid scenario the reason is client
* is not allowed to have only client charge.
* create a charge for loan and try to associate to client created in the above lines.it will be an invalid
* scenario the reason is client is not allowed to have only client charge.
*
*/
final Integer loanChargeId = ChargesHelper.createCharges(this.requestSpec, this.responseSpec,
@@ -80,8 +79,7 @@ public class ClientChargesTest {
Assertions.assertNull(clientLoanChargeId);
/**
* associates a clientCharge to a client and pay client charge for 10
* USD--success scenario
* associates a clientCharge to a client and pay client charge for 10 USD--success scenario
**/
final Integer clientChargeId = ClientHelper.addChargesForClient(this.requestSpec, this.responseSpec, clientId,
ClientHelper.getSpecifiedDueDateChargesClientAsJSON(chargeId.toString(), "29 October 2011"));
@@ -93,16 +91,15 @@ public class ClientChargesTest {
(float) 190.0);
/**
* Revert the paid client charge transaction by passing the
* clientChargePaidTransactionId and ensure the same is reverted.
* Revert the paid client charge transaction by passing the clientChargePaidTransactionId and ensure the same is
* reverted.
*/
final Integer undoTrxnId = ClientHelper.revertClientChargeTransaction(this.requestSpec, this.responseSpec, clientId.toString(),
clientChargePaidTransactionId);
Assertions.assertNotNull(undoTrxnId);
isReversedTransaction(clientId.toString(), undoTrxnId.toString());
/**
* Now pay client charge for 20 USD and ensure the outstanding amount is
* updated properly
* Now pay client charge for 20 USD and ensure the outstanding amount is updated properly
*/
ResponseSpecification responseSpecFailure = new ResponseSpecBuilder().expectStatusCode(400).build();
DateFormat dateFormat = new SimpleDateFormat("dd MMMM yyyy");
@@ -119,32 +116,28 @@ public class ClientChargesTest {
Assertions.assertNotNull(waiveOffClientChargeTransactionId);
/**
* Revert the waived off client charge transaction by passing the
* waiveOffClientChargeTransactionId and ensured the transaction is
* reversed.
* Revert the waived off client charge transaction by passing the waiveOffClientChargeTransactionId and ensured
* the transaction is reversed.
*/
final Integer undoWaiveTrxnId = ClientHelper.revertClientChargeTransaction(this.requestSpec, this.responseSpec, clientId.toString(),
waiveOffClientChargeTransactionId);
Assertions.assertNotNull(undoWaiveTrxnId);
isReversedTransaction(clientId.toString(), undoWaiveTrxnId.toString());
/**
* pay client charge before client activation date and ensured its a
* failure test case
* pay client charge before client activation date and ensured its a failure test case
*/
final String responseId_activationDate_failure = ClientHelper.payChargesForClients(this.requestSpec, responseSpecFailure, clientId,
clientChargeId, ClientHelper.getPayChargeJSON("30 September 2011", "20"));
Assertions.assertNull(responseId_activationDate_failure);
/**
* pay client charge more than outstanding amount amount and ensured its
* a failure test case
* pay client charge more than outstanding amount amount and ensured its a failure test case
*/
final String responseId_moreAmount_failure = ClientHelper.payChargesForClients(this.requestSpec, responseSpecFailure, clientId,
clientChargeId, ClientHelper.getPayChargeJSON("25 AUGUST 2015", "300"));
Assertions.assertNull(responseId_moreAmount_failure);
/**
* pay client charge for 10 USD and ensure outstanding amount is updated
* properly
* pay client charge for 10 USD and ensure outstanding amount is updated properly
*/
final String chargePaid_responseId = ClientHelper.payChargesForClients(this.requestSpec, this.responseSpec, clientId,
clientChargeId, ClientHelper.getPayChargeJSON("25 AUGUST 2015", "100"));
@@ -168,8 +161,8 @@ public class ClientChargesTest {
}
/**
* Check whether the outStandingAmount is equal to expected Amount or not
* after paying or after waiving off the client charge.
* Check whether the outStandingAmount is equal to expected Amount or not after paying or after waiving off the
* client charge.
*
* @param outStandingAmount
* @param expectedAmount
@@ -54,12 +54,12 @@ public class CurrencyDomain implements Comparable<CurrencyDomain> {
private String displayLabel;
CurrencyDomain() {
super();
}
private CurrencyDomain(final String code, final String name, final int decimalPlaces, final String displaySymbol, final String nameCode,
final String displayLabel) {
super();
this.code = code;
this.name = name;
this.decimalPlaces = decimalPlaces;
@@ -110,16 +110,13 @@ public class GlobalConfigurationHelper {
}
/**
* Helper method to get the current default instance data of the
* /configurations endpoint. Used to reset and verify that no global
* configuration affects state between integration tests.
* Helper method to get the current default instance data of the /configurations endpoint. Used to reset and verify
* that no global configuration affects state between integration tests.
*
* @see <a href=
* "https://issues.apache.org/jira/browse/FINERACT-722">FINERACT-722</a>
* This is a quick, fail fast and early implementation to resolve this
* issue. TODO: A more robust future solution would be isolating all
* integration test state using Spring Framework's integration test
* infrastructure for transaction commits and rollbacks.
* @see <a href= "https://issues.apache.org/jira/browse/FINERACT-722">FINERACT-722</a> This is a quick, fail fast
* and early implementation to resolve this issue. TODO: A more robust future solution would be isolating all
* integration test state using Spring Framework's integration test infrastructure for transaction commits and
* rollbacks.
*/
private static ArrayList<HashMap> getAllDefaultGlobalConfigurations() {
@@ -33,21 +33,21 @@ public class ImageHelper {
public static Integer createImageForStaff(final RequestSpecification requestSpec, final ResponseSpecification responseSpec,
Integer staffId) {
LOG.info("---------------------------------CREATING AN IMAGE FOR STAFF---------------------------------------------");
String URL = STAFF_IMAGE_URL + staffId + IMAGES_URI + "?" + Utils.TENANT_IDENTIFIER;
final String URL = STAFF_IMAGE_URL + staffId + IMAGES_URI + "?" + Utils.TENANT_IDENTIFIER;
return Utils.performServerPost(requestSpec, responseSpec, URL, generateImageAsText(), "resourceId");
}
public static Integer updateImageForStaff(final RequestSpecification requestSpec, final ResponseSpecification responseSpec,
Integer staffId) {
LOG.info("---------------------------------UPDATING AN IMAGE FOR STAFF---------------------------------------------");
String URL = STAFF_IMAGE_URL + staffId + IMAGES_URI + "?" + Utils.TENANT_IDENTIFIER;
final String URL = STAFF_IMAGE_URL + staffId + IMAGES_URI + "?" + Utils.TENANT_IDENTIFIER;
return Utils.performServerPut(requestSpec, responseSpec, URL, generateImageAsText(), "resourceId");
}
public static String getStaffImageAsText(final RequestSpecification requestSpec, final ResponseSpecification responseSpec,
Integer staffId) {
LOG.info("---------------------------------RETRIEVING STAFF IMAGE---------------------------------------------");
String URL = STAFF_IMAGE_URL + staffId + IMAGES_URI + "?" + Utils.TENANT_IDENTIFIER;
final String URL = STAFF_IMAGE_URL + staffId + IMAGES_URI + "?" + Utils.TENANT_IDENTIFIER;
requestSpec.header(HttpHeaders.ACCEPT, "text/plain");
return Utils.performGetTextResponse(requestSpec, responseSpec, URL);
}
@@ -55,7 +55,7 @@ public class ImageHelper {
public static byte[] getStaffImageAsBinary(final RequestSpecification requestSpec, final ResponseSpecification responseSpec,
Integer staffId) {
LOG.info("---------------------------------RETRIEVING STAFF IMAGE---------------------------------------------");
String URL = STAFF_IMAGE_URL + staffId + IMAGES_URI + "?" + Utils.TENANT_IDENTIFIER;
final String URL = STAFF_IMAGE_URL + staffId + IMAGES_URI + "?" + Utils.TENANT_IDENTIFIER;
requestSpec.header(HttpHeaders.ACCEPT, "application/octet-stream");
return Utils.performGetBinaryResponse(requestSpec, responseSpec, URL);
}
@@ -63,7 +63,7 @@ public class ImageHelper {
public static Integer deleteStaffImage(final RequestSpecification requestSpec, final ResponseSpecification responseSpec,
Integer staffId) {
LOG.info("---------------------------------RETRIEVING STAFF IMAGE---------------------------------------------");
String URL = STAFF_IMAGE_URL + staffId + IMAGES_URI + "?" + Utils.TENANT_IDENTIFIER;
final String URL = STAFF_IMAGE_URL + staffId + IMAGES_URI + "?" + Utils.TENANT_IDENTIFIER;
return Utils.performServerDelete(requestSpec, responseSpec, URL, "resourceId");
}
@@ -55,12 +55,12 @@ public class OfficeDomain {
private String hierarchy;
OfficeDomain() {
super();
}
private OfficeDomain(final int id, final String name, final String nameDecorated, final String externalId, final String[] openingDate,
final String hierarchy) {
super();
this.id = id;
this.name = name;
this.nameDecorated = nameDecorated;
@@ -74,7 +74,6 @@ public class ProvisioningIntegrationTest {
public void testCreateProvisioningCriteria() {
ProvisioningTransactionHelper transactionHelper = new ProvisioningTransactionHelper(requestSpec, responseSpec);
ArrayList<Integer> loanProducts = new ArrayList<>(LOANPRODUCTS_SIZE);
List<Integer> loans = new ArrayList<>();
final Integer clientID = ClientHelper.createClient(this.requestSpec, this.responseSpec);
ClientHelper.verifyClientCreatedOnServer(this.requestSpec, this.responseSpec, clientID);
for (int i = 0; i < LOANPRODUCTS_SIZE; i++) {
@@ -90,7 +89,6 @@ public class ProvisioningIntegrationTest {
LOG.info("-------------------------------DISBURSE LOAN-------------------------------------------");
loanStatusHashMap = this.loanTransactionHelper.disburseLoan("20 September 2011", loanID);
LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap);
loans.add(loanID);
Assertions.assertNotNull(loanID);
}
@@ -142,15 +142,13 @@ public class SchedulerJobHelper {
* Launches a Job and awaits its completion.
*
* @param jobName
* displayName (see
* {@link org.apache.fineract.infrastructure.jobs.service.JobName})
* of Scheduler Job
* displayName (see {@link org.apache.fineract.infrastructure.jobs.service.JobName}) of Scheduler Job
*
* @author Michael Vorburger.ch
*/
public void executeAndAwaitJob(String jobName) {
Duration TIMEOUT = Duration.ofSeconds(30);
Duration PAUSE = Duration.ofMillis(500);
final Duration timeout = Duration.ofSeconds(30);
final Duration pause = Duration.ofMillis(500);
DateTimeFormatter df = DateTimeFormatter.ISO_INSTANT; // FINERACT-926
Instant beforeExecuteTime = now().truncatedTo(ChronoUnit.SECONDS);
@@ -164,7 +162,7 @@ public class SchedulerJobHelper {
// Await JobDetailData.lastRunHistory [JobDetailHistoryData]
// jobRunStartTime >= beforeExecuteTime (or timeout)
await().atMost(TIMEOUT).pollInterval(PAUSE).until(jobLastRunHistorySupplier(jobId), lastRunHistory -> {
await().atMost(timeout).pollInterval(pause).until(jobLastRunHistorySupplier(jobId), lastRunHistory -> {
String jobRunStartText = lastRunHistory.get("jobRunStartTime");
if (jobRunStartText == null) {
return false;
@@ -175,7 +173,7 @@ public class SchedulerJobHelper {
// Await JobDetailData.lastRunHistory [JobDetailHistoryData]
// jobRunEndTime to be both set and >= jobRunStartTime (or timeout)
Map<String, String> finalLastRunHistory = await().atMost(TIMEOUT).pollInterval(PAUSE).until(jobLastRunHistorySupplier(jobId),
Map<String, String> finalLastRunHistory = await().atMost(timeout).pollInterval(pause).until(jobLastRunHistorySupplier(jobId),
lastRunHistory -> {
String jobRunEndText = lastRunHistory.get("jobRunEndTime");
if (jobRunEndText == null) {
@@ -45,8 +45,8 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Util for RestAssured tests. This class here in src/integrationTest is
* copy/pasted to src/test; please keep them in sync.
* Util for RestAssured tests. This class here in src/integrationTest is copy/pasted to src/test; please keep them in
* sync.
*/
@SuppressWarnings("unchecked")
public class Utils {
@@ -27,8 +27,8 @@ import org.apache.fineract.integrationtests.common.Utils;
@SuppressWarnings("rawtypes")
public class AccountHelper {
private final String CREATE_GL_ACCOUNT_URL = "/fineract-provider/api/v1/glaccounts?" + Utils.TENANT_IDENTIFIER;
private final String GL_ACCOUNT_ID_RESPONSE = "resourceId";
private static final String CREATE_GL_ACCOUNT_URL = "/fineract-provider/api/v1/glaccounts?" + Utils.TENANT_IDENTIFIER;
private static final String GL_ACCOUNT_ID_RESPONSE = "resourceId";
private final RequestSpecification requestSpec;
private final ResponseSpecification responseSpec;
@@ -40,29 +40,29 @@ public class AccountHelper {
public Account createAssetAccount() {
final String assetAccountJSON = new GLAccountBuilder().withAccountTypeAsAsset().build();
final Integer accountID = Utils.performServerPost(this.requestSpec, this.responseSpec, this.CREATE_GL_ACCOUNT_URL, assetAccountJSON,
this.GL_ACCOUNT_ID_RESPONSE);
final Integer accountID = Utils.performServerPost(this.requestSpec, this.responseSpec, CREATE_GL_ACCOUNT_URL, assetAccountJSON,
GL_ACCOUNT_ID_RESPONSE);
return new Account(accountID, Account.AccountType.ASSET);
}
public Account createIncomeAccount() {
final String assetAccountJSON = new GLAccountBuilder().withAccountTypeAsIncome().build();
final Integer accountID = Utils.performServerPost(this.requestSpec, this.responseSpec, this.CREATE_GL_ACCOUNT_URL, assetAccountJSON,
this.GL_ACCOUNT_ID_RESPONSE);
final Integer accountID = Utils.performServerPost(this.requestSpec, this.responseSpec, CREATE_GL_ACCOUNT_URL, assetAccountJSON,
GL_ACCOUNT_ID_RESPONSE);
return new Account(accountID, Account.AccountType.INCOME);
}
public Account createExpenseAccount() {
final String assetAccountJSON = new GLAccountBuilder().withAccountTypeAsExpense().build();
final Integer accountID = Utils.performServerPost(this.requestSpec, this.responseSpec, this.CREATE_GL_ACCOUNT_URL, assetAccountJSON,
this.GL_ACCOUNT_ID_RESPONSE);
final Integer accountID = Utils.performServerPost(this.requestSpec, this.responseSpec, CREATE_GL_ACCOUNT_URL, assetAccountJSON,
GL_ACCOUNT_ID_RESPONSE);
return new Account(accountID, Account.AccountType.EXPENSE);
}
public Account createLiabilityAccount() {
final String liabilityAccountJSON = new GLAccountBuilder().withAccountTypeAsLiability().build();
final Integer accountID = Utils.performServerPost(this.requestSpec, this.responseSpec, this.CREATE_GL_ACCOUNT_URL,
liabilityAccountJSON, this.GL_ACCOUNT_ID_RESPONSE);
final Integer accountID = Utils.performServerPost(this.requestSpec, this.responseSpec, CREATE_GL_ACCOUNT_URL, liabilityAccountJSON,
GL_ACCOUNT_ID_RESPONSE);
return new Account(accountID, Account.AccountType.LIABILITY);
}
@@ -66,15 +66,6 @@ public class JournalEntryHelper {
}
private String getEntryValueFromJournalEntry(final ArrayList<HashMap> entryResponse, final int entryNumber) {
final HashMap map = (HashMap) entryResponse.get(entryNumber).get("entryType");
return (String) map.get("value");
}
private Float getTransactionAmountFromJournalEntry(final ArrayList<HashMap> entryResponse, final int entryNumber) {
return (Float) entryResponse.get(entryNumber).get("amount");
}
private void checkJournalEntry(final Integer officeId, final Account account, final String date, final JournalEntry... accountEntries) {
final String url = createURLForGettingAccountEntries(account, date, officeId);
final ArrayList<HashMap> response = Utils.performServerGet(this.requestSpec, this.responseSpec, url, "pageItems");
@@ -47,11 +47,11 @@ public class FundsHelper {
private Long resourceId;
FundsHelper() {
super();
}
private FundsHelper(final String name, final String externalId) {
super();
this.name = name;
this.externalId = externalId;
}
@@ -98,14 +98,14 @@ public class LoanApplicationTestBuilder {
return build(map, loanProductId, savingsID);
}
public String build(final String ID, final String loanProductId, final String savingsID) {
public String build(final String id, final String loanProductId, final String savingsID) {
final HashMap<String, Object> map = new HashMap<>();
if ("group".equals(this.loanType)) {
map.put("groupId", ID);
map.put("groupId", id);
} else {
map.put("clientId", ID);
map.put("clientId", id);
}
return build(map, loanProductId, savingsID);
}
@@ -334,12 +334,10 @@ public class LoanApplicationTestBuilder {
}
/**
* calendarID parameter is used to sync repayments with group meetings,
* especially when using jlg loans
* calendarID parameter is used to sync repayments with group meetings, especially when using jlg loans
*
* @param calendarId
* the id of the calender record of the group meeting from
* m_calendar table
* the id of the calender record of the group meeting from m_calendar table
* @return
*/
public LoanApplicationTestBuilder withCalendarID(String calendarId) {
@@ -348,10 +346,8 @@ public class LoanApplicationTestBuilder {
}
/**
* This indicator is used mainly for jlg loans when we want to sync
* disbursement with the group meetings (it seems that if we do use this
* parameter we should also use calendarID to sync repayment with group
* meetings)
* This indicator is used mainly for jlg loans when we want to sync disbursement with the group meetings (it seems
* that if we do use this parameter we should also use calendarID to sync repayment with group meetings)
*
* @return
*/
@@ -81,27 +81,18 @@ public class LoanDisbursementTestBuilder {
}
/*
* public HashMap<String, String> build(String dueDate,String
* totalOriginalDueForPeriod,String totalOutstandingForPeriod, String
* interestOutstanding, String principalOutstanding, String
* principalLoanBalanceOutstanding, String principalDue, String
* principalOriginalDue, String fromDate) { HashMap<String, String>
* expectedRepaymentSchedule = new HashMap<String, String>();
* expectedRepaymentSchedule.put("dueDate", dueDate);
* expectedRepaymentSchedule.put("totalOriginalDueForPeriod",
* totalOriginalDueForPeriod);
* expectedRepaymentSchedule.put("totalOutstandingForPeriod",
* totalOutstandingForPeriod);
* expectedRepaymentSchedule.put("interestOutstanding",
* interestOutstanding);
* expectedRepaymentSchedule.put("principalOutstanding",
* principalOutstanding);
* expectedRepaymentSchedule.put("principalLoanBalanceOutstanding",
* principalLoanBalanceOutstanding);
* public HashMap<String, String> build(String dueDate,String totalOriginalDueForPeriod,String
* totalOutstandingForPeriod, String interestOutstanding, String principalOutstanding, String
* principalLoanBalanceOutstanding, String principalDue, String principalOriginalDue, String fromDate) {
* HashMap<String, String> expectedRepaymentSchedule = new HashMap<String, String>();
* expectedRepaymentSchedule.put("dueDate", dueDate); expectedRepaymentSchedule.put("totalOriginalDueForPeriod",
* totalOriginalDueForPeriod); expectedRepaymentSchedule.put("totalOutstandingForPeriod",
* totalOutstandingForPeriod); expectedRepaymentSchedule.put("interestOutstanding", interestOutstanding);
* expectedRepaymentSchedule.put("principalOutstanding", principalOutstanding);
* expectedRepaymentSchedule.put("principalLoanBalanceOutstanding", principalLoanBalanceOutstanding);
* expectedRepaymentSchedule.put("principalDue", principalDue);
* expectedRepaymentSchedule.put("principalOriginalDue",
* principalOriginalDue); expectedRepaymentSchedule.put("fromDate",
* fromDate);
* expectedRepaymentSchedule.put("principalOriginalDue", principalOriginalDue);
* expectedRepaymentSchedule.put("fromDate", fromDate);
*
* return expectedRepaymentSchedule; }
*/
@@ -46,8 +46,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Entity Datatable Checks Integration Test for checking Creation, Deletion and
* Retrieval of Entity-Datatable Check
* Entity Datatable Checks Integration Test for checking Creation, Deletion and Retrieval of Entity-Datatable Check
*/
public class EntityDatatableChecksIntegrationTest {
@@ -102,58 +102,58 @@ public class SavingsAccountHelper {
return sdf.format(calendar.getTime());
}
public Integer applyForSavingsApplication(final Integer ID, final Integer savingsProductID, final String accountType) {
return applyForSavingsApplicationOnDate(ID, savingsProductID, accountType, CREATED_DATE);
public Integer applyForSavingsApplication(final Integer id, final Integer savingsProductID, final String accountType) {
return applyForSavingsApplicationOnDate(id, savingsProductID, accountType, CREATED_DATE);
}
public Integer applyForSavingsApplicationOnDate(final Integer ID, final Integer savingsProductID, final String accountType,
public Integer applyForSavingsApplicationOnDate(final Integer id, final Integer savingsProductID, final String accountType,
final String submittedOnDate) {
return applyForSavingsApplicationOnDate(ID, savingsProductID, accountType, null, false, submittedOnDate);
return applyForSavingsApplicationOnDate(id, savingsProductID, accountType, null, false, submittedOnDate);
}
public Integer applyForSavingsApplicationWithExternalId(final Integer ID, final Integer savingsProductID, final String accountType,
public Integer applyForSavingsApplicationWithExternalId(final Integer id, final Integer savingsProductID, final String accountType,
String externalId, boolean withdrawalFeeForTransfers) {
return applyForSavingsApplicationOnDate(ID, savingsProductID, accountType, externalId, withdrawalFeeForTransfers, CREATED_DATE);
return applyForSavingsApplicationOnDate(id, savingsProductID, accountType, externalId, withdrawalFeeForTransfers, CREATED_DATE);
}
public Integer applyForSavingsApplicationOnDate(final Integer ID, final Integer savingsProductID, final String accountType,
public Integer applyForSavingsApplicationOnDate(final Integer id, final Integer savingsProductID, final String accountType,
String externalId, boolean withdrawalFeeForTransfers, final String submittedOnDate) {
LOG.info("--------------------------------APPLYING FOR SAVINGS APPLICATION--------------------------------");
final String savingsApplicationJSON = new SavingsApplicationTestBuilder() //
.withExternalId(externalId) //
.withWithdrawalFeeForTransfers(withdrawalFeeForTransfers) //
.withSubmittedOnDate(submittedOnDate) //
.build(ID.toString(), savingsProductID.toString(), accountType);
.build(id.toString(), savingsProductID.toString(), accountType);
return Utils.performServerPost(this.requestSpec, this.responseSpec, SAVINGS_ACCOUNT_URL + "?" + Utils.TENANT_IDENTIFIER,
savingsApplicationJSON, "savingsId");
}
public Integer applyForSavingsApplicationWithDatatables(final Integer ID, final Integer savingsProductID, final String accountType,
public Integer applyForSavingsApplicationWithDatatables(final Integer id, final Integer savingsProductID, final String accountType,
final String submittedOnDate, final String datatableName) {
LOG.info("----------------------------APPLYING FOR SAVINGS APPLICATION WITH DATATABLES----------------------------");
final String savingsApplicationJSON = new SavingsApplicationTestBuilder() //
.withSubmittedOnDate(submittedOnDate) //
.withDatatables(getTestDatatableAsJson(datatableName)) //
.build(ID.toString(), savingsProductID.toString(), accountType);
.build(id.toString(), savingsProductID.toString(), accountType);
return Utils.performServerPost(this.requestSpec, this.responseSpec, SAVINGS_ACCOUNT_URL + "?" + Utils.TENANT_IDENTIFIER,
savingsApplicationJSON, "savingsId");
}
public Object applyForSavingsApplicationWithFailure(final Integer ID, final Integer savingsProductID, final String accountType,
public Object applyForSavingsApplicationWithFailure(final Integer id, final Integer savingsProductID, final String accountType,
final String submittedOnDate, final String responseAttribute) {
LOG.info("----------------------------APPLYING FOR SAVINGS APPLICATION WITH ERROR----------------------------");
final String savingsApplicationJSON = new SavingsApplicationTestBuilder() //
.withSubmittedOnDate(submittedOnDate) //
.build(ID.toString(), savingsProductID.toString(), accountType);
.build(id.toString(), savingsProductID.toString(), accountType);
return Utils.performServerPost(this.requestSpec, this.responseSpec, SAVINGS_ACCOUNT_URL + "?" + Utils.TENANT_IDENTIFIER,
savingsApplicationJSON, responseAttribute);
}
public HashMap updateSavingsAccount(final Integer ID, final Integer savingsProductID, final Integer savingsId,
public HashMap updateSavingsAccount(final Integer id, final Integer savingsProductID, final Integer savingsId,
final String accountType) {
final String savingsApplicationJSON = new SavingsApplicationTestBuilder() //
.withSubmittedOnDate(CREATED_DATE_PLUS_ONE) //
.build(ID.toString(), savingsProductID.toString(), accountType);
.build(id.toString(), savingsProductID.toString(), accountType);
return Utils.performServerPut(this.requestSpec, this.responseSpec,
SAVINGS_ACCOUNT_URL + "/" + savingsId + "?" + Utils.TENANT_IDENTIFIER, savingsApplicationJSON,
@@ -591,13 +591,13 @@ public class SavingsAccountHelper {
}
private HashMap performSavingApplicationActions(final String postURLForSavingsTransaction, final String jsonToBeSent,
final Boolean IS_BLOCK) {
final Boolean isBlock) {
HashMap status = null;
final HashMap response = Utils.performServerPost(this.requestSpec, this.responseSpec, postURLForSavingsTransaction, jsonToBeSent,
CommonConstants.RESPONSE_CHANGES);
if (response != null) {
status = (HashMap) response.get("status");
if (IS_BLOCK != null && IS_BLOCK) {
if (isBlock != null && isBlock) {
status = (HashMap) response.get("subStatus");
}
}
@@ -43,14 +43,14 @@ public class SavingsApplicationTestBuilder {
private List<Map<String, Object>> clientArray = null;
private List<Map<String, Object>> savingsArray = null;
public String build(final String ID, final String savingsProductId, final String accountType) {
public String build(final String id, final String savingsProductId, final String accountType) {
final HashMap<String, Object> map = new HashMap<>();
map.put("dateFormat", "dd MMMM yyyy");
if (accountType.equals("GROUP")) {
map.put("groupId", ID);
map.put("groupId", id);
} else {
map.put("clientId", ID);
map.put("clientId", id);
}
map.put("productId", savingsProductId);
map.put("locale", LOCALE);
@@ -60,15 +60,11 @@ public class DividendsIntegrationTests {
public void testCreateDividends() {
DateFormat simple = new SimpleDateFormat("dd MMM yyyy");
final Integer productId = createShareProduct();
ArrayList<Integer> clients = new ArrayList<>();
ArrayList<Integer> savingAccounts = new ArrayList<>();
ArrayList<Integer> shareAccounts = new ArrayList<>();
for (int i = 0; i < 5; i++) {
final Integer clientId = ClientHelper.createClient(this.requestSpec, this.responseSpec);
clients.add(clientId);
Assertions.assertNotNull(clientId);
Integer savingsAccountId = SavingsAccountHelper.openSavingsAccount(requestSpec, responseSpec, clientId, "1000");
savingAccounts.add(savingsAccountId);
Assertions.assertNotNull(savingsAccountId);
final Integer shareAccountId = createShareAccount(clientId, productId, savingsAccountId, dates[i], shares[i]);
shareAccounts.add(shareAccountId);
@@ -56,12 +56,12 @@ public class GuarantorTest {
private LoanTransactionHelper loanTransactionHelper;
private GuarantorHelper guarantorHelper;
private SavingsAccountHelper savingsAccountHelper;
private final Float self1_balance = Float.valueOf((float) 5000);
private final Float external1_balance = Float.valueOf((float) 5000);
private final Float external2_balance = Float.valueOf((float) 5000);
private final Float self1_guarantee = Float.valueOf((float) 2000);
private final Float external1_guarantee = Float.valueOf((float) 2000);
private final Float external2_guarantee = Float.valueOf((float) 1000);
private static final Float SELF1_BALANCE = Float.valueOf((float) 5000);
private static final Float EXTERNAL1_BALANCE = Float.valueOf((float) 5000);
private static final Float EXTERNAL2_BALANCE = Float.valueOf((float) 5000);
private static final Float SELF1_GURANTEE = Float.valueOf((float) 2000);
private static final Float EXTERNAL1_GURANTEE = Float.valueOf((float) 2000);
private static final Float EXTERNAL2_GURANTEE = Float.valueOf((float) 1000);
@BeforeEach
public void setUp() throws Exception {
@@ -89,18 +89,18 @@ public class GuarantorTest {
ClientHelper.verifyClientCreatedOnServer(this.requestSpec, this.responseSpec, clientID_external);
final Integer selfSavigsId = SavingsAccountHelper.openSavingsAccount(this.requestSpec, this.responseSpec, clientID,
String.valueOf(self1_balance));
String.valueOf(SELF1_BALANCE));
final Integer externalSavigsId_1 = SavingsAccountHelper.openSavingsAccount(this.requestSpec, this.responseSpec, clientID_external,
String.valueOf(external1_balance));
String.valueOf(EXTERNAL1_BALANCE));
final Integer externalSavigsId_2 = SavingsAccountHelper.openSavingsAccount(this.requestSpec, this.responseSpec, clientID_external2,
String.valueOf(external2_balance));
String.valueOf(EXTERNAL2_BALANCE));
final Integer loanProductID = createLoanProductWithHoldFunds("50", "20", "20");
DateFormat dateFormat = new SimpleDateFormat("dd MMMM yyyy", Locale.US);
Calendar todaysDate = Calendar.getInstance();
todaysDate.add(Calendar.DAY_OF_MONTH, -7 * 4);
String LOAN_DISBURSEMENT_DATE = dateFormat.format(todaysDate.getTime());
final Integer loanID = applyForLoanApplication(clientID, loanProductID, LOAN_DISBURSEMENT_DATE);
final String loanDisbursementDate = dateFormat.format(todaysDate.getTime());
final Integer loanID = applyForLoanApplication(clientID, loanProductID, loanDisbursementDate);
Assertions.assertNotNull(loanID);
HashMap loanStatusHashMap = LoanStatusChecker.getStatusOfLoan(this.requestSpec, this.responseSpec, loanID);
LoanStatusChecker.verifyLoanIsPending(loanStatusHashMap);
@@ -113,49 +113,50 @@ public class GuarantorTest {
Integer withoutGuaranteeAmount = this.guarantorHelper.createGuarantor(loanID, guarantorJSON);
Assertions.assertNotNull(withoutGuaranteeAmount);
ArrayList<HashMap> errorData = (ArrayList<HashMap>) this.loanTransactionHelper.approveLoan(LOAN_DISBURSEMENT_DATE, null, loanID,
ArrayList<HashMap> errorData = (ArrayList<HashMap>) this.loanTransactionHelper.approveLoan(loanDisbursementDate, null, loanID,
CommonConstants.RESPONSE_ERROR);
assertTrue(checkForErrorCode(errorData, "validation.msg.loan.guarantor.min.self.guarantee.required"));
assertTrue(checkForErrorCode(errorData, "validation.msg.loan.guarantor.min.external.guarantee.required"));
assertTrue(checkForErrorCode(errorData, "validation.msg.loan.guarantor.mandated.guarantee.required"));
guarantorJSON = new GuarantorTestBuilder().existingCustomerWithGuaranteeAmount(String.valueOf(clientID),
String.valueOf(selfSavigsId), String.valueOf(self1_guarantee)).build();
guarantorJSON = new GuarantorTestBuilder()
.existingCustomerWithGuaranteeAmount(String.valueOf(clientID), String.valueOf(selfSavigsId), String.valueOf(SELF1_GURANTEE))
.build();
Integer selfGuarantee = this.guarantorHelper.createGuarantor(loanID, guarantorJSON);
verifySavingsOnHoldBalance(selfSavigsId, null);
Assertions.assertNotNull(selfGuarantee);
errorData = (ArrayList<HashMap>) this.loanTransactionHelper.approveLoan(LOAN_DISBURSEMENT_DATE, null, loanID,
errorData = (ArrayList<HashMap>) this.loanTransactionHelper.approveLoan(loanDisbursementDate, null, loanID,
CommonConstants.RESPONSE_ERROR);
assertFalse(checkForErrorCode(errorData, "validation.msg.loan.guarantor.min.self.guarantee.required"));
assertTrue(checkForErrorCode(errorData, "validation.msg.loan.guarantor.min.external.guarantee.required"));
assertTrue(checkForErrorCode(errorData, "validation.msg.loan.guarantor.mandated.guarantee.required"));
guarantorJSON = new GuarantorTestBuilder().existingCustomerWithGuaranteeAmount(String.valueOf(clientID_external),
String.valueOf(externalSavigsId_1), String.valueOf(external1_guarantee)).build();
String.valueOf(externalSavigsId_1), String.valueOf(EXTERNAL1_GURANTEE)).build();
Integer externalGuarantee_1 = this.guarantorHelper.createGuarantor(loanID, guarantorJSON);
verifySavingsOnHoldBalance(externalSavigsId_1, null);
Assertions.assertNotNull(externalGuarantee_1);
errorData = (ArrayList<HashMap>) this.loanTransactionHelper.approveLoan(LOAN_DISBURSEMENT_DATE, null, loanID,
errorData = (ArrayList<HashMap>) this.loanTransactionHelper.approveLoan(loanDisbursementDate, null, loanID,
CommonConstants.RESPONSE_ERROR);
assertFalse(checkForErrorCode(errorData, "validation.msg.loan.guarantor.min.self.guarantee.required"));
assertFalse(checkForErrorCode(errorData, "validation.msg.loan.guarantor.min.external.guarantee.required"));
assertTrue(checkForErrorCode(errorData, "validation.msg.loan.guarantor.mandated.guarantee.required"));
guarantorJSON = new GuarantorTestBuilder().existingCustomerWithGuaranteeAmount(String.valueOf(clientID_external2),
String.valueOf(externalSavigsId_2), String.valueOf(external2_guarantee)).build();
String.valueOf(externalSavigsId_2), String.valueOf(EXTERNAL2_GURANTEE)).build();
Integer externalGuarantee_2 = this.guarantorHelper.createGuarantor(loanID, guarantorJSON);
verifySavingsOnHoldBalance(externalSavigsId_2, null);
Assertions.assertNotNull(externalGuarantee_2);
LOG.info("-----------------------------------APPROVE LOAN-----------------------------------------");
loanStatusHashMap = this.loanTransactionHelper.approveLoan(LOAN_DISBURSEMENT_DATE, loanID);
loanStatusHashMap = this.loanTransactionHelper.approveLoan(loanDisbursementDate, loanID);
LoanStatusChecker.verifyLoanIsApproved(loanStatusHashMap);
LoanStatusChecker.verifyLoanIsWaitingForDisbursal(loanStatusHashMap);
self1_hold_funds += self1_guarantee;
external1_hold_funds += external1_guarantee;
external2_hold_funds += external2_guarantee;
self1_hold_funds += SELF1_GURANTEE;
external1_hold_funds += EXTERNAL1_GURANTEE;
external2_hold_funds += EXTERNAL2_GURANTEE;
verifySavingsOnHoldBalance(selfSavigsId, self1_hold_funds);
verifySavingsOnHoldBalance(externalSavigsId_1, external1_hold_funds);
verifySavingsOnHoldBalance(externalSavigsId_2, external2_hold_funds);
@@ -168,7 +169,7 @@ public class GuarantorTest {
verifySavingsOnHoldBalance(externalSavigsId_2, Float.valueOf((float) 0));
LOG.info("-----------------------------------APPROVE LOAN-----------------------------------------");
loanStatusHashMap = this.loanTransactionHelper.approveLoan(LOAN_DISBURSEMENT_DATE, loanID);
loanStatusHashMap = this.loanTransactionHelper.approveLoan(loanDisbursementDate, loanID);
LoanStatusChecker.verifyLoanIsApproved(loanStatusHashMap);
LoanStatusChecker.verifyLoanIsWaitingForDisbursal(loanStatusHashMap);
verifySavingsOnHoldBalance(selfSavigsId, self1_hold_funds);
@@ -176,18 +177,18 @@ public class GuarantorTest {
verifySavingsOnHoldBalance(externalSavigsId_2, external2_hold_funds);
LOG.info("-------------------------------DISBURSE LOAN-------------------------------------------");
loanStatusHashMap = this.loanTransactionHelper.disburseLoan(LOAN_DISBURSEMENT_DATE, loanID);
loanStatusHashMap = this.loanTransactionHelper.disburseLoan(loanDisbursementDate, loanID);
LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap);
// First repayment
ArrayList<HashMap> loanSchedule = this.loanTransactionHelper.getLoanRepaymentSchedule(this.requestSpec, this.responseSpec, loanID);
todaysDate = Calendar.getInstance();
todaysDate.add(Calendar.DAY_OF_MONTH, -7 * 3);
String LOAN_REPAYMENT_DATE = dateFormat.format(todaysDate.getTime());
String loanRepaymentDate = dateFormat.format(todaysDate.getTime());
Float totalDueForCurrentPeriod = (Float) loanSchedule.get(1).get("totalDueForPeriod");
external1_hold_funds -= Float.valueOf((float) 827.5867);
external2_hold_funds -= Float.valueOf((float) 413.7933);
this.loanTransactionHelper.makeRepayment(LOAN_REPAYMENT_DATE, totalDueForCurrentPeriod, loanID);
this.loanTransactionHelper.makeRepayment(loanRepaymentDate, totalDueForCurrentPeriod, loanID);
verifySavingsOnHoldBalance(selfSavigsId, self1_hold_funds);
verifySavingsOnHoldBalance(externalSavigsId_1, external1_hold_funds);
verifySavingsOnHoldBalance(externalSavigsId_2, external2_hold_funds);
@@ -195,11 +196,11 @@ public class GuarantorTest {
// Second repayment
todaysDate = Calendar.getInstance();
todaysDate.add(Calendar.DAY_OF_MONTH, -7 * 2);
LOAN_REPAYMENT_DATE = dateFormat.format(todaysDate.getTime());
loanRepaymentDate = dateFormat.format(todaysDate.getTime());
totalDueForCurrentPeriod = (Float) loanSchedule.get(2).get("totalDueForPeriod");
external1_hold_funds -= Float.valueOf((float) 831.4067);
external2_hold_funds -= Float.valueOf((float) 415.7033333);
this.loanTransactionHelper.makeRepayment(LOAN_REPAYMENT_DATE, totalDueForCurrentPeriod, loanID);
this.loanTransactionHelper.makeRepayment(loanRepaymentDate, totalDueForCurrentPeriod, loanID);
verifySavingsOnHoldBalance(selfSavigsId, self1_hold_funds);
verifySavingsOnHoldBalance(externalSavigsId_1, external1_hold_funds);
verifySavingsOnHoldBalance(externalSavigsId_2, external2_hold_funds);
@@ -207,19 +208,19 @@ public class GuarantorTest {
// third repayment
todaysDate = Calendar.getInstance();
todaysDate.add(Calendar.DAY_OF_MONTH, -7);
LOAN_REPAYMENT_DATE = dateFormat.format(todaysDate.getTime());
loanRepaymentDate = dateFormat.format(todaysDate.getTime());
totalDueForCurrentPeriod = (Float) loanSchedule.get(3).get("totalDueForPeriod");
self1_hold_funds -= Float.valueOf((float) 741.355);
this.loanTransactionHelper.makeRepayment(LOAN_REPAYMENT_DATE, totalDueForCurrentPeriod, loanID);
this.loanTransactionHelper.makeRepayment(loanRepaymentDate, totalDueForCurrentPeriod, loanID);
verifySavingsOnHoldBalance(selfSavigsId, self1_hold_funds);
verifySavingsOnHoldBalance(externalSavigsId_1, Float.valueOf((float) 0));
verifySavingsOnHoldBalance(externalSavigsId_2, Float.valueOf((float) 0));
// forth repayment
todaysDate = Calendar.getInstance();
LOAN_REPAYMENT_DATE = dateFormat.format(todaysDate.getTime());
loanRepaymentDate = dateFormat.format(todaysDate.getTime());
totalDueForCurrentPeriod = (Float) loanSchedule.get(3).get("totalDueForPeriod");
this.loanTransactionHelper.makeRepayment(LOAN_REPAYMENT_DATE, totalDueForCurrentPeriod, loanID);
this.loanTransactionHelper.makeRepayment(loanRepaymentDate, totalDueForCurrentPeriod, loanID);
verifySavingsOnHoldBalance(selfSavigsId, Float.valueOf((float) 0));
verifySavingsOnHoldBalance(externalSavigsId_1, Float.valueOf((float) 0));
verifySavingsOnHoldBalance(externalSavigsId_2, Float.valueOf((float) 0));
@@ -244,20 +245,20 @@ public class GuarantorTest {
ClientHelper.verifyClientCreatedOnServer(this.requestSpec, this.responseSpec, clientID_external);
final Integer selfSavigsId = SavingsAccountHelper.openSavingsAccount(this.requestSpec, this.responseSpec, clientID,
String.valueOf(self1_balance));
String.valueOf(SELF1_BALANCE));
final Integer externalSavigsId_1 = SavingsAccountHelper.openSavingsAccount(this.requestSpec, this.responseSpec, clientID_external,
String.valueOf(external1_balance));
String.valueOf(EXTERNAL1_BALANCE));
final Integer externalSavigsId_3 = SavingsAccountHelper.openSavingsAccount(this.requestSpec, this.responseSpec, clientID_external,
String.valueOf(external1_balance));
String.valueOf(EXTERNAL1_BALANCE));
final Integer externalSavigsId_2 = SavingsAccountHelper.openSavingsAccount(this.requestSpec, this.responseSpec, clientID_external2,
String.valueOf(external2_balance));
String.valueOf(EXTERNAL2_BALANCE));
final Integer loanProductID = createLoanProductWithHoldFunds("50", "20", "20");
DateFormat dateFormat = new SimpleDateFormat("dd MMMM yyyy", Locale.US);
Calendar todaysDate = Calendar.getInstance();
todaysDate.add(Calendar.DAY_OF_MONTH, -7 * 4);
String LOAN_DISBURSEMENT_DATE = dateFormat.format(todaysDate.getTime());
final Integer loanID = applyForLoanApplication(clientID, loanProductID, LOAN_DISBURSEMENT_DATE);
final String loanDisbursementDate = dateFormat.format(todaysDate.getTime());
final Integer loanID = applyForLoanApplication(clientID, loanProductID, loanDisbursementDate);
Assertions.assertNotNull(loanID);
HashMap loanStatusHashMap = LoanStatusChecker.getStatusOfLoan(this.requestSpec, this.responseSpec, loanID);
LoanStatusChecker.verifyLoanIsPending(loanStatusHashMap);
@@ -270,49 +271,50 @@ public class GuarantorTest {
Integer withoutGuaranteeAmount = this.guarantorHelper.createGuarantor(loanID, guarantorJSON);
Assertions.assertNotNull(withoutGuaranteeAmount);
ArrayList<HashMap> errorData = (ArrayList<HashMap>) this.loanTransactionHelper.approveLoan(LOAN_DISBURSEMENT_DATE, null, loanID,
ArrayList<HashMap> errorData = (ArrayList<HashMap>) this.loanTransactionHelper.approveLoan(loanDisbursementDate, null, loanID,
CommonConstants.RESPONSE_ERROR);
assertTrue(checkForErrorCode(errorData, "validation.msg.loan.guarantor.min.self.guarantee.required"));
assertTrue(checkForErrorCode(errorData, "validation.msg.loan.guarantor.min.external.guarantee.required"));
assertTrue(checkForErrorCode(errorData, "validation.msg.loan.guarantor.mandated.guarantee.required"));
guarantorJSON = new GuarantorTestBuilder().existingCustomerWithGuaranteeAmount(String.valueOf(clientID),
String.valueOf(selfSavigsId), String.valueOf(self1_guarantee)).build();
guarantorJSON = new GuarantorTestBuilder()
.existingCustomerWithGuaranteeAmount(String.valueOf(clientID), String.valueOf(selfSavigsId), String.valueOf(SELF1_GURANTEE))
.build();
Integer selfGuarantee = this.guarantorHelper.createGuarantor(loanID, guarantorJSON);
verifySavingsOnHoldBalance(selfSavigsId, null);
Assertions.assertNotNull(selfGuarantee);
errorData = (ArrayList<HashMap>) this.loanTransactionHelper.approveLoan(LOAN_DISBURSEMENT_DATE, null, loanID,
errorData = (ArrayList<HashMap>) this.loanTransactionHelper.approveLoan(loanDisbursementDate, null, loanID,
CommonConstants.RESPONSE_ERROR);
assertFalse(checkForErrorCode(errorData, "validation.msg.loan.guarantor.min.self.guarantee.required"));
assertTrue(checkForErrorCode(errorData, "validation.msg.loan.guarantor.min.external.guarantee.required"));
assertTrue(checkForErrorCode(errorData, "validation.msg.loan.guarantor.mandated.guarantee.required"));
guarantorJSON = new GuarantorTestBuilder().existingCustomerWithGuaranteeAmount(String.valueOf(clientID_external),
String.valueOf(externalSavigsId_1), String.valueOf(external1_guarantee)).build();
String.valueOf(externalSavigsId_1), String.valueOf(EXTERNAL1_GURANTEE)).build();
Integer externalGuarantee_1 = this.guarantorHelper.createGuarantor(loanID, guarantorJSON);
verifySavingsOnHoldBalance(externalSavigsId_1, null);
Assertions.assertNotNull(externalGuarantee_1);
errorData = (ArrayList<HashMap>) this.loanTransactionHelper.approveLoan(LOAN_DISBURSEMENT_DATE, null, loanID,
errorData = (ArrayList<HashMap>) this.loanTransactionHelper.approveLoan(loanDisbursementDate, null, loanID,
CommonConstants.RESPONSE_ERROR);
assertFalse(checkForErrorCode(errorData, "validation.msg.loan.guarantor.min.self.guarantee.required"));
assertFalse(checkForErrorCode(errorData, "validation.msg.loan.guarantor.min.external.guarantee.required"));
assertTrue(checkForErrorCode(errorData, "validation.msg.loan.guarantor.mandated.guarantee.required"));
guarantorJSON = new GuarantorTestBuilder().existingCustomerWithGuaranteeAmount(String.valueOf(clientID_external2),
String.valueOf(externalSavigsId_2), String.valueOf(external2_guarantee)).build();
String.valueOf(externalSavigsId_2), String.valueOf(EXTERNAL2_GURANTEE)).build();
Integer externalGuarantee_2 = this.guarantorHelper.createGuarantor(loanID, guarantorJSON);
Assertions.assertNotNull(externalGuarantee_2);
verifySavingsOnHoldBalance(externalSavigsId_2, null);
LOG.info("-----------------------------------APPROVE LOAN-----------------------------------------");
loanStatusHashMap = this.loanTransactionHelper.approveLoan(LOAN_DISBURSEMENT_DATE, loanID);
loanStatusHashMap = this.loanTransactionHelper.approveLoan(loanDisbursementDate, loanID);
LoanStatusChecker.verifyLoanIsApproved(loanStatusHashMap);
LoanStatusChecker.verifyLoanIsWaitingForDisbursal(loanStatusHashMap);
self1_hold_funds += self1_guarantee;
external1_hold_funds += external1_guarantee;
external2_hold_funds += external2_guarantee;
self1_hold_funds += SELF1_GURANTEE;
external1_hold_funds += EXTERNAL1_GURANTEE;
external2_hold_funds += EXTERNAL2_GURANTEE;
verifySavingsOnHoldBalance(selfSavigsId, self1_hold_funds);
verifySavingsOnHoldBalance(externalSavigsId_1, external1_hold_funds);
verifySavingsOnHoldBalance(externalSavigsId_2, external2_hold_funds);
@@ -325,7 +327,7 @@ public class GuarantorTest {
verifySavingsOnHoldBalance(externalSavigsId_2, Float.valueOf((float) 0));
LOG.info("-----------------------------------APPROVE LOAN-----------------------------------------");
loanStatusHashMap = this.loanTransactionHelper.approveLoan(LOAN_DISBURSEMENT_DATE, loanID);
loanStatusHashMap = this.loanTransactionHelper.approveLoan(loanDisbursementDate, loanID);
LoanStatusChecker.verifyLoanIsApproved(loanStatusHashMap);
LoanStatusChecker.verifyLoanIsWaitingForDisbursal(loanStatusHashMap);
verifySavingsOnHoldBalance(selfSavigsId, self1_hold_funds);
@@ -347,9 +349,9 @@ public class GuarantorTest {
assertTrue(checkForErrorCode(error, "validation.msg.loan.guarantor.min.external.guarantee.required"));
guarantorJSON = new GuarantorTestBuilder().existingCustomerWithGuaranteeAmount(String.valueOf(clientID_external),
String.valueOf(externalSavigsId_3), String.valueOf(external1_guarantee)).build();
String.valueOf(externalSavigsId_3), String.valueOf(EXTERNAL1_GURANTEE)).build();
Integer externalGuarantee_3 = this.guarantorHelper.createGuarantor(loanID, guarantorJSON);
verifySavingsOnHoldBalance(externalSavigsId_3, external1_guarantee);
verifySavingsOnHoldBalance(externalSavigsId_3, EXTERNAL1_GURANTEE);
Assertions.assertNotNull(externalGuarantee_3);
this.guarantorHelper.deleteGuarantor(externalGuarantee_1, fundDetailId, loanID);
@@ -367,18 +369,18 @@ public class GuarantorTest {
}
LOG.info("-------------------------------DISBURSE LOAN-------------------------------------------");
loanStatusHashMap = this.loanTransactionHelper.disburseLoan(LOAN_DISBURSEMENT_DATE, loanID);
loanStatusHashMap = this.loanTransactionHelper.disburseLoan(loanDisbursementDate, loanID);
LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap);
// First repayment
ArrayList<HashMap> loanSchedule = this.loanTransactionHelper.getLoanRepaymentSchedule(this.requestSpec, this.responseSpec, loanID);
todaysDate = Calendar.getInstance();
todaysDate.add(Calendar.DAY_OF_MONTH, -7 * 3);
String LOAN_REPAYMENT_DATE = dateFormat.format(todaysDate.getTime());
String loanRepaymentDate = dateFormat.format(todaysDate.getTime());
Float totalDueForCurrentPeriod = (Float) loanSchedule.get(1).get("totalDueForPeriod");
external1_hold_funds -= Float.valueOf((float) 827.5867);
external2_hold_funds -= Float.valueOf((float) 413.7933);
this.loanTransactionHelper.makeRepayment(LOAN_REPAYMENT_DATE, totalDueForCurrentPeriod, loanID);
this.loanTransactionHelper.makeRepayment(loanRepaymentDate, totalDueForCurrentPeriod, loanID);
verifySavingsOnHoldBalance(selfSavigsId, self1_hold_funds);
verifySavingsOnHoldBalance(externalSavigsId_3, external1_hold_funds);
verifySavingsOnHoldBalance(externalSavigsId_2, external2_hold_funds);
@@ -386,11 +388,11 @@ public class GuarantorTest {
// Second repayment
todaysDate = Calendar.getInstance();
todaysDate.add(Calendar.DAY_OF_MONTH, -7 * 2);
LOAN_REPAYMENT_DATE = dateFormat.format(todaysDate.getTime());
loanRepaymentDate = dateFormat.format(todaysDate.getTime());
totalDueForCurrentPeriod = (Float) loanSchedule.get(2).get("totalDueForPeriod");
external1_hold_funds -= Float.valueOf((float) 831.4067);
external2_hold_funds -= Float.valueOf((float) 415.7033333);
this.loanTransactionHelper.makeRepayment(LOAN_REPAYMENT_DATE, totalDueForCurrentPeriod, loanID);
this.loanTransactionHelper.makeRepayment(loanRepaymentDate, totalDueForCurrentPeriod, loanID);
verifySavingsOnHoldBalance(selfSavigsId, self1_hold_funds);
verifySavingsOnHoldBalance(externalSavigsId_3, external1_hold_funds);
verifySavingsOnHoldBalance(externalSavigsId_2, external2_hold_funds);
@@ -398,17 +400,17 @@ public class GuarantorTest {
// third repayment
todaysDate = Calendar.getInstance();
todaysDate.add(Calendar.DAY_OF_MONTH, -7);
LOAN_REPAYMENT_DATE = dateFormat.format(todaysDate.getTime());
loanRepaymentDate = dateFormat.format(todaysDate.getTime());
totalDueForCurrentPeriod = (Float) loanSchedule.get(3).get("totalDueForPeriod");
Float self1_hold_funds_temp = self1_hold_funds - Float.valueOf((float) 741.355);
HashMap transactionDetail = this.loanTransactionHelper.makeRepayment(LOAN_REPAYMENT_DATE, totalDueForCurrentPeriod, loanID);
HashMap transactionDetail = this.loanTransactionHelper.makeRepayment(loanRepaymentDate, totalDueForCurrentPeriod, loanID);
verifySavingsOnHoldBalance(selfSavigsId, self1_hold_funds_temp);
verifySavingsOnHoldBalance(externalSavigsId_3, Float.valueOf((float) 0));
verifySavingsOnHoldBalance(externalSavigsId_2, Float.valueOf((float) 0));
// undo repayment
this.loanTransactionHelper.adjustLoanTransaction(loanID, (Integer) transactionDetail.get(CommonConstants.RESPONSE_RESOURCE_ID),
LOAN_REPAYMENT_DATE, "0", "");
loanRepaymentDate, "0", "");
verifySavingsOnHoldBalance(selfSavigsId, self1_hold_funds);
verifySavingsOnHoldBalance(externalSavigsId_3, external1_hold_funds);
verifySavingsOnHoldBalance(externalSavigsId_2, external2_hold_funds);
@@ -417,9 +419,9 @@ public class GuarantorTest {
loanStatusHashMap = this.loanTransactionHelper.undoDisbursal(loanID);
LoanStatusChecker.verifyLoanIsApproved(loanStatusHashMap);
LoanStatusChecker.verifyLoanIsWaitingForDisbursal(loanStatusHashMap);
verifySavingsOnHoldBalance(selfSavigsId, Float.valueOf((float) self1_guarantee));
verifySavingsOnHoldBalance(externalSavigsId_3, Float.valueOf((float) external1_guarantee));
verifySavingsOnHoldBalance(externalSavigsId_2, Float.valueOf((float) external2_guarantee));
verifySavingsOnHoldBalance(selfSavigsId, Float.valueOf((float) SELF1_GURANTEE));
verifySavingsOnHoldBalance(externalSavigsId_3, Float.valueOf((float) EXTERNAL1_GURANTEE));
verifySavingsOnHoldBalance(externalSavigsId_2, Float.valueOf((float) EXTERNAL2_GURANTEE));
}
@SuppressWarnings({ "rawtypes", "unchecked" })
@@ -434,50 +436,51 @@ public class GuarantorTest {
ClientHelper.verifyClientCreatedOnServer(this.requestSpec, this.responseSpec, clientID_external);
final Integer selfSavigsId = SavingsAccountHelper.openSavingsAccount(this.requestSpec, this.responseSpec, clientID,
String.valueOf(self1_balance));
String.valueOf(SELF1_BALANCE));
final Integer externalSavigsId_1 = SavingsAccountHelper.openSavingsAccount(this.requestSpec, this.responseSpec, clientID_external,
String.valueOf(external1_balance));
String.valueOf(EXTERNAL1_BALANCE));
final Integer loanProductID = createLoanProductWithHoldFunds("40", "20", "20");
DateFormat dateFormat = new SimpleDateFormat("dd MMMM yyyy", Locale.US);
Calendar todaysDate = Calendar.getInstance();
todaysDate.add(Calendar.DAY_OF_MONTH, -21);
String LOAN_DISBURSEMENT_DATE = dateFormat.format(todaysDate.getTime());
final Integer loanID = applyForLoanApplication(clientID, loanProductID, LOAN_DISBURSEMENT_DATE);
final String loanDisbursementDate = dateFormat.format(todaysDate.getTime());
final Integer loanID = applyForLoanApplication(clientID, loanProductID, loanDisbursementDate);
Assertions.assertNotNull(loanID);
HashMap loanStatusHashMap = LoanStatusChecker.getStatusOfLoan(this.requestSpec, this.responseSpec, loanID);
LoanStatusChecker.verifyLoanIsPending(loanStatusHashMap);
String guarantorJSON = new GuarantorTestBuilder().existingCustomerWithGuaranteeAmount(String.valueOf(clientID),
String.valueOf(selfSavigsId), String.valueOf(self1_guarantee)).build();
String guarantorJSON = new GuarantorTestBuilder()
.existingCustomerWithGuaranteeAmount(String.valueOf(clientID), String.valueOf(selfSavigsId), String.valueOf(SELF1_GURANTEE))
.build();
Integer selfGuarantee = this.guarantorHelper.createGuarantor(loanID, guarantorJSON);
verifySavingsOnHoldBalance(selfSavigsId, null);
Assertions.assertNotNull(selfGuarantee);
guarantorJSON = new GuarantorTestBuilder().existingCustomerWithGuaranteeAmount(String.valueOf(clientID_external),
String.valueOf(externalSavigsId_1), String.valueOf(external1_guarantee)).build();
String.valueOf(externalSavigsId_1), String.valueOf(EXTERNAL1_GURANTEE)).build();
Integer externalGuarantee_1 = this.guarantorHelper.createGuarantor(loanID, guarantorJSON);
verifySavingsOnHoldBalance(externalSavigsId_1, null);
Assertions.assertNotNull(externalGuarantee_1);
LOG.info("-----------------------------------APPROVE LOAN-----------------------------------------");
loanStatusHashMap = this.loanTransactionHelper.approveLoan(LOAN_DISBURSEMENT_DATE, loanID);
loanStatusHashMap = this.loanTransactionHelper.approveLoan(loanDisbursementDate, loanID);
LoanStatusChecker.verifyLoanIsApproved(loanStatusHashMap);
LoanStatusChecker.verifyLoanIsWaitingForDisbursal(loanStatusHashMap);
self1_hold_funds += self1_guarantee;
external1_hold_funds += external1_guarantee;
self1_hold_funds += SELF1_GURANTEE;
external1_hold_funds += EXTERNAL1_GURANTEE;
verifySavingsOnHoldBalance(selfSavigsId, self1_hold_funds);
verifySavingsOnHoldBalance(externalSavigsId_1, external1_hold_funds);
LOG.info("-------------------------------DISBURSE LOAN-------------------------------------------");
loanStatusHashMap = this.loanTransactionHelper.disburseLoan(LOAN_DISBURSEMENT_DATE, loanID);
loanStatusHashMap = this.loanTransactionHelper.disburseLoan(loanDisbursementDate, loanID);
LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap);
// First repayment
ArrayList<HashMap> loanSchedule = this.loanTransactionHelper.getLoanRepaymentSchedule(this.requestSpec, this.responseSpec, loanID);
todaysDate = Calendar.getInstance();
todaysDate.add(Calendar.DAY_OF_MONTH, -14);
String LOAN_REPAYMENT_DATE = dateFormat.format(todaysDate.getTime());
final String LOAN_REPAYMENT_DATE = dateFormat.format(todaysDate.getTime());
Float totalDueForCurrentPeriod = (Float) loanSchedule.get(1).get("totalDueForPeriod");
external1_hold_funds -= Float.valueOf((float) 993.104);
this.loanTransactionHelper.makeRepayment(LOAN_REPAYMENT_DATE, totalDueForCurrentPeriod, loanID);
@@ -485,8 +488,8 @@ public class GuarantorTest {
verifySavingsOnHoldBalance(externalSavigsId_1, external1_hold_funds);
this.loanTransactionHelper.recoverFromGuarantor(loanID);
verifySavingsBalanceAndOnHoldBalance(selfSavigsId, Float.valueOf((float) 0), self1_balance - self1_hold_funds);
verifySavingsBalanceAndOnHoldBalance(externalSavigsId_1, Float.valueOf((float) 0), external1_balance - external1_hold_funds);
verifySavingsBalanceAndOnHoldBalance(selfSavigsId, Float.valueOf((float) 0), SELF1_BALANCE - self1_hold_funds);
verifySavingsBalanceAndOnHoldBalance(externalSavigsId_1, Float.valueOf((float) 0), EXTERNAL1_BALANCE - external1_hold_funds);
}
@@ -515,8 +518,8 @@ public class GuarantorTest {
DateFormat dateFormat = new SimpleDateFormat("dd MMMM yyyy", Locale.US);
Calendar todaysDate = Calendar.getInstance();
todaysDate.add(Calendar.DAY_OF_MONTH, -21);
String LOAN_DISBURSEMENT_DATE = dateFormat.format(todaysDate.getTime());
final Integer loanID = applyForLoanApplication(clientID, loanProductID, LOAN_DISBURSEMENT_DATE);
final String loanDisbursementDate = dateFormat.format(todaysDate.getTime());
final Integer loanID = applyForLoanApplication(clientID, loanProductID, loanDisbursementDate);
Assertions.assertNotNull(loanID);
HashMap loanStatusHashMap = LoanStatusChecker.getStatusOfLoan(this.requestSpec, this.responseSpec, loanID);
LoanStatusChecker.verifyLoanIsPending(loanStatusHashMap);
@@ -535,7 +538,7 @@ public class GuarantorTest {
Assertions.assertNotNull(externalGuarantee_1);
LOG.info("-----------------------------------APPROVE LOAN-----------------------------------------");
loanStatusHashMap = this.loanTransactionHelper.approveLoan(LOAN_DISBURSEMENT_DATE, loanID);
loanStatusHashMap = this.loanTransactionHelper.approveLoan(loanDisbursementDate, loanID);
LoanStatusChecker.verifyLoanIsApproved(loanStatusHashMap);
LoanStatusChecker.verifyLoanIsWaitingForDisbursal(loanStatusHashMap);
self1_hold_funds += selfguarantee;
@@ -544,14 +547,14 @@ public class GuarantorTest {
verifySavingsOnHoldBalance(externalSavigsId_1, external1_hold_funds);
LOG.info("-------------------------------DISBURSE LOAN-------------------------------------------");
loanStatusHashMap = this.loanTransactionHelper.disburseLoan(LOAN_DISBURSEMENT_DATE, loanID);
loanStatusHashMap = this.loanTransactionHelper.disburseLoan(loanDisbursementDate, loanID);
LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap);
// First repayment
ArrayList<HashMap> loanSchedule = this.loanTransactionHelper.getLoanRepaymentSchedule(this.requestSpec, this.responseSpec, loanID);
todaysDate = Calendar.getInstance();
todaysDate.add(Calendar.DAY_OF_MONTH, -14);
String LOAN_REPAYMENT_DATE = dateFormat.format(todaysDate.getTime());
final String LOAN_REPAYMENT_DATE = dateFormat.format(todaysDate.getTime());
Float totalDueForCurrentPeriod = (Float) loanSchedule.get(1).get("totalDueForPeriod");
external1_hold_funds -= Float.valueOf((float) 3227.588);
this.loanTransactionHelper.makeRepayment(LOAN_REPAYMENT_DATE, totalDueForCurrentPeriod, loanID);
@@ -577,50 +580,51 @@ public class GuarantorTest {
ClientHelper.verifyClientCreatedOnServer(this.requestSpec, this.responseSpec, clientID_external);
final Integer selfSavigsId = SavingsAccountHelper.openSavingsAccount(this.requestSpec, this.responseSpec, clientID,
String.valueOf(self1_balance));
String.valueOf(SELF1_BALANCE));
final Integer externalSavigsId_1 = SavingsAccountHelper.openSavingsAccount(this.requestSpec, this.responseSpec, clientID_external,
String.valueOf(external1_balance));
String.valueOf(EXTERNAL1_BALANCE));
final Integer loanProductID = createLoanProductWithHoldFunds("40", "20", "20");
DateFormat dateFormat = new SimpleDateFormat("dd MMMM yyyy", Locale.US);
Calendar todaysDate = Calendar.getInstance();
todaysDate.add(Calendar.DAY_OF_MONTH, -21);
String LOAN_DISBURSEMENT_DATE = dateFormat.format(todaysDate.getTime());
final Integer loanID = applyForLoanApplication(clientID, loanProductID, LOAN_DISBURSEMENT_DATE);
final String loanDisbursementDate = dateFormat.format(todaysDate.getTime());
final Integer loanID = applyForLoanApplication(clientID, loanProductID, loanDisbursementDate);
Assertions.assertNotNull(loanID);
HashMap loanStatusHashMap = LoanStatusChecker.getStatusOfLoan(this.requestSpec, this.responseSpec, loanID);
LoanStatusChecker.verifyLoanIsPending(loanStatusHashMap);
String guarantorJSON = new GuarantorTestBuilder().existingCustomerWithGuaranteeAmount(String.valueOf(clientID),
String.valueOf(selfSavigsId), String.valueOf(self1_guarantee)).build();
String guarantorJSON = new GuarantorTestBuilder()
.existingCustomerWithGuaranteeAmount(String.valueOf(clientID), String.valueOf(selfSavigsId), String.valueOf(SELF1_GURANTEE))
.build();
Integer selfGuarantee = this.guarantorHelper.createGuarantor(loanID, guarantorJSON);
verifySavingsOnHoldBalance(selfSavigsId, null);
Assertions.assertNotNull(selfGuarantee);
guarantorJSON = new GuarantorTestBuilder().existingCustomerWithGuaranteeAmount(String.valueOf(clientID_external),
String.valueOf(externalSavigsId_1), String.valueOf(external1_guarantee)).build();
String.valueOf(externalSavigsId_1), String.valueOf(EXTERNAL1_GURANTEE)).build();
Integer externalGuarantee_1 = this.guarantorHelper.createGuarantor(loanID, guarantorJSON);
Assertions.assertNotNull(externalGuarantee_1);
verifySavingsOnHoldBalance(externalSavigsId_1, null);
LOG.info("-----------------------------------APPROVE LOAN-----------------------------------------");
loanStatusHashMap = this.loanTransactionHelper.approveLoan(LOAN_DISBURSEMENT_DATE, loanID);
loanStatusHashMap = this.loanTransactionHelper.approveLoan(loanDisbursementDate, loanID);
LoanStatusChecker.verifyLoanIsApproved(loanStatusHashMap);
LoanStatusChecker.verifyLoanIsWaitingForDisbursal(loanStatusHashMap);
self1_hold_funds += self1_guarantee;
external1_hold_funds += external1_guarantee;
self1_hold_funds += SELF1_GURANTEE;
external1_hold_funds += EXTERNAL1_GURANTEE;
verifySavingsOnHoldBalance(selfSavigsId, self1_hold_funds);
verifySavingsOnHoldBalance(externalSavigsId_1, external1_hold_funds);
LOG.info("-------------------------------DISBURSE LOAN-------------------------------------------");
loanStatusHashMap = this.loanTransactionHelper.disburseLoan(LOAN_DISBURSEMENT_DATE, loanID);
loanStatusHashMap = this.loanTransactionHelper.disburseLoan(loanDisbursementDate, loanID);
LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap);
// First repayment
ArrayList<HashMap> loanSchedule = this.loanTransactionHelper.getLoanRepaymentSchedule(this.requestSpec, this.responseSpec, loanID);
todaysDate = Calendar.getInstance();
todaysDate.add(Calendar.DAY_OF_MONTH, -14);
String LOAN_REPAYMENT_DATE = dateFormat.format(todaysDate.getTime());
final String LOAN_REPAYMENT_DATE = dateFormat.format(todaysDate.getTime());
Float totalDueForCurrentPeriod = (Float) loanSchedule.get(1).get("totalDueForPeriod");
external1_hold_funds -= Float.valueOf((float) 993.104);
this.loanTransactionHelper.makeRepayment(LOAN_REPAYMENT_DATE, totalDueForCurrentPeriod, loanID);
@@ -628,10 +632,10 @@ public class GuarantorTest {
verifySavingsOnHoldBalance(externalSavigsId_1, external1_hold_funds);
todaysDate = Calendar.getInstance();
String LOAN_WRITEOFF_DATE = dateFormat.format(todaysDate.getTime());
final String LOAN_WRITEOFF_DATE = dateFormat.format(todaysDate.getTime());
this.loanTransactionHelper.writeOffLoan(LOAN_WRITEOFF_DATE, loanID);
verifySavingsBalanceAndOnHoldBalance(selfSavigsId, Float.valueOf((float) 0), self1_balance);
verifySavingsBalanceAndOnHoldBalance(externalSavigsId_1, Float.valueOf((float) 0), external1_balance);
verifySavingsBalanceAndOnHoldBalance(selfSavigsId, Float.valueOf((float) 0), SELF1_BALANCE);
verifySavingsBalanceAndOnHoldBalance(externalSavigsId_1, Float.valueOf((float) 0), EXTERNAL1_BALANCE);
}
@@ -18,9 +18,13 @@
*/
package org.apache.fineract.integrationtests.useradministration.users;
import io.restassured.path.json.JsonPath;
import io.restassured.specification.RequestSpecification;
import io.restassured.specification.ResponseSpecification;
import java.util.HashMap;
import java.util.List;
import org.apache.fineract.integrationtests.common.Utils;
import org.junit.jupiter.api.Assertions;
public class UserHelper {
@@ -44,6 +48,20 @@ public class UserHelper {
getTestCreateUserAsJSONForSelfService(roleId, staffId, clientId), attribute);
}
public static Integer getUserId(final RequestSpecification requestSpec, final ResponseSpecification responseSpec, String userName) {
String json = Utils.performServerGet(requestSpec, responseSpec, CREATE_USER_URL, null);
Assertions.assertNotNull(json);
List<HashMap<String, Object>> userList = JsonPath.from(json).getList("$");
for (HashMap<String, Object> user : userList) {
if (user.get("username").equals(userName)) {
return (Integer) user.get("id");
}
}
return null;
}
public static String getTestCreateUserAsJSON(int roleId, int staffId) {
return "{ \"username\": \"" + Utils.randomNameGenerator("User_Name_", 3)
+ "\", \"firstname\": \"Test\", \"lastname\": \"User\", \"email\": \"whatever@mifos.org\","
@@ -27,7 +27,7 @@ import org.apache.fineract.integrationtests.common.Utils;
@SuppressWarnings("rawtypes")
public class VariableIntallmentsTransactionHelper {
private final String URL = "https://localhost:8443/fineract-provider/api/v1/loans/";
private static final String URL = "https://localhost:8443/fineract-provider/api/v1/loans/";
private final RequestSpecification requestSpec;
private final ResponseSpecification responseSpec;
@@ -29,16 +29,13 @@ import org.springframework.context.annotation.Import;
import org.springframework.context.annotation.ImportResource;
/**
* Fineract main() application which launches Fineract in an embedded Tomcat
* HTTP (using Spring Boot).
* Fineract main() application which launches Fineract in an embedded Tomcat HTTP (using Spring Boot).
*
* The DataSource used is a to a "normal" external database (not use MariaDB4j).
* This DataSource can be configured with parameters, see
* {@link DataSourceProperties}.
* The DataSource used is a to a "normal" external database (not use MariaDB4j). This DataSource can be configured with
* parameters, see {@link DataSourceProperties}.
*
* You can easily launch this via Debug as Java Application in your IDE -
* without needing command line Gradle stuff, no need to build and deploy a WAR,
* remote attachment etc.
* You can easily launch this via Debug as Java Application in your IDE - without needing command line Gradle stuff, no
* need to build and deploy a WAR, remote attachment etc.
*
* It's the old/classic Mifos (non-X) Workspace 2.0 reborn for Fineract! ;-)
*
@@ -18,15 +18,12 @@
*/
package org.apache.fineract.accounting.accrual.api;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import io.swagger.annotations.ApiResponse;
import io.swagger.annotations.ApiResponses;
import io.swagger.annotations.SwaggerDefinition;
import io.swagger.annotations.Tag;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import io.swagger.v3.oas.annotations.tags.Tag;
import javax.ws.rs.Consumes;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
@@ -44,9 +41,7 @@ import org.springframework.stereotype.Component;
@Path("/runaccruals")
@Component
@Scope("singleton")
@Api(tags = { "Periodic Accrual Accounting" })
@SwaggerDefinition(tags = {
@Tag(name = "Periodic Accrual Accounting", description = "Periodic Accrual is to accrue the loan income till the specific date or till batch job scheduled time.\n") })
@Tag(name = "Periodic Accrual Accounting", description = "Periodic Accrual is to accrue the loan income till the specific date or till batch job scheduled time.\n")
public class AccrualAccountingApiResource {
private final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService;
@@ -63,13 +58,11 @@ public class AccrualAccountingApiResource {
@POST
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
@ApiOperation(value = "Executes Periodic Accrual Accounting", httpMethod = "POST", notes = "Mandatory Fields\n" + "\n" + "tillDate\n")
@ApiImplicitParams({
@ApiImplicitParam(paramType = "body", required = true, type = "body", dataTypeClass = AccrualAccountingApiResourceSwagger.PostRunaccrualsRequest.class, value = "Request Body\n"
+ "\n" + "Field Descriptions: \n" + "tillDate: \n"
+ "which specifies periodic accruals should happen till the given Date") })
@ApiResponses({ @ApiResponse(code = 200, message = "OK") })
public String executePeriodicAccrualAccounting(@ApiParam(hidden = true) final String jsonRequestBody) {
@Operation(summary = "Executes Periodic Accrual Accounting", method = "POST", description = "Mandatory Fields\n" + "\n" + "tillDate\n")
@Parameter(required = true, schema = @Schema(implementation = AccrualAccountingApiResourceSwagger.PostRunaccrualsRequest.class, description = "Request Body\n"
+ "\n" + "Field Descriptions: \n" + "tillDate: \n" + "which specifies periodic accruals should happen till the given Date"))
@ApiResponses({ @ApiResponse(responseCode = "200", description = "OK") })
public String executePeriodicAccrualAccounting(@Parameter(hidden = true) final String jsonRequestBody) {
final CommandWrapper commandRequest = new CommandWrapperBuilder().excuteAccrualAccounting().withJson(jsonRequestBody).build();
@@ -18,8 +18,7 @@
*/
package org.apache.fineract.accounting.accrual.api;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import io.swagger.v3.oas.annotations.media.Schema;
/**
* Created by sanyam on 24/7/17.
@@ -30,18 +29,18 @@ final class AccrualAccountingApiResourceSwagger {
// don't allow to instantiate; use only for live API documentation
}
@ApiModel(value = "runaccrualsRequest")
@Schema(description = "runaccrualsRequest")
public static final class PostRunaccrualsRequest {
private PostRunaccrualsRequest() {
// don't allow to instantiate; use only for live API documentation
}
@ApiModelProperty(example = "en")
@Schema(example = "en")
public String locale;
@ApiModelProperty(example = "dd MMMM yyyy")
@Schema(example = "dd MMMM yyyy")
public String dateFormat;
@ApiModelProperty(example = "04 June 2014", notes = "which specifies periodic accruals should happen till the given Date", required = true)
@Schema(example = "04 June 2014", description = "which specifies periodic accruals should happen till the given Date", required = true)
public String tillDate;
}
@@ -45,8 +45,7 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
/**
* Implementation of {@link FromApiJsonDeserializer} for
* {@link GuarantorCommand}'s.
* Implementation of {@link FromApiJsonDeserializer} for {@link GuarantorCommand}'s.
*/
@Component
public final class AccrualAccountingDataValidator {
@@ -61,7 +61,7 @@ public class AccrualAccountingWritePlatformServiceImpl implements AccrualAccount
.resource(PERIODIC_ACCRUAL_ACCOUNTING_RESOURCE_NAME);
baseDataValidator.reset().failWithCodeNoParameterAddedToErrorCode(PERIODIC_ACCRUAL_ACCOUNTING_EXECUTION_ERROR_CODE,
e.getMessage());
throw new PlatformApiDataValidationException(dataValidationErrors);
throw new PlatformApiDataValidationException(dataValidationErrors, e);
}
return CommandProcessingResult.empty();
}
@@ -18,15 +18,15 @@
*/
package org.apache.fineract.accounting.closure.api;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import io.swagger.annotations.ApiResponse;
import io.swagger.annotations.ApiResponses;
import io.swagger.annotations.SwaggerDefinition;
import io.swagger.annotations.Tag;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.ArraySchema;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.parameters.RequestBody;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import io.swagger.v3.oas.annotations.tags.Tag;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
@@ -61,12 +61,11 @@ import org.springframework.stereotype.Component;
@Path("/glclosures")
@Component
@Scope("singleton")
@Api(tags = { "Accounting Closure" })
@SwaggerDefinition(tags = {
@Tag(name = "Accounting Closure", description = "An accounting closure indicates that no more journal entries may be logged (or reversed) in the system, either manually or via the portfolio with an entry date prior to the defined closure date\n"
+ "\n" + "Field Descriptions\n" + "closingDate\n" + "The date for which the accounting closure is defined\n" + "officeId\n"
+ "The identifer of the branch for which accounting has been closed\n" + "comments\n"
+ "Description associated with an Accounting closure") })
@Tag(name = "Accounting Closure", description = "An accounting closure indicates that no more journal entries may be logged (or reversed) in the system, either manually or via the portfolio with an entry date prior to the defined closure date\n"
+ "\n" + "Field Descriptions\n" + "closingDate\n" + "The date for which the accounting closure is defined\n" + "officeId\n"
+ "The identifer of the branch for which accounting has been closed\n" + "comments\n"
+ "Description associated with an Accounting closure")
public class GLClosuresApiResource {
private static final Set<String> RESPONSE_DATA_PARAMETERS = new HashSet<>(
@@ -98,11 +97,11 @@ public class GLClosuresApiResource {
@GET
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
@ApiOperation(value = "List Accounting closures", notes = "Example Requests:\n" + "\n" + "glclosures")
@Operation(summary = "List Accounting closures", description = "Example Requests:\n" + "\n" + "glclosures")
@ApiResponses({
@ApiResponse(code = 200, response = GLClosuresApiResourceSwagger.GetGlClosureResponse.class, message = "", responseContainer = "list") })
@ApiResponse(responseCode = "200", content = @Content(array = @ArraySchema(schema = @Schema(implementation = GLClosuresApiResourceSwagger.GetGlClosureResponse.class, description = "")))) })
public String retrieveAllClosures(@Context final UriInfo uriInfo,
@QueryParam("officeId") @ApiParam(value = "officeId") final Long officeId) {
@QueryParam("officeId") @Parameter(name = "officeId") final Long officeId) {
this.context.authenticatedUser().validateHasReadPermission(this.resourceNameForPermission);
final List<GLClosureData> glClosureDatas = this.glClosureReadPlatformService.retrieveAllGLClosures(officeId);
@@ -115,10 +114,11 @@ public class GLClosuresApiResource {
@Path("{glClosureId}")
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
@ApiOperation(value = "Retrieve an Accounting Closure", notes = "Example Requests:\n" + "\n" + "glclosures/1\n" + "\n" + "\n"
@Operation(summary = "Retrieve an Accounting Closure", description = "Example Requests:\n" + "\n" + "glclosures/1\n" + "\n" + "\n"
+ "/glclosures/1?fields=officeName,closingDate")
@ApiResponses({ @ApiResponse(code = 200, message = "", response = GLClosuresApiResourceSwagger.GetGlClosureResponse.class) })
public String retreiveClosure(@PathParam("glClosureId") @ApiParam(value = "glClosureId") final Long glClosureId,
@ApiResponses({
@ApiResponse(responseCode = "200", description = "", content = @Content(schema = @Schema(implementation = GLClosuresApiResourceSwagger.GetGlClosureResponse.class))) })
public String retreiveClosure(@PathParam("glClosureId") @Parameter(description = "glClosureId") final Long glClosureId,
@Context final UriInfo uriInfo) {
this.context.authenticatedUser().validateHasReadPermission(this.resourceNameForPermission);
@@ -137,11 +137,11 @@ public class GLClosuresApiResource {
@POST
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
@ApiOperation(value = "Create an Accounting Closure", notes = "Mandatory Fields\n" + "officeId,closingDate")
@ApiImplicitParams({
@ApiImplicitParam(paramType = "body", required = true, type = "body", dataTypeClass = GLClosuresApiResourceSwagger.PostGlClosuresRequest.class, value = "Request Body") })
@ApiResponses({ @ApiResponse(code = 200, message = "", response = GLClosuresApiResourceSwagger.PostGlClosuresResponse.class) })
public String createGLClosure(@ApiParam(hidden = true) final String jsonRequestBody) {
@Operation(summary = "Create an Accounting Closure", description = "Mandatory Fields\n" + "officeId,closingDate")
@RequestBody(required = true, content = @Content(schema = @Schema(implementation = GLClosuresApiResourceSwagger.PostGlClosuresRequest.class, description = "Request Body")))
@ApiResponses({
@ApiResponse(responseCode = "200", description = "", content = @Content(schema = @Schema(implementation = GLClosuresApiResourceSwagger.PostGlClosuresResponse.class))) })
public String createGLClosure(@Parameter(hidden = true) final String jsonRequestBody) {
final CommandWrapper commandRequest = new CommandWrapperBuilder().createGLClosure().withJson(jsonRequestBody).build();
@@ -154,12 +154,12 @@ public class GLClosuresApiResource {
@Path("{glClosureId}")
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
@ApiOperation(value = "Update an Accounting closure", notes = "Once an accounting closure is created, only the comments associated with it may be edited")
@ApiImplicitParams({
@ApiImplicitParam(paramType = "body", value = "Request body", dataType = "body", dataTypeClass = GLClosuresApiResourceSwagger.PutGlClosuresRequest.class, required = true) })
@ApiResponses({ @ApiResponse(code = 200, message = "", response = GLClosuresApiResourceSwagger.PutGlClosuresResponse.class) })
public String updateGLClosure(@PathParam("glClosureId") @ApiParam(value = "glClosureId") final Long glClosureId,
@ApiParam(hidden = true) final String jsonRequestBody) {
@Operation(summary = "Update an Accounting closure", description = "Once an accounting closure is created, only the comments associated with it may be edited")
@RequestBody(content = @Content(schema = @Schema(implementation = GLClosuresApiResourceSwagger.PutGlClosuresRequest.class, required = true)))
@ApiResponses({
@ApiResponse(responseCode = "200", description = "", content = @Content(schema = @Schema(implementation = GLClosuresApiResourceSwagger.PutGlClosuresResponse.class))) })
public String updateGLClosure(@PathParam("glClosureId") @Parameter(description = "glClosureId") final Long glClosureId,
@Parameter(hidden = true) final String jsonRequestBody) {
final CommandWrapper commandRequest = new CommandWrapperBuilder().updateGLClosure(glClosureId).withJson(jsonRequestBody).build();
final CommandProcessingResult result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
@@ -171,9 +171,10 @@ public class GLClosuresApiResource {
@Path("{glClosureId}")
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
@ApiOperation(value = "Delete an accounting closure", notes = "Note: Only the latest accounting closure associated with a branch may be deleted.")
@ApiResponses({ @ApiResponse(code = 200, message = "", response = GLClosuresApiResourceSwagger.DeleteGlClosuresResponse.class) })
public String deleteGLClosure(@PathParam("glClosureId") @ApiParam(value = "glclosureId") final Long glClosureId) {
@Operation(summary = "Delete an accounting closure", description = "Note: Only the latest accounting closure associated with a branch may be deleted.")
@ApiResponses({
@ApiResponse(responseCode = "200", description = "", content = @Content(schema = @Schema(implementation = GLClosuresApiResourceSwagger.DeleteGlClosuresResponse.class))) })
public String deleteGLClosure(@PathParam("glClosureId") @Parameter(description = "glclosureId") final Long glClosureId) {
final CommandWrapper commandRequest = new CommandWrapperBuilder().deleteGLClosure(glClosureId).build();
@@ -18,8 +18,7 @@
*/
package org.apache.fineract.accounting.closure.api;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import io.swagger.v3.oas.annotations.media.Schema;
import org.joda.time.LocalDate;
final class GLClosuresApiResourceSwagger {
@@ -29,113 +28,112 @@ final class GLClosuresApiResourceSwagger {
}
/**
* TODO: describe where this belongs: {@link GLClosuresApiResource }
* {@Link GLClosuresApiResource}
* TODO: describe where this belongs: {@link GLClosuresApiResource } {@link GLClosuresApiResource}
*/
// Check !!
@ApiModel(value = "GetGLClosureResponse")
@Schema(description = "GetGLClosureResponse")
public static final class GetGlClosureResponse {
private GetGlClosureResponse() {
// dont allow to initiatiate
}
@ApiModelProperty(example = "7")
@Schema(example = "7")
public Long id;
@ApiModelProperty(example = "1")
@Schema(example = "1")
public Long officeId;
@ApiModelProperty(example = "Head Office")
@Schema(example = "Head Office")
public String officeName;
@ApiModelProperty(example = "2013,1,2")
@Schema(example = "2013,1,2")
public LocalDate closingDate;
@ApiModelProperty(example = "false")
@Schema(example = "false")
public boolean deleted;
@ApiModelProperty(example = "2013,1,3")
@Schema(example = "2013,1,3")
public LocalDate createdDate;
@ApiModelProperty(example = "2013,1,3")
@Schema(example = "2013,1,3")
public LocalDate lastUpdatedDate;
@ApiModelProperty(example = "1")
@Schema(example = "1")
public Long createdByUserId;
@ApiModelProperty(example = "mifos")
@Schema(example = "mifos")
public String createdByUsername;
@ApiModelProperty(example = "1")
@Schema(example = "1")
public Long lastUpdatedByUserId;
@ApiModelProperty(example = "mifos")
@Schema(example = "mifos")
public String lastUpdatedByUsername;
@ApiModelProperty(example = "closed")
@Schema(example = "closed")
public String comments;
}
@ApiModel(value = "PostGLCLosuresRequest")
@Schema(description = "PostGLCLosuresRequest")
public static final class PostGlClosuresRequest {
private PostGlClosuresRequest() {
// don't allow to instantiate; use only for live API documentation
}
@ApiModelProperty(example = "1")
@Schema(example = "1")
public Long officeId;
@ApiModelProperty(example = "06 December 2012")
@Schema(example = "06 December 2012")
public LocalDate closingDate;
@ApiModelProperty(example = "The accountants are heading for a carribean vacation")
@Schema(example = "The accountants are heading for a carribean vacation")
public String comments;
@ApiModelProperty(example = "en")
@Schema(example = "en")
public String locale;
@ApiModelProperty(example = "dd MMMM yyyy")
@Schema(example = "dd MMMM yyyy")
public String dateFormat;
}
@ApiModel(value = "PostGlClosuresResponse")
@Schema(description = "PostGlClosuresResponse")
public static final class PostGlClosuresResponse {
private PostGlClosuresResponse() {
// don't allow to instantiate; use only for live API documentation
}
@ApiModelProperty(example = "1")
@Schema(example = "1")
public Long officeId;
@ApiModelProperty(example = "9")
@Schema(example = "9")
public Long resourceId;
}
@ApiModel(value = "PutGlClosuresRequest")
@Schema(description = "PutGlClosuresRequest")
public static final class PutGlClosuresRequest {
private PutGlClosuresRequest() {
// don't allow to instantiate; use only for live API documentation
}
@ApiModelProperty(example = "All transactions verified by Johnny Cash")
@Schema(example = "All transactions verified by Johnny Cash")
public String comments;
}
@ApiModel(value = "PutGlClosuresResponse")
@Schema(description = "PutGlClosuresResponse")
public static final class PutGlClosuresResponse {
private PutGlClosuresResponse() {
// don't allow to instantiate; use only for live API documentation
}
@ApiModelProperty(example = "1")
@Schema(example = "1")
public Long officeId;
@ApiModelProperty(example = "9")
@Schema(example = "9")
public Long resourceId;
@ApiModelProperty(example = "All transactions verified by Johnny Cash")
@Schema(example = "All transactions verified by Johnny Cash")
public String comments;
}
@ApiModel(value = "DeleteGlClosuresResponse")
@Schema(description = "DeleteGlClosuresResponse")
public static final class DeleteGlClosuresResponse {
private DeleteGlClosuresResponse() {
}
@ApiModelProperty(example = "1")
@Schema(example = "1")
public Long officeId;
@ApiModelProperty(example = "9")
@Schema(example = "9")
public Long resourceId;
}
}
@@ -26,8 +26,7 @@ import org.joda.time.LocalDate;
/**
* Immutable object representing a General Ledger Account
*
* Note: no getter/setters required as google-gson will produce json from fields
* of object.
* Note: no getter/setters required as google-gson will produce json from fields of object.
*/
public class GLClosureData {
@@ -22,8 +22,7 @@ import org.apache.fineract.infrastructure.core.exception.AbstractPlatformDomainR
import org.joda.time.LocalDate;
/**
* A {@link RuntimeException} thrown when a GL Closure for a given date and
* Office combination is already present
* A {@link RuntimeException} thrown when a GL Closure for a given date and Office combination is already present
*/
public class GLClosureDuplicateException extends AbstractPlatformDomainRuleException {
@@ -19,14 +19,18 @@
package org.apache.fineract.accounting.closure.exception;
import org.apache.fineract.infrastructure.core.exception.AbstractPlatformResourceNotFoundException;
import org.springframework.dao.EmptyResultDataAccessException;
/**
* A {@link RuntimeException} thrown when GL account closure resources are not
* found.
* A {@link RuntimeException} thrown when GL account closure resources are not found.
*/
public class GLClosureNotFoundException extends AbstractPlatformResourceNotFoundException {
public GLClosureNotFoundException(final Long id) {
super("error.msg.glclosure.id.invalid", "Accounting Closure with identifier " + id + " does not exist", id);
}
public GLClosureNotFoundException(final Long id, EmptyResultDataAccessException e) {
super("error.msg.glclosure.id.invalid", "Accounting Closure with identifier " + id + " does not exist", id, e);
}
}
@@ -36,8 +36,7 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
/**
* Implementation of {@link FromApiJsonDeserializer} for
* {@link GuarantorCommand}'s.
* Implementation of {@link FromApiJsonDeserializer} for {@link GuarantorCommand}'s.
*/
@Component
public final class GLClosureCommandFromApiJsonDeserializer extends AbstractFromApiJsonDeserializer<GLClosureCommand> {
@@ -106,7 +106,7 @@ public class GLClosureReadPlatformServiceImpl implements GLClosureReadPlatformSe
return glAccountData;
} catch (final EmptyResultDataAccessException e) {
throw new GLClosureNotFoundException(glClosureId);
throw new GLClosureNotFoundException(glClosureId, e);
}
}
@@ -41,6 +41,8 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.dao.NonTransientDataAccessException;
import org.springframework.orm.jpa.JpaSystemException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@@ -91,8 +93,9 @@ public class GLClosureWritePlatformServiceJpaRepositoryImpl implements GLClosure
return new CommandProcessingResultBuilder().withCommandId(command.commandId()).withOfficeId(officeId)
.withEntityId(glClosure.getId()).build();
} catch (final DataIntegrityViolationException dve) {
handleGLClosureIntegrityIssues(command, dve);
} catch (final JpaSystemException | DataIntegrityViolationException dve) {
final Throwable throwable = dve.getMostSpecificCause();
handleGLClosureIntegrityIssues(command, throwable, dve);
return CommandProcessingResult.empty();
}
}
@@ -124,8 +127,7 @@ public class GLClosureWritePlatformServiceJpaRepositoryImpl implements GLClosure
.orElseThrow(() -> new GLClosureNotFoundException(glClosureId));
/**
* check if any closures are present for this branch at a later date
* than this closure date
* check if any closures are present for this branch at a later date than this closure date
**/
final Date closureDate = glClosure.getClosingDate();
final GLClosure latestGLClosure = this.glClosureRepository.getLatestGLClosureByBranch(glClosure.getOffice().getId());
@@ -142,9 +144,9 @@ public class GLClosureWritePlatformServiceJpaRepositoryImpl implements GLClosure
/**
* @param command
* @param dve
* @param dve
*/
private void handleGLClosureIntegrityIssues(final JsonCommand command, final DataIntegrityViolationException dve) {
final Throwable realCause = dve.getMostSpecificCause();
private void handleGLClosureIntegrityIssues(final JsonCommand command, final Throwable realCause, NonTransientDataAccessException dve) {
if (realCause.getMessage().contains("office_id_closing_date")) {
throw new GLClosureDuplicateException(command.longValueOfParameterNamed(GLClosureJsonInputParams.OFFICE_ID.getValue()),
new LocalDate(command.dateValueOfParameterNamed(GLClosureJsonInputParams.CLOSING_DATE.getValue())));
@@ -102,8 +102,7 @@ public class AccountingConstants {
}
/***
* Enum of all accounting related input parameter names used while
* creating/updating a loan product
* Enum of all accounting related input parameter names used while creating/updating a loan product
***/
public static enum LoanProductAccountingParams {
@@ -201,8 +200,7 @@ public class AccountingConstants {
}
/***
* Enum of all accounting related input parameter names used while
* creating/updating a savings product
* Enum of all accounting related input parameter names used while creating/updating a savings product
***/
public static enum SavingProductAccountingParams {
@@ -374,8 +372,7 @@ public class AccountingConstants {
}
/***
* Enum of all accounting related input parameter names used while
* creating/updating a savings product
* Enum of all accounting related input parameter names used while creating/updating a savings product
***/
public static enum SharesProductAccountingParams {
@@ -18,15 +18,15 @@
*/
package org.apache.fineract.accounting.financialactivityaccount.api;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import io.swagger.annotations.ApiResponse;
import io.swagger.annotations.ApiResponses;
import io.swagger.annotations.SwaggerDefinition;
import io.swagger.annotations.Tag;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.ArraySchema;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.parameters.RequestBody;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import io.swagger.v3.oas.annotations.tags.Tag;
import java.util.List;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
@@ -56,11 +56,9 @@ import org.springframework.stereotype.Component;
@Path("/financialactivityaccounts")
@Component
@Scope("singleton")
@Api(tags = { "Mapping Financial Activities to Accounts" })
@SwaggerDefinition(tags = {
@Tag(name = "Mapping Financial Activities to Accounts", description = "Organization Level Financial Activities like Asset and Liability Transfer can be mapped to GL Account. Integrated accounting takes these accounts into consideration when an Account transfer is made between a savings to loan/savings account and vice-versa\n"
+ "\n" + "Field Descriptions\n" + "financialActivityId\n" + "The identifier of the Financial Activity\n" + "glAccountId\n"
+ "The identifier of a GL Account ( Ledger Account) which shall be used as the default account for the selected Financial Activity") })
@Tag(name = "Mapping Financial Activities to Accounts", description = "Organization Level Financial Activities like Asset and Liability Transfer can be mapped to GL Account. Integrated accounting takes these accounts into consideration when an Account transfer is made between a savings to loan/savings account and vice-versa\n"
+ "\n" + "Field Descriptions\n" + "financialActivityId\n" + "The identifier of the Financial Activity\n" + "glAccountId\n"
+ "The identifier of a GL Account ( Ledger Account) which shall be used as the default account for the selected Financial Activity")
public class FinancialActivityAccountsApiResource {
private final FinancialActivityAccountReadPlatformService financialActivityAccountReadPlatformService;
@@ -101,10 +99,10 @@ public class FinancialActivityAccountsApiResource {
@GET
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
@ApiOperation(value = "List Financial Activities to Accounts Mappings", notes = "Example Requests:\n" + "\n"
@Operation(summary = "List Financial Activities to Accounts Mappings", description = "Example Requests:\n" + "\n"
+ "financialactivityaccounts")
@ApiResponses({
@ApiResponse(code = 200, message = "", response = FinancialActivityAccountsApiResourceSwagger.GetFinancialActivityAccountsResponse.class, responseContainer = "list") })
@ApiResponse(responseCode = "200", description = "", content = @Content(array = @ArraySchema(schema = @Schema(implementation = FinancialActivityAccountsApiResourceSwagger.GetFinancialActivityAccountsResponse.class)))) })
public String retrieveAll(@Context final UriInfo uriInfo) {
this.context.authenticatedUser().validateHasReadPermission(FinancialActivityAccountsConstants.resourceNameForPermission);
@@ -119,11 +117,12 @@ public class FinancialActivityAccountsApiResource {
@Path("{mappingId}")
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
@ApiOperation(value = "Retrieve a Financial Activity to Account Mapping\n", notes = "Example Requests:\n" + "\n"
@Operation(summary = "Retrieve a Financial Activity to Account Mapping\n", description = "Example Requests:\n" + "\n"
+ "financialactivityaccounts/1")
@ApiResponses({
@ApiResponse(code = 200, message = "", response = FinancialActivityAccountsApiResourceSwagger.GetFinancialActivityAccountsResponse.class) })
public String retreive(@PathParam("mappingId") @ApiParam(value = "mappingId") final Long mappingId, @Context final UriInfo uriInfo) {
@ApiResponse(responseCode = "200", description = "", content = @Content(schema = @Schema(implementation = FinancialActivityAccountsApiResourceSwagger.GetFinancialActivityAccountsResponse.class))) })
public String retreive(@PathParam("mappingId") @Parameter(description = "mappingId") final Long mappingId,
@Context final UriInfo uriInfo) {
this.context.authenticatedUser().validateHasReadPermission(FinancialActivityAccountsConstants.resourceNameForPermission);
@@ -141,13 +140,12 @@ public class FinancialActivityAccountsApiResource {
@POST
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
@ApiOperation(value = "Create a new Financial Activity to Accounts Mapping", notes = "Mandatory Fields\n"
@Operation(summary = "Create a new Financial Activity to Accounts Mapping", description = "Mandatory Fields\n"
+ "financialActivityId, glAccountId")
@ApiImplicitParams({
@ApiImplicitParam(value = "Request body", paramType = "body", dataType = "body", dataTypeClass = FinancialActivityAccountsApiResourceSwagger.PostFinancialActivityAccountsRequest.class) })
@RequestBody(content = @Content(schema = @Schema(implementation = FinancialActivityAccountsApiResourceSwagger.PostFinancialActivityAccountsRequest.class)))
@ApiResponses({
@ApiResponse(code = 200, message = "", response = FinancialActivityAccountsApiResourceSwagger.PostFinancialActivityAccountsResponse.class) })
public String createGLAccount(@ApiParam(hidden = true) final String jsonRequestBody) {
@ApiResponse(responseCode = "200", description = "", content = @Content(schema = @Schema(implementation = FinancialActivityAccountsApiResourceSwagger.PostFinancialActivityAccountsResponse.class))) })
public String createGLAccount(@Parameter(hidden = true) final String jsonRequestBody) {
final CommandWrapper commandRequest = new CommandWrapperBuilder().createOfficeToGLAccountMapping().withJson(jsonRequestBody)
.build();
@@ -161,13 +159,12 @@ public class FinancialActivityAccountsApiResource {
@Path("{mappingId}")
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
@ApiOperation(value = "Update a Financial Activity to Account Mapping", notes = "the API updates the Ledger account linked to a Financial Activity \n")
@ApiImplicitParams({
@ApiImplicitParam(value = "Request body", dataType = "body", paramType = "body", dataTypeClass = FinancialActivityAccountsApiResourceSwagger.PostFinancialActivityAccountsRequest.class) })
@Operation(summary = "Update a Financial Activity to Account Mapping", description = "the API updates the Ledger account linked to a Financial Activity \n")
@RequestBody(content = @Content(schema = @Schema(implementation = FinancialActivityAccountsApiResourceSwagger.PostFinancialActivityAccountsRequest.class)))
@ApiResponses({
@ApiResponse(code = 200, message = "", response = FinancialActivityAccountsApiResourceSwagger.PutFinancialActivityAccountsResponse.class) })
public String updateGLAccount(@PathParam("mappingId") @ApiParam(value = "mappingId") final Long mappingId,
@ApiParam(hidden = true) final String jsonRequestBody) {
@ApiResponse(responseCode = "200", description = "", content = @Content(schema = @Schema(implementation = FinancialActivityAccountsApiResourceSwagger.PutFinancialActivityAccountsResponse.class))) })
public String updateGLAccount(@PathParam("mappingId") @Parameter(description = "mappingId") final Long mappingId,
@Parameter(hidden = true) final String jsonRequestBody) {
final CommandWrapper commandRequest = new CommandWrapperBuilder().updateOfficeToGLAccountMapping(mappingId)
.withJson(jsonRequestBody).build();
@@ -181,10 +178,10 @@ public class FinancialActivityAccountsApiResource {
@Path("{mappingId}")
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
@ApiOperation(value = "Delete a Financial Activity to Account Mapping")
@Operation(summary = "Delete a Financial Activity to Account Mapping")
@ApiResponses({
@ApiResponse(code = 200, message = "OK", response = FinancialActivityAccountsApiResourceSwagger.DeleteFinancialActivityAccountsResponse.class) })
public String deleteGLAccount(@PathParam("mappingId") @ApiParam(value = "mappingId") final Long mappingId) {
@ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = FinancialActivityAccountsApiResourceSwagger.DeleteFinancialActivityAccountsResponse.class))) })
public String deleteGLAccount(@PathParam("mappingId") @Parameter(description = "mappingId") final Long mappingId) {
final CommandWrapper commandRequest = new CommandWrapperBuilder().deleteOfficeToGLAccountMapping(mappingId).build();
@@ -18,8 +18,7 @@
*/
package org.apache.fineract.accounting.financialactivityaccount.api;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import io.swagger.v3.oas.annotations.media.Schema;
import org.apache.fineract.accounting.financialactivityaccount.data.FinancialActivityData;
import org.apache.fineract.accounting.glaccount.data.GLAccountData;
@@ -30,58 +29,58 @@ final class FinancialActivityAccountsApiResourceSwagger {
private FinancialActivityAccountsApiResourceSwagger() {}
@ApiModel(value = "GetFinancialActivityAccountsResponse")
@Schema(description = "GetFinancialActivityAccountsResponse")
public static final class GetFinancialActivityAccountsResponse {
private GetFinancialActivityAccountsResponse() {
}
@ApiModelProperty(example = "1")
@Schema(example = "1")
public Long id;
public FinancialActivityData financialActivityData;
public GLAccountData glAccountData;
}
@ApiModel(value = "PostFinancialActivityAccountsRequest")
@Schema(description = "PostFinancialActivityAccountsRequest")
public static final class PostFinancialActivityAccountsRequest {
private PostFinancialActivityAccountsRequest() {
}
@ApiModelProperty(example = "200")
@Schema(example = "200")
public Long financialActivityId;
@ApiModelProperty(example = "2")
@Schema(example = "2")
public Long glAccountId;
}
@ApiModel(value = "PostFinancialActivityAccountsResponse")
@Schema(description = "PostFinancialActivityAccountsResponse")
public static final class PostFinancialActivityAccountsResponse {
private PostFinancialActivityAccountsResponse() {
}
@ApiModelProperty(example = "1")
@Schema(example = "1")
public Long resourceId;
}
@ApiModel(value = "PutFinancialActivityAccountsRequest")
@Schema(description = "PutFinancialActivityAccountsRequest")
public static final class PutFinancialActivityAccountsRequest {
private PutFinancialActivityAccountsRequest() {
}
@ApiModelProperty(example = "200")
@Schema(example = "200")
public Long financialActivityId;
@ApiModelProperty(example = "3")
@Schema(example = "3")
public Long glAccountId;
}
@ApiModel(value = "PutFinancialActivityAccountsResponse")
@Schema(description = "PutFinancialActivityAccountsResponse")
public static final class PutFinancialActivityAccountsResponse {
private PutFinancialActivityAccountsResponse() {
@@ -92,23 +91,23 @@ final class FinancialActivityAccountsApiResourceSwagger {
private PutFinancialActivityAccountscommentsSwagger() {}
@ApiModelProperty(example = "1")
@Schema(example = "1")
public Long glAccountId;
}
@ApiModelProperty(example = "1")
@Schema(example = "1")
public Long resourceId;
public PutFinancialActivityAccountscommentsSwagger comments;
}
@ApiModel(value = "DeleteFinancialActivityAccountsResponse")
@Schema(description = "DeleteFinancialActivityAccountsResponse")
public static final class DeleteFinancialActivityAccountsResponse {
private DeleteFinancialActivityAccountsResponse() {
}
@ApiModelProperty(example = "1")
@Schema(example = "1")
public Long resourceId;
}
@@ -39,7 +39,7 @@ public class FinancialActivityData {
}
public FinancialActivityData(Integer id, String name, GLAccountType mappedGLAccountType) {
super();
this.id = id;
this.name = name;
this.mappedGLAccountType = mappedGLAccountType;
@@ -25,8 +25,7 @@ import org.springframework.stereotype.Service;
/**
* <p>
* Wrapper for {@link FinancialActivityAccountRepository} that adds NULL
* checking and Error handling capabilities
* Wrapper for {@link FinancialActivityAccountRepository} that adds NULL checking and Error handling capabilities
* </p>
*/
@Service
@@ -21,8 +21,7 @@ package org.apache.fineract.accounting.financialactivityaccount.exception;
import org.apache.fineract.infrastructure.core.exception.AbstractPlatformDomainRuleException;
/**
* A {@link RuntimeException} thrown when product to GL account mapping are not
* found.
* A {@link RuntimeException} thrown when product to GL account mapping are not found.
*/
public class DuplicateFinancialActivityAccountFoundException extends AbstractPlatformDomainRuleException {
@@ -23,8 +23,7 @@ import org.apache.fineract.accounting.glaccount.domain.GLAccount;
import org.apache.fineract.infrastructure.core.exception.AbstractPlatformDomainRuleException;
/**
* A {@link RuntimeException} thrown when product to GL account mapping are not
* found.
* A {@link RuntimeException} thrown when product to GL account mapping are not found.
*/
public class FinancialActivityAccountInvalidException extends AbstractPlatformDomainRuleException {
@@ -19,10 +19,10 @@
package org.apache.fineract.accounting.financialactivityaccount.exception;
import org.apache.fineract.infrastructure.core.exception.AbstractPlatformResourceNotFoundException;
import org.springframework.dao.EmptyResultDataAccessException;
/**
* A {@link RuntimeException} thrown when product to GL account mapping are not
* found.
* A {@link RuntimeException} thrown when product to GL account mapping are not found.
*/
public class FinancialActivityAccountNotFoundException extends AbstractPlatformResourceNotFoundException {
@@ -30,6 +30,10 @@ public class FinancialActivityAccountNotFoundException extends AbstractPlatformR
super("error.msg.financialActivityAccount.not.found", "Financial Activity account with Id " + id + " does not exist", id);
}
public FinancialActivityAccountNotFoundException(final Long id, EmptyResultDataAccessException e) {
super("error.msg.financialActivityAccount.not.found", "Financial Activity account with Id " + id + " does not exist", id, e);
}
public FinancialActivityAccountNotFoundException(final Integer financialActivityType) {
super("error.msg.financialActivityAccount.not.found",
"Financial Activity account with for the financial Activity with Id " + financialActivityType + " does not exist",
@@ -67,7 +67,7 @@ public class FinancialActivityAccountReadPlatformServiceImpl implements Financia
return this.jdbcTemplate.queryForObject(sqlBuilder.toString(), this.financialActivityAccountMapper,
new Object[] { financialActivityAccountId });
} catch (final EmptyResultDataAccessException e) {
throw new FinancialActivityAccountNotFoundException(financialActivityAccountId);
throw new FinancialActivityAccountNotFoundException(financialActivityAccountId, e);
}
}
@@ -39,6 +39,8 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.dao.NonTransientDataAccessException;
import org.springframework.orm.jpa.JpaSystemException;
import org.springframework.stereotype.Service;
@Service
@@ -77,20 +79,18 @@ public class FinancialActivityAccountWritePlatformServiceImpl implements Financi
.withCommandId(command.commandId()) //
.withEntityId(financialActivityAccount.getId()) //
.build();
} catch (DataIntegrityViolationException dataIntegrityViolationException) {
handleFinancialActivityAccountDataIntegrityIssues(command, dataIntegrityViolationException.getMostSpecificCause(),
dataIntegrityViolationException);
} catch (final JpaSystemException | DataIntegrityViolationException dve) {
handleFinancialActivityAccountDataIntegrityIssues(command, dve.getMostSpecificCause(), dve);
return CommandProcessingResult.empty();
} catch (final PersistenceException ee) {
Throwable throwable = ExceptionUtils.getRootCause(ee.getCause());
final Throwable throwable = ExceptionUtils.getRootCause(ee.getCause());
handleFinancialActivityAccountDataIntegrityIssues(command, throwable, ee);
return CommandProcessingResult.empty();
}
}
/**
* Validate that the GL Account is appropriate for the particular Financial
* Activity Type
* Validate that the GL Account is appropriate for the particular Financial Activity Type
**/
private void validateFinancialActivityAndAccountMapping(FinancialActivityAccount financialActivityAccount) {
FinancialActivity financialActivity = FinancialActivity.fromInt(financialActivityAccount.getFinancialActivityType());
@@ -129,9 +129,8 @@ public class FinancialActivityAccountWritePlatformServiceImpl implements Financi
.withEntityId(financialActivityAccountId) //
.with(changes) //
.build();
} catch (DataIntegrityViolationException dataIntegrityViolationException) {
handleFinancialActivityAccountDataIntegrityIssues(command, dataIntegrityViolationException.getMostSpecificCause(),
dataIntegrityViolationException);
} catch (final JpaSystemException | DataIntegrityViolationException dve) {
handleFinancialActivityAccountDataIntegrityIssues(command, dve.getMostSpecificCause(), dve);
return CommandProcessingResult.empty();
} catch (final PersistenceException ee) {
Throwable throwable = ExceptionUtils.getRootCause(ee.getCause());
@@ -152,7 +151,19 @@ public class FinancialActivityAccountWritePlatformServiceImpl implements Financi
}
private void handleFinancialActivityAccountDataIntegrityIssues(final JsonCommand command, final Throwable realCause,
final Exception dve) {
final NonTransientDataAccessException dve) {
if (realCause.getMessage().contains("financial_activity_type")) {
final Integer financialActivityId = command
.integerValueSansLocaleOfParameterNamed(FinancialActivityAccountsJsonInputParams.FINANCIAL_ACTIVITY_ID.getValue());
throw new DuplicateFinancialActivityAccountFoundException(financialActivityId);
}
LOG.error("Error occured.", dve);
throw new PlatformDataIntegrityException("error.msg.glAccount.unknown.data.integrity.issue",
"Unknown data integrity issue with resource GL Account: " + realCause.getMessage());
}
private void handleFinancialActivityAccountDataIntegrityIssues(JsonCommand command, Throwable realCause, PersistenceException dve) {
if (realCause.getMessage().contains("financial_activity_type")) {
final Integer financialActivityId = command
.integerValueSansLocaleOfParameterNamed(FinancialActivityAccountsJsonInputParams.FINANCIAL_ACTIVITY_ID.getValue());
@@ -20,15 +20,15 @@ package org.apache.fineract.accounting.glaccount.api;
import com.sun.jersey.core.header.FormDataContentDisposition;
import com.sun.jersey.multipart.FormDataParam;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import io.swagger.annotations.ApiResponse;
import io.swagger.annotations.ApiResponses;
import io.swagger.annotations.SwaggerDefinition;
import io.swagger.annotations.Tag;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.ArraySchema;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.parameters.RequestBody;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import io.swagger.v3.oas.annotations.tags.Tag;
import java.io.InputStream;
import java.util.Arrays;
import java.util.Collection;
@@ -75,10 +75,8 @@ import org.springframework.stereotype.Component;
@Path("/glaccounts")
@Component
@Scope("singleton")
@Api(tags = { "General Ledger Account" })
@SwaggerDefinition(tags = {
@Tag(name = "General Ledger Account", description = "Ledger accounts represent an Individual account within an Organizations Chart Of Accounts(COA) and are assigned a name and unique number by which they can be identified. \n"
+ "All transactions relating to a company's assets, liabilities, owners' equity, revenue and expenses are recorded against these accounts") })
@Tag(name = "General Ledger Account", description = "Ledger accounts represent an Individual account within an Organizations Chart Of Accounts(COA) and are assigned a name and unique number by which they can be identified. \n"
+ "All transactions relating to a company's assets, liabilities, owners' equity, revenue and expenses are recorded against these accounts")
public class GLAccountsApiResource {
private static final Set<String> RESPONSE_DATA_PARAMETERS = new HashSet<>(Arrays.asList("id", "name", "parentId", "glCode", "disabled",
@@ -121,13 +119,15 @@ public class GLAccountsApiResource {
@Path("template")
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
@ApiOperation(value = "Retrieve GL Accounts Template", notes = "This is a convenience resource. It can be useful when building maintenance user interface screens for client applications. The template data returned consists of any or all of:\n"
+ "\n" + "Field Defaults\n" + "Allowed Value Lists\n" + "Example Request:\n" + "\n" + "glaccounts/template\n"
+ "glaccounts/template?type=1\n" + "\n" + "type is optional and integer value from 1 to 5.\n" + "\n" + "1.Assets \n"
+ "2.Liabilities \n" + "3.Equity \n" + "4.Income \n" + "5.Expenses")
@ApiResponses({ @ApiResponse(code = 200, message = "", response = GLAccountsApiResourceSwagger.GetGLAccountsTemplateResponse.class) })
@Operation(tags = {
"General Ledger Account" }, summary = "Retrieve GL Accounts Template", description = "This is a convenience resource. It can be useful when building maintenance user interface screens for client applications. The template data returned consists of any or all of:\n"
+ "\n" + "Field Defaults\n" + "Allowed Value Lists\n" + "Example Request:\n" + "\n" + "glaccounts/template\n"
+ "glaccounts/template?type=1\n" + "\n" + "type is optional and integer value from 1 to 5.\n" + "\n" + "1.Assets \n"
+ "2.Liabilities \n" + "3.Equity \n" + "4.Income \n" + "5.Expenses")
@ApiResponses({
@ApiResponse(responseCode = "200", description = "", content = @Content(schema = @Schema(implementation = GLAccountsApiResourceSwagger.GetGLAccountsTemplateResponse.class))) })
public String retrieveNewAccountDetails(@Context final UriInfo uriInfo,
@QueryParam("type") @ApiParam(value = "type") final Integer type) {
@QueryParam("type") @Parameter(description = "type") final Integer type) {
this.context.authenticatedUser().validateHasReadPermission(this.resourceNameForPermission);
@@ -141,18 +141,19 @@ public class GLAccountsApiResource {
@GET
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
@ApiOperation(value = "List General Ledger Accounts", notes = "ARGUMENTS\n"
@Operation(tags = { "General Ledger Account" }, summary = "List General Ledger Accounts", description = "ARGUMENTS\n"
+ "type Integer optional manualEntriesAllowed boolean optional usage Integer optional disabled boolean optional parentId Long optional tagId Long optional\n"
+ "Example Requests:\n" + "\n" + "glaccounts\n" + "\n" + "\n"
+ "glaccounts?type=1&manualEntriesAllowed=true&usage=1&disabled=false\n" + "\n" + "glaccounts?fetchRunningBalance=true")
@ApiResponses({
@ApiResponse(code = 200, message = "", response = GLAccountsApiResourceSwagger.GetGLAccountsResponse.class, responseContainer = "list") })
public String retrieveAllAccounts(@Context final UriInfo uriInfo, @QueryParam("type") @ApiParam(value = "type") final Integer type,
@QueryParam("searchParam") @ApiParam(value = "searchParam") final String searchParam,
@QueryParam("usage") @ApiParam(value = "usage") final Integer usage,
@QueryParam("manualEntriesAllowed") @ApiParam(value = "manualEntriesAllowed") final Boolean manualEntriesAllowed,
@QueryParam("disabled") @ApiParam(value = "disabled") final Boolean disabled,
@QueryParam("fetchRunningBalance") @ApiParam(value = "fetchRunningBalance") final boolean runningBalance) {
@ApiResponse(responseCode = "200", description = "", content = @Content(array = @ArraySchema(schema = @Schema(implementation = GLAccountsApiResourceSwagger.GetGLAccountsResponse.class)))) })
public String retrieveAllAccounts(@Context final UriInfo uriInfo,
@QueryParam("type") @Parameter(description = "type") final Integer type,
@QueryParam("searchParam") @Parameter(description = "searchParam") final String searchParam,
@QueryParam("usage") @Parameter(description = "usage") final Integer usage,
@QueryParam("manualEntriesAllowed") @Parameter(description = "manualEntriesAllowed") final Boolean manualEntriesAllowed,
@QueryParam("disabled") @Parameter(description = "disabled") final Boolean disabled,
@QueryParam("fetchRunningBalance") @Parameter(description = "fetchRunningBalance") final boolean runningBalance) {
this.context.authenticatedUser().validateHasReadPermission(this.resourceNameForPermission);
JournalEntryAssociationParametersData associationParametersData = new JournalEntryAssociationParametersData(false, runningBalance);
@@ -167,13 +168,14 @@ public class GLAccountsApiResource {
@Path("{glAccountId}")
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
@ApiOperation(value = "Retrieve a General Ledger Account", notes = "Example Requests:\n" + "\n" + "glaccounts/1\n" + "\n" + "\n"
+ "glaccounts/1?template=true\n" + "\n" + "\n" + "glaccounts/1?fields=name,glCode\n" + "\n" + "\n"
+ "glaccounts/1?fetchRunningBalance=true")
@ApiResponses({ @ApiResponse(code = 200, message = "", response = GLAccountsApiResourceSwagger.GetGLAccountsResponse.class) })
public String retreiveAccount(@PathParam("glAccountId") @ApiParam(value = "glAccountId") final Long glAccountId,
@Operation(tags = { "General Ledger Account" }, summary = "Retrieve a General Ledger Account", description = "Example Requests:\n"
+ "\n" + "glaccounts/1\n" + "\n" + "\n" + "glaccounts/1?template=true\n" + "\n" + "\n" + "glaccounts/1?fields=name,glCode\n"
+ "\n" + "\n" + "glaccounts/1?fetchRunningBalance=true")
@ApiResponses({
@ApiResponse(responseCode = "200", description = "", content = @Content(schema = @Schema(implementation = GLAccountsApiResourceSwagger.GetGLAccountsResponse.class))) })
public String retreiveAccount(@PathParam("glAccountId") @Parameter(description = "glAccountId") final Long glAccountId,
@Context final UriInfo uriInfo,
@QueryParam("fetchRunningBalance") @ApiParam(value = "fetchRunningBalance") final boolean runningBalance) {
@QueryParam("fetchRunningBalance") @Parameter(description = "fetchRunningBalance") final boolean runningBalance) {
this.context.authenticatedUser().validateHasReadPermission(this.resourceNameForPermission);
@@ -190,12 +192,13 @@ public class GLAccountsApiResource {
@POST
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
@ApiOperation(value = "Create a General Ledger Account", notes = "Note: You may optionally create Hierarchical Chart of Accounts by using the \"parentId\" property of an Account\n"
+ "Mandatory Fields: \n" + "name, glCode, type, usage and manualEntriesAllowed")
@ApiImplicitParams({
@ApiImplicitParam(paramType = "body", value = "body", dataType = "body", dataTypeClass = GLAccountsApiResourceSwagger.PostGLAccountsRequest.class) })
@ApiResponses({ @ApiResponse(code = 200, message = "", response = GLAccountsApiResourceSwagger.PostGLAccountsResponse.class) })
public String createGLAccount(@ApiParam(hidden = true) final String jsonRequestBody) {
@Operation(tags = {
"General Ledger Account" }, summary = "Create a General Ledger Account", description = "Note: You may optionally create Hierarchical Chart of Accounts by using the \"parentId\" property of an Account\n"
+ "Mandatory Fields: \n" + "name, glCode, type, usage and manualEntriesAllowed")
@RequestBody(content = @Content(schema = @Schema(implementation = GLAccountsApiResourceSwagger.PostGLAccountsRequest.class)))
@ApiResponses({
@ApiResponse(responseCode = "200", description = "", content = @Content(schema = @Schema(implementation = GLAccountsApiResourceSwagger.PostGLAccountsResponse.class))) })
public String createGLAccount(@Parameter(hidden = true) final String jsonRequestBody) {
final CommandWrapper commandRequest = new CommandWrapperBuilder().createGLAccount().withJson(jsonRequestBody).build();
@@ -208,13 +211,14 @@ public class GLAccountsApiResource {
@Path("{glAccountId}")
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
@ApiOperation(value = "Update an Accounting closure", notes = "Once an accounting closure is created, only the comments associated with it may be edited\n"
+ "\n")
@ApiImplicitParams({
@ApiImplicitParam(paramType = "body", value = "body", dataType = "body", dataTypeClass = GLAccountsApiResourceSwagger.PutGLAccountsRequest.class) })
@ApiResponses({ @ApiResponse(code = 200, message = "", response = GLAccountsApiResourceSwagger.PutGLAccountsResponse.class) })
public String updateGLAccount(@PathParam("glAccountId") @ApiParam(value = "glAccountId") final Long glAccountId,
@ApiParam(hidden = true) final String jsonRequestBody) {
@Operation(tags = {
"General Ledger Account" }, summary = "Update an Accounting closure", description = "Once an accounting closure is created, only the comments associated with it may be edited\n"
+ "\n")
@RequestBody(content = @Content(schema = @Schema(implementation = GLAccountsApiResourceSwagger.PutGLAccountsRequest.class)))
@ApiResponses({
@ApiResponse(responseCode = "200", description = "", content = @Content(schema = @Schema(implementation = GLAccountsApiResourceSwagger.PutGLAccountsResponse.class))) })
public String updateGLAccount(@PathParam("glAccountId") @Parameter(description = "glAccountId") final Long glAccountId,
@Parameter(hidden = true) final String jsonRequestBody) {
final CommandWrapper commandRequest = new CommandWrapperBuilder().updateGLAccount(glAccountId).withJson(jsonRequestBody).build();
@@ -227,9 +231,11 @@ public class GLAccountsApiResource {
@Path("{glAccountId}")
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
@ApiOperation(value = "Delete an accounting closure", notes = "Note: Only the latest accounting closure associated with a branch may be deleted.")
@ApiResponses({ @ApiResponse(code = 200, message = "", response = GLAccountsApiResourceSwagger.DeleteGLAccountsRequest.class) })
public String deleteGLAccount(@PathParam("glAccountId") @ApiParam(value = "glAccountId") final Long glAccountId) {
@Operation(tags = {
"General Ledger Account" }, summary = "Delete an accounting closure", description = "Note: Only the latest accounting closure associated with a branch may be deleted.")
@ApiResponses({
@ApiResponse(responseCode = "200", description = "", content = @Content(schema = @Schema(implementation = GLAccountsApiResourceSwagger.DeleteGLAccountsRequest.class))) })
public String deleteGLAccount(@PathParam("glAccountId") @Parameter(description = "glAccountId") final Long glAccountId) {
final CommandWrapper commandRequest = new CommandWrapperBuilder().deleteGLAccount(glAccountId).build();
@@ -18,8 +18,7 @@
*/
package org.apache.fineract.accounting.glaccount.api;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import io.swagger.v3.oas.annotations.media.Schema;
import java.util.Collection;
import java.util.List;
import org.apache.fineract.accounting.glaccount.data.GLAccountData;
@@ -35,57 +34,57 @@ final class GLAccountsApiResourceSwagger {
}
@ApiModel(value = "GetGLAccountsResponse")
@Schema(description = "GetGLAccountsResponse")
public static final class GetGLAccountsResponse {
private GetGLAccountsResponse() {
}
@ApiModelProperty(example = "16")
@Schema(example = "16")
public Long id;
@ApiModelProperty(example = "Cash")
@Schema(example = "Cash")
public String name;
@ApiModelProperty(example = "1")
@Schema(example = "1")
public Long parentId;
@ApiModelProperty(example = "100001")
@Schema(example = "100001")
public String glCode;
@ApiModelProperty(example = "false")
@Schema(example = "false")
public Boolean disabled;
@ApiModelProperty(example = "true")
@Schema(example = "true")
public Boolean manualEntriesAllowed;
public EnumOptionData type;
public EnumOptionData usage;
@ApiModelProperty(example = "Desc")
@Schema(example = "Desc")
public String description;
@ApiModelProperty(example = "....Cash")
@Schema(example = "....Cash")
public String nameDecorated;
public CodeValueData tagId;
@ApiModelProperty(example = "118437")
@Schema(example = "118437")
public Long organizationRunningBalance;
}
@ApiModel(value = "GetGLAccountsTemplateResponse")
@Schema(description = "GetGLAccountsTemplateResponse")
public static final class GetGLAccountsTemplateResponse {
private GetGLAccountsTemplateResponse() {
}
@ApiModelProperty(example = "false")
@Schema(example = "false")
public Boolean disabled;
@ApiModelProperty(example = "true")
@Schema(example = "true")
public Boolean manualEntriesAllowed;
public EnumOptionData type;
@@ -104,83 +103,83 @@ final class GLAccountsApiResourceSwagger {
}
@ApiModel(value = "PostGLAccountsRequest")
@Schema(description = "PostGLAccountsRequest")
public static final class PostGLAccountsRequest {
private PostGLAccountsRequest() {
}
@ApiModelProperty(example = "Cash at Bangalore")
@Schema(example = "Cash at Bangalore")
public String name;
@ApiModelProperty(example = "100001")
@Schema(example = "100001")
public String glCode;
@ApiModelProperty(example = "true")
@Schema(example = "true")
public Boolean manualEntriesAllowed;
@ApiModelProperty(example = "1")
@Schema(example = "1")
public String type;
@ApiModelProperty(example = "10")
@Schema(example = "10")
public String tagId;
@ApiModelProperty(example = "1")
@Schema(example = "1")
public Long parentId;
@ApiModelProperty(example = "1")
@Schema(example = "1")
public EnumOptionData usage;
@ApiModelProperty(example = "Desc")
@Schema(example = "Desc")
public String description;
}
@ApiModel(value = "PostGLAccountsResponse")
@Schema(description = "PostGLAccountsResponse")
public static final class PostGLAccountsResponse {
private PostGLAccountsResponse() {
}
@ApiModelProperty(example = "22")
@Schema(example = "22")
public int resourceId;
}
@ApiModel(value = "PutGLAccountsRequest")
@Schema(description = "PutGLAccountsRequest")
public static final class PutGLAccountsRequest {
private PutGLAccountsRequest() {
}
@ApiModelProperty(example = "Cash at Bangalore")
@Schema(example = "Cash at Bangalore")
public String name;
}
@ApiModel(value = "PutGLAccountsResponse")
@Schema(description = "PutGLAccountsResponse")
public static final class PutGLAccountsResponse {
private PutGLAccountsResponse() {
}
@ApiModel
@Schema
public static final class PutGLAccountsResponsechangesSwagger {
private PutGLAccountsResponsechangesSwagger() {}
@ApiModelProperty(example = "Cash at Bangalore")
@Schema(example = "Cash at Bangalore")
public String name;
}
@ApiModelProperty(example = "1")
@Schema(example = "1")
public int resourceId;
public PutGLAccountsResponsechangesSwagger changes;
}
@ApiModel(value = "DeleteGLAccountsRequest")
@Schema(description = "DeleteGLAccountsRequest")
public static final class DeleteGLAccountsRequest {
private DeleteGLAccountsRequest() {
@@ -193,7 +192,7 @@ final class GLAccountsApiResourceSwagger {
}
@ApiModelProperty(example = "1")
@Schema(example = "1")
public int resourceId;
private DeleteGLAccountsRequestchangesSwagger changes;
@@ -30,8 +30,7 @@ import org.apache.fineract.infrastructure.core.data.EnumOptionData;
/**
* Immutable object representing a General Ledger Account
*
* Note: no getter/setters required as google-gson will produce json from fields
* of object.
* Note: no getter/setters required as google-gson will produce json from fields of object.
*/
public class GLAccountData implements Serializable {
@@ -100,8 +100,9 @@ public class TrialBalance extends AbstractPersistableCustom {
}
TrialBalance other = (TrialBalance) obj;
return Objects.equals(other.officeId, officeId) && Objects.equals(other.glAccountId, glAccountId)
&& Objects.equals(other.amount, amount) && Objects.equals(other.entryDate, entryDate)
&& Objects.equals(other.transactionDate, transactionDate) && Objects.equals(other.closingBalance, closingBalance);
&& Objects.equals(other.amount, amount) && other.entryDate.compareTo(entryDate) == 0 ? Boolean.TRUE
: Boolean.FALSE && other.transactionDate.compareTo(transactionDate) == 0 ? Boolean.TRUE
: Boolean.FALSE && Objects.equals(other.closingBalance, closingBalance);
}
@Override
@@ -22,8 +22,7 @@ import org.apache.fineract.infrastructure.core.exception.AbstractPlatformDomainR
/**
*
* when gl account is attached with any product(loan/saving) then we can not
* disable the gl account
* when gl account is attached with any product(loan/saving) then we can not disable the gl account
*/
public class GLAccountDisableException extends AbstractPlatformDomainRuleException {
@@ -21,8 +21,7 @@ package org.apache.fineract.accounting.glaccount.exception;
import org.apache.fineract.infrastructure.core.exception.AbstractPlatformDomainRuleException;
/**
* A {@link RuntimeException} thrown when a GL Account with a given GL Code of
* the particular type is already present
* A {@link RuntimeException} thrown when a GL Account with a given GL Code of the particular type is already present
*/
public class GLAccountDuplicateException extends AbstractPlatformDomainRuleException {
@@ -21,8 +21,7 @@ package org.apache.fineract.accounting.glaccount.exception;
import org.apache.fineract.infrastructure.core.exception.AbstractPlatformDomainRuleException;
/**
* A {@link RuntimeException} thrown when trying to fetch accounts belonging to
* an Invalid Usage Type
* A {@link RuntimeException} thrown when trying to fetch accounts belonging to an Invalid Usage Type
*/
public class GLAccountInvalidClassificationException extends AbstractPlatformDomainRuleException {
@@ -21,8 +21,7 @@ package org.apache.fineract.accounting.glaccount.exception;
import org.apache.fineract.infrastructure.core.exception.AbstractPlatformDomainRuleException;
/**
* A {@link RuntimeException} thrown when a GL Account with a given GL Code of
* the particular type is already present
* A {@link RuntimeException} thrown when a GL Account with a given GL Code of the particular type is already present
*/
public class GLAccountInvalidDeleteException extends AbstractPlatformDomainRuleException {
@@ -21,8 +21,7 @@ package org.apache.fineract.accounting.glaccount.exception;
import org.apache.fineract.infrastructure.core.exception.AbstractPlatformDomainRuleException;
/**
* A {@link RuntimeException} thrown when trying to map invalid parents to a GL
* account
* A {@link RuntimeException} thrown when trying to map invalid parents to a GL account
*/
public class GLAccountInvalidParentException extends AbstractPlatformDomainRuleException {
@@ -21,8 +21,7 @@ package org.apache.fineract.accounting.glaccount.exception;
import org.apache.fineract.infrastructure.core.exception.AbstractPlatformDomainRuleException;
/**
* A {@link RuntimeException} thrown when an error is encountered during
* updating a GL Account
* A {@link RuntimeException} thrown when an error is encountered during updating a GL Account
*/
public class GLAccountInvalidUpdateException extends AbstractPlatformDomainRuleException {
@@ -21,8 +21,7 @@ package org.apache.fineract.accounting.glaccount.exception;
import org.apache.fineract.infrastructure.core.exception.AbstractPlatformDomainRuleException;
/**
* A {@link RuntimeException} thrown when trying to fetch accounts belonging to
* an Invalid Type
* A {@link RuntimeException} thrown when trying to fetch accounts belonging to an Invalid Type
*/
public class GLAccountInvalidUsageException extends AbstractPlatformDomainRuleException {
@@ -19,6 +19,7 @@
package org.apache.fineract.accounting.glaccount.exception;
import org.apache.fineract.infrastructure.core.exception.AbstractPlatformResourceNotFoundException;
import org.springframework.dao.EmptyResultDataAccessException;
/**
* A {@link RuntimeException} thrown when GL account resources are not found.
@@ -28,4 +29,8 @@ public class GLAccountNotFoundException extends AbstractPlatformResourceNotFound
public GLAccountNotFoundException(final Long id) {
super("error.msg.glaccount.id.invalid", "General Ledger account with identifier " + id + " does not exist ", id);
}
public GLAccountNotFoundException(final Long id, EmptyResultDataAccessException e) {
super("error.msg.glaccount.id.invalid", "General Ledger account with identifier " + id + " does not exist ", id, e);
}
}
@@ -35,8 +35,7 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
/**
* Implementation of {@link FromApiJsonDeserializer} for
* {@link GuarantorCommand}'s.
* Implementation of {@link FromApiJsonDeserializer} for {@link GuarantorCommand}'s.
*/
@Component
public final class GLAccountCommandFromApiJsonDeserializer extends AbstractFromApiJsonDeserializer<GLAccountCommand> {

Some files were not shown because too many files have changed in this diff Show More